This is an automated email from the ASF dual-hosted git repository.

robbie 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 2b331427d8 ARTEMIS-4552 Config all connection-router settings by using 
broker properties
2b331427d8 is described below

commit 2b331427d8e2278064314a9412ae0adcef144ce0
Author: Domenico Francesco Bruscino <[email protected]>
AuthorDate: Thu Jan 18 13:41:16 2024 +0100

    ARTEMIS-4552 Config all connection-router settings by using broker 
properties
---
 .../core/config/impl/ConfigurationImpl.java        | 33 ++++++++-
 .../core/config/impl/ConfigurationImplTest.java    | 81 +++++++++++++++++++++-
 2 files changed, 108 insertions(+), 6 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 f2c9b6ae6b..993717c45f 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
@@ -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 {
       CollectionAutoFillPropertiesUtil autoFillCollections = new 
CollectionAutoFillPropertiesUtil(getBrokerPropertiesRemoveValue(beanProperties));
       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
          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();
                while (resolver.hasNested(name)) {
                   try {
-                     target = getPropertyUtils().getProperty(target, 
resolver.next(name));
-                     if (target == null) {
-                        throw new InvocationTargetException(null, "Resolved 
nested property for:" + name + ", on: " + bean + " was null");
+                     String nextName = resolver.next(name);
+                     Object nextTarget = 
getPropertyUtils().getProperty(target, nextName);
+                     if (nextTarget == null) {
+                        nextTarget = initProperty(target, nextName);
                      }
+                     target = nextTarget;
                      name = resolver.remove(name);
                   } catch (final NoSuchMethodException e) {
                      throw new InvocationTargetException(e, "No getter for 
property:" + name + ", on: " + bean);
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 a567984fae..e0b1ded173 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
@@ -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.FederationQueuePolicyConfiguration;
 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.deployers.impl.FileConfigurationParser;
 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.routing.KeyType;
 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.DeletionPolicy;
 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.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);
 
-      Assert.assertEquals(1, 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));
+      Assert.assertEquals(2, configuration.getConnectionRouters().size());
+
+      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
@@ -2205,6 +2238,48 @@ public class ConfigurationImplTest extends 
ActiveMQTestBase {
       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
    @Before
    public void setUp() throws Exception {

Reply via email to