Loan Broker ExampleThis example shows how to use Camel to implement the EIP's loan broker example. The example has two versions,one for JMS, one for webservice one. Implementation with message queue (JMS)The queue version of loan broker is based on the camel-jms component, and it shows how to using the message queue to connect the different service models (such as the credit agency , and banks). The example should run if you type mvn exec:java -PQueue.LoanBroker mvn exec:java -PQueue.Client To stop the example hit ctrl + c let's take a look how this service modules are put together. Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20
The CreditAgency , Bank and Translator are all the implementation of Processor interface. We implement the business logical in the void process(Exchange exchange) method. CreditAgency Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20
Bank Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20
Translator Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20
You may found we set a custom aggregation strategy to find out the lowest loan rate from bank response message. 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; } 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 { return newExchange; } } } We start the loan broker after we start up the ActiveMq broker and the connection factory of Camel-JMS component. public static void main(String... args) throws Exception { // 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)); // 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(); } Now we can send the request from client and pull the response message back public final class Client { private Client() { } public static void main(String args[]) throws Exception { CamelContext context = new DefaultCamelContext(); // Set up the ActiveMQ JMS Components ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:51616"); // Note we can explicit name of the component context.addComponent("jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory)); context.start(); ProducerTemplate template = context.createProducerTemplate(); String out = template.requestBodyAndHeader("jms:queue:loan", null, Constants.PROPERTY_SSN, "Client-A", String.class); System.out.println(out); template.stop(); context.stop(); } } Implementation with web serviceThe web service version of loan broker is based on the camel-cxf component which can produce and consume the SOAP message on the wire. It uses the InOut Message exchange pattern, when the client send out the message to the router , it can get the response message back from the same endpoint. The example should run if you type mvn exec:java -PWS.LoanBroker mvn exec:java -PWS.Client To stop the example hit ctrl + c First, let's go through the SEI (Service Endpoint Interface) for LoanBroker, CreditAgency and Bank. LoanBroker // This SEI has no @WebService annotation, we use the simple frontend API to create client and server public interface LoanBrokerWS { String getLoanQuote(String ssn, Double loanAmount, Integer loanDuration); } CreditAgency @WebService public interface CreditAgencyWS { int getCreditScore(String ssn); int getCreditHistoryLength(String ssn); } Bank // Since we use @WebServices here, please make sure to use JaxWs frontend API create the client and server @WebService public interface BankWS { String getBankName(); BankQuote getQuote(String ssn, double loanAmount, int loanDuration, int creditHistory, int creditScore); } Here are two routing rules in DSL , one is for routing the request to bank sequentially, the other is for calling the bank service parallely. Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20
We use the CreditScoreProcessor to send two request to credit agency to get the credit history length and the credit score and prepare the request message for the bank. Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20
Now we implement the Bank and CreditAgency SEI with the business logical codes. Bank public class Bank implements BankWS { private String bankName; private double primeRate; public Bank(String name) { bankName = name; primeRate = 3.5; } public String getBankName() { return bankName; } public BankQuote getQuote(String ssn, double loanAmount, int loanDuration, int creditHistory, int creditScore) { Double rate = primeRate + (double)(loanDuration / 12) / 10 + Math.random() * 10 / 10; // Wait for a while try { Thread.sleep(1000); } catch (InterruptedException e) { // do nothing here } BankQuote result = new BankQuote(bankName, ssn, rate); return result; } } CreditAgency public class CreditAgency implements CreditAgencyWS { public int getCreditHistoryLength(String ssn) { int creditScore = (int)(Math.random() * 600 + 300); return creditScore; } public int getCreditScore(String ssn) { int creditHistoryLength = (int)(Math.random() * 19 + 1); return creditHistoryLength; } } The below codes show how the start the loan broker. Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20
We can send the request by creating a client proxy with the LoanBroker SEI in the client code. BTW, you can compare the two different routing rule's performance by running the client. public final class Client { private static String url = "http://localhost:9008/loanBroker"; private Client() { } public static LoanBrokerWS getProxy(String address) { // Now we use the simple front API to create the client proxy ClientProxyFactoryBean proxyFactory = new ClientProxyFactoryBean(); ClientFactoryBean clientBean = proxyFactory.getClientFactoryBean(); clientBean.setAddress(address); clientBean.setServiceClass(LoanBrokerWS.class); clientBean.setBus(BusFactory.getDefaultBus()); return (LoanBrokerWS) proxyFactory.create(); } public static void main(String[] args) { LoanBrokerWS loanBroker = getProxy(url); StopWatch watch = new StopWatch(); String result = loanBroker.getLoanQuote("SSN", 5000.00, 24); System.out.println("Took " + watch.stop() + " milliseconds to call the loan broker service"); System.out.println(result); } } |