<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesource.org/schema/mule/core/2.2"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:spring="http://www.springframework.org/schema/beans"
       xmlns:vm="http://www.mulesource.org/schema/mule/vm/2.2"
       xsi:schemaLocation="
               http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
               http://www.mulesource.org/schema/mule/core/2.2 http://www.mulesource.org/schema/mule/core/2.2/mule.xsd
               http://www.mulesource.org/schema/mule/vm/2.2 http://www.mulesource.org/schema/mule/vm/2.2/mule-vm.xsd">

    <description>
    This loan broker example is modeled on the Enterprise integration Patterns book sample.  
    This implementation differs in that this configuration uses an asynchronous model where 
    each component communicates messaging according to its configuration in this file.
    </description>

    <!-- Synchronous VM connector (messages are processed in the same execution thread) -->
    <vm:connector name="syncVm"/>

    <!-- Asynchronous VM connector (uses in-memory queues) -->
    <vm:connector name="asyncVm" queueEvents="true"/>

    <!-- only used for the async loan broker to send the lowest quote back to the customer -->
    <vm:endpoint name="CustomerResponses" path="customer.responses" connector-ref="asyncVm"/>

    <!--
       The Mule model initialises and manages your Mule components
    -->
    <model name="loan-broker">

        <!--
        The loan broker is used to receive loan requests
        -->
        <service name="TheLoanBroker">
            <!--
            This router uses the BankQuoteAggregator for events of type BankQuote, for all other
            types the catch all strategy is invoked, which simply passes the event to the component
            -->
            <inbound>
                <!-- New requests from customers -->
                <inbound-endpoint ref="CustomerRequests"/>
                <!-- Loan quotes from banks -->
                <inbound-endpoint ref="LoanBrokerQuotes"/>
                <custom-inbound-router class="org.mule.example.loanbroker.routers.BankQuotesInboundAggregator">
                    <payload-type-filter expectedType="org.mule.example.loanbroker.messages.LoanQuote"/>
                </custom-inbound-router>
                <custom-catch-all-strategy class="org.mule.routing.ServiceCatchAllStrategy"/>
            </inbound>

            <component class="org.mule.example.loanbroker.AsynchronousLoanBroker"/>

            <outbound>
                <!-- Credit profile requests -->
                <filtering-router>
                    <outbound-endpoint ref="CreditAgency" transformer-refs="ExtractCustomer"/>
                    <payload-type-filter expectedType="org.mule.example.loanbroker.messages.Customer"/>
                </filtering-router>
                <!-- Quote requests to the banks -->
                <filtering-router>
                    <outbound-endpoint ref="LenderService"/>
                    <payload-type-filter expectedType="org.mule.example.loanbroker.messages.LoanBrokerQuoteRequest"/>
                </filtering-router>
                <!-- Final quote response to the customer -->
                <filtering-router>
                    <outbound-endpoint ref="CustomerResponses"/>
                    <payload-type-filter expectedType="org.mule.example.loanbroker.messages.LoanQuote"/>
                </filtering-router>
            </outbound>
        </service>

        <!--
        The credit agency service will get the credit profile for a customer
        -->
        <service name="TheCreditAgencyService">
            <inbound>
                <inbound-endpoint ref="CreditAgency"/>
            </inbound>
            <component class="org.mule.example.loanbroker.credit.DefaultCreditAgency"/>
        </service>

        <!--
        The Lender service is used to determine which banks to contact for a quote
        -->
        <service name="TheLenderService">
            <inbound>
                <inbound-endpoint ref="LenderService"/>
            </inbound>
            <component class="org.mule.example.loanbroker.lender.DefaultLender"/>
            <outbound>
                <filtering-router>
                    <outbound-endpoint ref="BankGateway" transformer-refs="SetLendersAsRecipients"/>
                </filtering-router>
            </outbound>
        </service>

        <service name="TheBankGateway">
            <inbound>
                <inbound-endpoint ref="BankGateway"/>
            </inbound>
            <outbound>
                <static-recipient-list-router>
                    <reply-to address="LoanBrokerQuotes"/>
                    <message-property-filter pattern="recipients!=null"/>
                </static-recipient-list-router>
                <logging-catch-all-strategy/>                
            </outbound>
        </service>

        <!--
        These are mock bank services that represent remote bank loan services
        One or more of these are selected by the LenderService and a request
        is routed to them.   The lenderService outbound router also defines a
        replyTo property which will be used by Mule to route the responses back
        to the LoanBrokerQuotes destination
        -->
        <service name="TheBank1">
            <inbound>
                <inbound-endpoint ref="Bank1In"/>
            </inbound>
            <component class="org.mule.example.loanbroker.bank.Bank"/>
        </service>

        <service name="TheBank2">
            <inbound>
                <inbound-endpoint ref="Bank2In"/>
            </inbound>
            <component class="org.mule.example.loanbroker.bank.Bank"/>
        </service>

        <service name="TheBank3">
            <inbound>
                <inbound-endpoint ref="Bank3In"/>
            </inbound>
            <component class="org.mule.example.loanbroker.bank.Bank"/>
        </service>

        <service name="TheBank4">
            <inbound>
                <inbound-endpoint ref="Bank4In"/>
            </inbound>
            <component class="org.mule.example.loanbroker.bank.Bank"/>
        </service>

        <service name="TheBank5">
            <inbound>
                <inbound-endpoint ref="Bank5In"/>
            </inbound>
            <component class="org.mule.example.loanbroker.bank.Bank"/>
        </service>

    </model>
</mule>
