Updated Branches: refs/heads/trunk 2ea02bc8f -> 052577219
https://issues.apache.org/jira/browse/AMQ-4682 - use spring.schemas for spring.xsd resolution - use brokerContext for configurationurl, support property PropertyPlaceholderConfigurer locations and system prop replacement, nested networkConnector elements - excludedDestinations,dynamicallyIncludedDestinations etc. lists and sets of destination Project: http://git-wip-us.apache.org/repos/asf/activemq/repo Commit: http://git-wip-us.apache.org/repos/asf/activemq/commit/634a8189 Tree: http://git-wip-us.apache.org/repos/asf/activemq/tree/634a8189 Diff: http://git-wip-us.apache.org/repos/asf/activemq/diff/634a8189 Branch: refs/heads/trunk Commit: 634a81898c4db442222ba58ec3ef779f2868dfd4 Parents: 2ea02bc Author: gtully <[email protected]> Authored: Tue Sep 3 00:28:46 2013 +0100 Committer: gtully <[email protected]> Committed: Tue Sep 3 00:28:46 2013 +0100 ---------------------------------------------------------------------- .../apache/activemq/broker/BrokerContext.java | 5 +- .../activemq/broker/BrokerContextAware.java | 3 +- .../apache/activemq/broker/BrokerService.java | 8 - .../plugin/RuntimeConfigurationBroker.java | 230 +++++++++++++++++-- .../src/main/resources/binding.xjb | 28 +++ .../java/org/apache/activemq/MBeanTest.java | 8 +- .../apache/activemq/NetworkConnectorTest.java | 10 + .../org/apache/activemq/SpringBeanTest.java | 59 ++++- ...atableConfig1000-spring-property-file-nc.xml | 39 ++++ ...UpdatableConfig1000-spring-property-file.xml | 35 +++ ...tyUpdatableConfig1000-spring-property-nc.xml | 35 +++ ...emptyUpdatableConfig1000-spring-property.xml | 31 +++ .../activemq/networkConnectorTest-one-nc.xml | 16 +- .../activemq/spring/SpringBrokerContext.java | 10 +- .../activemq/xbean/XBeanBrokerFactory.java | 11 +- .../transport/stomp/JmsFrameTranslator.java | 5 + .../stomp/util/XStreamBrokerContext.java | 5 + 17 files changed, 492 insertions(+), 46 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/activemq/blob/634a8189/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerContext.java ---------------------------------------------------------------------- diff --git a/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerContext.java b/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerContext.java index 3c92801..641632c 100644 --- a/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerContext.java +++ b/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerContext.java @@ -27,6 +27,7 @@ public interface BrokerContext { Object getBean(String name); - public Map getBeansOfType(Class type); - + Map getBeansOfType(Class type); + + String getConfigurationUrl(); } http://git-wip-us.apache.org/repos/asf/activemq/blob/634a8189/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerContextAware.java ---------------------------------------------------------------------- diff --git a/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerContextAware.java b/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerContextAware.java index 4923d68..19035cc 100644 --- a/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerContextAware.java +++ b/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerContextAware.java @@ -23,5 +23,6 @@ package org.apache.activemq.broker; */ public interface BrokerContextAware { - void setBrokerContext(BrokerContext brokerContext); + void setBrokerContext(BrokerContext brokerContext); + BrokerContext getBrokerContext(); } http://git-wip-us.apache.org/repos/asf/activemq/blob/634a8189/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java ---------------------------------------------------------------------- diff --git a/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java b/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java index 3f6f4bf..666c4bd 100644 --- a/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java +++ b/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java @@ -2948,12 +2948,4 @@ public class BrokerService implements Service { public void setStoreOpenWireVersion(int storeOpenWireVersion) { this.storeOpenWireVersion = storeOpenWireVersion; } - - public String getConfigurationUrl() { - return configurationUrl; - } - - public void setConfigurationUrl(String configurationUrl) { - this.configurationUrl = configurationUrl; - } } http://git-wip-us.apache.org/repos/asf/activemq/blob/634a8189/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 0b4e434..7693692 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,16 +17,23 @@ 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; import java.util.Arrays; import java.util.Date; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.TreeMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.management.JMException; import javax.management.ObjectName; import javax.xml.XMLConstants; @@ -42,6 +49,7 @@ import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import org.apache.activemq.broker.Broker; +import org.apache.activemq.broker.BrokerContext; import org.apache.activemq.broker.BrokerFilter; import org.apache.activemq.broker.ConnectionContext; import org.apache.activemq.broker.jmx.ManagementContext; @@ -59,7 +67,10 @@ import org.apache.activemq.broker.region.virtual.VirtualDestination; import org.apache.activemq.broker.region.virtual.VirtualDestinationInterceptor; import org.apache.activemq.broker.region.virtual.VirtualTopic; import org.apache.activemq.command.ActiveMQDestination; +import org.apache.activemq.command.ActiveMQQueue; +import org.apache.activemq.command.ActiveMQTopic; import org.apache.activemq.filter.DestinationMapEntry; +import org.apache.activemq.network.DiscoveryNetworkConnector; import org.apache.activemq.network.NetworkConnector; import org.apache.activemq.plugin.jmx.RuntimeConfigurationView; import org.apache.activemq.schema.core.DtoAuthorizationEntry; @@ -71,6 +82,8 @@ import org.apache.activemq.schema.core.DtoCompositeTopic; import org.apache.activemq.schema.core.DtoNetworkConnector; import org.apache.activemq.schema.core.DtoPolicyEntry; import org.apache.activemq.schema.core.DtoPolicyMap; +import org.apache.activemq.schema.core.DtoQueue; +import org.apache.activemq.schema.core.DtoTopic; import org.apache.activemq.schema.core.DtoVirtualDestinationInterceptor; import org.apache.activemq.schema.core.DtoVirtualTopic; import org.apache.activemq.security.AuthorizationBroker; @@ -82,9 +95,13 @@ 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.config.PropertyPlaceholderConfigurer; +import org.springframework.beans.factory.xml.PluggableSchemaResolver; import org.springframework.core.io.Resource; import org.w3c.dom.Document; import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; import org.xml.sax.SAXException; public class RuntimeConfigurationBroker extends BrokerFilter { @@ -92,6 +109,7 @@ public class RuntimeConfigurationBroker extends BrokerFilter { public static final Logger LOG = LoggerFactory.getLogger(RuntimeConfigurationBroker.class); public static final String objectNamePropsAppendage = ",service=RuntimeConfiguration,name=Plugin"; private final ReentrantReadWriteLock addDestinationBarrier = new ReentrantReadWriteLock(); + PropertiesPlaceHolderUtil placeHolderUtil = null; private long checkPeriod; private long lastModified = -1; private Resource configToMonitor; @@ -110,7 +128,12 @@ public class RuntimeConfigurationBroker extends BrokerFilter { public void start() throws Exception { super.start(); try { - configToMonitor = Utils.resourceFromString(next.getBrokerService().getConfigurationUrl()); + BrokerContext brokerContext = next.getBrokerService().getBrokerContext(); + if (brokerContext != null) { + configToMonitor = Utils.resourceFromString(brokerContext.getConfigurationUrl()); + } else { + LOG.error("Null BrokerContext; impossible to determine configuration url resource from broker, updates cannot be tracked"); + } } catch (Exception error) { LOG.error("failed to determine configuration url resource from broker, updates cannot be tracked", error); } @@ -461,13 +484,8 @@ public class RuntimeConfigurationBroker extends BrokerFilter { DtoNetworkConnector networkConnector = (DtoNetworkConnector) o; if (networkConnector.getUri() != null) { try { - NetworkConnector nc = - getBrokerService().addNetworkConnector(networkConnector.getUri()); - Properties properties = new Properties(); - IntrospectionSupport.getProperties(networkConnector, properties, null); - properties.remove("uri"); - LOG.trace("applying networkConnector props: " + properties); - IntrospectionSupport.setProperties(nc, properties); + DiscoveryNetworkConnector nc = fromDto(networkConnector, new DiscoveryNetworkConnector()); + getBrokerService().addNetworkConnector(nc); nc.start(); info("started new network connector: " + nc); } catch (Exception e) { @@ -545,11 +563,65 @@ public class RuntimeConfigurationBroker extends BrokerFilter { private <T> T fromDto(Object dto, T instance) { Properties properties = new Properties(); IntrospectionSupport.getProperties(dto, properties, null); + replacePlaceHolders(properties); LOG.trace("applying props: " + properties + ", to " + instance.getClass().getSimpleName()); IntrospectionSupport.setProperties(instance, properties); + + // deal with nested elements + for (Object nested : filter(dto, Object.class)) { + String elementName = nested.getClass().getSimpleName(); + if (elementName.endsWith("s")) { + Method setter = findSetter(instance, elementName); + if (setter != null) { + + List<Object> argument = new LinkedList<Object>(); + for (Object elementContent : filter(nested, Object.class)) { + argument.add(fromDto(elementContent, inferTargetObject(elementContent))); + } + try { + setter.invoke(instance, matchType(argument, setter.getParameterTypes()[0])); + } catch (Exception e) { + info("failed to invoke " + setter + " on " + instance, e); + } + } else { + info("failed to find setter for " + elementName + " on :" + instance); + } + } else { + info("unsupported mapping of element for non plural:" + elementName); + } + } return instance; } + private Object matchType(List<Object> parameterValues, Class<?> aClass) { + Object result = parameterValues; + if (Set.class.isAssignableFrom(aClass)) { + result = new HashSet(parameterValues); + } + return result; + } + + private Object inferTargetObject(Object elementContent) { + if (DtoTopic.class.isAssignableFrom(elementContent.getClass())) { + return new ActiveMQTopic(); + } else if (DtoQueue.class.isAssignableFrom(elementContent.getClass())) { + return new ActiveMQQueue(); + } else { + info("update not supported for dto: " + elementContent); + return new Object(); + } + } + + private Method findSetter(Object instance, String elementName) { + String setter = "set" + elementName; + for (Method m : instance.getClass().getMethods()) { + if (setter.equals(m.getName())) { + return m; + } + } + return null; + } + private <T> List<Object> filter(Object obj, Class<T> type) { return filter(getContents(obj), type); } @@ -559,7 +631,7 @@ public class RuntimeConfigurationBroker extends BrokerFilter { for (Object o : objectList) { if (o instanceof JAXBElement) { JAXBElement element = (JAXBElement) o; - if (element.getDeclaredType() == type) { + if (type.isAssignableFrom(element.getDeclaredType())) { result.add((T) element.getValue()); } } else if (type.isAssignableFrom(o.getClass())) { @@ -591,6 +663,8 @@ public class RuntimeConfigurationBroker extends BrokerFilter { // if we can parse we can track mods lastModified = configToMonitor.lastModified(); + loadPropertiesPlaceHolderSupport(doc); + } catch (IOException e) { info("Failed to access: " + configToMonitor, e); } catch (JAXBException e) { @@ -604,20 +678,97 @@ public class RuntimeConfigurationBroker extends BrokerFilter { return jaxbConfig; } - private Schema getSchema() throws SAXException { + private void loadPropertiesPlaceHolderSupport(Document doc) { + BrokerContext brokerContext = getBrokerService().getBrokerContext(); + if (brokerContext != null && !brokerContext.getBeansOfType(PropertyPlaceholderConfigurer.class).isEmpty()) { + + Properties initialProperties = new Properties(System.getProperties()); + placeHolderUtil = new PropertiesPlaceHolderUtil(initialProperties); + mergeProperties(doc, initialProperties); + } + } + + private void mergeProperties(Document doc, Properties initialProperties) { + // find resources + // <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> + // <property name="locations"> + // <value>${props.base}users.properties</value> + // </property> + // </bean> + String resourcesString = null; + NodeList beans = doc.getElementsByTagName("bean"); + for (int i = 0; i < beans.getLength(); i++) { + Node bean = beans.item(0); + if (bean.hasAttributes() && bean.getAttributes().getNamedItem("class").getTextContent().contains("PropertyPlaceholderConfigurer")) { + if (bean.hasChildNodes()) { + NodeList beanProps = bean.getChildNodes(); + for (int j = 0; j < beanProps.getLength(); j++) { + Node beanProp = beanProps.item(j); + if (beanProp.hasAttributes() && beanProp.getAttributes().getNamedItem("name").getTextContent().equals("locations")) { + NodeList locationsPropNodes = beanProp.getChildNodes(); + for (int k = 0; k < locationsPropNodes.getLength(); k++) { + Node location = locationsPropNodes.item(k); + if (Node.ELEMENT_NODE == location.getNodeType() && location.getLocalName().equals("value")) { + resourcesString = location.getFirstChild().getTextContent(); + break; + } + } + } + } + } + } + } + List<Resource> propResources = new LinkedList<Resource>(); + if (resourcesString != null) { + for (String value : resourcesString.split(",")) { + try { + propResources.add(Utils.resourceFromString(replacePlaceHolders(value))); + } catch (MalformedURLException e) { + info("failed to resolve resource: " + value, e); + } + } + } + for (Resource resource : propResources) { + Properties properties = new Properties(); + try { + properties.load(resource.getInputStream()); + } catch (IOException e) { + info("failed to load properties resource: " + resource, e); + } + initialProperties.putAll(properties); + } + } + + private void replacePlaceHolders(Properties properties) { + if (placeHolderUtil != null) { + placeHolderUtil.filter(properties); + } + } + + private String replacePlaceHolders(String s) { + if (placeHolderUtil != null) { + s = placeHolderUtil.filter(s); + } + return s; + } + + private Schema getSchema() throws SAXException, IOException { if (schema == null) { - // need to pull the spring schemas from the classpath and find reelvant - // constants for the system id etc something like ... - //PluggableSchemaResolver resolver = - // new PluggableSchemaResolver(getClass().getClassLoader()); - //InputSource springBeans = resolver.resolveEntity("http://www.springframework.org/schema/beans", - // "http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"); - //LOG.trace("Beans schema:" + springBeans); SchemaFactory schemaFactory = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI); - schema = schemaFactory.newSchema( - new Source[]{new StreamSource(getClass().getResource("/activemq.xsd").toExternalForm()), - new StreamSource("http://www.springframework.org/schema/beans/spring-beans-2.0.xsd")}); + + // avoid going to the net to pull down the spring schema + final PluggableSchemaResolver springResolver = + new PluggableSchemaResolver(getClass().getClassLoader()); + final InputSource beanInputSource = + springResolver.resolveEntity( + "http://www.springframework.org/schema/beans", + "http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"); + + schema = schemaFactory.newSchema(new Source[]{ + new StreamSource(getClass().getResource("/activemq.xsd").toExternalForm()), + new StreamSource(beanInputSource.getByteStream()) + }); } return schema; } @@ -637,4 +788,43 @@ public class RuntimeConfigurationBroker extends BrokerFilter { public void setCheckPeriod(long checkPeriod) { this.checkPeriod = checkPeriod; } + + static public class PropertiesPlaceHolderUtil { + + static final Pattern pattern = Pattern.compile("\\$\\{([^\\}]+)\\}"); + final Properties properties; + + public PropertiesPlaceHolderUtil(Properties properties) { + this.properties = properties; + } + + public void filter(Properties toFilter) { + for (Map.Entry<Object, Object> entry : toFilter.entrySet()) { + String val = (String) entry.getValue(); + String newVal = filter(val); + if (!val.equals(newVal)) { + toFilter.put(entry.getKey(), newVal); + } + } + } + + public String filter(String str) { + int start = 0; + while (true) { + Matcher matcher = pattern.matcher(str); + if (!matcher.find(start)) { + break; + } + String group = matcher.group(1); + String property = properties.getProperty(group); + if (property != null) { + str = matcher.replaceFirst(Matcher.quoteReplacement(property)); + } else { + start = matcher.end(); + } + } + return str; + } + + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq/blob/634a8189/activemq-runtime-config/src/main/resources/binding.xjb ---------------------------------------------------------------------- diff --git a/activemq-runtime-config/src/main/resources/binding.xjb b/activemq-runtime-config/src/main/resources/binding.xjb index e8ba555..2a7890f 100644 --- a/activemq-runtime-config/src/main/resources/binding.xjb +++ b/activemq-runtime-config/src/main/resources/binding.xjb @@ -19,6 +19,34 @@ <jxb:property name="Contents" /> </jxb:bindings> + <jxb:bindings node="xs:element[@name='queue']/xs:complexType/xs:choice"> + <jxb:property name="Contents" /> + </jxb:bindings> + + <jxb:bindings node="xs:element[@name='topic']/xs:complexType/xs:choice"> + <jxb:property name="Contents" /> + </jxb:bindings> + + <jxb:bindings node="xs:element[@name='networkConnector']/xs:complexType/xs:choice"> + <jxb:property name="Contents" /> + </jxb:bindings> + + <jxb:bindings node="xs:element[@name='networkConnector']/xs:complexType/xs:choice/xs:choice/xs:element[@name='excludedDestinations']/xs:complexType/xs:sequence"> + <jxb:property name="Contents" /> + </jxb:bindings> + + <jxb:bindings node="xs:element[@name='networkConnector']/xs:complexType/xs:choice/xs:choice/xs:element[@name='dynamicallyIncludedDestinations']/xs:complexType/xs:sequence"> + <jxb:property name="Contents" /> + </jxb:bindings> + + <jxb:bindings node="xs:element[@name='networkConnector']/xs:complexType/xs:choice/xs:choice/xs:element[@name='durableDestinations']/xs:complexType/xs:sequence"> + <jxb:property name="Contents" /> + </jxb:bindings> + + <jxb:bindings node="xs:element[@name='networkConnector']/xs:complexType/xs:choice/xs:choice/xs:element[@name='staticallyIncludedDestinations']/xs:complexType/xs:sequence"> + <jxb:property name="Contents" /> + </jxb:bindings> + <jxb:bindings node="xs:element[@name='broker']/xs:complexType/xs:choice/xs:choice/xs:element[@name='destinationInterceptors']/xs:complexType/xs:choice"> <jxb:property name="Contents" /> </jxb:bindings> http://git-wip-us.apache.org/repos/asf/activemq/blob/634a8189/activemq-runtime-config/src/test/java/org/apache/activemq/MBeanTest.java ---------------------------------------------------------------------- diff --git a/activemq-runtime-config/src/test/java/org/apache/activemq/MBeanTest.java b/activemq-runtime-config/src/test/java/org/apache/activemq/MBeanTest.java index 399fecf..cce07cb 100644 --- a/activemq-runtime-config/src/test/java/org/apache/activemq/MBeanTest.java +++ b/activemq-runtime-config/src/test/java/org/apache/activemq/MBeanTest.java @@ -59,7 +59,7 @@ public class MBeanTest extends RuntimeConfigTestSupport { LOG.info("Result from update: " + result); - assertTrue("got sensible result", result.contains("started")); + assertTrue("got sensible result: " + result, result.contains("started")); assertEquals("one new network connectors", 1, brokerService.getNetworkConnectors().size()); @@ -72,7 +72,7 @@ public class MBeanTest extends RuntimeConfigTestSupport { } @Test - public void testUpdateFailedMod() throws Exception { + public void testUpdateFailedModParseError() throws Exception { final String brokerConfig = "mBeanTest-manual-broker"; applyNewConfig(brokerConfig, "emptyManualUpdateConfig"); startBroker(brokerConfig); @@ -96,7 +96,7 @@ public class MBeanTest extends RuntimeConfigTestSupport { String result = runtimeConfigurationView.updateNow(); LOG.info("Result from failed update: " + result); - assertTrue("got sensible result", result.contains("dudElement")); + assertTrue("got sensible result: " + result, result.contains("dudElement")); HashMap<String, String> propsAfter = new HashMap<String, String>(); IntrospectionSupport.getProperties(runtimeConfigurationView, propsAfter, null); @@ -111,7 +111,7 @@ public class MBeanTest extends RuntimeConfigTestSupport { result = runtimeConfigurationView.updateNow(); LOG.info("Result from update: " + result); - assertTrue("got sensible result", result.contains("started")); + assertTrue("got sensible result: " + result, result.contains("started")); assertEquals("one new network connectors", 1, brokerService.getNetworkConnectors().size()); propsAfter = new HashMap<String, String>(); http://git-wip-us.apache.org/repos/asf/activemq/blob/634a8189/activemq-runtime-config/src/test/java/org/apache/activemq/NetworkConnectorTest.java ---------------------------------------------------------------------- diff --git a/activemq-runtime-config/src/test/java/org/apache/activemq/NetworkConnectorTest.java b/activemq-runtime-config/src/test/java/org/apache/activemq/NetworkConnectorTest.java index 0e4f19a..3151cc4 100644 --- a/activemq-runtime-config/src/test/java/org/apache/activemq/NetworkConnectorTest.java +++ b/activemq-runtime-config/src/test/java/org/apache/activemq/NetworkConnectorTest.java @@ -16,6 +16,8 @@ */ package org.apache.activemq; +import java.util.List; +import org.apache.activemq.command.ActiveMQDestination; import org.apache.activemq.network.NetworkConnector; import org.apache.activemq.util.Wait; import org.junit.Before; @@ -51,6 +53,14 @@ public class NetworkConnectorTest extends RuntimeConfigTestSupport { applyNewConfig(brokerConfig, configurationSeed + "-one-nc"); assertEquals("no new network connectors", 1, brokerService.getNetworkConnectors().size()); assertSame("same instance", networkConnector, brokerService.getNetworkConnectors().get(0)); + + // verify nested elements + assertEquals("has exclusions", 2, networkConnector.getExcludedDestinations().size()); + + assertEquals("one statically included", 1, networkConnector.getStaticallyIncludedDestinations().size()); + assertEquals("one dynamically included", 1, networkConnector.getDynamicallyIncludedDestinations().size()); + assertEquals("one durable", 1, networkConnector.getDurableDestinations().size()); + } http://git-wip-us.apache.org/repos/asf/activemq/blob/634a8189/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 1ed107f..9455774 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 @@ -16,13 +16,14 @@ */ package org.apache.activemq; -import java.text.DateFormat; -import java.util.Date; import java.util.HashMap; import javax.management.ObjectName; +import org.apache.activemq.network.DiscoveryNetworkConnector; import org.apache.activemq.plugin.RuntimeConfigurationBroker; import org.apache.activemq.plugin.jmx.RuntimeConfigurationViewMBean; import org.apache.activemq.util.IntrospectionSupport; +import org.apache.activemq.util.Wait; +import org.junit.Ignore; import org.junit.Test; @@ -31,8 +32,8 @@ import static org.junit.Assert.*; public class SpringBeanTest extends RuntimeConfigTestSupport { @Test - public void testUpdateNow() throws Exception { - final String brokerConfig = "SpromgBeanTest-broker"; + public void testModifiable() throws Exception { + final String brokerConfig = "SpringBeanTest-broker"; applyNewConfig(brokerConfig, "emptyUpdatableConfig1000-spring-bean"); startBroker(brokerConfig); assertTrue("broker alive", brokerService.isStarted()); @@ -65,4 +66,54 @@ public class SpringBeanTest extends RuntimeConfigTestSupport { assertEquals("modified is same", props.get(propOfInterest), propsAfter.get(propOfInterest)); } + + @Test + public void testAddPropertyRef() throws Exception { + + System.setProperty("network.uri", "static:(tcp://localhost:8888)"); + final String brokerConfig = "SpringPropertyTest-broker"; + applyNewConfig(brokerConfig, "emptyUpdatableConfig1000-spring-property"); + startBroker(brokerConfig); + assertTrue("broker alive", brokerService.isStarted()); + + applyNewConfig(brokerConfig, "emptyUpdatableConfig1000-spring-property-nc", SLEEP); + + assertTrue("new network connectors", Wait.waitFor(new Wait.Condition() { + @Override + public boolean isSatisified() throws Exception { + return 1 == brokerService.getNetworkConnectors().size(); + } + })); + + DiscoveryNetworkConnector discoveryNetworkConnector = + (DiscoveryNetworkConnector) brokerService.getNetworkConnectors().get(0); + assertEquals("property replaced", System.getProperty("network.uri"), discoveryNetworkConnector.getUri().toASCIIString()); + } + + @Test + public void testAddPropertyRefFromFile() throws Exception { + + System.setProperty("network.uri", "static:(tcp://localhost:8888)"); + System.setProperty("props.base", "classpath:"); + final String brokerConfig = "SpringPropertyTest-broker"; + applyNewConfig(brokerConfig, "emptyUpdatableConfig1000-spring-property-file"); + startBroker(brokerConfig); + assertTrue("broker alive", brokerService.isStarted()); + + applyNewConfig(brokerConfig, "emptyUpdatableConfig1000-spring-property-file-nc", SLEEP); + + assertTrue("new network connectors", Wait.waitFor(new Wait.Condition() { + @Override + public boolean isSatisified() throws Exception { + return 1 == brokerService.getNetworkConnectors().size(); + } + })); + + DiscoveryNetworkConnector discoveryNetworkConnector = + (DiscoveryNetworkConnector) brokerService.getNetworkConnectors().get(0); + assertEquals("property replaced", System.getProperty("network.uri"), discoveryNetworkConnector.getUri().toASCIIString()); + + assertEquals("name is replaced", "guest", discoveryNetworkConnector.getName()); + } + } http://git-wip-us.apache.org/repos/asf/activemq/blob/634a8189/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property-file-nc.xml ---------------------------------------------------------------------- diff --git a/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property-file-nc.xml b/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property-file-nc.xml new file mode 100644 index 0000000..900270b --- /dev/null +++ b/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property-file-nc.xml @@ -0,0 +1,39 @@ +<?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"> + <value>${props.base}users.properties</value> + </property> + </bean> + + <broker xmlns="http://activemq.apache.org/schema/core" start="false" persistent="false" > + <plugins> + <runtimeConfigurationPlugin checkPeriod="1000" /> + </plugins> + + <networkConnectors> + <networkConnector uri="${network.uri}" networkTTL="1" name="${guest}" /> + </networkConnectors> + </broker> +</beans> http://git-wip-us.apache.org/repos/asf/activemq/blob/634a8189/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property-file.xml ---------------------------------------------------------------------- diff --git a/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property-file.xml b/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property-file.xml new file mode 100644 index 0000000..45f2711 --- /dev/null +++ b/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property-file.xml @@ -0,0 +1,35 @@ +<?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"> + <value>${props.base}users.properties</value> + </property> + </bean> + + <broker xmlns="http://activemq.apache.org/schema/core" start="false" persistent="false" > + <plugins> + <runtimeConfigurationPlugin checkPeriod="1000" /> + </plugins> + </broker> +</beans> http://git-wip-us.apache.org/repos/asf/activemq/blob/634a8189/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property-nc.xml ---------------------------------------------------------------------- diff --git a/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property-nc.xml b/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property-nc.xml new file mode 100644 index 0000000..bdc9278 --- /dev/null +++ b/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property-nc.xml @@ -0,0 +1,35 @@ +<?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" /> + + <broker xmlns="http://activemq.apache.org/schema/core" start="false" persistent="false" > + <plugins> + <runtimeConfigurationPlugin checkPeriod="1000" /> + </plugins> + + <networkConnectors> + <networkConnector uri="${network.uri}" networkTTL="1" name="one" /> + </networkConnectors> + </broker> +</beans> http://git-wip-us.apache.org/repos/asf/activemq/blob/634a8189/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property.xml ---------------------------------------------------------------------- diff --git a/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property.xml b/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property.xml new file mode 100644 index 0000000..ee54288 --- /dev/null +++ b/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyUpdatableConfig1000-spring-property.xml @@ -0,0 +1,31 @@ +<?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" /> + + <broker xmlns="http://activemq.apache.org/schema/core" start="false" persistent="false" > + <plugins> + <runtimeConfigurationPlugin checkPeriod="1000" /> + </plugins> + </broker> +</beans> http://git-wip-us.apache.org/repos/asf/activemq/blob/634a8189/activemq-runtime-config/src/test/resources/org/apache/activemq/networkConnectorTest-one-nc.xml ---------------------------------------------------------------------- diff --git a/activemq-runtime-config/src/test/resources/org/apache/activemq/networkConnectorTest-one-nc.xml b/activemq-runtime-config/src/test/resources/org/apache/activemq/networkConnectorTest-one-nc.xml index 395848d..581c27d 100644 --- a/activemq-runtime-config/src/test/resources/org/apache/activemq/networkConnectorTest-one-nc.xml +++ b/activemq-runtime-config/src/test/resources/org/apache/activemq/networkConnectorTest-one-nc.xml @@ -27,7 +27,21 @@ </plugins> <networkConnectors> - <networkConnector uri="static:(tcp://localhost:5555)" networkTTL="1" name="one" /> + <networkConnector uri="static:(tcp://localhost:5555)" networkTTL="1" name="one" > + <excludedDestinations> + <topic physicalName="LAN.>"/> + <queue physicalName="LAN.>"/> + </excludedDestinations> + <dynamicallyIncludedDestinations> + <queue physicalName="DynamicallyIncluded.*" /> + </dynamicallyIncludedDestinations> + <staticallyIncludedDestinations> + <topic physicalName="StaticallyIncluded.*" /> + </staticallyIncludedDestinations> + <durableDestinations> + <topic physicalName="durableDest" /> + </durableDestinations> + </networkConnector> </networkConnectors> </broker> </beans> http://git-wip-us.apache.org/repos/asf/activemq/blob/634a8189/activemq-spring/src/main/java/org/apache/activemq/spring/SpringBrokerContext.java ---------------------------------------------------------------------- diff --git a/activemq-spring/src/main/java/org/apache/activemq/spring/SpringBrokerContext.java b/activemq-spring/src/main/java/org/apache/activemq/spring/SpringBrokerContext.java index ca7c889..b7ee5a9 100644 --- a/activemq-spring/src/main/java/org/apache/activemq/spring/SpringBrokerContext.java +++ b/activemq-spring/src/main/java/org/apache/activemq/spring/SpringBrokerContext.java @@ -26,7 +26,8 @@ import org.springframework.context.ApplicationContextAware; public class SpringBrokerContext implements BrokerContext, ApplicationContextAware { ApplicationContext applicationContext; - + String configurationUrl; + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } @@ -43,4 +44,11 @@ public class SpringBrokerContext implements BrokerContext, ApplicationContextAwa return applicationContext.getBeansOfType(type); } + public void setConfigurationUrl(String configurationUrl) { + this.configurationUrl = configurationUrl; + } + + public String getConfigurationUrl() { + return configurationUrl; + } } http://git-wip-us.apache.org/repos/asf/activemq/blob/634a8189/activemq-spring/src/main/java/org/apache/activemq/xbean/XBeanBrokerFactory.java ---------------------------------------------------------------------- diff --git a/activemq-spring/src/main/java/org/apache/activemq/xbean/XBeanBrokerFactory.java b/activemq-spring/src/main/java/org/apache/activemq/xbean/XBeanBrokerFactory.java index 79a391b..7cee25a 100644 --- a/activemq-spring/src/main/java/org/apache/activemq/xbean/XBeanBrokerFactory.java +++ b/activemq-spring/src/main/java/org/apache/activemq/xbean/XBeanBrokerFactory.java @@ -20,8 +20,10 @@ import java.beans.PropertyEditorManager; import java.net.MalformedURLException; import java.net.URI; +import org.apache.activemq.broker.BrokerContextAware; import org.apache.activemq.broker.BrokerFactoryHandler; import org.apache.activemq.broker.BrokerService; +import org.apache.activemq.spring.SpringBrokerContext; import org.apache.activemq.spring.Utils; import org.apache.activemq.util.IntrospectionSupport; import org.apache.activemq.util.URISupport; @@ -85,11 +87,10 @@ public class XBeanBrokerFactory implements BrokerFactoryHandler { throw new IllegalArgumentException("The configuration has no BrokerService instance for resource: " + config); } - if (broker instanceof ApplicationContextAware) { - ((ApplicationContextAware)broker).setApplicationContext(context); - } - - broker.setConfigurationUrl(uri); + SpringBrokerContext springBrokerContext = new SpringBrokerContext(); + springBrokerContext.setApplicationContext(context); + springBrokerContext.setConfigurationUrl(uri); + broker.setBrokerContext(springBrokerContext); // TODO warning resources from the context may not be closed down! http://git-wip-us.apache.org/repos/asf/activemq/blob/634a8189/activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/JmsFrameTranslator.java ---------------------------------------------------------------------- diff --git a/activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/JmsFrameTranslator.java b/activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/JmsFrameTranslator.java index ca2906d..44cd420 100644 --- a/activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/JmsFrameTranslator.java +++ b/activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/JmsFrameTranslator.java @@ -281,6 +281,11 @@ public class JmsFrameTranslator extends LegacyFrameTranslator implements this.brokerContext = brokerContext; } + @Override + public BrokerContext getBrokerContext() { + return this.brokerContext; + } + /** * Return an Advisory message as a JSON formatted string * @param ds http://git-wip-us.apache.org/repos/asf/activemq/blob/634a8189/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/util/XStreamBrokerContext.java ---------------------------------------------------------------------- diff --git a/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/util/XStreamBrokerContext.java b/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/util/XStreamBrokerContext.java index a032802..2b1243e 100644 --- a/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/util/XStreamBrokerContext.java +++ b/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/util/XStreamBrokerContext.java @@ -52,4 +52,9 @@ public class XStreamBrokerContext implements BrokerContext { return null; } + @Override + public String getConfigurationUrl() { + return null; + } + }
