asterixdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mb...@apache.org
Subject [1/2] asterixdb git commit: HTTP API++: Threaddumps / CC / INI, Misc
Date Tue, 13 Sep 2016 17:54:55 GMT
Repository: asterixdb
Updated Branches:
  refs/heads/master 534d58929 -> a001e46ce


http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a001e46c/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/GetNodeDetailsJSONWork.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/GetNodeDetailsJSONWork.java
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/GetNodeDetailsJSONWork.java
index 6d20874..dab41ba 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/GetNodeDetailsJSONWork.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/GetNodeDetailsJSONWork.java
@@ -18,14 +18,34 @@
  */
 package org.apache.hyracks.control.cc.work;
 
-import org.apache.hyracks.control.common.work.IPCResponder;
-import org.json.JSONObject;
+import java.io.File;
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+import java.lang.management.MemoryUsage;
+import java.lang.management.OperatingSystemMXBean;
+import java.lang.management.RuntimeMXBean;
+import java.lang.management.ThreadMXBean;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import org.apache.hyracks.control.cc.ClusterControllerService;
 import org.apache.hyracks.control.cc.NodeControllerState;
+import org.apache.hyracks.control.common.utils.PidHelper;
+import org.apache.hyracks.control.common.work.IPCResponder;
 import org.apache.hyracks.control.common.work.SynchronizableWork;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.kohsuke.args4j.Option;
 
 public class GetNodeDetailsJSONWork extends SynchronizableWork {
+    private static final Logger LOGGER = Logger.getLogger(GetNodeDetailsJSONWork.class.getName());
     private final ClusterControllerService ccs;
     private final String nodeId;
     private final boolean includeStats;
@@ -49,9 +69,20 @@ public class GetNodeDetailsJSONWork extends SynchronizableWork {
 
     @Override
     protected void doRun() throws Exception {
-        NodeControllerState ncs = ccs.getNodeMap().get(nodeId);
-        if (ncs != null) {
-            detail = ncs.toDetailedJSON(includeStats, includeConfig);
+        if (nodeId == null) {
+            // null nodeId is a request for CC
+            detail = getCCDetails();
+            if (includeConfig) {
+                addIni(detail, ccs.getCCConfig());
+            }
+        } else {
+            NodeControllerState ncs = ccs.getNodeMap().get(nodeId);
+            if (ncs != null) {
+                detail = ncs.toDetailedJSON(includeStats, includeConfig);
+                if (includeConfig) {
+                    addIni(detail, ncs.getNCConfig());
+                }
+            }
         }
 
         if (callback != null) {
@@ -59,6 +90,89 @@ public class GetNodeDetailsJSONWork extends SynchronizableWork {
         }
     }
 
+    private JSONObject getCCDetails() throws JSONException {
+        JSONObject o = new JSONObject();
+        MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
+        List<GarbageCollectorMXBean> gcMXBeans = ManagementFactory.getGarbageCollectorMXBeans();
+        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
+        OperatingSystemMXBean osMXBean = ManagementFactory.getOperatingSystemMXBean();
+        RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
+
+        if (includeConfig) {
+            o.put("os_name", osMXBean.getName());
+            o.put("arch", osMXBean.getArch());
+            o.put("os_version", osMXBean.getVersion());
+            o.put("num_processors", osMXBean.getAvailableProcessors());
+            o.put("vm_name", runtimeMXBean.getVmName());
+            o.put("vm_version", runtimeMXBean.getVmVersion());
+            o.put("vm_vendor", runtimeMXBean.getVmVendor());
+            o.put("classpath", runtimeMXBean.getClassPath().split(File.pathSeparator));
+            o.put("library_path", runtimeMXBean.getLibraryPath().split(File.pathSeparator));
+            o.put("boot_classpath", runtimeMXBean.getBootClassPath().split(File.pathSeparator));
+            o.put("input_arguments", runtimeMXBean.getInputArguments());
+            o.put("system_properties", runtimeMXBean.getSystemProperties());
+            o.put("pid", PidHelper.getPid());
+        }
+        if (includeStats) {
+            MemoryUsage heapUsage = memoryMXBean.getHeapMemoryUsage();
+            MemoryUsage nonheapUsage = memoryMXBean.getNonHeapMemoryUsage();
+
+            List<JSONObject> gcs = new ArrayList<>();
+
+            for (GarbageCollectorMXBean gcMXBean : gcMXBeans) {
+                JSONObject gc = new JSONObject();
+                gc.put("name", gcMXBean.getName());
+                gc.put("collection-time", gcMXBean.getCollectionTime());
+                gc.put("collection-count", gcMXBean.getCollectionCount());
+                gcs.add(gc);
+            }
+            o.put("gcs", gcs);
+
+            o.put("date", new Date());
+            o.put("heap_init_size", heapUsage.getInit());
+            o.put("heap_used_size", heapUsage.getUsed());
+            o.put("heap_committed_size", heapUsage.getCommitted());
+            o.put("heap_max_size", heapUsage.getMax());
+            o.put("nonheap_init_size", nonheapUsage.getInit());
+            o.put("nonheap_used_size", nonheapUsage.getUsed());
+            o.put("nonheap_committed_size", nonheapUsage.getCommitted());
+            o.put("nonheap_max_size", nonheapUsage.getMax());
+            o.put("thread_count", threadMXBean.getThreadCount());
+            o.put("peak_thread_count", threadMXBean.getPeakThreadCount());
+            o.put("started_thread_count", threadMXBean.getTotalStartedThreadCount());
+            o.put("system_load_average", osMXBean.getSystemLoadAverage());
+        }
+        return o;
+    }
+
+    private static void addIni(JSONObject o, Object configBean) throws JSONException {
+        Map<String, Object> iniMap = new HashMap<>();
+        for (Field f : configBean.getClass().getFields()) {
+            Option option = f.getAnnotation(Option.class);
+            if (option == null) {
+                continue;
+            }
+            final String optionName = option.name();
+            Object value = null;
+            try {
+                value = f.get(configBean);
+            } catch (IllegalAccessException e) {
+                LOGGER.log(Level.WARNING, "Unable to access ini option " + optionName, e);
+            }
+            if (value != null) {
+                if ("--".equals(optionName)) {
+                    iniMap.put("app_args", value);
+                } else {
+                    iniMap.put(optionName.substring(1).replace('-', '_'),
+                            "-iodevices".equals(optionName)
+                            ? String.valueOf(value).split(",")
+                            : value);
+                }
+            }
+        }
+        o.put("ini", iniMap);
+    }
+
     public JSONObject getDetail() {
         return detail;
     }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a001e46c/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/GetThreadDumpWork.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/GetThreadDumpWork.java
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/GetThreadDumpWork.java
new file mode 100644
index 0000000..b18d388
--- /dev/null
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/GetThreadDumpWork.java
@@ -0,0 +1,75 @@
+/*
+ * 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
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.hyracks.control.cc.work;
+
+import java.lang.management.ManagementFactory;
+import java.util.UUID;
+
+import org.apache.hyracks.control.cc.ClusterControllerService;
+import org.apache.hyracks.control.cc.NodeControllerState;
+import org.apache.hyracks.control.common.work.IResultCallback;
+import org.apache.hyracks.control.common.work.ThreadDumpWork;
+
+public class GetThreadDumpWork extends ThreadDumpWork {
+    private final ClusterControllerService ccs;
+    private final String nodeId;
+    private final IResultCallback<String> callback;
+    private final ThreadDumpRun run;
+
+
+    public GetThreadDumpWork(ClusterControllerService ccs, String nodeId, IResultCallback<String>
callback) {
+        this.ccs = ccs;
+        this.nodeId = nodeId;
+        this.callback = callback;
+        this.run = new ThreadDumpRun(UUID.randomUUID().toString());
+    }
+
+    @Override
+    protected void doRun() throws Exception {
+        if (nodeId == null) {
+            // null nodeId means the request is for the cluster controller
+            callback.setValue(takeDump(ManagementFactory.getThreadMXBean()));
+        } else {
+            final NodeControllerState ncState = ccs.getNodeMap().get(nodeId);
+            if (ncState == null) {
+                // bad node id, reply with null immediately
+                callback.setValue(null);
+            } else {
+                ccs.addThreadDumpRun(run.getRequestId(), run);
+                ncState.getNodeController().takeThreadDump(run.getRequestId());
+            }
+        }
+    }
+
+    public class ThreadDumpRun {
+        private final String requestId;
+
+        public ThreadDumpRun(String requestId) {
+            this.requestId = requestId;
+        }
+
+        public String getRequestId() {
+            return requestId;
+        }
+
+        public synchronized void notifyThreadDumpReceived(String threadDumpJSON) {
+            callback.setValue(threadDumpJSON);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a001e46c/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/NotifyThreadDumpResponse.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/NotifyThreadDumpResponse.java
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/NotifyThreadDumpResponse.java
new file mode 100644
index 0000000..bbdf211
--- /dev/null
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/NotifyThreadDumpResponse.java
@@ -0,0 +1,41 @@
+/*
+ * 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
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.hyracks.control.cc.work;
+
+import org.apache.hyracks.control.cc.ClusterControllerService;
+import org.apache.hyracks.control.common.work.AbstractWork;
+
+public class NotifyThreadDumpResponse extends AbstractWork {
+
+    private final ClusterControllerService ccs;
+
+    private final String requestId;
+    private final String threadDumpJSON;
+
+    public NotifyThreadDumpResponse(ClusterControllerService ccs, String requestId, String
threadDumpJSON) {
+        this.ccs = ccs;
+        this.requestId = requestId;
+        this.threadDumpJSON = threadDumpJSON;
+    }
+
+    @Override
+    public void run() {
+        ccs.removeThreadDumpRun(requestId).notifyThreadDumpReceived(threadDumpJSON);
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a001e46c/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/base/IClusterController.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/base/IClusterController.java
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/base/IClusterController.java
index ec1613d..a0c0f95 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/base/IClusterController.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/base/IClusterController.java
@@ -70,4 +70,6 @@ public interface IClusterController {
     public void reportResultPartitionFailure(JobId jobId, ResultSetId rsId, int partition)
throws Exception;
 
     public void getNodeControllerInfos() throws Exception;
+
+    public void notifyThreadDump(String nodeId, String requestId, String threadDumpJSON)
throws Exception;
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a001e46c/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/base/INodeController.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/base/INodeController.java
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/base/INodeController.java
index 75c3127..bd550b5 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/base/INodeController.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/base/INodeController.java
@@ -54,4 +54,6 @@ public interface INodeController {
     public void shutdown() throws Exception;
 
     public void sendApplicationMessageToNC(byte[] data, DeploymentId deploymentId, String
nodeId) throws Exception;
+
+    public void takeThreadDump(String requestId) throws Exception;
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a001e46c/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/CCNCFunctions.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/CCNCFunctions.java
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/CCNCFunctions.java
index 96dca4e..aeb2de7 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/CCNCFunctions.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/CCNCFunctions.java
@@ -101,6 +101,9 @@ public class CCNCFunctions {
         STATE_DUMP_REQUEST,
         STATE_DUMP_RESPONSE,
 
+        THREAD_DUMP_REQUEST,
+        THREAD_DUMP_RESPONSE,
+
         OTHER
     }
 
@@ -895,6 +898,54 @@ public class CCNCFunctions {
         }
     }
 
+    public static class ThreadDumpRequestFunction extends Function {
+        private static final long serialVersionUID = 1L;
+        private final String requestId;
+
+        public ThreadDumpRequestFunction(String requestId) {
+            this.requestId = requestId;
+        }
+
+        @Override
+        public FunctionId getFunctionId() {
+            return FunctionId.THREAD_DUMP_REQUEST;
+        }
+
+        public String getRequestId() {
+            return requestId;
+        }
+    }
+
+    public static class ThreadDumpResponseFunction extends Function {
+        private static final long serialVersionUID = 1L;
+        private final String nodeId;
+        private final String requestId;
+        private final String threadDumpJSON;
+
+        public ThreadDumpResponseFunction(String nodeId, String requestId, String threadDumpJSON)
{
+            this.nodeId = nodeId;
+            this.requestId = requestId;
+            this.threadDumpJSON = threadDumpJSON;
+        }
+
+        @Override
+        public FunctionId getFunctionId() {
+            return FunctionId.THREAD_DUMP_RESPONSE;
+        }
+
+        public String getNodeId() {
+            return nodeId;
+        }
+
+        public String getRequestId() {
+            return requestId;
+        }
+
+        public String getThreadDumpJSON() {
+            return threadDumpJSON;
+        }
+    }
+
     public static class ReportPartitionAvailabilityFunction extends Function {
         private static final long serialVersionUID = 1L;
 

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a001e46c/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/ClusterControllerRemoteProxy.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/ClusterControllerRemoteProxy.java
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/ClusterControllerRemoteProxy.java
index 416b064..ac6fc2c 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/ClusterControllerRemoteProxy.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/ClusterControllerRemoteProxy.java
@@ -116,24 +116,27 @@ public class ClusterControllerRemoteProxy implements IClusterController
{
         ipcHandle.send(-1, fn, null);
     }
 
-    public void registerResultPartitionLocation(JobId jobId, ResultSetId rsId, boolean orderedResult,
boolean emptyResult, int partition,
-            int nPartitions, NetworkAddress networkAddress) throws Exception {
-        CCNCFunctions.RegisterResultPartitionLocationFunction fn = new CCNCFunctions.RegisterResultPartitionLocationFunction(
-                jobId, rsId, orderedResult, emptyResult, partition, nPartitions, networkAddress);
+    @Override
+    public void registerResultPartitionLocation(JobId jobId, ResultSetId rsId, boolean orderedResult,
+                                                boolean emptyResult, int partition, int nPartitions,
+                                                NetworkAddress networkAddress) throws Exception
{
+        CCNCFunctions.RegisterResultPartitionLocationFunction fn =
+                new CCNCFunctions.RegisterResultPartitionLocationFunction(jobId, rsId, orderedResult,
emptyResult,
+                        partition, nPartitions, networkAddress);
         ipcHandle.send(-1, fn, null);
     }
 
     @Override
     public void reportResultPartitionWriteCompletion(JobId jobId, ResultSetId rsId, int partition)
throws Exception {
-        CCNCFunctions.ReportResultPartitionWriteCompletionFunction fn = new CCNCFunctions.ReportResultPartitionWriteCompletionFunction(
-                jobId, rsId, partition);
+        CCNCFunctions.ReportResultPartitionWriteCompletionFunction fn =
+                new CCNCFunctions.ReportResultPartitionWriteCompletionFunction(jobId, rsId,
partition);
         ipcHandle.send(-1, fn, null);
     }
 
     @Override
     public void reportResultPartitionFailure(JobId jobId, ResultSetId rsId, int partition)
throws Exception {
-        CCNCFunctions.ReportResultPartitionFailureFunction fn = new CCNCFunctions.ReportResultPartitionFailureFunction(
-                jobId, rsId, partition);
+        CCNCFunctions.ReportResultPartitionFailureFunction fn =
+                new CCNCFunctions.ReportResultPartitionFailureFunction(jobId, rsId, partition);
         ipcHandle.send(-1, fn, null);
     }
 
@@ -144,14 +147,20 @@ public class ClusterControllerRemoteProxy implements IClusterController
{
 
     @Override
     public void notifyStateDump(String nodeId, String stateDumpId, String state) throws Exception
{
-        CCNCFunctions.StateDumpResponseFunction fn = new CCNCFunctions.StateDumpResponseFunction(nodeId,
stateDumpId,
-                state);
+        CCNCFunctions.StateDumpResponseFunction fn =
+                new CCNCFunctions.StateDumpResponseFunction(nodeId, stateDumpId, state);
         ipcHandle.send(-1, fn, null);
     }
     @Override
     public void notifyShutdown(String nodeId) throws Exception{
         CCNCFunctions.ShutdownResponseFunction sdrf = new CCNCFunctions.ShutdownResponseFunction(nodeId);
-        ipcHandle.send(-1,sdrf,null);
+        ipcHandle.send(-1, sdrf, null);
     }
 
+    @Override
+    public void notifyThreadDump(String nodeId, String requestId, String threadDumpJSON)
throws Exception {
+        CCNCFunctions.ThreadDumpResponseFunction tdrf =
+                new CCNCFunctions.ThreadDumpResponseFunction(nodeId, requestId, threadDumpJSON);
+        ipcHandle.send(-1, tdrf, null);
+    }
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a001e46c/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/NodeControllerRemoteProxy.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/NodeControllerRemoteProxy.java
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/NodeControllerRemoteProxy.java
index 841c889..e4682dc 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/NodeControllerRemoteProxy.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/NodeControllerRemoteProxy.java
@@ -101,4 +101,10 @@ public class NodeControllerRemoteProxy implements INodeController {
                 deploymentId, nodeId);
         ipcHandle.send(-1, fn, null);
     }
+
+    @Override
+    public void takeThreadDump(String requestId) throws Exception {
+        CCNCFunctions.ThreadDumpRequestFunction fn = new CCNCFunctions.ThreadDumpRequestFunction(requestId);
+        ipcHandle.send(-1, fn, null);
+    }
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a001e46c/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/work/ThreadDumpWork.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/work/ThreadDumpWork.java
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/work/ThreadDumpWork.java
new file mode 100644
index 0000000..bf1965d
--- /dev/null
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/work/ThreadDumpWork.java
@@ -0,0 +1,83 @@
+/*
+ * 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
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.hyracks.control.common.work;
+
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public abstract class ThreadDumpWork extends SynchronizableWork {
+
+    protected String takeDump(ThreadMXBean threadMXBean) throws JSONException {
+        ThreadInfo [] threadInfos = threadMXBean.dumpAllThreads(true, true);
+        List<Map<String, Object>> threads = new ArrayList<>();
+
+        for (ThreadInfo thread : threadInfos) {
+            Map<String, Object> threadMap = new HashMap<>();
+            threadMap.put("name", thread.getThreadName());
+            threadMap.put("id", thread.getThreadId());
+            threadMap.put("state", thread.getThreadState().name());
+            List<String> stacktrace = new ArrayList<>();
+            for (StackTraceElement element : thread.getStackTrace()) {
+                stacktrace.add(element.toString());
+            }
+            threadMap.put("stack", stacktrace);
+
+            if (thread.getLockName() != null) {
+                threadMap.put("lock_name", thread.getLockName());
+            }
+            if (thread.getLockOwnerId() != -1) {
+                threadMap.put("lock_owner_id", thread.getLockOwnerId());
+            }
+            if (thread.getBlockedTime() > 0) {
+                threadMap.put("blocked_time", thread.getBlockedTime());
+            }
+            if (thread.getBlockedCount() > 0) {
+                threadMap.put("blocked_count", thread.getBlockedCount());
+            }
+            if (thread.getLockedMonitors().length > 0) {
+                threadMap.put("locked_monitors", thread.getLockedMonitors());
+            }
+            if (thread.getLockedSynchronizers().length > 0) {
+                threadMap.put("locked_synchronizers", thread.getLockedSynchronizers());
+            }
+            threads.add(threadMap);
+        }
+        JSONObject json = new JSONObject();
+        json.put("date", new Date());
+        json.put("threads", threads);
+
+        long [] deadlockedThreads = threadMXBean.findDeadlockedThreads();
+        long [] monitorDeadlockedThreads = threadMXBean.findMonitorDeadlockedThreads();
+        if (deadlockedThreads != null && deadlockedThreads.length > 0) {
+            json.put("deadlocked_thread_ids", deadlockedThreads);
+        }
+        if (monitorDeadlockedThreads != null && monitorDeadlockedThreads.length >
0) {
+            json.put("monitor_deadlocked_thread_ids", monitorDeadlockedThreads);
+        }
+        return json.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a001e46c/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/NodeControllerService.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/NodeControllerService.java
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/NodeControllerService.java
index edadf57..dbf3af0 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/NodeControllerService.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/NodeControllerService.java
@@ -88,6 +88,7 @@ import org.apache.hyracks.control.nc.work.ReportPartitionAvailabilityWork;
 import org.apache.hyracks.control.nc.work.ShutdownWork;
 import org.apache.hyracks.control.nc.work.StartTasksWork;
 import org.apache.hyracks.control.nc.work.StateDumpWork;
+import org.apache.hyracks.control.nc.work.NodeThreadDumpWork;
 import org.apache.hyracks.control.nc.work.UnDeployBinaryWork;
 import org.apache.hyracks.ipc.api.IIPCHandle;
 import org.apache.hyracks.ipc.api.IIPCI;
@@ -416,6 +417,10 @@ public class NodeControllerService implements IControllerService {
         return queue;
     }
 
+    public ThreadMXBean getThreadMXBean() {
+        return threadMXBean;
+    }
+
     private class HeartbeatTask extends TimerTask {
         private IClusterController cc;
 
@@ -509,72 +514,71 @@ public class NodeControllerService implements IControllerService {
                 Exception exception) {
             CCNCFunctions.Function fn = (CCNCFunctions.Function) payload;
             switch (fn.getFunctionId()) {
-                case SEND_APPLICATION_MESSAGE: {
-                    CCNCFunctions.SendApplicationMessageFunction amf = (CCNCFunctions.SendApplicationMessageFunction)
fn;
+                case SEND_APPLICATION_MESSAGE:
+                    CCNCFunctions.SendApplicationMessageFunction amf =
+                            (CCNCFunctions.SendApplicationMessageFunction) fn;
                     queue.schedule(new ApplicationMessageWork(NodeControllerService.this,
amf.getMessage(),
                             amf.getDeploymentId(), amf.getNodeId()));
                     return;
-                }
-                case START_TASKS: {
+
+                case START_TASKS:
                     CCNCFunctions.StartTasksFunction stf = (CCNCFunctions.StartTasksFunction)
fn;
                     queue.schedule(new StartTasksWork(NodeControllerService.this, stf.getDeploymentId(),
stf.getJobId(),
                             stf.getPlanBytes(), stf.getTaskDescriptors(), stf.getConnectorPolicies(),
stf.getFlags()));
                     return;
-                }
 
-                case ABORT_TASKS: {
+                case ABORT_TASKS:
                     CCNCFunctions.AbortTasksFunction atf = (CCNCFunctions.AbortTasksFunction)
fn;
                     queue.schedule(new AbortTasksWork(NodeControllerService.this, atf.getJobId(),
atf.getTasks()));
                     return;
-                }
 
-                case CLEANUP_JOBLET: {
+                case CLEANUP_JOBLET:
                     CCNCFunctions.CleanupJobletFunction cjf = (CCNCFunctions.CleanupJobletFunction)
fn;
                     queue.schedule(new CleanupJobletWork(NodeControllerService.this, cjf.getJobId(),
cjf.getStatus()));
                     return;
-                }
 
-                case REPORT_PARTITION_AVAILABILITY: {
-                    CCNCFunctions.ReportPartitionAvailabilityFunction rpaf = (CCNCFunctions.ReportPartitionAvailabilityFunction)
fn;
+                case REPORT_PARTITION_AVAILABILITY:
+                    CCNCFunctions.ReportPartitionAvailabilityFunction rpaf =
+                            (CCNCFunctions.ReportPartitionAvailabilityFunction) fn;
                     queue.schedule(new ReportPartitionAvailabilityWork(NodeControllerService.this,
                             rpaf.getPartitionId(), rpaf.getNetworkAddress()));
                     return;
-                }
 
-                case NODE_REGISTRATION_RESULT: {
+                case NODE_REGISTRATION_RESULT:
                     CCNCFunctions.NodeRegistrationResult nrrf = (CCNCFunctions.NodeRegistrationResult)
fn;
                     setNodeRegistrationResult(nrrf.getNodeParameters(), nrrf.getException());
                     return;
-                }
 
-                case GET_NODE_CONTROLLERS_INFO_RESPONSE: {
-                    CCNCFunctions.GetNodeControllersInfoResponseFunction gncirf = (CCNCFunctions.GetNodeControllersInfoResponseFunction)
fn;
+                case GET_NODE_CONTROLLERS_INFO_RESPONSE:
+                    CCNCFunctions.GetNodeControllersInfoResponseFunction gncirf =
+                            (CCNCFunctions.GetNodeControllersInfoResponseFunction) fn;
                     setNodeControllersInfo(gncirf.getNodeControllerInfos());
                     return;
-                }
 
-                case DEPLOY_BINARY: {
-                    CCNCFunctions.DeployBinaryFunction ndbf = (CCNCFunctions.DeployBinaryFunction)
fn;
-                    queue.schedule(new DeployBinaryWork(NodeControllerService.this, ndbf.getDeploymentId(),
-                            ndbf.getBinaryURLs()));
+                case DEPLOY_BINARY:
+                    CCNCFunctions.DeployBinaryFunction dbf = (CCNCFunctions.DeployBinaryFunction)
fn;
+                    queue.schedule(new DeployBinaryWork(NodeControllerService.this, dbf.getDeploymentId(),
+                            dbf.getBinaryURLs()));
                     return;
-                }
 
-                case UNDEPLOY_BINARY: {
+                case UNDEPLOY_BINARY:
                     CCNCFunctions.UnDeployBinaryFunction ndbf = (CCNCFunctions.UnDeployBinaryFunction)
fn;
                     queue.schedule(new UnDeployBinaryWork(NodeControllerService.this, ndbf.getDeploymentId()));
                     return;
-                }
 
-                case STATE_DUMP_REQUEST: {
+                case STATE_DUMP_REQUEST:
                     final CCNCFunctions.StateDumpRequestFunction dsrf = (StateDumpRequestFunction)
fn;
                     queue.schedule(new StateDumpWork(NodeControllerService.this, dsrf.getStateDumpId()));
                     return;
-                }
-                case SHUTDOWN_REQUEST: {
+
+                case SHUTDOWN_REQUEST:
                     queue.schedule(new ShutdownWork(NodeControllerService.this));
                     return;
-                }
+
+                case THREAD_DUMP_REQUEST:
+                    final CCNCFunctions.ThreadDumpRequestFunction tdrf = (CCNCFunctions.ThreadDumpRequestFunction)
fn;
+                    queue.schedule(new NodeThreadDumpWork(NodeControllerService.this, tdrf.getRequestId()));
+                    return;
             }
             throw new IllegalArgumentException("Unknown function: " + fn.getFunctionId());
 
@@ -594,7 +598,7 @@ public class NodeControllerService implements IControllerService {
     }
 
     /**
-     * Shutdown hook that invokes {@link NCApplicationEntryPoint#stop() stop} method.
+     * Shutdown hook that invokes {@link NodeControllerService#stop() stop} method.
      */
     private static class JVMShutdownHook extends Thread {
 

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a001e46c/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/work/NodeThreadDumpWork.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/work/NodeThreadDumpWork.java
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/work/NodeThreadDumpWork.java
new file mode 100644
index 0000000..1fc4690
--- /dev/null
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/work/NodeThreadDumpWork.java
@@ -0,0 +1,40 @@
+/*
+ * 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
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.hyracks.control.nc.work;
+
+import org.apache.hyracks.control.common.work.ThreadDumpWork;
+import org.apache.hyracks.control.nc.NodeControllerService;
+
+public class NodeThreadDumpWork extends ThreadDumpWork {
+    private final NodeControllerService ncs;
+    private final String requestId;
+
+    public NodeThreadDumpWork(NodeControllerService ncs, String requestId) {
+        this.ncs = ncs;
+        this.requestId = requestId;
+    }
+
+    @Override
+    protected void doRun() throws Exception {
+        final String result = takeDump(ncs.getThreadMXBean());
+
+        ncs.getClusterController().notifyThreadDump(
+                ncs.getApplicationContext().getNodeId(), requestId, result);
+    }
+}


Mime
View raw message