SQL: Reorganize the translate action (elastic/x-pack-elasticsearch#2841)
Organizes the SQL translate action to match the way that x-pack has been organizing new actions for a while. All of the pieces are put into the same class file. Original commit: elastic/x-pack-elasticsearch@def911c0ab
This commit is contained in:
parent
562117a7b7
commit
25a0ec42f6
|
@ -67,7 +67,7 @@ import org.elasticsearch.xpack.security.user.User;
|
||||||
import org.elasticsearch.xpack.security.user.XPackSecurityUser;
|
import org.elasticsearch.xpack.security.user.XPackSecurityUser;
|
||||||
import org.elasticsearch.xpack.security.user.XPackUser;
|
import org.elasticsearch.xpack.security.user.XPackUser;
|
||||||
import org.elasticsearch.xpack.sql.plugin.sql.action.SqlAction;
|
import org.elasticsearch.xpack.sql.plugin.sql.action.SqlAction;
|
||||||
import org.elasticsearch.xpack.sql.plugin.sql.action.SqlTranslateAction;
|
import org.elasticsearch.xpack.sql.plugin.SqlTranslateAction;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
|
@ -29,8 +29,7 @@ import org.elasticsearch.xpack.sql.jdbc.net.protocol.MetaTableResponse;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.net.protocol.Proto;
|
import org.elasticsearch.xpack.sql.jdbc.net.protocol.Proto;
|
||||||
import org.elasticsearch.xpack.sql.plugin.sql.action.SqlAction;
|
import org.elasticsearch.xpack.sql.plugin.sql.action.SqlAction;
|
||||||
import org.elasticsearch.xpack.sql.plugin.sql.action.SqlResponse;
|
import org.elasticsearch.xpack.sql.plugin.sql.action.SqlResponse;
|
||||||
import org.elasticsearch.xpack.sql.plugin.sql.action.SqlTranslateAction;
|
import org.elasticsearch.xpack.sql.plugin.SqlTranslateAction;
|
||||||
import org.elasticsearch.xpack.sql.plugin.sql.action.SqlTranslateResponse;
|
|
||||||
import org.elasticsearch.xpack.sql.protocol.shared.Request;
|
import org.elasticsearch.xpack.sql.protocol.shared.Request;
|
||||||
import org.elasticsearch.xpack.sql.protocol.shared.Response;
|
import org.elasticsearch.xpack.sql.protocol.shared.Response;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
|
@ -149,7 +148,7 @@ public class SqlLicenseIT extends AbstractLicensesIntegrationTestCase {
|
||||||
assertThat(e.getMessage(), equalTo("current license is non-compliant for [sql]"));
|
assertThat(e.getMessage(), equalTo("current license is non-compliant for [sql]"));
|
||||||
enableSqlLicensing();
|
enableSqlLicensing();
|
||||||
|
|
||||||
SqlTranslateResponse response = client().prepareExecute(SqlTranslateAction.INSTANCE).query("SELECT * FROM test").get();
|
SqlTranslateAction.Response response = client().prepareExecute(SqlTranslateAction.INSTANCE).query("SELECT * FROM test").get();
|
||||||
SearchSourceBuilder source = response.source();
|
SearchSourceBuilder source = response.source();
|
||||||
assertThat(source.docValueFields(), Matchers.contains("count"));
|
assertThat(source.docValueFields(), Matchers.contains("count"));
|
||||||
FetchSourceContext fetchSource = source.fetchSource();
|
FetchSourceContext fetchSource = source.fetchSource();
|
||||||
|
|
|
@ -10,8 +10,7 @@ import org.elasticsearch.action.support.WriteRequest;
|
||||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||||
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
|
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
|
||||||
import org.elasticsearch.search.sort.SortBuilders;
|
import org.elasticsearch.search.sort.SortBuilders;
|
||||||
import org.elasticsearch.xpack.sql.plugin.sql.action.SqlTranslateAction;
|
import org.elasticsearch.xpack.sql.plugin.SqlTranslateAction;
|
||||||
import org.elasticsearch.xpack.sql.plugin.sql.action.SqlTranslateResponse;
|
|
||||||
|
|
||||||
import static java.util.Collections.singletonList;
|
import static java.util.Collections.singletonList;
|
||||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
||||||
|
@ -29,7 +28,7 @@ public class SqlTranslateActionIT extends AbstractSqlIntegTestCase {
|
||||||
|
|
||||||
boolean columnOrder = randomBoolean();
|
boolean columnOrder = randomBoolean();
|
||||||
String columns = columnOrder ? "data, count" : "count, data";
|
String columns = columnOrder ? "data, count" : "count, data";
|
||||||
SqlTranslateResponse response = client().prepareExecute(SqlTranslateAction.INSTANCE)
|
SqlTranslateAction.Response response = client().prepareExecute(SqlTranslateAction.INSTANCE)
|
||||||
.query("SELECT " + columns + " FROM test ORDER BY count").get();
|
.query("SELECT " + columns + " FROM test ORDER BY count").get();
|
||||||
SearchSourceBuilder source = response.source();
|
SearchSourceBuilder source = response.source();
|
||||||
FetchSourceContext fetch = source.fetchSource();
|
FetchSourceContext fetch = source.fetchSource();
|
||||||
|
@ -39,4 +38,3 @@ public class SqlTranslateActionIT extends AbstractSqlIntegTestCase {
|
||||||
assertEquals(singletonList(SortBuilders.fieldSort("count")), source.sorts());
|
assertEquals(singletonList(SortBuilders.fieldSort("count")), source.sorts());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,11 +27,8 @@ import org.elasticsearch.xpack.sql.analysis.catalog.FilteredCatalog;
|
||||||
import org.elasticsearch.xpack.sql.execution.PlanExecutor;
|
import org.elasticsearch.xpack.sql.execution.PlanExecutor;
|
||||||
import org.elasticsearch.xpack.sql.plugin.SqlGetIndicesAction.TransportAction.CatalogHolder;
|
import org.elasticsearch.xpack.sql.plugin.SqlGetIndicesAction.TransportAction.CatalogHolder;
|
||||||
import org.elasticsearch.xpack.sql.plugin.sql.action.SqlAction;
|
import org.elasticsearch.xpack.sql.plugin.sql.action.SqlAction;
|
||||||
import org.elasticsearch.xpack.sql.plugin.sql.action.SqlTranslateAction;
|
|
||||||
import org.elasticsearch.xpack.sql.plugin.sql.action.TransportSqlAction;
|
import org.elasticsearch.xpack.sql.plugin.sql.action.TransportSqlAction;
|
||||||
import org.elasticsearch.xpack.sql.plugin.sql.action.TransportSqlTranslateAction;
|
|
||||||
import org.elasticsearch.xpack.sql.plugin.sql.rest.RestSqlAction;
|
import org.elasticsearch.xpack.sql.plugin.sql.rest.RestSqlAction;
|
||||||
import org.elasticsearch.xpack.sql.plugin.sql.rest.RestSqlTranslateAction;
|
|
||||||
import org.elasticsearch.xpack.sql.session.Cursor;
|
import org.elasticsearch.xpack.sql.session.Cursor;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -68,12 +65,12 @@ public class SqlPlugin implements ActionPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<RestHandler> getRestHandlers(Settings settings, RestController restController,
|
public List<RestHandler> getRestHandlers(Settings settings, RestController restController,
|
||||||
ClusterSettings clusterSettings, IndexScopedSettings indexScopedSettings, SettingsFilter settingsFilter,
|
ClusterSettings clusterSettings, IndexScopedSettings indexScopedSettings, SettingsFilter settingsFilter,
|
||||||
IndexNameExpressionResolver indexNameExpressionResolver, Supplier<DiscoveryNodes> nodesInCluster) {
|
IndexNameExpressionResolver indexNameExpressionResolver, Supplier<DiscoveryNodes> nodesInCluster) {
|
||||||
|
|
||||||
return Arrays.asList(new RestSqlAction(settings, restController),
|
return Arrays.asList(new RestSqlAction(settings, restController),
|
||||||
new RestSqlTranslateAction(settings, restController),
|
new SqlTranslateAction.RestAction(settings, restController),
|
||||||
new RestSqlCliAction(settings, restController),
|
new RestSqlCliAction(settings, restController),
|
||||||
new RestSqlJdbcAction(settings, restController, sqlLicenseChecker));
|
new RestSqlJdbcAction(settings, restController, sqlLicenseChecker));
|
||||||
}
|
}
|
||||||
|
@ -82,6 +79,6 @@ public class SqlPlugin implements ActionPlugin {
|
||||||
public List<ActionHandler<? extends ActionRequest, ? extends ActionResponse>> getActions() {
|
public List<ActionHandler<? extends ActionRequest, ? extends ActionResponse>> getActions() {
|
||||||
return Arrays.asList(new ActionHandler<>(SqlAction.INSTANCE, TransportSqlAction.class),
|
return Arrays.asList(new ActionHandler<>(SqlAction.INSTANCE, TransportSqlAction.class),
|
||||||
new ActionHandler<>(SqlGetIndicesAction.INSTANCE, SqlGetIndicesAction.TransportAction.class),
|
new ActionHandler<>(SqlGetIndicesAction.INSTANCE, SqlGetIndicesAction.TransportAction.class),
|
||||||
new ActionHandler<>(SqlTranslateAction.INSTANCE, TransportSqlTranslateAction.class));
|
new ActionHandler<>(SqlTranslateAction.INSTANCE, SqlTranslateAction.TransportAction.class));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,218 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.xpack.sql.plugin;
|
||||||
|
|
||||||
|
import org.elasticsearch.action.Action;
|
||||||
|
import org.elasticsearch.action.ActionListener;
|
||||||
|
import org.elasticsearch.action.ActionRequestBuilder;
|
||||||
|
import org.elasticsearch.action.ActionRequestValidationException;
|
||||||
|
import org.elasticsearch.action.ActionResponse;
|
||||||
|
import org.elasticsearch.action.support.ActionFilters;
|
||||||
|
import org.elasticsearch.action.support.HandledTransportAction;
|
||||||
|
import org.elasticsearch.client.ElasticsearchClient;
|
||||||
|
import org.elasticsearch.client.node.NodeClient;
|
||||||
|
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||||
|
import org.elasticsearch.common.Strings;
|
||||||
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
|
import org.elasticsearch.common.settings.Setting;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
|
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||||
|
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.rest.BaseRestHandler;
|
||||||
|
import org.elasticsearch.rest.RestController;
|
||||||
|
import org.elasticsearch.rest.RestRequest;
|
||||||
|
import org.elasticsearch.rest.action.RestToXContentListener;
|
||||||
|
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||||
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
|
import org.elasticsearch.transport.TransportService;
|
||||||
|
import org.elasticsearch.xpack.sql.execution.PlanExecutor;
|
||||||
|
import org.elasticsearch.xpack.sql.plugin.sql.action.AbstractSqlRequest;
|
||||||
|
import org.elasticsearch.xpack.sql.session.Configuration;
|
||||||
|
import org.joda.time.DateTimeZone;
|
||||||
|
|
||||||
|
import static org.elasticsearch.action.ValidateActions.addValidationError;
|
||||||
|
import static org.elasticsearch.rest.RestRequest.Method.GET;
|
||||||
|
import static org.elasticsearch.rest.RestRequest.Method.POST;
|
||||||
|
import static org.elasticsearch.xpack.sql.plugin.sql.action.AbstractSqlRequest.DEFAULT_FETCH_SIZE;
|
||||||
|
import static org.elasticsearch.xpack.sql.plugin.sql.action.AbstractSqlRequest.DEFAULT_PAGE_TIMEOUT;
|
||||||
|
import static org.elasticsearch.xpack.sql.plugin.sql.action.AbstractSqlRequest.DEFAULT_REQUEST_TIMEOUT;
|
||||||
|
import static org.elasticsearch.xpack.sql.plugin.sql.action.AbstractSqlRequest.DEFAULT_TIME_ZONE;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class SqlTranslateAction
|
||||||
|
extends Action<SqlTranslateAction.Request, SqlTranslateAction.Response, SqlTranslateAction.RequestBuilder> {
|
||||||
|
|
||||||
|
public static final SqlTranslateAction INSTANCE = new SqlTranslateAction();
|
||||||
|
public static final String NAME = "indices:data/read/sql/translate";
|
||||||
|
|
||||||
|
private SqlTranslateAction() {
|
||||||
|
super(NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RequestBuilder newRequestBuilder(ElasticsearchClient client) {
|
||||||
|
return new RequestBuilder(client, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response newResponse() {
|
||||||
|
return new Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Request extends AbstractSqlRequest {
|
||||||
|
public static final ObjectParser<Request, Void> PARSER = objectParser(Request::new);
|
||||||
|
|
||||||
|
public Request() {}
|
||||||
|
|
||||||
|
public Request(String query, DateTimeZone timeZone, int fetchSize, TimeValue requestTimeout, TimeValue pageTimeout) {
|
||||||
|
super(query, timeZone, fetchSize, requestTimeout, pageTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionRequestValidationException validate() {
|
||||||
|
ActionRequestValidationException validationException = null;
|
||||||
|
if ((false == Strings.hasText(query()))) {
|
||||||
|
validationException = addValidationError("query is required", validationException);
|
||||||
|
}
|
||||||
|
return validationException;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "SQL Translate [" + query() + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class RequestBuilder extends ActionRequestBuilder<Request, Response, RequestBuilder> {
|
||||||
|
public RequestBuilder(ElasticsearchClient client, SqlTranslateAction action) {
|
||||||
|
this(client, action, null, DEFAULT_TIME_ZONE, DEFAULT_FETCH_SIZE, DEFAULT_REQUEST_TIMEOUT, DEFAULT_PAGE_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequestBuilder(ElasticsearchClient client, SqlTranslateAction action, String query, DateTimeZone timeZone,
|
||||||
|
int fetchSize, TimeValue requestTimeout, TimeValue pageTimeout) {
|
||||||
|
super(client, action, new Request(query, timeZone, fetchSize, requestTimeout, pageTimeout));
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequestBuilder query(String query) {
|
||||||
|
request.query(query);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequestBuilder timeZone(DateTimeZone timeZone) {
|
||||||
|
request.timeZone(timeZone);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Response extends ActionResponse implements ToXContentObject {
|
||||||
|
private SearchSourceBuilder source;
|
||||||
|
|
||||||
|
public Response() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response(SearchSourceBuilder source) {
|
||||||
|
this.source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SearchSourceBuilder source() {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readFrom(StreamInput in) throws IOException {
|
||||||
|
source = new SearchSourceBuilder(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTo(StreamOutput out) throws IOException {
|
||||||
|
source.writeTo(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj == null || getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Response other = (Response) obj;
|
||||||
|
return Objects.equals(source, other.source);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
|
return source.toXContent(builder, params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TransportAction extends HandledTransportAction<Request, Response> {
|
||||||
|
private final PlanExecutor planExecutor;
|
||||||
|
private final SqlLicenseChecker sqlLicenseChecker;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public TransportAction(Settings settings, ThreadPool threadPool,
|
||||||
|
TransportService transportService, ActionFilters actionFilters,
|
||||||
|
IndexNameExpressionResolver indexNameExpressionResolver,
|
||||||
|
PlanExecutor planExecutor,
|
||||||
|
SqlLicenseChecker sqlLicenseChecker) {
|
||||||
|
super(settings, SqlTranslateAction.NAME, threadPool, transportService, actionFilters,
|
||||||
|
indexNameExpressionResolver, Request::new);
|
||||||
|
|
||||||
|
this.planExecutor = planExecutor;
|
||||||
|
this.sqlLicenseChecker = sqlLicenseChecker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doExecute(Request request, ActionListener<Response> listener) {
|
||||||
|
sqlLicenseChecker.checkIfSqlAllowed();
|
||||||
|
String query = request.query();
|
||||||
|
|
||||||
|
Configuration cfg = new Configuration(request.timeZone(), request.fetchSize(),
|
||||||
|
request.requestTimeout(), request.pageTimeout());
|
||||||
|
|
||||||
|
listener.onResponse(new Response(planExecutor.searchSource(query, cfg)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class RestAction extends BaseRestHandler {
|
||||||
|
public RestAction(Settings settings, RestController controller) {
|
||||||
|
super(settings);
|
||||||
|
controller.registerHandler(GET, "/_sql/translate", this);
|
||||||
|
controller.registerHandler(POST, "/_sql/translate", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
|
||||||
|
Request sqlRequest;
|
||||||
|
try (XContentParser parser = request.contentOrSourceParamParser()) {
|
||||||
|
sqlRequest = Request.PARSER.apply(parser, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return channel -> client.executeLocally(SqlTranslateAction.INSTANCE,
|
||||||
|
sqlRequest, new RestToXContentListener<Response>(channel));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "sql_translate_action";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,29 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.sql.plugin.sql.action;
|
|
||||||
|
|
||||||
import org.elasticsearch.action.Action;
|
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
|
||||||
|
|
||||||
public class SqlTranslateAction extends Action<SqlTranslateRequest, SqlTranslateResponse, SqlTranslateRequestBuilder> {
|
|
||||||
|
|
||||||
public static final SqlTranslateAction INSTANCE = new SqlTranslateAction();
|
|
||||||
public static final String NAME = "indices:data/read/sql/translate";
|
|
||||||
|
|
||||||
private SqlTranslateAction() {
|
|
||||||
super(NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqlTranslateRequestBuilder newRequestBuilder(ElasticsearchClient client) {
|
|
||||||
return new SqlTranslateRequestBuilder(client, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqlTranslateResponse newResponse() {
|
|
||||||
return new SqlTranslateResponse();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.sql.plugin.sql.action;
|
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionRequestValidationException;
|
|
||||||
import org.elasticsearch.common.Strings;
|
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
|
||||||
import org.elasticsearch.common.xcontent.ObjectParser;
|
|
||||||
import org.joda.time.DateTimeZone;
|
|
||||||
|
|
||||||
import static org.elasticsearch.action.ValidateActions.addValidationError;
|
|
||||||
|
|
||||||
public class SqlTranslateRequest extends AbstractSqlRequest {
|
|
||||||
|
|
||||||
public static final ObjectParser<SqlTranslateRequest, Void> PARSER = objectParser(SqlTranslateRequest::new);
|
|
||||||
|
|
||||||
public SqlTranslateRequest() {}
|
|
||||||
|
|
||||||
public SqlTranslateRequest(String query, DateTimeZone timeZone, int fetchSize, TimeValue requestTimeout, TimeValue pageTimeout) {
|
|
||||||
super(query, timeZone, fetchSize, requestTimeout, pageTimeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ActionRequestValidationException validate() {
|
|
||||||
ActionRequestValidationException validationException = null;
|
|
||||||
if ((false == Strings.hasText(query()))) {
|
|
||||||
validationException = addValidationError("query is required", validationException);
|
|
||||||
}
|
|
||||||
return validationException;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDescription() {
|
|
||||||
return "SQL Translate [" + query() + "]";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.sql.plugin.sql.action;
|
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionRequestBuilder;
|
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
|
||||||
import org.joda.time.DateTimeZone;
|
|
||||||
|
|
||||||
import static org.elasticsearch.xpack.sql.plugin.sql.action.AbstractSqlRequest.DEFAULT_FETCH_SIZE;
|
|
||||||
import static org.elasticsearch.xpack.sql.plugin.sql.action.AbstractSqlRequest.DEFAULT_PAGE_TIMEOUT;
|
|
||||||
import static org.elasticsearch.xpack.sql.plugin.sql.action.AbstractSqlRequest.DEFAULT_REQUEST_TIMEOUT;
|
|
||||||
import static org.elasticsearch.xpack.sql.plugin.sql.action.AbstractSqlRequest.DEFAULT_TIME_ZONE;
|
|
||||||
|
|
||||||
public class SqlTranslateRequestBuilder
|
|
||||||
extends ActionRequestBuilder<SqlTranslateRequest, SqlTranslateResponse, SqlTranslateRequestBuilder> {
|
|
||||||
|
|
||||||
public SqlTranslateRequestBuilder(ElasticsearchClient client, SqlTranslateAction action) {
|
|
||||||
this(client, action, null, DEFAULT_TIME_ZONE, DEFAULT_FETCH_SIZE, DEFAULT_REQUEST_TIMEOUT, DEFAULT_PAGE_TIMEOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SqlTranslateRequestBuilder(ElasticsearchClient client, SqlTranslateAction action, String query, DateTimeZone timeZone,
|
|
||||||
int fetchSize, TimeValue requestTimeout, TimeValue pageTimeout) {
|
|
||||||
super(client, action, new SqlTranslateRequest(query, timeZone, fetchSize, requestTimeout, pageTimeout));
|
|
||||||
}
|
|
||||||
|
|
||||||
public SqlTranslateRequestBuilder query(String query) {
|
|
||||||
request.query(query);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SqlTranslateRequestBuilder timeZone(DateTimeZone timeZone) {
|
|
||||||
request.timeZone(timeZone);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.sql.plugin.sql.action;
|
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionResponse;
|
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
|
||||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class SqlTranslateResponse extends ActionResponse implements ToXContentObject {
|
|
||||||
|
|
||||||
private SearchSourceBuilder source;
|
|
||||||
|
|
||||||
public SqlTranslateResponse() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public SqlTranslateResponse(SearchSourceBuilder source) {
|
|
||||||
this.source = source;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SearchSourceBuilder source() {
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void readFrom(StreamInput in) throws IOException {
|
|
||||||
source = new SearchSourceBuilder(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeTo(StreamOutput out) throws IOException {
|
|
||||||
source.writeTo(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (obj == null || getClass() != obj.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
SqlTranslateResponse other = (SqlTranslateResponse) obj;
|
|
||||||
return Objects.equals(source, other.source);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
return source.toXContent(builder, params);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.sql.plugin.sql.action;
|
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
|
||||||
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.threadpool.ThreadPool;
|
|
||||||
import org.elasticsearch.transport.TransportService;
|
|
||||||
import org.elasticsearch.xpack.sql.execution.PlanExecutor;
|
|
||||||
import org.elasticsearch.xpack.sql.plugin.SqlLicenseChecker;
|
|
||||||
import org.elasticsearch.xpack.sql.session.Configuration;
|
|
||||||
|
|
||||||
public class TransportSqlTranslateAction extends HandledTransportAction<SqlTranslateRequest, SqlTranslateResponse> {
|
|
||||||
|
|
||||||
private final PlanExecutor planExecutor;
|
|
||||||
private final SqlLicenseChecker sqlLicenseChecker;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public TransportSqlTranslateAction(Settings settings, ThreadPool threadPool,
|
|
||||||
TransportService transportService, ActionFilters actionFilters,
|
|
||||||
IndexNameExpressionResolver indexNameExpressionResolver,
|
|
||||||
PlanExecutor planExecutor,
|
|
||||||
SqlLicenseChecker sqlLicenseChecker) {
|
|
||||||
super(settings, SqlTranslateAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver, SqlTranslateRequest::new);
|
|
||||||
|
|
||||||
this.planExecutor = planExecutor;
|
|
||||||
this.sqlLicenseChecker = sqlLicenseChecker;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doExecute(SqlTranslateRequest request, ActionListener<SqlTranslateResponse> listener) {
|
|
||||||
sqlLicenseChecker.checkIfSqlAllowed();
|
|
||||||
String query = request.query();
|
|
||||||
|
|
||||||
Configuration cfg = new Configuration(request.timeZone(), request.fetchSize(), request.requestTimeout(), request.pageTimeout());
|
|
||||||
|
|
||||||
listener.onResponse(new SqlTranslateResponse(planExecutor.searchSource(query, cfg)));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.sql.plugin.sql.rest;
|
|
||||||
|
|
||||||
import org.elasticsearch.client.node.NodeClient;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
|
||||||
import org.elasticsearch.rest.BaseRestHandler;
|
|
||||||
import org.elasticsearch.rest.RestController;
|
|
||||||
import org.elasticsearch.rest.RestRequest;
|
|
||||||
import org.elasticsearch.rest.action.RestToXContentListener;
|
|
||||||
import org.elasticsearch.xpack.sql.plugin.sql.action.SqlTranslateAction;
|
|
||||||
import org.elasticsearch.xpack.sql.plugin.sql.action.SqlTranslateRequest;
|
|
||||||
import org.elasticsearch.xpack.sql.plugin.sql.action.SqlTranslateResponse;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import static org.elasticsearch.rest.RestRequest.Method.GET;
|
|
||||||
import static org.elasticsearch.rest.RestRequest.Method.POST;
|
|
||||||
|
|
||||||
public class RestSqlTranslateAction extends BaseRestHandler {
|
|
||||||
|
|
||||||
public RestSqlTranslateAction(Settings settings, RestController controller) {
|
|
||||||
super(settings);
|
|
||||||
controller.registerHandler(GET, "/_sql/translate", this);
|
|
||||||
controller.registerHandler(POST, "/_sql/translate", this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
|
|
||||||
SqlTranslateRequest sqlRequest;
|
|
||||||
try (XContentParser parser = request.contentOrSourceParamParser()) {
|
|
||||||
sqlRequest = SqlTranslateRequest.PARSER.apply(parser, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return channel -> client.executeLocally(SqlTranslateAction.INSTANCE, sqlRequest, new RestToXContentListener<SqlTranslateResponse>(channel));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "sql_translate_action";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,19 +3,19 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.plugin.sql.action;
|
package org.elasticsearch.xpack.sql.plugin;
|
||||||
|
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.test.AbstractStreamableTestCase;
|
import org.elasticsearch.test.AbstractStreamableTestCase;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.test.EqualsHashCodeTestUtils.MutateFunction;
|
import org.elasticsearch.test.EqualsHashCodeTestUtils.MutateFunction;
|
||||||
|
|
||||||
public class SqlTranslateRequestTests extends AbstractStreamableTestCase<SqlTranslateRequest> {
|
public class SqlTranslateRequestTests extends AbstractStreamableTestCase<SqlTranslateAction.Request> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SqlTranslateRequest createTestInstance() {
|
protected SqlTranslateAction.Request createTestInstance() {
|
||||||
return new SqlTranslateRequest(randomAlphaOfLength(10), randomDateTimeZone(), between(1, Integer.MAX_VALUE), randomTV(),
|
return new SqlTranslateAction.Request(randomAlphaOfLength(10), randomDateTimeZone(), between(1, Integer.MAX_VALUE),
|
||||||
randomTV());
|
randomTV(), randomTV());
|
||||||
}
|
}
|
||||||
|
|
||||||
private TimeValue randomTV() {
|
private TimeValue randomTV() {
|
||||||
|
@ -23,23 +23,23 @@ public class SqlTranslateRequestTests extends AbstractStreamableTestCase<SqlTran
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SqlTranslateRequest createBlankInstance() {
|
protected SqlTranslateAction.Request createBlankInstance() {
|
||||||
return new SqlTranslateRequest();
|
return new SqlTranslateAction.Request();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected MutateFunction<SqlTranslateRequest> getMutateFunction() {
|
protected MutateFunction<SqlTranslateAction.Request> getMutateFunction() {
|
||||||
return randomFrom(
|
return randomFrom(
|
||||||
request -> (SqlTranslateRequest) getCopyFunction().copy(request)
|
request -> (SqlTranslateAction.Request) getCopyFunction().copy(request)
|
||||||
.query(randomValueOtherThan(request.query(), () -> randomAlphaOfLength(5))),
|
.query(randomValueOtherThan(request.query(), () -> randomAlphaOfLength(5))),
|
||||||
request -> (SqlTranslateRequest) getCopyFunction().copy(request)
|
request -> (SqlTranslateAction.Request) getCopyFunction().copy(request)
|
||||||
.timeZone(randomValueOtherThan(request.timeZone(), ESTestCase::randomDateTimeZone)),
|
.timeZone(randomValueOtherThan(request.timeZone(), ESTestCase::randomDateTimeZone)),
|
||||||
request -> (SqlTranslateRequest) getCopyFunction().copy(request)
|
request -> (SqlTranslateAction.Request) getCopyFunction().copy(request)
|
||||||
.fetchSize(randomValueOtherThan(request.fetchSize(), () -> between(1, Integer.MAX_VALUE))),
|
.fetchSize(randomValueOtherThan(request.fetchSize(), () -> between(1, Integer.MAX_VALUE))),
|
||||||
request -> (SqlTranslateRequest) getCopyFunction().copy(request)
|
request -> (SqlTranslateAction.Request) getCopyFunction().copy(request)
|
||||||
.requestTimeout(randomValueOtherThan(request.requestTimeout(), () -> randomTV())),
|
.requestTimeout(randomValueOtherThan(request.requestTimeout(), () -> randomTV())),
|
||||||
request -> (SqlTranslateRequest) getCopyFunction().copy(request)
|
request -> (SqlTranslateAction.Request) getCopyFunction().copy(request)
|
||||||
.pageTimeout(randomValueOtherThan(request.pageTimeout(), () -> randomTV())));
|
.pageTimeout(randomValueOtherThan(request.pageTimeout(), () -> randomTV())));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,15 +3,16 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.plugin.sql.action;
|
package org.elasticsearch.xpack.sql.plugin;
|
||||||
|
|
||||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||||
import org.elasticsearch.test.AbstractStreamableTestCase;
|
import org.elasticsearch.test.AbstractStreamableTestCase;
|
||||||
|
import org.elasticsearch.test.EqualsHashCodeTestUtils.MutateFunction;
|
||||||
|
|
||||||
public class SqlTranslateResponseTests extends AbstractStreamableTestCase<SqlTranslateResponse> {
|
public class SqlTranslateResponseTests extends AbstractStreamableTestCase<SqlTranslateAction.Response> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SqlTranslateResponse createTestInstance() {
|
protected SqlTranslateAction.Response createTestInstance() {
|
||||||
SearchSourceBuilder s = new SearchSourceBuilder();
|
SearchSourceBuilder s = new SearchSourceBuilder();
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
long docValues = iterations(5, 10);
|
long docValues = iterations(5, 10);
|
||||||
|
@ -29,12 +30,20 @@ public class SqlTranslateResponseTests extends AbstractStreamableTestCase<SqlTra
|
||||||
|
|
||||||
s.fetchSource(randomBoolean()).from(randomInt(256)).explain(randomBoolean()).size(randomInt(256));
|
s.fetchSource(randomBoolean()).from(randomInt(256)).explain(randomBoolean()).size(randomInt(256));
|
||||||
|
|
||||||
return new SqlTranslateResponse(s);
|
return new SqlTranslateAction.Response(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SqlTranslateResponse createBlankInstance() {
|
protected SqlTranslateAction.Response createBlankInstance() {
|
||||||
return new SqlTranslateResponse();
|
return new SqlTranslateAction.Response();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MutateFunction<SqlTranslateAction.Response> getMutateFunction() {
|
||||||
|
return response -> {
|
||||||
|
SqlTranslateAction.Response copy = getCopyFunction().copy(response);
|
||||||
|
copy.source().size(randomValueOtherThan(response.source().size(), () -> between(0, Integer.MAX_VALUE)));
|
||||||
|
return copy;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue