activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gtu...@apache.org
Subject [1/5] git commit: 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 network
Date Mon, 02 Sep 2013 23:40:04 GMT
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 <gtully@apache.org>
Authored: Tue Sep 3 00:28:46 2013 +0100
Committer: gtully <gtully@apache.org>
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;
+    }
+
 }


Mime
View raw message