Return-Path: X-Original-To: apmail-activemq-commits-archive@www.apache.org Delivered-To: apmail-activemq-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 69FDD10B07 for ; Thu, 22 Aug 2013 22:47:45 +0000 (UTC) Received: (qmail 16400 invoked by uid 500); 22 Aug 2013 22:47:45 -0000 Delivered-To: apmail-activemq-commits-archive@activemq.apache.org Received: (qmail 16376 invoked by uid 500); 22 Aug 2013 22:47:45 -0000 Mailing-List: contact commits-help@activemq.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@activemq.apache.org Delivered-To: mailing list commits@activemq.apache.org Received: (qmail 16369 invoked by uid 99); 22 Aug 2013 22:47:45 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 22 Aug 2013 22:47:45 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 22 Aug 2013 22:47:42 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 28FE0238888A; Thu, 22 Aug 2013 22:47:22 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1516650 - in /activemq/trunk/activemq-runtime-config/src: main/java/org/apache/activemq/plugin/ main/java/org/apache/activemq/plugin/jmx/ test/java/org/apache/activemq/ test/resources/org/apache/activemq/ Date: Thu, 22 Aug 2013 22:47:21 -0000 To: commits@activemq.apache.org From: gtully@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20130822224722.28FE0238888A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: gtully Date: Thu Aug 22 22:47:21 2013 New Revision: 1516650 URL: http://svn.apache.org/r1516650 Log: https://issues.apache.org/jira/browse/AMQ-4682 - add jmx mbean, manual update, validation and test refactor Added: activemq/trunk/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/jmx/ activemq/trunk/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/jmx/RuntimeConfigurationView.java (with props) activemq/trunk/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/jmx/RuntimeConfigurationViewMBean.java (with props) activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/MBeanTest.java (with props) activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/RuntimeConfigTestSupport.java (with props) activemq/trunk/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyManualUpdateConfig.xml (with props) activemq/trunk/activemq-runtime-config/src/test/resources/org/apache/activemq/parseErrorConfig.xml (with props) Modified: activemq/trunk/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/NetworkConnectorTest.java activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/VirtualDestTest.java Modified: activemq/trunk/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java?rev=1516650&r1=1516649&r2=1516650&view=diff ============================================================================== --- activemq/trunk/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java (original) +++ activemq/trunk/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java Thu Aug 22 22:47:21 2013 @@ -17,6 +17,7 @@ package org.apache.activemq.plugin; import java.io.IOException; +import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; @@ -26,6 +27,9 @@ import java.util.Properties; import java.util.TreeMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.locks.ReentrantReadWriteLock; +import javax.management.JMException; +import javax.management.ObjectName; +import javax.xml.XMLConstants; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; @@ -33,14 +37,20 @@ import javax.xml.bind.Unmarshaller; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; +import javax.xml.validation.ValidatorHandler; import org.apache.activemq.broker.BrokerFilter; import org.apache.activemq.broker.ConnectionContext; +import org.apache.activemq.broker.jmx.ManagementContext; import org.apache.activemq.broker.region.CompositeDestinationInterceptor; import org.apache.activemq.broker.region.Destination; import org.apache.activemq.broker.region.DestinationInterceptor; import org.apache.activemq.broker.region.RegionBroker; import org.apache.activemq.broker.region.virtual.VirtualDestination; import org.apache.activemq.command.ActiveMQDestination; +import org.apache.activemq.plugin.jmx.RuntimeConfigurationView; import org.apache.activemq.schema.core.Broker; import org.apache.activemq.schema.core.CompositeQueue; import org.apache.activemq.schema.core.CompositeTopic; @@ -59,6 +69,7 @@ import org.xml.sax.SAXException; public class RuntimeConfigurationBroker extends BrokerFilter { public static final Logger LOG = LoggerFactory.getLogger(RuntimeConfigurationBroker.class); + public static final String objectNamePropsAppendage = ",service=RuntimeConfiguration,name=Plugin"; private long checkPeriod; private long lastModified = -1; private Resource configToMonitor; @@ -66,6 +77,8 @@ public class RuntimeConfigurationBroker private Runnable monitorTask; private ConcurrentLinkedQueue destinationInterceptorUpdateWork = new ConcurrentLinkedQueue(); private final ReentrantReadWriteLock addDestinationBarrier = new ReentrantReadWriteLock(); + private ObjectName objectName; + private String infoString; public RuntimeConfigurationBroker(org.apache.activemq.broker.Broker next) { super(next); @@ -82,6 +95,7 @@ public class RuntimeConfigurationBroker currentConfiguration = loadConfiguration(configToMonitor); monitorModification(configToMonitor); + registerMbean(); } @Override @@ -93,9 +107,31 @@ public class RuntimeConfigurationBroker LOG.warn("Failed to cancel config monitor task", letsNotStopStop); } } + unregisterMbean(); super.stop(); } + private void registerMbean() { + if (getBrokerService().isUseJmx()) { + ManagementContext managementContext = getBrokerService().getManagementContext(); + try { + objectName = new ObjectName(getBrokerService().getBrokerObjectName().toString() + objectNamePropsAppendage); + managementContext.registerMBean(new RuntimeConfigurationView(this), objectName); + } catch (Exception ignored) { + LOG.debug("failed to register RuntimeConfigurationMBean", ignored); + } + } + } + + private void unregisterMbean() { + if (objectName != null) { + try { + getBrokerService().getManagementContext().unregisterMBean(objectName); + } catch (JMException ignored) { + } + } + } + // modification to virtual destinations interceptor needs exclusive access to destination add @Override public Destination addDestination(ConnectionContext context, ActiveMQDestination destination, boolean createIfTemporary) throws Exception { @@ -121,6 +157,15 @@ public class RuntimeConfigurationBroker } } + public String updateNow() { + LOG.info("Manual configuration update triggered"); + infoString = ""; + applyModifications(configToMonitor); + String result = infoString; + infoString = null; + return result; + } + private void monitorModification(final Resource configToMonitor) { monitorTask = new Runnable() { @Override @@ -134,22 +179,40 @@ public class RuntimeConfigurationBroker } } }; - if (lastModified > 0) { + if (lastModified > 0 && checkPeriod > 0) { this.getBrokerService().getScheduler().executePeriodically(monitorTask, checkPeriod); - LOG.info("Monitoring for updates (every " + checkPeriod + "millis) : " + configToMonitor); + info("Monitoring for updates (every " + checkPeriod + "millis) : " + configToMonitor); } } + private void info(String s) { + LOG.info(s); + if (infoString != null) { + infoString += s; + infoString += ";"; + } + } + + private void info(String s, Throwable t) { + LOG.info(s, t); + if (infoString != null) { + infoString += s; + infoString += ", " + t; + infoString += ";"; + } + } + + private void applyModifications(Resource configToMonitor) { Broker changed = loadConfiguration(configToMonitor); - if (!currentConfiguration.equals(changed)) { - LOG.info("configuration change in " + configToMonitor + " at: " + new Date(lastModified)); - LOG.info("current:" + currentConfiguration); - LOG.info("new :" + changed); + if (changed != null && !currentConfiguration.equals(changed)) { + LOG.info("change in " + configToMonitor + " at: " + new Date(lastModified)); + LOG.debug("current:" + currentConfiguration); + LOG.debug("new :" + changed); processSelectiveChanges(currentConfiguration, changed); currentConfiguration = changed; } else { - LOG.info("file modification but no material change to configuration in " + configToMonitor + " at: " + new Date(lastModified)); + info("No material change to configuration in " + configToMonitor + " at: " + new Date(lastModified)); } } @@ -192,7 +255,7 @@ public class RuntimeConfigurationBroker try { return (List) o.getClass().getMethod("getContents", new Class[]{}).invoke(o, new Object[]{}); } catch (Exception e) { - LOG.info("Failed to access getContents for " + o + ", runtime modifications not supported", e); + info("Failed to access getContents for " + o + ", runtime modifications not supported", e); } return new ArrayList(); } @@ -203,7 +266,7 @@ public class RuntimeConfigurationBroker Object existing = current.get(currentIndex); Object candidate = modification.get(modIndex); if (! existing.equals(candidate)) { - LOG.info("modification to:" + existing + " , with: " + candidate); + info("modification to:" + existing + " , with: " + candidate); remove(existing); addNew(candidate); } @@ -227,9 +290,9 @@ public class RuntimeConfigurationBroker if (getBrokerService().removeNetworkConnector(existingCandidate)) { try { existingCandidate.stop(); - LOG.info("stopped and removed networkConnector: " + existingCandidate); + info("stopped and removed networkConnector: " + existingCandidate); } catch (Exception e) { - LOG.error("Failed to stop removed network connector: " + existingCandidate); + info("Failed to stop removed network connector: " + existingCandidate); } } } @@ -247,11 +310,11 @@ public class RuntimeConfigurationBroker DestinationInterceptor[] destinationInterceptors = interceptorsList.toArray(new DestinationInterceptor[]{}); getBrokerService().setDestinationInterceptors(destinationInterceptors); ((CompositeDestinationInterceptor) ((RegionBroker) getBrokerService().getRegionBroker()).getDestinationInterceptor()).setInterceptors(destinationInterceptors); - LOG.trace("removed VirtualDestinationInterceptor from: " + interceptorsList); + info("removed VirtualDestinationInterceptor from: " + interceptorsList); } }); } else { - LOG.info("No runtime support for removal of: " + o); + info("No runtime support for removal of: " + o); } } @@ -284,9 +347,9 @@ public class RuntimeConfigurationBroker LOG.trace("applying networkConnector props: " + properties); IntrospectionSupport.setProperties(nc, properties); nc.start(); - LOG.info("started new network connector: " + nc); + info("started new network connector: " + nc); } catch (Exception e) { - LOG.error("Failed to add new networkConnector " + networkConnector, e); + info("Failed to add new networkConnector " + networkConnector, e); } } } else if (o instanceof VirtualDestinationInterceptor) { @@ -303,7 +366,7 @@ public class RuntimeConfigurationBroker (org.apache.activemq.broker.region.virtual.VirtualDestinationInterceptor) destinationInterceptor; virtualDestinationInterceptor.setVirtualDestinations(fromDto(dto)); - LOG.trace("applied updates to: " + virtualDestinationInterceptor); + info("applied updates to: " + virtualDestinationInterceptor); updatedExistingInterceptor = true; } } @@ -321,12 +384,12 @@ public class RuntimeConfigurationBroker DestinationInterceptor[] destinationInterceptors = interceptorsList.toArray(new DestinationInterceptor[]{}); getBrokerService().setDestinationInterceptors(destinationInterceptors); ((CompositeDestinationInterceptor) ((RegionBroker) getBrokerService().getRegionBroker()).getDestinationInterceptor()).setInterceptors(destinationInterceptors); - LOG.trace("applied new: " + interceptorsList); + info("applied new: " + interceptorsList); } } }); } else { - LOG.info("No runtime support for modifications to " + o); + info("No runtime support for modifications to " + o); } } @@ -381,6 +444,7 @@ public class RuntimeConfigurationBroker try { JAXBContext context = JAXBContext.newInstance(Broker.class); Unmarshaller unMarshaller = context.createUnmarshaller(); + unMarshaller.setSchema(getSchema()); // skip beans and pull out the broker node to validate DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); @@ -397,19 +461,41 @@ public class RuntimeConfigurationBroker lastModified = configToMonitor.lastModified(); } catch (IOException e) { - LOG.error("Failed to access: " + configToMonitor, e); + info("Failed to access: " + configToMonitor, e); } catch (JAXBException e) { - LOG.error("Failed to parse: " + configToMonitor, e); + info("Failed to parse: " + configToMonitor, e); } catch (ParserConfigurationException e) { - LOG.error("Failed to document parse: " + configToMonitor, e); + info("Failed to document parse: " + configToMonitor, e); } catch (SAXException e) { - LOG.error("Failed to find broker element in: " + configToMonitor, e); + info("Failed to find broker element in: " + configToMonitor, e); } } return jaxbConfig; } + private Schema schema; + private Schema getSchema() throws SAXException { + if (schema == null) { + SchemaFactory schemaFactory = SchemaFactory.newInstance( + XMLConstants.W3C_XML_SCHEMA_NS_URI); + schema = schemaFactory.newSchema(getClass().getResource("/activemq.xsd")); + } + return schema; + } + public void setCheckPeriod(long checkPeriod) { this.checkPeriod = checkPeriod; } + + public long getLastModified() { + return lastModified; + } + + public Resource getConfigToMonitor() { + return configToMonitor; + } + + public long getCheckPeriod() { + return checkPeriod; + } } \ No newline at end of file Added: activemq/trunk/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/jmx/RuntimeConfigurationView.java URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/jmx/RuntimeConfigurationView.java?rev=1516650&view=auto ============================================================================== --- activemq/trunk/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/jmx/RuntimeConfigurationView.java (added) +++ activemq/trunk/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/jmx/RuntimeConfigurationView.java Thu Aug 22 22:47:21 2013 @@ -0,0 +1,54 @@ +/** + * 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. + */ +package org.apache.activemq.plugin.jmx; + +import java.util.Date; +import org.apache.activemq.plugin.RuntimeConfigurationBroker; +import org.springframework.core.io.Resource; + +public class RuntimeConfigurationView implements RuntimeConfigurationViewMBean { + private final RuntimeConfigurationBroker runtimeConfigurationBroker; + + public RuntimeConfigurationView(RuntimeConfigurationBroker runtimeConfigurationBroker) { + this.runtimeConfigurationBroker = runtimeConfigurationBroker; + } + + @Override + public String getUrl() { + Resource value = runtimeConfigurationBroker.getConfigToMonitor(); + return value != null ? value.toString() : "null" ; + } + + @Override + public String getModified() { + long lastModified = runtimeConfigurationBroker.getLastModified(); + if (lastModified > 0) { + return new Date(lastModified).toString(); + } + return "unknown"; + } + + @Override + public String getCheckPeriod() { + return String.valueOf(runtimeConfigurationBroker.getCheckPeriod()); + } + + @Override + public String updateNow() { + return runtimeConfigurationBroker.updateNow(); + } +} Propchange: activemq/trunk/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/jmx/RuntimeConfigurationView.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: activemq/trunk/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/jmx/RuntimeConfigurationView.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Added: activemq/trunk/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/jmx/RuntimeConfigurationViewMBean.java URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/jmx/RuntimeConfigurationViewMBean.java?rev=1516650&view=auto ============================================================================== --- activemq/trunk/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/jmx/RuntimeConfigurationViewMBean.java (added) +++ activemq/trunk/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/jmx/RuntimeConfigurationViewMBean.java Thu Aug 22 22:47:21 2013 @@ -0,0 +1,35 @@ +/** + * 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. + */ +package org.apache.activemq.plugin.jmx; + +import org.apache.activemq.broker.jmx.MBeanInfo; + +public interface RuntimeConfigurationViewMBean { + + @MBeanInfo("Monitored configuration url.") + String getUrl(); + + @MBeanInfo("Current last modified.") + String getModified(); + + @MBeanInfo("check period.") + String getCheckPeriod(); + + @MBeanInfo("force a reread of the configuration url.") + String updateNow(); + +} Propchange: activemq/trunk/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/jmx/RuntimeConfigurationViewMBean.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: activemq/trunk/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/jmx/RuntimeConfigurationViewMBean.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Added: activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/MBeanTest.java URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/MBeanTest.java?rev=1516650&view=auto ============================================================================== --- activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/MBeanTest.java (added) +++ activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/MBeanTest.java Thu Aug 22 22:47:21 2013 @@ -0,0 +1,123 @@ +/** + * 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. + */ +package org.apache.activemq; + +import java.util.HashMap; +import javax.management.ObjectName; +import org.apache.activemq.plugin.RuntimeConfigurationBroker; +import org.apache.activemq.plugin.jmx.RuntimeConfigurationView; +import org.apache.activemq.plugin.jmx.RuntimeConfigurationViewMBean; +import org.apache.activemq.util.IntrospectionSupport; +import org.junit.Test; + + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + +public class MBeanTest extends RuntimeConfigTestSupport { + + @Test + public void testUpdateNow() throws Exception { + final String brokerConfig = "mBeanTest-manual-broker"; + applyNewConfig(brokerConfig, "emptyManualUpdateConfig"); + startBroker(brokerConfig); + assertTrue("broker alive", brokerService.isStarted()); + assertEquals("no network connectors", 0, brokerService.getNetworkConnectors().size()); + + applyNewConfig(brokerConfig, "networkConnectorTest-one-nc", SLEEP); + + assertEquals("no network connectors", 0, brokerService.getNetworkConnectors().size()); + + // apply via jmx + ObjectName objectName = + new ObjectName(brokerService.getBrokerObjectName().toString() + + RuntimeConfigurationBroker.objectNamePropsAppendage); + RuntimeConfigurationViewMBean runtimeConfigurationView = + (RuntimeConfigurationViewMBean) brokerService.getManagementContext().newProxyInstance(objectName, + RuntimeConfigurationViewMBean.class, false); + + HashMap props = new HashMap(); + IntrospectionSupport.getProperties(runtimeConfigurationView, props, null); + LOG.info("mbean attributes before: " + props); + + String result = runtimeConfigurationView.updateNow(); + + LOG.info("Result from update: " + result); + + assertTrue("got sensible result", result.contains("started")); + + assertEquals("one new network connectors", 1, brokerService.getNetworkConnectors().size()); + + HashMap propsAfter = new HashMap(); + IntrospectionSupport.getProperties(runtimeConfigurationView, propsAfter, null); + + LOG.info("mbean attributes after: " + propsAfter); + String propOfInterest = "modified"; + assertNotEquals("modified is different", props.get(propOfInterest), propsAfter.get(propOfInterest)); + } + + @Test + public void testUpdateFailedMod() throws Exception { + final String brokerConfig = "mBeanTest-manual-broker"; + applyNewConfig(brokerConfig, "emptyManualUpdateConfig"); + startBroker(brokerConfig); + assertTrue("broker alive", brokerService.isStarted()); + assertEquals("no network connectors", 0, brokerService.getNetworkConnectors().size()); + + applyNewConfig(brokerConfig, "parseErrorConfig", SLEEP); + + // apply via jmx + ObjectName objectName = + new ObjectName(brokerService.getBrokerObjectName().toString() + + RuntimeConfigurationBroker.objectNamePropsAppendage); + RuntimeConfigurationViewMBean runtimeConfigurationView = + (RuntimeConfigurationViewMBean) brokerService.getManagementContext().newProxyInstance(objectName, + RuntimeConfigurationViewMBean.class, false); + + HashMap props = new HashMap(); + IntrospectionSupport.getProperties(runtimeConfigurationView, props, null); + LOG.info("mbean attributes before: " + props); + + String result = runtimeConfigurationView.updateNow(); + LOG.info("Result from failed update: " + result); + + assertTrue("got sensible result", result.contains("dudElement")); + + HashMap propsAfter = new HashMap(); + IntrospectionSupport.getProperties(runtimeConfigurationView, propsAfter, null); + + LOG.info("mbean attributes after: " + propsAfter); + String propOfInterest = "modified"; + assertEquals("modified is same", props.get(propOfInterest), propsAfter.get(propOfInterest)); + + // apply good change now + applyNewConfig(brokerConfig, "networkConnectorTest-one-nc", SLEEP); + + result = runtimeConfigurationView.updateNow(); + + LOG.info("Result from update: " + result); + assertTrue("got sensible result", result.contains("started")); + assertEquals("one new network connectors", 1, brokerService.getNetworkConnectors().size()); + + propsAfter = new HashMap(); + IntrospectionSupport.getProperties(runtimeConfigurationView, propsAfter, null); + + assertNotEquals("modified is different", props.get(propOfInterest), propsAfter.get(propOfInterest)); + + } +} Propchange: activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/MBeanTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/MBeanTest.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Modified: activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/NetworkConnectorTest.java URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/NetworkConnectorTest.java?rev=1516650&r1=1516649&r2=1516650&view=diff ============================================================================== --- activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/NetworkConnectorTest.java (original) +++ activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/NetworkConnectorTest.java Thu Aug 22 22:47:21 2013 @@ -16,49 +16,21 @@ */ package org.apache.activemq; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.util.concurrent.TimeUnit; -import org.apache.activemq.broker.BrokerFactory; -import org.apache.activemq.broker.BrokerService; import org.apache.activemq.network.NetworkConnector; -import org.apache.activemq.spring.Utils; import org.apache.activemq.util.Wait; -import org.junit.After; -import org.junit.Ignore; +import org.junit.Before; import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.core.io.Resource; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; -public class NetworkConnectorTest { - - public static final Logger LOG = LoggerFactory.getLogger(NetworkConnectorTest.class); - public static final int SLEEP = 4; // seconds - public static final String EMPTY_UPDATABLE_CONFIG = "emptyUpdatableConfig1000" ; +public class NetworkConnectorTest extends RuntimeConfigTestSupport { String configurationSeed = "networkConnectorTest"; - BrokerService brokerService; - - public void startBroker(String configFileName) throws Exception { - brokerService = new BrokerService(); - brokerService = BrokerFactory.createBroker("xbean:org/apache/activemq/" + configFileName + ".xml"); - brokerService.start(); - brokerService.waitUntilStarted(); - } - - @After - public void stopBroker() throws Exception { - brokerService.stop(); - } @Test public void testNew() throws Exception { + final String brokerConfig = configurationSeed + "-no-nc-broker"; applyNewConfig(brokerConfig, EMPTY_UPDATABLE_CONFIG); startBroker(brokerConfig); @@ -67,7 +39,12 @@ public class NetworkConnectorTest { applyNewConfig(brokerConfig, configurationSeed + "-one-nc", SLEEP); - assertEquals("new network connectors", 1, brokerService.getNetworkConnectors().size()); + assertTrue("new network connectors", Wait.waitFor(new Wait.Condition() { + @Override + public boolean isSatisified() throws Exception { + return 1 == brokerService.getNetworkConnectors().size(); + } + })); // apply again - ensure no change NetworkConnector networkConnector = brokerService.getNetworkConnectors().get(0); @@ -124,22 +101,4 @@ public class NetworkConnectorTest { NetworkConnector remainingNetworkConnector = brokerService.getNetworkConnectors().get(0); assertEquals("name match", "one", remainingNetworkConnector.getName()); } - - private void applyNewConfig(String configName, String newConfigName) throws Exception { - applyNewConfig(configName, newConfigName, 0l); - } - - private void applyNewConfig(String configName, String newConfigName, long sleep) throws Exception { - Resource resource = Utils.resourceFromString("org/apache/activemq"); - FileOutputStream current = new FileOutputStream(new File(resource.getFile(), configName + ".xml")); - FileInputStream modifications = new FileInputStream(new File(resource.getFile(), newConfigName + ".xml")); - modifications.getChannel().transferTo(0, Long.MAX_VALUE, current.getChannel()); - current.flush(); - LOG.info("Updated: " + current.getChannel()); - - if (sleep > 0) { - // wait for mods to kick in - TimeUnit.SECONDS.sleep(sleep); - } - } } Added: activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/RuntimeConfigTestSupport.java URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/RuntimeConfigTestSupport.java?rev=1516650&view=auto ============================================================================== --- activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/RuntimeConfigTestSupport.java (added) +++ activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/RuntimeConfigTestSupport.java Thu Aug 22 22:47:21 2013 @@ -0,0 +1,71 @@ +/** + * 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. + */ +package org.apache.activemq; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.concurrent.TimeUnit; +import org.apache.activemq.broker.BrokerFactory; +import org.apache.activemq.broker.BrokerService; +import org.apache.activemq.spring.Utils; +import org.junit.After; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.Resource; + +public class RuntimeConfigTestSupport { + public static final Logger LOG = LoggerFactory.getLogger(RuntimeConfigTestSupport.class); + + public static final int SLEEP = 4; // seconds + public static final String EMPTY_UPDATABLE_CONFIG = "emptyUpdatableConfig1000" ; + BrokerService brokerService; + + public void startBroker(String configFileName) throws Exception { + brokerService = createBroker(configFileName); + brokerService.start(); + brokerService.waitUntilStarted(); + } + + public BrokerService createBroker(String configFileName) throws Exception { + brokerService = new BrokerService(); + return BrokerFactory.createBroker("xbean:org/apache/activemq/" + configFileName + ".xml"); + } + + protected void applyNewConfig(String configName, String newConfigName) throws Exception { + applyNewConfig(configName, newConfigName, 0l); + } + + protected void applyNewConfig(String configName, String newConfigName, long sleep) throws Exception { + Resource resource = Utils.resourceFromString("org/apache/activemq"); + FileOutputStream current = new FileOutputStream(new File(resource.getFile(), configName + ".xml")); + FileInputStream modifications = new FileInputStream(new File(resource.getFile(), newConfigName + ".xml")); + modifications.getChannel().transferTo(0, Long.MAX_VALUE, current.getChannel()); + current.flush(); + LOG.info("Updated: " + current.getChannel()); + + if (sleep > 0) { + // wait for mods to kick in + TimeUnit.SECONDS.sleep(sleep); + } + } + + @After + public void stopBroker() throws Exception { + brokerService.stop(); + } +} Propchange: activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/RuntimeConfigTestSupport.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/RuntimeConfigTestSupport.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Modified: activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/VirtualDestTest.java URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/VirtualDestTest.java?rev=1516650&r1=1516649&r2=1516650&view=diff ============================================================================== --- activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/VirtualDestTest.java (original) +++ activemq/trunk/activemq-runtime-config/src/test/java/org/apache/activemq/VirtualDestTest.java Thu Aug 22 22:47:21 2013 @@ -16,54 +16,27 @@ */ package org.apache.activemq; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.util.concurrent.TimeUnit; -import javax.jms.*; import javax.jms.Message; -import org.apache.activemq.broker.BrokerFactory; -import org.apache.activemq.broker.BrokerService; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TextMessage; import org.apache.activemq.broker.region.DestinationInterceptor; import org.apache.activemq.broker.region.virtual.VirtualDestinationInterceptor; -import org.apache.activemq.spring.Utils; import org.apache.activemq.util.Wait; -import org.junit.After; import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.core.io.Resource; import static org.junit.Assert.*; -public class VirtualDestTest { +public class VirtualDestTest extends RuntimeConfigTestSupport { - public static final Logger LOG = LoggerFactory.getLogger(VirtualDestTest.class); - public static final int SLEEP = 4; // seconds String configurationSeed = "virtualDestTest"; - BrokerService brokerService; - - public void startBroker(String configFileName) throws Exception { - brokerService = createBroker(configFileName); - brokerService.start(); - brokerService.waitUntilStarted(); - } - - public BrokerService createBroker(String configFileName) throws Exception { - brokerService = new BrokerService(); - return BrokerFactory.createBroker("xbean:org/apache/activemq/" + configFileName + ".xml"); - } - - @After - public void stopBroker() throws Exception { - brokerService.stop(); - } @Test public void testNew() throws Exception { - final String brokerConfig = configurationSeed + "-no-vd-broker"; - applyNewConfig(brokerConfig, NetworkConnectorTest.EMPTY_UPDATABLE_CONFIG); + final String brokerConfig = configurationSeed + "-new-no-vd-broker"; + applyNewConfig(brokerConfig, RuntimeConfigTestSupport.EMPTY_UPDATABLE_CONFIG); startBroker(brokerConfig); assertTrue("broker alive", brokerService.isStarted()); @@ -98,8 +71,8 @@ public class VirtualDestTest { @Test public void testNewNoDefaultVirtualTopicSupport() throws Exception { - final String brokerConfig = configurationSeed + "-no-vd-broker"; - applyNewConfig(brokerConfig, NetworkConnectorTest.EMPTY_UPDATABLE_CONFIG); + final String brokerConfig = configurationSeed + "-no-vd-vt-broker"; + applyNewConfig(brokerConfig, RuntimeConfigTestSupport.EMPTY_UPDATABLE_CONFIG); brokerService = createBroker(brokerConfig); brokerService.setUseVirtualTopics(false); brokerService.start(); @@ -128,8 +101,8 @@ public class VirtualDestTest { @Test public void testNewWithMirrorQueueSupport() throws Exception { - final String brokerConfig = configurationSeed + "-no-vd-broker"; - applyNewConfig(brokerConfig, NetworkConnectorTest.EMPTY_UPDATABLE_CONFIG); + final String brokerConfig = configurationSeed + "-no-vd-mq-broker"; + applyNewConfig(brokerConfig, RuntimeConfigTestSupport.EMPTY_UPDATABLE_CONFIG); brokerService = createBroker(brokerConfig); brokerService.setUseMirroredQueues(true); brokerService.start(); @@ -158,7 +131,7 @@ public class VirtualDestTest { @Test public void testRemove() throws Exception { - final String brokerConfig = configurationSeed + "-one-vd-broker"; + final String brokerConfig = configurationSeed + "-one-vd-rm-broker"; applyNewConfig(brokerConfig, configurationSeed + "-one-vd"); startBroker(brokerConfig); assertTrue("broker alive", brokerService.isStarted()); @@ -173,7 +146,7 @@ public class VirtualDestTest { exerciseVirtualTopic("A.Default"); - applyNewConfig(brokerConfig, NetworkConnectorTest.EMPTY_UPDATABLE_CONFIG, SLEEP); + applyNewConfig(brokerConfig, RuntimeConfigTestSupport.EMPTY_UPDATABLE_CONFIG, SLEEP); // update will happen on addDestination forceAddDestination("AnyDest"); @@ -197,7 +170,7 @@ public class VirtualDestTest { @Test public void testMod() throws Exception { - final String brokerConfig = configurationSeed + "-one-vd-broker"; + final String brokerConfig = configurationSeed + "-one-vd-mod-broker"; applyNewConfig(brokerConfig, configurationSeed + "-one-vd"); startBroker(brokerConfig); assertTrue("broker alive", brokerService.isStarted()); @@ -214,7 +187,7 @@ public class VirtualDestTest { @Test public void testModWithMirroredQueue() throws Exception { - final String brokerConfig = configurationSeed + "-one-vd-broker"; + final String brokerConfig = configurationSeed + "-one-vd-mq-mod-broker"; applyNewConfig(brokerConfig, configurationSeed + "-one-vd"); brokerService = createBroker(brokerConfig); brokerService.setUseMirroredQueues(true); @@ -257,21 +230,4 @@ public class VirtualDestTest { connection.close(); } - private void applyNewConfig(String configName, String newConfigName) throws Exception { - applyNewConfig(configName, newConfigName, 0l); - } - - private void applyNewConfig(String configName, String newConfigName, long sleep) throws Exception { - Resource resource = Utils.resourceFromString("org/apache/activemq"); - FileOutputStream current = new FileOutputStream(new File(resource.getFile(), configName + ".xml")); - FileInputStream modifications = new FileInputStream(new File(resource.getFile(), newConfigName + ".xml")); - modifications.getChannel().transferTo(0, Long.MAX_VALUE, current.getChannel()); - current.flush(); - LOG.info("Updated: " + current.getChannel()); - - if (sleep > 0) { - // wait for mods to kick in - TimeUnit.SECONDS.sleep(sleep); - } - } } Added: activemq/trunk/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyManualUpdateConfig.xml URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyManualUpdateConfig.xml?rev=1516650&view=auto ============================================================================== --- activemq/trunk/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyManualUpdateConfig.xml (added) +++ activemq/trunk/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyManualUpdateConfig.xml Thu Aug 22 22:47:21 2013 @@ -0,0 +1,29 @@ + + + + + + + + + + Propchange: activemq/trunk/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyManualUpdateConfig.xml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: activemq/trunk/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyManualUpdateConfig.xml ------------------------------------------------------------------------------ svn:keywords = Rev Date Propchange: activemq/trunk/activemq-runtime-config/src/test/resources/org/apache/activemq/emptyManualUpdateConfig.xml ------------------------------------------------------------------------------ svn:mime-type = text/xml Added: activemq/trunk/activemq-runtime-config/src/test/resources/org/apache/activemq/parseErrorConfig.xml URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-runtime-config/src/test/resources/org/apache/activemq/parseErrorConfig.xml?rev=1516650&view=auto ============================================================================== --- activemq/trunk/activemq-runtime-config/src/test/resources/org/apache/activemq/parseErrorConfig.xml (added) +++ activemq/trunk/activemq-runtime-config/src/test/resources/org/apache/activemq/parseErrorConfig.xml Thu Aug 22 22:47:21 2013 @@ -0,0 +1,30 @@ + + + + + + + + + ; + + Propchange: activemq/trunk/activemq-runtime-config/src/test/resources/org/apache/activemq/parseErrorConfig.xml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: activemq/trunk/activemq-runtime-config/src/test/resources/org/apache/activemq/parseErrorConfig.xml ------------------------------------------------------------------------------ svn:keywords = Rev Date Propchange: activemq/trunk/activemq-runtime-config/src/test/resources/org/apache/activemq/parseErrorConfig.xml ------------------------------------------------------------------------------ svn:mime-type = text/xml