diff options
Diffstat (limited to 'java/broker/src')
2 files changed, 695 insertions, 74 deletions
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java index 879eb7c9e6..edf88f9b5a 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java @@ -21,18 +21,19 @@ package org.apache.qpid.server.configuration; import java.io.File; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.Locale; -import java.util.Collections; +import java.util.Map; import java.util.Map.Entry; import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.ConfigurationFactory; +import org.apache.commons.configuration.HierarchicalConfiguration; import org.apache.commons.configuration.SystemConfiguration; import org.apache.commons.configuration.XMLConfiguration; import org.apache.qpid.server.configuration.management.ConfigurationManagementMBean; @@ -52,18 +53,17 @@ public class ServerConfiguration implements SignalHandler private Configuration _config; // Default Configuration values - //todo make these all public, to make validation of configuration easier. public static final int DEFAULT_BUFFER_READ_LIMIT_SIZE = 262144; public static final int DEFAULT_BUFFER_WRITE_LIMIT_SIZE = 262144; public static final boolean DEFAULT_BROKER_CONNECTOR_PROTECTIO_ENABLED = false; public static final String DEFAULT_STATUS_UPDATES = "on"; public static final String SECURITY_CONFIG_RELOADED = "SECURITY CONFIGURATION RELOADED"; - private static final int DEFAULT_FRAME_SIZE = 65536; - private static final int DEFAULT_PORT = 5672; - private static final int DEFAUL_SSL_PORT = 8672; - private static final long DEFAULT_HOUSEKEEPING_PERIOD = 30000L; - private static final int DEFAULT_JMXPORT = 8999; + public static final int DEFAULT_FRAME_SIZE = 65536; + public static final int DEFAULT_PORT = 5672; + public static final int DEFAULT_SSL_PORT = 8672; + public static final long DEFAULT_HOUSEKEEPING_PERIOD = 30000L; + public static final int DEFAULT_JMXPORT = 8999; private static int _jmxPort = DEFAULT_JMXPORT; @@ -71,6 +71,7 @@ public class ServerConfiguration implements SignalHandler private SecurityConfiguration _securityConfiguration = null; private File _configFile; + private File _vhostsFile; private Logger _log = LoggerFactory.getLogger(this.getClass()); @@ -134,8 +135,6 @@ public class ServerConfiguration implements SignalHandler { setConfig(conf); - substituteEnvironmentVariables(); - _jmxPort = getConfig().getInt("management.jmxport", 8999); _securityConfiguration = new SecurityConfiguration(conf.subset("security")); @@ -143,61 +142,86 @@ public class ServerConfiguration implements SignalHandler } - private void setupVirtualHosts(Configuration conf) throws ConfigurationException + /* + * Modified to enforce virtualhosts configuration in external file or main file, but not + * both, as a fix for QPID-2360 and QPID-2361. + */ + @SuppressWarnings("unchecked") + private void setupVirtualHosts(Configuration conf) throws ConfigurationException { - List vhosts = conf.getList("virtualhosts"); - Iterator i = vhosts.iterator(); - while (i.hasNext()) + List<String> vhostFiles = conf.getList("virtualhosts"); + Configuration vhostConfig = conf.subset("virtualhosts"); + + // Only one configuration mechanism allowed + if (!vhostFiles.isEmpty() && !vhostConfig.subset("virtualhost").isEmpty()) { - Object thing = i.next(); - if (thing instanceof String) - { - //Open the Virtualhost.xml file and copy values in to main config - XMLConfiguration vhostConfiguration = new XMLConfiguration((String) thing); - Iterator keys = vhostConfiguration.getKeys(); - while (keys.hasNext()) - { - String key = (String) keys.next(); - conf.setProperty("virtualhosts." + key, vhostConfiguration.getProperty(key)); - } - } + throw new ConfigurationException("Only one of external or embedded virtualhosts configuration allowed."); + } + + // We can only have one vhosts XML file included + if (vhostFiles.size() > 1) + { + throw new ConfigurationException("Only one external virtualhosts configuration file allowed, multiple filenames found."); + } + + // Virtualhost configuration object + Configuration vhostConfiguration = new HierarchicalConfiguration(); + + // Load from embedded configuration if possible + if (!vhostConfig.subset("virtualhost").isEmpty()) + { + vhostConfiguration = vhostConfig; } - - List hosts = conf.getList("virtualhosts.virtualhost.name"); + else + { + // Load from the external configuration if possible + for (String fileName : vhostFiles) + { + // Open the vhosts XML file and copy values from it to our config + _vhostsFile = new File(fileName); + vhostConfiguration = parseConfig(new File(fileName)); + } + } + + // Now extract the virtual host names from the configuration object + List hosts = vhostConfiguration.getList("virtualhost.name"); for (int j = 0; j < hosts.size(); j++) { String name = (String) hosts.get(j); - // Add the keys of the virtual host to the main config then bail out - - VirtualHostConfiguration vhostConfig = new VirtualHostConfiguration(name, conf.subset("virtualhosts.virtualhost." + name)); - _virtualHosts.put(vhostConfig.getName(), vhostConfig); + + // Add the virtual hosts to the server configuration + VirtualHostConfiguration virtualhost = new VirtualHostConfiguration(name, vhostConfiguration.subset("virtualhost." + name)); + _virtualHosts.put(virtualhost.getName(), virtualhost); } - } - private void substituteEnvironmentVariables() + private static void substituteEnvironmentVariables(Configuration conf) { for (Entry<String, String> var : envVarMap.entrySet()) { String val = System.getenv(var.getKey()); if (val != null) { - getConfig().setProperty(var.getValue(), val); + conf.setProperty(var.getValue(), val); } } } - private final static Configuration parseConfig(File file) throws ConfigurationException + private static Configuration parseConfig(File file) throws ConfigurationException { ConfigurationFactory factory = new ConfigurationFactory(); factory.setConfigurationFileName(file.getAbsolutePath()); Configuration conf = factory.getConfiguration(); - Iterator keys = conf.getKeys(); + + Iterator<?> keys = conf.getKeys(); if (!keys.hasNext()) { keys = null; conf = flatConfig(file); } + + substituteEnvironmentVariables(conf); + return conf; } @@ -311,13 +335,25 @@ public class ServerConfiguration implements SignalHandler if (_configFile != null) { Configuration newConfig = parseConfig(_configFile); + _securityConfiguration = new SecurityConfiguration(newConfig.subset("security")); - + + // Reload virtualhosts from correct location + Configuration newVhosts; + if (_vhostsFile == null) + { + newVhosts = newConfig.subset("virtualhosts"); + } + else + { + newVhosts = parseConfig(_vhostsFile); + } + VirtualHostRegistry vhostRegistry = ApplicationRegistry.getInstance().getVirtualHostRegistry(); for (String hostname : _virtualHosts.keySet()) { VirtualHost vhost = vhostRegistry.getVirtualHost(hostname); - SecurityConfiguration hostSecurityConfig = new SecurityConfiguration(newConfig.subset("virtualhosts.virtualhost."+hostname+".security")); + SecurityConfiguration hostSecurityConfig = new SecurityConfiguration(newVhosts.subset("virtualhost."+hostname+".security")); vhost.getAccessManager().configureGlobalPlugins(_securityConfiguration); vhost.getAccessManager().configureHostPlugins(hostSecurityConfig); } @@ -601,7 +637,7 @@ public class ServerConfiguration implements SignalHandler public int getSSLPort() { - return getConfig().getInt("connector.ssl.port", DEFAUL_SSL_PORT); + return getConfig().getInt("connector.ssl.port", DEFAULT_SSL_PORT); } public String getKeystorePath() diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java index e478f0f1f3..934367890d 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java @@ -20,11 +20,20 @@ */ package org.apache.qpid.server.configuration; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.List; +import java.util.Locale; + import junit.framework.TestCase; -import org.apache.commons.configuration.Configuration; + import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.XMLConfiguration; - +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.exchange.ExchangeType; import org.apache.qpid.server.protocol.AMQProtocolEngine; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.registry.ApplicationRegistry; @@ -33,24 +42,15 @@ import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.server.virtualhost.VirtualHostRegistry; import org.apache.qpid.transport.TestNetworkDriver; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; - public class ServerConfigurationTest extends TestCase { - private XMLConfiguration _config; @Override public void setUp() { //Highlight that this test will cause a new AR to be created -// ApplicationRegistry.getInstance(); + ApplicationRegistry.getInstance(); _config = new XMLConfiguration(); } @@ -59,7 +59,7 @@ public class ServerConfigurationTest extends TestCase public void tearDown() throws Exception { //Correctly Close the AR we created -// ApplicationRegistry.remove(); + ApplicationRegistry.remove(); } public void testSetJMXManagementPort() throws ConfigurationException @@ -756,10 +756,9 @@ public class ServerConfigurationTest extends TestCase public void testFirewallConfiguration() throws Exception { - // Write out config + // Write out config File mainFile = File.createTempFile(getClass().getName(), null); mainFile.deleteOnExit(); - FileWriter out; writeConfigFile(mainFile, false); // Load config @@ -903,6 +902,10 @@ public class ServerConfigurationTest extends TestCase } private void writeConfigFile(File mainFile, boolean allow) throws IOException { + writeConfigFile(mainFile, allow, true, null, "test"); + } + + private void writeConfigFile(File mainFile, boolean allow, boolean includeVhosts, File vhostsFile, String name) throws IOException { FileWriter out = new FileWriter(mainFile); out.write("<broker>\n"); out.write("\t<management><enabled>false</enabled></management>\n"); @@ -927,15 +930,101 @@ public class ServerConfigurationTest extends TestCase out.write("\t\t\t<rule access=\""+ ((allow) ? "allow" : "deny") +"\" network=\"127.0.0.1\"/>"); out.write("\t\t</firewall>\n"); out.write("\t</security>\n"); + if (includeVhosts) + { + out.write("\t<virtualhosts>\n"); + out.write("\t\t<virtualhost>\n"); + out.write(String.format("\t\t\t<name>%s</name>\n", name)); + out.write(String.format("\t\t<%s> \n", name)); + out.write("\t\t\t<exchanges>\n"); + out.write("\t\t\t\t<exchange>\n"); + out.write("\t\t\t\t\t<type>topic</type>\n"); + out.write(String.format("\t\t\t\t\t<name>%s.topic</name>\n", name)); + out.write("\t\t\t\t\t<durable>true</durable>\n"); + out.write("\t\t\t\t</exchange>\n"); + out.write("\t\tt</exchanges>\n"); + out.write(String.format("\t\t</%s> \n", name)); + out.write("\t\t</virtualhost>\n"); + out.write("\t</virtualhosts>\n"); + } + if (vhostsFile != null) + { + out.write("\t<virtualhosts>"+vhostsFile.getAbsolutePath()+"</virtualhosts>\n"); + } + out.write("</broker>\n"); + out.close(); + } + + private void writeTestFishConfigFile(File mainFile) throws IOException { + FileWriter out = new FileWriter(mainFile); + out.write("<broker>\n"); + out.write("\t<management><enabled>false</enabled></management>\n"); + out.write("\t<security>\n"); + out.write("\t\t<principal-databases>\n"); + out.write("\t\t\t<principal-database>\n"); + out.write("\t\t\t\t<name>passwordfile</name>\n"); + out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n"); + out.write("\t\t\t\t<attributes>\n"); + out.write("\t\t\t\t\t<attribute>\n"); + out.write("\t\t\t\t\t\t<name>passwordFile</name>\n"); + out.write("\t\t\t\t\t\t<value>/dev/null</value>\n"); + out.write("\t\t\t\t\t</attribute>\n"); + out.write("\t\t\t\t</attributes>\n"); + out.write("\t\t\t</principal-database>\n"); + out.write("\t\t</principal-databases>\n"); + out.write("\t\t<jmx>\n"); + out.write("\t\t\t<access>/dev/null</access>\n"); + out.write("\t\t\t<principal-database>passwordfile</principal-database>\n"); + out.write("\t\t</jmx>\n"); + out.write("\t\t<firewall>\n"); + out.write("\t\t\t<rule access=\"allow\" network=\"127.0.0.1\"/>"); + out.write("\t\t</firewall>\n"); + out.write("\t</security>\n"); out.write("\t<virtualhosts>\n"); out.write("\t\t<virtualhost>\n"); out.write("\t\t\t<name>test</name>\n"); + out.write("\t\t<test> \n"); + out.write("\t\t\t<exchanges>\n"); + out.write("\t\t\t\t<exchange>\n"); + out.write("\t\t\t\t\t<type>topic</type>\n"); + out.write("\t\t\t\t\t<name>test.topic</name>\n"); + out.write("\t\t\t\t\t<durable>true</durable>\n"); + out.write("\t\t\t\t</exchange>\n"); + out.write("\t\tt</exchanges>\n"); + out.write("\t\t</test> \n"); + out.write("\t\t</virtualhost>\n"); + out.write("\t\t<virtualhost>\n"); + out.write("\t\t\t<name>fish</name>\n"); + out.write("\t\t<fish> \n"); + out.write("\t\t\t<exchanges>\n"); + out.write("\t\t\t\t<exchange>\n"); + out.write("\t\t\t\t\t<type>topic</type>\n"); + out.write("\t\t\t\t\t<name>fish.topic</name>\n"); + out.write("\t\t\t\t\t<durable>false</durable>\n"); + out.write("\t\t\t\t</exchange>\n"); + out.write("\t\tt</exchanges>\n"); + out.write("\t\t</fish> \n"); out.write("\t\t</virtualhost>\n"); out.write("\t</virtualhosts>\n"); out.write("</broker>\n"); out.close(); } + private void writeFirewallVhostsFile(File vhostsFile, boolean allow) throws IOException + { + FileWriter out = new FileWriter(vhostsFile); + String ipAddr = "127.0.0.1"; // FIXME: get this from InetAddress.getLocalHost().getAddress() ? + out.write("<virtualhosts><virtualhost>"); + out.write("<name>test</name>"); + out.write("<test>"); + out.write("<security><firewall>"); + out.write("<rule access=\""+((allow) ? "allow" : "deny")+"\" network=\""+ipAddr +"\"/>"); + out.write("</firewall></security>"); + out.write("</test>"); + out.write("</virtualhost></virtualhosts>"); + out.close(); + } + public void testCombinedConfigurationFirewallReload() throws Exception { // Write out config @@ -1041,42 +1130,538 @@ public class ServerConfigurationTest extends TestCase } } - public void testnewParserOutputVsOldParserOutput() throws ConfigurationException - { - String configDir = System.getProperty("QPID_HOME")+"/etc"; + private void writeVirtualHostsFile(File vhostsFile, String name) throws IOException { + FileWriter out = new FileWriter(vhostsFile); + out.write("<virtualhosts>\n"); + out.write("\t<virtualhost>\n"); + out.write(String.format("\t\t<name>%s</name>\n", name)); + out.write(String.format("\t\t<%s>\n", name)); + out.write("\t\t\t<exchanges>\n"); + out.write("\t\t\t\t<exchange>\n"); + out.write("\t\t\t\t\t<type>topic</type>\n"); + out.write("\t\t\t\t\t<name>test.topic</name>\n"); + out.write("\t\t\t\t\t<durable>true</durable>\n"); + out.write("\t\t\t\t</exchange>\n"); + out.write("\t\tt</exchanges>\n"); + out.write(String.format("\t\t</%s>\n", name)); + out.write("\t</virtualhost>\n"); + out.write("</virtualhosts>\n"); + out.close(); + } - XMLConfiguration oldConfig = new XMLConfiguration(configDir +"/config-systests-ServerConfigurationTest-Old.xml"); - Configuration newConfig = new ServerConfiguration(new File(configDir+"/config-systests-ServerConfigurationTest-New.xml")).getConfig(); + private void writeMultiVirtualHostsFile(File vhostsFile) throws IOException { + FileWriter out = new FileWriter(vhostsFile); + out.write("<virtualhosts>\n"); + out.write("\t<virtualhost>\n"); + out.write("\t\t<name>topic</name>\n"); + out.write("\t\t<topic>\n"); + out.write("\t\t\t<exchanges>\n"); + out.write("\t\t\t\t<exchange>\n"); + out.write("\t\t\t\t\t<type>topic</type>\n"); + out.write("\t\t\t\t\t<name>test.topic</name>\n"); + out.write("\t\t\t\t\t<durable>true</durable>\n"); + out.write("\t\t\t\t</exchange>\n"); + out.write("\t\tt</exchanges>\n"); + out.write("\t\t</topic>\n"); + out.write("\t</virtualhost>\n"); + out.write("\t<virtualhost>\n"); + out.write("\t\t<name>fanout</name>\n"); + out.write("\t\t<fanout>\n"); + out.write("\t\t\t<exchanges>\n"); + out.write("\t\t\t\t<exchange>\n"); + out.write("\t\t\t\t\t<type>fanout</type>\n"); + out.write("\t\t\t\t\t<name>test.fanout</name>\n"); + out.write("\t\t\t\t\t<durable>true</durable>\n"); + out.write("\t\t\t\t</exchange>\n"); + out.write("\t\tt</exchanges>\n"); + out.write("\t\t</fanout>\n"); + out.write("\t</virtualhost>\n"); + out.write("</virtualhosts>\n"); + out.close(); + } - Iterator xmlKeys = oldConfig.getKeys(); - while (xmlKeys.hasNext()) + private void writeMultipleVhostsConfigFile(File mainFile, File[] vhostsFileArray) throws IOException { + FileWriter out = new FileWriter(mainFile); + out.write("<broker>\n"); + out.write("\t<management><enabled>false</enabled></management>\n"); + out.write("\t<security>\n"); + out.write("\t\t<principal-databases>\n"); + out.write("\t\t\t<principal-database>\n"); + out.write("\t\t\t\t<name>passwordfile</name>\n"); + out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n"); + out.write("\t\t\t\t<attributes>\n"); + out.write("\t\t\t\t\t<attribute>\n"); + out.write("\t\t\t\t\t\t<name>passwordFile</name>\n"); + out.write("\t\t\t\t\t\t<value>/dev/null</value>\n"); + out.write("\t\t\t\t\t</attribute>\n"); + out.write("\t\t\t\t</attributes>\n"); + out.write("\t\t\t</principal-database>\n"); + out.write("\t\t</principal-databases>\n"); + out.write("\t\t<jmx>\n"); + out.write("\t\t\t<access>/dev/null</access>\n"); + out.write("\t\t\t<principal-database>passwordfile</principal-database>\n"); + out.write("\t\t</jmx>\n"); + out.write("\t\t<firewall>\n"); + out.write("\t\t\t<rule access=\"allow\" network=\"127.0.0.1\"/>"); + out.write("\t\t</firewall>\n"); + out.write("\t</security>\n"); + for (File vhostsFile : vhostsFileArray) { - String key = (String) xmlKeys.next(); - assertEquals("Incorrect value for "+key, oldConfig.getProperty(key), newConfig.getProperty(key)); + out.write("\t<virtualhosts>"+vhostsFile.getAbsolutePath()+"</virtualhosts>\n"); } + out.write("</broker>\n"); + out.close(); } + private void writeCombinedConfigFile(File mainFile, File fileA, File fileB) throws Exception + { + FileWriter out = new FileWriter(mainFile); + out.write("<configuration><system/>"); + out.write("<xml fileName=\"" + fileA.getAbsolutePath() + "\"/>"); + out.write("<xml fileName=\"" + fileB.getAbsolutePath() + "\"/>"); + out.write("</configuration>"); + out.close(); + } + + /** + * Test that configuration loads correctly when virtual hosts are specified in the main + * configuration file only. + * <p> + * Test for QPID-2361 + */ + public void testInternalVirtualhostConfigFile() throws Exception + { + // Write out config + File mainFile = File.createTempFile(getClass().getName(), "config"); + mainFile.deleteOnExit(); + writeConfigFile(mainFile, false, true, null, "test"); - public void testNoVirtualhostXMLFile() throws Exception + // Load config + ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile); + ApplicationRegistry.initialise(reg, 1); + + // Test config + VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry(); + VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test"); + Exchange exchange = virtualHost.getExchangeRegistry().getExchange(new AMQShortString("test.topic")); + + assertEquals("Incorrect virtualhost count", 1, virtualHostRegistry.getVirtualHosts().size()); + assertEquals("Incorrect virtualhost name", "test", virtualHost.getName()); + assertEquals("Incorrect exchange type", "topic", exchange.getType().getName().toString()); + } + + /** + * Test that configuration loads correctly when virtual hosts are specified in an external + * configuration file only. + * <p> + * Test for QPID-2361 + */ + public void testExternalVirtualhostXMLFile() throws Exception { - int REGISTRY=1; + // Write out config + File mainFile = File.createTempFile(getClass().getName(), "config"); + mainFile.deleteOnExit(); + File vhostsFile = File.createTempFile(getClass().getName(), "vhosts"); + vhostsFile.deleteOnExit(); + writeConfigFile(mainFile, false, false, vhostsFile, null); + writeVirtualHostsFile(vhostsFile, "test"); + + // Load config + ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile); + ApplicationRegistry.initialise(reg, 1); - File configFile = new File(System.getProperty("QPID_HOME")+"/etc/config.xml"); - assertTrue(configFile.exists()); + // Test config + VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry(); + VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test"); + Exchange exchange = virtualHost.getExchangeRegistry().getExchange(new AMQShortString("test.topic")); + assertEquals("Incorrect virtualhost count", 1, virtualHostRegistry.getVirtualHosts().size()); + assertEquals("Incorrect virtualhost name", "test", virtualHost.getName()); + assertEquals("Incorrect exchange type", "topic", exchange.getType().getName().toString()); + } + + /** + * Test that configuration loads correctly when virtual hosts are specified in an external + * configuration file only, with two vhosts that have different properties. + * <p> + * Test for QPID-2361 + */ + public void testExternalMultiVirtualhostXMLFile() throws Exception + { + // Write out vhosts + File vhostsFile = File.createTempFile(getClass().getName(), "vhosts-multi"); + vhostsFile.deleteOnExit(); + writeMultiVirtualHostsFile(vhostsFile); + + // Write out config + File mainFile = File.createTempFile(getClass().getName(), "config"); + mainFile.deleteOnExit(); + writeConfigFile(mainFile, false, false, vhostsFile, null); + + // Load config + ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile); + ApplicationRegistry.initialise(reg, 1); + + // Test config + VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry(); + + assertEquals("Incorrect virtualhost count", 2, virtualHostRegistry.getVirtualHosts().size()); + + // test topic host + VirtualHost topicVirtualHost = virtualHostRegistry.getVirtualHost("topic"); + Exchange topicExchange = topicVirtualHost.getExchangeRegistry().getExchange(new AMQShortString("test.topic")); + + assertEquals("Incorrect topic virtualhost name", "topic", topicVirtualHost.getName()); + assertEquals("Incorrect topic exchange type", "topic", topicExchange.getType().getName().toString()); + + // Test fanout host + VirtualHost fanoutVirtualHost = virtualHostRegistry.getVirtualHost("fanout"); + Exchange fanoutExchange = fanoutVirtualHost.getExchangeRegistry().getExchange(new AMQShortString("test.fanout")); + + assertEquals("Incorrect fanout virtualhost name", "fanout", fanoutVirtualHost.getName()); + assertEquals("Incorrect fanout exchange type", "fanout", fanoutExchange.getType().getName().toString()); + } + + /** + * Test that configuration does not load when virtual hosts are specified in both the main + * configuration file and an external file. Should throw a {@link ConfigurationException}. + * <p> + * Test for QPID-2361 + */ + public void testInternalAndExternalVirtualhostXMLFile() throws Exception + { + // Write out vhosts + File vhostsFile = File.createTempFile(getClass().getName(), "vhosts"); + vhostsFile.deleteOnExit(); + writeVirtualHostsFile(vhostsFile, "test"); + + // Write out config + File mainFile = File.createTempFile(getClass().getName(), "config"); + mainFile.deleteOnExit(); + writeConfigFile(mainFile, false, true, vhostsFile, "test"); + + // Load config try { - ApplicationRegistry.initialise(new ConfigurationFileApplicationRegistry(configFile), REGISTRY); - - VirtualHostRegistry virtualHostRegistry = ApplicationRegistry.getInstance(REGISTRY).getVirtualHostRegistry(); + @SuppressWarnings("unused") + ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile); + fail("Different virtualhost XML configurations not allowed"); + } + catch (ConfigurationException ce) + { + assertEquals("Incorrect error message", "Only one of external or embedded virtualhosts configuration allowed.", ce.getMessage()); + } + } + + /** + * Test that configuration does not load when virtual hosts are specified in multiple external + * files. Should throw a {@link ConfigurationException}. + * <p> + * Test for QPID-2361 + */ + public void testMultipleInternalVirtualhostXMLFile() throws Exception + { + // Write out vhosts + File vhostsFileOne = File.createTempFile(getClass().getName(), "vhosts-one"); + vhostsFileOne.deleteOnExit(); + writeVirtualHostsFile(vhostsFileOne, "one"); + File vhostsFileTwo = File.createTempFile(getClass().getName(), "vhosts-two"); + vhostsFileTwo.deleteOnExit(); + writeVirtualHostsFile(vhostsFileTwo, "two"); + + // Write out config + File mainFile = File.createTempFile(getClass().getName(), "config"); + mainFile.deleteOnExit(); + writeMultipleVhostsConfigFile(mainFile, new File[] { vhostsFileOne, vhostsFileTwo }); + + // Load config + try + { + @SuppressWarnings("unused") + ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile); + fail("Multiple virtualhost XML configurations not allowed"); + } + catch (ConfigurationException ce) + { + assertEquals("Incorrect error message", + "Only one external virtualhosts configuration file allowed, multiple filenames found.", + ce.getMessage()); + } + } + + /** + * Test that configuration loads correctly when virtual hosts are specified in an external + * configuration file in the first of two configurations and embedded in the second. This + * will throe a {@link ConfigurationException} since the configurations have different + * types. + * <p> + * Test for QPID-2361 + */ + public void testCombinedDifferentVirtualhostConfig() throws Exception + { + // Write out vhosts config + File vhostsFile = File.createTempFile(getClass().getName(), "vhosts"); + vhostsFile.deleteOnExit(); + writeVirtualHostsFile(vhostsFile, "external"); + + // Write out combined config file + File mainFile = File.createTempFile(getClass().getName(), "main"); + File fileA = File.createTempFile(getClass().getName(), "a"); + File fileB = File.createTempFile(getClass().getName(), "b"); + mainFile.deleteOnExit(); + fileA.deleteOnExit(); + fileB.deleteOnExit(); + writeCombinedConfigFile(mainFile, fileA, fileB); + writeConfigFile(fileA, false, false, vhostsFile, null); + writeConfigFile(fileB, false); - assertEquals("Incorrect virtualhost count", 3 , virtualHostRegistry.getVirtualHosts().size()); + // Load config + try + { + @SuppressWarnings("unused") + ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile()); + fail("Different virtualhost XML configurations not allowed"); } - finally + catch (ConfigurationException ce) { - ApplicationRegistry.remove(REGISTRY); + assertEquals("Incorrect error message", "Only one of external or embedded virtualhosts configuration allowed.", ce.getMessage()); } } + /** + * Test that configuration loads correctly when virtual hosts are specified two overriding configurations + * each with an embedded virtualhost section. The first configuration section should be used. + * <p> + * Test for QPID-2361 + */ + public void testCombinedConfigEmbeddedVirtualhost() throws Exception + { + // Write out combined config file + File mainFile = File.createTempFile(getClass().getName(), "main"); + File fileA = File.createTempFile(getClass().getName(), "a"); + File fileB = File.createTempFile(getClass().getName(), "b"); + mainFile.deleteOnExit(); + fileA.deleteOnExit(); + fileB.deleteOnExit(); + writeCombinedConfigFile(mainFile, fileA, fileB); + writeConfigFile(fileA, false, true, null, "a"); + writeConfigFile(fileB, false, true, null, "b"); + + // Load config + ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile()); + + // Test config + VirtualHostConfiguration virtualHost = config.getVirtualHostConfig("a"); + + assertEquals("Incorrect virtualhost count", 1, config.getVirtualHosts().length); + assertEquals("Incorrect virtualhost name", "a", virtualHost.getName()); + } + + /** + * Test that configuration loads correctly when virtual hosts are specified two overriding configurations + * each with an external virtualhost XML file. The first configuration file should be used. + * <p> + * Test for QPID-2361 + */ + public void testCombinedConfigExternalVirtualhost() throws Exception + { + // Write out vhosts config + File vhostsOne = File.createTempFile(getClass().getName(), "vhosts-one"); + vhostsOne.deleteOnExit(); + writeVirtualHostsFile(vhostsOne, "one"); + File vhostsTwo = File.createTempFile(getClass().getName(), "vhosts-two"); + vhostsTwo.deleteOnExit(); + writeVirtualHostsFile(vhostsTwo, "two"); + + // Write out combined config file + File mainFile = File.createTempFile(getClass().getName(), "main"); + File fileA = File.createTempFile(getClass().getName(), "a"); + File fileB = File.createTempFile(getClass().getName(), "b"); + mainFile.deleteOnExit(); + fileA.deleteOnExit(); + fileB.deleteOnExit(); + writeCombinedConfigFile(mainFile, fileA, fileB); + writeConfigFile(fileA, false, false, vhostsOne, null); + writeConfigFile(fileB, false, false, vhostsTwo, null); + + // Load config + ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile()); + + // Test config + VirtualHostConfiguration virtualHost = config.getVirtualHostConfig("one"); + + assertEquals("Incorrect virtualhost count", 1, config.getVirtualHosts().length); + assertEquals("Incorrect virtualhost name", "one", virtualHost.getName()); + } + + /** + * Test that configuration loads correctly when an overriding virtualhost configuration resets + * a property of an embedded virtualhost section. The overriding configuration property value + * should be used. + * <p> + * Test for QPID-2361 + */ + public void testCombinedConfigEmbeddedVirtualhostOverride() throws Exception + { + // Write out combined config file + File mainFile = File.createTempFile(getClass().getName(), "main"); + File fileA = File.createTempFile(getClass().getName(), "override"); + File fileB = File.createTempFile(getClass().getName(), "config"); + mainFile.deleteOnExit(); + fileA.deleteOnExit(); + fileB.deleteOnExit(); + writeCombinedConfigFile(mainFile, fileA, fileB); + writeTestFishConfigFile(fileB); + + // Write out overriding virtualhosts section + FileWriter out = new FileWriter(fileA); + out.write("<broker>\n"); + out.write("<virtualhosts>\n"); + out.write("\t<virtualhost>\n"); + out.write("\t\t<test>\n"); + out.write("\t\t\t<exchanges>\n"); + out.write("\t\t\t\t<exchange>\n"); + out.write("\t\t\t\t\t<durable>false</durable>\n"); + out.write("\t\t\t\t</exchange>\n"); + out.write("\t\tt</exchanges>\n"); + out.write("\t\t</test>\n"); + out.write("\t\t<fish>\n"); + out.write("\t\t\t<exchanges>\n"); + out.write("\t\t\t\t<exchange>\n"); + out.write("\t\t\t\t\t<durable>true</durable>\n"); + out.write("\t\t\t\t</exchange>\n"); + out.write("\t\tt</exchanges>\n"); + out.write("\t\t</fish>\n"); + out.write("\t</virtualhost>\n"); + out.write("</virtualhosts>\n"); + out.write("</broker>\n"); + out.close(); + + // Load config + ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile()); + + // Test config + VirtualHostConfiguration testHost = config.getVirtualHostConfig("test"); + ExchangeConfiguration testExchange = testHost.getExchangeConfiguration("test.topic"); + VirtualHostConfiguration fishHost = config.getVirtualHostConfig("fish"); + ExchangeConfiguration fishExchange = fishHost.getExchangeConfiguration("fish.topic"); + + assertEquals("Incorrect virtualhost count", 2, config.getVirtualHosts().length); + assertEquals("Incorrect virtualhost name", "test", testHost.getName()); + assertFalse("Incorrect exchange durable property", testExchange.getDurable()); + assertEquals("Incorrect virtualhost name", "fish", fishHost.getName()); + assertTrue("Incorrect exchange durable property", fishExchange.getDurable()); + } + + /** + * Test that configuration loads correctly when virtual hosts are specified in an external + * configuration file only. + * <p> + * Test for QPID-2360 + */ + public void testExternalFirewallVirtualhostXMLFile() throws Exception + { + // Write out config + File mainFile = File.createTempFile(getClass().getName(), "config"); + mainFile.deleteOnExit(); + File vhostsFile = File.createTempFile(getClass().getName(), "vhosts"); + vhostsFile.deleteOnExit(); + writeConfigFile(mainFile, false, false, vhostsFile, null); + writeFirewallVhostsFile(vhostsFile, false); + + // Load config + ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile); + ApplicationRegistry.initialise(reg, 1); + // Test config + VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry(); + VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test"); + + assertEquals("Incorrect virtualhost count", 1, virtualHostRegistry.getVirtualHosts().size()); + assertEquals("Incorrect virtualhost name", "test", virtualHost.getName()); + } + + /** + * Test that configuration loads correctly when the virtualhost configuration is a set of overriding + * configuration files that resets a property of a virtualhost. The opmost overriding configuration + * property value should be used. + * <p> + * Test for QPID-2361 + */ + public void testCombinedVirtualhostOverride() throws Exception + { + // Write out combined config file + File mainFile = File.createTempFile(getClass().getName(), "main"); + File vhostsFile = File.createTempFile(getClass().getName(), "vhosts"); + File fileA = File.createTempFile(getClass().getName(), "vhosts-override"); + File fileB = File.createTempFile(getClass().getName(), "vhosts-base"); + mainFile.deleteOnExit(); + vhostsFile.deleteOnExit(); + fileA.deleteOnExit(); + fileB.deleteOnExit(); + writeConfigFile(mainFile, true, false, vhostsFile, null); + writeCombinedConfigFile(vhostsFile, fileA, fileB); + + // Write out overriding virtualhosts sections + FileWriter out = new FileWriter(fileA); + out.write("<virtualhosts>\n"); + out.write("\t<virtualhost>\n"); + out.write("\t\t<test>\n"); + out.write("\t\t\t<exchanges>\n"); + out.write("\t\t\t\t<exchange>\n"); + out.write("\t\t\t\t\t<durable>false</durable>\n"); + out.write("\t\t\t\t</exchange>\n"); + out.write("\t\tt</exchanges>\n"); + out.write("\t\t</test>\n"); + out.write("\t</virtualhost>\n"); + out.write("</virtualhosts>\n"); + out.close(); + writeVirtualHostsFile(fileB, "test"); + + // Load config + ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile()); + + // Test config + VirtualHostConfiguration testHost = config.getVirtualHostConfig("test"); + ExchangeConfiguration testExchange = testHost.getExchangeConfiguration("test.topic"); + + assertEquals("Incorrect virtualhost count", 1, config.getVirtualHosts().length); + assertEquals("Incorrect virtualhost name", "test", testHost.getName()); + assertFalse("Incorrect exchange durable property", testExchange.getDurable()); + } + + /** + * Test that configuration loads correctly when the virtualhost configuration is a set of overriding + * configuration files that define multiple virtualhosts, one per file. Only the virtualhosts defined in + * the topmost file should be used. + * <p> + * Test for QPID-2361 + */ + public void testCombinedMultipleVirtualhosts() throws Exception + { + // Write out combined config file + File mainFile = File.createTempFile(getClass().getName(), "main"); + File vhostsFile = File.createTempFile(getClass().getName(), "vhosts"); + File fileA = File.createTempFile(getClass().getName(), "vhosts-one"); + File fileB = File.createTempFile(getClass().getName(), "vhosts-two"); + mainFile.deleteOnExit(); + vhostsFile.deleteOnExit(); + fileA.deleteOnExit(); + fileB.deleteOnExit(); + writeConfigFile(mainFile, true, false, vhostsFile, null); + writeCombinedConfigFile(vhostsFile, fileA, fileB); + + // Write both virtualhosts definitions + writeVirtualHostsFile(fileA, "test-one"); + writeVirtualHostsFile(fileB, "test-two"); + + // Load config + ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile()); + + // Test config + VirtualHostConfiguration oneHost = config.getVirtualHostConfig("test-one"); + + assertEquals("Incorrect virtualhost count", 1, config.getVirtualHosts().length); + assertEquals("Incorrect virtualhost name", "test-one", oneHost.getName()); + } } |
