You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2011/12/28 13:12:59 UTC

svn commit: r1225165 - in /camel/trunk/examples/camel-example-loan-broker: ./ src/main/java/org/apache/camel/loanbroker/queue/version/ src/main/java/org/apache/camel/loanbroker/queue/version/bank/ src/main/java/org/apache/camel/loanbroker/webservice/ve...

Author: davsclaus
Date: Wed Dec 28 12:12:58 2011
New Revision: 1225165

URL: http://svn.apache.org/viewvc?rev=1225165&view=rev
Log:
CAMEL-4814: Use dynamic port numbers for testing examples. CAMEL-4830: Improved and preparing loan broker example to be split into two.

Added:
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/CreditAgencyProcessor.java   (contents, props changed)
      - copied, changed from r1225145, camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/CreditAgency.java
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/LoanBrokerRoute.java
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/ReplyProcessor.java   (contents, props changed)
      - copied, changed from r1225145, camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/Translator.java
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/bank/
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/bank/BankProcessor.java   (contents, props changed)
      - copied, changed from r1225145, camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/Bank.java
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/CreditScoreProcessor.java
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/ReplyProcessor.java
    camel/trunk/examples/camel-example-loan-broker/src/main/resources/loanbroker.properties
Removed:
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/Bank.java
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/CreditAgency.java
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/Translator.java
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/Constants.java
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/bank/BankServer.java
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/credit/CreditAgencyClient.java
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/credit/CreditAgencyServer.java
Modified:
    camel/trunk/examples/camel-example-loan-broker/README.txt
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/BankResponseAggregationStrategy.java
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/Client.java
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/Constants.java
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/JmsBroker.java
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/LoanBroker.java
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/BankResponseAggregationStrategy.java
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/Client.java
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/LoanBroker.java
    camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/bank/BankQuote.java
    camel/trunk/examples/camel-example-loan-broker/src/main/resources/META-INF/spring/webServiceCamelContext.xml
    camel/trunk/examples/camel-example-loan-broker/src/test/java/org/apache/camel/loanbroker/queue/version/LoanBrokerQueueTest.java
    camel/trunk/examples/camel-example-loan-broker/src/test/java/org/apache/camel/loanbroker/webservice/version/LoanBrokerWSTest.java

Modified: camel/trunk/examples/camel-example-loan-broker/README.txt
URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-loan-broker/README.txt?rev=1225165&r1=1225164&r2=1225165&view=diff
==============================================================================
--- camel/trunk/examples/camel-example-loan-broker/README.txt (original)
+++ camel/trunk/examples/camel-example-loan-broker/README.txt Wed Dec 28 12:12:58 2011
@@ -1,22 +1,21 @@
 Loan Broker Example
 ====================
 
-This example shows how to use Camel to implement the EIP's loan broker example.
+This example shows how to use Camel to implement the EIP's loan broker example,
+from the EIP book (http://www.enterpriseintegrationpatterns.com/index.html).
 
-The example has two version, one is queue version which leverages the message
-queue to combine the credit agency and bank loan quote processing and it
-uses the InOnly exchange pattern; the other is web service version which shows
-how to integrate the credit agency and bank web services together and it uses
-the InOut exchange pattern.
+The example has two versions (JMS queues, and web services),
+that uses a different transport for exchanging messages between
+the client, credit agency, and the banks.
 
 You will need to compile this example first:
   mvn compile
 
-The example of queue version should run if you type
+The example of JMS queue version should run if you type
   mvn exec:java -PQueue.LoanBroker
   mvn exec:java -PQueue.Client
 
-The exmple of WebServices version
+The example of web services version
   mvn exec:java -PWS.LoanBroker
   mvn exec:java -PWS.Client
 

Modified: camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/BankResponseAggregationStrategy.java
URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/BankResponseAggregationStrategy.java?rev=1225165&r1=1225164&r2=1225165&view=diff
==============================================================================
--- camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/BankResponseAggregationStrategy.java (original)
+++ camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/BankResponseAggregationStrategy.java Wed Dec 28 12:12:58 2011
@@ -17,42 +17,28 @@
 package org.apache.camel.loanbroker.queue.version;
 
 import org.apache.camel.Exchange;
-import org.apache.camel.Message;
+import org.apache.camel.loanbroker.webservice.version.bank.BankQuote;
 import org.apache.camel.processor.aggregate.AggregationStrategy;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 //START SNIPPET: aggregation
-public class BankResponseAggregationStrategy implements AggregationStrategy {    
-    private static final transient Logger LOG = LoggerFactory.getLogger(BankResponseAggregationStrategy.class);
-    
-    // Here we put the bank response together
-    public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
-        LOG.debug("oldExchange: {}, newExchange: {}", oldExchange, newExchange);
+public class BankResponseAggregationStrategy implements AggregationStrategy {
 
+    @Override
+    public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
         // the first time we only have the new exchange
         if (oldExchange == null) {
             return newExchange;
         }
 
-        Message oldMessage;
-        Message newMessage;
-       
-        oldMessage = oldExchange.getIn();
-        newMessage = newExchange.getIn();
-
-        Double oldRate = oldMessage.getHeader(Constants.PROPERTY_RATE, Double.class);
-        Double newRate = newMessage.getHeader(Constants.PROPERTY_RATE, Double.class);
-
-        Exchange result;
-        if (newRate >= oldRate) {
-            result = oldExchange;
+        Double oldQuote = oldExchange.getIn().getHeader(Constants.PROPERTY_RATE, Double.class);
+        Double newQuote = newExchange.getIn().getHeader(Constants.PROPERTY_RATE, Double.class);
+
+        // return the winner with the lowest rate
+        if (oldQuote.doubleValue() <= newQuote.doubleValue()) {
+            return oldExchange;
         } else {
-            result = newExchange;
+            return newExchange;
         }
-
-        LOG.debug("Lowest rate exchange: {}", result);
-        return result;
     }
 
 }

Modified: camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/Client.java
URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/Client.java?rev=1225165&r1=1225164&r2=1225165&view=diff
==============================================================================
--- camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/Client.java (original)
+++ camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/Client.java Wed Dec 28 12:12:58 2011
@@ -20,16 +20,15 @@ import javax.jms.ConnectionFactory;
 
 import org.apache.activemq.ActiveMQConnectionFactory;
 import org.apache.camel.CamelContext;
-import org.apache.camel.Exchange;
-import org.apache.camel.ExchangePattern;
-import org.apache.camel.Processor;
 import org.apache.camel.ProducerTemplate;
-import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.jms.JmsComponent;
 import org.apache.camel.impl.DefaultCamelContext;
 
 //START SNIPPET: client
-public class Client extends RouteBuilder {
+public final class Client {
+
+    private Client() {
+    }
 
     public static void main(String args[]) throws Exception {
         CamelContext context = new DefaultCamelContext();
@@ -37,54 +36,16 @@ public class Client extends RouteBuilder
         ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:51616");
         // Note we can explicit name of the component
         context.addComponent("jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
-
-        context.addRoutes(new Client());
+        context.start();
 
         ProducerTemplate template = context.createProducerTemplate();
 
-        context.start();
+        String out = template.requestBodyAndHeader("jms:queue:loan", null, Constants.PROPERTY_SSN, "Client-A", String.class);
+        System.out.println(out);
 
-        // send out the request message
-        for (int i = 0; i < 2; i++) {
-            template.sendBodyAndHeader("jms:queue:loanRequestQueue",
-                                       "Quote for the lowest rate of loaning bank",
-                                       Constants.PROPERTY_SSN, "Client-A" + i);
-            Thread.sleep(100);
-        }
-        // wait for the response
-        Thread.sleep(2000);
-        
-        // send the request and get the response from the same queue       
-        Exchange exchange = template.send("jms:queue2:parallelLoanRequestQueue", new Processor() {
-            public void process(Exchange exchange) throws Exception {
-                exchange.setPattern(ExchangePattern.InOut);
-                exchange.getIn().setBody("Quote for the lowst rate of loaning bank");
-                exchange.getIn().setHeader(Constants.PROPERTY_SSN, "Client-B");
-            }
-        });
-        
-        String bank = (String)exchange.getOut().getHeader(Constants.PROPERTY_BANK);
-        Double rate = (Double)exchange.getOut().getHeader(Constants.PROPERTY_RATE);
-        String ssn = (String)exchange.getOut().getHeader(Constants.PROPERTY_SSN);
-        System.out.println("Loan quote for Client " + ssn + "."
-                           + " The lowest rate bank is " + bank + ", with rate " + rate);
-        
-        // Wait a while before stop the context
-        Thread.sleep(1000 * 5);
+        template.stop();
         context.stop();
     }
 
-    /**
-     * Lets configure the Camel routing rules using Java code to pull the response message
-     */
-    public void configure() {
-        from("jms:queue:loanReplyQueue").process(new Processor() {
-            public void process(Exchange exchange) throws Exception {
-                // Print out the response message
-                System.out.println(exchange.getIn().getBody());
-            }
-        });
-    }
-
 }
 // END SNIPPET: client

Modified: camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/Constants.java
URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/Constants.java?rev=1225165&r1=1225164&r2=1225165&view=diff
==============================================================================
--- camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/Constants.java (original)
+++ camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/Constants.java Wed Dec 28 12:12:58 2011
@@ -18,17 +18,9 @@ package org.apache.camel.loanbroker.queu
 
 public interface Constants {
 
-    String LOANBROKER_SERVICE = "loan-broker";
-    String CREDITAGENCY_SERVICE = "credit-agency";
-    String LENDERGATEWAY_SERVICE = "lender-gateway";
-
-
     String PROPERTY_SSN = "ssn";
-    String PROPERTY_AMOUNT = "amount";
-    String PROPERTY_DURATION = "duration";
     String PROPERTY_SCORE = "score";
     String PROPERTY_HISTORYLENGTH = "hlength";
-    String PROPERTY_RECIPIENTS = "recipients";
     String PROPERTY_RATE = "rate";
     String PROPERTY_BANK = "bank";
 

Copied: camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/CreditAgencyProcessor.java (from r1225145, camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/CreditAgency.java)
URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/CreditAgencyProcessor.java?p2=camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/CreditAgencyProcessor.java&p1=camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/CreditAgency.java&r1=1225145&r2=1225165&rev=1225165&view=diff
==============================================================================
--- camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/CreditAgency.java (original)
+++ camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/CreditAgencyProcessor.java Wed Dec 28 12:12:58 2011
@@ -18,22 +18,18 @@ package org.apache.camel.loanbroker.queu
 
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 //START SNIPPET: creditAgency
-public class CreditAgency implements Processor {
-    private static final transient Logger LOG = LoggerFactory.getLogger(CreditAgency.class);
+public class CreditAgencyProcessor implements Processor {
 
     public void process(Exchange exchange) throws Exception {
-        LOG.info("Receiving credit agency request");
         String ssn = exchange.getIn().getHeader(Constants.PROPERTY_SSN, String.class);
         int score = (int) (Math.random() * 600 + 300);
         int hlength = (int) (Math.random() * 19 + 1);
+
         exchange.getOut().setHeader(Constants.PROPERTY_SCORE, score);
         exchange.getOut().setHeader(Constants.PROPERTY_HISTORYLENGTH, hlength);
         exchange.getOut().setHeader(Constants.PROPERTY_SSN, ssn);
-        exchange.getOut().setBody("CreditAgency processed the request.");
     }
 
 }

Propchange: camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/CreditAgencyProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/CreditAgencyProcessor.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/JmsBroker.java
URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/JmsBroker.java?rev=1225165&r1=1225164&r2=1225165&view=diff
==============================================================================
--- camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/JmsBroker.java (original)
+++ camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/JmsBroker.java Wed Dec 28 12:12:58 2011
@@ -21,9 +21,12 @@ import java.io.File;
 import org.apache.activemq.broker.BrokerService;
 import org.apache.activemq.store.memory.MemoryPersistenceAdapter;
 
+/**
+ * Embedded JMS broker
+ */
 public final class JmsBroker {
-    JMSEmbeddedBroker jmsBrokerThread;
-    String jmsBrokerUrl = "tcp://localhost:51616";
+    private JMSEmbeddedBroker jmsBrokerThread;
+    private String jmsBrokerUrl = "tcp://localhost:51616";
 
     public JmsBroker() {
     }

Modified: camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/LoanBroker.java
URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/LoanBroker.java?rev=1225165&r1=1225164&r2=1225165&view=diff
==============================================================================
--- camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/LoanBroker.java (original)
+++ camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/LoanBroker.java Wed Dec 28 12:12:58 2011
@@ -20,88 +20,44 @@ import javax.jms.ConnectionFactory;
 
 import org.apache.activemq.ActiveMQConnectionFactory;
 import org.apache.camel.CamelContext;
-import org.apache.camel.Exchange;
-import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.jms.JmsComponent;
 import org.apache.camel.impl.DefaultCamelContext;
 
 /**
- * The LoanBroker is a RouteBuilder which builds the whole loan message routing rules
- *
- * @version 
+ * Main class to start the loan broker server
  */
-public class LoanBroker extends RouteBuilder {
+public final class LoanBroker {
+
+    private LoanBroker() {
+    }
 
-    /**
-     * A main() so we can easily run these routing rules in our IDE
-     */
     // START SNIPPET: starting
     public static void main(String... args) throws Exception {
-
-        CamelContext context = new DefaultCamelContext();
+        // setup an embedded JMS broker
         JmsBroker broker = new JmsBroker();
         broker.start();
+
+        // create a camel context
+        CamelContext context = new DefaultCamelContext();
+
         // Set up the ActiveMQ JMS Components
         ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:51616");
-
         // Note we can explicitly name the component
         context.addComponent("jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
 
-        context.addRoutes(new LoanBroker());
-        // Start the loan broker
+        // add the route
+        context.addRoutes(new LoanBrokerRoute());
+
+        // start Camel
         context.start();
         System.out.println("Server is ready");
 
+        // let it run for 5 minutes before shutting down
         Thread.sleep(5 * 60 * 1000);
         context.stop();
         Thread.sleep(1000);
         broker.stop();
-
     }
     // END SNIPPET: starting
 
-    /**
-     * Lets configure the Camel routing rules using Java code...
-     */
-    public void configure() {
-    // START SNIPPET: dsl
-        // Put the message from loanRequestQueue to the creditRequestQueue
-        from("jms:queue:loanRequestQueue").to("jms:queue:creditRequestQueue");
-
-        // Now we can let the CreditAgency process the request, then the message will be put into creditResponseQueue
-        from("jms:queue:creditRequestQueue").process(new CreditAgency()).to("jms:queue:creditResponseQueue");
-
-        // Here we use the multicast pattern to send the message to three different bank queues
-        from("jms:queue:creditResponseQueue").multicast().to("jms:queue:bank1", "jms:queue:bank2", "jms:queue:bank3");
-
-        // Each bank processor will process the message and put the response message into the bankReplyQueue
-        from("jms:queue:bank1").process(new Bank("bank1")).to("jms:queue:bankReplyQueue");
-        from("jms:queue:bank2").process(new Bank("bank2")).to("jms:queue:bankReplyQueue");
-        from("jms:queue:bank3").process(new Bank("bank3")).to("jms:queue:bankReplyQueue");
-
-        // Now we aggregate the response message by using the Constants.PROPERTY_SSN header.
-        // The aggregation will be complete when all the three bank responses are received
-        from("jms:queue:bankReplyQueue")
-            .aggregate(header(Constants.PROPERTY_SSN), new BankResponseAggregationStrategy())
-            .completionPredicate(header(Exchange.AGGREGATED_SIZE).isEqualTo(3))
-
-            // Here we do some translation and put the message back to loanReplyQueue
-            .process(new Translator()).to("jms:queue:loanReplyQueue");
-
-    // END SNIPPET: dsl
-        
-    // START SNIPPET: dsl-2
-        // CreditAgency will get the request from parallelLoanRequestQueue
-        from("jms:queue2:parallelLoanRequestQueue").process(new CreditAgency())
-            // Set the aggregation strategy for aggregating the out message            
-            .multicast(new BankResponseAggregationStrategy())
-                // Send out the request to three different banks in parallel
-                .parallelProcessing().to("jms:queue2:bank1", "jms:queue2:bank2", "jms:queue2:bank3");
-        
-        // Each bank processor will process the message and put the response message back
-        from("jms:queue2:bank1").process(new Bank("bank1"));
-        from("jms:queue2:bank2").process(new Bank("bank2"));
-        from("jms:queue2:bank3").process(new Bank("bank3"));
-    // END SNIPPET: dsl-2
-    }
 }

Added: camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/LoanBrokerRoute.java
URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/LoanBrokerRoute.java?rev=1225165&view=auto
==============================================================================
--- camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/LoanBrokerRoute.java (added)
+++ camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/LoanBrokerRoute.java Wed Dec 28 12:12:58 2011
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.loanbroker.queue.version;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.loanbroker.queue.version.bank.BankProcessor;
+
+/**
+ * The route for the loan broker example.
+ */
+public class LoanBrokerRoute extends RouteBuilder {
+
+    /**
+     * Let's configure the Camel routing rules using Java code...
+     */
+    public void configure() {
+        // START SNIPPET: dsl-2
+        from("jms:queue:loan")
+                // let the credit agency do the first work
+                .process(new CreditAgencyProcessor())
+                // send the request to the three banks
+                .multicast(new BankResponseAggregationStrategy()).parallelProcessing()
+                    .to("jms:queue:bank1", "jms:queue:bank2", "jms:queue:bank3")
+                .end()
+                // and prepare the reply message
+                .process(new ReplyProcessor());
+
+        // Each bank processor will process the message and put the response message back
+        from("jms:queue:bank1").process(new BankProcessor("bank1"));
+        from("jms:queue:bank2").process(new BankProcessor("bank2"));
+        from("jms:queue:bank3").process(new BankProcessor("bank3"));
+        // END SNIPPET: dsl-2
+    }
+    
+}

Copied: camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/ReplyProcessor.java (from r1225145, camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/Translator.java)
URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/ReplyProcessor.java?p2=camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/ReplyProcessor.java&p1=camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/Translator.java&r1=1225145&r2=1225165&rev=1225165&view=diff
==============================================================================
--- camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/Translator.java (original)
+++ camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/ReplyProcessor.java Wed Dec 28 12:12:58 2011
@@ -20,14 +20,15 @@ import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 
 //START SNIPPET: translator
-public class Translator implements Processor {
+public class ReplyProcessor implements Processor {
 
     public void process(Exchange exchange) throws Exception {
-        String bank = (String)exchange.getIn().getHeader(Constants.PROPERTY_BANK);
-        Double rate = (Double)exchange.getIn().getHeader(Constants.PROPERTY_RATE);
-        String ssn = (String)exchange.getIn().getHeader(Constants.PROPERTY_SSN);
-        exchange.getOut().setBody("Loan quote for Client " + ssn + "."
-                                  + " The lowest rate bank is " + bank + ", with rate " + rate);
+        String bankName = exchange.getIn().getHeader(Constants.PROPERTY_BANK, String.class);
+        String ssn = exchange.getIn().getHeader(Constants.PROPERTY_SSN, String.class);
+        Double rate = exchange.getIn().getHeader(Constants.PROPERTY_RATE, Double.class);
+
+        String answer = "The best rate is [ssn:" + ssn + " bank:" + bankName + " rate:" + rate + "]";
+        exchange.getOut().setBody(answer);
     }
 
 }

Propchange: camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/ReplyProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/ReplyProcessor.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Copied: camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/bank/BankProcessor.java (from r1225145, camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/Bank.java)
URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/bank/BankProcessor.java?p2=camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/bank/BankProcessor.java&p1=camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/Bank.java&r1=1225145&r2=1225165&rev=1225165&view=diff
==============================================================================
--- camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/Bank.java (original)
+++ camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/bank/BankProcessor.java Wed Dec 28 12:12:58 2011
@@ -14,20 +14,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.loanbroker.queue.version;
+package org.apache.camel.loanbroker.queue.version.bank;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.camel.loanbroker.queue.version.Constants;
 
 //START SNIPPET: bank
-public class Bank implements Processor {
-    private static final transient Logger LOG = LoggerFactory.getLogger(Bank.class);
-    private String bankName;
-    private double primeRate;
+public class BankProcessor implements Processor {
+    private final String bankName;
+    private final double primeRate;
 
-    public Bank(String name) {
+    public BankProcessor(String name) {
         bankName = name;
         primeRate = 3.5;
     }
@@ -35,18 +33,12 @@ public class Bank implements Processor {
     public void process(Exchange exchange) throws Exception {
         String ssn = exchange.getIn().getHeader(Constants.PROPERTY_SSN, String.class);
         Integer historyLength = exchange.getIn().getHeader(Constants.PROPERTY_HISTORYLENGTH, Integer.class);
-        double rate = primeRate + (double)(historyLength / 12) / 10 + (double)(Math.random() * 10) / 10;
-        LOG.info("The bank: " + bankName + " for client: " + ssn + " 's rate " + rate);
-        exchange.getOut().setHeader(Constants.PROPERTY_RATE, new Double(rate));
+        double rate = primeRate + (double)(historyLength / 12) / 10 + (Math.random() * 10) / 10;
+
+        // set reply details as headers
         exchange.getOut().setHeader(Constants.PROPERTY_BANK, bankName);
         exchange.getOut().setHeader(Constants.PROPERTY_SSN, ssn);
-        exchange.getOut().setBody("Bank processed the request.");
-        // Sleep some time
-        try {
-            Thread.sleep((long) (Math.random() * 10) * 100);
-        } catch (InterruptedException e) {
-            // Discard
-        }
+        exchange.getOut().setHeader(Constants.PROPERTY_RATE, rate);
     }
 
 }

Propchange: camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/bank/BankProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/queue/version/bank/BankProcessor.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/BankResponseAggregationStrategy.java
URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/BankResponseAggregationStrategy.java?rev=1225165&r1=1225164&r2=1225165&view=diff
==============================================================================
--- camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/BankResponseAggregationStrategy.java (original)
+++ camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/BankResponseAggregationStrategy.java Wed Dec 28 12:12:58 2011
@@ -23,38 +23,22 @@ import org.apache.camel.processor.aggreg
 //START SNIPPET: aggregating
 public class BankResponseAggregationStrategy implements AggregationStrategy {
 
-    public static final String BANK_QUOTE = "bank_quote";
-
+    @Override
     public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
         // the first time we only have the new exchange
         if (oldExchange == null) {
             return newExchange;
         }
-
-        // Get the bank quote instance from the exchange
-        BankQuote oldQuote = oldExchange.getProperty(BANK_QUOTE, BankQuote.class);
-        // Get the oldQute from out message body if we can't get it from the exchange
-        if (oldQuote == null) {
-            oldQuote = oldExchange.getIn().getBody(BankQuote.class);
-        }
-        // Get the newQuote
+        
+        BankQuote oldQuote = oldExchange.getIn().getBody(BankQuote.class);
         BankQuote newQuote = newExchange.getIn().getBody(BankQuote.class);
-        Exchange result = null;
-        BankQuote bankQuote;
-
-        if (newQuote.getRate() >= oldQuote.getRate()) {
-            result = oldExchange;
-            bankQuote = oldQuote;
+        
+        // return the winner with the lowest rate
+        if (oldQuote.getRate() <= newQuote.getRate()) {
+            return oldExchange;
         } else {
-            result = newExchange;
-            bankQuote = newQuote;
+            return newExchange;
         }
-        // Set the lower rate BankQuote instance back to aggregated exchange
-        result.setProperty(BANK_QUOTE, bankQuote);
-        // Set the return message for the client
-        result.getOut().setBody("The best rate is " + bankQuote.toString());
-
-        return result;
     }
 
 }

Modified: camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/Client.java
URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/Client.java?rev=1225165&r1=1225164&r2=1225165&view=diff
==============================================================================
--- camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/Client.java (original)
+++ camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/Client.java Wed Dec 28 12:12:58 2011
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.loanbroker.webservice.version;
 
+import org.apache.camel.util.StopWatch;
 import org.apache.cxf.BusFactory;
 import org.apache.cxf.frontend.ClientFactoryBean;
 import org.apache.cxf.frontend.ClientProxyFactoryBean;
@@ -24,7 +25,12 @@ import org.apache.cxf.frontend.ClientPro
  * The client that will invoke the loan broker service
  */
 //START SNIPPET: client
-public class Client {
+public final class Client {
+    
+    private static String url = "http://localhost:9008/loanBroker";
+
+    private Client() {
+    }
 
     public LoanBrokerWS getProxy(String address) {
         // Now we use the simple front API to create the client proxy
@@ -38,22 +44,12 @@ public class Client {
 
     public static void main(String[] args) {
         Client client = new Client();
-        LoanBrokerWS loanBroker = client.getProxy(Constants.LOANBROKER_ADDRESS);
-
-        long startTime = System.currentTimeMillis();
-        String result = loanBroker.getLoanQuote("Sequential SSN", 1000.54, 10);
-        long endTime = System.currentTimeMillis();
-
-        System.out.println("It takes " + (endTime - startTime) + " milliseconds to call the sequential loan broker service");
-        System.out.println(result);
-
-        LoanBrokerWS parallelLoanBroker = client.getProxy(Constants.PARALLEL_LOANBROKER_ADDRESS);
+        LoanBrokerWS loanBroker = client.getProxy(url);
 
-        startTime = System.currentTimeMillis();
-        result = parallelLoanBroker.getLoanQuote("Parallel SSN", 1000.54, 10);
-        endTime = System.currentTimeMillis();
+        StopWatch watch = new StopWatch();
+        String result = loanBroker.getLoanQuote("SSN", 5000.00, 24);
 
-        System.out.println("It takes " + (endTime - startTime) + " milliseconds to call the parallel loan broker service");
+        System.out.println("Took " + watch.stop() + " milliseconds to call the loan broker service");
         System.out.println(result);
     }
 

Added: camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/CreditScoreProcessor.java
URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/CreditScoreProcessor.java?rev=1225165&view=auto
==============================================================================
--- camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/CreditScoreProcessor.java (added)
+++ camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/CreditScoreProcessor.java Wed Dec 28 12:12:58 2011
@@ -0,0 +1,73 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.loanbroker.webservice.version;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.loanbroker.webservice.version.credit.CreditAgencyWS;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.frontend.ClientFactoryBean;
+import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
+
+/**
+ * Credit score processor.
+ */
+//START SNIPPET: credit
+public class CreditScoreProcessor implements Processor {
+    private String creditAgencyAddress;
+    private CreditAgencyWS proxy;
+
+    public CreditScoreProcessor(String address) {
+        creditAgencyAddress = address;
+        proxy = getProxy();
+    }
+
+    private CreditAgencyWS getProxy() {
+        // Here we use JaxWs front end to create the proxy
+        JaxWsProxyFactoryBean proxyFactory = new JaxWsProxyFactoryBean();
+        ClientFactoryBean clientBean = proxyFactory.getClientFactoryBean();
+        clientBean.setAddress(creditAgencyAddress);
+        clientBean.setServiceClass(CreditAgencyWS.class);
+        clientBean.setBus(BusFactory.getDefaultBus());
+        return (CreditAgencyWS)proxyFactory.create();
+    }
+
+    @SuppressWarnings("unchecked")
+    public void process(Exchange exchange) throws Exception {
+        List<Object> request = exchange.getIn().getBody(List.class);
+
+        String ssn = (String) request.get(0);
+        Double amount = (Double) request.get(1);
+        Integer loanDuration = (Integer) request.get(2);
+        int historyLength = proxy.getCreditHistoryLength(ssn);
+        int score = proxy.getCreditScore(ssn);
+
+        // create the invocation message for Bank client
+        List<Object> bankRequest = new ArrayList<Object>();
+        bankRequest.add(ssn);
+        bankRequest.add(amount);
+        bankRequest.add(loanDuration);
+        bankRequest.add(historyLength);
+        bankRequest.add(score);
+        exchange.getOut().setBody(bankRequest);
+        exchange.getOut().setHeader("operationName", "getQuote");
+    }
+
+}

Modified: camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/LoanBroker.java
URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/LoanBroker.java?rev=1225165&r1=1225164&r2=1225165&view=diff
==============================================================================
--- camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/LoanBroker.java (original)
+++ camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/LoanBroker.java Wed Dec 28 12:12:58 2011
@@ -16,123 +16,23 @@
  */
 package org.apache.camel.loanbroker.webservice.version;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.Exchange;
-import org.apache.camel.Message;
-import org.apache.camel.Processor;
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.cxf.common.message.CxfConstants;
-import org.apache.camel.impl.DefaultCamelContext;
-import org.apache.camel.loanbroker.webservice.version.bank.BankServer;
-import org.apache.camel.loanbroker.webservice.version.credit.CreditAgencyServer;
-import org.apache.camel.loanbroker.webservice.version.credit.CreditAgencyWS;
-import org.apache.cxf.BusFactory;
-import org.apache.cxf.frontend.ClientFactoryBean;
-import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
+import org.apache.camel.spring.Main;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
 
 /**
- * The LoanBroker is a RouteBuilder which builds the whole loan message routing rules
+ * Main class to run the loan broker server from command line.
  */
-public class LoanBroker extends RouteBuilder {
-
-    //START SNIPPET: server
-    public static void main(String... args) throws Exception {
-        CamelContext context = new DefaultCamelContext();
-        CreditAgencyServer creditAgencyServer = new CreditAgencyServer();
-        // Start the credit server
-        creditAgencyServer.start();
-
-        // Start the bank server
-        BankServer bankServer = new BankServer();
-        bankServer.start();
-
-        // Start the camel context
-        context.addRoutes(new LoanBroker());
-        context.start();
+public final class LoanBroker {
 
-        // Start the loan broker
-        Thread.sleep(5 * 60 * 1000);
-        context.stop();
-        Thread.sleep(1000);
-        bankServer.stop();
-        creditAgencyServer.stop();
+    private LoanBroker() {
     }
-    //END SNIPPET: server
-
-    /**
-     * Lets configure the Camel routing rules using Java code...
-     */
-    public void configure() {
-    // START SNIPPET: dsl
-
-        // Router 1 to call the bank endpoints sequentially
-        from(Constants.LOANBROKER_URI)
-            // Using the CreditScoreProcessor to call the credit agency service
-            .process(new CreditScoreProcessor(Constants.CREDITAGENCY_ADDRESS))
-                // Set the aggregation strategy on the multicast pattern
-                .multicast(new BankResponseAggregationStrategy())
-                    // Send out the request to three different banks sequentially
-                    .to(Constants.BANK1_URI, Constants.BANK2_URI, Constants.BANK3_URI);
-
-        // Router 2 to call the bank endpoints in parallel
-        from(Constants.PARALLEL_LOANBROKER_URI)
-            .process(new CreditScoreProcessor(Constants.CREDITAGENCY_ADDRESS))
-                // Using the thread pool to send out messages to three different banks in parallel                
-                .multicast(new BankResponseAggregationStrategy())
-                    // Camel will create a thread pool with the default size (10) 
-                    // for sending the message in parallel
-                    .parallelProcessing()
-                    .to(Constants.BANK1_URI, Constants.BANK2_URI, Constants.BANK3_URI);
-
-    //END SNIPPET: dsl
-    }
-
-    //START SNIPPET: credit
-    class CreditScoreProcessor implements Processor {
-        private String creditAgencyAddress;
-        private CreditAgencyWS proxy;
-
-        public CreditScoreProcessor(String address) {
-            creditAgencyAddress = address;
-            proxy = getProxy();
-        }
-
-        private CreditAgencyWS getProxy() {
-            // Here we use JaxWs front end to create the proxy
-            JaxWsProxyFactoryBean proxyFactory = new JaxWsProxyFactoryBean();
-            ClientFactoryBean clientBean = proxyFactory.getClientFactoryBean();
-            clientBean.setAddress(creditAgencyAddress);
-            clientBean.setServiceClass(CreditAgencyWS.class);
-            clientBean.setBus(BusFactory.getDefaultBus());
-            return (CreditAgencyWS)proxyFactory.create();
-        }
-
-        @SuppressWarnings("unchecked")
-        public void process(Exchange exchange) throws Exception {
-            Message requestMessage = exchange.getIn();
-            List<Object> request = (List<Object>) requestMessage.getBody();
-
-            String ssn = (String)request.get(0);
-            Double amount = (Double) request.get(1);
-            Integer loanDuration = (Integer)request.get(2);
-            int historyLength = proxy.getCreditHistoryLength(ssn);
-            int score = proxy.getCreditScore(ssn);
-
-            // create the invocation message for Bank client
-            List<Object> bankRequest = new ArrayList<Object>();
-            bankRequest.add(ssn);
-            bankRequest.add(amount);
-            bankRequest.add(loanDuration);
-            bankRequest.add(historyLength);
-            bankRequest.add(score);
-            exchange.getOut().setBody(bankRequest);
-            exchange.getOut().setHeader(CxfConstants.OPERATION_NAME, "getQuote");
-        }
 
+    public static void main(String... args) throws Exception {
+        // create a new main which will boot the Spring XML file
+        Main main = new Main();
+        main.setApplicationContext(new ClassPathXmlApplicationContext("META-INF/spring/webServiceCamelContext.xml"));
+        main.enableHangupSupport();
+        main.run();
     }
-    //END SNIPPET: credit
 
 }

Added: camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/ReplyProcessor.java
URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/ReplyProcessor.java?rev=1225165&view=auto
==============================================================================
--- camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/ReplyProcessor.java (added)
+++ camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/ReplyProcessor.java Wed Dec 28 12:12:58 2011
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.loanbroker.webservice.version;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.loanbroker.webservice.version.bank.BankQuote;
+
+/**
+ * Processor to set the reply message for the loan broker web service
+ */
+public class ReplyProcessor implements Processor {
+    
+    @Override
+    public void process(Exchange exchange) throws Exception {
+        BankQuote quote = exchange.getIn().getBody(BankQuote.class);
+        
+        String answer = "The best rate is " + quote.toString();
+        exchange.getOut().setBody(answer);
+    }
+}

Modified: camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/bank/BankQuote.java
URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/bank/BankQuote.java?rev=1225165&r1=1225164&r2=1225165&view=diff
==============================================================================
--- camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/bank/BankQuote.java (original)
+++ camel/trunk/examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/bank/BankQuote.java Wed Dec 28 12:12:58 2011
@@ -55,7 +55,7 @@ public class BankQuote {
     }
 
     public String toString() {
-        return "[ ssn:" + ssn + " bank:" + bankName + " rate:" + rate + " ]";
+        return "[ssn:" + ssn + " bank:" + bankName + " rate:" + rate + "]";
     }
 
 }

Modified: camel/trunk/examples/camel-example-loan-broker/src/main/resources/META-INF/spring/webServiceCamelContext.xml
URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-loan-broker/src/main/resources/META-INF/spring/webServiceCamelContext.xml?rev=1225165&r1=1225164&r2=1225165&view=diff
==============================================================================
--- camel/trunk/examples/camel-example-loan-broker/src/main/resources/META-INF/spring/webServiceCamelContext.xml (original)
+++ camel/trunk/examples/camel-example-loan-broker/src/main/resources/META-INF/spring/webServiceCamelContext.xml Wed Dec 28 12:12:58 2011
@@ -19,17 +19,26 @@
 <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:camel="http://camel.apache.org/schema/spring"
+       xmlns:cxf="http://camel.apache.org/schema/cxf"
        xmlns:jaxws="http://cxf.apache.org/jaxws"
+       xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="
          http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
          http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
+         http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
          http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
 
   <import resource="classpath:META-INF/cxf/cxf.xml"/>
 
+  <!-- spring property placeholder, ignore resource not found as the file resource is for unit testing -->
+  <context:property-placeholder location="classpath:loanbroker.properties,file:target/custom.properties"
+                                ignore-resource-not-found="true"/>
+
+  <!-- web service for credit agency -->
   <jaxws:endpoint id="creditAgent"
                   implementor="org.apache.camel.loanbroker.webservice.version.credit.CreditAgency"
-                  address="http://localhost:9006/creditAgency"/>
+                  address="http://localhost:${credit_agency.port}/creditAgency"/>
 
   <bean id="bank1" class="org.apache.camel.loanbroker.webservice.version.bank.Bank">
     <constructor-arg index="0">
@@ -49,25 +58,53 @@
     </constructor-arg>
   </bean>
 
-
+  <!-- web service for the 3 banks -->
   <jaxws:endpoint id="bankService1"
                   implementor="#bank1"
-                  address="http://localhost:9001/bank1"/>
+                  address="http://localhost:${bank1.port}/bank1"/>
 
   <jaxws:endpoint id="bankService2"
                   implementor="#bank2"
-                  address="http://localhost:9002/bank2"/>
+                  address="http://localhost:${bank2.port}/bank2"/>
 
   <jaxws:endpoint id="bankService3"
                   implementor="#bank3"
-                  address="http://localhost:9003/bank3"/>
+                  address="http://localhost:${bank3.port}/bank3"/>
+  
+  
+  <!-- loan broker web service -->
+  <cxf:cxfEndpoint id="loanBroker"
+                   address="http://localhost:${loan_broker.port}/loanBroker"
+                   serviceClass="org.apache.camel.loanbroker.webservice.version.LoanBrokerWS"/>
 
   <!-- Camel -->
   <camel:camelContext id="webService">
-    <!-- refer to the route to use -->
-    <camel:routeBuilder ref="webServiceLoanBroker"/>
+
+    <!-- define endpoints for the banks -->
+    <camel:endpoint id="bank1WS" uri="cxf://http://localhost:${bank1.port}/bank1?serviceClass=org.apache.camel.loanbroker.webservice.version.bank.BankWS"/>
+    <camel:endpoint id="bank2WS" uri="cxf://http://localhost:${bank2.port}/bank2?serviceClass=org.apache.camel.loanbroker.webservice.version.bank.BankWS"/>
+    <camel:endpoint id="bank3WS" uri="cxf://http://localhost:${bank3.port}/bank3?serviceClass=org.apache.camel.loanbroker.webservice.version.bank.BankWS"/>
+
+    <camel:route id="loanBrokerRoute">
+      <camel:from uri="cxf:bean:loanBroker"/>
+      <camel:process ref="creditScoreProcessor"/>
+      <camel:multicast parallelProcessing="true" strategyRef="bankResponse">
+        <camel:to ref="bank1WS"/>
+        <camel:to ref="bank2WS"/>
+        <camel:to ref="bank3WS"/>
+      </camel:multicast>
+      <camel:process ref="replyProcessor"/>
+    </camel:route>
   </camel:camelContext>
 
-  <bean id="webServiceLoanBroker" class="org.apache.camel.loanbroker.webservice.version.LoanBroker"/>
+  <!-- processor to calculate credit score -->
+  <bean id="creditScoreProcessor" class="org.apache.camel.loanbroker.webservice.version.CreditScoreProcessor">
+    <constructor-arg index="0" value="http://localhost:${credit_agency.port}/creditAgency"/>
+  </bean>
+  
+  <bean id="replyProcessor" class="org.apache.camel.loanbroker.webservice.version.ReplyProcessor"/>
+  
+  <!-- strategy to assemble the bank responses -->
+  <bean id="bankResponse" class="org.apache.camel.loanbroker.webservice.version.BankResponseAggregationStrategy"/>
 
 </beans>

Added: camel/trunk/examples/camel-example-loan-broker/src/main/resources/loanbroker.properties
URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-loan-broker/src/main/resources/loanbroker.properties?rev=1225165&view=auto
==============================================================================
--- camel/trunk/examples/camel-example-loan-broker/src/main/resources/loanbroker.properties (added)
+++ camel/trunk/examples/camel-example-loan-broker/src/main/resources/loanbroker.properties Wed Dec 28 12:12:58 2011
@@ -0,0 +1,23 @@
+## ------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements.  See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License.  You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ------------------------------------------------------------------------
+
+# properties for the application
+bank1.port=9001
+bank2.port=9002
+bank3.port=9003
+credit_agency.port=9006
+loan_broker.port=9008

Modified: camel/trunk/examples/camel-example-loan-broker/src/test/java/org/apache/camel/loanbroker/queue/version/LoanBrokerQueueTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-loan-broker/src/test/java/org/apache/camel/loanbroker/queue/version/LoanBrokerQueueTest.java?rev=1225165&r1=1225164&r2=1225165&view=diff
==============================================================================
--- camel/trunk/examples/camel-example-loan-broker/src/test/java/org/apache/camel/loanbroker/queue/version/LoanBrokerQueueTest.java (original)
+++ camel/trunk/examples/camel-example-loan-broker/src/test/java/org/apache/camel/loanbroker/queue/version/LoanBrokerQueueTest.java Wed Dec 28 12:12:58 2011
@@ -16,18 +16,12 @@
  */
 package org.apache.camel.loanbroker.queue.version;
 
-import java.util.List;
 import javax.jms.ConnectionFactory;
 
 import org.apache.activemq.ActiveMQConnectionFactory;
 import org.apache.camel.CamelContext;
-import org.apache.camel.Exchange;
-import org.apache.camel.ExchangePattern;
-import org.apache.camel.Processor;
 import org.apache.camel.ProducerTemplate;
-import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.jms.JmsComponent;
-import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.impl.DefaultCamelContext;
 import org.apache.camel.test.junit4.TestSupport;
 import org.junit.After;
@@ -46,20 +40,14 @@ public class LoanBrokerQueueTest extends
         camelContext = new DefaultCamelContext();
         broker = new JmsBroker("vm://localhost");
         broker.start();
+        
         // Set up the ActiveMQ JMS Components
         ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost");
 
         // Note we can explicitly name the component
         camelContext.addComponent("jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
 
-        camelContext.addRoutes(new LoanBroker());
-        
-        camelContext.addRoutes(new RouteBuilder() {
-            // using the mock endpoint to check the result
-            public void configure() throws Exception {
-                from("jms:queue:loanReplyQueue").to("mock:endpoint");
-            }
-        });
+        camelContext.addRoutes(new LoanBrokerRoute());
        
         template = camelContext.createProducerTemplate();
         camelContext.start();
@@ -79,45 +67,11 @@ public class LoanBrokerQueueTest extends
     
     @Test
     public void testClientInvocation() throws Exception {
-        MockEndpoint endpoint = camelContext.getEndpoint("mock:endpoint", MockEndpoint.class);
-        endpoint.expectedMessageCount(2);
-        // send out the request message
-        for (int i = 0; i < 2; i++) {
-            template.sendBodyAndHeader("jms:queue:loanRequestQueue",
-                                       "Quote for the lowerst rate of loaning bank",
-                                       Constants.PROPERTY_SSN, "Client-A" + i);
-            Thread.sleep(100);
-        }
-        endpoint.assertIsSatisfied();
-
-        // check the response from the mock endpoint
-        List<Exchange> exchanges = endpoint.getExchanges();
-        int index = 0;
-        for (Exchange exchange : exchanges) {
-            String ssn = "Client-A" + index;
-            String result = exchange.getIn().getBody(String.class);
-            assertNotNull("The result should not be null", result);
-            assertTrue("The result is wrong", result.startsWith("Loan quote for Client " + ssn));
-            index++;
-        }
-        
-        // send the request and get the response from the same queue       
-        Exchange exchange = template.send("jms:queue2:parallelLoanRequestQueue", new Processor() {
-            public void process(Exchange exchange) throws Exception {
-                exchange.setPattern(ExchangePattern.InOut);
-                exchange.getIn().setBody("Quote for the lowest rate of loaning bank");
-                exchange.getIn().setHeader(Constants.PROPERTY_SSN, "Client-B");
-            }
-        });
-        
-        String bank = exchange.getOut().getHeader(Constants.PROPERTY_BANK, String.class);
-        Double rate = exchange.getOut().getHeader(Constants.PROPERTY_RATE, Double.class);
-        String ssn = exchange.getOut().getHeader(Constants.PROPERTY_SSN, String.class);
+        String out = template.requestBodyAndHeader("jms:queue:loan", null, Constants.PROPERTY_SSN, "Client-A", String.class);
         
-        assertNotNull("The ssn should not be null.", ssn);
-        assertEquals("Get a wrong ssn", "Client-B",  ssn);
-        assertNotNull("The bank should not be null", bank);
-        assertNotNull("The rate should not be null", rate);
+        log.info("Result: {}", out);
+        assertNotNull(out);
+        assertTrue(out.startsWith("The best rate is [ssn:Client-A bank:bank"));
     }
 
 }

Modified: camel/trunk/examples/camel-example-loan-broker/src/test/java/org/apache/camel/loanbroker/webservice/version/LoanBrokerWSTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-loan-broker/src/test/java/org/apache/camel/loanbroker/webservice/version/LoanBrokerWSTest.java?rev=1225165&r1=1225164&r2=1225165&view=diff
==============================================================================
--- camel/trunk/examples/camel-example-loan-broker/src/test/java/org/apache/camel/loanbroker/webservice/version/LoanBrokerWSTest.java (original)
+++ camel/trunk/examples/camel-example-loan-broker/src/test/java/org/apache/camel/loanbroker/webservice/version/LoanBrokerWSTest.java Wed Dec 28 12:12:58 2011
@@ -16,50 +16,64 @@
  */
 package org.apache.camel.loanbroker.webservice.version;
 
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
+import java.io.File;
+import java.io.FileOutputStream;
+
+import org.apache.camel.test.AvailablePortFinder;
+import org.apache.camel.test.junit4.CamelSpringTestSupport;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.springframework.context.support.AbstractApplicationContext;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 
-public class LoanBrokerWSTest extends Assert {
-    AbstractApplicationContext applicationContext;
+public class LoanBrokerWSTest extends CamelSpringTestSupport {
     
-    @Before
-    public void startServices() throws Exception {
-        if (!"true".equalsIgnoreCase(System.getProperty("skipStartingCamelContext"))) {
-            applicationContext = new ClassPathXmlApplicationContext(new String[]{"/META-INF/spring/webServiceCamelContext.xml"});
-        } else {
-            System.out.println("Skipping starting CamelContext as system property skipStartingCamelContext is set to be true.");
-        }
-    }
+    private static String url;
     
-    @After
-    public void stopServices() throws Exception {
-        if (applicationContext != null) {
-            applicationContext.stop();
-        }
+    @BeforeClass
+    public static void setupFreePort() throws Exception {
+        // find a free port number from 9100 onwards, and write that in the custom.properties file
+        // which we will use for the unit tests, to avoid port number in use problems
+        int port = AvailablePortFinder.getNextAvailable(9100); 
+        String bank1 = "bank1.port=" + port;
+        port = AvailablePortFinder.getNextAvailable(port + 1);
+        String bank2 = "bank2.port=" + port;
+        port = AvailablePortFinder.getNextAvailable(port + 1);
+        String bank3 = "bank3.port=" + port;
+        port = AvailablePortFinder.getNextAvailable(port + 1);
+        String credit = "credit_agency.port=" + port;
+        port = AvailablePortFinder.getNextAvailable(port + 1);
+        String loan = "loan_broker.port=" + port;
+
+        File custom = new File("target/custom.properties");
+        FileOutputStream fos = new FileOutputStream(custom);
+        fos.write(bank1.getBytes());
+        fos.write("\n".getBytes());
+        fos.write(bank2.getBytes());
+        fos.write("\n".getBytes());
+        fos.write(bank3.getBytes());
+        fos.write("\n".getBytes());
+        fos.write(credit.getBytes());
+        fos.write("\n".getBytes());
+        fos.write(loan.getBytes());
+        fos.write("\n".getBytes());
+        fos.close();
+
+        url = "http://localhost:" + port + "/loanBroker";
     }
-    
+
     @Test
-    public void testInvocation() {
+    public void testInvocation() throws Exception {
         Client client = new Client();
-        String result = null;
-        LoanBrokerWS loanBroker = client.getProxy(Constants.LOANBROKER_ADDRESS);
-        long startTime = System.currentTimeMillis();
-        result = loanBroker.getLoanQuote("Sequential SSN", 1000.54, 10);
-        long endTime = System.currentTimeMillis();
-        long delta1 = endTime - startTime;
-        assertTrue(result.startsWith("The best rate is [ ssn:Sequential SSN bank:bank"));
-
-        LoanBrokerWS paralleLoanBroker = client.getProxy(Constants.PARALLEL_LOANBROKER_ADDRESS);
-        startTime = System.currentTimeMillis();
-        result = paralleLoanBroker.getLoanQuote("Parallel SSN", 1000.54, 10);
-        endTime = System.currentTimeMillis();
-        long delta2 = endTime - startTime;
-        assertTrue(result.startsWith("The best rate is [ ssn:Parallel SSN bank:bank"));
-        
-        assertTrue(delta2 < delta1);
+
+        LoanBrokerWS loanBroker = client.getProxy(url);
+        String result = loanBroker.getLoanQuote("SSN", 1000.54, 10);
+        log.info("Result: {}", result);
+        assertTrue(result.startsWith("The best rate is [ssn:SSN bank:bank"));
+    }
+
+    @Override
+    protected AbstractApplicationContext createApplicationContext() {
+        return new ClassPathXmlApplicationContext("/META-INF/spring/webServiceCamelContext.xml");
     }
 }