ARTEMIS-801 Dealing properly with Spaces and Special Characters on broker

This commit is contained in:
Clebert Suconic 2016-10-17 18:27:58 -04:00
parent c183ed9cc1
commit 6483123417
15 changed files with 191 additions and 111 deletions

View File

@ -98,6 +98,15 @@
<version>${project.version}</version> <version>${project.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-commons</artifactId>
<version>${project.version}</version>
<scope>test</scope>
<type>test-jar</type>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -17,6 +17,7 @@
package org.apache.activemq.artemis.cli.commands; package org.apache.activemq.artemis.cli.commands;
import java.io.File; import java.io.File;
import java.net.URI;
import io.airlift.airline.Option; import io.airlift.airline.Option;
@ -29,6 +30,8 @@ public abstract class ActionAbstract implements Action {
private String brokerHome; private String brokerHome;
private URI brokerInstanceURI;
protected ActionContext context; protected ActionContext context;
@Override @Override
@ -62,6 +65,25 @@ public abstract class ActionAbstract implements Action {
return brokerInstance; return brokerInstance;
} }
public URI getBrokerURIInstance() {
if (brokerInstanceURI == null) {
String instanceProperty = getBrokerInstance();
File artemisInstance = null;
if (artemisInstance == null && instanceProperty != null) {
artemisInstance = new File(instanceProperty);
}
if (artemisInstance != null) {
brokerInstanceURI = artemisInstance.toURI();
}
}
return brokerInstanceURI;
}
@Override @Override
public String getBrokerHome() { public String getBrokerHome() {
if (brokerHome == null) { if (brokerHome == null) {

View File

@ -87,7 +87,7 @@ public abstract class Configurable extends ActionAbstract {
fileConfiguration = new FileConfiguration(); fileConfiguration = new FileConfiguration();
FileJMSConfiguration jmsConfiguration = new FileJMSConfiguration(); FileJMSConfiguration jmsConfiguration = new FileJMSConfiguration();
String serverConfiguration = getBrokerDTO().server.configuration; String serverConfiguration = getBrokerDTO().server.getConfigurationURI().toASCIIString();
FileDeploymentManager fileDeploymentManager = new FileDeploymentManager(serverConfiguration); FileDeploymentManager fileDeploymentManager = new FileDeploymentManager(serverConfiguration);
fileDeploymentManager.addDeployable(fileConfiguration).addDeployable(jmsConfiguration); fileDeploymentManager.addDeployable(fileConfiguration).addDeployable(jmsConfiguration);
fileDeploymentManager.readConfiguration(); fileDeploymentManager.readConfiguration();
@ -102,7 +102,7 @@ public abstract class Configurable extends ActionAbstract {
if (brokerDTO == null) { if (brokerDTO == null) {
getConfiguration(); getConfiguration();
brokerDTO = BrokerFactory.createBrokerConfiguration(configuration, getBrokerHome(), getBrokerInstance()); brokerDTO = BrokerFactory.createBrokerConfiguration(configuration, getBrokerHome(), getBrokerInstance(), getBrokerURIInstance());
if (brokerConfig != null) { if (brokerConfig != null) {
if (!brokerConfig.startsWith("file:")) { if (!brokerConfig.startsWith("file:")) {

View File

@ -16,7 +16,6 @@
*/ */
package org.apache.activemq.artemis.factory; package org.apache.activemq.artemis.factory;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
@ -30,12 +29,13 @@ import org.apache.activemq.artemis.utils.FactoryFinder;
public class BrokerFactory { public class BrokerFactory {
public static BrokerDTO createBrokerConfiguration(URI configURI) throws Exception { public static BrokerDTO createBrokerConfiguration(URI configURI) throws Exception {
return createBrokerConfiguration(configURI, null, null); return createBrokerConfiguration(configURI, null, null, null);
} }
public static BrokerDTO createBrokerConfiguration(URI configURI, public static BrokerDTO createBrokerConfiguration(URI configURI,
String artemisHome, String artemisHome,
String artemisInstance) throws Exception { String artemisInstance,
URI artemisURIInstance) throws Exception {
if (configURI.getScheme() == null) { if (configURI.getScheme() == null) {
throw new ConfigurationException("Invalid configuration URI, no scheme specified: " + configURI); throw new ConfigurationException("Invalid configuration URI, no scheme specified: " + configURI);
} }
@ -48,25 +48,18 @@ public class BrokerFactory {
throw new ConfigurationException("Invalid configuration URI, can't find configuration scheme: " + configURI.getScheme()); throw new ConfigurationException("Invalid configuration URI, can't find configuration scheme: " + configURI.getScheme());
} }
return factory.createBroker(configURI, artemisHome, artemisInstance); return factory.createBroker(configURI, artemisHome, artemisInstance, artemisURIInstance);
} }
public static BrokerDTO createBrokerConfiguration(String configuration) throws Exception { public static BrokerDTO createBrokerConfiguration(String configuration) throws Exception {
return createBrokerConfiguration(new URI(configuration), null, null); return createBrokerConfiguration(new URI(configuration), null, null, null);
} }
public static BrokerDTO createBrokerConfiguration(String configuration, public static BrokerDTO createBrokerConfiguration(String configuration,
String artemisHome, String artemisHome,
String artemisInstance) throws Exception { String artemisInstance,
return createBrokerConfiguration(new URI(configuration), artemisHome, artemisInstance); URI artemisURIInstance) throws Exception {
} return createBrokerConfiguration(new URI(configuration), artemisHome, artemisInstance, artemisURIInstance);
static String fixupFileURI(String value) {
if (value != null && value.startsWith("file:")) {
value = value.substring("file:".length());
value = new File(value).toURI().toString();
}
return value;
} }
public static Broker createServer(ServerDTO brokerDTO, ActiveMQSecurityManager security) throws Exception { public static Broker createServer(ServerDTO brokerDTO, ActiveMQSecurityManager security) throws Exception {

View File

@ -24,5 +24,5 @@ public interface BrokerFactoryHandler {
BrokerDTO createBroker(URI brokerURI) throws Exception; BrokerDTO createBroker(URI brokerURI) throws Exception;
BrokerDTO createBroker(URI brokerURI, String artemisHome, String artemisInstance) throws Exception; BrokerDTO createBroker(URI brokerURI, String artemisHome, String artemisInstance, URI artemisURIInstance) throws Exception;
} }

View File

@ -27,15 +27,15 @@ public class XmlBrokerFactoryHandler implements BrokerFactoryHandler {
@Override @Override
public BrokerDTO createBroker(URI brokerURI) throws Exception { public BrokerDTO createBroker(URI brokerURI) throws Exception {
return createBroker(brokerURI, null, null); return createBroker(brokerURI, null, null, null);
} }
@Override @Override
public BrokerDTO createBroker(URI brokerURI, String artemisHome, String artemisInstance) throws Exception { public BrokerDTO createBroker(URI brokerURI, String artemisHome, String artemisInstance, URI artemisURIInstance) throws Exception {
File file = new File(brokerURI.getSchemeSpecificPart()); File file = new File(brokerURI.getSchemeSpecificPart());
if (!file.exists()) { if (!file.exists()) {
throw new ConfigurationException("Invalid configuration URI, can't find file: " + file.getName()); throw new ConfigurationException("Invalid configuration URI, can't find file: " + file.getName());
} }
return XmlUtil.decode(BrokerDTO.class, file, artemisHome, artemisInstance); return XmlUtil.decode(BrokerDTO.class, file, artemisHome, artemisInstance, artemisURIInstance);
} }
} }

View File

@ -20,7 +20,9 @@
<jaas-security domain="activemq"/> <jaas-security domain="activemq"/>
<server configuration="file:${artemis.instance}/etc/broker.xml"/> <!-- artemis.URI.instance is parsed from artemis.instance by the CLI startup.
This is to avoid situations where you could have spaces or special characters on this URI -->
<server configuration="${artemis.URI.instance}/etc/broker.xml"/>
${bootstrap-web-settings} ${bootstrap-web-settings}

View File

@ -29,6 +29,7 @@ import java.nio.file.Files;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
import org.apache.activemq.artemis.api.core.client.ClientSession; import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory; import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.api.core.client.ServerLocator; import org.apache.activemq.artemis.api.core.client.ServerLocator;
@ -42,6 +43,8 @@ import org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl;
import org.apache.activemq.artemis.jlibaio.LibaioContext; import org.apache.activemq.artemis.jlibaio.LibaioContext;
import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory; import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
import org.apache.activemq.artemis.jms.client.ActiveMQDestination; import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
import org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoader;
import org.apache.activemq.artemis.utils.ThreadLeakCheckRule;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
@ -60,6 +63,9 @@ public class ArtemisTest {
@Rule @Rule
public TemporaryFolder temporaryFolder; public TemporaryFolder temporaryFolder;
@Rule
public ThreadLeakCheckRule leakCheckRule = new ThreadLeakCheckRule();
private String original = System.getProperty("java.security.auth.login.config"); private String original = System.getProperty("java.security.auth.login.config");
public ArtemisTest() { public ArtemisTest() {
@ -69,12 +75,23 @@ public class ArtemisTest {
} }
@Before @Before
public void setup() { public void setup() throws Exception {
System.setProperty("java.security.auth.login.config", temporaryFolder.getRoot().getAbsolutePath() + "/etc/login.config"); setupAuth();
Run.setEmbedded(true);
PropertiesLoader.resetUsersAndGroupsCache();
}
public void setupAuth() throws Exception {
setupAuth(temporaryFolder.getRoot());
}
public void setupAuth(File folder) throws Exception {
System.setProperty("java.security.auth.login.config", folder.getAbsolutePath() + "/etc/login.config");
} }
@After @After
public void cleanup() { public void cleanup() {
ActiveMQClient.clearThreadPools();
System.clearProperty("artemis.instance"); System.clearProperty("artemis.instance");
Run.setEmbedded(false); Run.setEmbedded(false);
@ -123,6 +140,7 @@ public class ArtemisTest {
@Test @Test
public void testWebConfig() throws Exception { public void testWebConfig() throws Exception {
setupAuth();
Run.setEmbedded(true); Run.setEmbedded(true);
//instance1: default using http //instance1: default using http
File instance1 = new File(temporaryFolder.getRoot(), "instance1"); File instance1 = new File(temporaryFolder.getRoot(), "instance1");
@ -196,13 +214,34 @@ public class ArtemisTest {
@Test @Test
public void testSimpleRun() throws Exception { public void testSimpleRun() throws Exception {
testSimpleRun("server");
}
@Test
public void testWeirdCharacter() throws Exception {
testSimpleRun("test%26%26x86_6");
}
@Test
public void testSpaces() throws Exception {
testSimpleRun("with space");
}
public void testSimpleRun(String folderName) throws Exception {
File instanceFolder = temporaryFolder.newFolder(folderName);
setupAuth(instanceFolder);
String queues = "q1,t2"; String queues = "q1,t2";
String topics = "t1,t2"; String topics = "t1,t2";
// This is usually set when run from the command line via artemis.profile // This is usually set when run from the command line via artemis.profile
Run.setEmbedded(true); Run.setEmbedded(true);
Artemis.main("create", temporaryFolder.getRoot().getAbsolutePath(), "--force", "--silent", "--no-web", "--queues", queues, "--topics", topics, "--no-autotune", "--require-login"); Artemis.main("create", instanceFolder.getAbsolutePath(), "--force", "--silent", "--no-web", "--queues", queues, "--topics", topics, "--no-autotune", "--require-login");
System.setProperty("artemis.instance", temporaryFolder.getRoot().getAbsolutePath()); System.setProperty("artemis.instance", instanceFolder.getAbsolutePath());
// Some exceptions may happen on the initialization, but they should be ok on start the basic core protocol // Some exceptions may happen on the initialization, but they should be ok on start the basic core protocol
Artemis.internalExecute("run"); Artemis.internalExecute("run");
@ -268,24 +307,6 @@ public class ArtemisTest {
} }
} }
@Test
public void testAnonymousAutoCreate() throws Exception {
// This is usually set when run from the command line via artemis.profile
Run.setEmbedded(true);
Artemis.main("create", temporaryFolder.getRoot().getAbsolutePath(), "--force", "--silent", "--no-web", "--no-autotune", "--allow-anonymous", "--user", "a", "--password", "a", "--role", "a");
System.setProperty("artemis.instance", temporaryFolder.getRoot().getAbsolutePath());
// Some exceptions may happen on the initialization, but they should be ok on start the basic core protocol
Artemis.internalExecute("run");
try {
Assert.assertEquals(Integer.valueOf(100), Artemis.internalExecute("producer", "--message-count", "100"));
Assert.assertEquals(Integer.valueOf(100), Artemis.internalExecute("consumer", "--message-count", "100"));
} finally {
stopServer();
}
}
private void testCli(String... args) { private void testCli(String... args) {
try { try {
Artemis.main(args); Artemis.main(args);

View File

@ -16,6 +16,7 @@
*/ */
package org.apache.activemq.cli.test; package org.apache.activemq.cli.test;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -104,7 +105,8 @@ public class FileBrokerTest {
Assert.assertNotNull(activeMQServer); Assert.assertNotNull(activeMQServer);
Assert.assertTrue(activeMQServer.isStarted()); Assert.assertTrue(activeMQServer.isStarted());
Assert.assertTrue(broker.isStarted()); Assert.assertTrue(broker.isStarted());
path = activeMQServer.getConfiguration().getConfigurationUrl().getPath(); File file = new File(activeMQServer.getConfiguration().getConfigurationUrl().toURI());
path = file.getPath();
Assert.assertNotNull(activeMQServer.getConfiguration().getConfigurationUrl()); Assert.assertNotNull(activeMQServer.getConfiguration().getConfigurationUrl());
Thread.sleep(activeMQServer.getConfiguration().getConfigurationFileRefreshPeriod() * 2); Thread.sleep(activeMQServer.getConfiguration().getConfigurationFileRefreshPeriod() * 2);

View File

@ -0,0 +1,72 @@
#!/usr/bin/env sh
# 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.
# This script will validate the distribution works with folders with spaces on Linux machines
echo validating instalation on $1
rm -rf target
mkdir target
mkdir target/"$1"
# Setting the script to fail if anything goes wrong
set -e
export TEST_TARGET="./target/$1"
. ./installHome.sh
export ARTEMIS_INSTANCE="$CURRENT_DIR/target/$1/artemis_instance"
echo home used is $ARTEMIS_HOME
echo artemis instance is $ARTEMIS_HOME
cd "$ARTEMIS_HOME/bin"
./artemis create --silent --force "$ARTEMIS_INSTANCE"
cd "$ARTEMIS_INSTANCE/bin"
pwd
./artemis run &
sleep 5
./artemis producer
./artemis consumer
./artemis stop
sleep 5
./artemis data print > data.log
./artemis data compact
./artemis data exp
./artemis-service start
sleep 5
./artemis producer
./artemis consumer
./artemis-service stop
cd $CURRENT_DIR
rm -rf target

View File

@ -18,54 +18,4 @@
# This script will validate the distribution works with folders with spaces on Linux machines # This script will validate the distribution works with folders with spaces on Linux machines
rm -rf target ./validate-instalation.sh with\ spaces\ And\ Weird\ %26\ Characters
mkdir target
mkdir target/with\ space
# Setting the script to fail if anything goes wrong
set -e
export TEST_TARGET="./target/with space"
. ./installHome.sh
export ARTEMIS_INSTANCE="$CURRENT_DIR/target/with space/artemis_instance"
echo home used is $ARTEMIS_HOME
echo artemis instance is $ARTEMIS_HOME
cd "$ARTEMIS_HOME/bin"
./artemis create --silent --force "$ARTEMIS_INSTANCE"
cd "$ARTEMIS_INSTANCE/bin"
pwd
./artemis run &
sleep 5
./artemis producer
./artemis consumer
./artemis stop
sleep 5
./artemis data print > data.log
./artemis data compact
./artemis data exp
./artemis-service start
sleep 5
./artemis producer
./artemis consumer
./artemis-service stop
cd $CURRENT_DIR
rm -rf target

View File

@ -36,7 +36,7 @@ public class ServerDTO {
public URI getConfigurationURI() throws Exception { public URI getConfigurationURI() throws Exception {
if (configurationURI == null) { if (configurationURI == null) {
configurationURI = new URI(fixupFileURI(configuration)); configurationURI = new URI(configuration);
} }
return configurationURI; return configurationURI;
@ -44,17 +44,10 @@ public class ServerDTO {
public File getConfigurationFile() throws Exception { public File getConfigurationFile() throws Exception {
if (configurationFile == null) { if (configurationFile == null) {
configurationFile = new File(new URI(fixupFileURI(configuration)).getSchemeSpecificPart()); configurationFile = new File(getConfigurationURI());
} }
return configurationFile; return configurationFile;
} }
private static String fixupFileURI(String value) {
if (value != null && value.startsWith("file:")) {
value = value.substring("file:".length());
value = new File(value).toURI().toString();
}
return value;
}
} }

View File

@ -28,6 +28,7 @@ import javax.xml.validation.SchemaFactory;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.net.URI;
import java.util.Properties; import java.util.Properties;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -75,7 +76,7 @@ public class XmlUtil {
private static final XMLInputFactory factory = XMLInputFactory.newInstance(); private static final XMLInputFactory factory = XMLInputFactory.newInstance();
public static <T> T decode(Class<T> clazz, File configuration) throws Exception { public static <T> T decode(Class<T> clazz, File configuration) throws Exception {
return decode(clazz, configuration, null, null); return decode(clazz, configuration, null, null, null);
} }
/** /**
@ -84,7 +85,8 @@ public class XmlUtil {
public static <T> T decode(Class<T> clazz, public static <T> T decode(Class<T> clazz,
File configuration, File configuration,
String artemisHome, String artemisHome,
String artemisInstance) throws Exception { String artemisInstance,
URI artemisURIInstance) throws Exception {
JAXBContext jaxbContext = JAXBContext.newInstance("org.apache.activemq.artemis.dto"); JAXBContext jaxbContext = JAXBContext.newInstance("org.apache.activemq.artemis.dto");
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
@ -104,6 +106,10 @@ public class XmlUtil {
props.put("artemis.instance", artemisInstance); props.put("artemis.instance", artemisInstance);
} }
if (artemisURIInstance != null) {
props.put("artemis.URI.instance", artemisURIInstance.toString());
}
XMLStreamReader reader = factory.createXMLStreamReader(new FileInputStream(configuration)); XMLStreamReader reader = factory.createXMLStreamReader(new FileInputStream(configuration));
reader = new PropertiesFilter(reader, props); reader = new PropertiesFilter(reader, props);

View File

@ -85,14 +85,24 @@ public class ReloadManagerImpl extends ActiveMQScheduledComponent implements Rel
class ReloadRegistry { class ReloadRegistry {
private final File file; private File file;
private final URL uri; private final URL uri;
private long lastModified; private long lastModified;
private final List<ReloadCallback> callbacks = new LinkedList<>(); private final List<ReloadCallback> callbacks = new LinkedList<>();
ReloadRegistry(URL uri) { ReloadRegistry(URL uri) {
this.file = new File(uri.getPath()); try {
file = new File(uri.toURI());
} catch (Exception e) {
logger.warn(e.getMessage(), e);
file = new File(uri.getPath());
}
if (!file.exists()) {
logger.warn("File " + file + " does not exist");
}
this.lastModified = file.lastModified(); this.lastModified = file.lastModified();
this.uri = uri; this.uri = uri;
} }

View File

@ -68,7 +68,7 @@ public class ReloadManagerTest extends ActiveMQTestBase {
@Test @Test
public void testUpdateWithSpace() throws Exception { public void testUpdateWithSpace() throws Exception {
File spaceDir = new File(getTemporaryDir(), "./with space"); File spaceDir = new File(getTemporaryDir(), "./with %25space");
spaceDir.mkdirs(); spaceDir.mkdirs();
File file = new File(spaceDir, "checkFile.tst"); File file = new File(spaceDir, "checkFile.tst");
internalTest(manager, file); internalTest(manager, file);