mirror of https://github.com/apache/activemq.git
https://issues.apache.org/jira/browse/AMQ-4821 - refix; we now use any referenced factorybean for default properties
This commit is contained in:
parent
c2eb4863a8
commit
da45d994ac
|
@ -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>
|
||||
|
|
|
@ -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")) {
|
||||
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<Resource> propResources = new LinkedList<Resource>();
|
||||
for (String value : resourcesString.split(",")) {
|
||||
for (String value : resources) {
|
||||
try {
|
||||
if (!value.isEmpty()) {
|
||||
propResources.add(Utils.resourceFromString(replacePlaceHolders(value)));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<String, String> props = new HashMap<String, String>();
|
||||
IntrospectionSupport.getProperties(runtimeConfigurationView, props, null);
|
||||
LOG.info("mbean attributes before: " + props);
|
||||
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());
|
||||
|
||||
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());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
Loading…
Reference in New Issue