<?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:context="http://www.springframework.org/schema/context"
        xmlns:vm="http://www.mulesource.org/schema/mule/vm/2.2"
        xmlns:ejb="http://www.mulesource.org/schema/mule/ejb/2.2"
        xmlns:jms="http://www.mulesource.org/schema/mule/jms/2.2"
        xsi:schemaLocation="
                http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-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
                http://www.mulesource.org/schema/mule/ejb/2.2 http://www.mulesource.org/schema/mule/ejb/2.2/mule-ejb.xsd
                http://www.mulesource.org/schema/mule/jms/2.2 http://www.mulesource.org/schema/mule/jms/2.2/mule-jms.xsd">

    <description>
        The Loan Broker ESB example implements the Loan Broker Example using an ESB topology. See
        http://mule.mulesource.org/wiki/display/MULE/LoanBroker+ESB for details.
    </description>

    <!-- Import property placeholders -->
    <context:property-placeholder location="openejb.properties"/>
    
    <ejb:connector name="ejbConnector" securityPolicy="security.policy"
        jndiInitialFactory="org.openejb.client.LocalInitialContextFactory">
        <jndi-provider-property key="openejb.base" value="${openejb.base}"/>
        <jndi-provider-property key="openejb.configuration" value="${openejb.configuration}"/>
        <jndi-provider-property key="logging.conf" value="${logging.conf}"/>
        <jndi-provider-property key="openejb.nobanner" value="${openejb.nobanner}"/>
    </ejb:connector>

    <jms:activemq-connector name="jmsConnector" />

    <!--
    Examples of different types of Transformers are used here to show some of the built in features of Mule transformers -->

    <!-- custom transformers that implements the Mule Transformer API -->
    <custom-transformer name="RestRequestToCustomerRequest"
                             class="org.mule.example.loanbroker.transformers.RestRequestToCustomerRequest" />

    <custom-transformer name="CreditProfileXmlToCreditProfile"
                             class="org.mule.example.loanbroker.transformers.CreditProfileXmlToCreditProfile" />

    <!-- The expression transformer can be used to extract multiple arguments from the current message (as a List or Array)
     Here we use the 'bean' Expression Evaluator to extract the name and SSN of the customer we are performing a credit check on.
     These arguments are accepted by the EJB service -->
    <expression-transformer name="CustomerToCreditProfileArgs">
        <return-argument evaluator="bean" expression="name"/>
        <return-argument evaluator="bean" expression="ssn"/>
    </expression-transformer>

    <!-- The Message properties transformer can be used to add, modify or delete properties on the current message.
    In this instance we use a groovy expression to get a List of endpoints from each of the lenders and set them as a property
    on the message called 'recipients'-->
    <message-properties-transformer name="SetLendersAsRecipients">
        <add-message-property key="recipients" value="#[groovy:payload.lenders.endpoint]"/>
    </message-properties-transformer>

    <!-- Example of a built-in, transport specific transformer -->
    <jms:object-to-jmsmessage-transformer name="ObjectToJMSMessage" />

    <endpoint name="CustomerRequestsREST" address="jetty:rest://localhost:8888/loanbroker" />
    <endpoint name="CustomerRequests" address="vm://customer.requests" />
    <endpoint name="CustomerResponses" address="LoanQuotes" />
    <endpoint name="LoanQuotes" address="jms://esb.loan.quotes" />
    <endpoint name="CreditAgencyGateway" address="jms://esb.credit.agency" />
    <!-- here we're telling Mule to invoke a remote Ejb directly (not host a
    proxy service for the remote object as with the other example in mule-config-with-ejb-container.xml example)
    -->
    <ejb:endpoint name="CreditAgency" host="localhost" port="1099" object="local/CreditAgency" method="getCreditProfile" />
    <!-- endpoint name="CreditAgency" address="ejb://localhost:1099/local/CreditAgency?method=getCreditProfile" / -->
    <endpoint name="LenderGateway" address="jms://esb.lender.service" />
    <endpoint name="LenderService" address="vm://lender.service" />
    <endpoint name="BankingGateway" address="jms://esb.banks" />
    <endpoint name="Bank1" address="axis:http://localhost:10080/mule/TheBank1?method=getLoanQuote"
                   synchronous="true" />
    <endpoint name="Bank2" address="axis:http://localhost:20080/mule/TheBank2?method=getLoanQuote"
                   synchronous="true" />
    <endpoint name="Bank3" address="axis:http://localhost:30080/mule/TheBank3?method=getLoanQuote"
                   synchronous="true" />
    <endpoint name="Bank4" address="axis:http://localhost:40080/mule/TheBank4?method=getLoanQuote"
                   synchronous="true" />
    <endpoint name="Bank5" address="axis:http://localhost:50080/mule/TheBank5?method=getLoanQuote"
                   synchronous="true" />
    <endpoint name="Bank1In" address="axis:http://localhost:10080/mule" />
    <endpoint name="Bank2In" address="axis:http://localhost:20080/mule" />
    <endpoint name="Bank3In" address="axis:http://localhost:30080/mule" />
    <endpoint name="Bank4In" address="axis:http://localhost:40080/mule" />
    <endpoint name="Bank5In" address="axis:http://localhost:50080/mule" />

    <model name="loan-broker">

        <service name="LoanBroker">
            <description>
                The LoanBroker service is our 'entry' service that accepts requests from the outside world
            </description>
            <inbound>
                <inbound-endpoint ref="CustomerRequestsREST" transformer-refs="RestRequestToCustomerRequest" />
                <inbound-endpoint ref="CustomerRequests" />
            </inbound>

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

            <outbound>
                <pass-through-router>
                    <outbound-endpoint ref="CreditAgencyGateway" />
                </pass-through-router>
            </outbound>

            <async-reply timeout="10000">
                <inbound-endpoint ref="LoanQuotes" />
                <custom-async-reply-router class="org.mule.example.loanbroker.routers.BankQuotesResponseAggregator" />
            </async-reply>
        </service>

        <service name="CreditAgencyGatewayService">
            <description>
                The credit agency service will get the credit profile for a customer.

                This service serves as a 'proxy' or 'gateway' to a back-end system. It is responsible for invoking the
                CreditAgency back-end service ensuring that the correct data is sent to the service and the data passed back is
                added to our bus message.
                This service uses a component binding to call out to the CreditAgency service before sending the bus message onto
                the next endpoint.
            </description>
            <inbound>
                <inbound-endpoint ref="CreditAgencyGateway" />
            </inbound>
            <component class="org.mule.example.loanbroker.esb.CreditAgencyGateway">
                <binding interface="org.mule.example.loanbroker.credit.CreditAgencyService" method="getCreditProfile">
                    <!-- We invoke the credit Agency service using synchronous which means that a response
                    will be returned from the service. there is also a responseTransformer that will
                    conver the Xml returned from the CreditAgency Ejb into a CreditProfile object -->
                    <outbound-endpoint synchronous="true" transformer-refs="CustomerToCreditProfileArgs"
                                   responseTransformer-refs="CreditProfileXmlToCreditProfile" ref="CreditAgency" />
                </binding>
            </component>
            <outbound>
                <pass-through-router>
                    <outbound-endpoint ref="LenderGateway" />
                </pass-through-router>
            </outbound>
        </service>

        <service name="LenderGatewayService">
            <description>
                Much like the previous service the is a gateway/proxy to a LenderService back-end application. In this instance
                the LenderService understands our bus message so we just use a chaining router to send the response form the
                Lender Service to the next endpoint.
            </description>
            <inbound>
                <inbound-endpoint ref="LenderGateway" />
            </inbound>
            <outbound>
                <chaining-router>
                    <outbound-endpoint synchronous="true" ref="LenderService" />
                    <outbound-endpoint ref="BankingGateway" transformer-refs="SetLendersAsRecipients ObjectToJMSMessage" />
                </chaining-router>
            </outbound>
        </service>

        <service name="LenderServiceService">
            <description>
                Responsible for getting a list of lenders that will provide a Loan quote.
            </description>
            <inbound>
                <inbound-endpoint ref="LenderService" />
            </inbound>
            <component class="org.mule.example.loanbroker.lender.DefaultLender" />
        </service>

        <service name="BankingGatewayService">
            <description>
                This gateway is responsible for sending the Loan Reqest information to each of the Lenders.
            </description>
            <inbound>
                <inbound-endpoint ref="BankingGateway" />
            </inbound>
            <outbound>
                <static-recipient-list-router>
                    <reply-to address="LoanQuotes" />
                    <message-property-filter pattern="recipients!=null" />
                </static-recipient-list-router>
            </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>
