This is an automated email from the ASF dual-hosted git repository.
cwylie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push:
new 5f05c2a503e Fix IT failure (#18067)
5f05c2a503e is described below
commit 5f05c2a503e8c3181a3e37b41b7fd94a92b4e28b
Author: Frank Chen <[email protected]>
AuthorDate: Wed Jun 4 12:19:15 2025 +0800
Fix IT failure (#18067)
---
integration-tests/pom.xml | 8 -
.../apache/druid/tests/query/ITSqlQueryTest.java | 225 ++++++++-------------
services/pom.xml | 4 +
.../druid/server/AsyncQueryForwardingServlet.java | 3 +-
.../java/org/apache/druid/sql/http/SqlQuery.java | 2 +-
5 files changed, 96 insertions(+), 146 deletions(-)
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index 60cbe4edcb4..f54e88c9304 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -418,14 +418,6 @@
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
</dependency>
- <dependency>
- <groupId>org.apache.httpcomponents</groupId>
- <artifactId>httpcore</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.httpcomponents</groupId>
- <artifactId>httpclient</artifactId>
- </dependency>
<!-- Tests -->
<dependency>
diff --git
a/integration-tests/src/test/java/org/apache/druid/tests/query/ITSqlQueryTest.java
b/integration-tests/src/test/java/org/apache/druid/tests/query/ITSqlQueryTest.java
index 46d6a938321..05fca8cf302 100644
---
a/integration-tests/src/test/java/org/apache/druid/tests/query/ITSqlQueryTest.java
+++
b/integration-tests/src/test/java/org/apache/druid/tests/query/ITSqlQueryTest.java
@@ -22,23 +22,24 @@ package org.apache.druid.tests.query;
import com.google.inject.Inject;
import org.apache.druid.java.util.common.ISE;
import org.apache.druid.java.util.common.StringUtils;
-import org.apache.druid.java.util.common.logger.Logger;
+import org.apache.druid.java.util.http.client.HttpClient;
+import org.apache.druid.java.util.http.client.Request;
+import org.apache.druid.java.util.http.client.response.StatusResponseHandler;
+import org.apache.druid.java.util.http.client.response.StatusResponseHolder;
import org.apache.druid.testing.IntegrationTestingConfig;
import org.apache.druid.testing.guice.DruidTestModuleFactory;
+import org.apache.druid.testing.guice.TestClient;
+import org.apache.druid.testing.utils.ITRetryUtil;
import org.apache.druid.tests.TestNGGroup;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpStatus;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.util.EntityUtils;
+import org.jboss.netty.handler.codec.http.HttpMethod;
+import org.jboss.netty.handler.codec.http.HttpResponseStatus;
+import org.testng.Assert;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import javax.ws.rs.core.MediaType;
import java.io.IOException;
+import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.function.Function;
@@ -46,77 +47,75 @@ import java.util.function.Function;
/**
* Test the SQL endpoint with different Content-Type
*/
-@Test(groups = {TestNGGroup.QUERY, TestNGGroup.CENTRALIZED_DATASOURCE_SCHEMA})
+@Test(groups = {TestNGGroup.QUERY})
@Guice(moduleFactory = DruidTestModuleFactory.class)
public class ITSqlQueryTest
{
- private static final Logger LOG = new Logger(ITSqlQueryTest.class);
-
@Inject
IntegrationTestingConfig config;
+ @Inject
+ @TestClient
+ HttpClient httpClient;
+
interface IExecutable
{
- void execute(String endpoint) throws IOException;
+ void execute(String endpoint) throws Exception;
}
interface OnRequest
{
- void on(HttpPost request) throws IOException;
+ void on(Request request) throws IOException;
}
interface OnResponse
{
- void on(int statusCode, HttpEntity response) throws IOException;
+ void on(int statusCode, String response) throws IOException;
}
private void executeWithRetry(String endpoint, String contentType,
IExecutable executable)
{
- Throwable lastException = null;
- for (int i = 1; i <= 5; i++) {
- LOG.info("Query to %s with Content-Type = %s, tries = %s", endpoint,
contentType, i);
- try {
- executable.execute(endpoint);
- return;
- }
- catch (IOException e) {
- // Only catch IOException
- lastException = e;
- }
- try {
- Thread.sleep(200);
- }
- catch (InterruptedException ignored) {
- break;
- }
- }
- throw new ISE(contentType + " failed after 5 tries, last exception: " +
lastException);
+ // Retry 5 times with 200 ms delay
+ ITRetryUtil.retryUntilEquals(
+ () -> {
+ executable.execute(endpoint);
+ return true;
+ }, true,
+ 200,
+ 5,
+ StringUtils.format("Query to %s with Content-Type = %s", endpoint,
contentType)
+ );
}
private void executeQuery(
String contentType,
+ String query,
OnRequest onRequest,
OnResponse onResponse
)
{
IExecutable executable = (endpoint) -> {
- try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
- HttpPost request = new HttpPost(endpoint);
- if (contentType != null) {
- request.addHeader("Content-Type", contentType);
- }
- onRequest.on(request);
+ Request request = new Request(HttpMethod.POST, new URL(endpoint));
+ if (contentType != null) {
+ request.addHeader("Content-Type", contentType);
+ }
- try (CloseableHttpResponse response = client.execute(request)) {
- HttpEntity responseEntity = response.getEntity();
- assertNotNull(responseEntity);
+ if (query != null) {
+ request.setContent(query.getBytes(StandardCharsets.UTF_8));
+ }
- onResponse.on(
- response.getStatusLine().getStatusCode(),
- responseEntity
- );
- }
+ if (onRequest != null) {
+ onRequest.on(request);
}
+
+ StatusResponseHolder response = httpClient.go(request,
StatusResponseHandler.getInstance())
+ .get();
+ Assert.assertNotNull(response);
+
+ onResponse.on(
+ response.getStatus().getCode(),
+ response.getContent().trim()
+ );
};
// Send query to broker to exeucte
@@ -126,27 +125,6 @@ public class ITSqlQueryTest
executeWithRetry(StringUtils.format("%s/druid/v2/sql/",
config.getRouterUrl()), contentType, executable);
}
- private void assertEquals(String expected, String actual)
- {
- if (!expected.equals(actual)) {
- throw new ISE("Expected [%s] but got [%s]", expected, actual);
- }
- }
-
- private void assertEquals(int expected, int actual)
- {
- if (expected != actual) {
- throw new ISE("Expected [%d] but got [%d]", expected, actual);
- }
- }
-
- private void assertNotNull(Object object)
- {
- if (object == null) {
- throw new ISE("Expected not null");
- }
- }
-
private void assertStringCompare(String expected, String actual,
Function<String, Boolean> predicate)
{
if (!predicate.apply(expected)) {
@@ -159,13 +137,11 @@ public class ITSqlQueryTest
{
executeQuery(
null,
+ "select 1",
(request) -> {
- request.setEntity(new StringEntity("select 1"));
},
- (statusCode, responseEntity) -> {
- assertEquals(HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, statusCode);
-
- String responseBody = EntityUtils.toString(responseEntity).trim();
+ (statusCode, responseBody) -> {
+ Assert.assertEquals(statusCode,
HttpResponseStatus.UNSUPPORTED_MEDIA_TYPE.getCode(), responseBody);
assertStringCompare("Unsupported Content-Type:", responseBody,
responseBody::contains);
}
);
@@ -176,13 +152,11 @@ public class ITSqlQueryTest
{
executeQuery(
"application/xml",
+ "select 1",
(request) -> {
- request.setEntity(new StringEntity("select 1"));
},
- (statusCode, responseEntity) -> {
- assertEquals(HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, statusCode);
-
- String responseBody = EntityUtils.toString(responseEntity).trim();
+ (statusCode, responseBody) -> {
+ Assert.assertEquals(statusCode,
HttpResponseStatus.UNSUPPORTED_MEDIA_TYPE.getCode(), responseBody);
assertStringCompare("Unsupported Content-Type:", responseBody,
responseBody::contains);
}
);
@@ -193,14 +167,12 @@ public class ITSqlQueryTest
{
executeQuery(
MediaType.TEXT_PLAIN,
+ "select \n1",
(request) -> {
- request.setEntity(new StringEntity("select \n1"));
},
- (statusCode, responseEntity) -> {
- assertEquals(200, statusCode);
-
- String responseBody = EntityUtils.toString(responseEntity).trim();
- assertEquals("[{\"EXPR$0\":1}]", responseBody);
+ (statusCode, responseBody) -> {
+ Assert.assertEquals(statusCode, 200, responseBody);
+ Assert.assertEquals(responseBody, "[{\"EXPR$0\":1}]");
}
);
}
@@ -210,14 +182,12 @@ public class ITSqlQueryTest
{
executeQuery(
MediaType.APPLICATION_FORM_URLENCODED,
+ URLEncoder.encode("select 'x % y'", StandardCharsets.UTF_8),
(request) -> {
- request.setEntity(new StringEntity(URLEncoder.encode("select 'x %
y'", StandardCharsets.UTF_8)));
},
- (statusCode, responseEntity) -> {
- assertEquals(200, statusCode);
-
- String responseBody = EntityUtils.toString(responseEntity).trim();
- assertEquals("[{\"EXPR$0\":\"x % y\"}]", responseBody);
+ (statusCode, responseBody) -> {
+ Assert.assertEquals(statusCode, 200, responseBody);
+ Assert.assertEquals(responseBody, "[{\"EXPR$0\":\"x % y\"}]");
}
);
}
@@ -227,14 +197,12 @@ public class ITSqlQueryTest
{
executeQuery(
MediaType.APPLICATION_FORM_URLENCODED,
+ "select 'x % y'",
(request) -> {
- request.setEntity(new StringEntity("select 'x % y'"));
},
- (statusCode, responseEntity) -> {
- assertEquals(400, statusCode);
-
- String responseBody = EntityUtils.toString(responseEntity).trim();
- assertStringCompare("Unable to decoded", responseBody,
responseBody::contains);
+ (statusCode, responseBody) -> {
+ Assert.assertEquals(statusCode, 400, responseBody);
+ assertStringCompare("Unable to decode", responseBody,
responseBody::contains);
}
);
}
@@ -244,14 +212,12 @@ public class ITSqlQueryTest
{
executeQuery(
MediaType.APPLICATION_JSON,
+ "{\"query\":\"select 567\"}",
(request) -> {
- request.setEntity(new
StringEntity(StringUtils.format("{\"query\":\"select 567\"}")));
},
- (statusCode, responseEntity) -> {
- assertEquals(200, statusCode);
-
- String responseBody = EntityUtils.toString(responseEntity).trim();
- assertEquals("[{\"EXPR$0\":567}]", responseBody);
+ (statusCode, responseBody) -> {
+ Assert.assertEquals(statusCode, 200, responseBody);
+ Assert.assertEquals(responseBody, "[{\"EXPR$0\":567}]");
}
);
}
@@ -261,13 +227,11 @@ public class ITSqlQueryTest
{
executeQuery(
MediaType.APPLICATION_JSON,
+ "{\"query\":select 567}",
(request) -> {
- request.setEntity(new
StringEntity(StringUtils.format("{\"query\":select 567}")));
},
- (statusCode, responseEntity) -> {
- assertEquals(400, statusCode);
-
- String responseBody = EntityUtils.toString(responseEntity).trim();
+ (statusCode, responseBody) -> {
+ Assert.assertEquals(statusCode, 400, responseBody);
assertStringCompare("Malformed SQL query", responseBody,
responseBody::contains);
}
);
@@ -278,13 +242,11 @@ public class ITSqlQueryTest
{
executeQuery(
MediaType.TEXT_PLAIN,
+ null,
(request) -> {
- // Empty query, DO NOTHING
},
- (statusCode, responseEntity) -> {
- assertEquals(400, statusCode);
-
- String responseBody = EntityUtils.toString(responseEntity).trim();
+ (statusCode, responseBody) -> {
+ Assert.assertEquals(statusCode, 400, responseBody);
assertStringCompare("Empty query", responseBody,
responseBody::contains);
}
);
@@ -295,13 +257,11 @@ public class ITSqlQueryTest
{
executeQuery(
MediaType.APPLICATION_FORM_URLENCODED,
+ null,
(request) -> {
- // Empty query, DO NOTHING
},
- (statusCode, responseEntity) -> {
- assertEquals(400, statusCode);
-
- String responseBody = EntityUtils.toString(responseEntity).trim();
+ (statusCode, responseBody) -> {
+ Assert.assertEquals(statusCode, 400, responseBody);
assertStringCompare("Empty query", responseBody,
responseBody::contains);
}
);
@@ -312,14 +272,11 @@ public class ITSqlQueryTest
{
executeQuery(
MediaType.TEXT_PLAIN,
+ " ",
(request) -> {
- // an query with blank characters
- request.setEntity(new StringEntity(" "));
},
- (statusCode, responseEntity) -> {
- assertEquals(400, statusCode);
-
- String responseBody = EntityUtils.toString(responseEntity).trim();
+ (statusCode, responseBody) -> {
+ Assert.assertEquals(statusCode, 400, responseBody);
assertStringCompare("Empty query", responseBody,
responseBody::contains);
}
);
@@ -330,36 +287,32 @@ public class ITSqlQueryTest
{
executeQuery(
MediaType.APPLICATION_JSON,
+ null,
(request) -> {
- // Empty query, DO NOTHING
},
- (statusCode, responseEntity) -> {
- assertEquals(400, statusCode);
-
- String responseBody = EntityUtils.toString(responseEntity).trim();
+ (statusCode, responseBody) -> {
+ Assert.assertEquals(statusCode, 400, responseBody);
assertStringCompare("Empty query", responseBody,
responseBody::contains);
}
);
}
/**
- * When multiple Content-Type headers are set, the first one(in this case
it's the text format) should be used.
+ * When multiple Content-Type headers are set, the first one (in this case,
it's the text format) should be used.
*/
@Test
public void testMultipleContentType()
{
executeQuery(
MediaType.TEXT_PLAIN,
+ "SELECT 1",
(request) -> {
// Add one more Content-Type header
request.addHeader("Content-Type", MediaType.APPLICATION_JSON);
- request.setEntity(new StringEntity(StringUtils.format("SELECT 1")));
},
- (statusCode, responseEntity) -> {
- assertEquals(200, statusCode);
-
- String responseBody = EntityUtils.toString(responseEntity).trim();
- assertEquals("[{\"EXPR$0\":1}]", responseBody);
+ (statusCode, responseBody) -> {
+ Assert.assertEquals(statusCode, 200, responseBody);
+ Assert.assertEquals(responseBody, "[{\"EXPR$0\":1}]");
}
);
}
diff --git a/services/pom.xml b/services/pom.xml
index 570e48da166..fad8933fb2c 100644
--- a/services/pom.xml
+++ b/services/pom.xml
@@ -125,6 +125,10 @@
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-smile-provider</artifactId>
</dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.dataformat</groupId>
+ <artifactId>jackson-dataformat-smile</artifactId>
+ </dependency>
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
diff --git
a/services/src/main/java/org/apache/druid/server/AsyncQueryForwardingServlet.java
b/services/src/main/java/org/apache/druid/server/AsyncQueryForwardingServlet.java
index 5b8e9c17f39..dba842ec689 100644
---
a/services/src/main/java/org/apache/druid/server/AsyncQueryForwardingServlet.java
+++
b/services/src/main/java/org/apache/druid/server/AsyncQueryForwardingServlet.java
@@ -21,6 +21,7 @@ package org.apache.druid.server;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.smile.SmileFactory;
import com.fasterxml.jackson.jaxrs.smile.SmileMediaTypes;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
@@ -484,7 +485,7 @@ public class AsyncQueryForwardingServlet extends
AsyncProxyServlet implements Qu
byte[] bytes = objectMapper.writeValueAsBytes(content);
proxyRequest.content(new BytesContentProvider(bytes));
proxyRequest.getHeaders().put(HttpHeader.CONTENT_LENGTH,
String.valueOf(bytes.length));
- proxyRequest.getHeaders().put(HttpHeader.CONTENT_TYPE,
MediaType.APPLICATION_JSON);
+ proxyRequest.getHeaders().put(HttpHeader.CONTENT_TYPE,
objectMapper.getFactory() instanceof SmileFactory ?
SmileMediaTypes.APPLICATION_JACKSON_SMILE : MediaType.APPLICATION_JSON);
}
catch (JsonProcessingException e) {
throw new RuntimeException(e);
diff --git a/sql/src/main/java/org/apache/druid/sql/http/SqlQuery.java
b/sql/src/main/java/org/apache/druid/sql/http/SqlQuery.java
index 71f9c14563c..022a3c4ed54 100644
--- a/sql/src/main/java/org/apache/druid/sql/http/SqlQuery.java
+++ b/sql/src/main/java/org/apache/druid/sql/http/SqlQuery.java
@@ -308,7 +308,7 @@ public class SqlQuery
catch (IllegalArgumentException e) {
throw new HttpException(
Response.Status.BAD_REQUEST,
- "Unable to decoded URL-Encoded SQL query: " + e.getMessage()
+ "Unable to decode URL-Encoded SQL query: " + e.getMessage()
);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]