From 76ce3f75201c9327578453635a8472ac68608faf Mon Sep 17 00:00:00 2001 From: "puspendu.banerjee@gmail.com" Date: Wed, 10 Feb 2016 01:17:00 -0600 Subject: [PATCH] NIFI-1481 support for dumping environment using nifi.sh env Reviewed and amended (Amendments reviewed by Aldrin Piri (aldrin@apache.org)) by Tony Kurc (tkurc@apache.org). This closes #218 --- .../org/apache/nifi/bootstrap/RunNiFi.java | 59 ++++++++++++++++++- .../src/main/resources/bin/nifi.sh | 39 +++++++++--- 2 files changed, 88 insertions(+), 10 deletions(-) diff --git a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/RunNiFi.java b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/RunNiFi.java index ea8127756b..f8d490d0f6 100644 --- a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/RunNiFi.java +++ b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/RunNiFi.java @@ -28,6 +28,7 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Reader; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; @@ -41,6 +42,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import java.util.concurrent.ExecutorService; @@ -186,6 +188,7 @@ public class RunNiFi { case "status": case "dump": case "restart": + case "env": break; default: printUsage(); @@ -215,6 +218,9 @@ public class RunNiFi { case "dump": runNiFi.dump(dumpFile); break; + case "env": + runNiFi.env(); + break; } } @@ -525,7 +531,7 @@ public class RunNiFi { final Status status = getStatus(logger); if (status.isRespondingToPing()) { logger.info("Apache NiFi is currently running, listening to Bootstrap on port {}, PID={}", - new Object[]{status.getPort(), status.getPid() == null ? "unknkown" : status.getPid()}); + new Object[]{status.getPort(), status.getPid() == null ? "unknown" : status.getPid()}); return; } @@ -546,6 +552,57 @@ public class RunNiFi { } } + public void env(){ + final Logger logger = cmdLogger; + final Status status = getStatus(logger); + if (status.getPid() == null) { + logger.info("Apache NiFi is not running"); + return; + } + final Class virtualMachineClass; + try { + virtualMachineClass = Class.forName("com.sun.tools.attach.VirtualMachine"); + } catch (final ClassNotFoundException cnfe) { + logger.error("Seems tools.jar (Linux / Windows JDK) or classes.jar (Mac OS) is not available in classpath"); + return; + } + final Method attachMethod; + final Method detachMethod; + + try { + attachMethod = virtualMachineClass.getMethod("attach", String.class); + detachMethod = virtualMachineClass.getDeclaredMethod("detach"); + } catch (final Exception e) { + logger.error("Methods required for getting environment not available", e); + return; + } + + final Object virtualMachine; + try { + virtualMachine = attachMethod.invoke(null, status.getPid()); + } catch (final Throwable t) { + logger.error("Problem attaching to NiFi", t); + return; + } + + try{ + final Method getSystemPropertiesMethod = virtualMachine.getClass().getMethod("getSystemProperties"); + + final Properties sysProps = (Properties)getSystemPropertiesMethod.invoke(virtualMachine); + for (Entry syspropEntry : sysProps.entrySet()) { + logger.info(syspropEntry.getKey().toString() + " = " +syspropEntry.getValue().toString()); + } + } catch (Throwable t) { + throw new RuntimeException(t); + } finally { + try { + detachMethod.invoke(virtualMachine); + } catch (final Exception e){ + logger.warn("Caught exception detaching from process", e); + } + } + } + /** * Writes a NiFi thread dump to the given file; if file is null, logs at * INFO level instead. diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/bin/nifi.sh b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/bin/nifi.sh index 2a7da05123..da9b7222f6 100755 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/bin/nifi.sh +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/bin/nifi.sh @@ -118,6 +118,15 @@ locateJava() { fi fi fi + # if command is env, attempt to add more to the classpath + if [ "$1" = "env" ]; then + [ "x${TOOLS_JAR}" = "x" ] && [ -n "${JAVA_HOME}" ] && TOOLS_JAR=$(find -H "${JAVA_HOME}" -name "tools.jar") + [ "x${TOOLS_JAR}" = "x" ] && TOOLS_JAR=$(find -H "${JAVA_HOME}" -name "classes.jar") + if [ "x${TOOLS_JAR}" = "x" ]; then + warn "Could not locate tools.jar or classes.jar. Please set manually to avail all command features." + fi + fi + } init() { @@ -128,7 +137,7 @@ init() { unlimitFD # Locate the Java VM to execute - locateJava + locateJava "$1" } @@ -151,7 +160,9 @@ install() { run() { - BOOTSTRAP_CONF="${NIFI_HOME}/conf/bootstrap.conf"; + BOOTSTRAP_CONF_DIR="${NIFI_HOME}/conf" + BOOTSTRAP_CONF="${BOOTSTRAP_CONF_DIR}/bootstrap.conf"; + BOOTSTRAP_LIBS="${NIFI_HOME}/lib/bootstrap/*" run_as=$(grep run.as "${BOOTSTRAP_CONF}" | cut -d'=' -f2) # If the run as user is the same as that starting the process, ignore this configuration @@ -168,6 +179,12 @@ run() { NIFI_HOME=$(cygpath --path --windows "${NIFI_HOME}") BOOTSTRAP_CONF=$(cygpath --path --windows "${BOOTSTRAP_CONF}") + BOOTSTRAP_CONF_DIR=$(cygpath --path --windows "${BOOTSTRAP_CONF_DIR}") + BOOTSTRAP_LIBS=$(cygpath --path --windows "${BOOTSTRAP_LIBS}") + BOOTSTRAP_CLASSPATH="${BOOTSTRAP_CONF_DIR};${BOOTSTRAP_LIBS}" + if [ -n "${TOOLS_JAR}" ]; then + BOOTSTRAP_CLASSPATH="${TOOLS_JAR};${BOOTSTRAP_CLASSPATH}" + fi else if [ -n "${run_as}" ]; then if id -u "${run_as}" >/dev/null 2>&1; then @@ -177,6 +194,10 @@ run() { exit 1 fi fi; + BOOTSTRAP_CLASSPATH="${BOOTSTRAP_CONF_DIR}:${BOOTSTRAP_LIBS}" + if [ -n "${TOOLS_JAR}" ]; then + BOOTSTRAP_CLASSPATH="${TOOLS_JAR}:${BOOTSTRAP_CLASSPATH}" + fi fi echo @@ -189,9 +210,9 @@ run() { # run 'start' in the background because the process will continue to run, monitoring NiFi. # all other commands will terminate quickly so want to just wait for them if [ "$1" = "start" ]; then - (cd "${NIFI_HOME}" && ${sudo_cmd_prefix} "${JAVA}" -cp "${NIFI_HOME}"/conf/:"${NIFI_HOME}"/lib/bootstrap/* -Xms12m -Xmx24m -Dorg.apache.nifi.bootstrap.config.file="${BOOTSTRAP_CONF}" org.apache.nifi.bootstrap.RunNiFi $@ &) + (cd "${NIFI_HOME}" && ${sudo_cmd_prefix} "${JAVA}" -cp "${BOOTSTRAP_CLASSPATH}" -Xms12m -Xmx24m -Dorg.apache.nifi.bootstrap.config.file="${BOOTSTRAP_CONF}" org.apache.nifi.bootstrap.RunNiFi $@ &) else - (cd "${NIFI_HOME}" && ${sudo_cmd_prefix} "${JAVA}" -cp "${NIFI_HOME}"/conf/:"${NIFI_HOME}"/lib/bootstrap/* -Xms12m -Xmx24m -Dorg.apache.nifi.bootstrap.config.file="${BOOTSTRAP_CONF}" org.apache.nifi.bootstrap.RunNiFi $@) + (cd "${NIFI_HOME}" && ${sudo_cmd_prefix} "${JAVA}" -cp "${BOOTSTRAP_CLASSPATH}" -Xms12m -Xmx24m -Dorg.apache.nifi.bootstrap.config.file="${BOOTSTRAP_CONF}" org.apache.nifi.bootstrap.RunNiFi $@) fi # Wait just a bit (3 secs) to wait for the logging to finish and then echo a new-line. @@ -202,7 +223,7 @@ run() { } main() { - init + init "$1" run "$@" } @@ -211,14 +232,14 @@ case "$1" in install) install "$@" ;; - start|stop|run|status|dump) + start|stop|run|status|dump|env) main "$@" ;; restart) init - run "stop" - run "start" - ;; + run "stop" + run "start" + ;; *) echo "Usage nifi {start|stop|run|restart|status|dump|install}" ;;