ARTEMIS-4818 Improve support for multiple broker plugins from broker properties

This commit is contained in:
Domenico Francesco Bruscino 2024-06-14 13:23:43 +02:00 committed by Gary Tully
parent 4967a0c4ba
commit a10694f202
2 changed files with 65 additions and 16 deletions

View File

@ -141,7 +141,7 @@ public class ConfigurationImpl implements Configuration, Serializable {
public static final JournalType DEFAULT_JOURNAL_TYPE = JournalType.ASYNCIO;
public static final String DOT_CLASS = ".class";
public static final String PROPERTY_CLASS_SUFFIX = ".class";
private static final int DEFAULT_JMS_MESSAGE_SIZE = 1864;
@ -798,8 +798,8 @@ public class ConfigurationImpl implements Configuration, Serializable {
} else { // Value into scalar
if (value instanceof String) {
String possibleDotClassValue = (String)value;
if (type != String.class && possibleDotClassValue.endsWith(DOT_CLASS)) {
final String clazzName = possibleDotClassValue.substring(0, possibleDotClassValue.length() - DOT_CLASS.length());
if (type != String.class && isClassProperty(possibleDotClassValue)) {
final String clazzName = extractPropertyClassName(possibleDotClassValue);
try {
newValue = ClassloadingUtil.getInstanceWithTypeCheck(clazzName, type, this.getClass().getClassLoader());
} catch (Exception e) {
@ -958,6 +958,15 @@ public class ConfigurationImpl implements Configuration, Serializable {
updateApplyStatus(propsId, errors);
}
private static boolean isClassProperty(String property) {
return property.endsWith(PROPERTY_CLASS_SUFFIX);
}
private static String extractPropertyClassName(String property) {
int propertyClassSuffixIndex = property.indexOf(PROPERTY_CLASS_SUFFIX);
return property.substring(0, propertyClassSuffixIndex);
}
private void trackError(HashMap<String, String> errors, Map.Entry<String,?> entry, Throwable oops) {
logger.debug("failed to populate property entry({}), reason: {}", entry, oops);
errors.put(entry.toString(), oops.toString());
@ -3489,10 +3498,19 @@ public class ConfigurationImpl implements Configuration, Serializable {
private Object findByNameProperty(String key, Collection collection) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
// locate on name property, may be a SimpleString
for (Object candidate : collection) {
Object candidateName = getProperty(candidate, "name");
if (candidateName != null && key.equals(candidateName.toString())) {
return candidate;
if (isClassProperty(key)) {
Object propertyClassName = extractPropertyClassName(key);
for (Object candidate : collection) {
if (candidate.getClass().getName().equals(propertyClassName)) {
return candidate;
}
}
} else {
for (Object candidate : collection) {
Object candidateName = getProperty(candidate, "name");
if (candidateName != null && key.equals(candidateName.toString())) {
return candidate;
}
}
}
return null;
@ -3603,8 +3621,8 @@ public class ConfigurationImpl implements Configuration, Serializable {
}
Class type = candidate.getParameterTypes()[candidate.getParameterCount() - 1];
if (name.indexOf(DOT_CLASS) > 0) {
final String clazzName = name.substring(0, name.length() - DOT_CLASS.length());
if (isClassProperty(name)) {
final String clazzName = extractPropertyClassName(name);
instance = ClassloadingUtil.getInstanceWithTypeCheck(clazzName, type, this.getClass().getClassLoader());
} else {
instance = type.getDeclaredConstructor().newInstance();

View File

@ -2116,18 +2116,23 @@ public class ConfigurationImplTest extends AbstractConfigurationTestBase {
assertTrue(configuration.getStatus().contains("\"errors\":[]"));
// verify invalid map errors out
insertionOrderedProperties = new ConfigurationImpl.InsertionOrderedProperties();
// impossible to change any attribute unless the plugin has a name attribute, but plugins only registered on start
// change attribute of a plugin without the name attribute, but plugins only registered on start
insertionOrderedProperties.put("brokerPlugins.\"org.apache.activemq.artemis.core.server.plugin.impl.LoggingActiveMQServerPlugin.class\".init", "LOG_ALL_EVENTS=false");
configuration.parsePrefixedProperties(insertionOrderedProperties, null);
assertEquals(1, configuration.getBrokerPlugins().size());
assertFalse(((LoggingActiveMQServerPlugin)(configuration.getBrokerPlugins().get(0))).isLogAll());
// verify error
insertionOrderedProperties.put("brokerPlugins.\"org.apache.activemq.artemis.core.server.plugin.impl.LoggingActiveMQServerPlugin.class\".init", "LOG_ALL_EVENTS");
configuration.parsePrefixedProperties(insertionOrderedProperties, null);
// verify error
assertFalse(configuration.getStatus().contains("\"errors\":[]"));
assertTrue(configuration.getStatus().contains("LOG_ALL_EVENTS"));
assertTrue(configuration.getStatus().contains("Unknown property 'name'"));
}
@Test
@ -2153,6 +2158,26 @@ public class ConfigurationImplTest extends AbstractConfigurationTestBase {
assertEquals("netty-.*", ((ConnectionPeriodicExpiryPlugin)(configuration.getBrokerPlugins().get(0))).getAcceptorMatchRegex());
}
@Test
public void testMultiplePlugins() 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");
insertionOrderedProperties.put("brokerPlugins.\"org.apache.activemq.artemis.core.server.plugin.impl.ConnectionPeriodicExpiryPlugin.class\".periodSeconds", "30");
insertionOrderedProperties.put("brokerPlugins.\"org.apache.activemq.artemis.core.server.plugin.impl.ConnectionPeriodicExpiryPlugin.class\".accuracyWindowSeconds", "10");
configuration.parsePrefixedProperties(insertionOrderedProperties, null);
assertTrue(configuration.getStatus().contains("\"errors\":[]"), configuration.getStatus());
assertEquals(2, configuration.getBrokerPlugins().size());
assertTrue(((LoggingActiveMQServerPlugin)(configuration.getBrokerPlugins().get(0))).isLogAll());
assertEquals(30, ((ConnectionPeriodicExpiryPlugin)(configuration.getBrokerPlugins().get(1))).getPeriodSeconds());
assertEquals(10, ((ConnectionPeriodicExpiryPlugin)(configuration.getBrokerPlugins().get(1))).getAccuracyWindowSeconds());
}
@Test
public void testConnectionExpiryPluginInit() throws Exception {
@ -2215,17 +2240,23 @@ public class ConfigurationImplTest extends AbstractConfigurationTestBase {
assertTrue(configuration.getStatus().contains("\"errors\":[]"));
// verify invalid map errors out
insertionOrderedProperties = new ConfigurationImpl.InsertionOrderedProperties();
// impossible to change any attribute unless there is a name attribute, but plugins only registered on start
// change attribute of a plugin without the name attribute, but plugins only registered on start
insertionOrderedProperties.put("securitySettingPlugins.\"org.apache.activemq.artemis.core.server.impl.LegacyLDAPSecuritySettingPlugin.class\".init", "initialContextFactory=org.eclipse.jetty.jndi.InitialContextFactory");
configuration.parsePrefixedProperties(insertionOrderedProperties, null);
assertEquals(1, configuration.getSecuritySettingPlugins().size());
assertEquals("org.eclipse.jetty.jndi.InitialContextFactory", ((LegacyLDAPSecuritySettingPlugin)(configuration.getSecuritySettingPlugins().get(0))).getInitialContextFactory());
// verify error
insertionOrderedProperties.put("securitySettingPlugins.\"org.apache.activemq.artemis.core.server.impl.LegacyLDAPSecuritySettingPlugin.class\".init", "initialContextFactory");
configuration.parsePrefixedProperties(insertionOrderedProperties, null);
assertFalse(configuration.getStatus().contains("\"errors\":[]"));
assertTrue(configuration.getStatus().contains("initialContextFactory"));
assertTrue(configuration.getStatus().contains("Unknown property 'name'"));
}
/**