ARTEMIS-3627 - support broker.properties for augmenting or supplying additional configuration via nested properties of the internal configuratinimpl bean - elements with a name attribute can be configured in collections, the type inferred by the add singular fluent api
This commit is contained in:
parent
9c01f9b983
commit
10d93d9c92
|
@ -23,6 +23,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||
|
||||
import io.airlift.airline.Command;
|
||||
import io.airlift.airline.Option;
|
||||
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
|
||||
import org.apache.activemq.artemis.api.core.Pair;
|
||||
import org.apache.activemq.artemis.cli.Artemis;
|
||||
import org.apache.activemq.artemis.cli.commands.tools.LockAbstract;
|
||||
|
@ -47,6 +48,9 @@ public class Run extends LockAbstract {
|
|||
@Option(name = "--allow-kill", description = "This will allow the server to kill itself. Useful for tests (failover tests for instance)")
|
||||
boolean allowKill;
|
||||
|
||||
@Option(name = "--properties", description = "A file url to a properties file that is applied to the server's internal ConfigurationImpl bean")
|
||||
String properties;
|
||||
|
||||
private static boolean embedded = false;
|
||||
|
||||
public static final ReusableLatch latchRunning = new ReusableLatch(0);
|
||||
|
@ -112,6 +116,14 @@ public class Run extends LockAbstract {
|
|||
|
||||
server.createComponents();
|
||||
server.getServer().registerActivationFailureListener(exception -> serverActivationFailed.set(exception));
|
||||
|
||||
if (properties == null) {
|
||||
File propertiesFileFromEtc = new File(getBrokerEtc(), ActiveMQDefaultConfiguration.BROKER_PROPERTIES_SYSTEM_PROPERTY_NAME);
|
||||
if (propertiesFileFromEtc.exists()) {
|
||||
properties = propertiesFileFromEtc.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
server.getServer().setProperties(properties);
|
||||
server.start();
|
||||
server.getServer().addExternalComponent(managementContext, false);
|
||||
|
||||
|
@ -121,7 +133,7 @@ public class Run extends LockAbstract {
|
|||
|
||||
for (ComponentDTO componentDTO : broker.components) {
|
||||
Class clazz = this.getClass().getClassLoader().loadClass(componentDTO.componentClassName);
|
||||
ExternalComponent component = (ExternalComponent) clazz.newInstance();
|
||||
ExternalComponent component = (ExternalComponent) clazz.getDeclaredConstructor(null).newInstance();
|
||||
component.configure(componentDTO, getBrokerInstance(), getBrokerHome());
|
||||
server.getServer().addExternalComponent(component, true);
|
||||
assert component.isStarted();
|
||||
|
@ -129,6 +141,7 @@ public class Run extends LockAbstract {
|
|||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
serverActivationFailed.set(t);
|
||||
latchRunning.countDown();
|
||||
}
|
||||
|
||||
if (serverActivationFailed.get() != null) {
|
||||
|
|
|
@ -39,6 +39,7 @@ import java.io.ByteArrayInputStream;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
|
@ -1920,6 +1921,39 @@ public class ArtemisTest extends CliTestBase {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRunPropertiesArgumentSetsAcceptorPort() throws Exception {
|
||||
File instanceFile = new File(temporaryFolder.getRoot(), "testRunPropertiesArgumentSetsAcceptorPort");
|
||||
setupAuth(instanceFile);
|
||||
Run.setEmbedded(true);
|
||||
Artemis.main("create", instanceFile.getAbsolutePath(), "--silent", "--no-fsync", "--no-autotune", "--no-web", "--require-login");
|
||||
System.setProperty("artemis.instance", instanceFile.getAbsolutePath());
|
||||
|
||||
// configure
|
||||
URL brokerPropertiesFromClasspath = this.getClass().getClassLoader().getResource(ActiveMQDefaultConfiguration.BROKER_PROPERTIES_SYSTEM_PROPERTY_NAME);
|
||||
Artemis.internalExecute("run", "--properties", new File(brokerPropertiesFromClasspath.toURI()).getAbsolutePath());
|
||||
|
||||
// verify
|
||||
try (ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("tcp://localhost:61618"); Connection connection = cf.createConnection("admin", "admin");) {
|
||||
connection.start();
|
||||
} finally {
|
||||
stopServer();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRunPropertiesDudArgument() throws Exception {
|
||||
File instanceFile = new File(temporaryFolder.getRoot(), "testRunPropertiesDudArgument");
|
||||
setupAuth(instanceFile);
|
||||
Run.setEmbedded(true);
|
||||
Artemis.main("create", instanceFile.getAbsolutePath(), "--silent", "--no-fsync", "--no-autotune", "--no-web", "--require-login");
|
||||
System.setProperty("artemis.instance", instanceFile.getAbsolutePath());
|
||||
|
||||
// verify error
|
||||
Object ret = Artemis.internalExecute("run", "--properties", "https://www.apache.org");
|
||||
assertTrue(ret instanceof IllegalStateException);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVersionCommand() throws Exception {
|
||||
TestActionContext context = new TestActionContext();
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
name=ConfiguredViaProperties
|
||||
acceptorConfigurations.artemis.params.port=61618
|
|
@ -557,6 +557,12 @@ public final class ActiveMQDefaultConfiguration {
|
|||
|
||||
public static final String DEFAULT_SYSTEM_PROPERTY_PREFIX = "brokerconfig.";
|
||||
|
||||
public static final String BROKER_PROPERTIES_SYSTEM_PROPERTY_NAME = "broker.properties";
|
||||
|
||||
public static final String BROKER_PROPERTIES_KEY_SURROUND = "\"";
|
||||
|
||||
public static final String BROKER_PROPERTIES_KEY_SURROUND_PROPERTY = "key.surround";
|
||||
|
||||
public static String DEFAULT_NETWORK_CHECK_LIST = null;
|
||||
|
||||
public static String DEFAULT_NETWORK_CHECK_URL_LIST = null;
|
||||
|
@ -1587,6 +1593,10 @@ public final class ActiveMQDefaultConfiguration {
|
|||
return DEFAULT_SYSTEM_PROPERTY_PREFIX;
|
||||
}
|
||||
|
||||
public static String getDefaultBrokerPropertiesKeySurround() {
|
||||
return BROKER_PROPERTIES_KEY_SURROUND;
|
||||
}
|
||||
|
||||
public static String getDefaultNetworkCheckList() {
|
||||
return DEFAULT_NETWORK_CHECK_LIST;
|
||||
}
|
||||
|
|
|
@ -164,6 +164,10 @@ public class TransportConfiguration implements Serializable {
|
|||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class name of ConnectorFactory being used by this TransportConfiguration
|
||||
*
|
||||
|
|
|
@ -20,7 +20,6 @@ import java.io.File;
|
|||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -87,9 +86,7 @@ public interface Configuration {
|
|||
*/
|
||||
String getSystemPropertyPrefix();
|
||||
|
||||
Configuration parseSystemProperties() throws Exception;
|
||||
|
||||
Configuration parseSystemProperties(Properties properties) throws Exception;
|
||||
Configuration parseProperties(String optionalUrlToPropertiesFile) throws Exception;
|
||||
|
||||
boolean isCriticalAnalyzer();
|
||||
|
||||
|
|
|
@ -31,16 +31,17 @@ public class AMQPBrokerConnectConfiguration extends BrokerConnectConfiguration {
|
|||
|
||||
List<TransportConfiguration> transportConfigurations;
|
||||
|
||||
List<AMQPBrokerConnectionElement> connectionElements;
|
||||
List<AMQPBrokerConnectionElement> connectionElements = new ArrayList<>();
|
||||
|
||||
public AMQPBrokerConnectConfiguration() {
|
||||
super(null, null);
|
||||
}
|
||||
|
||||
public AMQPBrokerConnectConfiguration(String name, String uri) {
|
||||
super(name, uri);
|
||||
}
|
||||
|
||||
public AMQPBrokerConnectConfiguration addElement(AMQPBrokerConnectionElement amqpBrokerConnectionElement) {
|
||||
if (connectionElements == null) {
|
||||
connectionElements = new ArrayList<>();
|
||||
}
|
||||
amqpBrokerConnectionElement.setParent(this);
|
||||
|
||||
|
||||
|
@ -53,6 +54,10 @@ public class AMQPBrokerConnectConfiguration extends BrokerConnectConfiguration {
|
|||
return this;
|
||||
}
|
||||
|
||||
public AMQPBrokerConnectConfiguration addConnectionElement(AMQPMirrorBrokerConnectionElement amqpBrokerConnectionElement) {
|
||||
return addElement(amqpBrokerConnectionElement);
|
||||
}
|
||||
|
||||
public List<AMQPBrokerConnectionElement> getConnectionElements() {
|
||||
return connectionElements;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.apache.activemq.artemis.core.config.WildcardConfiguration;
|
|||
import org.apache.activemq.artemis.core.postoffice.impl.AddressImpl;
|
||||
|
||||
public class AMQPBrokerConnectionElement implements Serializable {
|
||||
String name;
|
||||
SimpleString matchAddress;
|
||||
SimpleString queueName;
|
||||
AMQPBrokerConnectionAddressType type;
|
||||
|
@ -84,4 +85,14 @@ public class AMQPBrokerConnectionElement implements Serializable {
|
|||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,21 +16,27 @@
|
|||
*/
|
||||
package org.apache.activemq.artemis.core.config.impl;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Serializable;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
|
@ -38,12 +44,14 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
|
||||
import org.apache.activemq.artemis.api.core.BroadcastGroupConfiguration;
|
||||
import org.apache.activemq.artemis.api.core.DiscoveryGroupConfiguration;
|
||||
import org.apache.activemq.artemis.api.core.Pair;
|
||||
import org.apache.activemq.artemis.api.core.QueueConfiguration;
|
||||
import org.apache.activemq.artemis.api.core.SimpleString;
|
||||
import org.apache.activemq.artemis.api.core.TransportConfiguration;
|
||||
|
@ -65,6 +73,8 @@ import org.apache.activemq.artemis.core.config.WildcardConfiguration;
|
|||
import org.apache.activemq.artemis.core.config.ha.ReplicaPolicyConfiguration;
|
||||
import org.apache.activemq.artemis.core.config.ha.ReplicatedPolicyConfiguration;
|
||||
import org.apache.activemq.artemis.core.config.storage.DatabaseStorageConfiguration;
|
||||
import org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnectorFactory;
|
||||
import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory;
|
||||
import org.apache.activemq.artemis.core.security.Role;
|
||||
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
|
||||
import org.apache.activemq.artemis.core.server.JournalType;
|
||||
|
@ -89,7 +99,14 @@ import org.apache.activemq.artemis.core.settings.impl.ResourceLimitSettings;
|
|||
import org.apache.activemq.artemis.utils.Env;
|
||||
import org.apache.activemq.artemis.utils.ObjectInputStreamWithClassLoader;
|
||||
import org.apache.activemq.artemis.utils.critical.CriticalAnalyzerPolicy;
|
||||
import org.apache.activemq.artemis.utils.uri.BeanSupport;
|
||||
import org.apache.activemq.artemis.utils.uri.FluentPropertyBeanIntrospectorWithIgnores;
|
||||
import org.apache.commons.beanutils.BeanUtilsBean;
|
||||
import org.apache.commons.beanutils.ConvertUtilsBean;
|
||||
import org.apache.commons.beanutils.Converter;
|
||||
import org.apache.commons.beanutils.MappedPropertyDescriptor;
|
||||
import org.apache.commons.beanutils.MethodUtils;
|
||||
import org.apache.commons.beanutils.PropertyUtilsBean;
|
||||
import org.apache.commons.beanutils.expression.DefaultResolver;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
public class ConfigurationImpl implements Configuration, Serializable {
|
||||
|
@ -338,6 +355,8 @@ public class ConfigurationImpl implements Configuration, Serializable {
|
|||
|
||||
private String systemPropertyPrefix = ActiveMQDefaultConfiguration.getDefaultSystemPropertyPrefix();
|
||||
|
||||
private String brokerPropertiesKeySurround = ActiveMQDefaultConfiguration.getDefaultBrokerPropertiesKeySurround();
|
||||
|
||||
private String networkCheckList = ActiveMQDefaultConfiguration.getDefaultNetworkCheckList();
|
||||
|
||||
private String networkURLList = ActiveMQDefaultConfiguration.getDefaultNetworkCheckURLList();
|
||||
|
@ -429,31 +448,73 @@ public class ConfigurationImpl implements Configuration, Serializable {
|
|||
return systemPropertyPrefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Configuration parseSystemProperties() throws Exception {
|
||||
parseSystemProperties(System.getProperties());
|
||||
return this;
|
||||
public String getBrokerPropertiesKeySurround() {
|
||||
return brokerPropertiesKeySurround;
|
||||
}
|
||||
|
||||
public void setBrokerPropertiesKeySurround(String brokerPropertiesKeySurround) {
|
||||
this.brokerPropertiesKeySurround = brokerPropertiesKeySurround;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Configuration parseSystemProperties(Properties properties) throws Exception {
|
||||
public Configuration parseProperties(String fileUrlToProperties) throws Exception {
|
||||
// system property overrides
|
||||
fileUrlToProperties = System.getProperty(ActiveMQDefaultConfiguration.BROKER_PROPERTIES_SYSTEM_PROPERTY_NAME, fileUrlToProperties);
|
||||
if (fileUrlToProperties != null) {
|
||||
Properties brokerProperties = new Properties();
|
||||
try (FileInputStream fileInputStream = new FileInputStream(fileUrlToProperties); BufferedInputStream reader = new BufferedInputStream(fileInputStream)) {
|
||||
brokerProperties.load(reader);
|
||||
parsePrefixedProperties(brokerProperties, null);
|
||||
}
|
||||
}
|
||||
parsePrefixedProperties(System.getProperties(), systemPropertyPrefix);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void parsePrefixedProperties(Properties properties, String prefix) throws Exception {
|
||||
Map<String, Object> beanProperties = new HashMap<>();
|
||||
|
||||
synchronized (properties) {
|
||||
String key = null;
|
||||
for (Map.Entry<Object, Object> entry : properties.entrySet()) {
|
||||
if (entry.getKey().toString().startsWith(systemPropertyPrefix)) {
|
||||
String key = entry.getKey().toString().substring(systemPropertyPrefix.length());
|
||||
logger.debug("Setting up config, " + key + "=" + entry.getValue());
|
||||
beanProperties.put(key, entry.getValue());
|
||||
key = entry.getKey().toString();
|
||||
if (prefix != null) {
|
||||
if (!key.startsWith(prefix)) {
|
||||
continue;
|
||||
}
|
||||
key = entry.getKey().toString().substring(prefix.length());
|
||||
}
|
||||
logger.debug("Setting up config, " + key + "=" + entry.getValue());
|
||||
beanProperties.put(key, entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (!beanProperties.isEmpty()) {
|
||||
BeanSupport.setData(this, beanProperties);
|
||||
populateWithProperties(beanProperties);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
public void populateWithProperties(Map<String, Object> beanProperties) throws InvocationTargetException, IllegalAccessException {
|
||||
BeanUtilsBean beanUtils = new BeanUtilsBean(new ConvertUtilsBean(), new CollectionAutoFillPropertiesUtil());
|
||||
// nested property keys delimited by . and enclosed by '"' if they key's themselves contain dots
|
||||
beanUtils.getPropertyUtils().setResolver(new SurroundResolver(getBrokerPropertiesKeySurround(beanProperties)));
|
||||
beanUtils.getConvertUtils().register(new Converter() {
|
||||
@Override
|
||||
public <T> T convert(Class<T> type, Object value) {
|
||||
return (T) SimpleString.toSimpleString(value.toString());
|
||||
}
|
||||
}, SimpleString.class);
|
||||
beanUtils.getPropertyUtils().addBeanIntrospector(new FluentPropertyBeanIntrospectorWithIgnores());
|
||||
|
||||
beanUtils.populate(this, beanProperties);
|
||||
}
|
||||
|
||||
private String getBrokerPropertiesKeySurround(Map<String, Object> propertiesToApply) {
|
||||
if (propertiesToApply.containsKey(ActiveMQDefaultConfiguration.BROKER_PROPERTIES_KEY_SURROUND_PROPERTY)) {
|
||||
return String.valueOf(propertiesToApply.get(ActiveMQDefaultConfiguration.BROKER_PROPERTIES_KEY_SURROUND_PROPERTY));
|
||||
} else {
|
||||
return System.getProperty(getSystemPropertyPrefix() + ActiveMQDefaultConfiguration.BROKER_PROPERTIES_KEY_SURROUND_PROPERTY, getBrokerPropertiesKeySurround());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -698,6 +759,11 @@ public class ConfigurationImpl implements Configuration, Serializable {
|
|||
return this;
|
||||
}
|
||||
|
||||
public ConfigurationImpl addConnectorConfiguration(final TransportConfiguration info) {
|
||||
connectorConfigs.put(info.getName(), info);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationImpl addConnectorConfiguration(final String name, final String uri) throws Exception {
|
||||
|
||||
|
@ -795,6 +861,10 @@ public class ConfigurationImpl implements Configuration, Serializable {
|
|||
return this.amqpBrokerConnectConfigurations;
|
||||
}
|
||||
|
||||
public List<AMQPBrokerConnectConfiguration> getAMQPConnections() {
|
||||
return this.amqpBrokerConnectConfigurations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationImpl clearClusterConfigurations() {
|
||||
clusterConfigurations.clear();
|
||||
|
@ -1555,6 +1625,10 @@ public class ConfigurationImpl implements Configuration, Serializable {
|
|||
return this;
|
||||
}
|
||||
|
||||
public ConfigurationImpl addResourceLimitSetting(ResourceLimitSettings resourceLimitSettings) {
|
||||
return this.addResourceLimitSettings(resourceLimitSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Set<Role>> getSecurityRoles() {
|
||||
for (SecuritySettingPlugin securitySettingPlugin : securitySettingPlugins) {
|
||||
|
@ -2603,4 +2677,190 @@ public class ConfigurationImpl implements Configuration, Serializable {
|
|||
return this;
|
||||
}
|
||||
|
||||
// extend property utils with ability to auto-fill and locate from collections
|
||||
// collection entries are identified by the name() property
|
||||
private static class CollectionAutoFillPropertiesUtil extends PropertyUtilsBean {
|
||||
|
||||
private static final Object[] EMPTY_OBJECT_ARRAY = new Object[]{};
|
||||
final Stack<Pair<String, Object>> collections = new Stack<>();
|
||||
|
||||
@Override
|
||||
public void setProperty(final Object bean, final String name, final Object value) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
|
||||
// any set will invalidate our collections stack
|
||||
if (!collections.isEmpty()) {
|
||||
Pair<String, Object> collectionInfo = collections.pop();
|
||||
}
|
||||
super.setProperty(bean, name, value);
|
||||
}
|
||||
|
||||
// need to track collections such that we can locate or create entries on demand
|
||||
@Override
|
||||
public Object getProperty(final Object bean,
|
||||
final String name) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
||||
|
||||
if (!collections.isEmpty()) {
|
||||
final String key = getResolver().getProperty(name);
|
||||
Pair<String, Object> collectionInfo = collections.pop();
|
||||
if (bean instanceof Map) {
|
||||
Map map = (Map) bean;
|
||||
if (!map.containsKey(key)) {
|
||||
map.put(key, newNamedInstanceForCollection(collectionInfo.getA(), collectionInfo.getB(), key));
|
||||
}
|
||||
return map.get(key);
|
||||
} else { // collection
|
||||
// locate on name property
|
||||
for (Object candidate : (Collection) bean) {
|
||||
if (key.equals(getProperty(candidate, "name"))) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
// or create it
|
||||
Object created = newNamedInstanceForCollection(collectionInfo.getA(), collectionInfo.getB(), key);
|
||||
((Collection) bean).add(created);
|
||||
return created;
|
||||
}
|
||||
}
|
||||
|
||||
Object resolved = getNestedProperty(bean, name);
|
||||
|
||||
if (resolved instanceof Collection || resolved instanceof Map) {
|
||||
collections.push(new Pair<String, Object>(name, bean));
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
|
||||
// allow finding beans in collections via name() such that a mapped key (key)
|
||||
// can be used to access and *not* auto create entries
|
||||
@Override
|
||||
public Object getMappedProperty(final Object bean,
|
||||
final String name, final String key)
|
||||
throws IllegalAccessException, InvocationTargetException,
|
||||
NoSuchMethodException {
|
||||
|
||||
if (bean == null) {
|
||||
throw new IllegalArgumentException("No bean specified");
|
||||
}
|
||||
if (name == null) {
|
||||
throw new IllegalArgumentException("No name specified for bean class '" +
|
||||
bean.getClass() + "'");
|
||||
}
|
||||
if (key == null) {
|
||||
throw new IllegalArgumentException("No key specified for property '" +
|
||||
name + "' on bean class " + bean.getClass() + "'");
|
||||
}
|
||||
|
||||
Object result = null;
|
||||
|
||||
final PropertyDescriptor descriptor = getPropertyDescriptor(bean, name);
|
||||
if (descriptor == null) {
|
||||
throw new NoSuchMethodException("Unknown property '" +
|
||||
name + "'+ on bean class '" + bean.getClass() + "'");
|
||||
}
|
||||
|
||||
if (descriptor instanceof MappedPropertyDescriptor) {
|
||||
// Call the keyed getter method if there is one
|
||||
Method readMethod = ((MappedPropertyDescriptor) descriptor).
|
||||
getMappedReadMethod();
|
||||
readMethod = MethodUtils.getAccessibleMethod(bean.getClass(), readMethod);
|
||||
if (readMethod != null) {
|
||||
final Object[] keyArray = new Object[1];
|
||||
keyArray[0] = key;
|
||||
result = readMethod.invoke(bean, keyArray);
|
||||
} else {
|
||||
throw new NoSuchMethodException("Property '" + name +
|
||||
"' has no mapped getter method on bean class '" +
|
||||
bean.getClass() + "'");
|
||||
}
|
||||
} else {
|
||||
final Method readMethod = MethodUtils.getAccessibleMethod(bean.getClass(), descriptor.getReadMethod());
|
||||
if (readMethod != null) {
|
||||
final Object invokeResult = readMethod.invoke(bean, EMPTY_OBJECT_ARRAY);
|
||||
if (invokeResult instanceof Map) {
|
||||
result = ((Map<?, ?>)invokeResult).get(key);
|
||||
} else if (invokeResult instanceof Collection) {
|
||||
// locate on name property
|
||||
for (Object candidate : (Collection) invokeResult) {
|
||||
if (key.equals(getProperty(candidate, "name"))) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new NoSuchMethodException("Property '" + name +
|
||||
"' has no mapped getter method on bean class '" +
|
||||
bean.getClass() + "'");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Object newNamedInstanceForCollection(String collectionPropertyName, Object hostingBean, String name) {
|
||||
// find the add X and init an instance of the type with name=name
|
||||
|
||||
// expect an add... without the plural
|
||||
String addPropertyName = "add" + Character.toUpperCase(collectionPropertyName.charAt(0)) + collectionPropertyName.substring(1, collectionPropertyName.length() - 1);
|
||||
|
||||
// we don't know the type, infer from add method add(X x) or add(String key, X x)
|
||||
final Method[] methods = hostingBean.getClass().getMethods();
|
||||
for (Method candidate : methods) {
|
||||
if (candidate.getName().equals(addPropertyName) &&
|
||||
(candidate.getParameterCount() == 1 ||
|
||||
(candidate.getParameterCount() == 2
|
||||
// has a String key
|
||||
&& String.class.equals(candidate.getParameterTypes()[0])
|
||||
// but not initialised from a String form (eg: uri)
|
||||
&& !String.class.equals(candidate.getParameterTypes()[1])))) {
|
||||
|
||||
// create one and initialise with name
|
||||
try {
|
||||
Object instance = candidate.getParameterTypes()[candidate.getParameterCount() - 1].getDeclaredConstructor().newInstance(null);
|
||||
try {
|
||||
setProperty(instance, "name", name);
|
||||
} catch (NoSuchMethodException okIgnore) {
|
||||
}
|
||||
|
||||
// this is always going to be a little hacky b/c our config is not natively property friendly
|
||||
if (instance instanceof TransportConfiguration) {
|
||||
setProperty(instance, "factoryClassName", "invm".equals(name) ? InVMConnectorFactory.class.getName() : NettyConnectorFactory.class.getName());
|
||||
}
|
||||
return instance;
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.debug("Failed to add entry for " + name + " with method: " + candidate, e);
|
||||
throw new IllegalArgumentException("failed to add entry for collection key " + name, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("failed to locate add method for collection property " + addPropertyName);
|
||||
}
|
||||
}
|
||||
|
||||
private static class SurroundResolver extends DefaultResolver {
|
||||
final String surroundString;
|
||||
|
||||
SurroundResolver(String surroundString) {
|
||||
this.surroundString = surroundString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String next(String expression) {
|
||||
String result = super.next(expression);
|
||||
if (result != null) {
|
||||
if (result.startsWith(surroundString)) {
|
||||
// we need to recompute to properly terminate this SURROUND
|
||||
result = expression.substring(expression.indexOf(surroundString));
|
||||
return result.substring(0, result.indexOf(surroundString, surroundString.length()) + surroundString.length());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProperty(final String expression) {
|
||||
if (expression.startsWith(surroundString) && expression.endsWith(surroundString)) {
|
||||
return expression.substring(surroundString.length(), expression.length() - surroundString.length());
|
||||
}
|
||||
return super.getProperty(expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,8 +57,6 @@ public final class FileConfiguration extends ConfigurationImpl implements Deploy
|
|||
|
||||
setConfigurationUrl(url);
|
||||
|
||||
parseSystemProperties();
|
||||
|
||||
parsed = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -2052,7 +2052,7 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
|
|||
String uri = e.getAttribute("uri");
|
||||
|
||||
int retryInterval = getAttributeInteger(e, "retry-interval", 5000, Validators.GT_ZERO);
|
||||
int reconnectAttemps = getAttributeInteger(e, "reconnect-attempts", -1, Validators.MINUS_ONE_OR_GT_ZERO);
|
||||
int reconnectAttempts = getAttributeInteger(e, "reconnect-attempts", -1, Validators.MINUS_ONE_OR_GT_ZERO);
|
||||
String user = getAttributeValue(e, "user");
|
||||
String password = getAttributeValue(e, "password");
|
||||
boolean autoStart = getBooleanAttribute(e, "auto-start", true);
|
||||
|
@ -2061,7 +2061,7 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
|
|||
|
||||
AMQPBrokerConnectConfiguration config = new AMQPBrokerConnectConfiguration(name, uri);
|
||||
config.parseURI();
|
||||
config.setRetryInterval(retryInterval).setReconnectAttempts(reconnectAttemps).setUser(user).setPassword(password).setAutostart(autoStart);
|
||||
config.setRetryInterval(retryInterval).setReconnectAttempts(reconnectAttempts).setUser(user).setPassword(password).setAutostart(autoStart);
|
||||
|
||||
mainConfig.addAMQPConnection(config);
|
||||
|
||||
|
|
|
@ -961,4 +961,7 @@ public interface ActiveMQServer extends ServiceComponent {
|
|||
BrokerBalancerManager getBalancerManager();
|
||||
|
||||
String validateUser(String username, String password, RemotingConnection connection, String securityDomain) throws Exception;
|
||||
|
||||
default void setProperties(String fileUrltoBrokerProperties) {
|
||||
}
|
||||
}
|
|
@ -17,8 +17,11 @@
|
|||
package org.apache.activemq.artemis.core.server.embedded;
|
||||
|
||||
import javax.management.MBeanServer;
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
|
||||
import org.apache.activemq.artemis.core.config.Configuration;
|
||||
import org.apache.activemq.artemis.core.config.FileDeploymentManager;
|
||||
import org.apache.activemq.artemis.core.config.impl.FileConfiguration;
|
||||
|
@ -140,6 +143,11 @@ public class EmbeddedActiveMQ {
|
|||
} else {
|
||||
activeMQServer = new ActiveMQServerImpl(configuration, mbeanServer, securityManager);
|
||||
}
|
||||
|
||||
URL brokerPropertiesFromClasspath = this.getClass().getClassLoader().getResource(ActiveMQDefaultConfiguration.BROKER_PROPERTIES_SYSTEM_PROPERTY_NAME);
|
||||
if (brokerPropertiesFromClasspath != null) {
|
||||
activeMQServer.setProperties(new File(brokerPropertiesFromClasspath.toURI()).getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
public EmbeddedActiveMQ stop() throws Exception {
|
||||
|
|
|
@ -369,6 +369,8 @@ public class ActiveMQServerImpl implements ActiveMQServer {
|
|||
|
||||
private volatile FederationManager federationManager;
|
||||
|
||||
private String propertiesFileUrl;
|
||||
|
||||
private final ActiveMQComponent networkCheckMonitor = new ActiveMQComponent() {
|
||||
@Override
|
||||
public void start() throws Exception {
|
||||
|
@ -593,13 +595,18 @@ public class ActiveMQServerImpl implements ActiveMQServer {
|
|||
return this.analyzer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperties(String fileUrltoBrokerProperties) {
|
||||
propertiesFileUrl = fileUrltoBrokerProperties;
|
||||
}
|
||||
|
||||
private void internalStart() throws Exception {
|
||||
if (state != SERVER_STATE.STOPPED) {
|
||||
logger.debug("Server already started!");
|
||||
return;
|
||||
}
|
||||
|
||||
configuration.parseSystemProperties();
|
||||
configuration.parseProperties(propertiesFileUrl);
|
||||
|
||||
initializeExecutorServices();
|
||||
|
||||
|
@ -4323,6 +4330,7 @@ public class ActiveMQServerImpl implements ActiveMQServer {
|
|||
configuration.setQueueConfigs(config.getQueueConfigs());
|
||||
configurationReloadDeployed.set(false);
|
||||
if (isActive()) {
|
||||
configuration.parseProperties(propertiesFileUrl);
|
||||
deployReloadableConfigFromConfiguration();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,10 @@ public class ResourceLimitSettings implements Serializable, EncodingSupport {
|
|||
|
||||
// SimpleString queueNameRegex = null;
|
||||
|
||||
public void setName(String name) {
|
||||
setMatch(SimpleString.toSimpleString(name));
|
||||
}
|
||||
|
||||
public SimpleString getMatch() {
|
||||
return match != null ? match : DEFAULT_MATCH;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
import org.apache.activemq.artemis.ArtemisConstants;
|
||||
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
|
||||
import org.apache.activemq.artemis.api.core.SimpleString;
|
||||
import org.apache.activemq.artemis.api.core.TransportConfiguration;
|
||||
import org.apache.activemq.artemis.core.config.Configuration;
|
||||
import org.apache.activemq.artemis.core.config.amqpBrokerConnectivity.AMQPBrokerConnectConfiguration;
|
||||
import org.apache.activemq.artemis.core.config.amqpBrokerConnectivity.AMQPBrokerConnectionAddressType;
|
||||
import org.apache.activemq.artemis.core.config.amqpBrokerConnectivity.AMQPMirrorBrokerConnectionElement;
|
||||
import org.apache.activemq.artemis.core.config.ha.LiveOnlyPolicyConfiguration;
|
||||
import org.apache.activemq.artemis.core.server.JournalType;
|
||||
import org.apache.activemq.artemis.core.server.plugin.impl.LoggingActiveMQServerPlugin;
|
||||
|
@ -584,12 +588,127 @@ public class ConfigurationImplTest extends ActiveMQTestBase {
|
|||
properties.put(configuration.getSystemPropertyPrefix() + "fileDeployerScanPeriod", "1234");
|
||||
properties.put(configuration.getSystemPropertyPrefix() + "globalMaxSize", "4321");
|
||||
|
||||
configuration.parseSystemProperties(properties);
|
||||
configuration.parsePrefixedProperties(properties, configuration.getSystemPropertyPrefix());
|
||||
|
||||
Assert.assertEquals(1234, configuration.getFileDeployerScanPeriod());
|
||||
Assert.assertEquals(4321, configuration.getGlobalMaxSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetNestedPropertyOnCollections() throws Throwable {
|
||||
ConfigurationImpl configuration = new ConfigurationImpl();
|
||||
|
||||
Properties properties = new Properties();
|
||||
properties.put("balancerConfigurations.joe.localTargetFilter", "LF");
|
||||
properties.put("balancerConfigurations(joe).targetKeyFilter", "TF");
|
||||
|
||||
properties.put("acceptorConfigurations.tcp.params.HOST", "LOCALHOST");
|
||||
properties.put("acceptorConfigurations.tcp.params.PORT", "61616");
|
||||
|
||||
properties.put("acceptorConfigurations.invm.params.ID", "0");
|
||||
|
||||
// <amqp-connection uri="tcp://HOST:PORT" name="other-server" retry-interval="100" reconnect-attempts="-1" user="john" password="doe">
|
||||
properties.put("AMQPConnections.other-server.uri", "tcp://HOST:PORT");
|
||||
properties.put("AMQPConnections.other-server.retryInterval", "100");
|
||||
properties.put("AMQPConnections.other-server.reconnectAttempts", "100");
|
||||
properties.put("AMQPConnections.other-server.user", "john");
|
||||
properties.put("AMQPConnections.other-server.password", "doe");
|
||||
|
||||
// <amqp-connection uri="tcp://brokerB:5672" name="brokerB"> <mirror/> </amqp-connection>
|
||||
properties.put("AMQPConnections.brokerB.uri", "tcp://brokerB:5672");
|
||||
properties.put("AMQPConnections.brokerB.type", AMQPBrokerConnectionAddressType.MIRROR.toString());
|
||||
properties.put("AMQPConnections.brokerB.connectionElements.mirror.mirrorSNF", "mirrorSNFQueue");
|
||||
|
||||
properties.put("resourceLimitSettings.joe.maxConnections", "100");
|
||||
|
||||
configuration.parsePrefixedProperties(properties, null);
|
||||
|
||||
Assert.assertEquals(1, configuration.getBalancerConfigurations().size());
|
||||
Assert.assertEquals("LF", configuration.getBalancerConfigurations().get(0).getLocalTargetFilter());
|
||||
Assert.assertEquals("TF", configuration.getBalancerConfigurations().get(0).getTargetKeyFilter());
|
||||
|
||||
Assert.assertEquals(2, configuration.getAcceptorConfigurations().size());
|
||||
|
||||
for (TransportConfiguration acceptor : configuration.getAcceptorConfigurations()) {
|
||||
if ("tcp".equals(acceptor.getName())) {
|
||||
Assert.assertEquals("61616", acceptor.getParams().get("PORT"));
|
||||
}
|
||||
if ("invm".equals(acceptor.getName())) {
|
||||
Assert.assertEquals("0", acceptor.getParams().get("ID"));
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertEquals(2, configuration.getAMQPConnection().size());
|
||||
for (AMQPBrokerConnectConfiguration amqpBrokerConnectConfiguration : configuration.getAMQPConnection()) {
|
||||
if ("brokerB".equals(amqpBrokerConnectConfiguration.getName())) {
|
||||
Assert.assertEquals(AMQPBrokerConnectionAddressType.MIRROR.toString(), amqpBrokerConnectConfiguration.getConnectionElements().get(0).getType().toString());
|
||||
Assert.assertEquals("mirrorSNFQueue", ((AMQPMirrorBrokerConnectionElement)amqpBrokerConnectConfiguration.getConnectionElements().get(0)).getMirrorSNF().toString());
|
||||
|
||||
} else if ("other-server".equals(amqpBrokerConnectConfiguration.getName())) {
|
||||
Assert.assertEquals(100, amqpBrokerConnectConfiguration.getReconnectAttempts());
|
||||
} else {
|
||||
fail("unexpected amqp broker connection configuration: " + amqpBrokerConnectConfiguration.getName());
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertEquals(100, configuration.getResourceLimitSettings().get("joe").getMaxConnections());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetNestedPropertyOnExistingCollectionEntryViaMappedNotation() throws Throwable {
|
||||
ConfigurationImpl configuration = new ConfigurationImpl();
|
||||
|
||||
Properties properties = new Properties();
|
||||
properties.put("balancerConfigurations.joe.localTargetFilter", "LF");
|
||||
// does not exist, ignored
|
||||
properties.put("balancerConfigurations(bob).targetKeyFilter", "TF");
|
||||
properties.put("balancerConfigurations(joe).targetKeyFilter", "TF");
|
||||
|
||||
configuration.parsePrefixedProperties(properties, null);
|
||||
|
||||
Assert.assertEquals(1, configuration.getBalancerConfigurations().size());
|
||||
Assert.assertEquals("LF", configuration.getBalancerConfigurations().get(0).getLocalTargetFilter());
|
||||
Assert.assertEquals("TF", configuration.getBalancerConfigurations().get(0).getTargetKeyFilter());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddressSettingsViaProperties() throws Throwable {
|
||||
ConfigurationImpl configuration = new ConfigurationImpl();
|
||||
|
||||
Properties properties = new Properties();
|
||||
|
||||
properties.put("addressesSettings.#.expiryAddress", "sharedExpiry");
|
||||
properties.put("addressesSettings.NeedToTrackExpired.expiryAddress", "important");
|
||||
properties.put("addressesSettings.\"Name.With.Dots\".expiryAddress", "moreImportant");
|
||||
|
||||
configuration.parsePrefixedProperties(properties, null);
|
||||
|
||||
Assert.assertEquals(3, configuration.getAddressesSettings().size());
|
||||
Assert.assertEquals(SimpleString.toSimpleString("sharedExpiry"), configuration.getAddressesSettings().get("#").getExpiryAddress());
|
||||
Assert.assertEquals(SimpleString.toSimpleString("important"), configuration.getAddressesSettings().get("NeedToTrackExpired").getExpiryAddress());
|
||||
Assert.assertEquals(SimpleString.toSimpleString("moreImportant"), configuration.getAddressesSettings().get("Name.With.Dots").getExpiryAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNameWithDotsSurroundWithDollarDollar() throws Throwable {
|
||||
ConfigurationImpl configuration = new ConfigurationImpl();
|
||||
|
||||
Properties properties = new Properties();
|
||||
|
||||
// overrides the default surrounding string of '"' with '$$' using a property
|
||||
properties.put(ActiveMQDefaultConfiguration.BROKER_PROPERTIES_KEY_SURROUND_PROPERTY, "$$");
|
||||
properties.put("addressesSettings.#.expiryAddress", "sharedExpiry");
|
||||
properties.put("addressesSettings.NeedToTrackExpired.expiryAddress", "important");
|
||||
properties.put("addressesSettings.$$Name.With.Dots$$.expiryAddress", "moreImportant");
|
||||
|
||||
configuration.parsePrefixedProperties(properties, null);
|
||||
|
||||
Assert.assertEquals(3, configuration.getAddressesSettings().size());
|
||||
Assert.assertEquals(SimpleString.toSimpleString("sharedExpiry"), configuration.getAddressesSettings().get("#").getExpiryAddress());
|
||||
Assert.assertEquals(SimpleString.toSimpleString("important"), configuration.getAddressesSettings().get("NeedToTrackExpired").getExpiryAddress());
|
||||
Assert.assertEquals(SimpleString.toSimpleString("moreImportant"), configuration.getAddressesSettings().get("Name.With.Dots").getExpiryAddress());
|
||||
}
|
||||
|
||||
/**
|
||||
* To test ARTEMIS-926
|
||||
* @throws Throwable
|
||||
|
@ -632,7 +751,7 @@ public class ConfigurationImplTest extends ActiveMQTestBase {
|
|||
properties.put(configuration.getSystemPropertyPrefix() + "fileDeployerScanPeriod", "1234");
|
||||
properties.put(configuration.getSystemPropertyPrefix() + "globalMaxSize", "4321");
|
||||
|
||||
configuration.parseSystemProperties(properties);
|
||||
configuration.parsePrefixedProperties(properties, configuration.getSystemPropertyPrefix());
|
||||
|
||||
|
||||
} finally {
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* 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.server.config;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
|
||||
import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
|
||||
import org.apache.activemq.artemis.core.server.embedded.EmbeddedActiveMQ;
|
||||
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
|
||||
import org.junit.Test;
|
||||
|
||||
public class JMSServerPropertyConfigTest extends ActiveMQTestBase {
|
||||
|
||||
@Test
|
||||
public void testConfigViaBrokerPropertiesSystemProperty() throws Exception {
|
||||
EmbeddedActiveMQ server = new EmbeddedActiveMQ();
|
||||
ConfigurationImpl configuration = new ConfigurationImpl();
|
||||
|
||||
configuration.setJournalDirectory(new File(getTestDir(), "./journal").getAbsolutePath()).
|
||||
setPagingDirectory(new File(getTestDir(), "./paging").getAbsolutePath()).
|
||||
setLargeMessagesDirectory(new File(getTestDir(), "./largemessages").getAbsolutePath()).
|
||||
setBindingsDirectory(new File(getTestDir(), "./bindings").getAbsolutePath()).setPersistenceEnabled(true);
|
||||
|
||||
File bindingsDir = new File(configuration.getBindingsDirectory());
|
||||
bindingsDir.mkdirs();
|
||||
File propertiesInBindingsDir = new File(bindingsDir, ActiveMQDefaultConfiguration.BROKER_PROPERTIES_SYSTEM_PROPERTY_NAME);
|
||||
|
||||
try (PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(propertiesInBindingsDir)))) {
|
||||
// use the same name property as from the classpath broker.properties to verify precedence of system prop
|
||||
out.println("name=nameFromCopiedPropertiesRefViaSystemProp");
|
||||
}
|
||||
|
||||
System.setProperty(ActiveMQDefaultConfiguration.BROKER_PROPERTIES_SYSTEM_PROPERTY_NAME, propertiesInBindingsDir.getAbsolutePath());
|
||||
try {
|
||||
|
||||
server.setConfiguration(configuration);
|
||||
server.start();
|
||||
|
||||
assertEquals("nameFromCopiedPropertiesRefViaSystemProp", server.getActiveMQServer().getConfiguration().getName());
|
||||
|
||||
} finally {
|
||||
System.getProperties().remove(ActiveMQDefaultConfiguration.BROKER_PROPERTIES_SYSTEM_PROPERTY_NAME);
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfigViaBrokerPropertiesFromClasspath() throws Exception {
|
||||
|
||||
EmbeddedActiveMQ server = new EmbeddedActiveMQ();
|
||||
ConfigurationImpl configuration = new ConfigurationImpl();
|
||||
|
||||
configuration.setJournalDirectory(new File(getTestDir(), "./journal").getAbsolutePath()).
|
||||
setPagingDirectory(new File(getTestDir(), "./paging").getAbsolutePath()).
|
||||
setLargeMessagesDirectory(new File(getTestDir(), "./largemessages").getAbsolutePath()).
|
||||
setBindingsDirectory(new File(getTestDir(), "./bindings").getAbsolutePath()).setPersistenceEnabled(true);
|
||||
|
||||
try {
|
||||
|
||||
server.setConfiguration(configuration);
|
||||
server.start();
|
||||
|
||||
assertEquals("ConfiguredViaProperties", server.getActiveMQServer().getConfiguration().getName());
|
||||
|
||||
} finally {
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
name=ConfiguredViaProperties
|
Loading…
Reference in New Issue