You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by ma...@apache.org on 2014/12/10 17:09:20 UTC

[6/9] incubator-nifi git commit: NIFI-145: Added run-nifi.bat and fixed bugs

NIFI-145: Added run-nifi.bat and fixed bugs


Project: http://git-wip-us.apache.org/repos/asf/incubator-nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-nifi/commit/6d468297
Tree: http://git-wip-us.apache.org/repos/asf/incubator-nifi/tree/6d468297
Diff: http://git-wip-us.apache.org/repos/asf/incubator-nifi/diff/6d468297

Branch: refs/heads/develop
Commit: 6d46829795196afc797448cc386783fb147c0a7d
Parents: e544191
Author: Mark Payne <ma...@hotmail.com>
Authored: Wed Dec 10 09:23:51 2014 -0500
Committer: Mark Payne <ma...@hotmail.com>
Committed: Wed Dec 10 09:23:51 2014 -0500

----------------------------------------------------------------------
 .../src/main/resources/bin/run-nifi.bat         |  15 +++
 .../src/main/resources/conf/bootstrap.conf      |   7 ++
 .../java/org/apache/nifi/BootstrapListener.java |  19 ++--
 .../src/main/java/org/apache/nifi/NiFi.java     |  15 ++-
 .../java/org/apache/nifi/bootstrap/RunNiFi.java | 109 ++++++++++++++++---
 .../org/apache/nifi/bootstrap/ShutdownHook.java |  12 +-
 6 files changed, 144 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/6d468297/nar-bundles/framework-bundle/framework/resources/src/main/resources/bin/run-nifi.bat
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/resources/src/main/resources/bin/run-nifi.bat b/nar-bundles/framework-bundle/framework/resources/src/main/resources/bin/run-nifi.bat
new file mode 100644
index 0000000..ee00204
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/resources/src/main/resources/bin/run-nifi.bat
@@ -0,0 +1,15 @@
+@echo off
+
+rem Use JAVA_HOME if it's set; otherwise, just use java
+IF "%JAVA_HOME%"=="" (SET JAVA_EXE=java) ELSE (SET JAVA_EXE=%JAVA_HOME%\bin\java.exe)
+
+SET LIB_DIR=%~dp0..\lib
+SET CONF_DIR=%~dp0..\conf
+
+SET BOOTSTRAP_CONF_FILE=%CONF_DIR%\bootstrap.conf
+SET JAVA_ARGS=-Dorg.apache.nifi.boostrap.config.file=%BOOTSTRAP_CONF_FILE%
+
+SET JAVA_PARAMS=-cp %LIB_DIR%\nifi-bootstrap*.jar -Xms12m -Xmx24m %JAVA_ARGS% org.apache.nifi.bootstrap.RunNiFi
+SET BOOTSTRAP_ACTION=run
+
+cmd.exe /C "%JAVA_EXE%" %JAVA_PARAMS% %BOOTSTRAP_ACTION%

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/6d468297/nar-bundles/framework-bundle/framework/resources/src/main/resources/conf/bootstrap.conf
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/resources/src/main/resources/conf/bootstrap.conf b/nar-bundles/framework-bundle/framework/resources/src/main/resources/conf/bootstrap.conf
index 97d48f8..c45d8f8 100644
--- a/nar-bundles/framework-bundle/framework/resources/src/main/resources/conf/bootstrap.conf
+++ b/nar-bundles/framework-bundle/framework/resources/src/main/resources/conf/bootstrap.conf
@@ -1,7 +1,14 @@
+# Configure where NiFi's lib and conf directories live
 lib.dir=./lib
 conf.dir=./conf
+
+# How long to wait after telling NiFi to shutdown before explicitly killing the Process
+graceful.shutdown.seconds=20
+
+# Disable JSR 199 so that we can use JSP's without running a JDK
 java.arg.1=-Dorg.apache.jasper.compiler.disablejsr199=true
 
+# JVM memory settings
 java.arg.2=-Xms256m
 java.arg.3=-Xmx512m
 

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/6d468297/nar-bundles/framework-bundle/framework/runtime/src/main/java/org/apache/nifi/BootstrapListener.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/runtime/src/main/java/org/apache/nifi/BootstrapListener.java b/nar-bundles/framework-bundle/framework/runtime/src/main/java/org/apache/nifi/BootstrapListener.java
index 3bcbeb3..31f336c 100644
--- a/nar-bundles/framework-bundle/framework/runtime/src/main/java/org/apache/nifi/BootstrapListener.java
+++ b/nar-bundles/framework-bundle/framework/runtime/src/main/java/org/apache/nifi/BootstrapListener.java
@@ -24,6 +24,7 @@ import java.io.OutputStream;
 import java.net.InetSocketAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
+import java.net.SocketTimeoutException;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.concurrent.ExecutorService;
@@ -38,8 +39,8 @@ public class BootstrapListener {
 	private final NiFi nifi;
 	private final int bootstrapPort;
 
-	private Listener listener;
-	private ServerSocket serverSocket;
+	private volatile Listener listener;
+	private volatile ServerSocket serverSocket;
 	
 	
 	public BootstrapListener(final NiFi nifi, final int port) {
@@ -52,12 +53,14 @@ public class BootstrapListener {
 		
 		serverSocket = new ServerSocket();
 		serverSocket.bind(new InetSocketAddress("localhost", 0));
+		serverSocket.setSoTimeout(2000);
 		
 		final int localPort = serverSocket.getLocalPort();
 		logger.info("Started Bootstrap Listener, Listening for incoming requests on port {}", localPort);
 		
 		listener = new Listener(serverSocket);
 		final Thread listenThread = new Thread(listener);
+		listenThread.setDaemon(true);
 		listenThread.setName("Listen to Bootstrap");
 		listenThread.start();
 		
@@ -114,15 +117,17 @@ public class BootstrapListener {
 		
 		@Override
 		public void run() {
-			while (!serverSocket.isClosed()) {
+			while (!stopped) {
 				try {
-					if ( stopped ) {
-						return;
-					}
-					
 					final Socket socket;
 					try {
 						socket = serverSocket.accept();
+					} catch (final SocketTimeoutException ste) {
+						if ( stopped ) {
+							return;
+						}
+						
+						continue;
 					} catch (final IOException ioe) {
 						if ( stopped ) {
 							return;

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/6d468297/nar-bundles/framework-bundle/framework/runtime/src/main/java/org/apache/nifi/NiFi.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/runtime/src/main/java/org/apache/nifi/NiFi.java b/nar-bundles/framework-bundle/framework/runtime/src/main/java/org/apache/nifi/NiFi.java
index bf50a21..13cd4d6 100644
--- a/nar-bundles/framework-bundle/framework/runtime/src/main/java/org/apache/nifi/NiFi.java
+++ b/nar-bundles/framework-bundle/framework/runtime/src/main/java/org/apache/nifi/NiFi.java
@@ -48,6 +48,7 @@ public class NiFi {
     private final BootstrapListener bootstrapListener;
     
     public static final String BOOTSTRAP_PORT_PROPERTY = "nifi.bootstrap.listen.port";
+    private volatile boolean shutdown = false;
 
     public NiFi(final NiFiProperties properties) throws ClassNotFoundException, IOException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
         Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@@ -126,13 +127,21 @@ public class NiFi {
         final long startTime = System.nanoTime();
         nifiServer = (NiFiServer) jettyConstructor.newInstance(properties);
         nifiServer.setExtensionMapping(extensionMapping);
-        nifiServer.start();
-        final long endTime = System.nanoTime();
-        logger.info("Controller initialization took " + (endTime - startTime) + " nanoseconds.");
+        
+        if ( shutdown ) {
+        	logger.info("NiFi has been shutdown via NiFi Bootstrap. Will not start Controller");
+        } else {
+	        nifiServer.start();
+	        
+	        final long endTime = System.nanoTime();
+	        logger.info("Controller initialization took " + (endTime - startTime) + " nanoseconds.");
+        }
     }
 
     protected void shutdownHook() {
         try {
+        	this.shutdown = true;
+        	
             logger.info("Initiating shutdown of Jetty web server...");
             if (nifiServer != null) {
                 nifiServer.stop();

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/6d468297/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/RunNiFi.java
----------------------------------------------------------------------
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 54932c8..f93500f 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
@@ -57,6 +57,9 @@ public class RunNiFi {
 	public static final String DEFAULT_CONFIG_FILE = "./conf/boostrap.conf";
 	public static final String DEFAULT_NIFI_PROPS_FILE = "./conf/nifi.properties";
 
+	public static final String GRACEFUL_SHUTDOWN_PROP = "graceful.shutdown.seconds";
+	public static final String DEFAULT_GRACEFUL_SHUTDOWN_VALUE = "20";
+	
 	public static final int MAX_RESTART_ATTEMPTS = 5;
 	public static final int STARTUP_WAIT_SECONDS = 60;
 	
@@ -85,6 +88,7 @@ public class RunNiFi {
 		System.out.println("Start : Start a new instance of Apache NiFi");
 		System.out.println("Stop : Stop a running instance of Apache NiFi");
 		System.out.println("Status : Determine if there is a running instance of Apache NiFi");
+		System.out.println("Run : Start a new instance of Apache NiFi and monitor the Process, restarting if the instance dies");
 		System.out.println();
 	}
 	
@@ -96,6 +100,7 @@ public class RunNiFi {
 		
 		switch (args[0].toLowerCase()) {
 			case "start":
+			case "run":
 			case "stop":
 			case "status":
 				break;
@@ -127,7 +132,10 @@ public class RunNiFi {
 		
 		switch (args[0].toLowerCase()) {
 			case "start":
-				runNiFi.start();
+				runNiFi.start(false);
+				break;
+			case "run":
+				runNiFi.start(true);
 				break;
 			case "stop":
 				runNiFi.stop();
@@ -140,8 +148,10 @@ public class RunNiFi {
 	
 	
 	public File getStatusFile() {
-		final File rootDir = bootstrapConfigFile.getParentFile();
-		final File statusFile = new File(rootDir, "nifi.port");
+		final File confDir = bootstrapConfigFile.getParentFile();
+		final File nifiHome = confDir.getParentFile();
+		final File bin = new File(nifiHome, "bin");
+		final File statusFile = new File(bin, "nifi.port");
 		return statusFile;
 	}
 
@@ -165,11 +175,7 @@ public class RunNiFi {
 					return port;
 				}
 			} catch (final IOException ioe) {
-				System.out.println("Found NiFi instance info at " + statusFile + " but information appears to be stale. Removing file.");
-				if ( !statusFile.delete() ) {
-					System.err.println("Unable to remove status file");
-				}
-				
+				System.out.println("Found NiFi instance info at " + statusFile + " indicating that NiFi is running and listening to port " + port + " but unable to communicate with NiFi on that port. The process may have died or may be hung.");
 				throw ioe;
 			}
 		} catch (final Exception e) {
@@ -212,6 +218,11 @@ public class RunNiFi {
 			final String response = reader.readLine();
 			if ( SHUTDOWN_CMD.equals(response) ) {
 				System.out.println("Apache NiFi has accepted the Shutdown Command and is shutting down now");
+				
+				final File statusFile = getStatusFile();
+				if ( !statusFile.delete() ) {
+					System.err.println("Failed to delete status file " + statusFile + "; this file should be cleaned up manually");
+				}
 			} else {
 				System.err.println("When sending SHUTDOWN command to NiFi, got unexpected response " + response);
 			}
@@ -222,8 +233,17 @@ public class RunNiFi {
 	}
 	
 	
+	private boolean isAlive(final Process process) {
+		try {
+			process.exitValue();
+			return false;
+		} catch (final IllegalThreadStateException itse) {
+			return true;
+		}
+	}
+	
 	@SuppressWarnings({ "rawtypes", "unchecked" })
-	public void start() throws IOException, InterruptedException {
+	public void start(final boolean monitor) throws IOException, InterruptedException {
 		final Integer port = getCurrentPort();
 		if ( port != null ) {
 			System.out.println("Apache NiFi is already running, listening on port " + port);
@@ -344,16 +364,71 @@ public class RunNiFi {
 		System.out.println("Working Directory: " + workingDir.getAbsolutePath());
 		System.out.println("Command: " + cmdBuilder.toString());
 		
-		builder.start();
-		boolean started = waitForStart();
-		
-		if ( started ) {
-			System.out.println("Successfully started Apache NiFi");
+		if ( monitor ) {
+			String gracefulShutdown = props.get(GRACEFUL_SHUTDOWN_PROP);
+			if ( gracefulShutdown == null ) {
+				gracefulShutdown = DEFAULT_GRACEFUL_SHUTDOWN_VALUE;
+			}
+
+			final int gracefulShutdownSeconds;
+			try {
+				gracefulShutdownSeconds = Integer.parseInt(gracefulShutdown);
+			} catch (final NumberFormatException nfe) {
+				throw new NumberFormatException("The '" + GRACEFUL_SHUTDOWN_PROP + "' property in Boostrap Config File " + bootstrapConfigAbsoluteFile.getAbsolutePath() + " has an invalid value. Must be a non-negative integer");
+			}
+			
+			if ( gracefulShutdownSeconds < 0 ) {
+				throw new NumberFormatException("The '" + GRACEFUL_SHUTDOWN_PROP + "' property in Boostrap Config File " + bootstrapConfigAbsoluteFile.getAbsolutePath() + " has an invalid value. Must be a non-negative integer");
+			}
+			
+			Process process = builder.start();
+			
+			ShutdownHook shutdownHook = new ShutdownHook(process, this, gracefulShutdownSeconds);
+			final Runtime runtime = Runtime.getRuntime();
+			runtime.addShutdownHook(shutdownHook);
+			
+			while (true) {
+				final boolean alive = isAlive(process);
+				
+				if ( alive ) {
+					try {
+						Thread.sleep(1000L);
+					} catch (final InterruptedException ie) {
+					}
+				} else {
+					runtime.removeShutdownHook(shutdownHook);
+					
+					if (autoRestartNiFi) {
+						System.out.println("Apache NiFi appears to have died. Restarting...");
+						process = builder.start();
+						
+						shutdownHook = new ShutdownHook(process, this, gracefulShutdownSeconds);
+						runtime.addShutdownHook(shutdownHook);
+						
+						final boolean started = waitForStart();
+						
+						if ( started ) {
+							System.out.println("Successfully started Apache NiFi");
+						} else {
+							System.err.println("Apache NiFi does not appear to have started");
+						}
+					} else {
+						return;
+					}
+				}
+			}
 		} else {
-			System.err.println("Apache NiFi does not appear to have started");
+			builder.start();
+			boolean started = waitForStart();
+			
+			if ( started ) {
+				System.out.println("Successfully started Apache NiFi");
+			} else {
+				System.err.println("Apache NiFi does not appear to have started");
+			}
+			
+			listener.stop();
 		}
-		
-		listener.stop();
 	}
 	
 	

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/6d468297/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/ShutdownHook.java
----------------------------------------------------------------------
diff --git a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/ShutdownHook.java b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/ShutdownHook.java
index f804c7c..781b690 100644
--- a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/ShutdownHook.java
+++ b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/ShutdownHook.java
@@ -26,12 +26,12 @@ import java.util.concurrent.TimeUnit;
 public class ShutdownHook extends Thread {
 	private final Process nifiProcess;
 	private final RunNiFi runner;
+	private final int gracefulShutdownSeconds;
 	
-	public static final int WAIT_SECONDS = 10;
-	
-	public ShutdownHook(final Process nifiProcess, final RunNiFi runner) {
+	public ShutdownHook(final Process nifiProcess, final RunNiFi runner, final int gracefulShutdownSeconds) {
 		this.nifiProcess = nifiProcess;
 		this.runner = runner;
+		this.gracefulShutdownSeconds = gracefulShutdownSeconds;
 	}
 	
 	@Override
@@ -58,9 +58,9 @@ public class ShutdownHook extends Thread {
 		while ( isAlive(nifiProcess) ) {
 			final long waitNanos = System.nanoTime() - startWait;
 			final long waitSeconds = TimeUnit.NANOSECONDS.toSeconds(waitNanos);
-			if ( waitSeconds >= WAIT_SECONDS ) {
+			if ( waitSeconds >= gracefulShutdownSeconds && gracefulShutdownSeconds > 0 ) {
 				if ( isAlive(nifiProcess) ) {
-					System.out.println("NiFi has not finished shutting down after " + WAIT_SECONDS + " seconds. Killing process.");
+					System.out.println("NiFi has not finished shutting down after " + gracefulShutdownSeconds + " seconds. Killing process.");
 					nifiProcess.destroy();
 				}
 				break;
@@ -73,7 +73,7 @@ public class ShutdownHook extends Thread {
 		
 		final File statusFile = runner.getStatusFile();
 		if ( !statusFile.delete() ) {
-			System.err.println("Failed to delete status file " + statusFile.getAbsolutePath());
+			System.err.println("Failed to delete status file " + statusFile.getAbsolutePath() + "; this file should be cleaned up manually");
 		}
 	}