6.6. Tutorial: Configuring ActiveMQ JDBC Persistence on Fabric Container with PostgreSQL
Overview
This tutorial provides instructions for configuring ActiveMQ JDBC Persistence on Fabric Container using PostgreSQL database to store the broker's data.
This tutorial assumes that the PostgreSQL is provided as a JAR file on the local filesystem of each broker and referenced using a file:URI. If a filesystem location is used, then the location needs to be the same on each broker instance, or the configuration becomes uncoordinated.
The brokers must have fixed, known port numbers. In this example, a single broker is used which has a fixed port number. This port number is provided in a child profile. In case of multiple brokers, the brokers in the group could have the same configuration but different port numbers. You can create additional child profiles with different port numbers.
Prerequisites
Before following the instructions for this tutorial, make sure that your system satisfies the following prerequisites:
- You have already installed a PostgreSQL database server.
- The PostgreSQL database server is already running.
- You have root access to the PostgreSQL database server (that is, you have access to the root user account in PostgreSQL, which you can use to administer the database).
- You have access to the internet so that you can install the PostgreSQL JDBC driver bundle and the Apache Commons data source bundle, both of which must be downloaded from the Maven Central repository.
Steps to configure JDBC persistence with PostgreSQL
To configure Red Hat JBoss A-MQ broker to use JDBC persistence with PostgreSQL on a fabric container, perform following steps:
Procedure 6.1. Configure PostgreSQL database
- Log into the PostgreSQL database. Enter the following command to log on as the root user:
su - postgres psql
- Add the new user account
amq
to PostgreSQL with passwordamqPass
, by entering the following command:postgres=# create ROLE amq LOGIN PASSWORD 'amqPass' SUPERUSER; CREATE ROLE
- Create the
activemq
database instance, by entering the following command:postgres=# CREATE DATABASE activemq WITH OWNER = amq; CREATE DATABASE
- Grant privileges to the
amq
user, enabling it to access the activemq database instance (which has yet to be created). Enter the followingGRANT
command at the postgresql shell prompt:postgres=# GRANT CONNECT ON DATABASE activemq TO amq; GRANT
There is no need to create any database tables at this point. The broker's JDBC persistence will automatically create the necessary tables when it starts up for the first time. - Stop and restart the PostgreSQL server.
# service postgresql stop Stopping postgresql service: [ OK ] # service postgresql start Starting postgresql service:
Procedure 6.2. Create A-MQ Broker Group
- In JBoss A-MQ, start the local container as follows:
cd InstallDir/bin ./amq
- Create a broker group in a fabric container as follows:
JBossA-MQ:karaf@root> fabric:create --clean --wait-for-provisioning JBossA-MQ:karaf@root> fabric:mq-create --kind MasterSlave --group BrokerGroup AMQBroker
- Install the
PostgreSQL JDBC
driver into the container, as follows:JBossA-MQ:karaf@root> profile-edit --bundle wrap:file:///$DRIVER_PATH/postgresql-9.4-1206-jdbc4.jar mq-broker-BrokerGroup.AMQBroker
- Install the
Apache Commons
data source bundle andosgi.compendium
bundle as follows:JBossA-MQ:karaf@root> profile-edit --bundle mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.commons-dbcp/1.4_3 mq-broker-BrokerGroup.AMQBroker JBossA-MQ:karaf@root> profile-edit --bundle mvn:org.osgi/org.osgi.compendium/4.3.1 mq-broker-BrokerGroup.AMQBroker
- Create a child container:
JBossA-MQ:karaf@root> fabric:container-create-child --profile mq-broker-BrokerGroup.AMQBroker root broker-container1
- Enter following command to view the newly created container.
JBossA-MQ:karaf@root> container-list
- Stop the JBoss A-MQ container by entering following command at the console:
JBossA-MQ:karaf@root> container-stop broker-container1
Procedure 6.3. Create a custom JDBC broker configuration
When you use
mq-create
command, it creates a fabric profile which can be assigned to a container to instantiate an A-MQ message broker in that container. However, that profile does not have its own broker configuration file (for example, activemq.xml/broker.xml
), but inherits it from the parent profile. Since this is the default configuration file, it assumes KahaDB
persistence and also defaults to other settings. Hence it is necessary to create and configure a customized broker, without affecting the fabric defaults. For this, you need to add a customized configuration XML file to this profile and instruct fabric to use it. You can achieve this using Hawtio Web console
.
- Log in to Hawtio console and navigate to the mq-base profile in the console. Open the
broker.xml
and copy its contents to a text editor. - Navigate to newly created profile
mq-broker-BrokerGroup.AMQBroker
and click the+ Create
button in the top right hand corner. - Select XML document option. Enter the name of the file as
jdbc-broker.xml
and click Create. An empty xml document opens. Paste the content copied in the step 1. An example code is given below.<beans xmlns="http://www.springframework.org/schema/beans" xmlns:amq="http://activemq.apache.org/schema/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd"> <!-- Allows us to use system properties and fabric as variables in this configuration file --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="properties"> <bean class="io.fabric8.mq.fabric.ConfigurationProperties"/> </property> </bean> <bean id="postgres-ds" class="org.postgresql.ds.PGSimpleDataSource"> <property name="url" value="jdbc:postgresql://localhost/activemq"/> <property name="user" value="amq"/> <property name="password" value="amqPass"/> <property name="initialConnections" value="1"/> <property name="maxConnections" value="10"/> </bean> <broker xmlns="http://activemq.apache.org/schema/core" brokerName="${broker-name}" dataDirectory="${data}" start="false" restartAllowed="false"> <destinationPolicy> <policyMap> <policyEntries> <policyEntry topic=">" producerFlowControl="true"> <pendingMessageLimitStrategy> <constantPendingMessageLimitStrategy limit="1000"/> </pendingMessageLimitStrategy> </policyEntry> <policyEntry queue=">" producerFlowControl="true" memoryLimit="1mb"> </policyEntry> </policyEntries> </policyMap> </destinationPolicy> <managementContext> <managementContext createConnector="false"/> </managementContext> <persistenceAdapter> <jdbcPersistenceAdapter dataSource="#postgres-ds" lockKeepAlivePeriod="5000"> <locker> <lease-database-locker lockAcquireSleepInterval="10000"/> </locker> </jdbcPersistenceAdapter> </persistenceAdapter> <plugins> <jaasAuthenticationPlugin configuration="karaf" /> <authorizationPlugin> <map> <authorizationMap groupClass="org.apache.karaf.jaas.boot.principal.RolePrincipal"> <!-- manager,viewer,Operator,Maintainer,Deployer,Auditor,Administrator,SuperUser,admin,User --> <authorizationEntries> <authorizationEntry queue=">" read="manager,viewer,Operator,Maintainer,Deployer,Auditor,Administrator,SuperUser,admin" write="manager,Operator,Maintainer,Deployer,Auditor,Administrator,SuperUser,admin" admin="manager,Operator,Maintainer,Deployer,Auditor,Administrator,SuperUser,admin"/> <authorizationEntry topic=">" read="manager,viewer,Operator,Maintainer,Deployer,Auditor,Administrator,SuperUser,admin" write="manager,Operator,Maintainer,Deployer,Auditor,Administrator,SuperUser,admin" admin="manager,Operator,Maintainer,Deployer,Auditor,Administrator,SuperUser,admin"/> <authorizationEntry topic="ActiveMQ.Advisory.>" read="manager,viewer,Operator,Maintainer,Deployer,Auditor,Administrator,SuperUser,admin,User" write="manager,viewer,Operator,Maintainer,Deployer,Auditor,Administrator,SuperUser,admin,User" admin="manager,viewer,Operator,Maintainer,Deployer,Auditor,Administrator,SuperUser,admin,User" /> </authorizationEntries> <tempDestinationAuthorizationEntry> <tempDestinationAuthorizationEntry read="manager,viewer,Operator,Maintainer,Deployer,Auditor,Administrator,SuperUser,admin" write="manager,Operator,Maintainer,Deployer,Auditor,Administrator,SuperUser,admin" admin="manager,Operator,Maintainer,Deployer,Auditor,Administrator,SuperUser,admin"/> </tempDestinationAuthorizationEntry> </authorizationMap> </map> </authorizationPlugin> </plugins> <systemUsage> <systemUsage> <memoryUsage> <memoryUsage percentOfJvmHeap="70"/> </memoryUsage> <storeUsage> <storeUsage limit="100 gb"/> </storeUsage> <tempUsage> <tempUsage limit="50 gb"/> </tempUsage> </systemUsage> </systemUsage> <transportConnectors> <transportConnector name="openwire" uri="tcp://${bindAddress}:${bindPort}"/> </transportConnectors> </broker> <beans>
- Edit the broker/persistenceAdapter element in the
jdbc-broker.xml
as follows:<persistenceAdapter> <jdbcPersistenceAdapter dataSource="#postgres-ds" lockKeepAlivePeriod="5000"> <locker> <lease-database-locker lockAcquireSleepInterval="10000"/> </locker> </jdbcPersistenceAdapter> </persistenceAdapter>
- Add a new bean element for the PostgreSQL data source as follows:
<beans...> <bean id="postgres-ds" class="org.postgresql.ds.PGSimpleDataSource"> <property name="url" value="jdbc:postgresql://localhost/activemq"/> <property name="user" value="amq"/> <property name="password" value="amqPass"/> <property name="initialConnections" value="1"/> <property name="maxConnections" value="10"/> <bean> <beans>
- Click Save to save the newly created
jdbc-broker.xml
document. - Navigate to
mq-broker-BrokerGroup.AMQBroker
broker profile. Edit the configuration properties fileio.fabric8.mq.fabric.server-broker.properties
to assign newly createdjdbc-broker.xml
file as shown below.config = profile:jdbc-broker.xml
- Click Save.
Procedure 6.4. Verify Broker configuration and creation of data tables
- Restart the JBoss A-MQ container, as follows:
container-start broker-container1
- To verify that the requisite tables have been created in the activemq database instance, enter the following commands at the postgres client shell:
$ su - postgres Password: -bash-4.1$ psql # connect to activemq schema postgres=# \c activemq # check tables activemq=# \dt List of relations Schema | Name | Type | Owner --------+---------------+-------+---------- public | activemq_acks | table | activemq public | activemq_lock | table | activemq public | activemq_msgs | table | activemq (3 rows) # run select query. activemq=# select * from activemq_lock; id | time | broker_name ----+---------------+-------------- 1 | 1506947282760 | broker-container1