Chapter 1. Overview AMQ Broker configuration files define important settings for a broker instance. By editing a broker's configuration files, you can control how the broker operates in your environment. 1.1. AMQ Broker configuration files and locations All of a broker's configuration files are stored in <broker_instance_dir> /etc . You can configure a broker by editing the settings in these configuration files. Each broker instance uses the following configuration files: broker.xml The main configuration file. You use this file to configure most aspects of the broker, such as network connections, security settings, message addresses, and so on. bootstrap.xml The file that AMQ Broker uses to start a broker instance. You use it to change the location of broker.xml , configure the web server, and set some security settings. logging.properties You use this file to set logging properties for the broker instance. artemis.profile You use this file to set environment variables used while the broker instance is running. login.config , artemis-users.properties , artemis-roles.properties Security-related files. You use these files to set up authentication for user access to the broker instance. 1.2. Understanding the default broker configuration You configure most of a broker's functionality by editing the broker.xml configuration file. This file contains default settings, which are sufficient to start and operate a broker. However, you will likely need to change some of the default settings and add new settings to configure the broker for your environment. By default, broker.xml contains default settings for the following functionality: Message persistence Acceptors Security Message addresses Default message persistence settings By default, AMQ Broker persistence uses an append-only file journal that consists of a set of files on disk. The journal saves messages, transactions, and other information. <configuration ...> <core ...> ... <persistence-enabled>true</persistence-enabled> <!-- this could be ASYNCIO, MAPPED, NIO ASYNCIO: Linux Libaio MAPPED: mmap files NIO: Plain Java Files --> <journal-type>ASYNCIO</journal-type> <paging-directory>data/paging</paging-directory> <bindings-directory>data/bindings</bindings-directory> <journal-directory>data/journal</journal-directory> <large-messages-directory>data/large-messages</large-messages-directory> <journal-datasync>true</journal-datasync> <journal-min-files>2</journal-min-files> <journal-pool-files>10</journal-pool-files> <journal-file-size>10M</journal-file-size> <!-- This value was determined through a calculation. Your system could perform 8.62 writes per millisecond on the current journal configuration. That translates as a sync write every 115999 nanoseconds. Note: If you specify 0 the system will perform writes directly to the disk. We recommend this to be 0 if you are using journalType=MAPPED and journal-datasync=false. --> <journal-buffer-timeout>115999</journal-buffer-timeout> <!-- When using ASYNCIO, this will determine the writing queue depth for libaio. --> <journal-max-io>4096</journal-max-io> <!-- how often we are looking for how many bytes are being used on the disk in ms --> <disk-scan-period>5000</disk-scan-period> <!-- once the disk hits this limit the system will block, or close the connection in certain protocols that won't support flow control. --> <max-disk-usage>90</max-disk-usage> <!-- should the broker detect dead locks and other issues --> <critical-analyzer>true</critical-analyzer> <critical-analyzer-timeout>120000</critical-analyzer-timeout> <critical-analyzer-check-period>60000</critical-analyzer-check-period> <critical-analyzer-policy>HALT</critical-analyzer-policy> ... </core> </configuration> Default acceptor settings Brokers listen for incoming client connections by using an acceptor configuration element to define the port and protocols a client can use to make connections. By default, AMQ Broker includes an acceptor for each supported messaging protocol, as shown below. <configuration ...> <core ...> ... <acceptors> <!-- Acceptor for every supported protocol --> <acceptor name="artemis">tcp://0.0.0.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300</acceptor> <!-- AMQP Acceptor. Listens on default AMQP port for AMQP traffic --> <acceptor name="amqp">tcp://0.0.0.0:5672?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=AMQP;useEpoll=true;amqpCredits=1000;amqpLowCredits=300</acceptor> <!-- STOMP Acceptor --> <acceptor name="stomp">tcp://0.0.0.0:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true</acceptor> <!-- HornetQ Compatibility Acceptor. Enables HornetQ Core and STOMP for legacy HornetQ clients. --> <acceptor name="hornetq">tcp://0.0.0.0:5445?anycastPrefix=jms.queue.;multicastPrefix=jms.topic.;protocols=HORNETQ,STOMP;useEpoll=true</acceptor> <!-- MQTT Acceptor --> <acceptor name="mqtt">tcp://0.0.0.0:1883?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=MQTT;useEpoll=true</acceptor> </acceptors> ... </core> </configuration> Default security settings AMQ Broker contains a flexible role-based security model for applying security to queues, based on their addresses. The default configuration uses wildcards to apply the amq role to all addresses (represented by the number sign, # ). <configuration ...> <core ...> ... <security-settings> <security-setting match="#"> <permission type="createNonDurableQueue" roles="amq"/> <permission type="deleteNonDurableQueue" roles="amq"/> <permission type="createDurableQueue" roles="amq"/> <permission type="deleteDurableQueue" roles="amq"/> <permission type="createAddress" roles="amq"/> <permission type="deleteAddress" roles="amq"/> <permission type="consume" roles="amq"/> <permission type="browse" roles="amq"/> <permission type="send" roles="amq"/> <!-- we need this otherwise ./artemis data imp wouldn't work --> <permission type="manage" roles="amq"/> </security-setting> </security-settings> ... </core> </configuration> Default message address settings AMQ Broker includes a default address that establishes a default set of configuration settings to be applied to any created queue or topic. Additionally, the default configuration defines two queues: DLQ (Dead Letter Queue) handles messages that arrive with no known destination, and Expiry Queue holds messages that have lived past their expiration and therefore should not be routed to their original destination. <configuration ...> <core ...> ... <address-settings> ... <!--default for catch all--> <address-setting match="#"> <dead-letter-address>DLQ</dead-letter-address> <expiry-address>ExpiryQueue</expiry-address> <redelivery-delay>0</redelivery-delay> <!-- with -1 only the global-max-size is in use for limiting --> <max-size-bytes>-1</max-size-bytes> <message-counter-history-day-limit>10</message-counter-history-day-limit> <address-full-policy>PAGE</address-full-policy> <auto-create-queues>true</auto-create-queues> <auto-create-addresses>true</auto-create-addresses> <auto-create-jms-queues>true</auto-create-jms-queues> <auto-create-jms-topics>true</auto-create-jms-topics> </address-setting> </address-settings> <addresses> <address name="DLQ"> <anycast> <queue name="DLQ" /> </anycast> </address> <address name="ExpiryQueue"> <anycast> <queue name="ExpiryQueue" /> </anycast> </address> </addresses> </core> </configuration> 1.3. Reloading configuration updates By default, a broker checks for changes in the configuration files every 5000 milliseconds. If the broker detects a change in the "last modified" time stamp of the configuration file, the broker determines that a configuration change took place. In this case, the broker reloads the configuration file to activate the changes. When the broker reloads the broker.xml configuration file, it reloads the following modules: Address settings and queues When the configuration file is reloaded, the address settings determine how to handle addresses and queues that have been deleted from the configuration file. You can set this with the config-delete-addresses and config-delete-queues properties. For more information, see Appendix B, Address Setting Configuration Elements . Security settings SSL/TLS keystores and truststores on an existing acceptor can be reloaded to establish new certificates without any impact to existing clients. Connected clients, even those with older or differing certificates, can continue to send and receive messages. The certificate revocation list file, which is configured by using the crlPath parameter, can also be reloaded. Diverts A configuration reload deploys any new divert that you have added. However, removal of a divert from the configuration or a change to a sub-element within a <divert> element do not take effect until you restart the broker. The following procedure shows how to change the interval at which the broker checks for changes to the broker.xml configuration file. Procedure Open the <broker_instance_dir> /etc/broker.xml configuration file. Within the <core> element, add the <configuration-file-refresh-period> element and set the refresh period (in milliseconds). This example sets the configuration refresh period to be 60000 milliseconds: <configuration> <core> ... <configuration-file-refresh-period>60000</configuration-file-refresh-period> ... </core> </configuration> It is also possible to force the reloading of the configuration file using the Management API or the console if for some reason access to the configuration file is not possible. Configuration files can be reloaded using the management operation reloadConfigurationFile() on the ActiveMQServerControl (with the ObjectName org.apache.activemq.artemis:broker=" BROKER_NAME " or the resource name server ) Additional resources To learn how to use the management API, see Using the Management API in Managing AMQ Broker 1.4. Modularizing the broker configuration file If you have multiple brokers that share common configuration settings, you can define the common configuration in separate files, and then include these files in each broker's broker.xml configuration file. The most common configuration settings that you might share between brokers include: Addresses Address settings Security settings Procedure Create a separate XML file for each broker.xml section that you want to share. Each XML file can only include a single section from broker.xml (for example, either addresses or address settings, but not both). The top-level element must also define the element namespace ( xmlns="urn:activemq:core" ). This example shows a security settings configuration defined in my-security-settings.xml : my-security-settings.xml <security-settings xmlns="urn:activemq:core"> <security-setting match="a1"> <permission type="createNonDurableQueue" roles="a1.1"/> </security-setting> <security-setting match="a2"> <permission type="deleteNonDurableQueue" roles="a2.1"/> </security-setting> </security-settings> Open the <broker_instance_dir> /etc/broker.xml configuration file for each broker that should use the common configuration settings. For each broker.xml file that you opened, do the following: In the <configuration> element at the beginning of broker.xml , verify that the following line appears: xmlns:xi="http://www.w3.org/2001/XInclude" Add an XML inclusion for each XML file that contains shared configuration settings. This example includes the my-security-settings.xml file. broker.xml <configuration ...> <core ...> ... <xi:include href="/opt/my-broker-config/my-security-settings.xml"/> ... </core> </configuration> If desired, validate broker.xml to verify that the XML is valid against the schema. You can use any XML validator program. This example uses xmllint to validate broker.xml against the artemis-server.xsl schema. Additional resources For more information about XML Inclusions (XIncludes), see https://www.w3.org/TR/xinclude/ . 1.4.1. Reloading modular configuration files When the broker periodically checks for configuration changes (according to the frequency specified by configuration-file-refresh-period ), it does not automatically detect changes made to configuration files that are included in the broker.xml configuration file via xi:include . For example, if broker.xml includes my-address-settings.xml and you make configuration changes to my-address-settings.xml , the broker does not automatically detect the changes in my-address-settings.xml and reload the configuration. To force a reload of the broker.xml configuration file and any modified configuration files included within it, you must ensure that the "last modified" time stamp of the broker.xml configuration file has changed. You can use a standard Linux touch command to update the last-modified time stamp of broker.xml without making any other changes. For example: Alternatively you can use the management API to force a reload of the Broker. Configuration files can be reloaded using the management operation reloadConfigurationFile() on the ActiveMQServerControl (with the ObjectName org.apache.activemq.artemis:broker=" BROKER_NAME " or the resource name server ) Additional resources To learn how to use the management API, see Using the Management API in Managing AMQ Broker 1.4.2. Disabling External XML Entity (XXE) processing If you don't want to modularize your broker configuration in separate files that are included in the broker.xml file, you can disable XXE processing to protect AMQ Broker against XXE security vulnerabilities. If you don't have a modular broker configuration, Red Hat recommends that you disable XXE processing. Procedure Open the <broker_instance_dir>/etc/artemis.profile file. Add a new argument, -Dartemis.disableXxe , to the JAVA_ARGS list of Java system arguments. -Dartemis.disableXxe=true Save the artemis.profile file. 1.5. Extending the JAVA Classpath By default, JAR files in the <broker_instance_dir> /lib directory are loaded at runtime because the directory is part of the Java classpath. If you want AMQ Broker to load JAR files from a directory other than <broker_instance_dir> /lib , you must add that directory to the Java classpath. To add a directory to the Java class path, you can use either of the following methods: In the <broker_instance_dir>/etc/artemis.profile file, add a new property, artemis.extra.libs to the JAVA_ARGS list of system properties. Set the ARTEMIS_EXTRA_LIBS environment variable. The following are examples of comma-separated lists of directories that are added to the Java Classpath by using both methods: -Dartemis.extra.libs=/usr/local/share/java/lib1,/usr/local/share/java/lib2 export ARTEMIS_EXTRA_LIBS=/usr/local/share/java/lib1,/usr/local/share/java/lib2 Note The ARTEMIS_EXTRA_LIBS environment variable is ignored if the artemis.extra.libs Java system property is configured in the <broker_instance_dir>/etc/artemis.profile file. 1.6. Document conventions This document uses the following conventions for the sudo command, file paths, and replaceable values. The sudo command In this document, sudo is used for any command that requires root privileges. You should always exercise caution when using sudo , as any changes can affect the entire system. For more information about using sudo , see Managing sudo access . About the use of file paths in this document In this document, all file paths are valid for Linux, UNIX, and similar operating systems (for example, /home/... ). If you are using Microsoft Windows, you should use the equivalent Microsoft Windows paths (for example, C:\Users\... ). Replaceable values This document sometimes uses replaceable values that you must replace with values specific to your environment. Replaceable values are lowercase, enclosed by angle brackets ( < > ), and are styled using italics and monospace font. Multiple words are separated by underscores ( _ ) . For example, in the following command, replace <install_dir> with your own directory name. USD <install_dir> /bin/artemis create mybroker

Commands:
<configuration ...> <core ...> <persistence-enabled>true</persistence-enabled> <!-- this could be ASYNCIO, MAPPED, NIO ASYNCIO: Linux Libaio MAPPED: mmap files NIO: Plain Java Files --> <journal-type>ASYNCIO</journal-type> <paging-directory>data/paging</paging-directory> <bindings-directory>data/bindings</bindings-directory> <journal-directory>data/journal</journal-directory> <large-messages-directory>data/large-messages</large-messages-directory> <journal-datasync>true</journal-datasync> <journal-min-files>2</journal-min-files> <journal-pool-files>10</journal-pool-files> <journal-file-size>10M</journal-file-size> <!-- This value was determined through a calculation. Your system could perform 8.62 writes per millisecond on the current journal configuration. That translates as a sync write every 115999 nanoseconds. Note: If you specify 0 the system will perform writes directly to the disk. We recommend this to be 0 if you are using journalType=MAPPED and journal-datasync=false. --> <journal-buffer-timeout>115999</journal-buffer-timeout> <!-- When using ASYNCIO, this will determine the writing queue depth for libaio. --> <journal-max-io>4096</journal-max-io> <!-- how often we are looking for how many bytes are being used on the disk in ms --> <disk-scan-period>5000</disk-scan-period> <!-- once the disk hits this limit the system will block, or close the connection in certain protocols that won't support flow control. --> <max-disk-usage>90</max-disk-usage> <!-- should the broker detect dead locks and other issues --> <critical-analyzer>true</critical-analyzer> <critical-analyzer-timeout>120000</critical-analyzer-timeout> <critical-analyzer-check-period>60000</critical-analyzer-check-period> <critical-analyzer-policy>HALT</critical-analyzer-policy> </core> </configuration>
<configuration ...> <core ...> <acceptors> <!-- Acceptor for every supported protocol --> <acceptor name="artemis">tcp://0.0.0.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300</acceptor> <!-- AMQP Acceptor. Listens on default AMQP port for AMQP traffic --> <acceptor name="amqp">tcp://0.0.0.0:5672?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=AMQP;useEpoll=true;amqpCredits=1000;amqpLowCredits=300</acceptor> <!-- STOMP Acceptor --> <acceptor name="stomp">tcp://0.0.0.0:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true</acceptor> <!-- HornetQ Compatibility Acceptor. Enables HornetQ Core and STOMP for legacy HornetQ clients. --> <acceptor name="hornetq">tcp://0.0.0.0:5445?anycastPrefix=jms.queue.;multicastPrefix=jms.topic.;protocols=HORNETQ,STOMP;useEpoll=true</acceptor> <!-- MQTT Acceptor --> <acceptor name="mqtt">tcp://0.0.0.0:1883?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=MQTT;useEpoll=true</acceptor> </acceptors> </core> </configuration>
<configuration ...> <core ...> <security-settings> <security-setting match="#"> <permission type="createNonDurableQueue" roles="amq"/> <permission type="deleteNonDurableQueue" roles="amq"/> <permission type="createDurableQueue" roles="amq"/> <permission type="deleteDurableQueue" roles="amq"/> <permission type="createAddress" roles="amq"/> <permission type="deleteAddress" roles="amq"/> <permission type="consume" roles="amq"/> <permission type="browse" roles="amq"/> <permission type="send" roles="amq"/> <!-- we need this otherwise ./artemis data imp wouldn't work --> <permission type="manage" roles="amq"/> </security-setting> </security-settings> </core> </configuration>
<configuration ...> <core ...> <address-settings> <!--default for catch all--> <address-setting match="#"> <dead-letter-address>DLQ</dead-letter-address> <expiry-address>ExpiryQueue</expiry-address> <redelivery-delay>0</redelivery-delay> <!-- with -1 only the global-max-size is in use for limiting --> <max-size-bytes>-1</max-size-bytes> <message-counter-history-day-limit>10</message-counter-history-day-limit> <address-full-policy>PAGE</address-full-policy> <auto-create-queues>true</auto-create-queues> <auto-create-addresses>true</auto-create-addresses> <auto-create-jms-queues>true</auto-create-jms-queues> <auto-create-jms-topics>true</auto-create-jms-topics> </address-setting> </address-settings> <addresses> <address name="DLQ"> <anycast> <queue name="DLQ" /> </anycast> </address> <address name="ExpiryQueue"> <anycast> <queue name="ExpiryQueue" /> </anycast> </address> </addresses> </core> </configuration>
<configuration> <core> <configuration-file-refresh-period>60000</configuration-file-refresh-period> </core> </configuration>
<security-settings xmlns="urn:activemq:core"> <security-setting match="a1"> <permission type="createNonDurableQueue" roles="a1.1"/> </security-setting> <security-setting match="a2"> <permission type="deleteNonDurableQueue" roles="a2.1"/> </security-setting> </security-settings>
xmlns:xi="http://www.w3.org/2001/XInclude"
<configuration ...> <core ...> <xi:include href="/opt/my-broker-config/my-security-settings.xml"/> </core> </configuration>
xmllint --noout --xinclude --schema /opt/redhat/amq-broker/amq-broker-7.2.0/schema/artemis-server.xsd /var/opt/amq-broker/mybroker/etc/broker.xml /var/opt/amq-broker/mybroker/etc/broker.xml validates
touch -m <broker_instance_dir> /etc/broker.xml
-Dartemis.disableXxe=true
-Dartemis.extra.libs=/usr/local/share/java/lib1,/usr/local/share/java/lib2
export ARTEMIS_EXTRA_LIBS=/usr/local/share/java/lib1,/usr/local/share/java/lib2
<install_dir> /bin/artemis create mybroker