ARTEMIS-4552 Config all connection-router settings by using broker properties

This commit is contained in:
Domenico Francesco Bruscino 2024-01-18 13:41:16 +01:00 committed by Robbie Gemmell
parent 4ea55cd611
commit 2b331427d8
2 changed files with 108 additions and 6 deletions

View File

@ -614,6 +614,31 @@ public class ConfigurationImpl implements Configuration, Serializable {
public void populateWithProperties(final Object target, final String propsId, Map<String, Object> beanProperties) throws InvocationTargetException, IllegalAccessException { public void populateWithProperties(final Object target, final String propsId, Map<String, Object> beanProperties) throws InvocationTargetException, IllegalAccessException {
CollectionAutoFillPropertiesUtil autoFillCollections = new CollectionAutoFillPropertiesUtil(getBrokerPropertiesRemoveValue(beanProperties)); CollectionAutoFillPropertiesUtil autoFillCollections = new CollectionAutoFillPropertiesUtil(getBrokerPropertiesRemoveValue(beanProperties));
BeanUtilsBean beanUtils = new BeanUtilsBean(new ConvertUtilsBean(), autoFillCollections) { BeanUtilsBean beanUtils = new BeanUtilsBean(new ConvertUtilsBean(), autoFillCollections) {
// initialize the given property of the given bean with a new instance of the property class
private Object initProperty(Object bean, String name) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
PropertyDescriptor descriptor = getPropertyUtils().getPropertyDescriptor(bean, name);
if (descriptor == null) {
throw new InvocationTargetException(null, "No accessor method descriptor for: " + name + " on: " + bean.getClass());
}
Method writeMethod = descriptor.getWriteMethod();
if (writeMethod == null) {
throw new InvocationTargetException(null, "No Write method for: " + name + " on: " + bean.getClass());
}
Object propertyInstance;
try {
propertyInstance = descriptor.getPropertyType().getDeclaredConstructor().newInstance();
} catch (InstantiationException e) {
throw new InvocationTargetException(e);
}
writeMethod.invoke(bean, propertyInstance);
return propertyInstance;
}
// override to treat missing properties as errors, not skip as the default impl does // override to treat missing properties as errors, not skip as the default impl does
@Override @Override
public void setProperty(final Object bean, String name, final Object value) throws InvocationTargetException, IllegalAccessException { public void setProperty(final Object bean, String name, final Object value) throws InvocationTargetException, IllegalAccessException {
@ -626,10 +651,12 @@ public class ConfigurationImpl implements Configuration, Serializable {
final Resolver resolver = getPropertyUtils().getResolver(); final Resolver resolver = getPropertyUtils().getResolver();
while (resolver.hasNested(name)) { while (resolver.hasNested(name)) {
try { try {
target = getPropertyUtils().getProperty(target, resolver.next(name)); String nextName = resolver.next(name);
if (target == null) { Object nextTarget = getPropertyUtils().getProperty(target, nextName);
throw new InvocationTargetException(null, "Resolved nested property for:" + name + ", on: " + bean + " was null"); if (nextTarget == null) {
nextTarget = initProperty(target, nextName);
} }
target = nextTarget;
name = resolver.remove(name); name = resolver.remove(name);
} catch (final NoSuchMethodException e) { } catch (final NoSuchMethodException e) {
throw new InvocationTargetException(e, "No getter for property:" + name + ", on: " + bean); throw new InvocationTargetException(e, "No getter for property:" + name + ", on: " + bean);

View File

@ -53,6 +53,7 @@ import org.apache.activemq.artemis.core.config.federation.FederationAddressPolic
import org.apache.activemq.artemis.core.config.federation.FederationPolicySet; import org.apache.activemq.artemis.core.config.federation.FederationPolicySet;
import org.apache.activemq.artemis.core.config.federation.FederationQueuePolicyConfiguration; import org.apache.activemq.artemis.core.config.federation.FederationQueuePolicyConfiguration;
import org.apache.activemq.artemis.core.config.ha.PrimaryOnlyPolicyConfiguration; import org.apache.activemq.artemis.core.config.ha.PrimaryOnlyPolicyConfiguration;
import org.apache.activemq.artemis.core.config.routing.ConnectionRouterConfiguration;
import org.apache.activemq.artemis.core.config.storage.DatabaseStorageConfiguration; import org.apache.activemq.artemis.core.config.storage.DatabaseStorageConfiguration;
import org.apache.activemq.artemis.core.deployers.impl.FileConfigurationParser; import org.apache.activemq.artemis.core.deployers.impl.FileConfigurationParser;
import org.apache.activemq.artemis.core.io.SequentialFileFactory; import org.apache.activemq.artemis.core.io.SequentialFileFactory;
@ -68,6 +69,7 @@ import org.apache.activemq.artemis.core.server.cluster.impl.MessageLoadBalancing
import org.apache.activemq.artemis.core.server.plugin.impl.LoggingActiveMQServerPlugin; import org.apache.activemq.artemis.core.server.plugin.impl.LoggingActiveMQServerPlugin;
import org.apache.activemq.artemis.core.server.routing.KeyType; import org.apache.activemq.artemis.core.server.routing.KeyType;
import org.apache.activemq.artemis.core.server.routing.policies.ConsistentHashModuloPolicy; import org.apache.activemq.artemis.core.server.routing.policies.ConsistentHashModuloPolicy;
import org.apache.activemq.artemis.core.server.routing.policies.ConsistentHashPolicy;
import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy; import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy;
import org.apache.activemq.artemis.core.settings.impl.DeletionPolicy; import org.apache.activemq.artemis.core.settings.impl.DeletionPolicy;
import org.apache.activemq.artemis.core.settings.impl.ResourceLimitSettings; import org.apache.activemq.artemis.core.settings.impl.ResourceLimitSettings;
@ -719,11 +721,42 @@ public class ConfigurationImplTest extends ActiveMQTestBase {
insertionOrderedProperties.put("connectionRouters.autoShard.policyConfiguration", ConsistentHashModuloPolicy.NAME); insertionOrderedProperties.put("connectionRouters.autoShard.policyConfiguration", ConsistentHashModuloPolicy.NAME);
insertionOrderedProperties.put("connectionRouters.autoShard.policyConfiguration.properties." + ConsistentHashModuloPolicy.MODULO, 2); insertionOrderedProperties.put("connectionRouters.autoShard.policyConfiguration.properties." + ConsistentHashModuloPolicy.MODULO, 2);
insertionOrderedProperties.put("connectionRouters.symmetricRedirect.keyType", KeyType.CLIENT_ID);
insertionOrderedProperties.put("connectionRouters.symmetricRedirect.keyFilter", "^.{3}");
insertionOrderedProperties.put("connectionRouters.symmetricRedirect.policyConfiguration", ConsistentHashPolicy.NAME);
insertionOrderedProperties.put("connectionRouters.symmetricRedirect.poolConfiguration.username", "guest-username");
insertionOrderedProperties.put("connectionRouters.symmetricRedirect.poolConfiguration.password", "guest-password");
insertionOrderedProperties.put("connectionRouters.symmetricRedirect.poolConfiguration.quorumSize", "2");
insertionOrderedProperties.put("connectionRouters.symmetricRedirect.poolConfiguration.localTargetEnabled", Boolean.TRUE.toString());
insertionOrderedProperties.put("connectionRouters.symmetricRedirect.poolConfiguration.discoveryGroupName", "discovery-group-1");
insertionOrderedProperties.put("connectionRouters.symmetricRedirect.cacheConfiguration.persisted", Boolean.TRUE.toString());
insertionOrderedProperties.put("connectionRouters.symmetricRedirect.cacheConfiguration.timeout", "1234");
configuration.parsePrefixedProperties(insertionOrderedProperties, null); configuration.parsePrefixedProperties(insertionOrderedProperties, null);
Assert.assertEquals(1, configuration.getConnectionRouters().size()); Assert.assertEquals(2, configuration.getConnectionRouters().size());
Assert.assertEquals(KeyType.CLIENT_ID, configuration.getConnectionRouters().get(0).getKeyType());
Assert.assertEquals("2", configuration.getConnectionRouters().get(0).getPolicyConfiguration().getProperties().get(ConsistentHashModuloPolicy.MODULO)); ConnectionRouterConfiguration autoShardConfig = configuration.getConnectionRouters().stream().filter(
connectionRouterConfig -> "autoShard".equals(connectionRouterConfig.getName())).findFirst().get();
Assert.assertEquals(KeyType.CLIENT_ID, autoShardConfig.getKeyType());
Assert.assertEquals("2", autoShardConfig.getPolicyConfiguration().getProperties().get(ConsistentHashModuloPolicy.MODULO));
Assert.assertNull(autoShardConfig.getCacheConfiguration());
Assert.assertNull(autoShardConfig.getPoolConfiguration());
ConnectionRouterConfiguration symmetricRedirectConfig = configuration.getConnectionRouters().stream().filter(
connectionRouterConfig -> "symmetricRedirect".equals(connectionRouterConfig.getName())).findFirst().get();
Assert.assertEquals(KeyType.CLIENT_ID, symmetricRedirectConfig.getKeyType());
Assert.assertEquals("^.{3}", symmetricRedirectConfig.getKeyFilter());
Assert.assertEquals(ConsistentHashPolicy.NAME, symmetricRedirectConfig.getPolicyConfiguration().getName());
Assert.assertNotNull(symmetricRedirectConfig.getPoolConfiguration());
Assert.assertEquals("guest-username", symmetricRedirectConfig.getPoolConfiguration().getUsername());
Assert.assertEquals("guest-password", symmetricRedirectConfig.getPoolConfiguration().getPassword());
Assert.assertEquals(2, symmetricRedirectConfig.getPoolConfiguration().getQuorumSize());
Assert.assertEquals(Boolean.TRUE, symmetricRedirectConfig.getPoolConfiguration().isLocalTargetEnabled());
Assert.assertEquals("discovery-group-1", symmetricRedirectConfig.getPoolConfiguration().getDiscoveryGroupName());
Assert.assertNotNull(symmetricRedirectConfig.getCacheConfiguration());
Assert.assertEquals(Boolean.TRUE, symmetricRedirectConfig.getCacheConfiguration().isPersisted());
Assert.assertEquals(1234, symmetricRedirectConfig.getCacheConfiguration().getTimeout());
} }
@Test @Test
@ -2205,6 +2238,48 @@ public class ConfigurationImplTest extends ActiveMQTestBase {
Assert.assertEquals(4321, configuration.getGlobalMaxSize()); Assert.assertEquals(4321, configuration.getGlobalMaxSize());
} }
@Test
public void testConfigWithMultipleNullDescendantChildren() throws Throwable {
String dummyPropertyPrefix = "dummy.";
DummyConfig dummyConfig = new DummyConfig();
Properties properties = new Properties();
properties.put(dummyPropertyPrefix + "childConfig.childConfig.childConfig.intProperty", "1");
Configuration configuration = new ConfigurationImpl();
configuration.parsePrefixedProperties(dummyConfig, "dummy", properties, dummyPropertyPrefix);
Assert.assertNotNull(dummyConfig.getChildConfig());
Assert.assertNotNull(dummyConfig.getChildConfig().getChildConfig());
Assert.assertNotNull(dummyConfig.getChildConfig().getChildConfig().getChildConfig());
Assert.assertNull(dummyConfig.getChildConfig().getChildConfig().getChildConfig().getChildConfig());
Assert.assertEquals(1, dummyConfig.getChildConfig().getChildConfig().getChildConfig().getIntProperty());
}
public static class DummyConfig {
private int intProperty;
private DummyConfig childConfig;
public int getIntProperty() {
return intProperty;
}
public DummyConfig setIntProperty(int intProperty) {
this.intProperty = intProperty;
return this;
}
public DummyConfig getChildConfig() {
return childConfig;
}
public DummyConfig setChildConfig(DummyConfig childConfig) {
this.childConfig = childConfig;
return this;
}
}
@Override @Override
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {