https://issues.apache.org/jira/browse/AMQ-4821 - refix; we now use any referenced factorybean for default properties
Project: http://git-wip-us.apache.org/repos/asf/activemq/repo Commit: http://git-wip-us.apache.org/repos/asf/activemq/commit/499ab684 Tree: http://git-wip-us.apache.org/repos/asf/activemq/tree/499ab684 Diff: http://git-wip-us.apache.org/repos/asf/activemq/diff/499ab684 Branch: refs/heads/activemq-5.9 Commit: 499ab6849a341378a9349739a87378fe36e042a2 Parents: 81ebd58 Author: gtully <[email protected]> Authored: Thu Oct 24 22:08:36 2013 +0100 Committer: Hadrian Zbarcea <[email protected]> Committed: Tue Mar 11 21:03:01 2014 -0400 ---------------------------------------------------------------------- activemq-runtime-config/pom.xml | 1 + .../plugin/RuntimeConfigurationBroker.java | 62 ++++++++++++++------ .../apache/activemq/CustomPropertiesBean.java | 7 ++- .../org/apache/activemq/SpringBeanTest.java | 57 +++++++++++++++--- ...pring-property-file-list-and-beanFactory.xml | 41 +++++++++++++ ...roperty-file-list-and-beanFactory-new-nc.xml | 45 ++++++++++++++ 6 files changed, 186 insertions(+), 27 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/activemq/blob/499ab684/activemq-runtime-config/pom.xml ---------------------------------------------------------------------- diff --git a/activemq-runtime-config/pom.xml b/activemq-runtime-config/pom.xml index c198f77..6e3ea16 100755 --- a/activemq-runtime-config/pom.xml +++ b/activemq-runtime-config/pom.xml @@ -157,6 +157,7 @@ <artifactId>maven-surefire-plugin</artifactId> <configuration> <forkMode>always</forkMode> + <argLine>-Xmx512M -Djava.awt.headless=true</argLine> <systemProperties> <property> <name>org.apache.activemq.default.directory.prefix</name> http://git-wip-us.apache.org/repos/asf/activemq/blob/499ab684/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java ---------------------------------------------------------------------- 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 58a11e1..b541542 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 // <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> - // <property name="locations"> + // <property name="locations" || name="properties"> // ... // </property> // </bean> - String resourcesString = ""; - NodeList beans = doc.getElementsByTagName("bean"); + LinkedList<String> resources = new LinkedList<String>(); + LinkedList<String> propertiesClazzes = new LinkedList<String>(); + 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")) { - - // 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 += ","; + 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.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<Resource> propResources = new LinkedList<Resource>(); - for (String value : resourcesString.split(",")) { + for (String value : resources) { try { if (!value.isEmpty()) { propResources.add(Utils.resourceFromString(replacePlaceHolders(value))); http://git-wip-us.apache.org/repos/asf/activemq/blob/499ab684/activemq-runtime-config/src/test/java/org/apache/activemq/CustomPropertiesBean.java ---------------------------------------------------------------------- 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 97aebf4..09e8fce 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 properties = new Properties(); + public CustomPropertiesBean() { + properties.put("custom", "isKing"); + } + @Override public Properties getObject() throws Exception { - return System.getProperties(); + return properties; } @Override http://git-wip-us.apache.org/repos/asf/activemq/blob/499ab684/activemq-runtime-config/src/test/java/org/apache/activemq/SpringBeanTest.java ---------------------------------------------------------------------- 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 6d13746..c529eaa 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,19 +127,58 @@ 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<String, String> props = new HashMap<String, String>(); + 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()); - String propOfInterest = "modified"; - HashMap<String, String> props = new HashMap<String, String>(); - IntrospectionSupport.getProperties(runtimeConfigurationView, props, null); - LOG.info("mbean attributes before: " + props); + ObjectName objectName = + new ObjectName(brokerService.getBrokerObjectName().toString() + + RuntimeConfigurationBroker.objectNamePropsAppendage); + RuntimeConfigurationViewMBean runtimeConfigurationView = + (RuntimeConfigurationViewMBean) brokerService.getManagementContext().newProxyInstance(objectName, + RuntimeConfigurationViewMBean.class, false); + + String propOfInterest = "modified"; + HashMap<String, String> props = new HashMap<String, String>(); + 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()); } http://git-wip-us.apache.org/repos/asf/activemq/blob/499ab684/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property-file-list-and-beanFactory.xml ---------------------------------------------------------------------- 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 0000000..621c5d7 --- /dev/null +++ b/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property-file-list-and-beanFactory.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<beans + xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd + http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd"> + + <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> + <property name="locations"> + <list> + <value>${props.base}users.properties</value> + <value>${props.base}users.properties</value> + </list> + </property> + <property name="properties"> + <bean class="org.apache.activemq.CustomPropertiesBean"/> + </property> + </bean> + + <broker xmlns="http://activemq.apache.org/schema/core" start="false" persistent="false" brokerName="${custom}"> + <plugins> + <runtimeConfigurationPlugin checkPeriod="1000" /> + </plugins> + </broker> +</beans> http://git-wip-us.apache.org/repos/asf/activemq/blob/499ab684/activemq-runtime-config/src/test/resources/org/apache/activemq/spring-property-file-list-and-beanFactory-new-nc.xml ---------------------------------------------------------------------- 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 0000000..941c2f8 --- /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 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<beans + xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd + http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd"> + + <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> + <property name="locations"> + <list> + <value>${props.base}users.properties</value> + <value>${props.base}users.properties</value> + </list> + </property> + <property name="properties"> + <bean class="org.apache.activemq.CustomPropertiesBean"/> + </property> + </bean> + + <broker xmlns="http://activemq.apache.org/schema/core" start="false" persistent="false" brokerName="${custom}"> + <plugins> + <runtimeConfigurationPlugin checkPeriod="1000" /> + </plugins> + <networkConnectors> + <networkConnector uri="${network.uri}" networkTTL="1" name="${custom}" /> + </networkConnectors> + </broker> + +</beans>
