asterixdb-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Pritom Ahmed (Code Review)" <do-not-re...@asterixdb.incubator.apache.org>
Subject Change in hyracks[master]: Fixed Admin Console pages.
Date Wed, 16 Dec 2015 00:34:19 GMT
Pritom Ahmed has uploaded a new change for review.

  https://asterix-gerrit.ics.uci.edu/557

Change subject: Fixed Admin Console pages.
......................................................................

Fixed Admin Console pages.

Previously the job details page of the admin console was not working correctly. Now It is
fixed.

Also fixed some internal issues like wrong time shown.

The following commits from your working branch will be included:

commit 4e9510e6ee44bed73d9ebcd0fdf91f077e577226
Author: Pritom Ahmed <pritom.11@gmail.com>
Date:   Fri Dec 11 20:10:44 2015 -0800

    Fix for package renaming refactoring.

commit c5080306033395015084ad848cb985f6f961195c
Author: Pritom Ahmed <pritom.11@gmail.com>
Date:   Fri Dec 11 11:39:36 2015 -0800

    Removed configuration parameter in CCConfig which determines the interval of cluster data
gathering in asterix.

commit 6b13cb6b327351ba81ebc22a81f26788409a656a
Author: Pritom Ahmed <pritom.11@gmail.com>
Date:   Thu Oct 22 17:30:13 2015 -0700

    Now JSON data in adminconsole for Job Details is shown in tabular form.

    Previously, in job details page of admin console, all the data was shown
    in raw JSON format. Now using a MIT licensed js library, it is shown
    in tabular form.

commit 5b43e763ab888364d845ff57b48332de2ad1dbda
Author: Pritom Ahmed <pritom.11@gmail.com>
Date:   Fri Aug 21 00:49:15 2015 -0700

    Added Headers for the data shown in Index page of adminconsole.

commit a61d64d9991609f4b2d17ff340c18bfc4afed398
Author: Pritom Ahmed <pritom.11@gmail.com>
Date:   Fri Aug 21 00:32:09 2015 -0700

    Previously in job summary, create time, start time and end time was never updated. As
a result they all were 0. Fixed it.

    In adminconsole's Index page, the job create time, start time and end time all were being
assigned with create time. Fixed it.
    The same problem was also present in the REST API as well. Also fixed it.

commit 76b7a9767657a18a64490429652df3a7f360b7ef
Author: Pritom Ahmed <pritom.11@gmail.com>
Date:   Tue Aug 18 14:13:26 2015 -0700

    Showing a message in job details page in admin console for jobs that were deleted because
the maximum size of job archive was reached.

commit 3774772a3eb8df4af5465c7f409ad3994d2f2fce
Author: Pritom Ahmed <pritom.11@gmail.com>
Date:   Tue Aug 18 13:48:28 2015 -0700

    Added a configuration parameter in CCConfig which determines the interval of cluster data
gathering in asterix.

commit 4610973533d0f8c996034c75316b63e0920fdcb6
Author: Pritom Ahmed <pritom.11@gmail.com>
Date:   Sun Aug 16 15:26:08 2015 -0700

    Beautified the job details page in adminconsole by adding tabs.

commit 32d4f0c85e77f967ed293be98efb00bf64edc5f1
Author: Pritom Ahmed <pritom.11@gmail.com>
Date:   Fri Aug 14 13:07:00 2015 -0700

    * Fixed the job details page in adminconsole. Previously it was broken. Now it shows the
raw JSON data sent to it. * Optimized the node details information sent by the adminconsole
API. Previously, the API was sending the full array everytime even though the whole array
was not full. As a result, there were many instances with no data. Now its sending only the
subarrays that actually contains data.

Change-Id: I3944ed0c972f227aa1397d1cf6608f78f5f8c540
---
M hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/NodeControllerState.java
M hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/adminconsole/pages/IndexPage.java
M hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/job/JobRun.java
M hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/scheduler/JobScheduler.java
M hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/GetJobSummariesJSONWork.java
M hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/JobCleanupWork.java
M hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/JobStartWork.java
M hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/JobletCleanupNotificationWork.java
M hyracks/hyracks-control/hyracks-control-cc/src/main/resources/org/apache/hyracks/control/cc/adminconsole/pages/AbstractPage.html
M hyracks/hyracks-control/hyracks-control-cc/src/main/resources/org/apache/hyracks/control/cc/adminconsole/pages/IndexPage.html
M hyracks/hyracks-control/hyracks-control-cc/src/main/resources/org/apache/hyracks/control/cc/adminconsole/pages/JobDetailsPage.html
M hyracks/hyracks-control/hyracks-control-cc/src/main/resources/static/javascript/adminconsole/JobDetailsPage.js
A hyracks/hyracks-control/hyracks-control-cc/src/main/resources/static/javascript/adminconsole/json.human.js
A hyracks/hyracks-control/hyracks-control-cc/src/main/resources/static/stylesheet/json.human.css
M pom.xml
15 files changed, 685 insertions(+), 49 deletions(-)


  git pull ssh://asterix-gerrit.ics.uci.edu:29418/hyracks refs/changes/57/557/1

diff --git a/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/NodeControllerState.java
b/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/NodeControllerState.java
index e8596ae..c0c1f71 100644
--- a/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/NodeControllerState.java
+++ b/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/NodeControllerState.java
@@ -18,10 +18,7 @@
  */
 package org.apache.hyracks.control.cc;
 
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 import org.json.JSONArray;
 import org.json.JSONException;
@@ -289,35 +286,48 @@
         o.put("boot-classpath", bootClasspath);
         o.put("input-arguments", new JSONArray(inputArguments));
         o.put("rrd-ptr", rrdPtr);
-        o.put("heartbeat-times", hbTime);
-        o.put("heap-init-sizes", heapInitSize);
-        o.put("heap-used-sizes", heapUsedSize);
-        o.put("heap-committed-sizes", heapCommittedSize);
-        o.put("heap-max-sizes", heapMaxSize);
-        o.put("nonheap-init-sizes", nonheapInitSize);
-        o.put("nonheap-used-sizes", nonheapUsedSize);
-        o.put("nonheap-committed-sizes", nonheapCommittedSize);
-        o.put("nonheap-max-sizes", nonheapMaxSize);
-        o.put("thread-counts", threadCount);
-        o.put("peak-thread-counts", peakThreadCount);
-        o.put("system-load-averages", systemLoadAverage);
-        o.put("gc-names", gcNames);
-        o.put("gc-collection-counts", gcCollectionCounts);
-        o.put("gc-collection-times", gcCollectionTimes);
-        o.put("net-payload-bytes-read", netPayloadBytesRead);
-        o.put("net-payload-bytes-written", netPayloadBytesWritten);
-        o.put("net-signaling-bytes-read", netSignalingBytesRead);
-        o.put("net-signaling-bytes-written", netSignalingBytesWritten);
-        o.put("dataset-net-payload-bytes-read", datasetNetPayloadBytesRead);
-        o.put("dataset-net-payload-bytes-written", datasetNetPayloadBytesWritten);
-        o.put("dataset-net-signaling-bytes-read", datasetNetSignalingBytesRead);
-        o.put("dataset-net-signaling-bytes-written", datasetNetSignalingBytesWritten);
-        o.put("ipc-messages-sent", ipcMessagesSent);
-        o.put("ipc-message-bytes-sent", ipcMessageBytesSent);
-        o.put("ipc-messages-received", ipcMessagesReceived);
-        o.put("ipc-message-bytes-received", ipcMessageBytesReceived);
-        o.put("disk-reads", diskReads);
-        o.put("disk-writes", diskWrites);
+        o.put("heartbeat-times", Arrays.copyOfRange(hbTime, 0, rrdPtr));
+        o.put("heap-init-sizes", Arrays.copyOfRange(heapInitSize, 0, rrdPtr));
+        o.put("heap-used-sizes", Arrays.copyOfRange(heapUsedSize, 0, rrdPtr));
+        o.put("heap-committed-sizes", Arrays.copyOfRange(heapCommittedSize, 0, rrdPtr));
+        o.put("heap-max-sizes", Arrays.copyOfRange(heapMaxSize, 0, rrdPtr));
+        o.put("nonheap-init-sizes", Arrays.copyOfRange(nonheapInitSize, 0, rrdPtr));
+        o.put("nonheap-used-sizes", Arrays.copyOfRange(nonheapUsedSize, 0, rrdPtr));
+        o.put("nonheap-committed-sizes", Arrays.copyOfRange(nonheapCommittedSize, 0, rrdPtr));
+        o.put("nonheap-max-sizes", Arrays.copyOfRange(nonheapMaxSize, 0, rrdPtr));
+        o.put("thread-counts", Arrays.copyOfRange(threadCount, 0, rrdPtr));
+        o.put("peak-thread-counts", Arrays.copyOfRange(peakThreadCount, 0, rrdPtr));
+        o.put("system-load-averages", Arrays.copyOfRange(systemLoadAverage, 0, rrdPtr));
+        o.put("gc-names", Arrays.copyOfRange(gcNames, 0, rrdPtr));
+
+
+
+        int gcN = hbSchema.getGarbageCollectorInfos().length;
+        long[][] tempGccCollectionCounts = new long[gcN][rrdPtr];
+        long[][] tempGccCollectionTimes = new long[gcN][rrdPtr];
+        for (int i = 0; i < gcN; ++i) {
+            for (int j = 0; j< rrdPtr; j++) {
+                tempGccCollectionCounts[i][j] = gcCollectionCounts[i][j];
+                tempGccCollectionTimes[i][j] = gcCollectionTimes[i][j];
+            }
+        }
+        o.put("gc-collection-counts", Arrays.copyOfRange(tempGccCollectionCounts, 0, gcN));
+        o.put("gc-collection-times", Arrays.copyOfRange(tempGccCollectionTimes, 0, gcN));
+
+        o.put("net-payload-bytes-read", Arrays.copyOfRange(netPayloadBytesRead, 0, rrdPtr));
+        o.put("net-payload-bytes-written", Arrays.copyOfRange(netPayloadBytesWritten, 0,
rrdPtr));
+        o.put("net-signaling-bytes-read", Arrays.copyOfRange(netSignalingBytesRead, 0, rrdPtr));
+        o.put("net-signaling-bytes-written", Arrays.copyOfRange(netSignalingBytesWritten,
0, rrdPtr));
+        o.put("dataset-net-payload-bytes-read", Arrays.copyOfRange(datasetNetPayloadBytesRead,
0, rrdPtr));
+        o.put("dataset-net-payload-bytes-written", Arrays.copyOfRange(datasetNetPayloadBytesWritten,
0, rrdPtr));
+        o.put("dataset-net-signaling-bytes-read", Arrays.copyOfRange(datasetNetSignalingBytesRead,
0, rrdPtr));
+        o.put("dataset-net-signaling-bytes-written", Arrays.copyOfRange(datasetNetSignalingBytesWritten,
0, rrdPtr));
+        o.put("ipc-messages-sent", Arrays.copyOfRange(ipcMessagesSent, 0, rrdPtr));
+        o.put("ipc-message-bytes-sent", Arrays.copyOfRange(ipcMessageBytesSent, 0, rrdPtr));
+        o.put("ipc-messages-received", Arrays.copyOfRange(ipcMessagesReceived, 0, rrdPtr));
+        o.put("ipc-message-bytes-received", Arrays.copyOfRange(ipcMessageBytesReceived, 0,
rrdPtr));
+        o.put("disk-reads", Arrays.copyOfRange(diskReads, 0, rrdPtr));
+        o.put("disk-writes", Arrays.copyOfRange(diskWrites, 0, rrdPtr));
 
         return o;
     }
diff --git a/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/adminconsole/pages/IndexPage.java
b/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/adminconsole/pages/IndexPage.java
index 18d83b5..709e406 100644
--- a/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/adminconsole/pages/IndexPage.java
+++ b/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/adminconsole/pages/IndexPage.java
@@ -32,6 +32,9 @@
 import org.apache.hyracks.control.cc.work.GetJobSummariesJSONWork;
 import org.apache.hyracks.control.cc.work.GetNodeSummariesJSONWork;
 
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
 public class IndexPage extends AbstractPage {
     private static final long serialVersionUID = 1L;
 
@@ -74,9 +77,9 @@
                 try {
                     item.add(new Label("job-id", o.getString("job-id")));
                     item.add(new Label("status", o.getString("status")));
-                    item.add(new Label("create-time", o.getString("create-time")));
-                    item.add(new Label("start-time", o.getString("start-time")));
-                    item.add(new Label("end-time", o.getString("end-time")));
+                    item.add(new Label("create-time", longToDateString(Long.parseLong(o.getString("create-time")))));
+                    item.add(new Label("start-time", longToDateString(Long.parseLong(o.getString("start-time")))));
+                    item.add(new Label("end-time", longToDateString(Long.parseLong(o.getString("end-time")))));
                     PageParameters params = new PageParameters();
                     params.add("job-id", o.getString("job-id"));
                     item.add(new BookmarkablePageLink<Object>("job-details", JobDetailsPage.class,
params));
@@ -87,4 +90,10 @@
         };
         add(jobList);
     }
+
+    private String longToDateString(long milliseconds) {
+        SimpleDateFormat sdf = new SimpleDateFormat("MMM dd,yyyy HH:mm:ss");
+        Date date = new Date(milliseconds);
+        return sdf.format(date);
+    }
 }
\ No newline at end of file
diff --git a/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/job/JobRun.java
b/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/job/JobRun.java
index 0d3367c..dbe4202 100644
--- a/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/job/JobRun.java
+++ b/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/job/JobRun.java
@@ -110,6 +110,7 @@
         profile = new JobProfile(jobId);
         connectorPolicyMap = new HashMap<ConnectorDescriptorId, IConnectorPolicy>();
         operatorLocations = new HashMap<OperatorDescriptorId, Map<Integer, String>>();
+        createTime = System.currentTimeMillis();
     }
 
     public DeploymentId getDeploymentId() {
@@ -242,8 +243,8 @@
         result.put("job-id", jobId.toString());
         result.put("status", getStatus());
         result.put("create-time", getCreateTime());
-        result.put("start-time", getCreateTime());
-        result.put("end-time", getCreateTime());
+        result.put("start-time", getStartTime());
+        result.put("end-time", getEndTime());
 
         JSONArray aClusters = new JSONArray();
         for (ActivityCluster ac : acg.getActivityClusterMap().values()) {
diff --git a/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/scheduler/JobScheduler.java
b/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/scheduler/JobScheduler.java
index f221530..38f5ee5 100644
--- a/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/scheduler/JobScheduler.java
+++ b/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/scheduler/JobScheduler.java
@@ -722,6 +722,7 @@
             }
         }
         run.setStatus(run.getPendingStatus(), run.getPendingExceptions());
+        run.setEndTime(System.currentTimeMillis());
         ccs.getActiveRunMap().remove(jobId);
         ccs.getRunMapArchive().put(jobId, run);
         ccs.getRunHistory().put(jobId, run.getExceptions());
diff --git a/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/GetJobSummariesJSONWork.java
b/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/GetJobSummariesJSONWork.java
index 2a3a4cb..8ab9210 100644
--- a/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/GetJobSummariesJSONWork.java
+++ b/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/GetJobSummariesJSONWork.java
@@ -49,8 +49,8 @@
             jo.put("type", "job-summary");
             jo.put("job-id", run.getJobId().toString());
             jo.put("create-time", run.getCreateTime());
-            jo.put("start-time", run.getCreateTime());
-            jo.put("end-time", run.getCreateTime());
+            jo.put("start-time", run.getStartTime());
+            jo.put("end-time", run.getEndTime());
             jo.put("status", run.getStatus().toString());
             summaries.put(jo);
         }
diff --git a/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/JobCleanupWork.java
b/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/JobCleanupWork.java
index 10da691..bd85463 100644
--- a/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/JobCleanupWork.java
+++ b/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/JobCleanupWork.java
@@ -106,6 +106,7 @@
             }
         }
         run.setStatus(run.getPendingStatus(), run.getPendingExceptions());
+        run.setEndTime(System.currentTimeMillis());
         ccs.getActiveRunMap().remove(jobId);
         ccs.getRunMapArchive().put(jobId, run);
         ccs.getRunHistory().put(jobId, run.getExceptions());
diff --git a/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/JobStartWork.java
b/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/JobStartWork.java
index ae269c7..293d2ed 100644
--- a/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/JobStartWork.java
+++ b/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/JobStartWork.java
@@ -61,6 +61,7 @@
             IActivityClusterGraphGenerator acgg = acggf.createActivityClusterGraphGenerator(jobId,
appCtx, jobFlags);
             JobRun run = new JobRun(ccs, deploymentId, jobId, acgg, jobFlags);
             run.setStatus(JobStatus.INITIALIZED, null);
+            run.setStartTime(System.currentTimeMillis());
             ccs.getActiveRunMap().put(jobId, run);
             appCtx.notifyJobCreation(jobId, acggf);
             run.setStatus(JobStatus.RUNNING, null);
diff --git a/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/JobletCleanupNotificationWork.java
b/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/JobletCleanupNotificationWork.java
index 4b8ee96..7f7841a 100644
--- a/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/JobletCleanupNotificationWork.java
+++ b/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/JobletCleanupNotificationWork.java
@@ -68,6 +68,7 @@
                 }
             }
             run.setStatus(run.getPendingStatus(), run.getPendingExceptions());
+            run.setEndTime(System.currentTimeMillis());
             ccs.getActiveRunMap().remove(jobId);
             ccs.getRunMapArchive().put(jobId, run);
             ccs.getRunHistory().put(jobId, run.getExceptions());
diff --git a/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/org/apache/hyracks/control/cc/adminconsole/pages/AbstractPage.html
b/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/org/apache/hyracks/control/cc/adminconsole/pages/AbstractPage.html
index a30e024..ecd0edf 100644
--- a/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/org/apache/hyracks/control/cc/adminconsole/pages/AbstractPage.html
+++ b/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/org/apache/hyracks/control/cc/adminconsole/pages/AbstractPage.html
@@ -28,6 +28,7 @@
     <script type="text/javascript" src="/static/javascript/jsplumb/jquery.jsPlumb-1.3.5-all-min.js"></script>
     <link rel="stylesheet" type="text/css" href="/static/stylesheet/jquery-ui/themes/base/jquery-ui.css"></link>
     <link rel="stylesheet" type="text/css" href="/static/stylesheet/adminconsole.css"></link>
+    <link rel="stylesheet" type="text/css" href="/static/stylesheet/json.human.css">
 </head>
 <body>
     <div id="header">
diff --git a/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/org/apache/hyracks/control/cc/adminconsole/pages/IndexPage.html
b/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/org/apache/hyracks/control/cc/adminconsole/pages/IndexPage.html
index d8a9e13..bdba2cb 100644
--- a/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/org/apache/hyracks/control/cc/adminconsole/pages/IndexPage.html
+++ b/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/org/apache/hyracks/control/cc/adminconsole/pages/IndexPage.html
@@ -19,9 +19,15 @@
 
 <wicket:extend xmlns:wicket>
     <div>
-        Registered Node Count: <span wicket:id="node-count"></span>
+        <b>Registered Node Count:</b> <span wicket:id="node-count"></span>
     </div>
     <table>
+        <tr>
+            <th>Node ID</th>
+            <th>Heap Used</th>
+            <th>System Load Average</th>
+            <th>Node Details</th>
+        </tr>
         <tr wicket:id="node-list">
             <td>
                 <span wicket:id="node-id"></span>
@@ -38,6 +44,13 @@
         </tr>
     </table>
     <table>
+        <tr>
+            <th>JOB ID</th>
+            <th>Status</th>
+            <th>Create Time</th>
+            <th>Start Time</th>
+            <th>Job Details</th>
+        </tr>
         <tr wicket:id="jobs-list">
             <td>
                 <span wicket:id="job-id"></span>
diff --git a/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/org/apache/hyracks/control/cc/adminconsole/pages/JobDetailsPage.html
b/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/org/apache/hyracks/control/cc/adminconsole/pages/JobDetailsPage.html
index 356f440..a385ed0 100644
--- a/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/org/apache/hyracks/control/cc/adminconsole/pages/JobDetailsPage.html
+++ b/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/org/apache/hyracks/control/cc/adminconsole/pages/JobDetailsPage.html
@@ -18,14 +18,67 @@
  !-->
 
 <wicket:extend xmlns:wicket>
-    <div id="job-specification" wicket:id="job-specification" style="display: none;">
+    <div id="tabs">
+        <ul>
+            <li><a href="#tabs-1">Activity Cluster Graph</a></li>
+                <li><a href="#tabs-2">Job Run</a></li>
+                <li><a href="#tabs-3">Job Timeline</a></li>
+        </ul>
+
+        <div id="tabs-1">
+            <table>
+                <tr>
+                    <td>
+                        <div>
+                            <div id="activityclustergraph" wicket:id="activity-cluster-graph"
style="display: none;"></div>
+                            <div id="activityclustergraphpre"></div>
+                        </div>
+                    </td>
+                </tr>
+            </table>
+        </div>
+
+        <div id="tabs-2">
+            <table>
+                <tr>
+                    <td>
+                        <div>
+                            <div id="jobrun" wicket:id="job-run" style="display: none;"></div>
+                            <div id="jobrunpre"></div>
+                        </div>
+                    </td>
+                </tr>
+            </table>
+        </div>
+
+        <div id="tabs-3">
+            <table>
+                <tr>
+                    <td>
+            <div wicket:id="job-timeline" style="overflow: auto;"></div>
+                    </td>
+                </tr>
+            </table>
+        </div>
     </div>
-    <div id="job-activity-graph" wicket:id="job-activity-graph" style="display: none;">
-    </div>
-    <div id="job-run" wicket:id="job-run" style="display: none;">
-    </div>
-    <div wicket:id="job-timeline" style="overflow: auto;"></div>
-    <div id="job-graph" style="position:relative"></div>
+
+    <script src="/static/javascript/adminconsole/json.human.js" type="text/javascript"></script>
+
+    <script>
+    var jobRun = JsonHuman.format(jQuery.parseJSON($('#jobrun')[0].innerHTML));
+    $('#jobrunpre').append(jobRun);
+
+    var activityGraph = JsonHuman.format(jQuery.parseJSON($('#activityclustergraph')[0].innerHTML));
+    $('#activityclustergraphpre').append(activityGraph);
+
+    if ($('#jobrun')[0].innerHTML == '{}') {
+        $('#jobrunpre')[0].innerHTML = "<b>Job is too old so it was cleared</b>";
+    }
+    if ($('#activityclustergraph')[0].innerHTML == '{}') {
+        $('#activityclustergraphpre')[0].innerHTML = "<b>Job is too old so it was cleared</b>";
+    }
+
+    </script>
 
     <script src="/static/javascript/adminconsole/Graphs.js" type="text/javascript"></script>
     <script src="/static/javascript/adminconsole/JobDetailsPage.js" type="text/javascript"></script>
diff --git a/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/static/javascript/adminconsole/JobDetailsPage.js
b/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/static/javascript/adminconsole/JobDetailsPage.js
index 8f67ec9..35eb6d9 100644
--- a/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/static/javascript/adminconsole/JobDetailsPage.js
+++ b/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/static/javascript/adminconsole/JobDetailsPage.js
@@ -17,6 +17,8 @@
  * under the License.
  */
  $(function() {
+    $('#tabs').tabs();
+
     var jobSpecDAG = new Graphs.DAG();
     var jobSpecRenderer;
 
@@ -94,7 +96,8 @@
     }
 
     function init() {
-        fetchJobSpecification();
+//        fetchJobSpecification();
+          fetchJobActivityGraph();
     }
 
     jsPlumb.bind("ready", function() {
diff --git a/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/static/javascript/adminconsole/json.human.js
b/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/static/javascript/adminconsole/json.human.js
new file mode 100644
index 0000000..0ddd80c
--- /dev/null
+++ b/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/static/javascript/adminconsole/json.human.js
@@ -0,0 +1,395 @@
+// MIT License:
+//
+// Copyright (c) 2015, Mariano Guerra
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+
+/*globals define, module, require, document*/
+(function (root, factory) {
+    "use strict";
+    if (typeof define === 'function' && define.amd) {
+        define([], factory);
+    } else if (typeof module !== 'undefined' && module.exports) {
+		module.exports = factory();
+    } else {
+        root.JsonHuman = factory();
+    }
+}(this, function () {
+    "use strict";
+
+    var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i <
l; i++) { if (i in this && this[i] === item) return i; } return -1; };
+
+    function makePrefixer(prefix) {
+        return function (name) {
+            return prefix + "-" + name;
+        };
+    }
+
+    function isArray(obj) {
+        return toString.call(obj) === '[object Array]';
+    }
+
+    function sn(tagName, className, data) {
+        var result = document.createElement(tagName);
+
+        result.className = className;
+        result.appendChild(document.createTextNode("" + data));
+
+        return result;
+    }
+
+    function scn(tagName, className, child) {
+        var result = document.createElement(tagName),
+            i, len;
+
+        result.className = className;
+
+        if (isArray(child)) {
+            for (i = 0, len = child.length; i < len; i += 1) {
+                result.appendChild(child[i]);
+            }
+        } else {
+            result.appendChild(child);
+        }
+
+        return result;
+    }
+
+    function linkNode(child, href, target){
+        var a = scn("a", HYPERLINK_CLASS_NAME, child);
+        a.setAttribute('href', href);
+        a.setAttribute('target', target);
+        return a;
+    }
+
+    var toString = Object.prototype.toString,
+        prefixer = makePrefixer("jh"),
+        p = prefixer,
+        ARRAY = 1,
+        BOOL = 2,
+        INT = 3,
+        FLOAT = 4,
+        STRING = 5,
+        OBJECT = 6,
+        FUNCTION = 7,
+        UNK = 99,
+
+        STRING_CLASS_NAME = p("type-string"),
+        STRING_EMPTY_CLASS_NAME = p("type-string") + " " + p("empty"),
+
+        BOOL_TRUE_CLASS_NAME = p("type-bool-true"),
+        BOOL_FALSE_CLASS_NAME = p("type-bool-false"),
+        BOOL_IMAGE = p("type-bool-image"),
+        INT_CLASS_NAME = p("type-int") + " " + p("type-number"),
+        FLOAT_CLASS_NAME = p("type-float") + " " + p("type-number"),
+
+        OBJECT_CLASS_NAME = p("type-object"),
+        OBJ_KEY_CLASS_NAME = p("key") + " " + p("object-key"),
+        OBJ_VAL_CLASS_NAME = p("value") + " " + p("object-value"),
+        OBJ_EMPTY_CLASS_NAME = p("type-object") + " " + p("empty"),
+
+        FUNCTION_CLASS_NAME = p("type-function"),
+
+        ARRAY_KEY_CLASS_NAME = p("key") + " " + p("array-key"),
+        ARRAY_VAL_CLASS_NAME = p("value") + " " + p("array-value"),
+        ARRAY_CLASS_NAME = p("type-array"),
+        ARRAY_EMPTY_CLASS_NAME = p("type-array") + " " + p("empty"),
+
+        HYPERLINK_CLASS_NAME = p('a'),
+
+        UNKNOWN_CLASS_NAME = p("type-unk");
+
+    function getType(obj) {
+        var type = typeof obj;
+
+        switch (type) {
+        case "boolean":
+            return BOOL;
+        case "string":
+            return STRING;
+        case "number":
+            return (obj % 1 === 0) ? INT : FLOAT;
+        case "function":
+            return FUNCTION;
+        default:
+            if (isArray(obj)) {
+                return ARRAY;
+            } else if (obj === Object(obj)) {
+                return OBJECT;
+            } else {
+                return UNK;
+            }
+        }
+    }
+
+    function _format(data, options, parentKey) {
+
+        var result, container, key, keyNode, valNode, len, childs, tr, value,
+            isEmpty = true,
+            accum = [],
+            type = getType(data);
+
+        // Initialized & used only in case of objects & arrays
+        var hyperlinksEnabled, aTarget, hyperlinkKeys ;
+
+        switch (type) {
+        case BOOL:
+            var boolOpt = options.bool;
+            container = document.createElement('div');
+
+            if(boolOpt.showImage) {
+                var img = document.createElement('img');
+                img.setAttribute('class', BOOL_IMAGE);
+
+                img.setAttribute('src',
+                  '' + (data ? boolOpt.img.true : boolOpt.img.false));
+
+                container.appendChild(img);
+            }
+
+            if(boolOpt.showText){
+                container.appendChild(data ?
+                    sn("span", BOOL_TRUE_CLASS_NAME, boolOpt.text.true) :
+                    sn("span", BOOL_FALSE_CLASS_NAME, boolOpt.text.false));
+            }
+
+            result = container;
+            break;
+
+        case STRING:
+            if (data === "") {
+                result = sn("span", STRING_EMPTY_CLASS_NAME, "(Empty Text)");
+            } else {
+                result = sn("span", STRING_CLASS_NAME, data);
+            }
+            break;
+        case INT:
+            result = sn("span", INT_CLASS_NAME, data);
+            break;
+        case FLOAT:
+            result = sn("span", FLOAT_CLASS_NAME, data);
+            break;
+        case OBJECT:
+            childs = [];
+
+            aTarget =  options.hyperlinks.target;
+            hyperlinkKeys = options.hyperlinks.keys;
+
+            // Is Hyperlink Key
+            hyperlinksEnabled =
+                options.hyperlinks.enable &&
+                hyperlinkKeys &&
+                hyperlinkKeys.length > 0;
+
+            for (key in data) {
+                isEmpty = false;
+
+                value = data[key];
+
+                valNode = _format(value, options, key);
+                keyNode = sn("th", OBJ_KEY_CLASS_NAME, key);
+
+                if( hyperlinksEnabled &&
+                    typeof(value) === 'string' &&
+                    indexOf.call(hyperlinkKeys, key) >= 0){
+
+                    valNode = scn("td", OBJ_VAL_CLASS_NAME, linkNode(valNode, value, aTarget));
+                } else {
+                    valNode = scn("td", OBJ_VAL_CLASS_NAME, valNode);
+                }
+
+                tr = document.createElement("tr");
+                tr.appendChild(keyNode);
+                tr.appendChild(valNode);
+
+                childs.push(tr);
+            }
+
+            if (isEmpty) {
+                result = sn("span", OBJ_EMPTY_CLASS_NAME, "(Empty Object)");
+            } else {
+                result = scn("table", OBJECT_CLASS_NAME, scn("tbody", '', childs));
+            }
+            break;
+        case FUNCTION:
+            result = sn("span", FUNCTION_CLASS_NAME, data);
+            break;
+        case ARRAY:
+            if (data.length > 0) {
+                childs = [];
+                var showArrayIndices = options.showArrayIndex;
+
+                aTarget =  options.hyperlinks.target;
+                hyperlinkKeys = options.hyperlinks.keys;
+
+                // Hyperlink of arrays?
+                hyperlinksEnabled = parentKey && options.hyperlinks.enable &&
+                    hyperlinkKeys &&
+                    hyperlinkKeys.length > 0 &&
+                    indexOf.call(hyperlinkKeys, parentKey) >= 0;
+
+                for (key = 0, len = data.length; key < len; key += 1) {
+
+                    keyNode = sn("th", ARRAY_KEY_CLASS_NAME, key);
+                    value = data[key];
+
+                    if(hyperlinksEnabled && typeof(value) === "string") {
+                        valNode = _format(value, options, key);
+                        valNode = scn("td", ARRAY_VAL_CLASS_NAME, linkNode(valNode, value,
aTarget));
+                    } else {
+                        valNode = scn("td", ARRAY_VAL_CLASS_NAME, _format(value, options,
key));
+                    }
+
+                    tr = document.createElement("tr");
+
+                    if(showArrayIndices) {
+                        tr.appendChild(keyNode);
+                    }
+                    tr.appendChild(valNode);
+
+                    childs.push(tr);
+                }
+
+                result = scn("table", ARRAY_CLASS_NAME, scn("tbody", '', childs));
+            } else {
+                result = sn("span", ARRAY_EMPTY_CLASS_NAME, "(Empty List)");
+            }
+            break;
+        default:
+            result = sn("span", UNKNOWN_CLASS_NAME, data);
+            break;
+        }
+
+        return result;
+    }
+
+    function format(data, options) {
+        options = validateOptions(options || {});
+
+        var result;
+
+        result = _format(data, options);
+        result.className = result.className + " " + prefixer("root");
+
+        return result;
+    }
+
+    function validateOptions(options){
+        options = validateArrayIndexOption(options);
+        options = validateHyperlinkOptions(options);
+        options = validateBoolOptions(options);
+
+        // Add any more option validators here
+
+        return options;
+    }
+
+
+    function validateArrayIndexOption(options) {
+        if(options.showArrayIndex === undefined){
+            options.showArrayIndex = true;
+        } else {
+            // Force to boolean just in case
+            options.showArrayIndex = options.showArrayIndex ? true: false;
+        }
+
+        return options;
+    }
+
+    function validateHyperlinkOptions(options){
+        var hyperlinks = {
+            enable : false,
+            keys : null,
+            target : ''
+        };
+
+        if(options.hyperlinks && options.hyperlinks.enable) {
+            hyperlinks.enable = true;
+
+            hyperlinks.keys =  isArray(options.hyperlinks.keys) ? options.hyperlinks.keys
: [];
+
+            if(options.hyperlinks.target) {
+                hyperlinks.target = '' + options.hyperlinks.target;
+            } else {
+                hyperlinks.target = '_blank';
+            }
+        }
+
+        options.hyperlinks = hyperlinks;
+
+        return options;
+    }
+
+    function validateBoolOptions(options){
+        if(!options.bool){
+            options.bool = {
+                text:  {
+                    true : "true",
+                    false : "false"
+                },
+                img : {
+                    true: "",
+                    false: ""
+                },
+                showImage : false,
+                showText : true
+            };
+        } else {
+            var boolOptions = options.bool;
+
+            // Show text if no option
+            if(!boolOptions.showText && !boolOptions.showImage){
+                boolOptions.showImage  =  false;
+                boolOptions.showText  =  true;
+            }
+
+            if(boolOptions.showText){
+                if(!boolOptions.text){
+                    boolOptions.text = {
+                        true : "true",
+                        false : "false"
+                    };
+                } else {
+                    var t = boolOptions.text.true, f = boolOptions.text.false;
+
+                    if(getType(t) != STRING || t === ''){
+                        boolOptions.text.true = 'true';
+                    }
+
+                    if(getType(f) != STRING || f === ''){
+                        boolOptions.text.false = 'false';
+                    }
+                }
+            }
+
+            if(boolOptions.showImage){
+                if(!boolOptions.img.true && !boolOptions.img.false){
+                    boolOptions.showImage = false;
+                }
+            }
+        }
+
+        return options;
+    }
+
+    return {
+        format: format
+    };
+}));
diff --git a/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/static/stylesheet/json.human.css
b/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/static/stylesheet/json.human.css
new file mode 100644
index 0000000..0c4f3cb
--- /dev/null
+++ b/hyracks/hyracks-control/hyracks-control-cc/src/main/resources/static/stylesheet/json.human.css
@@ -0,0 +1,146 @@
+// MIT License:
+//
+// Copyright (c) 2015, Mariano Guerra
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+
+.jh-root, .jh-type-object, .jh-type-array, .jh-key, .jh-value, .jh-root tr{
+ -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
+ -moz-box-sizing: border-box;    /* Firefox, other Gecko */
+ box-sizing: border-box;         /* Opera/IE 8+ */
+ font-weight: bold;
+}
+
+.jh-key, .jh-value{
+ margin: 0;
+ padding: 0.2em;
+ font-weight: bold;
+}
+
+.jh-value{
+    border-left: 1px solid #ddd;
+}
+
+.jh-type-number{
+    text-align: center;
+    color: #5286BC;
+}
+
+.jh-type-bool-true{
+    text-align: center;
+    color: #5A811C;
+}
+
+.jh-type-bool-false{
+    text-align: center;
+    color: #D45317;
+}
+
+.jh-type-bool-image {
+    width: 20px;
+    height: 20px;
+    margin-right: 5px;
+    vertical-align: bottom;
+}
+
+.jh-type-string{
+    font-style: italic;
+    color: #6E6E6E;
+}
+
+.jh-array-key{
+    font-style: italic;
+    font-size: small;
+    text-align: center;
+}
+
+.jh-object-key, .jh-array-key{
+    color: #444;
+    vertical-align: top;
+}
+
+.jh-type-object > tr:nth-child(odd), .jh-type-array > tr:nth-child(odd){
+    background-color: #f5f5f5;
+}
+
+.jh-type-object > tr:nth-child(even), .jh-type-array > tr:nth-child(even){
+    background-color: #fff;
+}
+
+.jh-type-object, .jh-type-array{
+    width: 100%;
+    border-collapse: collapse;
+}
+
+.jh-root{
+ border: 1px solid #ccc;
+ margin: 0.2em;
+}
+
+th.jh-key{
+ text-align: left;
+}
+
+.jh-type-object > tr, .jh-type-array > tr{
+ border: 1px solid #ddd;
+ border-bottom: none;
+}
+
+.jh-type-object > tr:last-child, .jh-type-array > tr:last-child{
+ border-bottom: 1px solid #ddd;
+}
+
+.jh-type-object > tr:hover, .jh-type-array > tr:hover{
+ border: 1px solid #F99927;
+}
+
+.jh-empty{
+ font-style: italic;
+ color: #999;
+ font-size: small;
+}
+
+.jh-a {
+    text-decoration: none;
+}
+
+.jh-a:hover{
+    text-decoration: underline;
+}
+
+.jh-a span.jh-type-string {
+    text-decoration: none;
+    color : #268ddd;
+    font-style: normal;
+}
+
+html, body{
+    margin: 0;
+    padding: 0;
+}
+
+body{
+    font-family: sans;
+    color: #222;
+    background-color: #fdfdfd;
+    width: 80%;
+    margin: 10%;
+    margin-top: 2em;
+}
diff --git a/pom.xml b/pom.xml
index fbe936d..ac1976e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -172,6 +172,7 @@
            <exclude>**/target/**</exclude>
            <exclude>**/output/**</exclude>
            <exclude>**/*.iml</exclude>
+           <exclude>**/stylesheet/json.human.css</exclude>
       </excludes>
         </configuration>
       </plugin>

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/557
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I3944ed0c972f227aa1397d1cf6608f78f5f8c540
Gerrit-PatchSet: 1
Gerrit-Project: hyracks
Gerrit-Branch: master
Gerrit-Owner: Pritom Ahmed <pritom.11@gmail.com>


Mime
View raw message