cryptoe commented on code in PR #17937:
URL: https://github.com/apache/druid/pull/17937#discussion_r2068749115
##########
sql/src/main/java/org/apache/druid/sql/http/SqlQuery.java:
##########
@@ -200,4 +211,94 @@ public SqlQuery withQueryContext(Map<String, Object>
newContext)
{
return new SqlQuery(query, resultFormat, header, typesHeader,
sqlTypesHeader, newContext, parameters);
}
+
+ /**
+ * Extract SQL query object or SQL text from an HTTP Request
+ */
+ @FunctionalInterface
+ interface ISqlQueryExtractor<T>
+ {
+ T extract() throws IOException;
+ }
+
+ /**
+ * For BROKERs to use.
+ * <p>
+ * Brokers use com.sun.jersey upon Jetty for RESTful API, however jersey
internally has special handling for x-www-form-urlencoded,
+ * it's not able to get the data from the stream of HttpServletRequest for
such content type.
+ * So we use HttpContext to get the request entity/string instead of using
HttpServletRequest.
+ *
+ * @throws HttpException if the content type is not supported
+ * @throws BadRequestException if the SQL query is malformed or fail to read
from the request
+ */
+ public static SqlQuery from(HttpContext httpContext)
+ {
+ MediaType mediaType = httpContext.getRequest().getMediaType();
+ if (mediaType == null) {
+ throw new HttpException(
+ Response.Status.UNSUPPORTED_MEDIA_TYPE,
+ "Unsupported Content-Type: null"
+ );
+ }
+
+ try {
+ return from(
+ mediaType.getType() + "/" + mediaType.getSubtype(),
+ () -> httpContext.getRequest().getEntity(SqlQuery.class),
+ () -> httpContext.getRequest().getEntity(String.class)
+ );
+ }
+ catch (IOException e) {
+ throw new BadRequestException("Unable to parse SQL query: " +
e.getMessage());
+ }
+ }
+
+ /**
+ * For Router to use
+ * @throws HttpException if the content type is not supported
+ * @throws IOException if the SQL query is malformed or fail to read from
the request
+ */
+ public static SqlQuery from(HttpServletRequest request, ObjectMapper
objectMapper) throws IOException
+ {
+ String contentType = request.getContentType();
+ return from(
+ contentType,
+ () -> objectMapper.readValue(request.getInputStream(), SqlQuery.class),
+ () -> new String(IOUtils.toByteArray(request.getInputStream()),
StandardCharsets.UTF_8)
+ );
+ }
+
+ private static SqlQuery from(
+ String contentType,
+ ISqlQueryExtractor<SqlQuery> jsonQueryExtractor,
+ ISqlQueryExtractor<String> rawQueryExtractor
+ ) throws IOException
+ {
+ if (MediaType.APPLICATION_JSON.equals(contentType)) {
+
+ return jsonQueryExtractor.extract();
+
+ } else if (MediaType.TEXT_PLAIN.equals(contentType)) {
+
+ String sql = rawQueryExtractor.extract();
+ return new SqlQuery(sql, null, false, false, false, null, null);
+
+ } else if (MediaType.APPLICATION_FORM_URLENCODED.equals(contentType)) {
+
+ String sql = rawQueryExtractor.extract();
+ if (sql == null) {
+ throw new HttpException(Response.Status.BAD_REQUEST, "No SQL given");
+ }
+
+ sql = URLDecoder.decode(sql, StandardCharsets.UTF_8);
+
+ return new SqlQuery(sql, null, false, false, false, null, null);
+
+ } else {
+ throw new HttpException(
+ Response.Status.UNSUPPORTED_MEDIA_TYPE,
+ "Unsupported Content-Type: " + contentType
Review Comment:
Can we also mention the supported context types here ?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]