You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by kw...@apache.org on 2015/11/25 17:05:19 UTC

svn commit: r1716455 - in /qpid/java/trunk: broker-core/src/main/java/org/apache/qpid/server/ broker-core/src/main/java/org/apache/qpid/server/model/ broker-core/src/main/java/org/apache/qpid/server/model/adapter/ broker-core/src/main/java/org/apache/q...

Author: kwall
Date: Wed Nov 25 16:05:18 2015
New Revision: 1716455

URL: http://svn.apache.org/viewvc?rev=1716455&view=rev
Log:
QPID-6908: [Java Broker] Add Broker model operation to shutdown the Broker.

* Protect operation with an ACL operation type SHUTDOWN
* Wire up the JMX Shutdown MBean to the model operation

Modified:
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/Broker.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/access/ObjectType.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/access/Operation.java
    qpid/java/trunk/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java
    qpid/java/trunk/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/Shutdown.java
    qpid/java/trunk/doc/book/src/java-broker/Java-Broker-Getting-Started.xml
    qpid/java/trunk/doc/book/src/java-broker/security/Java-Broker-Security-ACLs.xml

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/Broker.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/Broker.java?rev=1716455&r1=1716454&r2=1716455&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/Broker.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/Broker.java Wed Nov 25 16:05:18 2015
@@ -24,7 +24,6 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
-import java.security.PrivilegedAction;
 import java.security.PrivilegedExceptionAction;
 import java.util.HashSet;
 import java.util.Properties;
@@ -60,7 +59,6 @@ public class Broker
 {
     private static final Logger LOGGER = LoggerFactory.getLogger(Broker.class);
 
-    private volatile Thread _shutdownHookThread;
     private EventLogger _eventLogger;
     private final TaskExecutor _taskExecutor = new TaskExecutorImpl();
 
@@ -88,27 +86,20 @@ public class Broker
     {
         try
         {
-            removeShutdownHook();
+            if(_systemConfig != null)
+            {
+                ListenableFuture<Void> closeResult = _systemConfig.closeAsync();
+                closeResult.get(30000l, TimeUnit.MILLISECONDS);
+            }
+
+        }
+        catch (TimeoutException | InterruptedException | ExecutionException e)
+        {
+            LOGGER.warn("Attempting to cleanly shutdown took too long, exiting immediately");
         }
         finally
         {
-            try
-            {
-                if(_systemConfig != null)
-                {
-                    ListenableFuture<Void> closeResult = _systemConfig.closeAsync();
-                    closeResult.get(30000l, TimeUnit.MILLISECONDS);
-                }
-
-            }
-            catch (TimeoutException | InterruptedException | ExecutionException e)
-            {
-                LOGGER.warn("Attempting to cleanly shutdown took too long, exiting immediately");
-            }
-            finally
-            {
-                cleanUp(exitStatusCode);
-            }
+            cleanUp(exitStatusCode);
         }
     }
 
@@ -200,10 +191,6 @@ public class Broker
         {
             throw new RuntimeException("Closing broker as it cannot operate due to errors");
         }
-        else
-        {
-            addShutdownHook();
-        }
     }
 
     private void closeSystemConfigAndCleanUp()
@@ -228,48 +215,6 @@ public class Broker
         }
     }
 
-
-    private void addShutdownHook()
-    {
-        Thread shutdownHookThread = new Thread(new ShutdownService());
-        shutdownHookThread.setName("QpidBrokerShutdownHook");
-
-        Runtime.getRuntime().addShutdownHook(shutdownHookThread);
-        _shutdownHookThread = shutdownHookThread;
-
-        LOGGER.debug("Added shutdown hook");
-    }
-
-    private void removeShutdownHook()
-    {
-        Thread shutdownThread = _shutdownHookThread;
-
-        //if there is a shutdown thread and we aren't it, we should remove it
-        if(shutdownThread != null && !(Thread.currentThread() == shutdownThread))
-        {
-            LOGGER.debug("Removing shutdown hook");
-
-            _shutdownHookThread = null;
-
-            boolean removed = false;
-            try
-            {
-                removed = Runtime.getRuntime().removeShutdownHook(shutdownThread);
-            }
-            catch(IllegalStateException ise)
-            {
-                //ignore, means the JVM is already shutting down
-            }
-
-            LOGGER.debug("Removed shutdown hook: {}", removed);
-
-        }
-        else
-        {
-            LOGGER.debug("Skipping shutdown hook removal as there either isn't one, or we are it.");
-        }
-    }
-
     public static void populateSystemPropertiesFromDefaults(final String initialProperties) throws IOException
     {
         URL initialPropertiesLocation;
@@ -299,23 +244,4 @@ public class Broker
             System.setProperty(propName, props.getProperty(propName));
         }
     }
-
-
-    private class ShutdownService implements Runnable
-    {
-        public void run()
-        {
-            Subject.doAs(SecurityManager.getSystemTaskSubject("Shutdown"), new PrivilegedAction<Object>()
-            {
-                @Override
-                public Object run()
-                {
-                    LOGGER.debug("Shutdown hook running");
-                    Broker.this.shutdown();
-                    return null;
-                }
-            });
-        }
-    }
-
 }

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java?rev=1716455&r1=1716454&r2=1716455&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java Wed Nov 25 16:05:18 2015
@@ -26,15 +26,23 @@ import java.io.InputStreamReader;
 import java.io.Reader;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.security.PrivilegedAction;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import javax.security.auth.Subject;
 
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.SettableFuture;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import org.apache.qpid.server.configuration.IllegalConfigurationException;
 import org.apache.qpid.server.configuration.store.ManagementModeStoreHandler;
@@ -53,10 +61,13 @@ import org.apache.qpid.server.util.Serve
 public abstract class AbstractSystemConfig<X extends SystemConfig<X>>
         extends AbstractConfiguredObject<X> implements SystemConfig<X>
 {
+    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSystemConfig.class);
+
     private static final UUID SYSTEM_ID = new UUID(0l, 0l);
+    private static final long SHUTDOWN_TIMEOUT = 30000l;
     private final EventLogger _eventLogger;
 
-    private DurableConfigurationStore _configurationStore;
+    private volatile DurableConfigurationStore _configurationStore;
 
     @ManagedAttributeField
     private boolean _managementMode;
@@ -82,6 +93,7 @@ public abstract class AbstractSystemConf
     @ManagedAttributeField
     private boolean _startupLoggedToSystemOut;
 
+    private final Thread _shutdownHook = new Thread(new ShutdownService(), "QpidBrokerShutdownHook");
 
     public AbstractSystemConfig(final TaskExecutor taskExecutor,
                                 final EventLogger eventLogger,
@@ -117,22 +129,35 @@ public abstract class AbstractSystemConf
     @Override
     protected void onClose()
     {
+        final TaskExecutor taskExecutor = getTaskExecutor();
         try
         {
+            try
+            {
+                boolean removed = Runtime.getRuntime().removeShutdownHook(_shutdownHook);
+                LOGGER.debug("Removed shutdown hook : {}", removed);
+            }
+            catch(IllegalStateException ise)
+            {
+                //ignore, means the JVM is already shutting down
+            }
 
-            if (getTaskExecutor() != null)
+            if (taskExecutor != null)
             {
-                getTaskExecutor().stop();
+                taskExecutor.stop();
             }
 
-            _configurationStore.closeConfigurationStore();
+            if (_configurationStore != null)
+            {
+                _configurationStore.closeConfigurationStore();
+            }
 
         }
         finally
         {
-            if (getTaskExecutor() != null)
+            if (taskExecutor != null)
             {
-                getTaskExecutor().stopImmediately();
+                taskExecutor.stopImmediately();
             }
         }
 
@@ -157,6 +182,10 @@ public abstract class AbstractSystemConf
     protected void onOpen()
     {
         super.onOpen();
+
+        Runtime.getRuntime().addShutdownHook(_shutdownHook);
+        LOGGER.debug("Added shutdown hook");
+
         _configurationStore = createStoreObject();
 
         if (isManagementMode())
@@ -176,9 +205,6 @@ public abstract class AbstractSystemConf
         {
             throw new IllegalArgumentException(e);
         }
-
-
-
     }
 
     @StateTransition(currentState = State.UNINITIALIZED, desiredState = State.ACTIVE)
@@ -243,7 +269,7 @@ public abstract class AbstractSystemConf
         return true;
     }
 
-    abstract protected DurableConfigurationStore createStoreObject();
+    protected abstract DurableConfigurationStore createStoreObject();
 
     @Override
     public DurableConfigurationStore getConfigurationStore()
@@ -330,4 +356,31 @@ public abstract class AbstractSystemConf
     {
         return _startupLoggedToSystemOut;
     }
+
+    private class ShutdownService implements Runnable
+    {
+        public void run()
+        {
+            Subject.doAs(org.apache.qpid.server.security.SecurityManager.getSystemTaskSubject("Shutdown"),
+                         new PrivilegedAction<Object>()
+                         {
+                             @Override
+                             public Object run()
+                             {
+                                 LOGGER.debug("Shutdown hook initiating close");
+                                 ListenableFuture<Void> closeResult = closeAsync();
+                                 try
+                                 {
+                                     closeResult.get(SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS);
+                                 }
+                                 catch (InterruptedException | ExecutionException  | TimeoutException e)
+                                 {
+                                     LOGGER.warn("Attempting to cleanly shutdown took too long, exiting immediately", e);
+                                 }
+                                 return null;
+                             }
+                         });
+        }
+    }
+
 }

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java?rev=1716455&r1=1716454&r2=1716455&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java Wed Nov 25 16:05:18 2015
@@ -163,6 +163,8 @@ public interface Broker<X extends Broker
     @ManagedStatistic(statisticType = StatisticType.CUMULATIVE, units = StatisticUnit.MESSAGES, label = "Outbound")
     long getMessagesOut();
 
+    @ManagedOperation(nonModifying = true, description = "Initiates an orderly shutdown of the Broker.")
+    void initiateShutdown();
 
     //children
     Collection<VirtualHostNode<?>> getVirtualHostNodes();

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java?rev=1716455&r1=1716454&r2=1716455&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java Wed Nov 25 16:05:18 2015
@@ -46,6 +46,7 @@ import com.google.common.util.concurrent
 import org.apache.qpid.bytebuffer.QpidByteBuffer;
 import org.apache.qpid.server.logging.QpidLoggerTurboFilter;
 import org.apache.qpid.server.logging.StartupAppender;
+import org.apache.qpid.server.security.access.Operation;
 import org.apache.qpid.server.util.ServerScopedRuntimeException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -210,6 +211,7 @@ public class BrokerAdapter extends Abstr
 
     }
 
+    @Override
     public void onValidate()
     {
         super.onValidate();
@@ -302,6 +304,13 @@ public class BrokerAdapter extends Abstr
         }
     }
 
+    @Override
+    public void initiateShutdown()
+    {
+        _securityManager.authorise(Operation.SHUTDOWN, this);
+        _parent.closeAsync();
+    }
+
     private void performActivation()
     {
         boolean hasBrokerAnyErroredChildren = false;

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/access/ObjectType.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/access/ObjectType.java?rev=1716455&r1=1716454&r2=1716455&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/access/ObjectType.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/access/ObjectType.java Wed Nov 25 16:05:18 2015
@@ -27,6 +27,7 @@ import static org.apache.qpid.server.sec
 import static org.apache.qpid.server.security.access.Operation.DELETE;
 import static org.apache.qpid.server.security.access.Operation.PUBLISH;
 import static org.apache.qpid.server.security.access.Operation.PURGE;
+import static org.apache.qpid.server.security.access.Operation.SHUTDOWN;
 import static org.apache.qpid.server.security.access.Operation.UNBIND;
 import static org.apache.qpid.server.security.access.Operation.UPDATE;
 
@@ -52,7 +53,7 @@ public enum ObjectType
     METHOD(Operation.ALL, ACCESS, UPDATE),
     USER(Operation.ALL, CREATE, DELETE, UPDATE),
     GROUP(Operation.ALL, CREATE, DELETE, UPDATE),
-    BROKER(Operation.ALL, CONFIGURE, ACCESS_LOGS);
+    BROKER(Operation.ALL, CONFIGURE, ACCESS_LOGS, SHUTDOWN);
 
     private EnumSet<Operation> _actions;
     

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/access/Operation.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/access/Operation.java?rev=1716455&r1=1716454&r2=1716455&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/access/Operation.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/access/Operation.java Wed Nov 25 16:05:18 2015
@@ -34,7 +34,8 @@ public enum Operation
     PURGE,
     UPDATE,
     CONFIGURE,
-    ACCESS_LOGS;
+    ACCESS_LOGS,
+    SHUTDOWN;
 
     public static Operation parse(String text)
     {

Modified: qpid/java/trunk/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java?rev=1716455&r1=1716454&r2=1716455&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java (original)
+++ qpid/java/trunk/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java Wed Nov 25 16:05:18 2015
@@ -159,7 +159,7 @@ public class JMXManagementPluginImpl
                     createObjectMBeans(brokerLogger);
                 }
             }
-            new Shutdown(_objectRegistry);
+            new Shutdown(_objectRegistry, broker);
             new ServerInformationMBean(_objectRegistry, broker);
 
             _objectRegistry.start();

Modified: qpid/java/trunk/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/Shutdown.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/Shutdown.java?rev=1716455&r1=1716454&r2=1716455&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/Shutdown.java (original)
+++ qpid/java/trunk/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/Shutdown.java Wed Nov 25 16:05:18 2015
@@ -35,6 +35,7 @@ import org.slf4j.LoggerFactory;
 import org.apache.qpid.server.jmx.DefaultManagedObject;
 import org.apache.qpid.server.jmx.ManagedObject;
 import org.apache.qpid.server.jmx.ManagedObjectRegistry;
+import org.apache.qpid.server.model.Broker;
 
 /**
  * Implementation of the JMX broker shutdown plugin.
@@ -49,10 +50,12 @@ public class Shutdown extends DefaultMan
     private static final ScheduledExecutorService EXECUTOR = new ScheduledThreadPoolExecutor(THREAD_COUNT);
 
     private final Runnable _shutdown = new SystemExiter();
+    private final Broker _broker;
 
-    public Shutdown(ManagedObjectRegistry registry) throws JMException
+    public Shutdown(ManagedObjectRegistry registry, final Broker broker) throws JMException
     {
         super(ShutdownMBean.class, ShutdownMBean.TYPE, registry);
+        _broker = broker;
         register();
     }
 
@@ -126,7 +129,7 @@ public class Shutdown extends DefaultMan
     {
         public void run()
         {
-            System.exit(0);
+            _broker.initiateShutdown();
         }
     }
 

Modified: qpid/java/trunk/doc/book/src/java-broker/Java-Broker-Getting-Started.xml
URL: http://svn.apache.org/viewvc/qpid/java/trunk/doc/book/src/java-broker/Java-Broker-Getting-Started.xml?rev=1716455&r1=1716454&r2=1716455&view=diff
==============================================================================
--- qpid/java/trunk/doc/book/src/java-broker/Java-Broker-Getting-Started.xml (original)
+++ qpid/java/trunk/doc/book/src/java-broker/Java-Broker-Getting-Started.xml Wed Nov 25 16:05:18 2015
@@ -61,8 +61,10 @@
 [Broker] BRK-1004 : Qpid Broker Ready</screen>
     <para>The BRK-1004 message confirms that the Broker is ready for work.  The MNG-1002 and BRK-1002 confirm the ports on
       which the Broker is listening (for HTTP/JMX management and AMQP respectively).</para>
-    <para>To stop the Broker, use Control-C or use the Shutdown MBean from the
-          <link linkend="Java-Broker-Management-Channel-JMX">JMX management plugin</link>.</para>
+    <para>To stop the Broker, use Control-C from the controlling command prompy, the
+      <link linkend="Java-Broker-Management-Channel-REST-API-Operations">REST operation broker/shutdown</link> or the Shutdown MBean
+      from the <link linkend="Java-Broker-Management-Channel-JMX">JMX management plugin</link>.
+    </para>
   </section>
   <section role="h2" id="Java-Broker-Getting-Started-Starting-Stopping-Unix">
     <title>Starting/Stopping the broker on Unix</title>
@@ -87,8 +89,9 @@
     <para>The BRK-1004 message confirms that the Broker is ready for work.  The MNG-1002 and BRK-1002 confirm the ports on
     which the Broker is listening (for HTTP/JMX management and AMQP respectively).</para>
     <para>To stop the Broker, use Control-C from the controlling shell, use the
-        <command>bin/qpid.stop</command> script, use <command>kill -TERM &lt;pid&gt;</command>, or
-      the Shutdown MBean from the <link linkend="Java-Broker-Management-Channel-JMX">JMX management plugin</link>.</para>
+        <command>bin/qpid.stop</command> script, use <command>kill -TERM &lt;pid&gt;</command>,
+      the <link linkend="Java-Broker-Management-Channel-REST-API-Operations">REST operation broker/shutdown</link> or the 
+      Shutdown MBean from the <link linkend="Java-Broker-Management-Channel-JMX">JMX management plugin</link>.</para>
   </section>
   <section role="h2" id="Java-Broker-Getting-Started-Logging">
     <title>Log file</title>

Modified: qpid/java/trunk/doc/book/src/java-broker/security/Java-Broker-Security-ACLs.xml
URL: http://svn.apache.org/viewvc/qpid/java/trunk/doc/book/src/java-broker/security/Java-Broker-Security-ACLs.xml?rev=1716455&r1=1716454&r2=1716455&view=diff
==============================================================================
--- qpid/java/trunk/doc/book/src/java-broker/security/Java-Broker-Security-ACLs.xml (original)
+++ qpid/java/trunk/doc/book/src/java-broker/security/Java-Broker-Security-ACLs.xml Wed Nov 25 16:05:18 2015
@@ -242,10 +242,16 @@
         </row>
         <row>
           <entry><command>ACCESS_LOGS</command> </entry>
-          <entry><para>Allows/denies to the specific user an operation to download broker log file(s) over REST interfaces</para> </entry>
+          <entry><para>Allows/denies the specific user to download log file(s) over REST interfaces.</para> </entry>
           <entry><para>BROKER, VIRTUALHOST</para></entry>
           <entry><para>name (for VIRTUALHOST only)</para></entry>
         </row>
+        <row>
+          <entry><command>SHUTDOWN</command> </entry>
+          <entry><para>Allows/denies the specific user to shutdown the Broker.</para> </entry>
+          <entry><para>BROKER</para></entry>
+          <entry><para></para></entry>
+        </row>
       </tbody>
     </tgroup>
   </table>



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org