ARTEMIS-1575 configure custom broker plugins with key/value properties.
The properties are read and passed into the the broker plugin's init(Map<String,String>)
This commit is contained in:
parent
1ef8199f23
commit
d95757057e
|
@ -703,6 +703,8 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
|
|||
private ActiveMQServerPlugin parseActiveMQServerPlugin(Node item) {
|
||||
final String clazz = item.getAttributes().getNamedItem("class-name").getNodeValue();
|
||||
|
||||
Map<String, String> properties = getMapOfChildPropertyElements(item);
|
||||
|
||||
ActiveMQServerPlugin serverPlugin = AccessController.doPrivileged(new PrivilegedAction<ActiveMQServerPlugin>() {
|
||||
@Override
|
||||
public ActiveMQServerPlugin run() {
|
||||
|
@ -710,9 +712,25 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
|
|||
}
|
||||
});
|
||||
|
||||
serverPlugin.init(properties);
|
||||
|
||||
return serverPlugin;
|
||||
}
|
||||
|
||||
private Map<String, String> getMapOfChildPropertyElements(Node item) {
|
||||
Map<String, String> 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 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
|
|||
Element element = (Element) node;
|
||||
String className = getString(element, "class-name", null, Validators.NO_CHECK);
|
||||
|
||||
Map<String, String> 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<String, String> properties = getMapOfChildPropertyElements(element);
|
||||
return new TransformerConfiguration(className).setProperties(properties);
|
||||
}
|
||||
|
||||
|
|
|
@ -460,4 +460,11 @@ public interface ActiveMQServerPlugin {
|
|||
default void criticalFailure(CriticalComponent components) throws ActiveMQException {
|
||||
}
|
||||
|
||||
/**
|
||||
* used to pass configured properties to Plugin
|
||||
*
|
||||
* @param properties
|
||||
*/
|
||||
default void init(Map<String, String> properties) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -934,6 +934,15 @@
|
|||
a broker plugin
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="property" maxOccurs="unbounded" minOccurs="0">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
properties to configure a plugin
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="class-name" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
|
@ -1443,7 +1452,7 @@
|
|||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="property" type="transformerProperty" maxOccurs="unbounded" minOccurs="0">
|
||||
<xsd:element ref="property" maxOccurs="unbounded" minOccurs="0">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
properties to configure the transformer class
|
||||
|
@ -1453,8 +1462,8 @@
|
|||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
|
||||
<xsd:complexType name="transformerProperty">
|
||||
<xsd:element name="property">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="key" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
|
@ -1470,6 +1479,7 @@
|
|||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
|
||||
<!-- CLUSTER CONNECTION CONFIGURATION -->
|
||||
|
|
|
@ -20,7 +20,11 @@
|
|||
xsi:schemaLocation="urn:activemq ../../../../activemq-server/src/main/resources/schema/artemis-server.xsd">
|
||||
<core xmlns="urn:activemq:core">
|
||||
<broker-plugins>
|
||||
<broker-plugin class-name="org.apache.activemq.artemis.core.config.impl.FileConfigurationTest$EmptyPlugin1" />
|
||||
<broker-plugin class-name="org.apache.activemq.artemis.core.config.impl.FileConfigurationTest$EmptyPlugin1">
|
||||
<property key="key1" value="value1"/>
|
||||
<property key="key2" value="value2"/>
|
||||
<property key="key3" value="value3"/>
|
||||
</broker-plugin>
|
||||
<broker-plugin class-name="org.apache.activemq.artemis.core.config.impl.FileConfigurationTest$EmptyPlugin2" />
|
||||
</broker-plugins>
|
||||
</core>
|
||||
|
|
|
@ -1271,7 +1271,7 @@
|
|||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="property" type="transformerProperty" maxOccurs="unbounded" minOccurs="0">
|
||||
<xsd:element ref="property" maxOccurs="unbounded" minOccurs="0">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
properties to configure the transformer class
|
||||
|
@ -1281,8 +1281,8 @@
|
|||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
|
||||
<xsd:complexType name="transformerProperty">
|
||||
<xsd:element name="property">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="key" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
|
@ -1298,6 +1298,7 @@
|
|||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
|
||||
<!-- CLUSTER CONNECTION CONFIGURATION -->
|
||||
|
|
|
@ -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<String, String>)` operation after the plugin
|
||||
has been instantiated.
|
||||
|
||||
```xml
|
||||
<configuration ...>
|
||||
|
||||
...
|
||||
<broker-plugins>
|
||||
<broker-plugin class-name="some.plugin.UserPlugin" />
|
||||
<broker-plugin class-name="some.plugin.UserPlugin">
|
||||
<property key="property1" value="val_1" />
|
||||
<property key="property2" value="val_2" />
|
||||
</broker-plugin>
|
||||
</broker-plugins>
|
||||
...
|
||||
|
||||
|
|
|
@ -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
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* 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<String, String> 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();
|
||||
}
|
||||
|
||||
}
|
|
@ -76,12 +76,17 @@ public class CorePluginTest extends JMSTestBase {
|
|||
|
||||
private final Map<String, AtomicInteger> 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<String, String> 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 class CorePluginTest extends JMSTestBase {
|
|||
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
|
||||
|
|
|
@ -38,8 +38,13 @@ public class XmlConfigPluginTest extends ActiveMQTestBase {
|
|||
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();
|
||||
|
|
|
@ -42,6 +42,10 @@
|
|||
|
||||
<broker-plugins>
|
||||
<broker-plugin class-name="org.apache.activemq.artemis.tests.integration.plugin.MethodCalledVerifier" />
|
||||
<broker-plugin class-name="org.apache.activemq.artemis.tests.integration.plugin.ConfigurationVerifier">
|
||||
<property key="property1" value="val_1"/>
|
||||
<property key="property2" value="val_2"/>
|
||||
</broker-plugin>
|
||||
</broker-plugins>
|
||||
</core>
|
||||
|
||||
|
|
Loading…
Reference in New Issue