From 0dc40ec0dfe9232dea10d992c2ac46bd153cdbfd Mon Sep 17 00:00:00 2001 From: Abbas Hussain Date: Tue, 28 Apr 2020 12:42:04 -0700 Subject: [PATCH 01/14] Add cusror to JSONQueryResponse --- .../jdbc/protocol/QueryResponse.java | 2 ++ .../jdbc/protocol/http/JsonQueryResponse.java | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/QueryResponse.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/QueryResponse.java index dc16a76..c39e36c 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/QueryResponse.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/QueryResponse.java @@ -30,5 +30,7 @@ public interface QueryResponse { int getStatus(); + String getCursor(); + RequestError getError(); } diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonQueryResponse.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonQueryResponse.java index 6e8eaa7..f12823c 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonQueryResponse.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonQueryResponse.java @@ -41,6 +41,8 @@ public class JsonQueryResponse implements QueryResponse { private int status; + private String cursor; + private JsonRequestError error; @Override @@ -73,6 +75,10 @@ public void setStatus(int status) { this.status = status; } + public void setCursor(String cursor) { + this.cursor = cursor; + } + public void setError(JsonRequestError error) { this.error = error; } @@ -92,6 +98,11 @@ public int getStatus() { return status; } + @Override + public String getCursor() { + return cursor; + } + @Override public RequestError getError() { return error; @@ -105,6 +116,7 @@ public boolean equals(Object o) { return getSize() == response.getSize() && getTotal() == response.getTotal() && getStatus() == response.getStatus() && + getCursor() == response.getCursor() && Objects.equals(schema, response.schema) && Objects.equals(getDatarows(), response.getDatarows()) && Objects.equals(getError(), response.getError()); @@ -112,13 +124,14 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(schema, getDatarows(), getSize(), getTotal(), getStatus(), getError()); + return Objects.hash(schema, getDatarows(), getSize(), getTotal(), getStatus(), getCursor(), getError()); } @Override public String toString() { return "JsonQueryResponse{" + "schema=" + schema + + "cursor=" + cursor + ", datarows=" + datarows + ", size=" + size + ", total=" + total + From ebd27f39d48d6975c00affcddb94b8bf1c9d7c92 Mon Sep 17 00:00:00 2001 From: Abbas Hussain Date: Tue, 28 Apr 2020 12:45:09 -0700 Subject: [PATCH 02/14] Add fetchSize property --- .../jdbc/config/FetchSizeProperty.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/java/com/amazon/opendistroforelasticsearch/jdbc/config/FetchSizeProperty.java diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/config/FetchSizeProperty.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/config/FetchSizeProperty.java new file mode 100644 index 0000000..cc632dc --- /dev/null +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/config/FetchSizeProperty.java @@ -0,0 +1,14 @@ +package com.amazon.opendistroforelasticsearch.jdbc.config; + +public class FetchSizeProperty extends IntConnectionProperty{ + + public static final String KEY = "fetchSize"; + + public FetchSizeProperty() { + super(KEY); + } + + public Integer getDefault() { + return 0; + } +} From 2336e1fd2904341f1243a39b34b41059a3b0eba8 Mon Sep 17 00:00:00 2001 From: Abbas Hussain Date: Tue, 28 Apr 2020 14:10:04 -0700 Subject: [PATCH 03/14] Add fetchSize property to connection configuration --- .../jdbc/config/ConnectionConfig.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/config/ConnectionConfig.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/config/ConnectionConfig.java index 78b5489..ecd8133 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/config/ConnectionConfig.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/config/ConnectionConfig.java @@ -34,6 +34,7 @@ public class ConnectionConfig { private String url; private String host; private int port; + private int fetchSize; private String path; private boolean useSSL; private int loginTimeout; @@ -60,6 +61,7 @@ private ConnectionConfig(Builder builder) { this.url = builder.getUrl(); this.host = builder.getHostProperty().getValue(); this.port = builder.getPortProperty().getValue(); + this.fetchSize = builder.getFetchSizeProperty().getValue(); this.path = builder.getPathProperty().getValue(); this.useSSL = builder.getUseSSLProperty().getValue(); @@ -106,6 +108,10 @@ public int getPort() { return port; } + public int getFetchSize() { + return fetchSize; + } + public String getPath() { return path; } @@ -192,6 +198,7 @@ public String toString() { "url='" + url + '\'' + ", host='" + host + '\'' + ", port=" + port + + ", fetchSize=" + fetchSize + ", path='" + path + '\'' + ", useSSL=" + useSSL + ", loginTimeout=" + loginTimeout + @@ -223,6 +230,7 @@ public static class Builder { private HostConnectionProperty hostProperty = new HostConnectionProperty(); private PortConnectionProperty portProperty = new PortConnectionProperty(); + private FetchSizeProperty fetchSizeProperty = new FetchSizeProperty(); private LoginTimeoutConnectionProperty loginTimeoutProperty = new LoginTimeoutConnectionProperty(); private UseSSLConnectionProperty useSSLProperty = new UseSSLConnectionProperty(); private PathConnectionProperty pathProperty = new PathConnectionProperty(); @@ -261,6 +269,7 @@ public static class Builder { ConnectionProperty[] connectionProperties = new ConnectionProperty[]{ hostProperty, portProperty, + fetchSizeProperty, loginTimeoutProperty, useSSLProperty, pathProperty, @@ -302,6 +311,10 @@ public PortConnectionProperty getPortProperty() { return portProperty; } + public FetchSizeProperty getFetchSizeProperty() { + return fetchSizeProperty; + } + public LoginTimeoutConnectionProperty getLoginTimeoutProperty() { return loginTimeoutProperty; } @@ -519,6 +532,11 @@ private void validateConfig() throws ConnectionPropertyException { // change the default port to use to 443 portProperty.setRawValue(443); } + + if (fetchSizeProperty.getValue() < 0) { + throw new ConnectionPropertyException(fetchSizeProperty.getKey(), + "Cursor fetch size value should be greater or equal to zero"); + } } /** From 43bba4bf89d487313661d30e21ad8031bfa84bda Mon Sep 17 00:00:00 2001 From: Abbas Hussain Date: Fri, 1 May 2020 15:06:18 -0700 Subject: [PATCH 04/14] Use user fetchSize to retrieve query results --- .../jdbc/ConnectionImpl.java | 6 ++ .../jdbc/PreparedStatementImpl.java | 10 ++- .../jdbc/ResultSetImpl.java | 63 +++++++++++++++++-- .../jdbc/StatementImpl.java | 14 ++++- .../jdbc/protocol/JdbcQueryRequest.java | 11 +++- .../protocol/http/JdbcCursorQueryRequest.java | 59 +++++++++++++++++ .../protocol/http/JsonCursorHttpProtocol.java | 49 +++++++++++++++ .../http/JsonCursorHttpProtocolFactory.java | 19 ++++++ .../protocol/http/JsonCursorQueryRequest.java | 39 ++++++++++++ .../jdbc/protocol/http/JsonHttpProtocol.java | 16 +++-- .../jdbc/protocol/http/JsonQueryRequest.java | 9 ++- 11 files changed, 276 insertions(+), 19 deletions(-) create mode 100644 src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JdbcCursorQueryRequest.java create mode 100644 src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocol.java create mode 100644 src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocolFactory.java create mode 100644 src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequest.java diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/ConnectionImpl.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/ConnectionImpl.java index 6d4885c..7a5fce4 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/ConnectionImpl.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/ConnectionImpl.java @@ -60,6 +60,7 @@ public class ConnectionImpl implements ElasticsearchConnection, JdbcWrapper, Log private String url; private String user; private Logger log; + private int fetchSize; private boolean open = false; private Transport transport; private Protocol protocol; @@ -74,6 +75,7 @@ public ConnectionImpl(ConnectionConfig connectionConfig, TransportFactory transp this.log = log; this.url = connectionConfig.getUrl(); this.user = connectionConfig.getUser(); + this.fetchSize = connectionConfig.getFetchSize(); try { this.transport = transportFactory.getTransport(connectionConfig, log, getUserAgent()); @@ -101,6 +103,10 @@ public String getUser() { return user; } + public int getFetchSize() { + return fetchSize; + } + @Override public Statement createStatement() throws SQLException { log.debug(() -> logEntry("createStatement()")); diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/PreparedStatementImpl.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/PreparedStatementImpl.java index 15410b3..8bfdd5a 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/PreparedStatementImpl.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/PreparedStatementImpl.java @@ -75,11 +75,19 @@ public PreparedStatementImpl(ConnectionImpl connection, String sql, Logger log) public ResultSet executeQuery() throws SQLException { log.debug(() -> logEntry("executeQuery()")); checkOpen(); - ResultSet rs = executeQueryX(); + ResultSet rs = executeQueryXWithFetchSize(getFetchSize()); log.debug(() -> logExit("executeQuery", rs)); return rs; } + protected ResultSet executeQueryXWithFetchSize(int fetchSize) throws SQLException { + checkParamsFilled(); + JdbcQueryRequest jdbcQueryRequest = new JdbcQueryRequest(sql, fetchSize); + jdbcQueryRequest.setParameters(Arrays.asList(parameters)); + return executeQueryRequest(jdbcQueryRequest); + } + + protected ResultSet executeQueryX() throws SQLException { checkParamsFilled(); JdbcQueryRequest jdbcQueryRequest = new JdbcQueryRequest(sql); diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/ResultSetImpl.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/ResultSetImpl.java index 097c641..7e8713a 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/ResultSetImpl.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/ResultSetImpl.java @@ -26,10 +26,17 @@ import com.amazon.opendistroforelasticsearch.jdbc.protocol.ColumnDescriptor; import com.amazon.opendistroforelasticsearch.jdbc.internal.JdbcWrapper; import com.amazon.opendistroforelasticsearch.jdbc.protocol.QueryResponse; +import com.amazon.opendistroforelasticsearch.jdbc.protocol.exceptions.InternalServerErrorException; +import com.amazon.opendistroforelasticsearch.jdbc.protocol.exceptions.ResponseException; +import com.amazon.opendistroforelasticsearch.jdbc.protocol.http.JdbcCursorQueryRequest; +import com.amazon.opendistroforelasticsearch.jdbc.protocol.http.JsonCursorHttpProtocol; +import com.amazon.opendistroforelasticsearch.jdbc.protocol.http.JsonCursorHttpProtocolFactory; +import com.amazon.opendistroforelasticsearch.jdbc.transport.http.HttpTransport; import com.amazon.opendistroforelasticsearch.jdbc.types.TypeConverter; import com.amazon.opendistroforelasticsearch.jdbc.types.TypeConverters; import com.amazon.opendistroforelasticsearch.jdbc.types.UnrecognizedElasticsearchTypeException; +import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.math.BigDecimal; @@ -71,6 +78,7 @@ public class ResultSetImpl implements ResultSet, JdbcWrapper, LoggingSource { private StatementImpl statement; protected Cursor cursor; + private String cursorId; private boolean open = false; private boolean wasNull = false; private boolean afterLast = false; @@ -78,11 +86,16 @@ public class ResultSetImpl implements ResultSet, JdbcWrapper, LoggingSource { private Logger log; public ResultSetImpl(StatementImpl statement, QueryResponse queryResponse, Logger log) throws SQLException { - this(statement, queryResponse.getColumnDescriptors(), queryResponse.getDatarows(), log); + this(statement, queryResponse.getColumnDescriptors(), queryResponse.getDatarows(), queryResponse.getCursor(), log); } public ResultSetImpl(StatementImpl statement, List columnDescriptors, List> dataRows, Logger log) throws SQLException { + this(statement, columnDescriptors, dataRows, null, log); + } + + public ResultSetImpl(StatementImpl statement, List columnDescriptors, + List> dataRows, String cursorId, Logger log) throws SQLException { this.statement = statement; this.log = log; @@ -93,12 +106,10 @@ public ResultSetImpl(StatementImpl statement, List c .map(ColumnMetaData::new) .collect(Collectors.toList())); - List rows = dataRows - .parallelStream() - .map(Row::new) - .collect(Collectors.toList()); + List rows = getRowsFromDataRows(dataRows); this.cursor = new Cursor(schema, rows); + this.cursorId = cursorId; this.open = true; } catch (UnrecognizedElasticsearchTypeException ex) { @@ -112,15 +123,55 @@ public boolean next() throws SQLException { log.debug(() -> logEntry("next()")); checkOpen(); boolean next = cursor.next(); + + if (!next && this.cursorId != null) { + // TODO: add debug logs around here + buildNextPageFromCursorId(); + next = cursor.next(); + } + if (next) { beforeFirst = false; } else { afterLast = true; } - log.debug(() -> logExit("next", next)); + boolean finalNext = next; + log.debug(() -> logExit("next", finalNext)); return next; } + + protected void buildNextPageFromCursorId() throws SQLException { + try { + JdbcCursorQueryRequest jdbcCursorQueryRequest = new JdbcCursorQueryRequest(this.cursorId); + JsonCursorHttpProtocolFactory protocolFactory = JsonCursorHttpProtocolFactory.INSTANCE; + ConnectionImpl connection = (ConnectionImpl) statement.getConnection(); + + JsonCursorHttpProtocol protocol = protocolFactory.getProtocol(null, (HttpTransport) connection.getTransport()); + QueryResponse queryResponse = protocol.execute(jdbcCursorQueryRequest); + + if (queryResponse.getError() != null) { + throw new InternalServerErrorException( + queryResponse.getError().getReason(), + queryResponse.getError().getType(), + queryResponse.getError().getDetails()); + } + + cursor = new Cursor(cursor.getSchema(), getRowsFromDataRows(queryResponse.getDatarows())); + cursorId = queryResponse.getCursor(); + + } catch (ResponseException | IOException ex) { + logAndThrowSQLException(log, new SQLException("Error executing cursor query", ex)); + } + } + + private List getRowsFromDataRows(List> dataRows) { + return dataRows + .parallelStream() + .map(Row::new) + .collect(Collectors.toList()); + } + @Override public void close() throws SQLException { log.debug(() -> logEntry("close()")); diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/StatementImpl.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/StatementImpl.java index 2d39cde..a9976b2 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/StatementImpl.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/StatementImpl.java @@ -24,6 +24,7 @@ import com.amazon.opendistroforelasticsearch.jdbc.protocol.exceptions.InternalServerErrorException; import com.amazon.opendistroforelasticsearch.jdbc.protocol.QueryResponse; import com.amazon.opendistroforelasticsearch.jdbc.protocol.exceptions.ResponseException; +import com.amazon.opendistroforelasticsearch.jdbc.protocol.http.JsonQueryResponse; import java.io.IOException; import java.sql.Connection; @@ -38,6 +39,7 @@ public class StatementImpl implements Statement, JdbcWrapper, LoggingSource { protected ConnectionImpl connection; protected boolean open = false; + protected int fetchSize; protected ResultSetImpl resultSet; protected Logger log; private boolean closeOnCompletion; @@ -45,13 +47,14 @@ public class StatementImpl implements Statement, JdbcWrapper, LoggingSource { public StatementImpl(ConnectionImpl connection, Logger log) { this.connection = connection; this.open = true; + this.fetchSize = connection.getFetchSize(); this.log = log; } @Override public ResultSet executeQuery(String sql) throws SQLException { log.debug(()-> logEntry("executeQuery (%s)", sql)); - ResultSet rs = executeQueryX(sql); + ResultSet rs = executeQueryXWithFetchSize(sql, fetchSize); log.debug(()-> logExit("executeQuery", rs)); return rs; } @@ -61,6 +64,11 @@ protected ResultSet executeQueryX(String sql) throws SQLException { return executeQueryRequest(jdbcQueryRequest); } + protected ResultSet executeQueryXWithFetchSize(String sql, int fetchSize) throws SQLException { + JdbcQueryRequest jdbcQueryRequest = new JdbcQueryRequest(sql, fetchSize); + return executeQueryRequest(jdbcQueryRequest); + } + protected ResultSet executeQueryRequest(JdbcQueryRequest jdbcQueryRequest) throws SQLException { // JDBC Spec: A ResultSet object is automatically closed when the Statement @@ -205,12 +213,12 @@ public int getFetchDirection() throws SQLException { @Override public void setFetchSize(int rows) throws SQLException { - + fetchSize = rows; } @Override public int getFetchSize() throws SQLException { - return 0; + return fetchSize; } @Override diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/JdbcQueryRequest.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/JdbcQueryRequest.java index 2cb2b37..1572521 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/JdbcQueryRequest.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/JdbcQueryRequest.java @@ -22,13 +22,19 @@ public class JdbcQueryRequest implements QueryRequest { String statement; - + int fetchSize; List parameters; public JdbcQueryRequest(String sql) { this.statement = sql; } + public JdbcQueryRequest(String sql, int fetchSize) { + this.statement = sql; + this.fetchSize = fetchSize; + } + + @Override public boolean equals(Object o) { if (this == o) return true; @@ -59,13 +65,14 @@ public void setParameters(List parameters) { @Override public int getFetchSize() { - return 0; + return fetchSize; } @Override public String toString() { return "JdbcQueryRequest{" + "statement='" + statement + '\'' + + ", fetchSize='" + fetchSize + '\'' + ", parameters=" + parameters + '}'; } diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JdbcCursorQueryRequest.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JdbcCursorQueryRequest.java new file mode 100644 index 0000000..0839db4 --- /dev/null +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JdbcCursorQueryRequest.java @@ -0,0 +1,59 @@ +package com.amazon.opendistroforelasticsearch.jdbc.protocol.http; + +import com.amazon.opendistroforelasticsearch.jdbc.protocol.JdbcQueryParam;; +import com.amazon.opendistroforelasticsearch.jdbc.protocol.QueryRequest; + + +import java.util.List; +import java.util.Objects; + +public class JdbcCursorQueryRequest implements QueryRequest { + + String cursor; + List parameters; + + public JdbcCursorQueryRequest(String cursor) { + this.cursor = cursor; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof JdbcCursorQueryRequest)) return false; + JdbcCursorQueryRequest that = (JdbcCursorQueryRequest) o; + return Objects.equals(cursor, that.cursor) && + Objects.equals(getParameters(), that.getParameters()); + } + + @Override + public int hashCode() { + return Objects.hash(cursor, getParameters()); + } + + @Override + public String getQuery() { + return cursor; + } + + @Override + public List getParameters() { + return parameters; + } + + public void setParameters(List parameters) { + this.parameters = parameters; + } + + @Override + public int getFetchSize() { + return 0; + } + + @Override + public String toString() { + return "JdbcQueryRequest{" + + "cursor='" + cursor + '\'' + + ", parameters=" + parameters + + '}'; + } +} diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocol.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocol.java new file mode 100644 index 0000000..17cef7b --- /dev/null +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocol.java @@ -0,0 +1,49 @@ +package com.amazon.opendistroforelasticsearch.jdbc.protocol.http; + +import com.amazon.opendistroforelasticsearch.jdbc.protocol.QueryRequest; +import com.amazon.opendistroforelasticsearch.jdbc.protocol.QueryResponse; +import com.amazon.opendistroforelasticsearch.jdbc.protocol.exceptions.ResponseException; +import com.amazon.opendistroforelasticsearch.jdbc.transport.http.HttpTransport; +import org.apache.http.client.methods.CloseableHttpResponse; + +import java.io.IOException; +import java.io.InputStream; + +public class JsonCursorHttpProtocol extends JsonHttpProtocol { + + public JsonCursorHttpProtocol(HttpTransport transport) { + this(transport, DEFAULT_SQL_CONTEXT_PATH); + } + + public JsonCursorHttpProtocol(HttpTransport transport, String sqlContextPath) { + super(transport, sqlContextPath); + } + + @Override + public QueryResponse execute(QueryRequest request) throws ResponseException, IOException { + try (CloseableHttpResponse response = getTransport().doPost( + getSqlContextPath(), + defaultJsonHeaders, + defaultJdbcParams, + buildQueryRequestBody(request), 0)) { + + return getJsonHttpResponseHandler().handleResponse(response, this::processQueryResponse); + + } + } + + private String buildQueryRequestBody(QueryRequest queryRequest) throws IOException { + String requestBody = null; + + JsonCursorQueryRequest jsonQueryRequest = new JsonCursorQueryRequest(queryRequest); + requestBody = mapper.writeValueAsString(jsonQueryRequest); + System.out.println("Cursor request body:" + requestBody); + + return requestBody; + } + + private JsonQueryResponse processQueryResponse(InputStream contentStream) throws IOException { + return mapper.readValue(contentStream, JsonQueryResponse.class); + } + +} diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocolFactory.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocolFactory.java new file mode 100644 index 0000000..2011222 --- /dev/null +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocolFactory.java @@ -0,0 +1,19 @@ +package com.amazon.opendistroforelasticsearch.jdbc.protocol.http; + +import com.amazon.opendistroforelasticsearch.jdbc.config.ConnectionConfig; +import com.amazon.opendistroforelasticsearch.jdbc.protocol.ProtocolFactory; +import com.amazon.opendistroforelasticsearch.jdbc.transport.http.HttpTransport; + +public class JsonCursorHttpProtocolFactory implements ProtocolFactory { + + public static JsonCursorHttpProtocolFactory INSTANCE = new JsonCursorHttpProtocolFactory(); + + private JsonCursorHttpProtocolFactory() { + + } + + @Override + public JsonCursorHttpProtocol getProtocol(ConnectionConfig connectionConfig, HttpTransport transport) { + return new JsonCursorHttpProtocol(transport); + } +} diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequest.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequest.java new file mode 100644 index 0000000..34c6ec7 --- /dev/null +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequest.java @@ -0,0 +1,39 @@ +package com.amazon.opendistroforelasticsearch.jdbc.protocol.http; + +import com.amazon.opendistroforelasticsearch.jdbc.protocol.Parameter; +import com.amazon.opendistroforelasticsearch.jdbc.protocol.QueryRequest; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +public class JsonCursorQueryRequest implements QueryRequest { + + private String cursor; + private List parameters; + + public JsonCursorQueryRequest(QueryRequest queryRequest) { + this.cursor = queryRequest.getQuery(); + this.parameters = queryRequest.getParameters(); + } + + + @JsonProperty("cursor") + @Override + public String getQuery() { + return cursor; + } + + @JsonInclude(JsonInclude.Include.NON_NULL) + @Override + public List getParameters() { + return parameters; + } + + @JsonIgnore + @Override + public int getFetchSize() { + return 0; + } +} diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonHttpProtocol.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonHttpProtocol.java index 5ad6dba..72117dc 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonHttpProtocol.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonHttpProtocol.java @@ -32,6 +32,7 @@ import java.io.IOException; import java.io.InputStream; +import java.util.Map; public class JsonHttpProtocol implements Protocol { @@ -42,11 +43,11 @@ public class JsonHttpProtocol implements Protocol { private static final Header acceptJson = new BasicHeader(HttpHeaders.ACCEPT, "application/json"); private static final Header contentTypeJson = new BasicHeader(HttpHeaders.CONTENT_TYPE, "application/json"); private static final HttpParam requestJdbcFormatParam = new HttpParam("format", "jdbc"); - private static final Header[] defaultJsonHeaders = new Header[]{acceptJson, contentTypeJson}; + protected static final Header[] defaultJsonHeaders = new Header[]{acceptJson, contentTypeJson}; private static final Header[] defaultEmptyRequestBodyJsonHeaders = new Header[]{acceptJson}; - private static final HttpParam[] defaultJdbcParams = new HttpParam[]{requestJdbcFormatParam}; + protected static final HttpParam[] defaultJdbcParams = new HttpParam[]{requestJdbcFormatParam}; - private static final ObjectMapper mapper = new ObjectMapper(); + protected static final ObjectMapper mapper = new ObjectMapper(); private String sqlContextPath; private HttpTransport transport; private JsonHttpResponseHandler jsonHttpResponseHandler; @@ -65,6 +66,14 @@ public String getSqlContextPath() { return sqlContextPath; } + public HttpTransport getTransport() { + return this.transport; + } + + public JsonHttpResponseHandler getJsonHttpResponseHandler() { + return this.jsonHttpResponseHandler; + } + @Override public ConnectionResponse connect(int timeout) throws ResponseException, IOException { try (CloseableHttpResponse response = transport.doGet( @@ -95,7 +104,6 @@ private String buildQueryRequestBody(QueryRequest queryRequest) throws IOExcepti JsonQueryRequest jsonQueryRequest = new JsonQueryRequest(queryRequest); requestBody = mapper.writeValueAsString(jsonQueryRequest); - return requestBody; } diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonQueryRequest.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonQueryRequest.java index e49f2c6..b79eb5c 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonQueryRequest.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonQueryRequest.java @@ -18,20 +18,23 @@ import com.amazon.opendistroforelasticsearch.jdbc.protocol.Parameter; import com.amazon.opendistroforelasticsearch.jdbc.protocol.QueryRequest; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; public class JsonQueryRequest implements QueryRequest { private String query; + private int fetchSize; private List parameters; public JsonQueryRequest(QueryRequest queryRequest) { this.query = queryRequest.getQuery(); this.parameters = queryRequest.getParameters(); + this.fetchSize = queryRequest.getFetchSize(); + } @Override @@ -45,9 +48,9 @@ public List getParameters() { return parameters; } - @JsonIgnore + @JsonProperty("fetch_size") @Override public int getFetchSize() { - return 0; + return fetchSize; } } From 1ee34ac33eeebed28c02ba98a0f24e061abb6083 Mon Sep 17 00:00:00 2001 From: Abbas Hussain Date: Fri, 1 May 2020 15:12:20 -0700 Subject: [PATCH 05/14] Add unit test for fetch size validation --- .../jdbc/config/ConnectionConfigTests.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/test/java/com/amazon/opendistroforelasticsearch/jdbc/config/ConnectionConfigTests.java b/src/test/java/com/amazon/opendistroforelasticsearch/jdbc/config/ConnectionConfigTests.java index 27de6de..fbd6116 100644 --- a/src/test/java/com/amazon/opendistroforelasticsearch/jdbc/config/ConnectionConfigTests.java +++ b/src/test/java/com/amazon/opendistroforelasticsearch/jdbc/config/ConnectionConfigTests.java @@ -95,6 +95,24 @@ void testPortConfig() { PortConnectionProperty.KEY, ConnectionConfig::getPort, "9400", 9400); } + @Test + void testFetchSizeConfig() { + // exception with invalid values + assertPropertyRejects(FetchSizeProperty.KEY, + "invalidValue", + -1, + "-1", + "3.14"); + + // valid values + assertPropertyAccepts(FetchSizeProperty.KEY, ConnectionConfig::getFetchSize, + 500, + 0); + + assertPropertyAcceptsParsedValue( + FetchSizeProperty.KEY, ConnectionConfig::getFetchSize, "25", 25); + } + @Test void testPathConfig() { // exception with invalid values @@ -873,6 +891,7 @@ private void verifyDefaults(ConnectionConfig connectionConfig) { // verify defaults assertEquals(9200, connectionConfig.getPort()); assertEquals("", connectionConfig.getPath()); + assertEquals(0, connectionConfig.getFetchSize()); assertEquals("localhost", connectionConfig.getHost()); assertEquals(0, connectionConfig.getLoginTimeout()); assertFalse(connectionConfig.isUseSSL()); From 077d02721acf65ebbb3ff59c0e22d2724045f2c4 Mon Sep 17 00:00:00 2001 From: Abbas Hussain Date: Fri, 1 May 2020 15:46:15 -0700 Subject: [PATCH 06/14] Add fetchSize property documentation --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d5f4d2a..be2bb4e 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ To setup a connection, the driver requires a JDBC connection URL. The connection | ------------- |-------------| -----|---------| | user | Connection username. mandatory if `auth` property selects a authentication scheme that mandates a username value | any string | `null` | | password | Connection password. mandatory if `auth` property selects a authentication scheme that mandates a password value | any string | `null` | + | fetchSize | Cursor page size | positive integer value. Max value is limited by `index.max_result_window` Elasticsearch setting | `0` (for non-paginated response) | | logOutput | location where driver logs should be emitted | a valid file path | `null` (logs are disabled) | | logLevel | severity level for which driver logs should be emitted | in order from highest(least logging) to lowest(most logging): OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE, ALL | OFF (logs are disabled) | | auth | authentication mechanism to use | `NONE` (no auth), `BASIC` (HTTP Basic), `AWS_SIGV4` (AWS SIGV4) | `basic` if username and/or password is specified, `NONE` otherwise | From 85b30bec615294d8289e9df183ed3fcf208aeb69 Mon Sep 17 00:00:00 2001 From: Abbas Hussain Date: Mon, 4 May 2020 14:25:27 -0700 Subject: [PATCH 07/14] Address comments --- .../opendistroforelasticsearch/jdbc/ResultSetImpl.java | 3 ++- .../jdbc/protocol/JdbcQueryRequest.java | 4 ++-- .../jdbc/protocol/http/JsonCursorHttpProtocol.java | 6 +----- .../jdbc/protocol/http/JsonCursorQueryRequest.java | 2 +- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/ResultSetImpl.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/ResultSetImpl.java index 7e8713a..cc1b8a3 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/ResultSetImpl.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/ResultSetImpl.java @@ -125,8 +125,9 @@ public boolean next() throws SQLException { boolean next = cursor.next(); if (!next && this.cursorId != null) { - // TODO: add debug logs around here + log.debug(() -> logEntry("buildNextPageFromCursorId()")); buildNextPageFromCursorId(); + log.debug(() -> logExit("buildNextPageFromCursorId()")); next = cursor.next(); } diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/JdbcQueryRequest.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/JdbcQueryRequest.java index 1572521..cdd3a0f 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/JdbcQueryRequest.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/JdbcQueryRequest.java @@ -21,8 +21,8 @@ public class JdbcQueryRequest implements QueryRequest { - String statement; - int fetchSize; + private String statement; + private int fetchSize; List parameters; public JdbcQueryRequest(String sql) { diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocol.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocol.java index 17cef7b..3e02438 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocol.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocol.java @@ -33,12 +33,8 @@ public QueryResponse execute(QueryRequest request) throws ResponseException, IOE } private String buildQueryRequestBody(QueryRequest queryRequest) throws IOException { - String requestBody = null; - JsonCursorQueryRequest jsonQueryRequest = new JsonCursorQueryRequest(queryRequest); - requestBody = mapper.writeValueAsString(jsonQueryRequest); - System.out.println("Cursor request body:" + requestBody); - + String requestBody = mapper.writeValueAsString(jsonQueryRequest); return requestBody; } diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequest.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequest.java index 34c6ec7..b4e7133 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequest.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequest.java @@ -10,7 +10,7 @@ public class JsonCursorQueryRequest implements QueryRequest { - private String cursor; + private final String cursor; private List parameters; public JsonCursorQueryRequest(QueryRequest queryRequest) { From a4c3b68b16047816d5a080495463490c0bd74b19 Mon Sep 17 00:00:00 2001 From: Abbas Hussain Date: Tue, 5 May 2020 00:42:46 -0700 Subject: [PATCH 08/14] Refactor --- .../jdbc/PreparedStatementImpl.java | 14 +++----------- .../jdbc/StatementImpl.java | 14 ++++---------- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/PreparedStatementImpl.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/PreparedStatementImpl.java index 8bfdd5a..ae83d11 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/PreparedStatementImpl.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/PreparedStatementImpl.java @@ -75,26 +75,18 @@ public PreparedStatementImpl(ConnectionImpl connection, String sql, Logger log) public ResultSet executeQuery() throws SQLException { log.debug(() -> logEntry("executeQuery()")); checkOpen(); - ResultSet rs = executeQueryXWithFetchSize(getFetchSize()); + ResultSet rs = executeQueryX(getFetchSize()); log.debug(() -> logExit("executeQuery", rs)); return rs; } - protected ResultSet executeQueryXWithFetchSize(int fetchSize) throws SQLException { + protected ResultSet executeQueryX(int fetchSize) throws SQLException { checkParamsFilled(); JdbcQueryRequest jdbcQueryRequest = new JdbcQueryRequest(sql, fetchSize); jdbcQueryRequest.setParameters(Arrays.asList(parameters)); return executeQueryRequest(jdbcQueryRequest); } - - protected ResultSet executeQueryX() throws SQLException { - checkParamsFilled(); - JdbcQueryRequest jdbcQueryRequest = new JdbcQueryRequest(sql); - jdbcQueryRequest.setParameters(Arrays.asList(parameters)); - return executeQueryRequest(jdbcQueryRequest); - } - @Override public int executeUpdate() throws SQLException { throw new SQLFeatureNotSupportedException("Updates are not supported"); @@ -301,7 +293,7 @@ private int javaToSqlType(Object x) throws SQLException { public boolean execute() throws SQLException { log.debug(() -> logEntry("execute()")); checkOpen(); - executeQueryX(); + executeQueryX(getFetchSize()); log.debug(() -> logExit("execute", true)); return true; } diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/StatementImpl.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/StatementImpl.java index a9976b2..dae35b7 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/StatementImpl.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/StatementImpl.java @@ -24,7 +24,6 @@ import com.amazon.opendistroforelasticsearch.jdbc.protocol.exceptions.InternalServerErrorException; import com.amazon.opendistroforelasticsearch.jdbc.protocol.QueryResponse; import com.amazon.opendistroforelasticsearch.jdbc.protocol.exceptions.ResponseException; -import com.amazon.opendistroforelasticsearch.jdbc.protocol.http.JsonQueryResponse; import java.io.IOException; import java.sql.Connection; @@ -54,17 +53,12 @@ public StatementImpl(ConnectionImpl connection, Logger log) { @Override public ResultSet executeQuery(String sql) throws SQLException { log.debug(()-> logEntry("executeQuery (%s)", sql)); - ResultSet rs = executeQueryXWithFetchSize(sql, fetchSize); + ResultSet rs = executeQueryX(sql, fetchSize); log.debug(()-> logExit("executeQuery", rs)); return rs; } - protected ResultSet executeQueryX(String sql) throws SQLException { - JdbcQueryRequest jdbcQueryRequest = new JdbcQueryRequest(sql); - return executeQueryRequest(jdbcQueryRequest); - } - - protected ResultSet executeQueryXWithFetchSize(String sql, int fetchSize) throws SQLException { + protected ResultSet executeQueryX(String sql, int fetchSize) throws SQLException { JdbcQueryRequest jdbcQueryRequest = new JdbcQueryRequest(sql, fetchSize); return executeQueryRequest(jdbcQueryRequest); } @@ -175,7 +169,7 @@ public void setCursorName(String name) throws SQLException { public boolean execute(String sql) throws SQLException { log.debug(()->logEntry("execute (%s)", sql)); checkOpen(); - executeQueryX(sql); + executeQueryX(sql, fetchSize); log.debug(() -> logExit("execute", true)); return true; } @@ -283,7 +277,7 @@ public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { if (autoGeneratedKeys != Statement.NO_GENERATED_KEYS) { throw new SQLNonTransientException("Auto generated keys are not supported"); } - executeQueryX(sql); + executeQueryX(sql, fetchSize); log.debug(() -> logExit("execute", true)); return true; } From 1720414c9319c64d87787cf36a65953339ec0a1d Mon Sep 17 00:00:00 2001 From: Abbas Hussain Date: Tue, 5 May 2020 10:15:27 -0700 Subject: [PATCH 09/14] Add jacoco test coverage --- build.gradle | 22 +++++++++++++++++++ .../jdbc/config/FetchSizeProperty.java | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 22f91c2..6fbe31e 100644 --- a/build.gradle +++ b/build.gradle @@ -184,3 +184,25 @@ signing { sign publishing.publications.shadow } +jacoco { + toolVersion = "0.8.3" +} + +jacocoTestReport { + reports { + html.enabled true + } +} +test.finalizedBy(project.tasks.jacocoTestReport) + +jacocoTestCoverageVerification { + violationRules { + rule { + limit { + minimum = 0.4 + } + } + } +} + +check.dependsOn jacocoTestCoverageVerification diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/config/FetchSizeProperty.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/config/FetchSizeProperty.java index cc632dc..5075786 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/config/FetchSizeProperty.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/config/FetchSizeProperty.java @@ -1,6 +1,6 @@ package com.amazon.opendistroforelasticsearch.jdbc.config; -public class FetchSizeProperty extends IntConnectionProperty{ +public class FetchSizeProperty extends IntConnectionProperty { public static final String KEY = "fetchSize"; From dafdee78337459d2e49cac5ae04d5c7920df3815 Mon Sep 17 00:00:00 2001 From: Abbas Hussain Date: Thu, 7 May 2020 02:59:59 -0700 Subject: [PATCH 10/14] Add unit tests on effective fetchSize value --- .../jdbc/PreparedStatementTests.java | 51 +++++++++++++++++++ .../jdbc/StatementTests.java | 51 +++++++++++++++++++ 2 files changed, 102 insertions(+) diff --git a/src/test/java/com/amazon/opendistroforelasticsearch/jdbc/PreparedStatementTests.java b/src/test/java/com/amazon/opendistroforelasticsearch/jdbc/PreparedStatementTests.java index a2e94d9..eacec90 100644 --- a/src/test/java/com/amazon/opendistroforelasticsearch/jdbc/PreparedStatementTests.java +++ b/src/test/java/com/amazon/opendistroforelasticsearch/jdbc/PreparedStatementTests.java @@ -25,9 +25,11 @@ import java.sql.SQLNonTransientException; import java.util.Arrays; import java.util.Objects; +import java.util.Properties; import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; @@ -139,4 +141,53 @@ private Connection getMockConnection() throws IOException, ResponseException, SQ return con; } + @Test + void testEffectiveFetchSizeOnPreparedStatement() throws ResponseException, IOException, SQLException { + + TransportFactory tf = mock(TransportFactory.class); + ProtocolFactory pf = mock(ProtocolFactory.class); + Protocol mockProtocol = mock(Protocol.class); + + when(mockProtocol.connect(anyInt())).thenReturn(mock(ConnectionResponse.class)); + + when(tf.getTransport(any(), any(), any())) + .thenReturn(mock(Transport.class)); + + when(pf.getProtocol(any(ConnectionConfig.class), any(Transport.class))) + .thenReturn(mockProtocol); + + when(mockProtocol.execute(any(QueryRequest.class))) + .thenReturn(mock(QueryResponse.class)); + + String url = "jdbc:elasticsearch://localhost:9200?fetchSize=400"; + + ConnectionConfig connectionConfig = ConnectionConfig.builder().setUrl(url).build(); + Connection con = new ConnectionImpl(connectionConfig, tf, pf, NoOpLogger.INSTANCE); + PreparedStatement st = con.prepareStatement(sql); + assertEquals(st.getFetchSize(), 400); + st.close(); + con.close(); + + // Properties override connection string fetchSize + Properties properties = new Properties(); + properties.setProperty("fetchSize", "5000"); + connectionConfig = ConnectionConfig.builder().setUrl(url).setProperties(properties).build(); + con = new ConnectionImpl(connectionConfig, tf, pf, NoOpLogger.INSTANCE); + st = con.prepareStatement(sql); + assertEquals(st.getFetchSize(), 5000); + st.close(); + con.close(); + + + // setFetchSize overrides fetchSize set anywhere + connectionConfig = ConnectionConfig.builder().setUrl(url).setProperties(properties).build(); + con = new ConnectionImpl(connectionConfig, tf, pf, NoOpLogger.INSTANCE); + st = con.prepareStatement(sql); + st.setFetchSize(200); + assertEquals(st.getFetchSize(), 200); + st.close(); + con.close(); + + } + } diff --git a/src/test/java/com/amazon/opendistroforelasticsearch/jdbc/StatementTests.java b/src/test/java/com/amazon/opendistroforelasticsearch/jdbc/StatementTests.java index 8029ecb..d333b62 100644 --- a/src/test/java/com/amazon/opendistroforelasticsearch/jdbc/StatementTests.java +++ b/src/test/java/com/amazon/opendistroforelasticsearch/jdbc/StatementTests.java @@ -40,6 +40,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import java.util.Properties; import static com.github.tomakehurst.wiremock.client.WireMock.get; @@ -91,6 +92,56 @@ void testQueryRequest() throws ResponseException, IOException, SQLException { con.close(); } + + @Test + void testEffectiveFetchSizeOnStatement() throws ResponseException, IOException, SQLException { + + TransportFactory tf = mock(TransportFactory.class); + ProtocolFactory pf = mock(ProtocolFactory.class); + Protocol mockProtocol = mock(Protocol.class); + + when(mockProtocol.connect(anyInt())).thenReturn(mock(ConnectionResponse.class)); + + when(tf.getTransport(any(), any(), any())) + .thenReturn(mock(Transport.class)); + + when(pf.getProtocol(any(ConnectionConfig.class), any(Transport.class))) + .thenReturn(mockProtocol); + + when(mockProtocol.execute(any(QueryRequest.class))) + .thenReturn(mock(QueryResponse.class)); + + String url = "jdbc:elasticsearch://localhost:9200?fetchSize=400"; + + ConnectionConfig connectionConfig = ConnectionConfig.builder().setUrl(url).build(); + Connection con = new ConnectionImpl(connectionConfig, tf, pf, NoOpLogger.INSTANCE); + Statement st = con.createStatement(); + assertEquals(st.getFetchSize(), 400); + st.close(); + con.close(); + + // Properties override connection string fetchSize + Properties properties = new Properties(); + properties.setProperty("fetchSize", "5000"); + connectionConfig = ConnectionConfig.builder().setUrl(url).setProperties(properties).build(); + con = new ConnectionImpl(connectionConfig, tf, pf, NoOpLogger.INSTANCE); + st = con.createStatement(); + assertEquals(st.getFetchSize(), 5000); + st.close(); + con.close(); + + + // setFetchSize overrides fetchSize set anywhere + connectionConfig = ConnectionConfig.builder().setUrl(url).setProperties(properties).build(); + con = new ConnectionImpl(connectionConfig, tf, pf, NoOpLogger.INSTANCE); + st = con.createStatement(); + st.setFetchSize(200); + assertEquals(st.getFetchSize(), 200); + st.close(); + con.close(); + + } + @Test void testQueryInternalServerError(WireMockServer mockServer) throws SQLException, IOException { QueryMock queryMock = new QueryMock.NycTaxisQueryInternalErrorMock(); From 3d30396b479c0ab5f6a7a990bf7789ec6acd9cd2 Mon Sep 17 00:00:00 2001 From: Abbas Hussain Date: Thu, 7 May 2020 11:58:06 -0700 Subject: [PATCH 11/14] Refactor --- .../jdbc/config/FetchSizeProperty.java | 4 ---- .../jdbc/protocol/http/JdbcCursorQueryRequest.java | 8 +------- .../jdbc/protocol/http/JsonCursorQueryRequest.java | 8 ++------ .../jdbc/protocol/http/JsonHttpProtocol.java | 4 +--- 4 files changed, 4 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/config/FetchSizeProperty.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/config/FetchSizeProperty.java index 5075786..baf75d8 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/config/FetchSizeProperty.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/config/FetchSizeProperty.java @@ -7,8 +7,4 @@ public class FetchSizeProperty extends IntConnectionProperty { public FetchSizeProperty() { super(KEY); } - - public Integer getDefault() { - return 0; - } } diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JdbcCursorQueryRequest.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JdbcCursorQueryRequest.java index 0839db4..b831c37 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JdbcCursorQueryRequest.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JdbcCursorQueryRequest.java @@ -10,7 +10,6 @@ public class JdbcCursorQueryRequest implements QueryRequest { String cursor; - List parameters; public JdbcCursorQueryRequest(String cursor) { this.cursor = cursor; @@ -37,11 +36,7 @@ public String getQuery() { @Override public List getParameters() { - return parameters; - } - - public void setParameters(List parameters) { - this.parameters = parameters; + return null; } @Override @@ -53,7 +48,6 @@ public int getFetchSize() { public String toString() { return "JdbcQueryRequest{" + "cursor='" + cursor + '\'' + - ", parameters=" + parameters + '}'; } } diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequest.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequest.java index b4e7133..4a7fb5a 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequest.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequest.java @@ -3,7 +3,6 @@ import com.amazon.opendistroforelasticsearch.jdbc.protocol.Parameter; import com.amazon.opendistroforelasticsearch.jdbc.protocol.QueryRequest; import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; @@ -11,24 +10,21 @@ public class JsonCursorQueryRequest implements QueryRequest { private final String cursor; - private List parameters; public JsonCursorQueryRequest(QueryRequest queryRequest) { this.cursor = queryRequest.getQuery(); - this.parameters = queryRequest.getParameters(); } - @JsonProperty("cursor") @Override public String getQuery() { return cursor; } - @JsonInclude(JsonInclude.Include.NON_NULL) + @JsonIgnore @Override public List getParameters() { - return parameters; + return null; } @JsonIgnore diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonHttpProtocol.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonHttpProtocol.java index 72117dc..a445d58 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonHttpProtocol.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonHttpProtocol.java @@ -100,10 +100,8 @@ public QueryResponse execute(QueryRequest request) throws ResponseException, IOE } private String buildQueryRequestBody(QueryRequest queryRequest) throws IOException { - String requestBody = null; - JsonQueryRequest jsonQueryRequest = new JsonQueryRequest(queryRequest); - requestBody = mapper.writeValueAsString(jsonQueryRequest); + String requestBody = mapper.writeValueAsString(jsonQueryRequest); return requestBody; } From 692e95d993af819fd38ff50edbdf922010574f44 Mon Sep 17 00:00:00 2001 From: Abbas Hussain Date: Thu, 7 May 2020 12:02:25 -0700 Subject: [PATCH 12/14] Add unit tests --- .../jdbc/ResultSetTests.java | 99 +++++++++++++++++++ .../http/JsonCursorQueryRequestTests.java | 25 +++++ .../cursor/queryresponse_accounts_00.json | 30 ++++++ .../cursor/queryresponse_accounts_01.json | 17 ++++ .../cursor/queryresponse_accounts_02.json | 17 ++++ .../cursor/queryresponse_accounts_03.json | 16 +++ 6 files changed, 204 insertions(+) create mode 100644 src/test/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequestTests.java create mode 100644 src/test/resources/mock/protocol/json/cursor/queryresponse_accounts_00.json create mode 100644 src/test/resources/mock/protocol/json/cursor/queryresponse_accounts_01.json create mode 100644 src/test/resources/mock/protocol/json/cursor/queryresponse_accounts_02.json create mode 100644 src/test/resources/mock/protocol/json/cursor/queryresponse_accounts_03.json diff --git a/src/test/java/com/amazon/opendistroforelasticsearch/jdbc/ResultSetTests.java b/src/test/java/com/amazon/opendistroforelasticsearch/jdbc/ResultSetTests.java index 95c3fd4..db1f61b 100644 --- a/src/test/java/com/amazon/opendistroforelasticsearch/jdbc/ResultSetTests.java +++ b/src/test/java/com/amazon/opendistroforelasticsearch/jdbc/ResultSetTests.java @@ -19,6 +19,9 @@ import com.amazon.opendistroforelasticsearch.jdbc.internal.exceptions.ObjectClosedException; import com.amazon.opendistroforelasticsearch.jdbc.logging.NoOpLogger; import com.amazon.opendistroforelasticsearch.jdbc.protocol.QueryResponse; +import com.amazon.opendistroforelasticsearch.jdbc.protocol.http.JsonHttpProtocol; +import com.amazon.opendistroforelasticsearch.jdbc.test.TestResources; +import com.amazon.opendistroforelasticsearch.jdbc.test.mocks.MockES; import com.amazon.opendistroforelasticsearch.jdbc.types.ElasticsearchType; import com.amazon.opendistroforelasticsearch.jdbc.test.PerTestWireMockServerExtension; import com.amazon.opendistroforelasticsearch.jdbc.test.WireMockServerHelpers; @@ -41,6 +44,12 @@ import java.sql.Timestamp; import java.util.stream.Stream; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; @@ -92,6 +101,81 @@ private static Stream queryMockProvider() { ); } + + + @Test + void testResultSetOnPaginatedResponse(WireMockServer mockServer) throws SQLException, IOException { + + String queryUrl = JsonHttpProtocol.DEFAULT_SQL_CONTEXT_PATH+"?format=jdbc"; + final String sql = "SELECT firstname, age FROM accounts LIMIT 12"; + + // get Connection stub + setupStubForConnect(mockServer, "/"); + + // query response stub for initial page + mockServer.stubFor(post(urlEqualTo(queryUrl)) + .withHeader("Accept", equalTo("application/json")) + .withHeader("Content-Type", equalTo("application/json")) + .withRequestBody(matchingJsonPath("$.query", equalTo(sql))) + .willReturn(aResponse() + .withHeader("Content-Type", "application/json") + .withBody(getResponseBodyFromPath("mock/protocol/json/cursor/queryresponse_accounts_00.json")))); + + // query response stub for second page + mockServer.stubFor(post(urlEqualTo(queryUrl)) + .withHeader("Accept", equalTo("application/json")) + .withHeader("Content-Type", equalTo("application/json")) + .withRequestBody(matchingJsonPath("$.cursor", equalTo("abcde_1"))) + .willReturn(aResponse() + .withHeader("Content-Type", "application/json") + .withBody(getResponseBodyFromPath("mock/protocol/json/cursor/queryresponse_accounts_01.json")))); + + // query response stub for third page + mockServer.stubFor(post(urlEqualTo(queryUrl)) + .withHeader("Accept", equalTo("application/json")) + .withHeader("Content-Type", equalTo("application/json")) + .withRequestBody(matchingJsonPath("$.cursor", equalTo("abcde_2"))) + .willReturn(aResponse() + .withHeader("Content-Type", "application/json") + .withBody(getResponseBodyFromPath("mock/protocol/json/cursor/queryresponse_accounts_02.json")))); + + // query response stub for last page + mockServer.stubFor(post(urlEqualTo(queryUrl)) + .withHeader("Accept", equalTo("application/json")) + .withHeader("Content-Type", equalTo("application/json")) + .withRequestBody(matchingJsonPath("$.cursor", equalTo("abcde_3"))) + .willReturn(aResponse() + .withHeader("Content-Type", "application/json") + .withBody(getResponseBodyFromPath("mock/protocol/json/cursor/queryresponse_accounts_03.json")))); + + + Connection con = new Driver().connect(getBaseURLForMockServer(mockServer), null); + Statement st = con.createStatement(); + st.setFetchSize(3); + ResultSet rs = assertDoesNotThrow(() -> st.executeQuery(sql)); + int cursorRowCount = 0; + + while(rs.next()) { + cursorRowCount++; + } + assertEquals(12, cursorRowCount, "Unexpected number of rows retrieved from cursor."); + + // test for execute method, mostly used by BI tools like Tableau for example. + con = new Driver().connect(getBaseURLForMockServer(mockServer), null); + Statement statement = con.createStatement(); + st.setFetchSize(3); + boolean executed = assertDoesNotThrow(() -> statement.execute(sql)); + assertTrue(executed); + rs = statement.getResultSet(); + cursorRowCount = 0; + + while(rs.next()) { + cursorRowCount++; + } + assertEquals(12, cursorRowCount, "Unexpected number of rows retrieved from cursor."); + } + + @Test void testNullableFieldsQuery(WireMockServer mockServer) throws SQLException, IOException { QueryMock.NullableFieldsQueryMock queryMock = new QueryMock.NullableFieldsQueryMock(); @@ -177,4 +261,19 @@ void testResultSetWrapper() throws SQLException { SQLException ex = assertThrows(SQLException.class, () -> rsImpl.unwrap(mock(ResultSet.class).getClass())); assertTrue(ex.getMessage().contains("Unable to unwrap")); } + + + public String getResponseBodyFromPath(String path) throws IOException { + return TestResources.readResourceAsString(path); + } + + public void setupStubForConnect(final WireMockServer mockServer, final String contextPath) { + // get Connection stub + mockServer.stubFor(get(urlEqualTo(contextPath)) + .withHeader("Accept", equalTo("application/json")) + .willReturn(aResponse() + .withHeader("Content-Type", "application/json") + .withBody(MockES.INSTANCE.getConnectionResponse()))); + } + } diff --git a/src/test/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequestTests.java b/src/test/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequestTests.java new file mode 100644 index 0000000..a42605a --- /dev/null +++ b/src/test/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequestTests.java @@ -0,0 +1,25 @@ +package com.amazon.opendistroforelasticsearch.jdbc.protocol.http; + +import com.amazon.opendistroforelasticsearch.jdbc.protocol.JdbcQueryRequest; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +public class JsonCursorQueryRequestTests { + + @Test + public void testCursorRequestBody() { + JdbcQueryRequest jdbcQueryRequest = new JdbcQueryRequest("abcde12345"); + JsonCursorQueryRequest jsonCursorQueryRequest = new JsonCursorQueryRequest(jdbcQueryRequest); + ObjectMapper mapper = new ObjectMapper(); + String expectedRequestBody = "{\"cursor\":\"abcde12345\"}"; + String actual = assertDoesNotThrow(() -> mapper.writeValueAsString(jsonCursorQueryRequest)); + assertEquals(expectedRequestBody, actual); + + assertEquals(0, jsonCursorQueryRequest.getFetchSize()); + assertEquals(null, jsonCursorQueryRequest.getParameters()); + + } +} diff --git a/src/test/resources/mock/protocol/json/cursor/queryresponse_accounts_00.json b/src/test/resources/mock/protocol/json/cursor/queryresponse_accounts_00.json new file mode 100644 index 0000000..090cac8 --- /dev/null +++ b/src/test/resources/mock/protocol/json/cursor/queryresponse_accounts_00.json @@ -0,0 +1,30 @@ +{ + "schema": [ + { + "name": "firstname", + "type": "text" + }, + { + "name": "age", + "type": "long" + } + ], + "cursor": "abcde_1", + "total": 20, + "datarows": [ + [ + "Amber", + 32 + ], + [ + "Hattie", + 36 + ], + [ + "Nanette", + 28 + ] + ], + "size": 3, + "status": 200 +} \ No newline at end of file diff --git a/src/test/resources/mock/protocol/json/cursor/queryresponse_accounts_01.json b/src/test/resources/mock/protocol/json/cursor/queryresponse_accounts_01.json new file mode 100644 index 0000000..3df9caa --- /dev/null +++ b/src/test/resources/mock/protocol/json/cursor/queryresponse_accounts_01.json @@ -0,0 +1,17 @@ +{ + "cursor": "abcde_2", + "datarows": [ + [ + "Dale", + 33 + ], + [ + "Elinor", + 36 + ], + [ + "Virginia", + 39 + ] + ] +} \ No newline at end of file diff --git a/src/test/resources/mock/protocol/json/cursor/queryresponse_accounts_02.json b/src/test/resources/mock/protocol/json/cursor/queryresponse_accounts_02.json new file mode 100644 index 0000000..d76d17a --- /dev/null +++ b/src/test/resources/mock/protocol/json/cursor/queryresponse_accounts_02.json @@ -0,0 +1,17 @@ +{ + "cursor": "abcde_3", + "datarows": [ + [ + "Dillard", + 34 + ], + [ + "Mcgee", + 39 + ], + [ + "Aurelia", + 37 + ] + ] +} \ No newline at end of file diff --git a/src/test/resources/mock/protocol/json/cursor/queryresponse_accounts_03.json b/src/test/resources/mock/protocol/json/cursor/queryresponse_accounts_03.json new file mode 100644 index 0000000..99b4448 --- /dev/null +++ b/src/test/resources/mock/protocol/json/cursor/queryresponse_accounts_03.json @@ -0,0 +1,16 @@ +{ + "datarows": [ + [ + "Fulton", + 23 + ], + [ + "Burton", + 31 + ], + [ + "Josie", + 32 + ] + ] +} \ No newline at end of file From 46f381ce0526502b5d2ff1713b3582a9dc521e3c Mon Sep 17 00:00:00 2001 From: Abbas Hussain Date: Thu, 7 May 2020 12:26:22 -0700 Subject: [PATCH 13/14] Add comments --- .../opendistroforelasticsearch/jdbc/ResultSetImpl.java | 9 ++++++++- .../jdbc/protocol/http/JdbcCursorQueryRequest.java | 6 ++++++ .../jdbc/protocol/http/JsonCursorHttpProtocol.java | 6 ++++++ .../jdbc/protocol/http/JsonCursorQueryRequest.java | 6 ++++++ .../jdbc/protocol/http/JsonHttpProtocolFactory.java | 7 +++++++ 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/ResultSetImpl.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/ResultSetImpl.java index cc1b8a3..14a4ae8 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/ResultSetImpl.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/ResultSetImpl.java @@ -141,7 +141,14 @@ public boolean next() throws SQLException { return next; } - + /** + * TODO: Refactor as suggested https://github.com/opendistro-for-elasticsearch/sql-jdbc/pull/76#discussion_r421571383 + * + * This method has side effects. It creates a new Cursor to hold rows from new pages. + * Ideally fetching next set of rows using cursorId should be delegated to Cursor. + * In addition, the cursor should be final. + * + **/ protected void buildNextPageFromCursorId() throws SQLException { try { JdbcCursorQueryRequest jdbcCursorQueryRequest = new JdbcCursorQueryRequest(this.cursorId); diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JdbcCursorQueryRequest.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JdbcCursorQueryRequest.java index b831c37..e1c8030 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JdbcCursorQueryRequest.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JdbcCursorQueryRequest.java @@ -7,6 +7,12 @@ import java.util.List; import java.util.Objects; +/** + * Bean to encapsulate cursor ID + * + * @author abbas hussain + * @since 07.05.20 + **/ public class JdbcCursorQueryRequest implements QueryRequest { String cursor; diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocol.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocol.java index 3e02438..d733ac9 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocol.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocol.java @@ -9,6 +9,12 @@ import java.io.IOException; import java.io.InputStream; +/** + * Http protocol for cursor request and response + * + * @author abbas hussain + * @since 07.05.20 + **/ public class JsonCursorHttpProtocol extends JsonHttpProtocol { public JsonCursorHttpProtocol(HttpTransport transport) { diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequest.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequest.java index 4a7fb5a..16b777d 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequest.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequest.java @@ -7,6 +7,12 @@ import java.util.List; +/** + * Definition of json cursor request + * + * @author abbas hussain + * @since 07.05.20 + **/ public class JsonCursorQueryRequest implements QueryRequest { private final String cursor; diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonHttpProtocolFactory.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonHttpProtocolFactory.java index 4d69073..a5f48bd 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonHttpProtocolFactory.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonHttpProtocolFactory.java @@ -20,6 +20,13 @@ import com.amazon.opendistroforelasticsearch.jdbc.protocol.ProtocolFactory; import com.amazon.opendistroforelasticsearch.jdbc.transport.http.HttpTransport; + +/** + * Factory to create JsonHttpProtocol objects + * + * @author abbas hussain + * @since 07.05.20 + */ public class JsonHttpProtocolFactory implements ProtocolFactory { public static JsonHttpProtocolFactory INSTANCE = new JsonHttpProtocolFactory(); From c54a2de4f65ae18bf683ab404310181084caa08d Mon Sep 17 00:00:00 2001 From: Abbas Hussain Date: Thu, 7 May 2020 12:49:51 -0700 Subject: [PATCH 14/14] Add license headers --- .../protocol/http/JdbcCursorQueryRequest.java | 16 ++++++++++++++ .../protocol/http/JsonCursorHttpProtocol.java | 16 ++++++++++++++ .../http/JsonCursorHttpProtocolFactory.java | 22 +++++++++++++++++++ .../protocol/http/JsonCursorQueryRequest.java | 16 ++++++++++++++ .../http/JsonHttpProtocolFactory.java | 6 ----- 5 files changed, 70 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JdbcCursorQueryRequest.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JdbcCursorQueryRequest.java index e1c8030..048c4a3 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JdbcCursorQueryRequest.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JdbcCursorQueryRequest.java @@ -1,3 +1,19 @@ +/* + * Copyright <2019> Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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 com.amazon.opendistroforelasticsearch.jdbc.protocol.http; import com.amazon.opendistroforelasticsearch.jdbc.protocol.JdbcQueryParam;; diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocol.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocol.java index d733ac9..882528f 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocol.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocol.java @@ -1,3 +1,19 @@ +/* + * Copyright <2019> Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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 com.amazon.opendistroforelasticsearch.jdbc.protocol.http; import com.amazon.opendistroforelasticsearch.jdbc.protocol.QueryRequest; diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocolFactory.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocolFactory.java index 2011222..5c2cf77 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocolFactory.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorHttpProtocolFactory.java @@ -1,9 +1,31 @@ +/* + * Copyright <2019> Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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 com.amazon.opendistroforelasticsearch.jdbc.protocol.http; import com.amazon.opendistroforelasticsearch.jdbc.config.ConnectionConfig; import com.amazon.opendistroforelasticsearch.jdbc.protocol.ProtocolFactory; import com.amazon.opendistroforelasticsearch.jdbc.transport.http.HttpTransport; +/** + * Factory to create JsonCursorHttpProtocol objects + * + * @author abbas hussain + * @since 07.05.20 + */ public class JsonCursorHttpProtocolFactory implements ProtocolFactory { public static JsonCursorHttpProtocolFactory INSTANCE = new JsonCursorHttpProtocolFactory(); diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequest.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequest.java index 16b777d..b2b3c06 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequest.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonCursorQueryRequest.java @@ -1,3 +1,19 @@ +/* + * Copyright <2019> Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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 com.amazon.opendistroforelasticsearch.jdbc.protocol.http; import com.amazon.opendistroforelasticsearch.jdbc.protocol.Parameter; diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonHttpProtocolFactory.java b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonHttpProtocolFactory.java index a5f48bd..255251e 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonHttpProtocolFactory.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/jdbc/protocol/http/JsonHttpProtocolFactory.java @@ -21,12 +21,6 @@ import com.amazon.opendistroforelasticsearch.jdbc.transport.http.HttpTransport; -/** - * Factory to create JsonHttpProtocol objects - * - * @author abbas hussain - * @since 07.05.20 - */ public class JsonHttpProtocolFactory implements ProtocolFactory { public static JsonHttpProtocolFactory INSTANCE = new JsonHttpProtocolFactory();