Repository: cassandra
Updated Branches:
  refs/heads/trunk e1c5ebde3 -> 027006dcb


Allow CassandraDaemon to be run as a managed service

Patch by Heiko Braun, reviewed by brandonwilliams for CASSANDRA-7997


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/027006dc
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/027006dc
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/027006dc

Branch: refs/heads/trunk
Commit: 027006dcb0931e5b93f5378494831aadc3baa809
Parents: e1c5ebd
Author: Brandon Williams <brandonwilli...@apache.org>
Authored: Wed Oct 15 15:15:24 2014 -0500
Committer: Brandon Williams <brandonwilli...@apache.org>
Committed: Wed Oct 15 15:15:24 2014 -0500

----------------------------------------------------------------------
 .../cassandra/config/DatabaseDescriptor.java    | 25 ++--------
 .../cassandra/service/CassandraDaemon.java      | 48 +++++++++++++++-----
 .../cassandra/service/StorageService.java       |  2 -
 3 files changed, 42 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/027006dc/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java 
b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
index 319801d..8659c94 100644
--- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
+++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
@@ -119,17 +119,9 @@ public class DatabaseDescriptor
         {
             applyConfig(loadConfig());
         }
-        catch (ConfigurationException e)
-        {
-            logger.error("Fatal configuration error", e);
-            System.err.println(e.getMessage() + "\nFatal configuration error; 
unable to start. See log for stacktrace.");
-            System.exit(1);
-        }
         catch (Exception e)
         {
-            logger.error("Fatal error during configuration loading", e);
-            System.err.println(e.getMessage() + "\nFatal error during 
configuration loading; unable to start. See log for stacktrace.");
-            System.exit(1);
+            throw new ExceptionInInitializerError(e.getMessage() + "\nFatal 
configuration error; unable to start. See log for stacktrace.");
         }
     }
 
@@ -601,9 +593,7 @@ public class DatabaseDescriptor
         // there are about 5 checked exceptions that could be thrown here.
         catch (Exception e)
         {
-            logger.error("Fatal configuration error", e);
-            System.err.println(e.getMessage() + "\nFatal configuration error; 
unable to start server.  See log for stacktrace.");
-            System.exit(1);
+            throw new ConfigurationException(e.getMessage() + "\nFatal 
configuration error; unable to start server.  See log for stacktrace.");
         }
         if (seedProvider.getSeeds().size() == 0)
             throw new ConfigurationException("The seed provider lists no 
seeds.");
@@ -722,15 +712,11 @@ public class DatabaseDescriptor
         }
         catch (ConfigurationException e)
         {
-            logger.error("Fatal error: {}", e.getMessage());
-            System.err.println("Bad configuration; unable to start server");
-            System.exit(1);
+            throw new IllegalArgumentException("Bad configuration; unable to 
start server: "+e.getMessage());
         }
         catch (FSWriteError e)
         {
-            logger.error("Fatal error: {}", e.getMessage());
-            System.err.println(e.getCause().getMessage() + "; unable to start 
server");
-            System.exit(1);
+            throw new IllegalStateException(e.getCause().getMessage() + "; 
unable to start server");
         }
     }
 
@@ -1571,8 +1557,7 @@ public class DatabaseDescriptor
             case offheap_buffers:
                 if (!FileUtils.isCleanerAvailable())
                 {
-                    logger.error("Could not free direct byte buffer: 
offheap_buffers is not a safe memtable_allocation_type without this ability, 
please adjust your config. This feature is only guaranteed to work on an Oracle 
JVM. Refusing to start.");
-                    System.exit(-1);
+                    throw new IllegalStateException("Could not free direct 
byte buffer: offheap_buffers is not a safe memtable_allocation_type without 
this ability, please adjust your config. This feature is only guaranteed to 
work on an Oracle JVM. Refusing to start.");
                 }
                 return new SlabPool(heapLimit, offHeapLimit, 
conf.memtable_cleanup_threshold, new 
ColumnFamilyStore.FlushLargestColumnFamily());
             case offheap_objects:

http://git-wip-us.apache.org/repos/asf/cassandra/blob/027006dc/src/java/org/apache/cassandra/service/CassandraDaemon.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/CassandraDaemon.java 
b/src/java/org/apache/cassandra/service/CassandraDaemon.java
index cc81c4f..be94cf6 100644
--- a/src/java/org/apache/cassandra/service/CassandraDaemon.java
+++ b/src/java/org/apache/cassandra/service/CassandraDaemon.java
@@ -77,6 +77,16 @@ public class CassandraDaemon
     public Server thriftServer;
     public Server nativeServer;
 
+    private final boolean runManaged;
+
+    public CassandraDaemon() {
+        this(false);
+    }
+
+    public CassandraDaemon(boolean runManaged) {
+        this.runManaged = runManaged;
+    }
+
     /**
      * This is a hook for concrete daemons to initialize themselves suitably.
      *
@@ -140,8 +150,7 @@ public class CassandraDaemon
 
             if (jnaRequired)
             {
-                logger.error("JNA failing to initialize properly. Use 
-Dcassandra.boot_without_jna=true to bootstrap even so.");
-                System.exit(3);
+                exitOrFail(3, "JNA failing to initialize properly. Use 
-Dcassandra.boot_without_jna=true to bootstrap even so.");
             }
         }
 
@@ -198,15 +207,14 @@ public class CassandraDaemon
                 // if they don't, failing their creation, stop cassandra.
                 if (!dir.mkdirs())
                 {
-                    logger.error("Has no permission to create {} directory", 
dataDir);
-                    System.exit(3);
+                    exitOrFail(3, "Has no permission to create directory "+ 
dataDir);
                 }
             }
             // if directories exist verify their permissions
             if (!Directories.verifyFullPermissions(dir, dataDir))
             {
                 // if permissions aren't sufficient, stop cassandra.
-                System.exit(3);
+                exitOrFail(3, "Insufficient permissions on directory " + 
dataDir);
             }
 
 
@@ -226,10 +234,10 @@ public class CassandraDaemon
         }
         catch (ConfigurationException e)
         {
-            logger.error("Fatal exception during initialization", e);
-            System.exit(100);
+            exitOrFail(100, "Fatal exception during initialization", e);
         }
 
+
         // load keyspace && function descriptions.
         DatabaseDescriptor.loadSchemas();
         Functions.loadUDFFromSchema();
@@ -337,9 +345,8 @@ public class CassandraDaemon
         }
         catch (ConfigurationException e)
         {
-            logger.error("Fatal configuration error", e);
             System.err.println(e.getMessage() + "\nFatal configuration error; 
unable to start server.  See log for stacktrace.");
-            System.exit(1);
+            exitOrFail(1, "Fatal configuration error", e);
         }
 
         Mx4jTool.maybeLoad();
@@ -474,8 +481,7 @@ public class CassandraDaemon
             // try to warn user on stdout too, if we haven't already detached
             e.printStackTrace();
             System.out.println("Exception encountered during startup: " + 
e.getMessage());
-
-            System.exit(3);
+            exitOrFail(3, "Exception encountered during startup", e);
         }
     }
 
@@ -486,6 +492,10 @@ public class CassandraDaemon
     {
         stop();
         destroy();
+        // completely shut down cassandra
+        if(!runManaged) {
+            System.exit(0);
+        }
     }
 
     private void waitForGossipToSettle()
@@ -543,6 +553,22 @@ public class CassandraDaemon
     {
         instance.activate();
     }
+    
+    private void exitOrFail(int code, String message) {
+        exitOrFail(code, message, null);
+    }
+
+    private void exitOrFail(int code, String message, Throwable cause) {
+            if(runManaged) {
+                RuntimeException t = cause!=null ? new 
RuntimeException(message, cause) : new RuntimeException(message);
+                throw t;
+            }
+            else {
+                logger.error(message, cause);
+                System.exit(code);
+            }
+
+        }
 
     static class NativeAccess implements NativeAccessMBean
     {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/027006dc/src/java/org/apache/cassandra/service/StorageService.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/StorageService.java 
b/src/java/org/apache/cassandra/service/StorageService.java
index 0982047..b341276 100644
--- a/src/java/org/apache/cassandra/service/StorageService.java
+++ b/src/java/org/apache/cassandra/service/StorageService.java
@@ -412,8 +412,6 @@ public class StorageService extends 
NotificationBroadcasterSupport implements IE
         if (daemon == null)
             throw new IllegalStateException("No configured daemon");
         daemon.deactivate();
-        // completely shut down cassandra
-        System.exit(0);
     }
 
     public synchronized Collection<Token> prepareReplacementInfo() throws 
ConfigurationException

Reply via email to