From 9009d12b5a1e5aab5e89b04e325077b49d9890b0 Mon Sep 17 00:00:00 2001 From: Clebert Suconic Date: Tue, 15 Nov 2016 15:10:49 -0500 Subject: [PATCH] ARTEMIS-851 Allowing broker configuration to be changed through system properties This will use Bean Utilities to change propertyes at the main configuration. --- .../config/ActiveMQDefaultConfiguration.java | 6 +++ .../artemis/core/config/Configuration.java | 25 ++++++++++ .../core/config/impl/ConfigurationImpl.java | 47 +++++++++++++++++++ .../core/config/impl/FileConfiguration.java | 2 + .../impl/FileConfigurationParser.java | 2 + .../core/server/impl/ActiveMQServerImpl.java | 2 + .../schema/artemis-configuration.xsd | 8 ++++ .../config/impl/ConfigurationImplTest.java | 15 ++++++ docs/user-manual/en/configuration-index.md | 19 ++++++++ 9 files changed, 126 insertions(+) diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java index 60dd3eb747..33e7faad03 100644 --- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java +++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java @@ -438,6 +438,8 @@ public final class ActiveMQDefaultConfiguration { public static final int DEFAULT_DISK_SCAN = 5000; + public static final String DEFAULT_SYSTEM_PROPERTY_PREFIX = "brokerconfig."; + /** * If true then the ActiveMQ Artemis Server will make use of any Protocol Managers that are in available on the classpath. If false then only the core protocol will be available, unless in Embedded mode where users can inject their own Protocol Managers. */ @@ -1175,4 +1177,8 @@ public final class ActiveMQDefaultConfiguration { public static int getDefaultDiskScanPeriod() { return DEFAULT_DISK_SCAN; } + + public static String getDefaultSystemPropertyPrefix() { + return DEFAULT_SYSTEM_PROPERTY_PREFIX; + } } diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java index c1ed6ce4be..8f4b97d174 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java @@ -20,6 +20,7 @@ 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 org.apache.activemq.artemis.api.core.BroadcastGroupConfiguration; @@ -49,6 +50,30 @@ public interface Configuration { */ Configuration setName(String name); + + /** + * We use Bean-utils to pass in System.properties that start with {@link #setSystemPropertyPrefix(String)}. + * The default should be 'brokerconfig.' (Including the "."). + * For example if you want to set clustered through a system property you must do: + * + * -Dbrokerconfig.clustered=true + * + * The prefix is configured here. + * @param systemPropertyPrefix + * @return + */ + Configuration setSystemPropertyPrefix(String systemPropertyPrefix); + + /** + * See doc at {@link #setSystemPropertyPrefix(String)}. + * @return + */ + String getSystemPropertyPrefix(); + + Configuration parseSystemProperties() throws Exception; + + Configuration parseSystemProperties(Properties properties) throws Exception; + /** * Returns whether this server is clustered.
* {@code true} if {@link #getClusterConfigurations()} is not empty. diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java index 53a5e089d6..dce0998434 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java @@ -36,6 +36,7 @@ import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Properties; import java.util.Set; import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration; @@ -63,10 +64,14 @@ import org.apache.activemq.artemis.core.settings.impl.ResourceLimitSettings; import org.apache.activemq.artemis.uri.AcceptorTransportConfigurationParser; import org.apache.activemq.artemis.uri.ConnectorTransportConfigurationParser; import org.apache.activemq.artemis.utils.ObjectInputStreamWithClassLoader; +import org.apache.activemq.artemis.utils.uri.BeanSupport; +import org.jboss.logging.Logger; public class ConfigurationImpl implements Configuration, Serializable { // Constants ------------------------------------------------------------------------------ + private static final Logger logger = Logger.getLogger(ConfigurationImpl.class); + public static final JournalType DEFAULT_JOURNAL_TYPE = JournalType.ASYNCIO; private static final long serialVersionUID = 4077088945050267843L; @@ -254,6 +259,8 @@ public class ConfigurationImpl implements Configuration, Serializable { private int diskScanPeriod = ActiveMQDefaultConfiguration.getDefaultDiskScanPeriod(); + private String systemPropertyPrefix = ActiveMQDefaultConfiguration.getDefaultSystemPropertyPrefix(); + /** * Parent folder for all data folders. */ @@ -261,6 +268,46 @@ public class ConfigurationImpl implements Configuration, Serializable { // Public ------------------------------------------------------------------------- + @Override + public Configuration setSystemPropertyPrefix(String systemPropertyPrefix) { + this.systemPropertyPrefix = systemPropertyPrefix; + return this; + } + + @Override + public String getSystemPropertyPrefix() { + return systemPropertyPrefix; + } + + + @Override + public Configuration parseSystemProperties() throws Exception { + parseSystemProperties(System.getProperties()); + return this; + } + + @Override + public Configuration parseSystemProperties(Properties properties) throws Exception { + + Map beanProperties = new HashMap<>(); + + + for (Map.Entry 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()); + } + } + + if (!beanProperties.isEmpty()) { + BeanSupport.setData(this, beanProperties); + } + + return this; + } + + @Override public boolean isClustered() { return !getClusterConfigurations().isEmpty(); diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/FileConfiguration.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/FileConfiguration.java index 16e97452a4..40bfc1a309 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/FileConfiguration.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/FileConfiguration.java @@ -56,6 +56,8 @@ public final class FileConfiguration extends ConfigurationImpl implements Deploy setConfigurationUrl(url); + parseSystemProperties(); + parsed = true; } diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java index 02a9e94d88..3ea95d8468 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java @@ -217,6 +217,8 @@ public final class FileConfigurationParser extends XMLConfigurationUtil { config.setName(getString(e, "name", config.getName(), Validators.NO_CHECK)); + config.setSystemPropertyPrefix(getString(e, "system-property-prefix", config.getSystemPropertyPrefix(), Validators.NOT_NULL_OR_EMPTY)); + NodeList haPolicyNodes = e.getElementsByTagName("ha-policy"); if (haPolicyNodes.getLength() > 0) { diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java index 2cd9328cb6..c112892aea 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java @@ -435,6 +435,8 @@ public class ActiveMQServerImpl implements ActiveMQServer { return; } + configuration.parseSystemProperties(); + startDate = new Date(); state = SERVER_STATE.STARTING; diff --git a/artemis-server/src/main/resources/schema/artemis-configuration.xsd b/artemis-server/src/main/resources/schema/artemis-configuration.xsd index a58c33fc91..e6505405eb 100644 --- a/artemis-server/src/main/resources/schema/artemis-configuration.xsd +++ b/artemis-server/src/main/resources/schema/artemis-configuration.xsd @@ -34,6 +34,14 @@ + + + + This defines the prefix which we will use to parse System properties for the configuration. Default= + + + + diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImplTest.java b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImplTest.java index 3fd1aaaccc..19dd8aab55 100644 --- a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImplTest.java +++ b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImplTest.java @@ -17,6 +17,7 @@ package org.apache.activemq.artemis.core.config.impl; import java.io.File; +import java.util.Properties; import org.apache.activemq.artemis.ArtemisConstants; import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration; @@ -543,6 +544,20 @@ public class ConfigurationImplTest extends ActiveMQTestBase { } + + @Test + public void testSetSystemProperty() throws Throwable { + ConfigurationImpl configuration = new ConfigurationImpl(); + Properties properties = new Properties(); + properties.put(configuration.getSystemPropertyPrefix() + "fileDeployerScanPeriod", "1234"); + properties.put(configuration.getSystemPropertyPrefix() + "globalMaxSize", "4321"); + + configuration.parseSystemProperties(properties); + + Assert.assertEquals(1234, configuration.getFileDeployerScanPeriod()); + Assert.assertEquals(4321, configuration.getGlobalMaxSize()); + } + @Override @Before public void setUp() throws Exception { diff --git a/docs/user-manual/en/configuration-index.md b/docs/user-manual/en/configuration-index.md index 240d6db8dc..895fe771da 100644 --- a/docs/user-manual/en/configuration-index.md +++ b/docs/user-manual/en/configuration-index.md @@ -15,6 +15,24 @@ This is the main core server configuration file which contains to elements The 'core' element contains the main server configuration while the 'jms' element is used by the server side JMS service to load JMS Queues, Topics +# System properties + +It is possible to use System properties to replace some of the configuration properties. If you define a System property starting with "brokerconfig." that will be passed along to Bean Utils and the configuration would be replaced. + +To define global-max-size=1000000 using a system property you would have to define this property, for example through java arguments: + +``` +java -Dbrokerconfig.globalMaxSize=1000000 +``` + +You can also change the prefix through the broker.xml by setting: + +``` +yourprefix +``` + +This is to help you customize artemis on embedded systems. + # The core configuration This describes the root of the XML configuration. You will see here also multiple sub-types listed. @@ -87,6 +105,7 @@ Name | Description [scheduled-thread-pool-max-size](thread-pooling.md#server.scheduled.thread.pool "Server Scheduled Thread Pool")| Maximum number of threads to use for the scheduled thread pool. Default=5 [security-enabled](security.md "Security") | true means that security is enabled. Default=true [security-invalidation-interval](security.md "Security") | how long (in ms) to wait before invalidating the security cache. Default=10000 +system-property-prefix | Prefix for replacing configuration settings using Bean Utils. [populate-validated-user](security.md "Security") | whether or not to add the name of the validated user to the messages that user sends. Default=false [security-settings](security.md "Role based security for addresses") | [a list of security-setting](#security-setting-type) [thread-pool-max-size](thread-pooling.md "Server Scheduled Thread Pool") | Maximum number of threads to use for the thread pool. -1 means 'no limits'.. Default=30