From 99b9d87bfde31dc30c8f3715974ea3a2a5b0ab1e Mon Sep 17 00:00:00 2001 From: AntonRoskvist Date: Wed, 9 Feb 2022 11:22:51 +0100 Subject: [PATCH] ARTEMIS-2934 Add option to suppress SESSION notifications --- .../config/ActiveMQDefaultConfiguration.java | 8 ++++++ .../artemis/core/config/Configuration.java | 8 ++++++ .../core/config/impl/ConfigurationImpl.java | 12 +++++++++ .../impl/FileConfigurationParser.java | 3 +++ .../core/server/impl/ServerSessionImpl.java | 3 +++ .../schema/artemis-configuration.xsd | 10 +++++++ .../config/impl/FileConfigurationTest.java | 1 + .../ConfigurationTest-full-config.xml | 1 + docs/user-manual/en/management.md | 15 +++++++++++ .../management/NotificationTest.java | 26 +++++++++++++++++++ 10 files changed, 87 insertions(+) diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java index b9b9928da2..cbaa2353f6 100644 --- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java +++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java @@ -647,6 +647,9 @@ public final class ActiveMQDefaultConfiguration { // How often (in ms) to scan for expired MQTT sessions private static long DEFAULT_MQTT_SESSION_SCAN_INTERVAL = 500; + // If SESSION-notifications should be suppressed or not + public static boolean DEFAULT_SUPPRESS_SESSION_NOTIFICATIONS = false; + /** * If true then the ActiveMQ Artemis Server will make use of any Protocol Managers that are in available on the classpath. If false then only the core protocol will be available, unless in Embedded mode where users can inject their own Protocol Managers. */ @@ -1772,4 +1775,9 @@ public final class ActiveMQDefaultConfiguration { public static long getMqttSessionScanInterval() { return DEFAULT_MQTT_SESSION_SCAN_INTERVAL; } + + public static boolean getDefaultSuppressSessionNotifications() { + return DEFAULT_SUPPRESS_SESSION_NOTIFICATIONS; + } + } diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java index 20fcbfdc2a..69d0bda0fd 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java @@ -1393,4 +1393,12 @@ public interface Configuration { */ long getMqttSessionScanInterval(); + /** + * Returns whether suppression of session-notifications is enabled for this server.
+ * Default value is {@link org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration#DEFAULT_SUPPRESS_SESSION_NOTIFICATIONS}. + */ + boolean isSuppressSessionNotifications(); + + Configuration setSuppressSessionNotifications(boolean suppressSessionNotifications); + } diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java index 68d1a1d280..ff7d511967 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java @@ -387,6 +387,7 @@ public class ConfigurationImpl implements Configuration, Serializable { private long mqttSessionScanInterval = ActiveMQDefaultConfiguration.getMqttSessionScanInterval(); + private boolean suppressSessionNotifications = ActiveMQDefaultConfiguration.getDefaultSuppressSessionNotifications(); /** * Parent folder for all data folders. @@ -2690,6 +2691,17 @@ public class ConfigurationImpl implements Configuration, Serializable { return this; } + @Override + public boolean isSuppressSessionNotifications() { + return suppressSessionNotifications; + } + + @Override + public Configuration setSuppressSessionNotifications(boolean suppressSessionNotifications) { + this.suppressSessionNotifications = suppressSessionNotifications; + return this; + } + // extend property utils with ability to auto-fill and locate from collections // collection entries are identified by the name() property private static class CollectionAutoFillPropertiesUtil extends PropertyUtilsBean { diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java index 907b1705af..9fb7689e11 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java @@ -323,6 +323,7 @@ public final class FileConfigurationParser extends XMLConfigurationUtil { private static final String ENABLE_INGRESS_TIMESTAMP = "enable-ingress-timestamp"; + private static final String SUPPRESS_SESSION_NOTIFICATIONS = "suppress-session-notifications"; private boolean validateAIO = false; @@ -769,6 +770,8 @@ public final class FileConfigurationParser extends XMLConfigurationUtil { config.setPageSyncTimeout(getInteger(e, "page-sync-timeout", config.getJournalBufferTimeout_NIO(), Validators.GE_ZERO)); + config.setSuppressSessionNotifications(getBoolean(e, "suppress-session-notifications", config.isSuppressSessionNotifications())); + parseAddressSettings(e, config); parseResourceLimits(e, config); diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java index 97c712df1b..8a9d7c323a 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java @@ -474,6 +474,9 @@ public class ServerSessionImpl implements ServerSession, FailureListener { } private void sendSessionNotification(final CoreNotificationType type) throws Exception { + if (server.getConfiguration().isSuppressSessionNotifications()) { + return; + } final TypedProperties props = new TypedProperties(); if (this.getConnectionID() != null) { props.putSimpleStringProperty(ManagementHelper.HDR_CONNECTION_NAME, SimpleString.toSimpleString(this.getConnectionID().toString())); diff --git a/artemis-server/src/main/resources/schema/artemis-configuration.xsd b/artemis-server/src/main/resources/schema/artemis-configuration.xsd index 8f8a60f606..e418d863f0 100644 --- a/artemis-server/src/main/resources/schema/artemis-configuration.xsd +++ b/artemis-server/src/main/resources/schema/artemis-configuration.xsd @@ -1000,6 +1000,16 @@ + + + + Whether or not to suppress SESSION_CREATED and SESSION_CLOSED notifications. + Set to true to reduce notification overhead. However, these are required to + enforce unique client ID utilization in a cluster for MQTT clients. + + + + diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java index 7a21cfec85..8834c17fa6 100644 --- a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java +++ b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java @@ -136,6 +136,7 @@ public class FileConfigurationTest extends ConfigurationImplTest { Assert.assertEquals("somedir", conf.getBindingsDirectory()); Assert.assertEquals(false, conf.isCreateBindingsDir()); Assert.assertEquals(true, conf.isAmqpUseCoreSubscriptionNaming()); + Assert.assertEquals(false, conf.isSuppressSessionNotifications()); Assert.assertEquals("max concurrent io", 17, conf.getPageMaxConcurrentIO()); Assert.assertEquals(true, conf.isReadWholePage()); diff --git a/artemis-server/src/test/resources/ConfigurationTest-full-config.xml b/artemis-server/src/test/resources/ConfigurationTest-full-config.xml index c331dfaa9d..c2abdc8dc4 100644 --- a/artemis-server/src/test/resources/ConfigurationTest-full-config.xml +++ b/artemis-server/src/test/resources/ConfigurationTest-full-config.xml @@ -67,6 +67,7 @@ 333 777 false + false org.apache.activemq.artemis.tests.unit.core.config.impl.TestInterceptor1 org.apache.activemq.artemis.tests.unit.core.config.impl.TestInterceptor2 diff --git a/docs/user-manual/en/management.md b/docs/user-manual/en/management.md index f725e039b5..e6f61c4d6e 100644 --- a/docs/user-manual/en/management.md +++ b/docs/user-manual/en/management.md @@ -723,6 +723,21 @@ configured in `broker.xml`: By default, the address is `activemq.notifications`. +#### Suppressing Session Notifications + +Some messaging patterns can generate a lot of `SESSION_CREATED` and +`SESSION_CLOSED` notifications. In a clustered environment this will come with +some computational overhead. If these notifications are not otherwise used they +can be disabled through: + +```xml +true +``` + +The only time these notifications are *required* is in a cluster with MQTT +clients where unique client ID utilization needs to be enforced. Default value +is `false` + #### Receiving Notification Messages Apache ActiveMQ Artemis's Core JMS Client can be used to receive notifications: diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/NotificationTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/NotificationTest.java index e6e66cd57c..04be9b2845 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/NotificationTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/NotificationTest.java @@ -193,6 +193,32 @@ public class NotificationTest extends ActiveMQTestBase { session.deleteQueue(queue); } + @Test + public void testSuppressSessionNotifications() throws Exception { + server.getConfiguration().setSuppressSessionNotifications(false); + ClientSessionFactory sf = createSessionFactory(locator); + + NotificationTest.flush(notifConsumer); + ClientSession mySession = sf.createSession("myUser", "myPassword", false, true, true, locator.isPreAcknowledge(), locator.getAckBatchSize()); + + mySession.start(); + ClientMessage[] notifications = NotificationTest.consumeMessages(1, notifConsumer); + Assert.assertEquals(SESSION_CREATED.toString(), notifications[0].getObjectProperty(ManagementHelper.HDR_NOTIFICATION_TYPE).toString()); + mySession.close(); + notifications = NotificationTest.consumeMessages(1, notifConsumer); + Assert.assertEquals(SESSION_CLOSED.toString(), notifications[0].getObjectProperty(ManagementHelper.HDR_NOTIFICATION_TYPE).toString()); + + NotificationTest.flush(notifConsumer); + server.getConfiguration().setSuppressSessionNotifications(true); + mySession = sf.createSession("myUser", "myPassword", false, true, true, locator.isPreAcknowledge(), locator.getAckBatchSize()); + + mySession.start(); + NotificationTest.consumeMessages(0, notifConsumer); + mySession.close(); + NotificationTest.consumeMessages(0, notifConsumer); + + } + @Test public void testCONSUMER_CLOSED() throws Exception { ClientSessionFactory sf = createSessionFactory(locator);