<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mule="http://www.mulesource.org/schema/mule/core/2.0"
    xmlns:vm="http://www.mulesource.org/schema/mule/vm/2.0"
    xmlns:ejb="http://www.mulesource.org/schema/mule/ejb/2.0"
    xmlns:jms="http://www.mulesource.org/schema/mule/jms/2.0"
    xsi:schemaLocation="
               http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
               http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.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.0 http://www.mulesource.org/schema/mule/core/2.0/mule.xsd
               http://www.mulesource.org/schema/mule/vm/2.0 http://www.mulesource.org/schema/mule/vm/2.0/mule-vm.xsd
               http://www.mulesource.org/schema/mule/ejb/2.0 http://www.mulesource.org/schema/mule/ejb/2.0/mule-ejb.xsd
               http://www.mulesource.org/schema/mule/jms/2.0 http://www.mulesource.org/schema/mule/jms/2.0/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>

    <context:property-placeholder location="openejb.properties"/>

    <jee:remote-slsb id="creditAgencyEJB" jndi-name="local/CreditAgency"
        business-interface="org.mule.example.loanbroker.credit.CreditAgency">
        <jee:environment>
            java.naming.factory.initial=org.openejb.client.LocalInitialContextFactory
            java.naming.provider.url=rmi://localhost:1099
            openejb.base=${openejb.base}
            openejb.configuration=${openejb.configuration}
            logging.conf=${logging.conf}
            openejb.nobanner=${openejb.nobanner}
        </jee:environment>
    </jee:remote-slsb>

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

        <mule:custom-transformer name="RestRequestToCustomerRequest"
                                 class="org.mule.example.loanbroker.transformers.RestRequestToCustomerRequest" />
        <mule:custom-transformer name="LoanQuoteRequestToCreditProfileArgs"
                                 class="org.mule.example.loanbroker.transformers.LoanQuoteRequestToCreditProfileArgs" />
        <mule:custom-transformer name="CreditProfileXmlToCreditProfile"
                                 class="org.mule.example.loanbroker.transformers.CreditProfileXmlToCreditProfile" />
        <mule:custom-transformer name="SetLendersAsRecipients"
                                 class="org.mule.example.loanbroker.transformers.SetLendersAsRecipients" />
        <jms:object-to-jmsmessage-transformer name="ObjectToJMSMessage" />

        <mule:endpoint name="CustomerRequestsREST" address="jetty:rest://localhost:8888/loanbroker" />
        <mule:endpoint name="CustomerRequests" address="vm://customer.requests" />
        <mule:endpoint name="CustomerResponses" address="LoanQuotes" />
        <mule:endpoint name="LoanQuotes" address="jms://esb.loan.quotes" />
        <mule:endpoint name="CreditAgencyGateway" address="jms://esb.credit.agency" />
        <!-- This endpoint is used to pass events to the Credit Agency Ejb
        Notice we set the 'method' param on the endpoint. This is because we need to tell
        Mule which meothod to invoke as Mule cannot introspect the EJB proxy -->
        <mule:endpoint name="CreditAgency" address="vm://credit.agency.service?method=getCreditProfile" />
        <mule:endpoint name="LenderGateway" address="jms://esb.lender.service" />
        <mule:endpoint name="LenderService" address="vm://lender.service" />
        <mule:endpoint name="BankingGateway" address="jms://esb.banks" />
        <mule:endpoint name="Bank1" address="axis:http://localhost:10080/mule/TheBank1?method=getLoanQuote"
                       synchronous="true" />
        <mule:endpoint name="Bank2" address="axis:http://localhost:20080/mule/TheBank2?method=getLoanQuote"
                       synchronous="true" />
        <mule:endpoint name="Bank3" address="axis:http://localhost:30080/mule/TheBank3?method=getLoanQuote"
                       synchronous="true" />
        <mule:endpoint name="Bank4" address="axis:http://localhost:40080/mule/TheBank4?method=getLoanQuote"
                       synchronous="true" />
        <mule:endpoint name="Bank5" address="axis:http://localhost:50080/mule/TheBank5?method=getLoanQuote"
                       synchronous="true" />
        <mule:endpoint name="Bank1In" address="axis:http://localhost:10080/mule" />
        <mule:endpoint name="Bank2In" address="axis:http://localhost:20080/mule" />
        <mule:endpoint name="Bank3In" address="axis:http://localhost:30080/mule" />
        <mule:endpoint name="Bank4In" address="axis:http://localhost:40080/mule" />
        <mule:endpoint name="Bank5In" address="axis:http://localhost:50080/mule" />

        <mule:model name="loan-broker">

            <!--
            The loan broker is used to receive loan requests
            -->
            <mule:service name="LoanBroker">
                <mule:inbound>
                    <mule:inbound-endpoint ref="CustomerRequestsREST" transformer-refs="RestRequestToCustomerRequest" />
                    <mule:inbound-endpoint ref="CustomerRequests" />
                </mule:inbound>

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

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

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

            <!--
            The credit agency service will get the credit profile for a customer
            -->
            <mule:service name="CreditAgencyGatewayService">
                <mule:inbound>
                    <mule:inbound-endpoint ref="CreditAgencyGateway" />
                </mule:inbound>
                <mule:component class="org.mule.component.builder.ReflectionMessageBuilder" />
                <mule:outbound>
                    <mule:filtering-router>
                        <!-- We invoke the credit Agency service using remoteSync 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 -->
                        <mule:outbound-endpoint remoteSync="true" transformer-refs="LoanQuoteRequestToCreditProfileArgs"
                                       responseTransformer-refs="CreditProfileXmlToCreditProfile" ref="CreditAgency" />
                        <mule:outbound-endpoint ref="LenderGateway" />
                    </mule:filtering-router>
                </mule:outbound>
            </mule:service>

            <!--  This is the CreditAgency Ejb component.  The implementation is the Jndi naming location
            of the the Home interface for the CreditAgency bean.  This is just a single inbound endpoint which
            with return the result of the invocation
            -->
            <mule:service name="CreditAgencyService">
                <mule:inbound>
                    <mule:inbound-endpoint ref="CreditAgency" />
                </mule:inbound>
                <mule:component>
                    <mule:spring-object bean="creditAgencyEJB"/>
                </mule:component>
            </mule:service>

            <mule:service name="LenderGatewayService">
                <mule:inbound>
                    <mule:inbound-endpoint ref="LenderGateway" />
                    <mule:forwarding-router/>
                </mule:inbound>
                <mule:outbound>
                    <mule:chaining-router>
                        <mule:outbound-endpoint remoteSync="true" ref="LenderService" />
                        <mule:outbound-endpoint ref="BankingGateway"
                                       transformer-refs="SetLendersAsRecipients ObjectToJMSMessage" />
                    </mule:chaining-router>
                </mule:outbound>
            </mule:service>

            <mule:service name="LenderServiceService">
                <mule:inbound>
                    <mule:inbound-endpoint ref="LenderService" />
                </mule:inbound>
                <mule:component class="org.mule.example.loanbroker.lender.DefaultLender" />
            </mule:service>

            <mule:service name="BankingGatewayService">
                <mule:inbound>
                    <mule:inbound-endpoint ref="BankingGateway" />
                    <mule:forwarding-router/>
                </mule:inbound>
                <mule:outbound>
                    <mule:static-recipient-list-router>
                        <mule:reply-to address="LoanQuotes" />
                        <mule:message-property-filter pattern="recipients!=null" />
                    </mule:static-recipient-list-router>
                </mule:outbound>
            </mule: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
            -->
            <mule:service name="TheBank1">
                <mule:inbound>
                    <mule:inbound-endpoint ref="Bank1In" />
                </mule:inbound>
                <mule:component class="org.mule.example.loanbroker.bank.Bank" />
            </mule:service>

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

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

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

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

        </mule:model>

    </mule:mule>

</beans>
