Author: orudyy Date: Thu Nov 26 14:29:56 2015 New Revision: 1716686 URL: http://svn.apache.org/viewvc?rev=1716686&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 ------------------------------------------------------------------------ Merged from trunk with command: svn merge -c r1716455 https://svn.apache.org/repos/asf/qpid/java/trunk Modified: qpid/java/branches/6.0.x/ (props changed) qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/Broker.java qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/access/ObjectType.java qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/access/Operation.java qpid/java/branches/6.0.x/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java qpid/java/branches/6.0.x/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/Shutdown.java qpid/java/branches/6.0.x/doc/book/src/java-broker/ (props changed) qpid/java/branches/6.0.x/doc/book/src/java-broker/Java-Broker-Getting-Started.xml qpid/java/branches/6.0.x/doc/book/src/java-broker/security/Java-Broker-Security-ACLs.xml Propchange: qpid/java/branches/6.0.x/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Thu Nov 26 14:29:56 2015 @@ -9,5 +9,5 @@ /qpid/branches/java-broker-vhost-refactor/java:1493674-1494547 /qpid/branches/java-network-refactor/qpid/java:805429-821809 /qpid/branches/qpid-2935/qpid/java:1061302-1072333 -/qpid/java/trunk:1715445-1715447,1715586,1715940,1716086-1716087,1716127-1716128,1716141,1716153,1716155,1716194,1716204,1716209,1716227,1716277,1716357,1716368,1716370,1716374,1716432,1716444-1716445 +/qpid/java/trunk:1715445-1715447,1715586,1715940,1716086-1716087,1716127-1716128,1716141,1716153,1716155,1716194,1716204,1716209,1716227,1716277,1716357,1716368,1716370,1716374,1716432,1716444-1716445,1716455 /qpid/trunk/qpid:796646-796653 Modified: qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/Broker.java URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/Broker.java?rev=1716686&r1=1716685&r2=1716686&view=diff ============================================================================== --- qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/Broker.java (original) +++ qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/Broker.java Thu Nov 26 14:29:56 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/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java?rev=1716686&r1=1716685&r2=1716686&view=diff ============================================================================== --- qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java (original) +++ qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java Thu Nov 26 14:29:56 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/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java?rev=1716686&r1=1716685&r2=1716686&view=diff ============================================================================== --- qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java (original) +++ qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java Thu Nov 26 14:29:56 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/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java?rev=1716686&r1=1716685&r2=1716686&view=diff ============================================================================== --- qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java (original) +++ qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java Thu Nov 26 14:29:56 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/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/access/ObjectType.java URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/access/ObjectType.java?rev=1716686&r1=1716685&r2=1716686&view=diff ============================================================================== --- qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/access/ObjectType.java (original) +++ qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/access/ObjectType.java Thu Nov 26 14:29:56 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/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/access/Operation.java URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/access/Operation.java?rev=1716686&r1=1716685&r2=1716686&view=diff ============================================================================== --- qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/access/Operation.java (original) +++ qpid/java/branches/6.0.x/broker-core/src/main/java/org/apache/qpid/server/security/access/Operation.java Thu Nov 26 14:29:56 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/branches/6.0.x/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java?rev=1716686&r1=1716685&r2=1716686&view=diff ============================================================================== --- qpid/java/branches/6.0.x/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java (original) +++ qpid/java/branches/6.0.x/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java Thu Nov 26 14:29:56 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/branches/6.0.x/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/Shutdown.java URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/Shutdown.java?rev=1716686&r1=1716685&r2=1716686&view=diff ============================================================================== --- qpid/java/branches/6.0.x/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/Shutdown.java (original) +++ qpid/java/branches/6.0.x/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/Shutdown.java Thu Nov 26 14:29:56 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(); } } Propchange: qpid/java/branches/6.0.x/doc/book/src/java-broker/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Thu Nov 26 14:29:56 2015 @@ -7,4 +7,4 @@ /qpid/branches/mcpierce-QPID-4719/qpid/doc/book/src/java-broker:1477004-1477093 /qpid/branches/qpid-2935/qpid/doc/book/src/java-broker:1061302-1072333 /qpid/branches/qpid-3346/qpid/doc/book/src/java-broker:1144319-1179855 -/qpid/java/trunk/doc/book/src/java-broker:1716086-1716087 +/qpid/java/trunk/doc/book/src/java-broker:1716086-1716087,1716455 Modified: qpid/java/branches/6.0.x/doc/book/src/java-broker/Java-Broker-Getting-Started.xml URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/doc/book/src/java-broker/Java-Broker-Getting-Started.xml?rev=1716686&r1=1716685&r2=1716686&view=diff ============================================================================== --- qpid/java/branches/6.0.x/doc/book/src/java-broker/Java-Broker-Getting-Started.xml (original) +++ qpid/java/branches/6.0.x/doc/book/src/java-broker/Java-Broker-Getting-Started.xml Thu Nov 26 14:29:56 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 <pid></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 <pid></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/branches/6.0.x/doc/book/src/java-broker/security/Java-Broker-Security-ACLs.xml URL: http://svn.apache.org/viewvc/qpid/java/branches/6.0.x/doc/book/src/java-broker/security/Java-Broker-Security-ACLs.xml?rev=1716686&r1=1716685&r2=1716686&view=diff ============================================================================== --- qpid/java/branches/6.0.x/doc/book/src/java-broker/security/Java-Broker-Security-ACLs.xml (original) +++ qpid/java/branches/6.0.x/doc/book/src/java-broker/security/Java-Broker-Security-ACLs.xml Thu Nov 26 14:29:56 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: [email protected] For additional commands, e-mail: [email protected]
