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 mentioned the support context types here ?



##########
extensions-core/multi-stage-query/src/main/java/org/apache/druid/msq/sql/resources/SqlStatementResource.java:
##########
@@ -167,8 +167,14 @@ public Response isEnabled(@Context final 
HttpServletRequest request)
 
   @POST
   @Produces(MediaType.APPLICATION_JSON)
-  @Consumes(MediaType.APPLICATION_JSON)
-  public Response doPost(final SqlQuery sqlQuery, @Context final 
HttpServletRequest req)
+  public Response doPost(@Context final HttpServletRequest req,
+                         @Context final HttpContext httpContext)
+  {
+    return doPost(SqlQuery.from(httpContext), req);
+  }
+
+  public Response doPost(SqlQuery sqlQuery,

Review Comment:
   Can we make this private/protected ?



##########
extensions-core/multi-stage-query/src/main/java/org/apache/druid/msq/sql/resources/SqlStatementResource.java:
##########
@@ -167,8 +167,14 @@ public Response isEnabled(@Context final 
HttpServletRequest request)
 
   @POST
   @Produces(MediaType.APPLICATION_JSON)
-  @Consumes(MediaType.APPLICATION_JSON)
-  public Response doPost(final SqlQuery sqlQuery, @Context final 
HttpServletRequest req)
+  public Response doPost(@Context final HttpServletRequest req,
+                         @Context final HttpContext httpContext)
+  {
+    return doPost(SqlQuery.from(httpContext), req);
+  }
+
+  public Response doPost(SqlQuery sqlQuery,

Review Comment:
   ```suggestion
     public Response doPost(final SqlQuery sqlQuery,
   ```



-- 
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]

Reply via email to