From 9fc22675df15b75be5b9ba98d32fefbc34befe8a Mon Sep 17 00:00:00 2001 From: Justin Bertram Date: Mon, 4 Jan 2021 11:18:13 -0600 Subject: [PATCH] ARTEMIS-3031 add new callback for broker deactivation The existing deactivation callback happens *after* several important services are shutdown (e.g. the remoting service which allows client connectivity). This commit adds a new callback which is invoked *before* any services are stopped. This is useful for embedded use-cases where applications want to stop gracefully before any part of the broker is stopped. A default, empty method implementation is provided so that existing callback implementations don't need to change. --- .../artemis/core/server/ActivateCallback.java | 6 ++++++ .../artemis/core/server/ActiveMQServerLogger.java | 4 ++-- .../core/server/impl/ActiveMQServerImpl.java | 15 ++++++++++++++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActivateCallback.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActivateCallback.java index 9a646d479a..c5e5d6ea02 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActivateCallback.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActivateCallback.java @@ -37,6 +37,12 @@ public interface ActivateCallback { default void deActivate() { } + /* + * this is called when the server is stopping, before any resources or clients are closed/stopped + */ + default void preDeActivate() { + } + /* * this is called when all resources have been started including any JMS resources */ diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java index 1d6b8dd09d..3fa190caa5 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java @@ -1459,8 +1459,8 @@ public interface ActiveMQServerLogger extends BasicLogger { void unableDestroyConnectionWithSessionMetadata(@Cause Throwable e); @LogMessage(level = Logger.Level.WARN) - @Message(id = 222234, value = "Unable to deactivate a callback", format = Message.Format.MESSAGE_FORMAT) - void unableToDeactiveCallback(@Cause Throwable e); + @Message(id = 222234, value = "Unable to invoke a callback", format = Message.Format.MESSAGE_FORMAT) + void unableToInvokeCallback(@Cause Throwable e); @LogMessage(level = Logger.Level.WARN) @Message(id = 222235, value = "Unable to inject a monitor", format = Message.Format.MESSAGE_FORMAT) diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java index dc5995ba09..c8479e7011 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java @@ -1186,6 +1186,8 @@ public class ActiveMQServerImpl implements ActiveMQServer { } state = SERVER_STATE.STOPPING; + callPreDeActiveCallbacks(); + if (criticalIOError) { final ManagementService managementService = this.managementService; if (managementService != null) { @@ -2899,7 +2901,18 @@ public class ActiveMQServerImpl implements ActiveMQServer { } catch (Throwable e) { // https://bugzilla.redhat.com/show_bug.cgi?id=1009530: // we won't interrupt the shutdown sequence because of a failed callback here - ActiveMQServerLogger.LOGGER.unableToDeactiveCallback(e); + ActiveMQServerLogger.LOGGER.unableToInvokeCallback(e); + } + } + } + + private void callPreDeActiveCallbacks() { + for (ActivateCallback callback : activateCallbacks) { + try { + callback.preDeActivate(); + } catch (Throwable e) { + // we won't interrupt the shutdown sequence because of a failed callback here + ActiveMQServerLogger.LOGGER.unableToInvokeCallback(e); } } }