Michael Blow has submitted this change and it was merged. Change subject: Extend Cluster API Servlet, += Config / Stats ......................................................................
Extend Cluster API Servlet, += Config / Stats - New APIs to return NC stats & configs, discoverable URIs returned as part of /admin/cluster. - Tests for constant info (still need non-exact match tests for config / stats endpoints) Change-Id: Ia7549f2bb0b6621886356d50df800d447928aa2c Reviewed-on: https://asterix-gerrit.ics.uci.edu/1147 Tested-by: Jenkins <[email protected]> Integration-Tests: Jenkins <[email protected]> Reviewed-by: Till Westmann <[email protected]> --- M asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ClusterAPIServlet.java A asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ClusterNodeDetailsAPIServlet.java M asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplicationEntryPoint.java A asterixdb/asterix-app/src/test/resources/runtimets/queries/api/cluster_state_3/cluster_state_3.1.cstate.aql A asterixdb/asterix-app/src/test/resources/runtimets/queries/api/cluster_state_4/cluster_state_4.1.cstate.aql M asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1/cluster_state_1.1.adm A asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_3/cluster_state_3.1.adm A asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_4/cluster_state_4.1.adm M asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml M asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/ServletUtil.java M asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/util/AsterixClusterProperties.java M hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/HyracksClientInterfaceFunctions.java M hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/HyracksClientInterfaceRemoteProxy.java M hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/HyracksConnection.java M hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/IHyracksClientConnection.java M hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/IHyracksClientInterface.java M hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/ClusterControllerService.java M hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/NodeControllerState.java M hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/web/NodesRESTAPIFunction.java M hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/work/GetNodeDetailsJSONWork.java M hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/controllers/NodeRegistration.java A hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/utils/PidHelper.java M hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/NodeControllerService.java 23 files changed, 543 insertions(+), 84 deletions(-) Approvals: Till Westmann: Looks good to me, approved Jenkins: Verified; Verified Objections: Jenkins: Violations found diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ClusterAPIServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ClusterAPIServlet.java index 8a16cd7..8cedabc 100644 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ClusterAPIServlet.java +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ClusterAPIServlet.java @@ -31,6 +31,7 @@ import org.apache.asterix.app.result.ResultUtil; import org.apache.asterix.common.config.AbstractAsterixProperties; import org.apache.asterix.runtime.util.AsterixClusterProperties; +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -42,13 +43,16 @@ response.setContentType("application/json"); response.setCharacterEncoding("utf-8"); PrintWriter responseWriter = response.getWriter(); + JSONObject json; + try { - JSONObject responseObject = AsterixClusterProperties.INSTANCE.getClusterStateDescription(); - Map<String, Object> allProperties = getAllClusterProperties(); - responseObject.put("config", allProperties); - responseWriter.write(responseObject.toString(4)); + json = getClusterStateJSON(request, "node/"); response.setStatus(HttpServletResponse.SC_OK); - } catch (JSONException e) { + responseWriter.write(json.toString(4)); + } catch (IllegalArgumentException e) { + ResultUtil.apiErrorHandler(responseWriter, e); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + } catch (Exception e) { ResultUtil.apiErrorHandler(responseWriter, e); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } @@ -66,4 +70,26 @@ protected List<AbstractAsterixProperties> getPropertiesInstances() { return AbstractAsterixProperties.getImplementations(); } + + protected JSONObject getClusterStateJSON(HttpServletRequest request, String pathToNode) + throws JSONException { + JSONObject json; + json = AsterixClusterProperties.INSTANCE.getClusterStateDescription(); + Map<String, Object> allProperties = getAllClusterProperties(); + json.put("config", allProperties); + + JSONArray ncs = json.getJSONArray("ncs"); + final StringBuffer requestURL = request.getRequestURL(); + if (requestURL.charAt(requestURL.length() - 1) != '/') { + requestURL.append('/'); + } + requestURL.append(pathToNode); + String nodeURL = requestURL.toString().replaceAll("/[^./]+/\\.\\./", "/"); + for (int i = 0; i < ncs.length(); i++) { + JSONObject nc = ncs.getJSONObject(i); + nc.put("configUri", nodeURL + nc.getString("node_id") + "/config"); + nc.put("statsUri", nodeURL + nc.getString("node_id") + "/stats"); + } + return json; + } } diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ClusterNodeDetailsAPIServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ClusterNodeDetailsAPIServlet.java new file mode 100644 index 0000000..9cccdad --- /dev/null +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ClusterNodeDetailsAPIServlet.java @@ -0,0 +1,163 @@ +/* + * 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.asterix.api.http.servlet; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.asterix.app.result.ResultUtil; +import org.apache.hyracks.api.client.IHyracksClientConnection; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import static org.apache.asterix.api.http.servlet.ServletConstants.HYRACKS_CONNECTION_ATTR; + +public class ClusterNodeDetailsAPIServlet extends ClusterAPIServlet { + private static final long serialVersionUID = 1L; + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + PrintWriter responseWriter = response.getWriter(); + ServletContext context = getServletContext(); + IHyracksClientConnection hcc = (IHyracksClientConnection) context.getAttribute(HYRACKS_CONNECTION_ATTR); + JSONObject json; + + try { + if (request.getPathInfo() == null) { + json = new JSONObject(); + json.put("ncs", getClusterStateJSON(request, "").getJSONArray("ncs")); + } else { + json = processNode(request, hcc); + } + response.setStatus(HttpServletResponse.SC_OK); + response.setContentType("application/json"); + response.setCharacterEncoding("utf-8"); + responseWriter.write(json.toString(4)); + } catch (IllegalArgumentException e) { //NOSONAR - exception not logged or rethrown + response.sendError(HttpServletResponse.SC_NOT_FOUND); + } catch (Exception e) { + ResultUtil.apiErrorHandler(responseWriter, e); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + responseWriter.flush(); + } + + private JSONObject processNode(HttpServletRequest request, IHyracksClientConnection hcc) + throws Exception { + String[] parts = request.getPathInfo().substring(1).replaceAll("/+", "/").split("/"); + final String node = parts[0]; + + if (parts.length == 1) { + JSONArray ncs = getClusterStateJSON(request, "../").getJSONArray("ncs"); + for (int i = 0; i < ncs.length(); i++) { + JSONObject json = ncs.getJSONObject(i); + if (node.equals(json.getString("node_id"))) { + return json; + } + } + if ("cc".equals(node)) { + return new JSONObject(); + } + throw new IllegalArgumentException(); + } else if (parts.length == 2) { + JSONObject json; + + switch (parts[1]) { + case "config": + json = processNodeConfig(hcc, node); + break; + case "stats": + json = processNodeStats(hcc, node); + break; + default: + throw new IllegalArgumentException(); + } + fixupKeys(json); + + return json; + } else { + throw new IllegalArgumentException(); + } + } + + private void fixupKeys(JSONObject json) throws JSONException { + // TODO (mblow): generate the keys with _ to begin with + List<String> keys = new ArrayList<>(); + for (Iterator iter = json.keys(); iter.hasNext(); ) { + keys.add((String) iter.next()); + } + for (String key : keys) { + String newKey = key.replace('-', '_'); + if (!newKey.equals(key)) { + json.put(newKey, json.remove(key)); + } + } + } + + private JSONObject processNodeStats(IHyracksClientConnection hcc, String node) throws Exception { + if ("cc".equals(node)) { + return new JSONObject(); + } + + final String details = hcc.getNodeDetailsJSON(node, true, false); + if (details == null) { + throw new IllegalArgumentException(); + } + JSONObject json = new JSONObject(details); + int index = json.getInt("rrd-ptr") - 1; + json.remove("rrd-ptr"); + + List<String> keys = new ArrayList<>(); + for (Iterator iter = json.keys(); iter.hasNext(); ) { + keys.add((String) iter.next()); + } + + int gcNames = json.getJSONArray("gc-names").length(); + for (String key : keys) { + if (key.startsWith("gc-collection-")) { + final JSONArray gcArray = json.getJSONArray(key); + for (int i = 0; i < gcNames; i++) { + gcArray.put(i, gcArray.getJSONArray(i).get(index)); + } + } else if (!"node-id".equals(key) && !"gc-names".equals(key)) { + json.put(key, json.getJSONArray(key).get(index)); + } + } + return json; + } + + private JSONObject processNodeConfig(IHyracksClientConnection hcc, String node) throws Exception { + if ("cc".equals(node)) { + return new JSONObject(); + } + String config = hcc.getNodeDetailsJSON(node, false, true); + if (config == null) { + throw new IllegalArgumentException(); + } + return new JSONObject(config); + } +} diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplicationEntryPoint.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplicationEntryPoint.java index 5b36782..9883960 100644 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplicationEntryPoint.java +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplicationEntryPoint.java @@ -18,9 +18,6 @@ */ package org.apache.asterix.hyracks.bootstrap; -import static org.apache.asterix.api.http.servlet.ServletConstants.ASTERIX_BUILD_PROP_ATTR; -import static org.apache.asterix.api.http.servlet.ServletConstants.HYRACKS_CONNECTION_ATTR; - import java.util.ArrayList; import java.util.List; import java.util.logging.Level; @@ -32,6 +29,7 @@ import org.apache.asterix.api.http.servlet.APIServlet; import org.apache.asterix.api.http.servlet.AQLAPIServlet; import org.apache.asterix.api.http.servlet.ClusterAPIServlet; +import org.apache.asterix.api.http.servlet.ClusterNodeDetailsAPIServlet; import org.apache.asterix.api.http.servlet.ConnectorAPIServlet; import org.apache.asterix.api.http.servlet.DDLAPIServlet; import org.apache.asterix.api.http.servlet.FeedServlet; @@ -72,6 +70,10 @@ import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.servlet.ServletMapping; + +import static org.apache.asterix.api.http.servlet.ServletConstants.ASTERIX_BUILD_PROP_ATTR; +import static org.apache.asterix.api.http.servlet.ServletConstants.HYRACKS_CONNECTION_ATTR; public class CCApplicationEntryPoint implements ICCApplicationEntryPoint { @@ -216,6 +218,7 @@ addServlet(context, Servlets.SHUTDOWN); addServlet(context, Servlets.VERSION); addServlet(context, Servlets.CLUSTER_STATE); + addServlet(context, Servlets.CLUSTER_STATE_NODE_DETAIL); return jsonAPIServer; } @@ -235,8 +238,13 @@ return queryWebServer; } - protected void addServlet(ServletContextHandler context, Servlet servlet, String path) { - context.addServlet(new ServletHolder(servlet), path); + protected void addServlet(ServletContextHandler context, Servlet servlet, String... paths) { + final ServletHolder holder = new ServletHolder(servlet); + context.getServletHandler().addServlet(holder); + ServletMapping mapping = new ServletMapping(); + mapping.setServletName(holder.getName()); + mapping.setPathSpecs(paths); + context.getServletHandler().addServletMapping(mapping); } protected void addServlet(ServletContextHandler context, Servlets key) { @@ -284,6 +292,8 @@ return new VersionAPIServlet(); case CLUSTER_STATE: return new ClusterAPIServlet(); + case CLUSTER_STATE_NODE_DETAIL: + return new ClusterNodeDetailsAPIServlet(); default: throw new IllegalStateException(String.valueOf(key)); } diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/cluster_state_3/cluster_state_3.1.cstate.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/cluster_state_3/cluster_state_3.1.cstate.aql new file mode 100644 index 0000000..22b4a19 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/cluster_state_3/cluster_state_3.1.cstate.aql @@ -0,0 +1,25 @@ +/* + * 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. + */ +/* + * Test case Name : cluster_state_3 + * Description : cluster state api all nodes + * Expected Result : Positive + * Date : 8th September 2016 + */ +/node diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/cluster_state_4/cluster_state_4.1.cstate.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/cluster_state_4/cluster_state_4.1.cstate.aql new file mode 100644 index 0000000..0faba10 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/cluster_state_4/cluster_state_4.1.cstate.aql @@ -0,0 +1,25 @@ +/* + * 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. + */ +/* + * Test case Name : cluster_state_4 + * Description : cluster state api valid node + * Expected Result : Positive + * Date : 8th September 2016 + */ +/node/asterix_nc1 diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1/cluster_state_1.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1/cluster_state_1.1.adm index 0bc8f17..1dfa743 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1/cluster_state_1.1.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1/cluster_state_1.1.adm @@ -1,6 +1,4 @@ { - "Metadata_Node": "asterix_nc1", - "State": "ACTIVE", "config": { "api.port": 19002, "cc.java.opts": "-Xmx1024m", @@ -51,8 +49,26 @@ "web.queryinterface.port": 19006, "web.secondary.port": 19005 }, - "partition_0": "asterix_nc1", - "partition_1": "asterix_nc1", - "partition_2": "asterix_nc2", - "partition_3": "asterix_nc2" + "metadata_node": "asterix_nc1", + "ncs": [ + { + "configUri": "http://127.0.0.1:19002/admin/cluster/node/asterix_nc1/config", + "node_id": "asterix_nc1", + "partitions": [ + "partition_0", + "partition_1" + ], + "statsUri": "http://127.0.0.1:19002/admin/cluster/node/asterix_nc1/stats" + }, + { + "configUri": "http://127.0.0.1:19002/admin/cluster/node/asterix_nc2/config", + "node_id": "asterix_nc2", + "partitions": [ + "partition_2", + "partition_3" + ], + "statsUri": "http://127.0.0.1:19002/admin/cluster/node/asterix_nc2/stats" + } + ], + "state": "ACTIVE" } \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_3/cluster_state_3.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_3/cluster_state_3.1.adm new file mode 100644 index 0000000..2bbfa10 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_3/cluster_state_3.1.adm @@ -0,0 +1,20 @@ +{"ncs": [ + { + "configUri": "http://127.0.0.1:19002/admin/cluster/node/asterix_nc1/config", + "node_id": "asterix_nc1", + "partitions": [ + "partition_0", + "partition_1" + ], + "statsUri": "http://127.0.0.1:19002/admin/cluster/node/asterix_nc1/stats" + }, + { + "configUri": "http://127.0.0.1:19002/admin/cluster/node/asterix_nc2/config", + "node_id": "asterix_nc2", + "partitions": [ + "partition_2", + "partition_3" + ], + "statsUri": "http://127.0.0.1:19002/admin/cluster/node/asterix_nc2/stats" + } +]} diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_4/cluster_state_4.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_4/cluster_state_4.1.adm new file mode 100644 index 0000000..819c1e7 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_4/cluster_state_4.1.adm @@ -0,0 +1,9 @@ +{ + "configUri": "http://127.0.0.1:19002/admin/cluster/node/asterix_nc1/config", + "node_id": "asterix_nc1", + "partitions": [ + "partition_0", + "partition_1" + ], + "statsUri": "http://127.0.0.1:19002/admin/cluster/node/asterix_nc1/stats" +} diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml index 34a0805..b00d995 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml +++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml @@ -7315,5 +7315,15 @@ <expected-error>HTTP/1.1 404 Not Found</expected-error> </compilation-unit> </test-case> + <test-case FilePath="api"> + <compilation-unit name="cluster_state_3"> + <output-dir compare="Text">cluster_state_3</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="api"> + <compilation-unit name="cluster_state_4"> + <output-dir compare="Text">cluster_state_4</output-dir> + </compilation-unit> + </test-case> </test-group> </test-suite> diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/ServletUtil.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/ServletUtil.java index 9e9bbc5..047f010 100644 --- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/ServletUtil.java +++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/ServletUtil.java @@ -35,7 +35,8 @@ CONNECTOR("/connector"), SHUTDOWN("/admin/shutdown"), VERSION("/admin/version"), - CLUSTER_STATE("/admin/cluster"); + CLUSTER_STATE("/admin/cluster"), + CLUSTER_STATE_NODE_DETAIL("/admin/cluster/node/*"); private final String path; diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/util/AsterixClusterProperties.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/util/AsterixClusterProperties.java index 2457ddc..d201d60 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/util/AsterixClusterProperties.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/util/AsterixClusterProperties.java @@ -668,10 +668,17 @@ public synchronized JSONObject getClusterStateDescription() throws JSONException { JSONObject stateDescription = new JSONObject(); - stateDescription.put("State", state.name()); - stateDescription.put("Metadata_Node", currentMetadataNode); - for (ClusterPartition partition : clusterPartitions.values()) { - stateDescription.put("partition_" + partition.getPartitionId(), partition.getActiveNodeId()); + stateDescription.put("state", state.name()); + stateDescription.put("metadata_node", currentMetadataNode); + for (Map.Entry<String, ClusterPartition[]> entry : node2PartitionsMap.entrySet()) { + JSONObject nodeJSON = new JSONObject(); + nodeJSON.put("node_id", entry.getKey()); + List<String> partitions = new ArrayList<>(); + for (ClusterPartition part : entry.getValue()) { + partitions.add("partition_" + part.getPartitionId()); + } + nodeJSON.put("partitions", partitions); + stateDescription.accumulate("ncs", nodeJSON); } return stateDescription; } diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/HyracksClientInterfaceFunctions.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/HyracksClientInterfaceFunctions.java index bf36183..ca0783b 100644 --- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/HyracksClientInterfaceFunctions.java +++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/HyracksClientInterfaceFunctions.java @@ -45,7 +45,8 @@ GET_NODE_CONTROLLERS_INFO, CLI_DEPLOY_BINARY, CLI_UNDEPLOY_BINARY, - CLUSTER_SHUTDOWN + CLUSTER_SHUTDOWN, + GET_NODE_DETAILS_JSON } public abstract static class Function implements Serializable { @@ -294,4 +295,34 @@ } } + public static class GetNodeDetailsJSONFunction extends Function { + private static final long serialVersionUID = 1L; + private final String nodeId; + private final boolean includeStats; + private final boolean includeConfig; + + public GetNodeDetailsJSONFunction(String nodeId, boolean includeStats, boolean includeConfig) { + this.nodeId = nodeId; + this.includeStats = includeStats; + this.includeConfig = includeConfig; + } + + public String getNodeId() { + return nodeId; + } + + public boolean isIncludeStats() { + return includeStats; + } + + public boolean isIncludeConfig() { + return includeConfig; + } + + @Override + public FunctionId getFunctionId() { + return FunctionId.GET_NODE_DETAILS_JSON; + } + } + } diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/HyracksClientInterfaceRemoteProxy.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/HyracksClientInterfaceRemoteProxy.java index 25b5a0f..3f453e5 100644 --- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/HyracksClientInterfaceRemoteProxy.java +++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/HyracksClientInterfaceRemoteProxy.java @@ -131,4 +131,11 @@ throw new IPCException("CC refused to release connection after 9 seconds"); } } + + @Override + public String getNodeDetailsJSON(String nodeId, boolean includeStats, boolean includeConfig) throws Exception { + HyracksClientInterfaceFunctions.GetNodeDetailsJSONFunction gjsf = + new HyracksClientInterfaceFunctions.GetNodeDetailsJSONFunction(nodeId, includeStats, includeConfig); + return (String) rpci.call(ipcHandle, gjsf); + } } diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/HyracksConnection.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/HyracksConnection.java index 3f1ced6..73813f3 100644 --- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/HyracksConnection.java +++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/HyracksConnection.java @@ -187,8 +187,14 @@ public JobInfo getJobInfo(JobId jobId) throws Exception { return hci.getJobInfo(jobId); } + @Override public void stopCluster() throws Exception{ hci.stopCluster(); } + + @Override + public String getNodeDetailsJSON(String nodeId, boolean includeStats, boolean includeConfig) throws Exception { + return hci.getNodeDetailsJSON(nodeId, includeStats, includeConfig); + } } diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/IHyracksClientConnection.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/IHyracksClientConnection.java index 824c914..0690c9f 100644 --- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/IHyracksClientConnection.java +++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/IHyracksClientConnection.java @@ -188,4 +188,13 @@ */ public void stopCluster() throws Exception; + /** + * Get details of specified node as JSON object + * @param nodeId + * id the subject node + * @param includeStats + * @param includeConfig @return serialized JSON containing the node details + * @throws Exception + */ + public String getNodeDetailsJSON(String nodeId, boolean includeStats, boolean includeConfig) throws Exception; } diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/IHyracksClientInterface.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/IHyracksClientInterface.java index b70ef41..4ddb81f 100644 --- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/IHyracksClientInterface.java +++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/client/IHyracksClientInterface.java @@ -56,4 +56,5 @@ public void stopCluster() throws Exception; + public String getNodeDetailsJSON(String nodeId, boolean includeStats, boolean includeConfig) throws Exception; } diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/ClusterControllerService.java b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/ClusterControllerService.java index ae097a6..8dada48 100644 --- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/ClusterControllerService.java +++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/ClusterControllerService.java @@ -41,7 +41,6 @@ import org.apache.hyracks.api.client.NodeControllerInfo; import org.apache.hyracks.api.comm.NetworkAddress; import org.apache.hyracks.api.context.ICCContext; -import org.apache.hyracks.api.dataset.DatasetDirectoryRecord; import org.apache.hyracks.api.dataset.DatasetJobRecord.Status; import org.apache.hyracks.api.deployment.DeploymentId; import org.apache.hyracks.api.exceptions.HyracksDataException; @@ -67,6 +66,7 @@ import org.apache.hyracks.control.cc.work.GetJobInfoWork; import org.apache.hyracks.control.cc.work.GetJobStatusWork; import org.apache.hyracks.control.cc.work.GetNodeControllersInfoWork; +import org.apache.hyracks.control.cc.work.GetNodeDetailsJSONWork; import org.apache.hyracks.control.cc.work.GetResultPartitionLocationsWork; import org.apache.hyracks.control.cc.work.GetResultStatusWork; import org.apache.hyracks.control.cc.work.JobStartWork; @@ -418,6 +418,8 @@ return; } + case CREATE_JOB: + break; case GET_JOB_STATUS: { HyracksClientInterfaceFunctions.GetJobStatusFunction gjsf = (HyracksClientInterfaceFunctions.GetJobStatusFunction) fn; @@ -457,12 +459,14 @@ return; } + case GET_DATASET_RECORD_DESCRIPTOR: + break; case GET_DATASET_RESULT_LOCATIONS: { HyracksClientInterfaceFunctions.GetDatasetResultLocationsFunction gdrlf = (HyracksClientInterfaceFunctions.GetDatasetResultLocationsFunction) fn; workQueue.schedule(new GetResultPartitionLocationsWork(ClusterControllerService.this, gdrlf.getJobId(), gdrlf.getResultSetId(), gdrlf.getKnownRecords(), - new IPCResponder<DatasetDirectoryRecord[]>(handle, mid))); + new IPCResponder<>(handle, mid))); return; } @@ -476,7 +480,7 @@ case GET_NODE_CONTROLLERS_INFO: { workQueue.schedule(new GetNodeControllersInfoWork(ClusterControllerService.this, - new IPCResponder<Map<String, NodeControllerInfo>>(handle, mid))); + new IPCResponder<>(handle, mid))); return; } @@ -493,7 +497,7 @@ HyracksClientInterfaceFunctions.CliDeployBinaryFunction dbf = (HyracksClientInterfaceFunctions.CliDeployBinaryFunction) fn; workQueue.schedule(new CliDeployBinaryWork(ClusterControllerService.this, dbf.getBinaryURLs(), - dbf.getDeploymentId(), new IPCResponder<DeploymentId>(handle, mid))); + dbf.getDeploymentId(), new IPCResponder<>(handle, mid))); return; } @@ -501,14 +505,21 @@ HyracksClientInterfaceFunctions.CliUnDeployBinaryFunction udbf = (HyracksClientInterfaceFunctions.CliUnDeployBinaryFunction) fn; workQueue.schedule(new CliUnDeployBinaryWork(ClusterControllerService.this, udbf.getDeploymentId(), - new IPCResponder<DeploymentId>(handle, mid))); + new IPCResponder<>(handle, mid))); return; } case CLUSTER_SHUTDOWN: { workQueue.schedule(new ClusterShutdownWork(ClusterControllerService.this, - new IPCResponder<Boolean>(handle, mid))); + new IPCResponder<>(handle, mid))); return; } + + case GET_NODE_DETAILS_JSON: + HyracksClientInterfaceFunctions.GetNodeDetailsJSONFunction gndjf = + (HyracksClientInterfaceFunctions.GetNodeDetailsJSONFunction) fn; + workQueue.schedule(new GetNodeDetailsJSONWork(ClusterControllerService.this, gndjf.getNodeId(), + gndjf.isIncludeStats(), gndjf.isIncludeConfig(), new IPCResponder<>(handle, mid))); + return; } try { handle.send(mid, null, new IllegalArgumentException("Unknown function " + fn.getFunctionId())); diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/NodeControllerState.java b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/NodeControllerState.java index 7fd027b..a848c6e 100644 --- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/NodeControllerState.java +++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/NodeControllerState.java @@ -20,7 +20,6 @@ import java.io.File; import java.util.Arrays; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -76,6 +75,8 @@ private final List<String> inputArguments; private final Map<String, String> systemProperties; + + private final int pid; private final HeartbeatSchema hbSchema; @@ -147,7 +148,7 @@ dataPort = reg.getDataPort(); datasetPort = reg.getDatasetPort(); messagingPort = reg.getMessagingPort(); - activeJobIds = new HashSet<JobId>(); + activeJobIds = new HashSet<>(); osName = reg.getOSName(); arch = reg.getArch(); @@ -161,6 +162,7 @@ bootClasspath = reg.getBootClasspath(); inputArguments = reg.getInputArguments(); systemProperties = reg.getSystemProperties(); + pid = reg.getPid(); hbSchema = reg.getHeartbeatSchema(); @@ -203,7 +205,7 @@ rrdPtr = 0; } - public void notifyHeartbeat(HeartbeatData hbData) { + public synchronized void notifyHeartbeat(HeartbeatData hbData) { lastHeartbeatDuration = 0; hbTime[rrdPtr] = System.currentTimeMillis(); if (hbData != null) { @@ -282,51 +284,57 @@ return o; } - public JSONObject toDetailedJSON() throws JSONException { + public synchronized JSONObject toDetailedJSON(boolean includeStats, boolean includeConfig) throws JSONException { JSONObject o = new JSONObject(); o.put("node-id", ncConfig.nodeId); - o.put("os-name", osName); - o.put("arch", arch); - o.put("os-version", osVersion); - o.put("num-processors", nProcessors); - o.put("vm-name", vmName); - o.put("vm-version", vmVersion); - o.put("vm-vendor", vmVendor); - o.put("classpath", new JSONArray(Arrays.asList(classpath.split(File.pathSeparator)))); - o.put("library-path", new JSONArray(Arrays.asList(libraryPath.split(File.pathSeparator)))); - o.put("boot-classpath", new JSONArray(Arrays.asList(bootClasspath.split(File.pathSeparator)))); - 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); + if (includeConfig) { + o.put("os-name", osName); + o.put("arch", arch); + o.put("os-version", osVersion); + o.put("num-processors", nProcessors); + o.put("vm-name", vmName); + o.put("vm-version", vmVersion); + o.put("vm-vendor", vmVendor); + o.put("classpath", new JSONArray(Arrays.asList(classpath.split(File.pathSeparator)))); + o.put("library-path", new JSONArray(Arrays.asList(libraryPath.split(File.pathSeparator)))); + o.put("boot-classpath", new JSONArray(Arrays.asList(bootClasspath.split(File.pathSeparator)))); + o.put("input-arguments", new JSONArray(inputArguments)); + o.put("system-properties", new JSONObject(systemProperties)); + o.put("pid", pid); + } + if (includeStats) { + 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); + } return o; } diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/web/NodesRESTAPIFunction.java b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/web/NodesRESTAPIFunction.java index 8423ea6..58deb55 100644 --- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/web/NodesRESTAPIFunction.java +++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/web/NodesRESTAPIFunction.java @@ -43,7 +43,7 @@ result.put("result", gnse.getSummaries()); } else { String nodeId = arguments[0]; - GetNodeDetailsJSONWork gnde = new GetNodeDetailsJSONWork(ccs, nodeId); + GetNodeDetailsJSONWork gnde = new GetNodeDetailsJSONWork(ccs, nodeId, true, true); ccs.getWorkQueue().scheduleAndSync(gnde); result.put("result", gnde.getDetail()); } 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 ca3f1e5..6d20874 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,6 +18,7 @@ */ package org.apache.hyracks.control.cc.work; +import org.apache.hyracks.control.common.work.IPCResponder; import org.json.JSONObject; import org.apache.hyracks.control.cc.ClusterControllerService; @@ -27,21 +28,35 @@ public class GetNodeDetailsJSONWork extends SynchronizableWork { private final ClusterControllerService ccs; private final String nodeId; + private final boolean includeStats; + private final boolean includeConfig; + private final IPCResponder<String> callback; private JSONObject detail; - public GetNodeDetailsJSONWork(ClusterControllerService ccs, String nodeId) { + public GetNodeDetailsJSONWork(ClusterControllerService ccs, String nodeId, boolean includeStats, + boolean includeConfig, IPCResponder<String> callback) { this.ccs = ccs; this.nodeId = nodeId; + this.includeStats = includeStats; + this.includeConfig = includeConfig; + this.callback = callback; + } + + public GetNodeDetailsJSONWork(ClusterControllerService ccs, String nodeId, boolean includeStats, + boolean includeConfig) { + this(ccs, nodeId, includeStats, includeConfig, null); } @Override protected void doRun() throws Exception { NodeControllerState ncs = ccs.getNodeMap().get(nodeId); - if (ncs == null) { - detail = new JSONObject(); - return; + if (ncs != null) { + detail = ncs.toDetailedJSON(includeStats, includeConfig); } - detail = ncs.toDetailedJSON(); + + if (callback != null) { + callback.setValue(detail == null ? null : detail.toString()); + } } public JSONObject getDetail() { diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/controllers/NodeRegistration.java b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/controllers/NodeRegistration.java index bb8022e..e95a004 100644 --- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/controllers/NodeRegistration.java +++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/controllers/NodeRegistration.java @@ -67,11 +67,13 @@ private final NetworkAddress messagingPort; + private final int pid; + public NodeRegistration(InetSocketAddress ncAddress, String nodeId, NCConfig ncConfig, NetworkAddress dataPort, - NetworkAddress datasetPort, String osName, String arch, String osVersion, int nProcessors, String vmName, - String vmVersion, String vmVendor, String classpath, String libraryPath, String bootClasspath, - List<String> inputArguments, Map<String, String> systemProperties, HeartbeatSchema hbSchema, - NetworkAddress messagingPort) { + NetworkAddress datasetPort, String osName, String arch, String osVersion, int nProcessors, + String vmName, String vmVersion, String vmVendor, String classpath, String libraryPath, + String bootClasspath, List<String> inputArguments, Map<String, String> systemProperties, + HeartbeatSchema hbSchema, NetworkAddress messagingPort, int pid) { this.ncAddress = ncAddress; this.nodeId = nodeId; this.ncConfig = ncConfig; @@ -91,6 +93,7 @@ this.systemProperties = systemProperties; this.hbSchema = hbSchema; this.messagingPort = messagingPort; + this.pid = pid; } public InetSocketAddress getNodeControllerAddress() { @@ -168,4 +171,6 @@ public NetworkAddress getMessagingPort() { return messagingPort; } + + public int getPid() { return pid; } } diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/utils/PidHelper.java b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/utils/PidHelper.java new file mode 100644 index 0000000..79642c0 --- /dev/null +++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/utils/PidHelper.java @@ -0,0 +1,52 @@ +/* + * 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.utils; + +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class PidHelper { + + private static final Logger LOGGER = Logger.getLogger(PidHelper.class.getName()); + + private PidHelper() { + } + + public static int getPid() { + return getPid(ManagementFactory.getRuntimeMXBean()); + } + + public static int getPid(RuntimeMXBean runtimeMXBean) { + try { + Field jvmField = runtimeMXBean.getClass().getDeclaredField("jvm"); + jvmField.setAccessible(true); + Object vmManagement = jvmField.get(runtimeMXBean); + Method getProcessIdMethod = vmManagement.getClass().getDeclaredMethod("getProcessId"); + getProcessIdMethod.setAccessible(true); + return (Integer) getProcessIdMethod.invoke(vmManagement); + } catch (Exception e) { + LOGGER.log(Level.INFO, "Unable to determine PID due to exception", e); + return -1; + } + } +} 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 8373ebe..edadf57 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 @@ -65,6 +65,7 @@ import org.apache.hyracks.control.common.ipc.CCNCFunctions.StateDumpRequestFunction; import org.apache.hyracks.control.common.ipc.ClusterControllerRemoteProxy; import org.apache.hyracks.control.common.job.profiling.om.JobProfile; +import org.apache.hyracks.control.common.utils.PidHelper; import org.apache.hyracks.control.common.work.FutureValue; import org.apache.hyracks.control.common.work.WorkQueue; import org.apache.hyracks.control.nc.application.NCApplicationContext; @@ -290,7 +291,8 @@ osMXBean.getName(), osMXBean.getArch(), osMXBean.getVersion(), osMXBean.getAvailableProcessors(), runtimeMXBean.getVmName(), runtimeMXBean.getVmVersion(), runtimeMXBean.getVmVendor(), runtimeMXBean.getClassPath(), runtimeMXBean.getLibraryPath(), runtimeMXBean.getBootClassPath(), - runtimeMXBean.getInputArguments(), runtimeMXBean.getSystemProperties(), hbSchema, meesagingPort)); + runtimeMXBean.getInputArguments(), runtimeMXBean.getSystemProperties(), hbSchema, meesagingPort, + PidHelper.getPid())); synchronized (this) { while (registrationPending) { -- To view, visit https://asterix-gerrit.ics.uci.edu/1147 To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ia7549f2bb0b6621886356d50df800d447928aa2c Gerrit-PatchSet: 7 Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-Owner: Michael Blow <[email protected]> Gerrit-Reviewer: Jenkins <[email protected]> Gerrit-Reviewer: Michael Blow <[email protected]> Gerrit-Reviewer: Till Westmann <[email protected]>
