From da45d994ac31cb8ef78ff429fd7e26e5f6834749 Mon Sep 17 00:00:00 2001 From: gtully Date: Thu, 24 Oct 2013 22:08:36 +0100 Subject: [PATCH] https://issues.apache.org/jira/browse/AMQ-4821 - refix; we now use any referenced factorybean for default properties --- activemq-runtime-config/pom.xml | 1 + .../plugin/RuntimeConfigurationBroker.java | 60 ++++++++++++++----- .../apache/activemq/CustomPropertiesBean.java | 7 ++- .../org/apache/activemq/SpringBeanTest.java | 57 +++++++++++++++--- ...ing-property-file-list-and-beanFactory.xml | 41 +++++++++++++ ...perty-file-list-and-beanFactory-new-nc.xml | 45 ++++++++++++++ 6 files changed, 185 insertions(+), 26 deletions(-) create mode 100644 activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property-file-list-and-beanFactory.xml create mode 100644 activemq-runtime-config/src/test/resources/org/apache/activemq/spring-property-file-list-and-beanFactory-new-nc.xml diff --git a/activemq-runtime-config/pom.xml b/activemq-runtime-config/pom.xml index 0b4f57931f..eead4ada87 100755 --- a/activemq-runtime-config/pom.xml +++ b/activemq-runtime-config/pom.xml @@ -157,6 +157,7 @@ maven-surefire-plugin always + -Xmx512M -Djava.awt.headless=true org.apache.activemq.default.directory.prefix diff --git a/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java b/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java index 58a11e19bd..b5415421cb 100644 --- a/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java +++ b/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java @@ -17,6 +17,7 @@ package org.apache.activemq.plugin; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.util.ArrayList; @@ -94,6 +95,8 @@ import org.apache.activemq.spring.Utils; import org.apache.activemq.util.IntrospectionSupport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; import org.springframework.beans.factory.xml.PluggableSchemaResolver; import org.springframework.core.io.Resource; @@ -694,19 +697,20 @@ public class RuntimeConfigurationBroker extends BrokerFilter { if (brokerContext != null) { Properties initialProperties = new Properties(System.getProperties()); placeHolderUtil = new PropertiesPlaceHolderUtil(initialProperties); - mergeProperties(doc, initialProperties); + mergeProperties(doc, initialProperties, brokerContext); } } - private void mergeProperties(Document doc, Properties initialProperties) { + private void mergeProperties(Document doc, Properties initialProperties, BrokerContext brokerContext) { // find resources // - // + // // ... // // - String resourcesString = ""; - NodeList beans = doc.getElementsByTagName("bean"); + LinkedList resources = new LinkedList(); + LinkedList propertiesClazzes = new LinkedList(); + NodeList beans = doc.getElementsByTagNameNS("*", "bean"); for (int i = 0; i < beans.getLength(); i++) { Node bean = beans.item(0); if (bean.hasAttributes() && bean.getAttributes().getNamedItem("class").getTextContent().contains("PropertyPlaceholderConfigurer")) { @@ -714,26 +718,50 @@ public class RuntimeConfigurationBroker extends BrokerFilter { NodeList beanProps = bean.getChildNodes(); for (int j = 0; j < beanProps.getLength(); j++) { Node beanProp = beanProps.item(j); - if (Node.ELEMENT_NODE == beanProp.getNodeType() && - beanProp.hasAttributes() && beanProp.getAttributes().getNamedItem("name").getTextContent().equals("locations")) { + if (Node.ELEMENT_NODE == beanProp.getNodeType() && beanProp.hasAttributes() && beanProp.getAttributes().getNamedItem("name") != null) { + String propertyName = beanProp.getAttributes().getNamedItem("name").getTextContent(); + if ("locations".equals(propertyName)) { - // interested in value or list/value of locations property - Element beanPropElement = (Element) beanProp; - NodeList values = beanPropElement.getElementsByTagName("value"); - for (int k = 0; k < values.getLength(); k++) { - Node value = values.item(k); - if (!resourcesString.isEmpty()) { - resourcesString += ","; + // interested in value or list/value of locations property + Element beanPropElement = (Element) beanProp; + NodeList values = beanPropElement.getElementsByTagNameNS("*", "value"); + for (int k = 0; k < values.getLength(); k++) { + Node value = values.item(k); + resources.add(value.getFirstChild().getTextContent()); + } + } else if ("properties".equals(propertyName)) { + + // bean or beanFactory + Element beanPropElement = (Element) beanProp; + NodeList values = beanPropElement.getElementsByTagNameNS("*", "bean"); + for (int k = 0; k < values.getLength(); k++) { + Node value = values.item(k); + if (value.hasAttributes()) { + Node beanClassTypeNode = value.getAttributes().getNamedItem("class"); + if (beanClassTypeNode != null) { + propertiesClazzes.add(beanClassTypeNode.getFirstChild().getTextContent()); + } + } } - resourcesString += value.getFirstChild().getTextContent(); } } } } } } + for (String value : propertiesClazzes) { + try { + Object springBean = getClass().getClassLoader().loadClass(value).newInstance(); + if (springBean instanceof FactoryBean) { + // can't access the factory or created properties from spring context so we got to recreate + initialProperties.putAll((Properties) FactoryBean.class.getMethod("getObject", null).invoke(springBean)); + } + } catch (Throwable e) { + LOG.debug("unexpected exception processing properties bean class: " + propertiesClazzes, e); + } + } List propResources = new LinkedList(); - for (String value : resourcesString.split(",")) { + for (String value : resources) { try { if (!value.isEmpty()) { propResources.add(Utils.resourceFromString(replacePlaceHolders(value))); diff --git a/activemq-runtime-config/src/test/java/org/apache/activemq/CustomPropertiesBean.java b/activemq-runtime-config/src/test/java/org/apache/activemq/CustomPropertiesBean.java index 97aebf45eb..09e8fce169 100644 --- a/activemq-runtime-config/src/test/java/org/apache/activemq/CustomPropertiesBean.java +++ b/activemq-runtime-config/src/test/java/org/apache/activemq/CustomPropertiesBean.java @@ -20,9 +20,14 @@ import java.util.Properties; import org.springframework.beans.factory.FactoryBean; public class CustomPropertiesBean implements FactoryBean { + Properties properties = new Properties(); + public CustomPropertiesBean() { + properties.put("custom", "isKing"); + } + @Override public Properties getObject() throws Exception { - return System.getProperties(); + return properties; } @Override diff --git a/activemq-runtime-config/src/test/java/org/apache/activemq/SpringBeanTest.java b/activemq-runtime-config/src/test/java/org/apache/activemq/SpringBeanTest.java index 6d137466e9..c529eaa2e7 100644 --- a/activemq-runtime-config/src/test/java/org/apache/activemq/SpringBeanTest.java +++ b/activemq-runtime-config/src/test/java/org/apache/activemq/SpringBeanTest.java @@ -127,20 +127,59 @@ public class SpringBeanTest extends RuntimeConfigTestSupport { assertTrue("broker alive", brokerService.isStarted()); ObjectName objectName = - new ObjectName(brokerService.getBrokerObjectName().toString() + - RuntimeConfigurationBroker.objectNamePropsAppendage); - RuntimeConfigurationViewMBean runtimeConfigurationView = - (RuntimeConfigurationViewMBean) brokerService.getManagementContext().newProxyInstance(objectName, - RuntimeConfigurationViewMBean.class, false); + new ObjectName(brokerService.getBrokerObjectName().toString() + + RuntimeConfigurationBroker.objectNamePropsAppendage); + RuntimeConfigurationViewMBean runtimeConfigurationView = + (RuntimeConfigurationViewMBean) brokerService.getManagementContext().newProxyInstance(objectName, + RuntimeConfigurationViewMBean.class, false); - String propOfInterest = "modified"; - HashMap props = new HashMap(); - IntrospectionSupport.getProperties(runtimeConfigurationView, props, null); - LOG.info("mbean attributes before: " + props); + String propOfInterest = "modified"; + HashMap props = new HashMap(); + IntrospectionSupport.getProperties(runtimeConfigurationView, props, null); + LOG.info("mbean attributes before: " + props); assertNotEquals("unknown", props.get(propOfInterest)); } + @Test + public void testAddPropertyRefFromFileAndBeanFactory() throws Exception { + + System.setProperty("network.uri", "static:(tcp://localhost:8888)"); + System.setProperty("props.base", "classpath:"); + final String brokerConfig = "SpringPropertyTestFileListBeanFactory-broker"; + applyNewConfig(brokerConfig, "emptyUpdatableConfig1000-spring-property-file-list-and-beanFactory"); + startBroker(brokerConfig); + assertTrue("broker alive", brokerService.isStarted()); + + ObjectName objectName = + new ObjectName(brokerService.getBrokerObjectName().toString() + + RuntimeConfigurationBroker.objectNamePropsAppendage); + RuntimeConfigurationViewMBean runtimeConfigurationView = + (RuntimeConfigurationViewMBean) brokerService.getManagementContext().newProxyInstance(objectName, + RuntimeConfigurationViewMBean.class, false); + + String propOfInterest = "modified"; + HashMap props = new HashMap(); + IntrospectionSupport.getProperties(runtimeConfigurationView, props, null); + LOG.info("mbean attributes before: " + props); + + assertNotEquals("unknown", props.get(propOfInterest)); + + assertEquals("our custom prop is applied", "isKing", brokerService.getBrokerName()); + + applyNewConfig(brokerConfig, "spring-property-file-list-and-beanFactory-new-nc", SLEEP); + + assertTrue("new network connectors", Wait.waitFor(new Wait.Condition() { + @Override + public boolean isSatisified() throws Exception { + return 1 == brokerService.getNetworkConnectors().size(); + } + })); + + assertEquals("our custom prop is applied", "isKing", brokerService.getNetworkConnectors().get(0).getName()); + + } + } diff --git a/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property-file-list-and-beanFactory.xml b/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property-file-list-and-beanFactory.xml new file mode 100644 index 0000000000..621c5d723a --- /dev/null +++ b/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property-file-list-and-beanFactory.xml @@ -0,0 +1,41 @@ + + + + + + + + ${props.base}users.properties + ${props.base}users.properties + + + + + + + + + + + + + diff --git a/activemq-runtime-config/src/test/resources/org/apache/activemq/spring-property-file-list-and-beanFactory-new-nc.xml b/activemq-runtime-config/src/test/resources/org/apache/activemq/spring-property-file-list-and-beanFactory-new-nc.xml new file mode 100644 index 0000000000..941c2f8b2a --- /dev/null +++ b/activemq-runtime-config/src/test/resources/org/apache/activemq/spring-property-file-list-and-beanFactory-new-nc.xml @@ -0,0 +1,45 @@ + + + + + + + + ${props.base}users.properties + ${props.base}users.properties + + + + + + + + + + + + + + + + +