<!--
    Copyright (c) 2017, NextGate Solutions All Rights Reserved.

    This program, and all the NextGate Solutions authored routines referenced herein,
    are the proprietary properties and trade secrets of NextGate Solutions.

    Except as provided for by license agreement, this program shall not be duplicated,
    used, reversed engineered, decompiled, disclosed, shared, transferred, placed in a
    publicly available location (such as but not limited to ftp sites, bit torrents,
    shared drives, peer to peer networks, and such) without  written consent signed by
    an officer of NextGate Solutions.

    DISCLAIMER:

    This software is provided as is without warranty of any kind. The entire risk as to
    the results and performance of this software is assumed by the licensee and/or its
    affiliates and/or assignees. NextGate Solutions disclaims all warranties, either
    expressed or implied, including but not limited to the implied warranties of
    merchantability, fitness for a particular purpose, title and non-infringement, with
    respect to this software.

    - version control -
    $Id: activemq.xml 29591 2017-10-24 17:12:47Z peter.berkman $
-->

<beans xmlns="http://www.springframework.org/schema/beans"
       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
                           http://activemq.apache.org/camel/schema/spring http://activemq.apache.org/camel/schema/spring/camel-spring.xsd">

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    
        <!-- 
            Allows us to use system properties as variables in this configuration file 
        -->
        
        <property name="locations">
            <value>file:${karaf.base}/etc/activemq/credentials.properties</value>
        </property>
    </bean>

    <broker xmlns="http://activemq.apache.org/schema/core"
            brokerId="${broker-name}"
            brokerName="${broker-name}"
            useJmx="true"
            populateJMSXUserID="true"
            dataDirectory="${data}"
            start="false"
            restartAllowed="false">

        <!-- 
            broker-name and data are set in etc/org.apache.activemq.server-default.cfg 
        -->
        
        <plugins>
            <!--
                Security: http://activemq.apache.org/security.html 
            -->

            <jaasAuthenticationPlugin configuration="karaf" />
            
            <authorizationPlugin>
                <map>
                    <authorizationMap groupClass="org.apache.karaf.jaas.boot.principal.RolePrincipal">
                        <authorizationEntries>
                            <authorizationEntry queue=">" read="jmssubscriber" write="jmspublisher" admin="jmsadmin" />
                            <authorizationEntry topic=">" read="jmssubscriber" write="jmspublisher" admin="jmsadmin" />
                            <authorizationEntry topic="ActiveMQ.Advisory.>" read="jmssubscriber" write="jmspublisher" admin="jmsadmin"/>
                        </authorizationEntries>
                    </authorizationMap>
                </map>
            </authorizationPlugin>
            
            <!--
                http://activemq.apache.org/runtime-configuration.html 
            -->
            <runtimeConfigurationPlugin checkPeriod="2000" />
        </plugins>
        
        <destinationPolicy>
            <!--
                For better performances use VM cursor and small memory limit.
                For more information, see:
     
                http://activemq.apache.org/message-cursors.html
     
                Also, if your producer is "hanging", it's probably due to producer flow control.
                For more information, see:
    
                http://activemq.apache.org/producer-flow-control.html
            -->
    
            <!-- 
                The constantPendingMessageLimitStrategy is used to prevent
                slow topic consumers to block producers and affect other consumers
                by limiting the number of messages that are retained
                For more information, see:
    
                http://activemq.apache.org/slow-consumer-handling.html
            -->
        
            <policyMap>
                <policyEntries>
                    <policyEntry topic=">" producerFlowControl="false" cursorMemoryHighWaterMark="30" memoryLimit="64mb">
                        <pendingSubscriberPolicy>
                            <vmCursor />
                        </pendingSubscriberPolicy>
                    </policyEntry>
                    
                    <policyEntry queue="ngmmNotificationsPerson" producerFlowControl="false" cursorMemoryHighWaterMark="30" memoryLimit="64mb">
                        <pendingQueuePolicy>
                            <fileQueueCursor />
                        </pendingQueuePolicy>
                    </policyEntry>
                    
                    <policyEntry queue="ngmmNotificationsProvider" producerFlowControl="false" cursorMemoryHighWaterMark="30" memoryLimit="64mb">
                        <pendingQueuePolicy>
                            <fileQueueCursor />
                        </pendingQueuePolicy>
                    </policyEntry>
                
                    <policyEntry queue=">" producerFlowControl="true" cursorMemoryHighWaterMark="30" memoryLimit="64mb">
                        <pendingQueuePolicy>
                            <fileQueueCursor />
                        </pendingQueuePolicy>
                    </policyEntry>
                </policyEntries>
            </policyMap>
        </destinationPolicy>

        <managementContext>
            <!-- 
                http://activemq.apache.org/jmx.html
            -->
            <managementContext createConnector="false"/>
        </managementContext>

        <persistenceAdapter>
            <!--
                Configure message persistence for the broker. The default persistence
                mechanism is the KahaDB store (identified by the kahaDB tag).
                For more information, see:
                
                http://activemq.apache.org/kahadb.html
                http://activemq.apache.org/persistence.html
            -->
    
            <!--
                Configuration for JDBC Master Slave.
                
                if you are using the JDBC persistanceAdapter, make sure to comment out the
                mKahaDB adapter section below and uncomment the jdbcPersistenceAdapter section.
                
                Also, uncomment out one of the JDBC datasource entries near the bottom and adjust
                the configuration per your database settings.
                
                http://activemq.apache.org/jdbc-master-slave.html
                http://activemq.apache.org/pluggable-storage-lockers.html  
            -->
            
            <!-- [BEGIN] AMQ JDBC PERSISTENCE -->  
            <jdbcPersistenceAdapter dataDirectory="${data}" dataSource="#mysql-ds" lockKeepAlivePeriod="10000">
                <locker>
                    <lease-database-locker lockAcquireSleepInterval="30000"/>
                </locker>
            </jdbcPersistenceAdapter>
            <!-- [END] AMQ JDBC PERSISTENCE -->  
            
            <!-- [BEGIN] AMQ KAHADB PERSISTENCE   
            <mKahaDB directory="${data}/kahadb">
                <filteredPersistenceAdapters>
                    <filteredKahaDB queue="ngmsErrors>">
                        <persistenceAdapter>
                            <kahaDB
                                preallocationStrategy="zeros"
                                ignoreMissingJournalfiles="true" 
                                checkForCorruptJournalFiles="true" 
                                checksumJournalFiles="true"/>
                        </persistenceAdapter>
                    </filteredKahaDB>
                    <filteredKahaDB queue="ActiveMQ.DLQ">
                        <persistenceAdapter>
                            <kahaDB 
                                preallocationStrategy="zeros"
                                ignoreMissingJournalfiles="true" 
                                checkForCorruptJournalFiles="true" 
                                checksumJournalFiles="true"/>
                        </persistenceAdapter>
                    </filteredKahaDB>
                    <filteredKahaDB>
                        <persistenceAdapter>
                            <kahaDB 
                                preallocationStrategy="zeros"
                                ignoreMissingJournalfiles="true" 
                                checkForCorruptJournalFiles="true" 
                                checksumJournalFiles="true"/>
                        </persistenceAdapter>
                    </filteredKahaDB>
                </filteredPersistenceAdapters>
            </mKahaDB>
            [END] AMQ KAHADB PERSISTENCE -->    
        </persistenceAdapter>

        <systemUsage>
            <!--
                The systemUsage controls the maximum amount of space the broker will
                use before slowing down producers. For more information, see:
    
                http://activemq.apache.org/producer-flow-control.html
            -->
    
            <systemUsage sendFailIfNoSpace="true">
                <memoryUsage>
                    <memoryUsage percentOfJvmHeap="25" />
                </memoryUsage>
                
                <storeUsage>
                    <storeUsage limit="100 gb" name="ngs"/>
                </storeUsage>
                
                <tempUsage>
                    <tempUsage limit="50 gb"/>
                </tempUsage>
            </systemUsage>
        </systemUsage>
        
        <!-- 
            http://activemq.apache.org/networks-of-brokers.html
            
            The following is the setting for node1 (where node1 is primary), simply change the host 
            references for other nodes.
        -->
        <!-- [BEGIN] AMQ NETWORK OF BROKERS
        <networkConnectors>
            <networkConnector   name="AMQBridgeErrors_${broker-name}"
                                uri="masterslave:(tcp://localhost:8206,tcp://localhost:7206,tcp://localhost:6206)"
                                networkTTL="3"
                                userName="${activemq.username}" password="${activemq.password}">
                <staticallyIncludedDestinations>
                    <queue physicalName="ActiveMQ.DLQ"/>
                    <queue physicalName="ngmsErrors"/>
                    <queue physicalName="ngmsEmailAlert"/>
                </staticallyIncludedDestinations>
            </networkConnector>

            <networkConnector   name="AMQBridgeOutbound_${broker-name}"
                                uri="masterslave:(tcp://localhost:8206,tcp://localhost:7206,tcp://localhost:6206)"
                                networkTTL="3"
                                userName="${activemq.username}" password="${activemq.password}">
                <staticallyIncludedDestinations>
                    <queue physicalName="ngmsOutboundFileWriterProcessing"/>
                    <queue physicalName="ngmsOutboundMockQueue"/>
                    <queue physicalName="ngmsOutboundHL7v2Feed"/>
                    <queue physicalName="ngmsOutboundPIXSender"/>
                    <queue physicalName="ngmsMMRegistryProcessing"/>
                    <queue physicalName="ngmsEventRegistryNotifications"/>
                </staticallyIncludedDestinations>
            </networkConnector>
        </networkConnectors>
        [END] AMQ NETWORK OF BROKERS -->
        
        <transportConnectors>
            <!--
                The transport connectors expose ActiveMQ over a given protocol to
                clients and other brokers. For more information, see:
     
                http://activemq.apache.org/configuring-transports.html

                DOS protection, limit concurrent connections to 1000 and frame size to 100MB 
                
                For AMQ Cluster setup, uncomment the following transportConnector section and comment out
                the local connector section.  The AMQ Cluster setup must allow connections from "off-box", so
                you must not listen on the loopback adapter only (localhost).
            -->
            <!-- [BEGIN] AMQ CLUSTER CONNECTOR -->
            <transportConnector name="openwire" uri="tcp://0.0.0.0:8206?maximumConnections=1000&amp;wireformat.maxFrameSize=104857600"/>
            <transportConnector name="amqp" uri="amqp://0.0.0.0:8672?maximumConnections=1000&amp;wireformat.maxFrameSize=104857600"/>
            <!-- [END] AMQ CLUSTER CONNECTOR -->
            
            <!-- [BEGIN] AMQ LOCAL CONNECTOR
            <transportConnector name="openwire" uri="tcp://localhost:8206?maximumConnections=1000&amp;wireformat.maxFrameSize=104857600"/>
            <transportConnector name="amqp" uri="amqp://localhost:8672?maximumConnections=1000&amp;wireformat.maxFrameSize=104857600"/>
            [END] AMQ LOCAL CONNECTOR -->

            <transportConnector name="vm" uri="vm://${broker-name}?async=false&amp;warnAboutUnstartedConnectionTimeout=-1"/>
        </transportConnectors>
        
        <shutdownHooks>
            <!-- destroy the spring context on shutdown to stop jetty -->
            <bean xmlns="http://www.springframework.org/schema/beans" class="org.apache.activemq.hooks.SpringContextHook" />
        </shutdownHooks>        
    </broker>

    <!-- [BEGIN] AMQ JDBC DATASOURCE MYSQL -->
    <bean id="mysql-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>  
        <property name="url" value="jdbc:mysql://localhost/activemq?relaxAutoCommit=true&amp;useJDBCCompliantTimezoneShift=true"/>  
        <property name="username" value="activemq"/>  
        <property name="password" value="activemq"/>  
        <property name="maxActive" value="200"/>  
        <property name="poolPreparedStatements" value="true"/>  
    </bean>  
    <!-- [END] AMQ JDBC DATASOURCE MYSQL -->
     
     
    <!-- [BEGIN] AMQ JDBC DATASOURCE MARIADB
    <bean id="mariadb-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
        <property name="driverClassName" value="com.mariadb.jdbc.Driver"/>  
        <property name="url" value="jdbc:mariadb://localhost/activemq?relaxAutoCommit=true&amp;useJDBCCompliantTimezoneShift=true"/>  
        <property name="username" value="activemq"/>  
        <property name="password" value="activemq"/>  
        <property name="maxActive" value="200"/>  
        <property name="poolPreparedStatements" value="true"/>  
    </bean>  
    [END] AMQ JDBC DATASOURCE MARIADB -->
     
     
    <!-- [BEGIN] AMQ JDBC DATASOURCE ORACLE
    <bean id="oracle-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
        <property name="url" value="jdbc:oracle:thin:@localhost:1521:AMQDB"/>
        <property name="username" value="scott"/>
        <property name="password" value="tiger"/>
        <property name="poolPreparedStatements" value="true"/>
    </bean>
    [END] AMQ JDBC DATASOURCE ORACLE -->
       
    <bean id="jmsPolicyRedelivery" class="org.apache.activemq.RedeliveryPolicy">
    
        <property name="maximumRedeliveries" value="10"/>
        <property name="useExponentialBackOff" value="true"/>
        <property name="backOffMultiplier" value="5"/>
        <property name="queue" value="*" />
    </bean>
    
    <bean id="jmsReconnectionPolicy" class="org.apache.activemq.network.jms.ReconnectionPolicy">
        <property name="maxReconnectAttempts" value="10"/>
    </bean>

    <bean id="jmsPolicyPrefetch" class="org.apache.activemq.ActiveMQPrefetchPolicy">
    
        <!--
            http://activemq.apache.org/what-is-the-prefetch-limit-for.html 
        -->
        <property name="queuePrefetch" value="1000" />
        <property name="topicPrefetch" value="500" />
        <property name="durableTopicPrefetch" value="1000" />
    </bean>
    
    <bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">

        <!--
            To support AMQ Clustering, uncomment the following 'brokerURL' property setting, change the hostnames, add other hosts
            if applicable, and comment out the SINGLE 'brokerURL' property setting below. 
        -->
        
        <!-- [BEGIN] AMQ BROKERURL FAILOVER -->
        <property name="brokerURL" value="failover:(tcp://localhost:8206,tcp://localhost:7206)" />
        <!-- [END] AMQ BROKERURL FAILOVER -->
       
        <!-- [BEGIN] AMQ BROKERURL SINGLE
        <property name="brokerURL" value="tcp://localhost:8206" />
        [END] AMQ BROKERURL SINGLE -->

        <property name="trustAllPackages" value="true"/>
       
        <property name="optimizeAcknowledge" value="true" /> <!-- http://activemq.apache.org/performance-tuning.html -->
        <property name="alwaysSessionAsync" value="false" /> <!-- http://activemq.apache.org/performance-tuning.html -->
       
        <property name="prefetchPolicy" ref="jmsPolicyPrefetch" />
        <property name="redeliveryPolicy" ref="jmsPolicyRedelivery" />
       
        <property name="watchTopicAdvisories" value="false" />
    </bean>
    
    <bean id="jmsPooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" init-method="start" destroy-method="stop">
    
       <property name="connectionFactory" ref="jmsConnectionFactory" />
       <property name="maxConnections" value="8" />
       <property name="idleTimeout" value="0" />
    </bean>
</beans>
