This is an automated email from the ASF dual-hosted git repository.
gtully pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git
The following commit(s) were added to refs/heads/main by this push:
new cca027b1cc ARTEMIS-4443 support broker plugin config via broker
properties
cca027b1cc is described below
commit cca027b1cc6b122c4cf0a81427bb60761fdcd08e
Author: Gary Tully <[email protected]>
AuthorDate: Tue Sep 26 10:04:56 2023 +0100
ARTEMIS-4443 support broker plugin config via broker properties
---
.../core/config/impl/ConfigurationImpl.java | 86 ++++++++++++++--------
.../core/server/impl/ActiveMQServerImpl.java | 2 +-
.../server/plugin/ActiveMQServerBasePlugin.java | 5 +-
.../core/config/impl/ConfigurationImplTest.java | 38 ++++++++++
4 files changed, 98 insertions(+), 33 deletions(-)
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 dedf624054..ab1af3cbd6 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
@@ -138,6 +138,8 @@ public class ConfigurationImpl implements Configuration,
Serializable {
public static final JournalType DEFAULT_JOURNAL_TYPE = JournalType.ASYNCIO;
+ public static final String DOT_CLASS = ".class";
+
private static final int DEFAULT_JMS_MESSAGE_SIZE = 1864;
private static final int RANGE_SIZE_MIN = 0;
@@ -811,6 +813,21 @@ public class ConfigurationImpl implements Configuration,
Serializable {
}
}, java.util.Set.class);
+ beanUtils.getConvertUtils().register(new Converter() {
+ @Override
+ public <T> T convert(Class<T> type, Object value) {
+ Map convertedValue = new HashMap();
+ for (String entry : value.toString().split(",")) {
+ String[] kv = entry.split("=");
+ if (2 != kv.length) {
+ throw new IllegalArgumentException("map value " + value + "
not in k=v format");
+ }
+ convertedValue.put(kv[0], kv[1]);
+ }
+ return (T) convertedValue;
+ }
+ }, java.util.Map.class);
+
// support 25K or 25m etc like xml config
beanUtils.getConvertUtils().register(new Converter() {
@Override
@@ -2139,41 +2156,44 @@ public class ConfigurationImpl implements
Configuration, Serializable {
@Override
public void registerBrokerPlugin(final ActiveMQServerBasePlugin plugin) {
- brokerPlugins.add(plugin);
- if (plugin instanceof ActiveMQServerConnectionPlugin) {
+ // programmatic call can be a duplicate if used before server start
+ if (!brokerPlugins.contains(plugin)) {
+ brokerPlugins.add(plugin);
+ }
+ if (plugin instanceof ActiveMQServerConnectionPlugin &&
!brokerConnectionPlugins.contains(plugin)) {
brokerConnectionPlugins.add((ActiveMQServerConnectionPlugin) plugin);
}
- if (plugin instanceof ActiveMQServerSessionPlugin) {
+ if (plugin instanceof ActiveMQServerSessionPlugin &&
!brokerSessionPlugins.contains(plugin)) {
brokerSessionPlugins.add((ActiveMQServerSessionPlugin) plugin);
}
- if (plugin instanceof ActiveMQServerConsumerPlugin) {
+ if (plugin instanceof ActiveMQServerConsumerPlugin &&
!brokerConsumerPlugins.contains(plugin)) {
brokerConsumerPlugins.add((ActiveMQServerConsumerPlugin) plugin);
}
- if (plugin instanceof ActiveMQServerAddressPlugin) {
+ if (plugin instanceof ActiveMQServerAddressPlugin &&
!brokerAddressPlugins.contains(plugin)) {
brokerAddressPlugins.add((ActiveMQServerAddressPlugin) plugin);
}
- if (plugin instanceof ActiveMQServerQueuePlugin) {
+ if (plugin instanceof ActiveMQServerQueuePlugin &&
!brokerQueuePlugins.contains(plugin)) {
brokerQueuePlugins.add((ActiveMQServerQueuePlugin) plugin);
}
- if (plugin instanceof ActiveMQServerBindingPlugin) {
+ if (plugin instanceof ActiveMQServerBindingPlugin &&
!brokerBindingPlugins.contains(plugin)) {
brokerBindingPlugins.add((ActiveMQServerBindingPlugin) plugin);
}
- if (plugin instanceof ActiveMQServerMessagePlugin) {
+ if (plugin instanceof ActiveMQServerMessagePlugin &&
!brokerMessagePlugins.contains(plugin)) {
brokerMessagePlugins.add((ActiveMQServerMessagePlugin) plugin);
}
- if (plugin instanceof ActiveMQServerBridgePlugin) {
+ if (plugin instanceof ActiveMQServerBridgePlugin &&
!brokerBridgePlugins.contains(plugin)) {
brokerBridgePlugins.add((ActiveMQServerBridgePlugin) plugin);
}
- if (plugin instanceof ActiveMQServerCriticalPlugin) {
+ if (plugin instanceof ActiveMQServerCriticalPlugin &&
!brokerCriticalPlugins.contains(plugin)) {
brokerCriticalPlugins.add((ActiveMQServerCriticalPlugin) plugin);
}
- if (plugin instanceof ActiveMQServerFederationPlugin) {
+ if (plugin instanceof ActiveMQServerFederationPlugin &&
!brokerFederationPlugins.contains(plugin)) {
brokerFederationPlugins.add((ActiveMQServerFederationPlugin) plugin);
}
- if (plugin instanceof AMQPFederationBrokerPlugin) {
+ if (plugin instanceof AMQPFederationBrokerPlugin &&
!brokerAMQPFederationPlugins.contains(plugin)) {
brokerAMQPFederationPlugins.add((AMQPFederationBrokerPlugin) plugin);
}
- if (plugin instanceof ActiveMQServerResourcePlugin) {
+ if (plugin instanceof ActiveMQServerResourcePlugin &&
!brokerResourcePlugins.contains(plugin)) {
brokerResourcePlugins.add((ActiveMQServerResourcePlugin) plugin);
}
}
@@ -3341,24 +3361,28 @@ public class ConfigurationImpl implements
Configuration, Serializable {
}
}
- // we don't know the type, infer from add method add(X x) or
add(String key, X x)
- final String addPropertyName = addPropertyNameBuilder.toString();
- final Method[] methods = hostingBean.getClass().getMethods();
- final Method candidate = Arrays.stream(methods).filter(method ->
method.getName().equals(addPropertyName) &&
- ((method.getParameterCount() == 1) || (method.getParameterCount()
== 2
- // has a String key
- && String.class.equals(method.getParameterTypes()[0])
- // but not initialised from a String form (eg: uri)
- && !String.class.equals(method.getParameterTypes()[1]))))
- .sorted((method1, method2) -> method2.getParameterCount() -
method1.getParameterCount()).findFirst().orElse(null);
-
- if (candidate == null) {
- throw new IllegalArgumentException("failed to locate add method
for collection property " + addPropertyName);
- }
-
- // create one and initialise with name
+ Object instance = null;
try {
- Object instance =
candidate.getParameterTypes()[candidate.getParameterCount() -
1].getDeclaredConstructor().newInstance();
+ if (name.indexOf(DOT_CLASS) > 0) {
+ final String clazzName = name.substring(0, name.length() -
DOT_CLASS.length());
+ instance =
this.getClass().getClassLoader().loadClass(clazzName).getDeclaredConstructor().newInstance();
+ } else {
+ // we don't know the type, infer from add method add(X x) or
add(String key, X x)
+ final String addPropertyName =
addPropertyNameBuilder.toString();
+ final Method[] methods = hostingBean.getClass().getMethods();
+ final Method candidate = Arrays.stream(methods).filter(method
-> method.getName().equals(addPropertyName) && ((method.getParameterCount() ==
1) || (method.getParameterCount() == 2
+ // has a String key
+ && String.class.equals(method.getParameterTypes()[0])
+ // but not initialised from a String form (eg: uri)
+ &&
!String.class.equals(method.getParameterTypes()[1])))).sorted((method1,
method2) -> method2.getParameterCount() -
method1.getParameterCount()).findFirst().orElse(null);
+
+ if (candidate == null) {
+ throw new IllegalArgumentException("failed to locate add
method for collection property " + addPropertyName);
+ }
+
+ instance =
candidate.getParameterTypes()[candidate.getParameterCount() -
1].getDeclaredConstructor().newInstance();
+ }
+ // initialise with name
try {
beanUtilsBean.setProperty(instance, "name", name);
@@ -3374,7 +3398,7 @@ public class ConfigurationImpl implements Configuration,
Serializable {
} catch (Exception e) {
if (logger.isDebugEnabled()) {
- logger.debug("Failed to add entry for {} with method: {}",
name, candidate, e);
+ logger.debug("Failed to add entry for {} to collection: {}",
name, hostingBean, e);
}
throw new IllegalArgumentException("failed to add entry for
collection key " + name, e);
}
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 91a2754de3..cff2e68fe9 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
@@ -3364,7 +3364,7 @@ public class ActiveMQServerImpl implements ActiveMQServer
{
}
if (hasBrokerPlugins()) {
- callBrokerPlugins(plugin -> plugin.registered(this));
+ registerBrokerPlugins(getBrokerPlugins());
}
return true;
diff --git
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/plugin/ActiveMQServerBasePlugin.java
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/plugin/ActiveMQServerBasePlugin.java
index bc101918d1..a37d028cce 100644
---
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/plugin/ActiveMQServerBasePlugin.java
+++
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/plugin/ActiveMQServerBasePlugin.java
@@ -19,12 +19,15 @@ package org.apache.activemq.artemis.core.server.plugin;
import java.util.Map;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
-
/**
*
*/
public interface ActiveMQServerBasePlugin {
+ default void setInit(Map<String, String> props) {
+ init(props);
+ }
+
/**
* used to pass configured properties to Plugin
*
diff --git
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImplTest.java
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImplTest.java
index 9e891f0672..2bff8fff74 100644
---
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImplTest.java
+++
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImplTest.java
@@ -543,6 +543,8 @@ public class ConfigurationImplTest extends ActiveMQTestBase
{
conf.registerBrokerPlugin(new LoggingActiveMQServerPlugin());
Assert.assertEquals("ensure one plugin registered", 1,
conf.getBrokerPlugins().size());
+ Assert.assertEquals("ensure one connection plugin registered", 1,
conf.getBrokerConnectionPlugins().size());
+
// This will use serialization to perform a deep copy of the object
Configuration conf2 = conf.copy();
@@ -2110,6 +2112,42 @@ public class ConfigurationImplTest extends
ActiveMQTestBase {
assertTrue(jsonStatus.contains("alder32"));
}
+ @Test
+ public void testPlugin() throws Exception {
+
+ final ConfigurationImpl configuration = new ConfigurationImpl();
+
+ Properties insertionOrderedProperties = new
ConfigurationImpl.InsertionOrderedProperties();
+
+
insertionOrderedProperties.put("brokerPlugins.\"org.apache.activemq.artemis.core.server.plugin.impl.LoggingActiveMQServerPlugin.class\".init",
"LOG_ALL_EVENTS=true,LOG_SESSION_EVENTS=false");
+
+ configuration.parsePrefixedProperties(insertionOrderedProperties, null);
+
+ Assert.assertEquals(1, configuration.getBrokerPlugins().size());
+
Assert.assertTrue(((LoggingActiveMQServerPlugin)(configuration.getBrokerPlugins().get(0))).isLogAll());
+
Assert.assertFalse(((LoggingActiveMQServerPlugin)(configuration.getBrokerPlugins().get(0))).isLogSessionEvents());
+
+ // mimic server initialisePart1
+ configuration.registerBrokerPlugins(configuration.getBrokerPlugins());
+
+ Assert.assertEquals(1, configuration.getBrokerPlugins().size());
+ Assert.assertEquals(1, configuration.getBrokerMessagePlugins().size());
+ Assert.assertEquals(1,
configuration.getBrokerConnectionPlugins().size());
+
+ Assert.assertTrue(configuration.getStatus().contains("\"errors\":[]"));
+
+ // verify invalid map errors out
+ insertionOrderedProperties = new
ConfigurationImpl.InsertionOrderedProperties();
+
+ // possible to change any attribute, but plugins only registered on start
+
insertionOrderedProperties.put("brokerPlugins.\"org.apache.activemq.artemis.core.server.plugin.impl.LoggingActiveMQServerPlugin.class\".init",
"LOG_ALL_EVENTS");
+
+ configuration.parsePrefixedProperties(insertionOrderedProperties, null);
+
+ Assert.assertFalse(configuration.getStatus().contains("\"errors\":[]"));
+ Assert.assertTrue(configuration.getStatus().contains("LOG_ALL_EVENTS"));
+ }
+
/**
* To test ARTEMIS-926
* @throws Throwable