From 2b057fab64a260755140854fe9f227cae6d99285 Mon Sep 17 00:00:00 2001 From: Pat Fox Date: Sat, 23 Dec 2017 21:04:31 +0100 Subject: [PATCH] ARTEMIS-1575 configure custom broker plugins with key/value properties. The properties are read and passed into the the broker plugin's init(Map) --- .../impl/FileConfigurationParser.java | 29 ++++++--- .../server/plugin/ActiveMQServerPlugin.java | 7 ++ .../schema/artemis-configuration.xsd | 46 +++++++------ .../src/test/resources/brokerPlugin.xml | 6 +- .../test/resources/artemis-configuration.xsd | 37 +++++------ docs/user-manual/en/broker-plugins.md | 10 ++- .../plugin/ConfigurationVerifier.java | 64 +++++++++++++++++++ .../integration/plugin/CorePluginTest.java | 8 +++ .../plugin/XmlConfigPluginTest.java | 7 +- .../test/resources/broker-plugins-config.xml | 4 ++ 10 files changed, 168 insertions(+), 50 deletions(-) create mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/plugin/ConfigurationVerifier.java 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 b29e1b4529f..9b9050b47d8 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 @@ -703,6 +703,8 @@ private void parseBrokerPlugins(final Element e, final Configuration config) { private ActiveMQServerPlugin parseActiveMQServerPlugin(Node item) { final String clazz = item.getAttributes().getNamedItem("class-name").getNodeValue(); + Map properties = getMapOfChildPropertyElements(item); + ActiveMQServerPlugin serverPlugin = AccessController.doPrivileged(new PrivilegedAction() { @Override public ActiveMQServerPlugin run() { @@ -710,9 +712,25 @@ public ActiveMQServerPlugin run() { } }); + serverPlugin.init(properties); + return serverPlugin; } + private Map getMapOfChildPropertyElements(Node item) { + Map properties = new HashMap<>(); + NodeList children = item.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if (child.getNodeName().equals("property")) { + String key = getAttributeValue(child, "key"); + String value = getAttributeValue(child, "value"); + properties.put(key, value); + } + } + return properties; + } + /** * @param e * @param config @@ -1656,16 +1674,7 @@ private TransformerConfiguration getTransformerConfiguration(final Node node) { Element element = (Element) node; String className = getString(element, "class-name", null, Validators.NO_CHECK); - Map properties = new HashMap<>(); - NodeList children = element.getChildNodes(); - for (int j = 0; j < children.getLength(); j++) { - Node child = children.item(j); - if (child.getNodeName().equals("property")) { - String key = getAttributeValue(child, "key"); - String value = getAttributeValue(child, "value"); - properties.put(key, value); - } - } + Map properties = getMapOfChildPropertyElements(element); return new TransformerConfiguration(className).setProperties(properties); } diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/plugin/ActiveMQServerPlugin.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/plugin/ActiveMQServerPlugin.java index fddec48ecea..c5e22ef23aa 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/plugin/ActiveMQServerPlugin.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/plugin/ActiveMQServerPlugin.java @@ -460,4 +460,11 @@ default void afterDeployBridge(Bridge bridge) throws ActiveMQException { default void criticalFailure(CriticalComponent components) throws ActiveMQException { } + /** + * used to pass configured properties to Plugin + * + * @param properties + */ + default void init(Map properties) { + } } diff --git a/artemis-server/src/main/resources/schema/artemis-configuration.xsd b/artemis-server/src/main/resources/schema/artemis-configuration.xsd index 18ad6e47114..58abd67f5c9 100644 --- a/artemis-server/src/main/resources/schema/artemis-configuration.xsd +++ b/artemis-server/src/main/resources/schema/artemis-configuration.xsd @@ -934,6 +934,15 @@ a broker plugin + + + + + properties to configure a plugin + + + + @@ -1443,7 +1452,7 @@ - + properties to configure the transformer class @@ -1453,23 +1462,24 @@ - - - - - - key for the property - - - - - - - value for the property - - - - + + + + + + key for the property + + + + + + + value for the property + + + + + diff --git a/artemis-server/src/test/resources/brokerPlugin.xml b/artemis-server/src/test/resources/brokerPlugin.xml index 6b1da34e97f..828b0ecc91e 100644 --- a/artemis-server/src/test/resources/brokerPlugin.xml +++ b/artemis-server/src/test/resources/brokerPlugin.xml @@ -20,7 +20,11 @@ xsi:schemaLocation="urn:activemq ../../../../activemq-server/src/main/resources/schema/artemis-server.xsd"> - + + + + + diff --git a/artemis-tools/src/test/resources/artemis-configuration.xsd b/artemis-tools/src/test/resources/artemis-configuration.xsd index 47a92ffcb4c..c0b88f9ecc5 100644 --- a/artemis-tools/src/test/resources/artemis-configuration.xsd +++ b/artemis-tools/src/test/resources/artemis-configuration.xsd @@ -1271,7 +1271,7 @@ - + properties to configure the transformer class @@ -1281,23 +1281,24 @@ - - - - - - key for the property - - - - - - - value for the property - - - - + + + + + + key for the property + + + + + + + value for the property + + + + + diff --git a/docs/user-manual/en/broker-plugins.md b/docs/user-manual/en/broker-plugins.md index d524f68f071..9d19c1698f5 100644 --- a/docs/user-manual/en/broker-plugins.md +++ b/docs/user-manual/en/broker-plugins.md @@ -16,14 +16,20 @@ If you are using an embed system than you will need the jar under the regular cl ## Registering a Plugin -To register a plugin with by XML you need to add the `broker-plugins` element at the `broker.xml`. +To register a plugin with by XML you need to add the `broker-plugins` element at the `broker.xml`. It is also possible +to pass configuration to a plugin using the `property` child element(s). These properties (zero to many) +will be read and passed into the Plugin's `init(Map)` operation after the plugin +has been instantiated. ```xml ... - + + + + ... diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/plugin/ConfigurationVerifier.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/plugin/ConfigurationVerifier.java new file mode 100644 index 00000000000..88f0ec392be --- /dev/null +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/plugin/ConfigurationVerifier.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package org.apache.activemq.artemis.tests.integration.plugin; + +import java.io.Serializable; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.activemq.artemis.api.core.ActiveMQException; +import org.apache.activemq.artemis.api.core.Message; +import org.apache.activemq.artemis.core.postoffice.RoutingStatus; +import org.apache.activemq.artemis.core.server.ServerSession; +import org.apache.activemq.artemis.core.server.plugin.ActiveMQServerPlugin; +import org.apache.activemq.artemis.core.transaction.Transaction; + +/** + * Used in tests to verify configuration passed into plugin correctly. + */ +public class ConfigurationVerifier implements ActiveMQServerPlugin, Serializable { + + public static final String PROPERTY1 = "property1"; + public static final String PROPERTY2 = "property2"; + public static final String PROPERTY3 = "property3"; + + public String value1; + public String value2; + public String value3; + public AtomicInteger afterSendCounter = new AtomicInteger(); + + @Override + public void init(Map properties) { + value1 = properties.get(PROPERTY1); + value2 = properties.get(PROPERTY2); + value3 = properties.get(PROPERTY3); + } + + /** + * Used to ensure the plugin is being invoked + */ + @Override + public void afterSend(ServerSession session, + Transaction tx, + Message message, + boolean direct, + boolean noAutoCreateQueue, + RoutingStatus result) throws ActiveMQException { + afterSendCounter.incrementAndGet(); + } + +} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/plugin/CorePluginTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/plugin/CorePluginTest.java index 191869d521c..7df0ac01d20 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/plugin/CorePluginTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/plugin/CorePluginTest.java @@ -76,12 +76,17 @@ public class CorePluginTest extends JMSTestBase { private final Map methodCalls = new HashMap<>(); private final MethodCalledVerifier verifier = new MethodCalledVerifier(methodCalls); + private final ConfigurationVerifier configurationVerifier = new ConfigurationVerifier(); public static final String INVM_CONNECTOR_FACTORY = InVMConnectorFactory.class.getCanonicalName(); @Override protected Configuration createDefaultConfig(boolean netty) throws Exception { Configuration config = super.createDefaultConfig(netty); config.registerBrokerPlugin(verifier); + Map props = new HashMap<>(1); + props.put(ConfigurationVerifier.PROPERTY1, "val_1"); + configurationVerifier.init(props); + config.registerBrokerPlugin(configurationVerifier); config.setMessageExpiryScanPeriod(0); // disable expiry scan so it's alwyas through delivery return config; } @@ -118,6 +123,9 @@ public void testSendReceive() throws Exception { AFTER_MESSAGE_ROUTE); verifier.validatePluginMethodsEquals(2, BEFORE_CREATE_SESSION, AFTER_CREATE_SESSION, BEFORE_CLOSE_SESSION, AFTER_CLOSE_SESSION); + + assertEquals("configurationVerifier is invoked", 1, configurationVerifier.afterSendCounter.get()); + assertEquals("configurationVerifier config set", "val_1", configurationVerifier.value1); } @Test diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/plugin/XmlConfigPluginTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/plugin/XmlConfigPluginTest.java index fc8109877e4..2dcd9ccfabf 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/plugin/XmlConfigPluginTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/plugin/XmlConfigPluginTest.java @@ -38,8 +38,13 @@ public void testStopStart1() throws Exception { ActiveMQServer server = addServer(new ActiveMQServerImpl(fc)); try { server.start(); - assertEquals(1, server.getBrokerPlugins().size()); + assertEquals(2, server.getBrokerPlugins().size()); assertTrue(server.getBrokerPlugins().get(0) instanceof MethodCalledVerifier); + assertTrue(server.getBrokerPlugins().get(1) instanceof ConfigurationVerifier); + ConfigurationVerifier configurationVerifier = (ConfigurationVerifier) server.getBrokerPlugins().get(1); + assertEquals("value1", "val_1", configurationVerifier.value1); + assertEquals("value2", "val_2", configurationVerifier.value2); + assertNull("value3 should not have been set", configurationVerifier.value3); } finally { if (server != null) { server.stop(); diff --git a/tests/integration-tests/src/test/resources/broker-plugins-config.xml b/tests/integration-tests/src/test/resources/broker-plugins-config.xml index a8ac3fb2f8e..b795e38372f 100644 --- a/tests/integration-tests/src/test/resources/broker-plugins-config.xml +++ b/tests/integration-tests/src/test/resources/broker-plugins-config.xml @@ -42,6 +42,10 @@ + + + +