From 454107f13003a0b68a585abf2340e5501d619554 Mon Sep 17 00:00:00 2001 From: AntonRoskvist Date: Mon, 11 Nov 2024 11:16:35 +0100 Subject: [PATCH] ARTEMIS-5141 Add or remove plugins on configuration reload --- .../artemis/core/config/Configuration.java | 10 +++ .../core/config/impl/ConfigurationImpl.java | 16 +++++ .../impl/FileConfigurationParser.java | 2 +- .../core/server/impl/ActiveMQServerImpl.java | 22 +++++++ .../tests/integration/jms/RedeployTest.java | 63 +++++++++++++++++++ .../test/resources/reload-plugin-updated.xml | 44 +++++++++++++ .../src/test/resources/reload-plugin.xml | 32 ++++++++++ 7 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 tests/integration-tests/src/test/resources/reload-plugin-updated.xml create mode 100644 tests/integration-tests/src/test/resources/reload-plugin.xml 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 17765802b57..06664410fd6 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 @@ -1365,6 +1365,11 @@ default boolean isJDBC() { */ void registerBrokerPlugin(ActiveMQServerBasePlugin plugin); + /** + * @param plugin + */ + void registerConfiguredBrokerPlugin(ActiveMQServerBasePlugin plugin); + /** * @param plugin */ @@ -1375,6 +1380,11 @@ default boolean isJDBC() { */ List getBrokerPlugins(); + /** + * @return + */ + List getConfiguredBrokerPlugins(); + /** * @return */ 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 88b77210992..bfa1b47b697 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 @@ -341,6 +341,7 @@ public class ConfigurationImpl implements Configuration, Serializable { private MetricsConfiguration metricsConfiguration = null; private final List brokerPlugins = new CopyOnWriteArrayList<>(); + private final List configuredBrokerPlugins = new CopyOnWriteArrayList<>(); private final List brokerConnectionPlugins = new CopyOnWriteArrayList<>(); private final List brokerSessionPlugins = new CopyOnWriteArrayList<>(); private final List brokerConsumerPlugins = new CopyOnWriteArrayList<>(); @@ -2270,6 +2271,14 @@ public MetricsConfiguration getMetricsConfiguration() { return this.metricsConfiguration; } + @Override + public void registerConfiguredBrokerPlugin(final ActiveMQServerBasePlugin plugin) { + if (!configuredBrokerPlugins.contains(plugin)) { + configuredBrokerPlugins.add(plugin); + registerBrokerPlugin(plugin); + } + } + @Override public void registerBrokerPlugins(final List plugins) { plugins.forEach(plugin -> registerBrokerPlugin(plugin)); @@ -2321,7 +2330,9 @@ public void registerBrokerPlugin(final ActiveMQServerBasePlugin plugin) { @Override public void unRegisterBrokerPlugin(final ActiveMQServerBasePlugin plugin) { + configuredBrokerPlugins.remove(plugin); brokerPlugins.remove(plugin); + if (plugin instanceof ActiveMQServerConnectionPlugin) { brokerConnectionPlugins.remove(plugin); } @@ -2365,6 +2376,11 @@ public List getBrokerPlugins() { return brokerPlugins; } + @Override + public List getConfiguredBrokerPlugins() { + return configuredBrokerPlugins; + } + // for properties type inference public void addBrokerPlugin(ActiveMQServerBasePlugin type) { registerBrokerPlugin(type); 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 6819b307ade..bebf45f7809 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 @@ -980,7 +980,7 @@ private void parseBrokerPlugins(final Element e, final Configuration config) { NodeList list = node.getElementsByTagName(BROKER_PLUGIN_ELEMENT_NAME); for (int i = 0; i < list.getLength(); i++) { ActiveMQServerPlugin plugin = parseActiveMQServerPlugin(list.item(i)); - config.registerBrokerPlugin(plugin); + config.registerConfiguredBrokerPlugin(plugin); } } } 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 eeaf45b258b..4455b4df6f5 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 @@ -4657,6 +4657,7 @@ private void reloadConfigurationFile(URL uri) throws Exception { configuration.parseProperties(propertiesFileUrl); updateStatus(ServerStatus.CONFIGURATION_COMPONENT, configuration.getStatus()); deployReloadableConfigFromConfiguration(); + deployConfiguredBrokerPlugins(config); } } @@ -4788,6 +4789,27 @@ private void deployReloadableConfigFromConfiguration() throws Exception { } } + private void deployConfiguredBrokerPlugins(Configuration newConfiguration) { + ActiveMQServerLogger.LOGGER.reloadingConfiguration("broker plugins"); + + if (hasBrokerPlugins() || !newConfiguration.getConfiguredBrokerPlugins().isEmpty()) { + + for (ActiveMQServerBasePlugin plugin : configuration.getConfiguredBrokerPlugins()) { + if (!newConfiguration.getConfiguredBrokerPlugins().contains(plugin)) { + unRegisterBrokerPlugin(plugin); + } + } + + for (ActiveMQServerBasePlugin plugin : newConfiguration.getConfiguredBrokerPlugins()) { + if (!configuration.getConfiguredBrokerPlugins().contains(plugin)) { + configuration.registerConfiguredBrokerPlugin(plugin); + plugin.registered(this); + } + } + + } + } + public Set getActivateCallbacks() { return activateCallbacks; } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/RedeployTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/RedeployTest.java index c6fbbd64d11..e6007529c5e 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/RedeployTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/RedeployTest.java @@ -61,6 +61,8 @@ import org.apache.activemq.artemis.core.server.cluster.impl.RemoteQueueBindingImpl; import org.apache.activemq.artemis.core.server.embedded.EmbeddedActiveMQ; import org.apache.activemq.artemis.core.server.impl.AddressInfo; +import org.apache.activemq.artemis.core.server.plugin.impl.LoggingActiveMQServerPlugin; +import org.apache.activemq.artemis.core.server.plugin.impl.NotificationActiveMQServerPlugin; import org.apache.activemq.artemis.core.server.reload.ReloadManager; import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy; import org.apache.activemq.artemis.core.settings.impl.AddressSettings; @@ -233,6 +235,67 @@ public void testRedeployConnector() throws Exception { } } + @Test + public void testRedeployPlugin() throws Exception { + Path brokerXML = getTestDirfile().toPath().resolve("broker.xml"); + URL url1 = RedeployTest.class.getClassLoader().getResource("reload-plugin.xml"); + URL url2 = RedeployTest.class.getClassLoader().getResource("reload-plugin-updated.xml"); + Files.copy(url1.openStream(), brokerXML); + + EmbeddedActiveMQ embeddedActiveMQ = new EmbeddedActiveMQ(); + embeddedActiveMQ.setConfigResourcePath(brokerXML.toUri().toString()); + embeddedActiveMQ.start(); + + final ReusableLatch latch = new ReusableLatch(1); + + Runnable tick = latch::countDown; + + embeddedActiveMQ.getActiveMQServer().getReloadManager().setTick(tick); + + try { + latch.await(10, TimeUnit.SECONDS); + + //No plugins registered at start + assertEquals(0, embeddedActiveMQ.getActiveMQServer().getBrokerPlugins().size()); + + //register plugin programmatically + embeddedActiveMQ.getActiveMQServer().registerBrokerPlugin(new NotificationActiveMQServerPlugin()); + assertEquals(1, embeddedActiveMQ.getActiveMQServer().getBrokerPlugins().size()); + assertTrue(embeddedActiveMQ.getActiveMQServer().getBrokerPlugins().stream() + .anyMatch(plugin -> + plugin instanceof NotificationActiveMQServerPlugin)); + + Files.copy(url2.openStream(), brokerXML, StandardCopyOption.REPLACE_EXISTING); + brokerXML.toFile().setLastModified(System.currentTimeMillis() + 1000); + latch.setCount(1); + embeddedActiveMQ.getActiveMQServer().getReloadManager().setTick(tick); + latch.await(10, TimeUnit.SECONDS); + + //plugin added on configuration reload, programmatically added plugin stays registered + assertEquals(2, embeddedActiveMQ.getActiveMQServer().getBrokerPlugins().size()); + assertTrue(embeddedActiveMQ.getActiveMQServer().getBrokerPlugins().stream() + .anyMatch(plugin -> + plugin instanceof NotificationActiveMQServerPlugin)); + assertTrue(embeddedActiveMQ.getActiveMQServer().getBrokerPlugins().stream() + .anyMatch(plugin -> + plugin instanceof LoggingActiveMQServerPlugin)); + + Files.copy(url1.openStream(), brokerXML, StandardCopyOption.REPLACE_EXISTING); + brokerXML.toFile().setLastModified(System.currentTimeMillis() + 1000); + latch.setCount(1); + embeddedActiveMQ.getActiveMQServer().getReloadManager().setTick(tick); + latch.await(10, TimeUnit.SECONDS); + + //removing plugin in config, programmatically added plugin stays registered + assertEquals(1, embeddedActiveMQ.getActiveMQServer().getBrokerPlugins().size()); + assertTrue(embeddedActiveMQ.getActiveMQServer().getBrokerPlugins().stream() + .anyMatch(plugin -> + plugin instanceof NotificationActiveMQServerPlugin)); + } finally { + embeddedActiveMQ.stop(); + } + } + @Test public void testRedeploySecuritySettings() throws Exception { Path brokerXML = getTestDirfile().toPath().resolve("broker.xml"); diff --git a/tests/integration-tests/src/test/resources/reload-plugin-updated.xml b/tests/integration-tests/src/test/resources/reload-plugin-updated.xml new file mode 100644 index 00000000000..48370f35260 --- /dev/null +++ b/tests/integration-tests/src/test/resources/reload-plugin-updated.xml @@ -0,0 +1,44 @@ + + + + + + + + 100 + + false + + + + + + + + + + + + + + + diff --git a/tests/integration-tests/src/test/resources/reload-plugin.xml b/tests/integration-tests/src/test/resources/reload-plugin.xml new file mode 100644 index 00000000000..530d654c0c3 --- /dev/null +++ b/tests/integration-tests/src/test/resources/reload-plugin.xml @@ -0,0 +1,32 @@ + + + + + + + + 100 + + false + + +