You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by jb...@apache.org on 2016/08/10 14:24:54 UTC
[1/2] activemq-artemis git commit: ARTEMIS-601 Implementing reload
manager on JMS Destinations and Address Settings
Repository: activemq-artemis
Updated Branches:
refs/heads/master 155a345d3 -> 2b710229e
ARTEMIS-601 Implementing reload manager on JMS Destinations and Address Settings
Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/04d48203
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/04d48203
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/04d48203
Branch: refs/heads/master
Commit: 04d482037c6dcd7b6272fbc83a6ce5de7886d311
Parents: 155a345
Author: Clebert Suconic <cl...@apache.org>
Authored: Tue Aug 9 22:37:14 2016 -0400
Committer: Clebert Suconic <cl...@apache.org>
Committed: Wed Aug 10 10:03:40 2016 -0400
----------------------------------------------------------------------
.../jms/server/config/JMSConfiguration.java | 6 +
.../config/impl/FileJMSConfiguration.java | 1 +
.../config/impl/JMSConfigurationImpl.java | 14 ++
.../jms/server/impl/JMSServerManagerImpl.java | 37 +++++
.../artemis/core/server/ActiveMQServer.java | 3 +
.../core/server/impl/ActiveMQServerImpl.java | 49 ++----
.../core/server/reload/ReloadCallback.java | 24 +++
.../core/server/reload/ReloadManager.java | 29 ++++
.../core/server/reload/ReloadManagerImpl.java | 165 +++++++++++++++++++
.../artemis/core/reload/ReloadManagerTest.java | 89 ++++++++++
.../tests/integration/jms/RedeployTest.java | 97 +++++++++++
.../src/test/resources/reload-test-jms.xml | 112 +++++++++++++
.../test/resources/reload-test-updated-jms.xml | 114 +++++++++++++
13 files changed, 708 insertions(+), 32 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/04d48203/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/JMSConfiguration.java
----------------------------------------------------------------------
diff --git a/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/JMSConfiguration.java b/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/JMSConfiguration.java
index 3fd0298..8c8f7e0 100644
--- a/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/JMSConfiguration.java
+++ b/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/JMSConfiguration.java
@@ -16,6 +16,7 @@
*/
package org.apache.activemq.artemis.jms.server.config;
+import java.net.URL;
import java.util.List;
public interface JMSConfiguration {
@@ -35,4 +36,9 @@ public interface JMSConfiguration {
String getDomain();
JMSConfiguration setDomain(String domain);
+
+ URL getConfigurationUrl();
+
+ JMSConfiguration setConfigurationUrl(URL configurationUrl);
+
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/04d48203/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/impl/FileJMSConfiguration.java
----------------------------------------------------------------------
diff --git a/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/impl/FileJMSConfiguration.java b/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/impl/FileJMSConfiguration.java
index f17568d..a0c81f9 100644
--- a/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/impl/FileJMSConfiguration.java
+++ b/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/impl/FileJMSConfiguration.java
@@ -60,6 +60,7 @@ public class FileJMSConfiguration extends JMSConfigurationImpl implements Deploy
@Override
public void parse(Element config, URL url) throws Exception {
parseConfiguration(config);
+ setConfigurationUrl(url);
parsed = true;
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/04d48203/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/impl/JMSConfigurationImpl.java
----------------------------------------------------------------------
diff --git a/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/impl/JMSConfigurationImpl.java b/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/impl/JMSConfigurationImpl.java
index 406fb3b..6959098 100644
--- a/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/impl/JMSConfigurationImpl.java
+++ b/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/impl/JMSConfigurationImpl.java
@@ -16,6 +16,7 @@
*/
package org.apache.activemq.artemis.jms.server.config.impl;
+import java.net.URL;
import java.util.ArrayList;
import java.util.List;
@@ -35,6 +36,8 @@ public class JMSConfigurationImpl implements JMSConfiguration {
private String domain = ActiveMQDefaultConfiguration.getDefaultJmxDomain();
+ private URL configurationUrl;
+
// JMSConfiguration implementation -------------------------------
public JMSConfigurationImpl() {
@@ -83,4 +86,15 @@ public class JMSConfigurationImpl implements JMSConfiguration {
this.domain = domain;
return this;
}
+
+ @Override
+ public URL getConfigurationUrl() {
+ return configurationUrl;
+ }
+
+ @Override
+ public JMSConfiguration setConfigurationUrl(URL configurationUrl) {
+ this.configurationUrl = configurationUrl;
+ return this;
+ }
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/04d48203/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/impl/JMSServerManagerImpl.java
----------------------------------------------------------------------
diff --git a/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/impl/JMSServerManagerImpl.java b/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/impl/JMSServerManagerImpl.java
index b15dba3..364bb75 100644
--- a/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/impl/JMSServerManagerImpl.java
+++ b/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/impl/JMSServerManagerImpl.java
@@ -21,7 +21,11 @@ import javax.json.JsonArrayBuilder;
import javax.json.JsonObject;
import javax.naming.NamingException;
import javax.transaction.xa.Xid;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
import java.net.InetAddress;
+import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
@@ -59,6 +63,8 @@ import org.apache.activemq.artemis.core.server.QueueCreator;
import org.apache.activemq.artemis.core.server.QueueDeleter;
import org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl;
import org.apache.activemq.artemis.core.server.management.Notification;
+import org.apache.activemq.artemis.core.server.reload.ReloadCallback;
+import org.apache.activemq.artemis.core.server.reload.ReloadManager;
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
import org.apache.activemq.artemis.core.transaction.ResourceManager;
import org.apache.activemq.artemis.core.transaction.Transaction;
@@ -82,6 +88,7 @@ import org.apache.activemq.artemis.jms.server.config.JMSConfiguration;
import org.apache.activemq.artemis.jms.server.config.JMSQueueConfiguration;
import org.apache.activemq.artemis.jms.server.config.TopicConfiguration;
import org.apache.activemq.artemis.jms.server.config.impl.ConnectionFactoryConfigurationImpl;
+import org.apache.activemq.artemis.jms.server.config.impl.FileJMSConfiguration;
import org.apache.activemq.artemis.jms.server.management.JMSManagementService;
import org.apache.activemq.artemis.jms.server.management.JMSNotificationType;
import org.apache.activemq.artemis.jms.server.management.impl.JMSManagementServiceImpl;
@@ -91,6 +98,8 @@ import org.apache.activemq.artemis.utils.JsonLoader;
import org.apache.activemq.artemis.utils.SelectorTranslator;
import org.apache.activemq.artemis.utils.TimeAndCounterIDGenerator;
import org.apache.activemq.artemis.utils.TypedProperties;
+import org.apache.activemq.artemis.utils.XMLUtil;
+import org.w3c.dom.Element;
/**
* A Deployer used to create and add to Bindings queues, topics and connection
@@ -204,6 +213,8 @@ public class JMSServerManagerImpl implements JMSServerManager, ActivateCallback
// do not clear the cachedCommands - HORNETQ-1047
recoverBindings();
+
+
}
catch (Exception e) {
active = false;
@@ -394,6 +405,11 @@ public class JMSServerManagerImpl implements JMSServerManager, ActivateCallback
*/
startCalled = true;
server.start();
+ ReloadManager reloadManager = server.getReloadManager();
+ if (config != null && config.getConfigurationUrl() != null && reloadManager != null) {
+ reloadManager.addCallback(config.getConfigurationUrl(), new JMSReloader());
+ }
+
}
@@ -1741,4 +1757,25 @@ public class JMSServerManagerImpl implements JMSServerManager, ActivateCallback
}
}
}
+
+ private final class JMSReloader implements ReloadCallback {
+ @Override
+ public void reload(URL url) throws Exception {
+ InputStream input = url.openStream();
+ Reader reader = new InputStreamReader(input);
+ String xml = XMLUtil.readerToString(reader);
+ xml = XMLUtil.replaceSystemProps(xml);
+ Element e = XMLUtil.stringToElement(xml);
+
+ if (config instanceof FileJMSConfiguration) {
+ ((FileJMSConfiguration)config).parse(e, url);
+
+ JMSServerManagerImpl.this.deploy();
+ }
+
+
+
+ }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/04d48203/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServer.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServer.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServer.java
index af2f7cf..b777ced 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServer.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServer.java
@@ -41,6 +41,7 @@ import org.apache.activemq.artemis.core.server.group.GroupingHandler;
import org.apache.activemq.artemis.core.server.impl.Activation;
import org.apache.activemq.artemis.core.server.impl.ConnectorsService;
import org.apache.activemq.artemis.core.server.management.ManagementService;
+import org.apache.activemq.artemis.core.server.reload.ReloadManager;
import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
import org.apache.activemq.artemis.core.transaction.ResourceManager;
@@ -379,6 +380,8 @@ public interface ActiveMQServer extends ActiveMQComponent {
* */
void removeProtocolManagerFactory(ProtocolManagerFactory factory);
+ ReloadManager getReloadManager();
+
ActiveMQServer createBackupServer(Configuration configuration);
void addScaledDownNode(SimpleString scaledDownNodeId);
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/04d48203/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
index cc9ef1d..7edd985 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
@@ -129,6 +129,9 @@ import org.apache.activemq.artemis.core.server.group.impl.LocalGroupingHandler;
import org.apache.activemq.artemis.core.server.group.impl.RemoteGroupingHandler;
import org.apache.activemq.artemis.core.server.management.ManagementService;
import org.apache.activemq.artemis.core.server.management.impl.ManagementServiceImpl;
+import org.apache.activemq.artemis.core.server.reload.ReloadCallback;
+import org.apache.activemq.artemis.core.server.reload.ReloadManager;
+import org.apache.activemq.artemis.core.server.reload.ReloadManagerImpl;
import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
import org.apache.activemq.artemis.core.settings.impl.HierarchicalObjectRepository;
@@ -244,6 +247,8 @@ public class ActiveMQServerImpl implements ActiveMQServer {
private MemoryManager memoryManager;
+ private ReloadManager reloadManager;
+
/**
* This will be set by the JMS Queue Manager.
*/
@@ -374,6 +379,10 @@ public class ActiveMQServerImpl implements ActiveMQServer {
this.serviceRegistry = serviceRegistry == null ? new ServiceRegistryImpl() : serviceRegistry;
}
+ public ReloadManager getReloadManager() {
+ return reloadManager;
+ }
+
// life-cycle methods
// ----------------------------------------------------------------
@@ -453,8 +462,10 @@ public class ActiveMQServerImpl implements ActiveMQServer {
connectorsService = new ConnectorsService(configuration, storageManager, scheduledPool, postOffice, serviceRegistry);
connectorsService.start();
+ this.reloadManager = new ReloadManagerImpl(getScheduledPool(), configuration.getConfigurationFileRefreshPeriod());
+
if (configuration.getConfigurationUrl() != null && getScheduledPool() != null) {
- getScheduledPool().scheduleWithFixedDelay(new ConfigurationFileReloader(this), configuration.getConfigurationFileRefreshPeriod(), configuration.getConfigurationFileRefreshPeriod(), TimeUnit.MILLISECONDS);
+ reloadManager.addCallback(configuration.getConfigurationUrl(), new ConfigurationFileReloader());
}
}
finally {
@@ -2358,38 +2369,12 @@ public class ActiveMQServerImpl implements ActiveMQServer {
}
- private final class ConfigurationFileReloader implements Runnable {
- long lastModified;
- boolean first = true;
- ActiveMQServer server;
-
- ConfigurationFileReloader(ActiveMQServer server) {
- this.server = server;
- }
-
+ private final class ConfigurationFileReloader implements ReloadCallback {
@Override
- public void run() {
- try {
- URL url = server.getConfiguration().getConfigurationUrl();
- long currentLastModified = new File(url.getPath()).lastModified();
- if (first) {
- first = false;
- lastModified = currentLastModified;
- return;
- }
- if (currentLastModified > lastModified) {
- if (ActiveMQServerLogger.LOGGER.isDebugEnabled()) {
- ActiveMQServerLogger.LOGGER.debug("Configuration file change detected. Reloading...");
- }
- Configuration config = new FileConfigurationParser().parseMainConfig(url.openStream());
- securityRepository.swap(config.getSecurityRoles().entrySet());
-
- lastModified = currentLastModified;
- }
- }
- catch (Exception e) {
- ActiveMQServerLogger.LOGGER.configurationReloadFailed(e);
- }
+ public void reload(URL uri) throws Exception {
+ Configuration config = new FileConfigurationParser().parseMainConfig(uri.openStream());
+ securityRepository.swap(config.getSecurityRoles().entrySet());
+ addressSettingsRepository.swap(config.getAddressesSettings().entrySet());
}
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/04d48203/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/reload/ReloadCallback.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/reload/ReloadCallback.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/reload/ReloadCallback.java
new file mode 100644
index 0000000..cc4f5df
--- /dev/null
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/reload/ReloadCallback.java
@@ -0,0 +1,24 @@
+/**
+ * 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.artemis.core.server.reload;
+
+import java.net.URL;
+
+public interface ReloadCallback {
+ void reload(URL uri) throws Exception;
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/04d48203/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/reload/ReloadManager.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/reload/ReloadManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/reload/ReloadManager.java
new file mode 100644
index 0000000..0dfe6a7
--- /dev/null
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/reload/ReloadManager.java
@@ -0,0 +1,29 @@
+/**
+ * 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.artemis.core.server.reload;
+
+import java.net.URL;
+
+import org.apache.activemq.artemis.core.server.ActiveMQComponent;
+
+public interface ReloadManager extends ActiveMQComponent {
+ void addCallback(URL uri, ReloadCallback callback);
+
+ /** Callback for the next tick */
+ void setTick(Runnable callback);
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/04d48203/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/reload/ReloadManagerImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/reload/ReloadManagerImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/reload/ReloadManagerImpl.java
new file mode 100644
index 0000000..0ccbea1
--- /dev/null
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/reload/ReloadManagerImpl.java
@@ -0,0 +1,165 @@
+/**
+ * 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.artemis.core.server.reload;
+
+import java.io.File;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
+import org.jboss.logging.Logger;
+
+public class ReloadManagerImpl implements ReloadManager {
+ private static final Logger logger = Logger.getLogger(ReloadManagerImpl.class);
+
+ private final ScheduledExecutorService scheduledExecutorService;
+ private final long checkPeriod;
+ private ScheduledFuture future;
+ private volatile Runnable tick;
+
+ private Map<URL, ReloadRegistry> registry = new HashMap<>();
+
+ public ReloadManagerImpl(ScheduledExecutorService scheduledExecutorService, long checkPeriod) {
+ this.scheduledExecutorService = scheduledExecutorService;
+ this.checkPeriod = checkPeriod;
+ }
+
+ @Override
+ public synchronized void start() {
+ if (future != null) {
+ return;
+ }
+ future = scheduledExecutorService.scheduleWithFixedDelay(new ConfigurationFileReloader(), checkPeriod, checkPeriod, TimeUnit.MILLISECONDS);
+ }
+
+ @Override
+ public synchronized void setTick(Runnable tick) {
+ this.tick = tick;
+ }
+
+ @Override
+ public synchronized void stop() {
+ if (future == null) {
+ return; // no big deal
+ }
+
+ future.cancel(false);
+ future = null;
+
+ }
+
+ @Override
+ public synchronized boolean isStarted() {
+ return future != null;
+ }
+
+ @Override
+ public synchronized void addCallback(URL uri, ReloadCallback callback) {
+ if (future == null) {
+ start();
+ }
+ ReloadRegistry uriRegistry = getRegistry(uri);
+ uriRegistry.add(callback);
+ }
+
+ private synchronized void tick() {
+ for (ReloadRegistry item : registry.values()) {
+ item.check();
+ }
+
+ if (tick != null) {
+ tick.run();
+ tick = null;
+ }
+ }
+
+ private ReloadRegistry getRegistry(URL uri) {
+ ReloadRegistry uriRegistry = registry.get(uri);
+ if (uriRegistry == null) {
+ uriRegistry = new ReloadRegistry(uri);
+ registry.put(uri, uriRegistry);
+ }
+
+ return uriRegistry;
+ }
+
+
+
+ private final class ConfigurationFileReloader implements Runnable {
+ @Override
+ public void run() {
+ try {
+ tick();
+ }
+ catch (Exception e) {
+ ActiveMQServerLogger.LOGGER.configurationReloadFailed(e);
+ }
+ }
+ }
+
+ class ReloadRegistry {
+ private final File file;
+ private final URL uri;
+ private volatile long lastModified;
+
+ private final List<ReloadCallback> callbacks = new LinkedList<>();
+
+ ReloadRegistry(URL uri) {
+ this.file = new File(uri.getPath());
+ this.uri = uri;
+ }
+
+ public void check() {
+
+ long fileModified = file.lastModified();
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Validating lastModified " + lastModified + " modified = " + fileModified + " on " + uri);
+ }
+
+ if (lastModified > 0 && fileModified > lastModified) {
+
+ for (ReloadCallback callback : callbacks) {
+ try {
+ callback.reload(uri);
+ }
+ catch (Throwable e) {
+ ActiveMQServerLogger.LOGGER.configurationReloadFailed(e);
+ }
+ }
+ }
+
+ this.lastModified = fileModified;
+ }
+
+
+ public List<ReloadCallback> getCallbacks() {
+ return callbacks;
+ }
+
+ public void add(ReloadCallback callback) {
+ callbacks.add(callback);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/04d48203/artemis-server/src/test/java/org/apache/activemq/artemis/core/reload/ReloadManagerTest.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/core/reload/ReloadManagerTest.java b/artemis-server/src/test/java/org/apache/activemq/artemis/core/reload/ReloadManagerTest.java
new file mode 100644
index 0000000..181604f
--- /dev/null
+++ b/artemis-server/src/test/java/org/apache/activemq/artemis/core/reload/ReloadManagerTest.java
@@ -0,0 +1,89 @@
+/**
+ * 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.artemis.core.reload;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.activemq.artemis.core.server.reload.ReloadCallback;
+import org.apache.activemq.artemis.core.server.reload.ReloadManagerImpl;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.apache.activemq.artemis.utils.ReusableLatch;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ReloadManagerTest extends ActiveMQTestBase {
+
+ private ScheduledExecutorService scheduledExecutorService;
+
+ private ReloadManagerImpl manager;
+
+ @Before
+ public void startScheduled() {
+ scheduledExecutorService = new ScheduledThreadPoolExecutor(5);
+ manager = new ReloadManagerImpl(scheduledExecutorService, 100);
+ }
+
+ @After
+ public void stopScheduled() {
+ manager.stop();
+ scheduledExecutorService.shutdown();
+ scheduledExecutorService = null;
+ }
+
+ @Test
+ public void testUpdate() throws Exception {
+
+ File file = new File(getTemporaryDir(), "checkFile.tst");
+ internalTest(manager, file);
+
+ }
+
+ @Test
+ public void testUpdateWithSpace() throws Exception {
+ File spaceDir = new File(getTemporaryDir(), "./with space");
+ spaceDir.mkdirs();
+ File file = new File(spaceDir, "checkFile.tst");
+ internalTest(manager, file);
+ }
+
+ private void internalTest(ReloadManagerImpl manager, File file) throws IOException, InterruptedException {
+ file.createNewFile();
+
+ final ReusableLatch latch = new ReusableLatch(1);
+
+ manager.addCallback(file.toURL(), new ReloadCallback() {
+ @Override
+ public void reload(URL uri) {
+ latch.countDown();
+ }
+ });
+
+ Assert.assertFalse(latch.await(1, TimeUnit.SECONDS));
+
+ file.setLastModified(System.currentTimeMillis());
+
+ Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/04d48203/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/RedeployTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/RedeployTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/RedeployTest.java
new file mode 100644
index 0000000..c106897
--- /dev/null
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/RedeployTest.java
@@ -0,0 +1,97 @@
+/**
+ * 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.artemis.tests.integration.jms;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.MessageConsumer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
+import org.apache.activemq.artemis.jms.server.embedded.EmbeddedJMS;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.apache.activemq.artemis.utils.ReusableLatch;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class RedeployTest extends ActiveMQTestBase {
+
+ @Test
+ public void testRedeploy() throws Exception {
+ Path brokerXML = getTestDirfile().toPath().resolve("broker.xml");
+ URL url1 = RedeployTest.class.getClassLoader().getResource("reload-test-jms.xml");
+ URL url2 = RedeployTest.class.getClassLoader().getResource("reload-test-updated-jms.xml");
+ Files.copy(url1.openStream(), brokerXML);
+
+ EmbeddedJMS embeddedJMS = new EmbeddedJMS();
+ embeddedJMS.setConfigResourcePath(brokerXML.toUri().toString());
+ embeddedJMS.start();
+
+ final ReusableLatch latch = new ReusableLatch(1);
+
+ Runnable tick = new Runnable() {
+ @Override
+ public void run() {
+ latch.countDown();
+ }
+ };
+
+ embeddedJMS.getActiveMQServer().getReloadManager().setTick(tick);
+
+ try {
+ latch.await(10, TimeUnit.SECONDS);
+ Assert.assertEquals("jms.queue.DLQ", embeddedJMS.getActiveMQServer().getAddressSettingsRepository().getMatch("jms").getDeadLetterAddress().toString());
+ Assert.assertEquals("jms.queue.ExpiryQueue", embeddedJMS.getActiveMQServer().getAddressSettingsRepository().getMatch("jms").getExpiryAddress().toString());
+ Assert.assertFalse(tryConsume());
+ Files.copy(url2.openStream(), brokerXML, StandardCopyOption.REPLACE_EXISTING);
+ brokerXML.toFile().setLastModified(System.currentTimeMillis() + 1000);
+ latch.setCount(1);
+ embeddedJMS.getActiveMQServer().getReloadManager().setTick(tick);
+ latch.await(10, TimeUnit.SECONDS);
+
+ Assert.assertTrue(tryConsume());
+
+ Assert.assertEquals("jms.queue.NewQueue", embeddedJMS.getActiveMQServer().getAddressSettingsRepository().getMatch("jms").getDeadLetterAddress().toString());
+ Assert.assertEquals("jms.queue.NewQueue", embeddedJMS.getActiveMQServer().getAddressSettingsRepository().getMatch("jms").getExpiryAddress().toString());
+
+ }
+ finally {
+ embeddedJMS.stop();
+ }
+ }
+
+ private boolean tryConsume() throws JMSException {
+ try (ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
+ Connection connection = factory.createConnection();
+ Session session = connection.createSession(Session.AUTO_ACKNOWLEDGE)) {
+ Queue queue = session.createQueue("NewQueue");
+ MessageConsumer consumer = session.createConsumer(queue);
+ return true;
+ }
+ catch (JMSException e) {
+ return false;
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/04d48203/tests/integration-tests/src/test/resources/reload-test-jms.xml
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/resources/reload-test-jms.xml b/tests/integration-tests/src/test/resources/reload-test-jms.xml
new file mode 100644
index 0000000..9d56984
--- /dev/null
+++ b/tests/integration-tests/src/test/resources/reload-test-jms.xml
@@ -0,0 +1,112 @@
+<?xml version='1.0'?>
+<!--
+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.
+-->
+
+<configuration xmlns="urn:activemq"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
+
+ <jms xmlns="urn:activemq:jms">
+ <queue name="DLQ"/>
+ <queue name="ExpiryQueue"/>
+
+ </jms>
+
+ <core xmlns="urn:activemq:core">
+
+ <name>0.0.0.0</name>
+
+ <configuration-file-refresh-period>100</configuration-file-refresh-period>
+
+ <persistence-enabled>false</persistence-enabled>
+
+ <security-enabled>false</security-enabled>
+
+ <!-- this could be ASYNCIO or NIO
+ -->
+ <journal-type>NIO</journal-type>
+
+ <paging-directory>./data/paging</paging-directory>
+
+ <bindings-directory>./data/bindings</bindings-directory>
+
+ <journal-directory>./data/journal</journal-directory>
+
+ <large-messages-directory>./data/large-messages</large-messages-directory>
+
+ <journal-min-files>2</journal-min-files>
+
+ <journal-pool-files>-1</journal-pool-files>
+
+ <!--
+ This value was determined through a calculation.
+ Your system could perform 25 writes per millisecond
+ on the current journal configuration.
+ That translates as a sync write every 40000 nanoseconds
+ -->
+ <journal-buffer-timeout>40000</journal-buffer-timeout>
+
+
+ <acceptors>
+ <!-- Default ActiveMQ Artemis Acceptor. Multi-protocol adapter. Currently supports ActiveMQ Artemis Core, OpenWire, STOMP, AMQP, MQTT, and HornetQ Core. -->
+ <!-- performance tests have shown that openWire performs best with these buffer sizes -->
+ <acceptor name="artemis">tcp://0.0.0.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576</acceptor>
+
+ <!-- AMQP Acceptor. Listens on default AMQP port for AMQP traffic.-->
+ <acceptor name="amqp">tcp://0.0.0.0:5672?protocols=AMQP</acceptor>
+
+ <!-- STOMP Acceptor. -->
+ <acceptor name="stomp">tcp://0.0.0.0:61613?protocols=STOMP</acceptor>
+
+ <!-- HornetQ Compatibility Acceptor. Enables HornetQ Core and STOMP for legacy HornetQ clients. -->
+ <acceptor name="hornetq">tcp://0.0.0.0:5445?protocols=HORNETQ,STOMP</acceptor>
+
+ <!-- MQTT Acceptor -->
+ <acceptor name="mqtt">tcp://0.0.0.0:1883?protocols=MQTT</acceptor>
+
+ </acceptors>
+
+
+ <security-settings>
+ <security-setting match="#">
+ <permission type="createNonDurableQueue" roles="a"/>
+ <permission type="deleteNonDurableQueue" roles="a"/>
+ <permission type="createDurableQueue" roles="a"/>
+ <permission type="deleteDurableQueue" roles="a"/>
+ <permission type="browse" roles="a"/>
+ <permission type="send" roles="a"/>
+ <!-- we need this otherwise ./artemis data imp wouldn't work -->
+ <permission type="manage" roles="a"/>
+ </security-setting>
+ </security-settings>
+
+ <address-settings>
+ <!--default for catch all-->
+ <address-setting match="#">
+ <auto-create-jms-queues>false</auto-create-jms-queues>
+ <dead-letter-address>jms.queue.DLQ</dead-letter-address>
+ <expiry-address>jms.queue.ExpiryQueue</expiry-address>
+ <redelivery-delay>0</redelivery-delay>
+ <max-size-bytes>10485760</max-size-bytes>
+ <message-counter-history-day-limit>10</message-counter-history-day-limit>
+ <address-full-policy>BLOCK</address-full-policy>
+ </address-setting>
+ </address-settings>
+ </core>
+</configuration>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/04d48203/tests/integration-tests/src/test/resources/reload-test-updated-jms.xml
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/resources/reload-test-updated-jms.xml b/tests/integration-tests/src/test/resources/reload-test-updated-jms.xml
new file mode 100644
index 0000000..3e6e329
--- /dev/null
+++ b/tests/integration-tests/src/test/resources/reload-test-updated-jms.xml
@@ -0,0 +1,114 @@
+<?xml version='1.0'?>
+<!--
+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.
+-->
+
+<configuration xmlns="urn:activemq"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
+
+ <jms xmlns="urn:activemq:jms">
+ <queue name="DLQ"/>
+ <queue name="ExpiryQueue"/>
+ <queue name="NewQueue"/>
+
+ </jms>
+
+ <core xmlns="urn:activemq:core">
+
+ <name>0.0.0.0</name>
+
+ <configuration-file-refresh-period>100</configuration-file-refresh-period>
+
+ <persistence-enabled>false</persistence-enabled>
+
+ <security-enabled>false</security-enabled>
+
+ <!-- this could be ASYNCIO or NIO
+ -->
+ <journal-type>NIO</journal-type>
+
+ <paging-directory>./data/paging</paging-directory>
+
+ <bindings-directory>./data/bindings</bindings-directory>
+
+ <journal-directory>./data/journal</journal-directory>
+
+ <large-messages-directory>./data/large-messages</large-messages-directory>
+
+ <journal-min-files>2</journal-min-files>
+
+ <journal-pool-files>-1</journal-pool-files>
+
+ <!--
+ This value was determined through a calculation.
+ Your system could perform 25 writes per millisecond
+ on the current journal configuration.
+ That translates as a sync write every 40000 nanoseconds
+ -->
+ <journal-buffer-timeout>40000</journal-buffer-timeout>
+
+
+ <acceptors>
+ <!-- Default ActiveMQ Artemis Acceptor. Multi-protocol adapter. Currently supports ActiveMQ Artemis Core, OpenWire, STOMP, AMQP, MQTT, and HornetQ Core. -->
+ <!-- performance tests have shown that openWire performs best with these buffer sizes -->
+ <acceptor name="artemis">tcp://0.0.0.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576</acceptor>
+
+ <!-- AMQP Acceptor. Listens on default AMQP port for AMQP traffic.-->
+ <acceptor name="amqp">tcp://0.0.0.0:5672?protocols=AMQP</acceptor>
+
+ <!-- STOMP Acceptor. -->
+ <acceptor name="stomp">tcp://0.0.0.0:61613?protocols=STOMP</acceptor>
+
+ <!-- HornetQ Compatibility Acceptor. Enables HornetQ Core and STOMP for legacy HornetQ clients. -->
+ <acceptor name="hornetq">tcp://0.0.0.0:5445?protocols=HORNETQ,STOMP</acceptor>
+
+ <!-- MQTT Acceptor -->
+ <acceptor name="mqtt">tcp://0.0.0.0:1883?protocols=MQTT</acceptor>
+
+ </acceptors>
+
+
+ <security-settings>
+ <security-setting match="#">
+ <permission type="createNonDurableQueue" roles="a"/>
+ <permission type="deleteNonDurableQueue" roles="a"/>
+ <permission type="createDurableQueue" roles="a"/>
+ <permission type="deleteDurableQueue" roles="a"/>
+ <permission type="consume" roles="a"/>
+ <permission type="browse" roles="a"/>
+ <permission type="send" roles="a"/>
+ <!-- we need this otherwise ./artemis data imp wouldn't work -->
+ <permission type="manage" roles="a"/>
+ </security-setting>
+ </security-settings>
+
+ <address-settings>
+ <!--default for catch all-->
+ <address-setting match="#">
+ <auto-create-jms-queues>false</auto-create-jms-queues>
+ <dead-letter-address>jms.queue.NewQueue</dead-letter-address>
+ <expiry-address>jms.queue.NewQueue</expiry-address>
+ <redelivery-delay>0</redelivery-delay>
+ <max-size-bytes>10485760</max-size-bytes>
+ <message-counter-history-day-limit>10</message-counter-history-day-limit>
+ <address-full-policy>BLOCK</address-full-policy>
+ </address-setting>
+ </address-settings>
+ </core>
+</configuration>
[2/2] activemq-artemis git commit: This closes #711
Posted by jb...@apache.org.
This closes #711
Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/2b710229
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/2b710229
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/2b710229
Branch: refs/heads/master
Commit: 2b710229e28df805c3e361b052a28fc238c4b7a7
Parents: 155a345 04d4820
Author: jbertram <jb...@apache.org>
Authored: Wed Aug 10 09:24:02 2016 -0500
Committer: jbertram <jb...@apache.org>
Committed: Wed Aug 10 09:24:02 2016 -0500
----------------------------------------------------------------------
.../jms/server/config/JMSConfiguration.java | 6 +
.../config/impl/FileJMSConfiguration.java | 1 +
.../config/impl/JMSConfigurationImpl.java | 14 ++
.../jms/server/impl/JMSServerManagerImpl.java | 37 +++++
.../artemis/core/server/ActiveMQServer.java | 3 +
.../core/server/impl/ActiveMQServerImpl.java | 49 ++----
.../core/server/reload/ReloadCallback.java | 24 +++
.../core/server/reload/ReloadManager.java | 29 ++++
.../core/server/reload/ReloadManagerImpl.java | 165 +++++++++++++++++++
.../artemis/core/reload/ReloadManagerTest.java | 89 ++++++++++
.../tests/integration/jms/RedeployTest.java | 97 +++++++++++
.../src/test/resources/reload-test-jms.xml | 112 +++++++++++++
.../test/resources/reload-test-updated-jms.xml | 114 +++++++++++++
13 files changed, 708 insertions(+), 32 deletions(-)
----------------------------------------------------------------------