ARTEMIS-4001 - add properties url to the reload manager watch list, validate queue creation on reload with new test
This commit is contained in:
parent
1974ec5289
commit
d7d1c2ee42
|
@ -23,6 +23,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
|
||||
import org.apache.activemq.artemis.api.core.QueueConfiguration;
|
||||
import org.apache.activemq.artemis.core.config.amqpBrokerConnectivity.AMQPBrokerConnectConfiguration;
|
||||
import org.apache.activemq.artemis.core.config.routing.ConnectionRouterConfiguration;
|
||||
|
@ -1426,4 +1427,7 @@ public interface Configuration {
|
|||
|
||||
Configuration setSuppressSessionNotifications(boolean suppressSessionNotifications);
|
||||
|
||||
default String resolvePropertiesSources(String propertiesFileUrl) {
|
||||
return System.getProperty(ActiveMQDefaultConfiguration.BROKER_PROPERTIES_SYSTEM_PROPERTY_NAME, propertiesFileUrl);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.io.Serializable;
|
|||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.activemq.artemis.api.core.QueueConfiguration;
|
||||
import org.apache.activemq.artemis.api.core.RoutingType;
|
||||
|
@ -48,6 +49,12 @@ public class CoreAddressConfiguration implements Serializable {
|
|||
return routingTypes;
|
||||
}
|
||||
|
||||
public void setRoutingTypes(Set<String> rawRootingTypes) {
|
||||
for (String routingTypeString : rawRootingTypes) {
|
||||
routingTypes.add(RoutingType.valueOf(routingTypeString));
|
||||
}
|
||||
}
|
||||
|
||||
public CoreAddressConfiguration addRoutingType(RoutingType routingType) {
|
||||
routingTypes.add(routingType);
|
||||
return this;
|
||||
|
|
|
@ -470,7 +470,7 @@ public class ConfigurationImpl implements Configuration, Serializable {
|
|||
@Override
|
||||
public Configuration parseProperties(String fileUrlToProperties) throws Exception {
|
||||
// system property overrides location of file(s)
|
||||
fileUrlToProperties = System.getProperty(ActiveMQDefaultConfiguration.BROKER_PROPERTIES_SYSTEM_PROPERTY_NAME, fileUrlToProperties);
|
||||
fileUrlToProperties = resolvePropertiesSources(fileUrlToProperties);
|
||||
if (fileUrlToProperties != null) {
|
||||
for (String fileUrl : fileUrlToProperties.split(",")) {
|
||||
Properties brokerProperties = new InsertionOrderedProperties();
|
||||
|
@ -3051,7 +3051,7 @@ public class ConfigurationImpl implements Configuration, Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
static class InsertionOrderedProperties extends Properties {
|
||||
public static class InsertionOrderedProperties extends Properties {
|
||||
|
||||
final LinkedHashMap<Object, Object> orderedMap = new LinkedHashMap<>();
|
||||
|
||||
|
|
|
@ -173,6 +173,7 @@ import org.apache.activemq.artemis.core.server.plugin.ActiveMQServerMessagePlugi
|
|||
import org.apache.activemq.artemis.core.server.plugin.ActiveMQServerQueuePlugin;
|
||||
import org.apache.activemq.artemis.core.server.plugin.ActiveMQServerResourcePlugin;
|
||||
import org.apache.activemq.artemis.core.server.plugin.ActiveMQServerSessionPlugin;
|
||||
import org.apache.activemq.artemis.core.server.reload.ReloadCallback;
|
||||
import org.apache.activemq.artemis.core.server.routing.ConnectionRouterManager;
|
||||
import org.apache.activemq.artemis.core.server.reload.ReloadManager;
|
||||
import org.apache.activemq.artemis.core.server.reload.ReloadManagerImpl;
|
||||
|
@ -3252,7 +3253,21 @@ public class ActiveMQServerImpl implements ActiveMQServer {
|
|||
this.reloadManager = new ReloadManagerImpl(getScheduledPool(), executorFactory.getExecutor(), configurationFileRefreshPeriod);
|
||||
|
||||
if (configuration.getConfigurationUrl() != null && getScheduledPool() != null) {
|
||||
reloadManager.addCallback(configuration.getConfigurationUrl(), uri -> reloadConfigurationFile(uri));
|
||||
final URL configUrl = configuration.getConfigurationUrl();
|
||||
ReloadCallback xmlConfigReload = uri -> {
|
||||
// ignore the argument from the callback such that we can respond
|
||||
// to property file locations with a full reload
|
||||
reloadConfigurationFile(configUrl);
|
||||
};
|
||||
reloadManager.addCallback(configUrl, xmlConfigReload);
|
||||
|
||||
// watch properties and reload xml config
|
||||
String propsLocations = configuration.resolvePropertiesSources(propertiesFileUrl);
|
||||
if (propsLocations != null) {
|
||||
for (String fileUrl : propsLocations.split(",")) {
|
||||
reloadManager.addCallback(new File(fileUrl).toURI().toURL(), xmlConfigReload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (System.getProperty("logging.configuration") != null) {
|
||||
|
|
|
@ -117,7 +117,9 @@ public class ReloadManagerImpl extends ActiveMQScheduledComponent implements Rel
|
|||
logger.debug("Validating lastModified " + lastModified + " modified = " + fileModified + " on " + uri);
|
||||
}
|
||||
|
||||
if (lastModified > 0 && fileModified > lastModified) {
|
||||
if ((lastModified > 0 && fileModified > lastModified) ||
|
||||
// newly created file, first valid modified time
|
||||
(fileModified > 0 && lastModified == 0)) {
|
||||
|
||||
for (ReloadCallback callback : callbacks) {
|
||||
try {
|
||||
|
|
|
@ -74,6 +74,62 @@ public class ReloadManagerTest extends ActiveMQTestBase {
|
|||
internalTest(manager, file);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateOnDirectory() throws Exception {
|
||||
File nested = new File(getTemporaryDir(), "./sub/nested.txt");
|
||||
nested.mkdirs();
|
||||
nested.createNewFile();
|
||||
|
||||
File parentDir = nested.getParentFile();
|
||||
|
||||
Assert.assertTrue(parentDir.isDirectory());
|
||||
|
||||
final ReusableLatch latch = new ReusableLatch(1);
|
||||
|
||||
ReloadCallback reloadCallback = new ReloadCallback() {
|
||||
@Override
|
||||
public void reload(URL uri) {
|
||||
latch.countDown();
|
||||
}
|
||||
};
|
||||
manager.addCallback(parentDir.toURI().toURL(), reloadCallback);
|
||||
|
||||
Assert.assertFalse(latch.await(1, TimeUnit.SECONDS));
|
||||
|
||||
parentDir.setLastModified(System.currentTimeMillis());
|
||||
|
||||
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateOnNewNotExistingDirectory() throws Exception {
|
||||
final ReusableLatch latch = new ReusableLatch(1);
|
||||
|
||||
ReloadCallback reloadCallback = new ReloadCallback() {
|
||||
@Override
|
||||
public void reload(URL uri) {
|
||||
latch.countDown();
|
||||
}
|
||||
};
|
||||
|
||||
// verify not existing dir is not a problem
|
||||
File notExistFile = new File(getTemporaryDir(), "./sub2/not-there");
|
||||
File notExistDir = notExistFile.getParentFile();
|
||||
|
||||
Assert.assertFalse(notExistDir.exists());
|
||||
|
||||
manager.addCallback(notExistDir.toURI().toURL(), reloadCallback);
|
||||
|
||||
Assert.assertFalse(latch.await(1, TimeUnit.SECONDS));
|
||||
|
||||
// create that non-existent file now
|
||||
notExistFile.mkdirs();
|
||||
notExistFile.createNewFile();
|
||||
|
||||
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
private void internalTest(ReloadManagerImpl manager, File file) throws IOException, InterruptedException {
|
||||
file.createNewFile();
|
||||
|
||||
|
|
|
@ -16,9 +16,13 @@
|
|||
*/
|
||||
package org.apache.activemq.artemis.tests.integration.server;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
import org.apache.activemq.artemis.api.core.SimpleString;
|
||||
import org.apache.activemq.artemis.core.config.CoreQueueConfiguration;
|
||||
import org.apache.activemq.artemis.core.config.FileDeploymentManager;
|
||||
import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
|
||||
import org.apache.activemq.artemis.core.config.impl.FileConfiguration;
|
||||
import org.apache.activemq.artemis.core.config.impl.SecurityConfiguration;
|
||||
import org.apache.activemq.artemis.core.postoffice.Bindings;
|
||||
|
@ -29,6 +33,8 @@ import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager
|
|||
import org.apache.activemq.artemis.spi.core.security.jaas.InVMLoginModule;
|
||||
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
|
||||
import org.apache.activemq.artemis.tests.util.RandomUtil;
|
||||
import org.apache.activemq.artemis.tests.util.Wait;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ConfigurationTest extends ActiveMQTestBase {
|
||||
|
@ -65,6 +71,65 @@ public class ConfigurationTest extends ActiveMQTestBase {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertiesConfigReload() throws Exception {
|
||||
|
||||
File propsFile = new File(getTestDirfile(),"some.props");
|
||||
propsFile.createNewFile();
|
||||
|
||||
ConfigurationImpl.InsertionOrderedProperties config = new ConfigurationImpl.InsertionOrderedProperties();
|
||||
config.put("configurationFileRefreshPeriod", "500");
|
||||
|
||||
config.put("addressConfigurations.mytopic_3.routingTypes", "MULTICAST");
|
||||
|
||||
config.put("addressConfigurations.mytopic_3.queueConfigs.\"queue.A3\".address", "mytopic_3");
|
||||
config.put("addressConfigurations.mytopic_3.queueConfigs.\"queue.A3\".routingType", "MULTICAST");
|
||||
|
||||
config.put("addressConfigurations.mytopic_3.queueConfigs.\"queue.B3\".address", "mytopic_3");
|
||||
config.put("addressConfigurations.mytopic_3.queueConfigs.\"queue.B3\".routingType", "MULTICAST");
|
||||
|
||||
try (FileOutputStream outStream = new FileOutputStream(propsFile)) {
|
||||
config.store(outStream, null);
|
||||
}
|
||||
|
||||
Assert.assertTrue(propsFile.exists());
|
||||
|
||||
System.out.println("props: " + propsFile.getAbsolutePath());
|
||||
|
||||
ActiveMQServer server = getActiveMQServer("duplicate-queues.xml");
|
||||
server.setProperties(propsFile.getAbsolutePath());
|
||||
try {
|
||||
|
||||
server.start();
|
||||
Bindings mytopic_1 = server.getPostOffice().getBindingsForAddress(new SimpleString("mytopic_1"));
|
||||
assertEquals(mytopic_1.getBindings().size(), 0);
|
||||
Bindings mytopic_2 = server.getPostOffice().getBindingsForAddress(new SimpleString("mytopic_2"));
|
||||
assertEquals(mytopic_2.getBindings().size(), 3);
|
||||
|
||||
Bindings mytopic_3 = server.getPostOffice().getBindingsForAddress(new SimpleString("mytopic_3"));
|
||||
assertEquals(mytopic_3.getBindings().size(), 2);
|
||||
|
||||
|
||||
// add new binding from props update
|
||||
config.put("addressConfigurations.mytopic_3.queueConfigs.\"queue.C3\".address", "mytopic_3");
|
||||
|
||||
try (FileOutputStream outStream = new FileOutputStream(propsFile)) {
|
||||
config.store(outStream, null);
|
||||
}
|
||||
|
||||
Wait.assertTrue(() -> {
|
||||
Bindings mytopic_31 = server.getPostOffice().getBindingsForAddress(new SimpleString("mytopic_3"));
|
||||
return mytopic_31.getBindings().size() == 3;
|
||||
});
|
||||
|
||||
} finally {
|
||||
try {
|
||||
server.stop();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected ActiveMQServer getActiveMQServer(String brokerConfig) throws Exception {
|
||||
FileConfiguration fc = new FileConfiguration();
|
||||
FileJMSConfiguration fileConfiguration = new FileJMSConfiguration();
|
||||
|
|
Loading…
Reference in New Issue