You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@drill.apache.org by am...@apache.org on 2017/09/03 06:54:00 UTC
[1/2] drill git commit: DRILL-5757: CONVERT_TO_JSON function is
failed while using non-existence field as a parameter.
Repository: drill
Updated Branches:
refs/heads/master 406dd2a58 -> 789b83d77
DRILL-5757: CONVERT_TO_JSON function is failed while using non-existence field as a parameter.
close apache/drill#929
Project: http://git-wip-us.apache.org/repos/asf/drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/2c470de3
Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/2c470de3
Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/2c470de3
Branch: refs/heads/master
Commit: 2c470de30a9ae70709b392f8cb36094a450e52d8
Parents: 406dd2a
Author: Vitalii Diravka <vi...@gmail.com>
Authored: Thu Aug 31 13:24:37 2017 +0000
Committer: Aman Sinha <as...@maprtech.com>
Committed: Sat Sep 2 22:59:44 2017 -0700
----------------------------------------------------------------------
.../drill/exec/expr/ExpressionTreeMaterializer.java | 7 ++++---
.../complex/writer/TestComplexTypeReader.java | 16 +++++++++++++++-
2 files changed, 19 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/drill/blob/2c470de3/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
index f14d816..23df262 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
@@ -423,10 +423,11 @@ public class ExpressionTreeMaterializer {
TypeProtos.MajorType parmType = matchedFuncHolder.getParmMajorType(i);
//Case 1: If 1) the argument is NullExpression
- // 2) the parameter of matchedFuncHolder allows null input, or func's null_handling is NULL_IF_NULL (means null and non-null are exchangable).
+ // 2) the minor type of parameter of matchedFuncHolder is not LATE (the type of null expression is still unknown)
+ // 3) the parameter of matchedFuncHolder allows null input, or func's null_handling is NULL_IF_NULL (means null and non-null are exchangeable).
// then replace NullExpression with a TypedNullConstant
- if (currentArg.equals(NullExpression.INSTANCE) &&
- ( parmType.getMode().equals(TypeProtos.DataMode.OPTIONAL) ||
+ if (currentArg.equals(NullExpression.INSTANCE) && !MinorType.LATE.equals(parmType.getMinorType()) &&
+ (TypeProtos.DataMode.OPTIONAL.equals(parmType.getMode()) ||
matchedFuncHolder.getNullHandling() == FunctionTemplate.NullHandling.NULL_IF_NULL)) {
argsWithCast.add(new TypedNullConstant(parmType));
} else if (Types.softEquals(parmType, currentArg.getMajorType(), matchedFuncHolder.getNullHandling() == FunctionTemplate.NullHandling.NULL_IF_NULL) ||
http://git-wip-us.apache.org/repos/asf/drill/blob/2c470de3/exec/java-exec/src/test/java/org/apache/drill/exec/vector/complex/writer/TestComplexTypeReader.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/vector/complex/writer/TestComplexTypeReader.java b/exec/java-exec/src/test/java/org/apache/drill/exec/vector/complex/writer/TestComplexTypeReader.java
index c3cfb68..67b2e5a 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/exec/vector/complex/writer/TestComplexTypeReader.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/exec/vector/complex/writer/TestComplexTypeReader.java
@@ -1,4 +1,4 @@
-/**
+/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -299,4 +299,18 @@ public class TestComplexTypeReader extends BaseTestQuery{
Files.deleteIfExists(path1);
Files.deleteIfExists(path2);
}
+
+ @Test
+ public void testNonExistentFieldConverting() throws Exception {
+ String query = "select employee_id, convert_to(`complex_field`, 'JSON') as complex_field from cp.`employee.json` " +
+ "where employee_id = 1";
+
+ testBuilder()
+ .sqlQuery(query)
+ .unOrdered()
+ .baselineColumns("employee_id", "complex_field")
+ .baselineValues(1L, null)
+ .build()
+ .run();
+ }
}
[2/2] drill git commit: DRILL-5726: Support Impersonation without
authentication for REST API
Posted by am...@apache.org.
DRILL-5726: Support Impersonation without authentication for REST API
DRILL-5726: Changes after code review.
close apache/drill#910
Project: http://git-wip-us.apache.org/repos/asf/drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/789b83d7
Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/789b83d7
Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/789b83d7
Branch: refs/heads/master
Commit: 789b83d773b9022638c3e9841e9f13a7033cb60b
Parents: 2c470de
Author: Arina Ielchiieva <ar...@gmail.com>
Authored: Wed Aug 23 16:17:11 2017 +0300
Committer: Aman Sinha <as...@maprtech.com>
Committed: Sat Sep 2 23:00:07 2017 -0700
----------------------------------------------------------------------
.../drill/exec/server/rest/DrillRestServer.java | 28 +++++++--
.../drill/exec/server/rest/QueryResources.java | 7 ++-
.../drill/exec/server/rest/UserNameFilter.java | 61 ++++++++++++++++++++
.../drill/exec/server/rest/WebServer.java | 19 +++++-
.../src/main/resources/rest/query/query.ftl | 48 ++++++++++++++-
5 files changed, 153 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/drill/blob/789b83d7/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRestServer.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRestServer.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRestServer.java
index e88d1b0..bd01fea 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRestServer.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRestServer.java
@@ -1,4 +1,4 @@
-/**
+/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.jaxrs.base.JsonMappingExceptionMapper;
import com.fasterxml.jackson.jaxrs.base.JsonParseExceptionMapper;
import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
+import com.google.common.base.Strings;
import org.apache.drill.common.config.DrillConfig;
import org.apache.drill.exec.ExecConstants;
import org.apache.drill.exec.memory.BufferAllocator;
@@ -188,7 +189,6 @@ public class DrillRestServer extends ResourceConfig {
@Override
public WebUserConnection provide() {
- final HttpSession session = request.getSession();
final DrillbitContext drillbitContext = workManager.getContext();
final DrillConfig config = drillbitContext.getConfig();
@@ -198,9 +198,9 @@ public class DrillRestServer extends ResourceConfig {
config.getLong(ExecConstants.HTTP_SESSION_MEMORY_RESERVATION),
config.getLong(ExecConstants.HTTP_SESSION_MEMORY_MAXIMUM));
- final Principal sessionUserPrincipal = new AnonDrillUserPrincipal();
+ final Principal sessionUserPrincipal = createSessionUserPrincipal(config, request);
- // Create new UserSession for each request from Anonymous user
+ // Create new UserSession for each request from non-authenticated user
final UserSession drillUserSession = UserSession.Builder.newBuilder()
.withCredentials(UserBitShared.UserCredentials.newBuilder()
.setUserName(sessionUserPrincipal.getName())
@@ -230,6 +230,26 @@ public class DrillRestServer extends ResourceConfig {
public void dispose(WebUserConnection instance) {
}
+
+ /**
+ * Creates session user principal. If impersonation is enabled without authentication and User-Name header is present and valid,
+ * will create session user principal with provided user name, otherwise anonymous user name will be used.
+ * In both cases session user principal will have admin rights.
+ *
+ * @param config drill config
+ * @param request client request
+ * @return session user principal
+ */
+ private Principal createSessionUserPrincipal(DrillConfig config, HttpServletRequest request) {
+ if (WebServer.isImpersonationOnlyEnabled(config)) {
+ final String userName = request.getHeader("User-Name");
+ if (!Strings.isNullOrEmpty(userName)) {
+ return new DrillUserPrincipal(userName, true);
+ }
+ }
+ return new AnonDrillUserPrincipal();
+ }
+
}
// Provider which injects DrillUserPrincipal directly instead of getting it from SecurityContext and typecasting
http://git-wip-us.apache.org/repos/asf/drill/blob/789b83d7/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/QueryResources.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/QueryResources.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/QueryResources.java
index 99e26ff..c46c4b5 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/QueryResources.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/QueryResources.java
@@ -54,7 +54,12 @@ public class QueryResources {
@Path("/query")
@Produces(MediaType.TEXT_HTML)
public Viewable getQuery() {
- return ViewableWithPermissions.create(authEnabled.get(), "/rest/query/query.ftl", sc);
+ return ViewableWithPermissions.create(
+ authEnabled.get(),
+ "/rest/query/query.ftl",
+ sc,
+ // if impersonation is enabled without authentication, will provide mechanism to add user name to request header from Web UI
+ WebServer.isImpersonationOnlyEnabled(work.getContext().getConfig()));
}
@POST
http://git-wip-us.apache.org/repos/asf/drill/blob/789b83d7/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/UserNameFilter.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/UserNameFilter.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/UserNameFilter.java
new file mode 100644
index 0000000..b8c898c
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/UserNameFilter.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 org.apache.drill.exec.server.rest;
+
+import com.google.common.base.Strings;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.HttpMethod;
+import java.io.IOException;
+
+/**
+ * Responsible for filtering out POST requests that do not contain valid <b>User-Name</b> header.
+ */
+public class UserNameFilter implements Filter {
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+
+ }
+
+ @Override
+ public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
+ HttpServletRequest request = (HttpServletRequest) req;
+ HttpServletResponse response = (HttpServletResponse) resp;
+
+ if (HttpMethod.POST.equalsIgnoreCase(request.getMethod()) && Strings.isNullOrEmpty(request.getHeader("User-Name"))) {
+ response.reset();
+ response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED, "User-Name header is not set");
+ return;
+ }
+
+ chain.doFilter(request, response);
+ }
+
+ @Override
+ public void destroy() {
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/drill/blob/789b83d7/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/WebServer.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/WebServer.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/WebServer.java
index 1706b71..3fc95cd 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/WebServer.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/WebServer.java
@@ -1,4 +1,4 @@
-/**
+/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -20,7 +20,6 @@ package org.apache.drill.exec.server.rest;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.servlets.MetricsServlet;
import com.codahale.metrics.servlets.ThreadDumpServlet;
-import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
@@ -126,6 +125,16 @@ public class WebServer implements AutoCloseable {
private static final String DRILL_ICON_RESOURCE_RELATIVE_PATH = "img/drill.ico";
/**
+ * Checks if only impersonation is enabled.
+ *
+ * @param config Drill configuration
+ * @return true if impersonation without authentication is enabled, false otherwise
+ */
+ public static boolean isImpersonationOnlyEnabled(DrillConfig config) {
+ return !config.getBoolean(ExecConstants.USER_AUTHENTICATION_ENABLED) && config.getBoolean(ExecConstants.IMPERSONATION_ENABLED);
+ }
+
+ /**
* Start the web server including setup.
* @throws Exception
*/
@@ -185,6 +194,12 @@ public class WebServer implements AutoCloseable {
servletContextHandler.setSessionHandler(createSessionHandler(servletContextHandler.getSecurityHandler()));
}
+ if (isImpersonationOnlyEnabled(workManager.getContext().getConfig())) {
+ for (String path : new String[]{"/query", "/query.json"}) {
+ servletContextHandler.addFilter(UserNameFilter.class, path, EnumSet.of(DispatcherType.REQUEST));
+ }
+ }
+
if (config.getBoolean(ExecConstants.HTTP_CORS_ENABLED)) {
FilterHolder holder = new FilterHolder(CrossOriginFilter.class);
holder.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM,
http://git-wip-us.apache.org/repos/asf/drill/blob/789b83d7/exec/java-exec/src/main/resources/rest/query/query.ftl
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/resources/rest/query/query.ftl b/exec/java-exec/src/main/resources/rest/query/query.ftl
index 5033aca..f9765eb 100644
--- a/exec/java-exec/src/main/resources/rest/query/query.ftl
+++ b/exec/java-exec/src/main/resources/rest/query/query.ftl
@@ -11,6 +11,9 @@
<#include "*/generic.ftl">
<#macro page_head>
+ <#if model?? && model>
+ <script src="/static/js/jquery.form.js"></script>
+ </#if>
</#macro>
<#macro page_body>
@@ -21,8 +24,16 @@
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
Sample SQL query: <strong>SELECT * FROM cp.`employee.json` LIMIT 20</strong>
</div>
- <form role="form" action="/query" method="POST">
- <div class="form-group">
+
+ <#if model?? && model>
+ <div class="form-group">
+ <label for="userName">User Name</label>
+ <input type="text" size="30" name="userName" id="userName" placeholder="User Name">
+ </div>
+ </#if>
+
+ <form role="form" id="queryForm" action="/query" method="POST">
+ <div class="form-group">
<label for="queryType">Query Type</label>
<div class="radio">
<label>
@@ -47,8 +58,39 @@
<label for="query">Query</label>
<textarea class="form-control" id="query" rows="5" name="query" style="font-family: Courier;"></textarea>
</div>
- <button type="submit" class="btn btn-default">Submit</button>
+
+ <button class="btn btn-default" type=<#if model?? && model>"button" onclick="doSubmit()"<#else>"submit"</#if>>
+ Submit
+ </button>
</form>
+
+ <#if model?? && model>
+ <script>
+ function doSubmit() {
+ var userName = document.getElementById("userName").value;
+ if (!userName.trim()) {
+ alert("Please fill in User Name field");
+ return;
+ }
+ $.ajax({
+ type: "POST",
+ beforeSend: function (request) {
+ request.setRequestHeader("User-Name", userName);
+ },
+ url: "/query",
+ data: $("#queryForm").serializeArray(),
+ success: function (response) {
+ var newDoc = document.open("text/html", "replace");
+ newDoc.write(response);
+ newDoc.close();
+ },
+ error: function (request, textStatus, errorThrown) {
+ alert(errorThrown);
+ }
+ });
+ }
+ </script>
+ </#if>
</#macro>
<@page_html/>