SQL: Remove test-utils project (elastic/x-pack-elasticsearch#3583)

Makes Sql Translate Action consistent with other SQL Actions and removes test-utils project

Follow up for elastic/x-pack-elasticsearch#3543

Original commit: elastic/x-pack-elasticsearch@8ff2148d67
This commit is contained in:
Igor Motov 2018-01-17 12:18:25 -05:00 committed by GitHub
parent 78b0cec4ad
commit c3b82e5ee1
18 changed files with 329 additions and 289 deletions

View File

@ -23,6 +23,7 @@ import org.elasticsearch.xpack.sql.plugin.SqlListColumnsResponse;
import org.elasticsearch.xpack.sql.plugin.SqlQueryAction;
import org.elasticsearch.xpack.sql.plugin.SqlQueryResponse;
import org.elasticsearch.xpack.sql.plugin.SqlTranslateAction;
import org.elasticsearch.xpack.sql.plugin.SqlTranslateResponse;
import org.hamcrest.Matchers;
import org.junit.Before;
@ -180,7 +181,7 @@ public class SqlLicenseIT extends AbstractLicensesIntegrationTestCase {
assertThat(e.getMessage(), equalTo("current license is non-compliant for [sql]"));
enableSqlLicensing();
SqlTranslateAction.Response response = client().prepareExecute(SqlTranslateAction.INSTANCE).query("SELECT * FROM test").get();
SqlTranslateResponse response = client().prepareExecute(SqlTranslateAction.INSTANCE).query("SELECT * FROM test").get();
SearchSourceBuilder source = response.source();
assertThat(source.docValueFields(), Matchers.contains("count"));
FetchSourceContext fetchSource = source.fetchSource();

View File

@ -11,6 +11,7 @@ import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.xpack.sql.plugin.SqlTranslateAction;
import org.elasticsearch.xpack.sql.plugin.SqlTranslateResponse;
import static java.util.Collections.singletonList;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
@ -28,7 +29,7 @@ public class SqlTranslateActionIT extends AbstractSqlIntegTestCase {
boolean columnOrder = randomBoolean();
String columns = columnOrder ? "data, count" : "count, data";
SqlTranslateAction.Response response = client().prepareExecute(SqlTranslateAction.INSTANCE)
SqlTranslateResponse response = client().prepareExecute(SqlTranslateAction.INSTANCE)
.query("SELECT " + columns + " FROM test ORDER BY count").get();
SearchSourceBuilder source = response.source();
FetchSourceContext fetch = source.fetchSource();

View File

@ -32,6 +32,7 @@ import org.elasticsearch.xpack.sql.plugin.RestSqlClearCursorAction;
import org.elasticsearch.xpack.sql.plugin.RestSqlListColumnsAction;
import org.elasticsearch.xpack.sql.plugin.RestSqlListTablesAction;
import org.elasticsearch.xpack.sql.plugin.RestSqlQueryAction;
import org.elasticsearch.xpack.sql.plugin.RestSqlTranslateAction;
import org.elasticsearch.xpack.sql.plugin.SqlClearCursorAction;
import org.elasticsearch.xpack.sql.plugin.SqlLicenseChecker;
import org.elasticsearch.xpack.sql.plugin.SqlListColumnsAction;
@ -42,6 +43,7 @@ import org.elasticsearch.xpack.sql.plugin.TransportSqlClearCursorAction;
import org.elasticsearch.xpack.sql.plugin.TransportSqlListColumnsAction;
import org.elasticsearch.xpack.sql.plugin.TransportSqlListTablesAction;
import org.elasticsearch.xpack.sql.plugin.TransportSqlQueryAction;
import org.elasticsearch.xpack.sql.plugin.TransportSqlTranslateAction;
import org.elasticsearch.xpack.sql.session.Cursor;
import java.util.Arrays;
@ -82,7 +84,7 @@ public class SqlEmbedPlugin extends Plugin implements ActionPlugin {
Supplier<DiscoveryNodes> nodesInCluster) {
return Arrays.asList(new RestSqlQueryAction(settings, restController),
new SqlTranslateAction.RestAction(settings, restController),
new RestSqlTranslateAction(settings, restController),
new RestSqlClearCursorAction(settings, restController),
new RestSqlListTablesAction(settings, restController),
new RestSqlListColumnsAction(settings, restController));
@ -91,7 +93,7 @@ public class SqlEmbedPlugin extends Plugin implements ActionPlugin {
@Override
public List<ActionHandler<? extends ActionRequest, ? extends ActionResponse>> getActions() {
return Arrays.asList(new ActionHandler<>(SqlQueryAction.INSTANCE, TransportSqlQueryAction.class),
new ActionHandler<>(SqlTranslateAction.INSTANCE, SqlTranslateAction.TransportAction.class),
new ActionHandler<>(SqlTranslateAction.INSTANCE, TransportSqlTranslateAction.class),
new ActionHandler<>(SqlClearCursorAction.INSTANCE, TransportSqlClearCursorAction.class),
new ActionHandler<>(SqlListTablesAction.INSTANCE, TransportSqlListTablesAction.class),
new ActionHandler<>(SqlListColumnsAction.INSTANCE, TransportSqlListColumnsAction.class));

View File

@ -13,8 +13,6 @@ dependencies {
runtime "com.fasterxml.jackson.core:jackson-core:${versions.jackson}"
runtime "org.apache.logging.log4j:log4j-api:${versions.log4j}"
runtime "org.apache.logging.log4j:log4j-core:${versions.log4j}"
testCompile project(':x-pack-elasticsearch:sql:test-utils')
}
dependencyLicenses {

View File

@ -0,0 +1,32 @@
/*
* 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.client.ElasticsearchClient;
/**
* Sql action for translating SQL queries into ES requests
*/
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();
}
}

View File

@ -0,0 +1,58 @@
/*
* 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.ActionRequestValidationException;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.QueryBuilder;
import org.joda.time.DateTimeZone;
import java.io.IOException;
import static org.elasticsearch.action.ValidateActions.addValidationError;
/**
* Request for the sql action for translating SQL queries into ES requests
*/
public class SqlTranslateRequest extends AbstractSqlQueryRequest {
private static final ObjectParser<SqlTranslateRequest, Void> PARSER = objectParser(SqlTranslateRequest::new);
public SqlTranslateRequest() {
}
public SqlTranslateRequest(Mode mode, String query, QueryBuilder filter, DateTimeZone timeZone, int fetchSize, TimeValue requestTimeout,
TimeValue pageTimeout) {
super(mode, query, filter, timeZone, fetchSize, requestTimeout, pageTimeout);
}
public SqlTranslateRequest(StreamInput in) throws IOException {
super(in);
}
@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() + "][" + filter() + "]";
}
public static SqlTranslateRequest fromXContent(XContentParser parser, Mode mode) {
SqlTranslateRequest request = PARSER.apply(parser, null);
request.mode(mode);
return request;
}
}

View File

@ -0,0 +1,44 @@
/*
* 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.ActionRequestBuilder;
import org.elasticsearch.client.ElasticsearchClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.QueryBuilder;
import org.joda.time.DateTimeZone;
import static org.elasticsearch.xpack.sql.plugin.AbstractSqlQueryRequest.DEFAULT_FETCH_SIZE;
import static org.elasticsearch.xpack.sql.plugin.AbstractSqlQueryRequest.DEFAULT_PAGE_TIMEOUT;
import static org.elasticsearch.xpack.sql.plugin.AbstractSqlQueryRequest.DEFAULT_REQUEST_TIMEOUT;
import static org.elasticsearch.xpack.sql.plugin.AbstractSqlQueryRequest.DEFAULT_TIME_ZONE;
/**
* Builder for the request for the sql action for translating SQL queries into ES requests
*/
public class SqlTranslateRequestBuilder extends ActionRequestBuilder<SqlTranslateRequest, SqlTranslateResponse,
SqlTranslateRequestBuilder> {
public SqlTranslateRequestBuilder(ElasticsearchClient client, SqlTranslateAction action) {
this(client, action, AbstractSqlRequest.Mode.PLAIN, null, null, DEFAULT_TIME_ZONE, DEFAULT_FETCH_SIZE, DEFAULT_REQUEST_TIMEOUT,
DEFAULT_PAGE_TIMEOUT);
}
public SqlTranslateRequestBuilder(ElasticsearchClient client, SqlTranslateAction action, AbstractSqlRequest.Mode mode, String query,
QueryBuilder filter, DateTimeZone timeZone, int fetchSize, TimeValue requestTimeout,
TimeValue pageTimeout) {
super(client, action, new SqlTranslateRequest(mode, query, filter, timeZone, fetchSize, requestTimeout, pageTimeout));
}
public SqlTranslateRequestBuilder query(String query) {
request.query(query);
return this;
}
public SqlTranslateRequestBuilder timeZone(DateTimeZone timeZone) {
request.timeZone(timeZone);
return this;
}
}

View File

@ -0,0 +1,68 @@
/*
* 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.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;
/**
* Response for the sql action for translating SQL queries into ES requests
*/
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);
}
}

View File

@ -14,15 +14,14 @@ import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.search.SearchModule;
import org.elasticsearch.test.AbstractSerializingTestCase;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.sql.test.SqlTestUtils;
import org.junit.Before;
import java.io.IOException;
import java.util.Collections;
import java.util.function.Consumer;
import static org.elasticsearch.xpack.sql.test.SqlTestUtils.randomFilter;
import static org.elasticsearch.xpack.sql.test.SqlTestUtils.randomFilterOrNull;
import static org.elasticsearch.xpack.sql.plugin.SqlTestUtils.randomFilter;
import static org.elasticsearch.xpack.sql.plugin.SqlTestUtils.randomFilterOrNull;
public class SqlQueryRequestTests extends AbstractSerializingTestCase<SqlQueryRequest> {

View File

@ -3,7 +3,7 @@
* 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.test;
package org.elasticsearch.xpack.sql.plugin;
import com.carrotsearch.randomizedtesting.generators.RandomStrings;
import org.elasticsearch.index.query.QueryBuilder;

View File

@ -20,10 +20,10 @@ import java.io.IOException;
import java.util.Collections;
import java.util.function.Consumer;
import static org.elasticsearch.xpack.sql.test.SqlTestUtils.randomFilter;
import static org.elasticsearch.xpack.sql.test.SqlTestUtils.randomFilterOrNull;
import static org.elasticsearch.xpack.sql.plugin.SqlTestUtils.randomFilter;
import static org.elasticsearch.xpack.sql.plugin.SqlTestUtils.randomFilterOrNull;
public class SqlTranslateRequestTests extends AbstractSerializingTestCase<SqlTranslateAction.Request> {
public class SqlTranslateRequestTests extends AbstractSerializingTestCase<SqlTranslateRequest> {
public AbstractSqlRequest.Mode testMode;
@ -33,14 +33,14 @@ public class SqlTranslateRequestTests extends AbstractSerializingTestCase<SqlTra
}
@Override
protected SqlTranslateAction.Request createTestInstance() {
return new SqlTranslateAction.Request(testMode, randomAlphaOfLength(10), randomFilterOrNull(random()), randomDateTimeZone(),
protected SqlTranslateRequest createTestInstance() {
return new SqlTranslateRequest(testMode, randomAlphaOfLength(10), randomFilterOrNull(random()), randomDateTimeZone(),
between(1, Integer.MAX_VALUE), randomTV(), randomTV());
}
@Override
protected Writeable.Reader<SqlTranslateAction.Request> instanceReader() {
return SqlTranslateAction.Request::new;
protected Writeable.Reader<SqlTranslateRequest> instanceReader() {
return SqlTranslateRequest::new;
}
private TimeValue randomTV() {
@ -60,14 +60,14 @@ public class SqlTranslateRequestTests extends AbstractSerializingTestCase<SqlTra
}
@Override
protected SqlTranslateAction.Request doParseInstance(XContentParser parser) {
return SqlTranslateAction.Request.fromXContent(parser, testMode);
protected SqlTranslateRequest doParseInstance(XContentParser parser) {
return SqlTranslateRequest.fromXContent(parser, testMode);
}
@Override
protected SqlTranslateAction.Request mutateInstance(SqlTranslateAction.Request instance) throws IOException {
protected SqlTranslateRequest mutateInstance(SqlTranslateRequest instance) throws IOException {
@SuppressWarnings("unchecked")
Consumer<SqlTranslateAction.Request> mutator = randomFrom(
Consumer<SqlTranslateRequest> mutator = randomFrom(
request -> request.query(randomValueOtherThan(request.query(), () -> randomAlphaOfLength(5))),
request -> request.timeZone(randomValueOtherThan(request.timeZone(), ESTestCase::randomDateTimeZone)),
request -> request.fetchSize(randomValueOtherThan(request.fetchSize(), () -> between(1, Integer.MAX_VALUE))),
@ -75,7 +75,7 @@ public class SqlTranslateRequestTests extends AbstractSerializingTestCase<SqlTra
request -> request.filter(randomValueOtherThan(request.filter(),
() -> request.filter() == null ? randomFilter(random()) : randomFilterOrNull(random())))
);
SqlTranslateAction.Request newRequest = new SqlTranslateAction.Request(instance.mode(), instance.query(), instance.filter(),
SqlTranslateRequest newRequest = new SqlTranslateRequest(instance.mode(), instance.query(), instance.filter(),
instance.timeZone(), instance.fetchSize(), instance.requestTimeout(), instance.pageTimeout());
mutator.accept(newRequest);
return newRequest;

View File

@ -9,10 +9,10 @@ import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.test.AbstractStreamableTestCase;
import org.elasticsearch.test.EqualsHashCodeTestUtils.MutateFunction;
public class SqlTranslateResponseTests extends AbstractStreamableTestCase<SqlTranslateAction.Response> {
public class SqlTranslateResponseTests extends AbstractStreamableTestCase<SqlTranslateResponse> {
@Override
protected SqlTranslateAction.Response createTestInstance() {
protected SqlTranslateResponse createTestInstance() {
SearchSourceBuilder s = new SearchSourceBuilder();
if (randomBoolean()) {
long docValues = iterations(5, 10);
@ -30,18 +30,18 @@ public class SqlTranslateResponseTests extends AbstractStreamableTestCase<SqlTra
s.fetchSource(randomBoolean()).from(randomInt(256)).explain(randomBoolean()).size(randomInt(256));
return new SqlTranslateAction.Response(s);
return new SqlTranslateResponse(s);
}
@Override
protected SqlTranslateAction.Response createBlankInstance() {
return new SqlTranslateAction.Response();
protected SqlTranslateResponse createBlankInstance() {
return new SqlTranslateResponse();
}
@Override
protected MutateFunction<SqlTranslateAction.Response> getMutateFunction() {
protected MutateFunction<SqlTranslateResponse> getMutateFunction() {
return response -> {
SqlTranslateAction.Response copy = getCopyFunction().copy(response);
SqlTranslateResponse copy = getCopyFunction().copy(response);
copy.source().size(randomValueOtherThan(response.source().size(), () -> between(0, Integer.MAX_VALUE)));
return copy;
};

View File

@ -4,8 +4,6 @@ dependencies {
compile project(':x-pack-elasticsearch:sql:rest-proto')
compile 'org.antlr:antlr4-runtime:4.5.3'
provided "org.elasticsearch:elasticsearch:${project.versions.elasticsearch}"
testCompile project(':x-pack-elasticsearch:sql:test-utils')
}
dependencyLicenses {

View File

@ -0,0 +1,45 @@
/*
* 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.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 java.io.IOException;
import static org.elasticsearch.rest.RestRequest.Method.GET;
import static org.elasticsearch.rest.RestRequest.Method.POST;
/**
* REST action for translating SQL queries into ES requests
*/
public class RestSqlTranslateAction extends BaseRestHandler {
public RestSqlTranslateAction(Settings settings, RestController controller) {
super(settings);
controller.registerHandler(GET, "/_xpack/sql/translate", this);
controller.registerHandler(POST, "/_xpack/sql/translate", this);
}
@Override
protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
SqlTranslateRequest sqlRequest;
try (XContentParser parser = request.contentOrSourceParamParser()) {
sqlRequest = SqlTranslateRequest.fromXContent(parser, AbstractSqlRequest.Mode.fromString(request.param("mode")));
}
return channel -> client.executeLocally(SqlTranslateAction.INSTANCE, sqlRequest, new RestToXContentListener<>(channel));
}
@Override
public String getName() {
return "sql_translate_action";
}
}

View File

@ -65,7 +65,7 @@ public class SqlPlugin implements ActionPlugin {
}
return Arrays.asList(new RestSqlQueryAction(settings, restController),
new SqlTranslateAction.RestAction(settings, restController),
new RestSqlTranslateAction(settings, restController),
new RestSqlClearCursorAction(settings, restController),
new RestSqlListTablesAction(settings, restController),
new RestSqlListColumnsAction(settings, restController));
@ -78,7 +78,7 @@ public class SqlPlugin implements ActionPlugin {
}
return Arrays.asList(new ActionHandler<>(SqlQueryAction.INSTANCE, TransportSqlQueryAction.class),
new ActionHandler<>(SqlTranslateAction.INSTANCE, SqlTranslateAction.TransportAction.class),
new ActionHandler<>(SqlTranslateAction.INSTANCE, TransportSqlTranslateAction.class),
new ActionHandler<>(SqlClearCursorAction.INSTANCE, TransportSqlClearCursorAction.class),
new ActionHandler<>(SqlListTablesAction.INSTANCE, TransportSqlListTablesAction.class),
new ActionHandler<>(SqlListColumnsAction.INSTANCE, TransportSqlListColumnsAction.class));

View File

@ -1,229 +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;
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.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.index.query.QueryBuilder;
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.session.Configuration;
import org.joda.time.DateTimeZone;
import java.io.IOException;
import java.util.Objects;
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.AbstractSqlQueryRequest.DEFAULT_FETCH_SIZE;
import static org.elasticsearch.xpack.sql.plugin.AbstractSqlQueryRequest.DEFAULT_PAGE_TIMEOUT;
import static org.elasticsearch.xpack.sql.plugin.AbstractSqlQueryRequest.DEFAULT_REQUEST_TIMEOUT;
import static org.elasticsearch.xpack.sql.plugin.AbstractSqlQueryRequest.DEFAULT_TIME_ZONE;
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 AbstractSqlQueryRequest {
private static final ObjectParser<Request, Void> PARSER = objectParser(Request::new);
public Request() {}
public Request(Mode mode, String query, QueryBuilder filter, DateTimeZone timeZone, int fetchSize, TimeValue requestTimeout,
TimeValue pageTimeout) {
super(mode, query, filter, timeZone, fetchSize, requestTimeout, pageTimeout);
}
public Request(StreamInput in) throws IOException {
super(in);
}
@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() + "][" + filter() + "]";
}
public static Request fromXContent(XContentParser parser, Mode mode) {
Request request = PARSER.apply(parser, null);
request.mode(mode);
return request;
}
}
public static class RequestBuilder extends ActionRequestBuilder<Request, Response, RequestBuilder> {
public RequestBuilder(ElasticsearchClient client, SqlTranslateAction action) {
this(client, action, AbstractSqlRequest.Mode.PLAIN, null, null, DEFAULT_TIME_ZONE, DEFAULT_FETCH_SIZE, DEFAULT_REQUEST_TIMEOUT,
DEFAULT_PAGE_TIMEOUT);
}
public RequestBuilder(ElasticsearchClient client, SqlTranslateAction action, AbstractSqlRequest.Mode mode, String query,
QueryBuilder filter, DateTimeZone timeZone, int fetchSize, TimeValue requestTimeout, TimeValue pageTimeout) {
super(client, action, new Request(mode, query, filter, 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,
Request::new, indexNameExpressionResolver);
this.planExecutor = planExecutor;
this.sqlLicenseChecker = sqlLicenseChecker;
}
@Override
protected void doExecute(Request request, ActionListener<Response> listener) {
sqlLicenseChecker.checkIfSqlAllowed(request.mode());
String query = request.query();
Configuration cfg = new Configuration(request.timeZone(), request.fetchSize(),
request.requestTimeout(), request.pageTimeout(), request.filter());
planExecutor.searchSource(query, cfg, ActionListener.wrap(
searchSourceBuilder -> listener.onResponse(new Response(searchSourceBuilder)), listener::onFailure));
}
}
public static class RestAction extends BaseRestHandler {
public RestAction(Settings settings, RestController controller) {
super(settings);
controller.registerHandler(GET, "/_xpack/sql/translate", this);
controller.registerHandler(POST, "/_xpack/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);
}
sqlRequest.mode(AbstractSqlRequest.Mode.fromString(request.param("mode")));
return channel -> client.executeLocally(SqlTranslateAction.INSTANCE, sqlRequest, new RestToXContentListener<>(channel));
}
@Override
public String getName() {
return "sql_translate_action";
}
}
}

View File

@ -0,0 +1,50 @@
/*
* 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.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.session.Configuration;
/**
* Transport action for translating SQL queries into ES requests
*/
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,
SqlTranslateRequest::new, indexNameExpressionResolver);
this.planExecutor = planExecutor;
this.sqlLicenseChecker = sqlLicenseChecker;
}
@Override
protected void doExecute(SqlTranslateRequest request, ActionListener<SqlTranslateResponse> listener) {
sqlLicenseChecker.checkIfSqlAllowed(request.mode());
String query = request.query();
Configuration cfg = new Configuration(request.timeZone(), request.fetchSize(),
request.requestTimeout(), request.pageTimeout(), request.filter());
planExecutor.searchSource(query, cfg, ActionListener.wrap(
searchSourceBuilder -> listener.onResponse(new SqlTranslateResponse(searchSourceBuilder)), listener::onFailure));
}
}

View File

@ -1,27 +0,0 @@
apply plugin: 'elasticsearch.build'
description = 'Shared test utilities for jdbc and cli protocol projects'
dependencies {
compile "junit:junit:${versions.junit}"
compile "org.hamcrest:hamcrest-all:${versions.hamcrest}"
compile "org.elasticsearch.test:framework:${versions.elasticsearch}"
}
thirdPartyAudit.excludes = [
// Referneced by the test:framework but not used
'org.apache.tools.ant.BuildException',
'org.apache.tools.ant.DirectoryScanner',
'org.apache.tools.ant.Task',
'org.apache.tools.ant.types.FileSet',
'org.easymock.EasyMock',
'org.easymock.IArgumentMatcher',
'org.jmock.core.Constraint',
]
/* Elasticsearch traditionally disables this for test utilities because it is
* hard to configure and (hopefully) much less important for tests than
* production code. */
dependencyLicenses.enabled = false
test.enabled = false