You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@drill.apache.org by lu...@apache.org on 2021/07/18 23:15:24 UTC
[drill] branch master updated: DRILL-7922: Add feature of viewing
external profile in web UI (#2225)
This is an automated email from the ASF dual-hosted git repository.
luoc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/drill.git
The following commit(s) were added to refs/heads/master by this push:
new d71864a DRILL-7922: Add feature of viewing external profile in web UI (#2225)
d71864a is described below
commit d71864a3d40b54c1f28926dc0d8d5ba1ea37298f
Author: feiteng <32...@qq.com>
AuthorDate: Thu Jul 8 23:37:13 2021 +0800
DRILL-7922: Add feature of viewing external profile in web UI (#2225)
---
.../exec/server/rest/profile/ProfileResources.java | 38 +++++++++++++++++++++-
.../src/main/resources/rest/profile/list.ftl | 13 ++++++++
2 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/ProfileResources.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/ProfileResources.java
index 1cdc359..b5e77b3 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/ProfileResources.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/ProfileResources.java
@@ -28,7 +28,9 @@ import java.util.concurrent.TimeUnit;
import javax.annotation.security.RolesAllowed;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
+import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@@ -57,11 +59,14 @@ import org.apache.drill.exec.store.sys.PersistentStore;
import org.apache.drill.exec.store.sys.PersistentStoreProvider;
import org.apache.drill.exec.work.WorkManager;
import org.apache.drill.exec.work.foreman.Foreman;
+import org.glassfish.jersey.media.multipart.FormDataParam;
import org.glassfish.jersey.server.mvc.Viewable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.drill.shaded.guava.com.google.common.base.Joiner;
import org.apache.drill.shaded.guava.com.google.common.collect.Lists;
+import org.apache.drill.shaded.guava.com.google.common.cache.Cache;
+import org.apache.drill.shaded.guava.com.google.common.cache.CacheBuilder;
@Path("/")
@RolesAllowed(DrillUserPrincipal.AUTHENTICATED_ROLE)
@@ -244,6 +249,9 @@ public class ProfileResources {
//max Param to cap listing of profiles
private static final String MAX_QPROFILES_PARAM = "max";
+ private static final Cache<String, String> PROFILE_CACHE = CacheBuilder
+ .newBuilder().expireAfterAccess(1, TimeUnit.MINUTES).build();
+
@GET
@Path("/profiles.json")
@Produces(MediaType.APPLICATION_JSON)
@@ -375,7 +383,14 @@ public class ProfileResources {
@Produces(MediaType.APPLICATION_JSON)
public String getProfileJSON(@PathParam("queryid") String queryId) {
try {
- return new String(work.getContext().getProfileStoreContext().getProfileStoreConfig().getSerializer().serialize(getQueryProfile(queryId)));
+ String profileData = PROFILE_CACHE.getIfPresent(queryId);
+ if (profileData == null) {
+ return new String(work.getContext().getProfileStoreContext()
+ .getProfileStoreConfig().getSerializer().serialize(getQueryProfile(queryId)));
+ } else {
+ PROFILE_CACHE.invalidate(queryId);
+ return profileData;
+ }
} catch (Exception e) {
logger.debug("Failed to serialize profile for: " + queryId);
return ("{ 'message' : 'error (unable to serialize profile)' }");
@@ -395,6 +410,27 @@ public class ProfileResources {
}
}
+ @POST
+ @Path("/profiles/view")
+ @Consumes(MediaType.MULTIPART_FORM_DATA)
+ @Produces(MediaType.TEXT_HTML)
+ public Viewable viewProfile(@FormDataParam("profileData") String content) {
+ try {
+ QueryProfile profile = work.getContext().getProfileStoreContext()
+ .getProfileStoreConfig().getSerializer().deserialize(content.getBytes());
+ PROFILE_CACHE.put(profile.getQueryId(), content);
+ ProfileWrapper wrapper = new ProfileWrapper(profile,
+ work.getContext().getConfig(), request);
+ return ViewableWithPermissions.create(authEnabled.get(),
+ "/rest/profile/profile.ftl", sc, wrapper);
+ } catch (Exception | Error e) {
+ logger.error("Exception was thrown when parsing profile {} :\n{}",
+ content, e);
+ return ViewableWithPermissions.create(authEnabled.get(),
+ "/rest/errorMessage.ftl", sc, e);
+ }
+ }
+
@GET
@Path("/profiles/cancel/{queryid}")
@Produces(MediaType.TEXT_PLAIN)
diff --git a/exec/java-exec/src/main/resources/rest/profile/list.ftl b/exec/java-exec/src/main/resources/rest/profile/list.ftl
index 58c86a4..5f4fd6c 100644
--- a/exec/java-exec/src/main/resources/rest/profile/list.ftl
+++ b/exec/java-exec/src/main/resources/rest/profile/list.ftl
@@ -84,6 +84,14 @@
$("#queryCancelModal").modal("show");
}
+ //Trigger the click event of file input and submit the file selected to the server
+ function viewProfile() {
+ $("#view-profile-file").change(function() {
+ $("#view-profile").submit();
+ this.value = null;
+ });
+ $("#view-profile-file").trigger("click");
+ }
</script>
<!-- CSS to control DataTable Elements -->
@@ -173,6 +181,11 @@
<input id="fetchMax" type="text" size="5" name="max" value="" style="text-align: right" />
<input type="submit" value="Reload"/>
</form></td>
+ <td align="right" width="1px">
+ <form id="view-profile" action="/profiles/view" enctype='multipart/form-data' method="post">
+ <input type="file" id="view-profile-file" name="profileData" style="display: none"/>
+ <input type="button" value="View" onclick = "viewProfile()"/>
+ </form></td>
</tr></table>
<!-- Placed after textbox to allow for DOM to contain "fetchMax" element -->
<script type="text/javascript" language="javascript">