<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE mule-configuration PUBLIC "-//MuleSource //DTD mule-configuration XML V1.0//EN"
                                "http://mule.mulesource.org/dtds/mule-configuration.dtd">

<mule-configuration id="LabKey_Pipeline" version="1.0">

    <mule-environment-properties serverUrl="">
        <connection-strategy className="org.mule.providers.SimpleRetryConnectionStrategy">
            <properties>
                <property name="retryCount" value="-1"/>
                <property name="frequency" value="10000"/>
                <!--This needs to be true or the web server will block when starting up if it can't connect to JMS -->
                <property name="doThreading" value="true" />
            </properties>
        </connection-strategy>
    </mule-environment-properties>

<!--
    <connector name="VMConnector" className="org.mule.providers.vm.VMConnector">
        <properties>
            <property name="numberOfConcurrentTransactedReceivers" value="1"/>
            <property name="createMultipleTransactedReceivers" value="false"/>
        </properties>
        <threading-profile doThreading="false"/>
    </connector>
-->

    <!-- ****** Beginning of customized section -->
    <!--
    Define a thread pool and JMS connector for a set of tasks. You can add as many of these as you like, and it's paired
    with a mule-descriptor section below.

    One editable setting:
    1. The connector name. Whatever you like as long as it doesn't collide with other connectors in this file
    -->
    <connector name="newConnector" className="org.mule.providers.jms.activemq.ActiveMqJmsConnector">
        <properties>
            <!-- JMS connector from JNDI. -->
            <property name="connectionFactoryJndiName" value="java:comp/env/jms/ConnectionFactory"/>
            <property name="jndiInitialFactory" value="org.apache.naming.java.javaURLContextFactory"/>
            <property name="persistentDelivery" value="true"/>

            <property name="specification" value="1.1"/>
        </properties>
        <threading-profile id="receiver" maxBufferSize="0" maxThreadsActive="1"
                maxThreadsIdle="0" threadTTL="100" poolExhaustedAction="WAIT"/>

        <exception-strategy className="org.labkey.pipeline.mule.PipelineJobExceptionStrategy" />
    </connector>
    <!-- ****** End of customized section -->


    <connector name="jmsConnectorWork" className="org.mule.providers.jms.activemq.ActiveMqJmsConnector">
        <properties>
            <!-- JMS connector from JNDI. -->
            <property name="connectionFactoryJndiName" value="java:comp/env/jms/ConnectionFactory"/>
            <property name="jndiInitialFactory" value="org.apache.naming.java.javaURLContextFactory"/>
            <property name="persistentDelivery" value="true"/>

            <property name="specification" value="1.1"/>
        </properties>
        <threading-profile id="receiver" maxBufferSize="0" maxThreadsActive="1"
                maxThreadsIdle="0" threadTTL="100" poolExhaustedAction="WAIT"/>

        <exception-strategy className="org.labkey.pipeline.mule.PipelineJobExceptionStrategy" />
    </connector>

    <connector name="jmsConnectorHighPriorityWork" className="org.mule.providers.jms.activemq.ActiveMqJmsConnector">
        <properties>
            <!-- JMS connector from JNDI. -->
            <property name="connectionFactoryJndiName" value="java:comp/env/jms/ConnectionFactory"/>
            <property name="jndiInitialFactory" value="org.apache.naming.java.javaURLContextFactory"/>
            <property name="persistentDelivery" value="true"/>

            <property name="specification" value="1.1"/>
        </properties>
        <threading-profile id="receiver" maxBufferSize="0" maxThreadsActive="1"
                maxThreadsIdle="0" threadTTL="100" poolExhaustedAction="WAIT"/>

        <exception-strategy className="org.labkey.pipeline.mule.PipelineJobExceptionStrategy" />
    </connector>

    <connector name="jmsConnectorFastaCheckWork" className="org.mule.providers.jms.activemq.ActiveMqJmsConnector">
        <properties>
            <!-- JMS connector from JNDI. -->
            <property name="connectionFactoryJndiName" value="java:comp/env/jms/ConnectionFactory"/>
            <property name="jndiInitialFactory" value="org.apache.naming.java.javaURLContextFactory"/>
            <property name="persistentDelivery" value="true"/>

            <property name="specification" value="1.1"/>
        </properties>
        <threading-profile id="receiver" maxBufferSize="0" maxThreadsActive="1"
                maxThreadsIdle="0" threadTTL="100" poolExhaustedAction="WAIT"/>

        <exception-strategy className="org.labkey.pipeline.mule.PipelineJobExceptionStrategy" />
    </connector>

    <connector name="jmsConnectorRemoteExecution" className="org.mule.providers.jms.activemq.ActiveMqJmsConnector">
        <properties>
            <!-- JMS connector from JNDI. -->
            <property name="connectionFactoryJndiName" value="java:comp/env/jms/ConnectionFactory"/>
            <property name="jndiInitialFactory" value="org.apache.naming.java.javaURLContextFactory"/>
            <property name="persistentDelivery" value="true"/>

            <property name="specification" value="1.1"/>
        </properties>
        <threading-profile id="receiver" maxBufferSize="0" maxThreadsActive="1"
                maxThreadsIdle="0" threadTTL="100" poolExhaustedAction="WAIT"/>

        <exception-strategy className="org.labkey.pipeline.mule.PipelineJobExceptionStrategy" />
    </connector>

    <connector name="jmsConnectorState" className="org.mule.providers.jms.activemq.ActiveMqJmsConnector">
        <properties>
            <!-- JMS connector from JNDI. -->
            <property name="connectionFactoryJndiName" value="java:comp/env/jms/ConnectionFactory"/>
            <property name="jndiInitialFactory" value="org.apache.naming.java.javaURLContextFactory"/>
            <property name="persistentDelivery" value="true"/>

            <property name="specification" value="1.1"/>
        </properties>
        <threading-profile id="receiver" maxBufferSize="0" maxThreadsActive="1"
                maxThreadsIdle="0" threadTTL="100" poolExhaustedAction="WAIT"/>

        <exception-strategy className="org.labkey.pipeline.mule.PipelineJobExceptionStrategy" />
    </connector>

    <connector name="jmsConnectorCloud" className="org.mule.providers.jms.activemq.ActiveMqJmsConnector">
        <properties>
            <!-- JMS connector from JNDI. -->
            <property name="connectionFactoryJndiName" value="java:comp/env/jms/ConnectionFactory"/>
            <property name="jndiInitialFactory" value="org.apache.naming.java.javaURLContextFactory"/>
            <property name="persistentDelivery" value="true"/>

            <property name="specification" value="1.1"/>
        </properties>
        <threading-profile id="receiver" maxBufferSize="0" maxThreadsActive="1"
                maxThreadsIdle="0" threadTTL="100" poolExhaustedAction="WAIT"/>

        <exception-strategy className="org.labkey.pipeline.mule.PipelineJobExceptionStrategy" />
    </connector>

    <!--<connector name="sqsConnectorState" className="org.mule.providers.sqs.SqsConnector">-->
        <!--<properties>-->
            <!--<property name="awsAccessKey" value="14YHE2J1CWVFR0JGG2G2" />-->
            <!--<property name="awsSecretKey" value="mBNF8S/Tbp/CwOpsG9u+6ps2ptZv6lBmzN+Ry1dZ" />-->
            <!--<property name="pollingFrequency" value="10000" />-->
        <!--</properties>-->
    <!--</connector>-->

    <endpoint-identifiers>
        <endpoint-identifier name="JobMQ" value="jms://job.queue"/>
        <endpoint-identifier name="StatusMQ" value="jms://status.queue"/>
        <!--<endpoint-identifier name="StatusSQS" value="sqs://status-queue"/>-->
    </endpoint-identifiers>

    <transformers>
        <transformer name="JobToJMSMessage" className="org.labkey.pipeline.mule.transformers.PipelineJobToJMSMessage"
            returnClass="javax.jms.TextMessage"/>
        <transformer name="JMSMessageToJob" className="org.labkey.pipeline.mule.transformers.JMSMessageToPipelineJob"
            returnClass="org.labkey.api.pipeline.PipelineJob"/>
        <transformer name="JMSMessageToXML" className="org.mule.providers.jms.transformers.JMSMessageToObject"
            returnClass="java.lang.String"/>
        <transformer name="XMLToStatus" className="org.mule.transformers.xml.XmlToObject"
            returnClass="org.labkey.pipeline.mule.StatusRequest"/>

        <transformer name="StatusToXML" className="org.mule.transformers.xml.ObjectToXml"
            returnClass="java.lang.String"/>
        <transformer name="XMLToJMSMessage" className="org.mule.providers.jms.transformers.ObjectToJMSMessage"
            returnClass="javax.jms.TextMessage" />
        <transformer name="NoOpTransformer" className="org.labkey.pipeline.mule.transformers.NoOpTransformer"
            returnClass="java.lang.Object"/>
    </transformers>

    <global-endpoints>
        <endpoint name="PipelineQueue" type="sender" address="JobMQ"
                  transformers="JobToJMSMessage" connector="jmsConnectorState"/>

        <!-- Give the pipeline module access to this address for queue browsing -->
        <endpoint name="JobQueue" address="JobMQ" connector="jmsConnectorWork"/>
    </global-endpoints>

<!--
    <interceptor-stack name="default">
        <interceptor className="org.mule.interceptors.LoggingInterceptor"/>
        <interceptor className="org.mule.interceptors.TimerInterceptor"/>
    </interceptor-stack>
-->

    <model name="pipeline">
        <exception-strategy className="org.labkey.pipeline.mule.PipelineJobExceptionStrategy" />

        <mule-descriptor name="PipelineJobRunnerUMO"
            implementation="org.labkey.pipeline.mule.PipelineJobRunner">
            <inbound-router>
                <endpoint type="receiver" address="JobMQ" transformers="JMSMessageToJob"
                        responseTransformers="NoOpTransformer" connector="jmsConnectorWork">
                    <!--<transaction action="ALWAYS_BEGIN" factory="org.mule.providers.jms.JmsTransactionFactory" />-->
                    <filter className="org.labkey.pipeline.mule.filters.TaskJmsSelectorFilter">
                        <properties>
                            <property name="location" value="webserver"/>
                            <property name="includeMonolithic" value="true"/>
                        </properties>
                    </filter>
                </endpoint>
            </inbound-router>

            <!-- Return to job queue if not complete -->
            <outbound-router>
                <router className="org.labkey.pipeline.mule.routing.EPipelineQueueMessageSplitter">
                    <endpoint type="sender" address="JobMQ" transformers="JobToJMSMessage"
                            connector="jmsConnectorWork"/>
                    <filter className="org.labkey.pipeline.mule.filters.JobIncompleteFilter"/>
                </router>
            </outbound-router>

            <threading-profile maxThreadsActive="1" maxThreadsIdle="0" threadTTL="100"/>
            <pooling-profile maxActive="1" maxIdle="0" initialisationPolicy="INITIALISE_NONE"/>
        </mule-descriptor>

        <!-- Define a worker for tasks that should run on the web server but should be quick and shouldn't block on
        other, longer running tasks -->
        <mule-descriptor name="PipelineJobRunnerHighPriorityUMO"
            implementation="org.labkey.pipeline.mule.PipelineJobRunner">
            <inbound-router>
                <endpoint type="receiver" address="JobMQ" transformers="JMSMessageToJob"
                        responseTransformers="NoOpTransformer" connector="jmsConnectorHighPriorityWork">
                    <!--<transaction action="ALWAYS_BEGIN" factory="org.mule.providers.jms.JmsTransactionFactory" />-->
                    <filter className="org.labkey.pipeline.mule.filters.TaskJmsSelectorFilter">
                        <properties>
                            <property name="location" value="webserver-high-priority"/>
                        </properties>
                    </filter>
                </endpoint>
            </inbound-router>

            <!-- Return to job queue if not complete -->
            <outbound-router>
                <router className="org.labkey.pipeline.mule.routing.EPipelineQueueMessageSplitter">
                    <endpoint type="sender" address="JobMQ" transformers="JobToJMSMessage"
                            connector="jmsConnectorHighPriorityWork"/>
                    <filter className="org.labkey.pipeline.mule.filters.JobIncompleteFilter"/>
                </router>
            </outbound-router>

            <threading-profile maxThreadsActive="1" maxThreadsIdle="0" threadTTL="100"/>
            <pooling-profile maxActive="1" maxIdle="0" initialisationPolicy="INITIALISE_NONE"/>

            <properties>
                <property name="location" value="webserver-high-priority" />
            </properties>
        </mule-descriptor>


        <!-- ****** Beginning of customized section -->
        <!--
        Define routers to capture and resubit messages to/from the work queue. Paired with a connector defined above.

        Three editable values:
        1. The desciptor name. Whatever you like as long as it doesn't collide with others in this file.
        2. The connector name. Appears in both the inbound and outbound sections. Must match the name used in connector
        section earlier in this file.
        3. The location name. Whatever you like as long as it doesn't collide. Must match the location specified
        for tasks in the separate *Config.xml files.
        4. maxThreadsActive in the threading-profile section. The number of threads servicing the tasks assigned to this
        location.
        -->

        <mule-descriptor name="newDescriptor"
            implementation="org.labkey.pipeline.mule.PipelineJobRunner">
            <inbound-router>
                <endpoint type="receiver" address="JobMQ" transformers="JMSMessageToJob"
                        responseTransformers="NoOpTransformer" connector="newConnector">
                    <filter className="org.labkey.pipeline.mule.filters.TaskJmsSelectorFilter">
                        <properties>
                            <property name="location" value="newLocation"/>
                        </properties>
                    </filter>
                </endpoint>
            </inbound-router>

            <!-- Return to job queue if not complete -->
            <outbound-router>
                <router className="org.labkey.pipeline.mule.routing.EPipelineQueueMessageSplitter">
                    <endpoint type="sender" address="JobMQ" transformers="JobToJMSMessage"
                            connector="newConnector"/>
                    <filter className="org.labkey.pipeline.mule.filters.JobIncompleteFilter"/>
                </router>
            </outbound-router>

            <threading-profile maxThreadsActive="1" maxThreadsIdle="0" threadTTL="100"/>
            <pooling-profile maxActive="1" maxIdle="0" initialisationPolicy="INITIALISE_NONE"/>

            <properties>
                <property name="location" value="newLocation" />
            </properties>
        </mule-descriptor>
        <!-- ****** End of customized section -->

        <mule-descriptor name="PipelineJobRunnerRemoteExecutionUMO"
            implementation="org.labkey.pipeline.mule.PipelineJobRunnerRemoteExecution">
            <inbound-router>
                <endpoint type="receiver" address="JobMQ" transformers="JMSMessageToXML"
                        responseTransformers="NoOpTransformer" connector="jmsConnectorRemoteExecution">
                    <filter className="org.labkey.pipeline.mule.filters.TaskRemoteExecutionEngineJmsSelectorFilter" />
                </endpoint>
            </inbound-router>

            <threading-profile maxThreadsActive="1" maxThreadsIdle="0" threadTTL="100"/>
            <pooling-profile maxActive="1" maxIdle="0" initialisationPolicy="INITIALISE_NONE"/>
        </mule-descriptor>

        <!-- Define a worker for doing FASTA checks  -->
        <mule-descriptor name="PipelineJobRunnerFastaCheckUMO"
            implementation="org.labkey.pipeline.mule.PipelineTaskRunner">
            <inbound-router>
                <endpoint type="receiver" address="JobMQ" transformers="JMSMessageToJob"
                        responseTransformers="NoOpTransformer" connector="jmsConnectorFastaCheckWork">
                    <filter className="org.labkey.pipeline.mule.filters.TaskJmsSelectorFilter">
                        <properties>
                            <property name="location" value="webserver-fasta-check"/>
                        </properties>
                    </filter>
                </endpoint>
            </inbound-router>

            <!-- Return to job queue (task runner cannot complete) -->
            <outbound-router>
                <router className="org.mule.routing.outbound.OutboundPassThroughRouter">
                    <endpoint type="sender" address="JobMQ" transformers="JobToJMSMessage"
                            connector="jmsConnectorFastaCheckWork" />
                </router>
            </outbound-router>

            <threading-profile maxThreadsActive="1" maxThreadsIdle="0" threadTTL="100"/>
            <pooling-profile maxActive="1" maxIdle="0" initialisationPolicy="INITIALISE_NONE"/>

            <properties>
                <property name="location" value="webserver-fasta-check" />
            </properties>
        </mule-descriptor>

        <mule-descriptor name="PipelineProgressionRunnerUMO"
                         implementation="org.labkey.pipeline.mule.PipelineProgressionRunner">
            <inbound-router>
                <endpoint type="receiver" address="JobMQ" transformers="JMSMessageToJob"
                          responseTransformers="NoOpTransformer" connector="jmsConnectorState">
                    <!--<transaction action="ALWAYS_BEGIN" factory="org.mule.providers.jms.JmsTransactionFactory" />-->
                    <filter className="org.labkey.pipeline.mule.filters.TaskStateChangeJmsSelectorFilter"/>
                </endpoint>
            </inbound-router>

            <!-- Return to job queue if not complete -->
            <outbound-router>
                <router className="org.labkey.pipeline.mule.routing.EPipelineQueueMessageSplitter">
                    <endpoint type="sender" address="JobMQ" transformers="JobToJMSMessage"
                              connector="jmsConnectorState"/>
                    <filter className="org.labkey.pipeline.mule.filters.JobIncompleteFilter"/>
                </router>
            </outbound-router>

            <threading-profile maxThreadsActive="1" maxThreadsIdle="0" threadTTL="100"/>
            <pooling-profile maxActive="1" maxIdle="0" initialisationPolicy="INITIALISE_NONE"/>
        </mule-descriptor>

        <mule-descriptor name="PipelineStatusSetterUMO"
            implementation="org.labkey.pipeline.mule.StatusRequestHandler">
            <inbound-router>
                <endpoint type="receiver" address="StatusMQ" transformers="JMSMessageToXML XMLToStatus"
                        responseTransformers="NoOpTransformer" connector="jmsConnectorState">
                </endpoint>
            </inbound-router>

            <threading-profile maxThreadsActive="1" maxThreadsIdle="0" threadTTL="100"/>
            <pooling-profile maxActive="1" maxIdle="0" initialisationPolicy="INITIALISE_NONE"/>

            <exception-strategy className="org.labkey.pipeline.mule.PipelineJobExceptionStrategy" />
        </mule-descriptor>

        <!--<mule-descriptor name="PipelineStatusSetterCloud" implementation="org.labkey.pipeline.mule.StatusRequestHandler">-->

            <!--<inbound-router>-->
                <!--<endpoint type="receiver" address="StatusSQS"-->
                         <!--connector="sqsConnectorState"/>-->
                <!--<router className="org.labkey.pipeline.mule.routing.CloudInboundAggregator"/>-->
            <!--</inbound-router>-->

            <!--<threading-profile maxThreadsActive="1" maxThreadsIdle="0" threadTTL="100"/>-->
            <!--<pooling-profile maxActive="1" maxIdle="0" initialisationPolicy="INITIALISE_NONE"/>-->

            <!--<exception-strategy className="org.labkey.pipeline.mule.PipelineJobExceptionStrategy" />-->
        <!--</mule-descriptor>-->
        <!--<mule-descriptor name="CloudWaitDummy" implementation="org.mule.components.simple.PassThroughComponent" >-->

            <!--<inbound-router>-->
                <!--<endpoint type="receiver" address="JobMQ" transformers="NoOpTransformer"-->
                        <!--responseTransformers="NoOpTransformer" connector="jmsConnectorCloud">-->
                    <!--<filter className="org.labkey.pipeline.mule.filters.TaskJmsSelectorFilter">-->
                        <!--<properties>-->
                            <!--<property name="location" value="cloud"/>-->
                            <!--<property name="includeMonolithic" value="true"/>-->
                        <!--</properties>-->
                    <!--</filter>-->
                <!--</endpoint>-->
            <!--</inbound-router>-->

            <!--<threading-profile maxThreadsActive="1" maxThreadsIdle="0" threadTTL="100"/>-->
            <!--<pooling-profile maxActive="1" maxIdle="0" initialisationPolicy="INITIALISE_NONE"/>-->

            <!--<exception-strategy className="org.labkey.pipeline.mule.PipelineJobExceptionStrategy" />-->
        <!--</mule-descriptor>-->
    </model>
</mule-configuration>
