Skip to content

Commit 8a1ac8a

Browse files
authored
SQL: handle SQL not being available in a more graceful way (#43665)
* Add test for SQL not being available error message in JDBC. * Add a new qa sub-project that explicitly disables SQL XPack module in Gradle.
1 parent 341006e commit 8a1ac8a

File tree

7 files changed

+54
-11
lines changed

7 files changed

+54
-11
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
testClusters.integTest {
2+
setting 'xpack.security.enabled', 'false'
3+
setting 'xpack.sql.enabled', 'false'
4+
setting 'xpack.license.self_generated.type', 'trial'
5+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
package org.elasticsearch.xpack.sql.qa.no_sql;
8+
9+
import org.elasticsearch.xpack.sql.qa.jdbc.JdbcNoSqlTestCase;
10+
11+
public class JdbcNoSqlIT extends JdbcNoSqlTestCase {
12+
13+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
package org.elasticsearch.xpack.sql.qa.jdbc;
8+
9+
import java.sql.Connection;
10+
import java.sql.SQLException;
11+
12+
public class JdbcNoSqlTestCase extends JdbcIntegrationTestCase {
13+
14+
public void testJdbcExceptionMessage() throws SQLException {
15+
try (Connection c = esJdbc()) {
16+
SQLException e = expectThrows(SQLException.class, () -> c.prepareStatement("SELECT * FROM bla").executeQuery());
17+
assertTrue(e.getMessage().startsWith("X-Pack/SQL does not seem to be available on the Elasticsearch"
18+
+ " node using the access path"));
19+
}
20+
}
21+
}

x-pack/plugin/sql/sql-client/src/main/java/org/elasticsearch/xpack/sql/client/JreHttpUrlConnection.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ public class JreHttpUrlConnection implements Closeable {
4848
* error.
4949
*/
5050
public static final String SQL_STATE_BAD_SERVER = "bad_server";
51-
private static final String SQL_NOT_AVAILABLE_ERROR_MESSAGE = "request [" + SQL_QUERY_REST_ENDPOINT
52-
+ "] contains unrecognized parameter: [mode]";
51+
private static final String SQL_NOT_AVAILABLE_ERROR_MESSAGE = "Incorrect HTTP method for uri [" + SQL_QUERY_REST_ENDPOINT
52+
+ "?error_trace] and method [POST], allowed:";
5353

5454
public static <R> R http(String path, String query, ConnectionConfiguration cfg, Function<JreHttpUrlConnection, R> handler) {
5555
final URI uriPath = cfg.baseUri().resolve(path); // update path if needed
@@ -181,9 +181,8 @@ private <R> ResponseOrException<R> parserError() throws IOException {
181181
if (type == null) {
182182
// check if x-pack or sql are not available (x-pack not installed or sql not enabled)
183183
// by checking the error message the server is sending back
184-
if (con.getResponseCode() >= HttpURLConnection.HTTP_BAD_REQUEST
185-
&& failure.reason().contains(SQL_NOT_AVAILABLE_ERROR_MESSAGE)) {
186-
return new ResponseOrException<>(new SQLException("X-Pack/SQL do not seem to be available"
184+
if (con.getResponseCode() >= HttpURLConnection.HTTP_BAD_REQUEST && failure.reason().contains(SQL_NOT_AVAILABLE_ERROR_MESSAGE)) {
185+
return new ResponseOrException<>(new SQLException("X-Pack/SQL does not seem to be available"
187186
+ " on the Elasticsearch node using the access path '"
188187
+ con.getURL().getHost()
189188
+ (con.getURL().getPort() > 0 ? ":" + con.getURL().getPort() : "")

x-pack/plugin/sql/sql-client/src/main/java/org/elasticsearch/xpack/sql/client/RemoteFailure.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,15 @@ private static RemoteFailure parseResponseTopLevel(JsonParser parser) throws IOE
155155
} else {
156156
switch (fieldName) {
157157
case "error":
158-
if (token != JsonToken.START_OBJECT) {
159-
throw new IOException("Expected [error] to be an object but was [" + token + "][" + parser.getText() + "]");
158+
if (token != JsonToken.START_OBJECT && token != JsonToken.VALUE_STRING) {
159+
throw new IOException("Expected [error] to be an object or string but was [" + token + "]["
160+
+ parser.getText() + "]");
161+
}
162+
if (token == JsonToken.VALUE_STRING) {
163+
exception = new RemoteFailure(StringUtils.EMPTY, parser.getText(), null, null, null, null);
164+
} else {
165+
exception = parseFailure(parser);
160166
}
161-
exception = parseFailure(parser);
162167
continue;
163168
case "status":
164169
if (token != JsonToken.VALUE_NUMBER_INT) {

x-pack/plugin/sql/sql-client/src/test/java/org/elasticsearch/xpack/sql/client/RemoteFailureTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ public void testNoError() {
7070
public void testBogusError() {
7171
IOException e = expectThrows(IOException.class, () -> parse("bogus_error.json"));
7272
assertEquals(
73-
"Can't parse error from Elasticsearch [Expected [error] to be an object but was [VALUE_STRING][bogus]] "
73+
"Can't parse error from Elasticsearch [Expected [error] to be an object or string but was [START_ARRAY][[]] "
7474
+ "at [line 1 col 12]. Response:\n"
75-
+ "{ \"error\": \"bogus\" }",
75+
+ "{ \"error\": [\"bogus\"] }",
7676
e.getMessage());
7777
}
7878

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{ "error": "bogus" }
1+
{ "error": ["bogus"] }

0 commit comments

Comments
 (0)