EIP 'Loan Broker' Reference Implementation (Part 1)

Oleg Zhurakousky

We are pleased to announce the first installment of the 'Loan Broker' Reference Implementation.
'Loan Broker' concept has become a de-facto reference domain for showcasing Enterprise Integration Patterns (EIP) – by Gregor Hohpe ad Bobby Woolf, and this installment of the Loan Broker RI demonstrates how Enterprise Integration Patterns are realized and applied using Spring Integration (SI) framework.

Introduction

lb-pipesFilters

At the core of EIP architecture are the very simple yet powerful concepts of Pipes and Filters and Message. Endpoints (Filters) are connected with one another via Channels (Pipes). The producing endpoint sends Message to the Channel and the Message is retrieved by the Consuming endpoint.  This architecture is meant to define various mechanisms that describe How information is exchanged between the endpoints, without any awareness of What those endpoints are or What information they are exchanging, thus providing for a very loosely coupled and flexible collaboration model while also, decoupling Integration concerns from Business concerns. EIP extends this architecture by further defining:

  • the types of pipes (Point-to-Point Channel, Publish-Subscribe Channel, Channel Adapter, etc.)
  • the core filters and patterns around how filters collaborate with pipes (Message Router, Splitters and Aggregators, various Message Transformation patterns, etc.)

The Spring Integration (SI) messaging framework is designed to provide a POJO-based programming model built on top of Enterprise Integration Patterns.

Use Case

The details and variations of this use case are very nicely described in Chapter 9 of the EIP Book, but here is the brief summary;
A Consumer while shopping for the best Loan Quote(s) subscribes to the services of a Loan Broker, which handles details such as:

  1. Consumer pre-screening (e.g., obtain and review the consumer's Credit history)
  2. Determine the most appropriate Banks (e.g., based on consumer's credit history/score)
  3. Send a Loan quote request to each selected Bank
  4. Collect responses from each Bank
  5. Filter responses and determine the best quote(s), based on consumer's requirements.
  6. Pass the Loan quote(s) back to the consumer.

Obviously the real process of obtaining a loan quote is a bit more complex, but since our goal here is to demonstrate how Enterprise Integration Patterns are realized and implemented within SI, the use case has been simplified to concentrate only on the Integration aspects of the process. It is not an attempt to give you an advice in consumer finances.
loan-broker-1
As you can see, by hiring a Loan Broker, the consumer is isolated from the details of the Loan Broker's operations, and each Loan Broker's operations may defer from one another to maintain competitive advantage, so whatever we assemble/implement must be flexible so any changes could be introduced quickly and painlessly.
Speaking of change, this first installment of the Loan Broker RI does not actually talk to any 'imaginary' Banks or Credit bureaus. Those services are stubbed out. Our goal here is to assemble, orchestrate and test the integration aspect of the process as a whole. Only then can we start thinking about wiring such process to the real services. We will do this in Part 2, where you'll realize the true benefit of separating integration and business concerns. You will see, that the process and configuration describing this process will not change regardless of the number of Banks a particular Loan Broker is dealing with, or the type of communication media (or protocols) used (JMS, WS, TCP, etc.) to communicate with these Banks.

Design

As you analyze the 6 requirements above you'll quickly see that they all fall into the category of Integration concerns. For example, in the consumer pre-screening step we need to gather additional information about the consumer and the consumer's desires and enrich the loan request with additional meta information. We then have to filter such information to select the most appropriate list of Banks, and so on. Enrich, filter, select – these are all integration concerns for which EIP defines a solution in the form of patterns. SI provides an implementation of these patterns.

Submit Loan Quote request – Messaging Gateway

lb-gateway

The Messaging Gateway pattern provides a simple mechanism to access messaging systems, including our Loan Broker. In SI you define the Gateway as a Plain Old Java Interface (no need to provide an implementation), configure it via the XML <gateway> element or via annotation and use it as any other Spring bean. SI will take care of delegating and mapping method invocations to the Messaging infrastructure by generating a Message (payload is mapped to an input parameter of the method) and sending it to the designated channel.

LoanBrokerGateway.java is the interface representing the Message Gateway used by the consumer

Gateway XML configuration:

<int:gateway id="loanBrokerGateway"
		     default-request-channel="loanBrokerPreProcessingChannel"
		     service-interface="org.springframework.integration.loanbroker.LoanBrokerGateway"/>

In the above configuration whenever any method is invoked on the 'loanBrokerGateway' bean, a Message will be constructed and sent to the 'loanBrokerPreProcessingChannel'.

Our definition of the Messaging Gateway (LoanBrokerGateway.java) gives the consumer two ways to interact with the Loan Broker. The Consumer might request a single(best) quote by invoking the getLoanQuote(loanRequest) method, or all quotes via a call to getAllLoanQuotes(loanRequest) method. This means that our Loan Broker must be aware of the type of the Loan request. We also know there are some pre-screening steps such as getting and evaluating the consumer's credit score, simply because some premiere Banks will only typically accept quote requests from consumers that meet a minimum credit score requirement.

Essentially, this whole process resembles doctors visit where before seeing the real doctor you meet the nurse who takes your temperature, blood pressure etc., writing up a list of 'meta information' the doctor will need.

In EIP  a Message is a simple structure which consists of a Message Payload and Message Headers. Message Headers are a great mechanism to store meta information related to the Message. So how can we enrich our Message with the additional information? EIP defines the Content Enricher pattern which describes how to augment a Message with additional information. Spring Integration provides a <header-enricher> element allowing you to quickly enrich a Message in-transit. But since our Loan Broker must perform several tasks before sending out the quote, it would be nice if there were also a mechanism to compose a process from a set of individual and independent tasks.

Loan Request Pre-screeening – Composed Message Processor and Content Enricher

The Composed Message Processor pattern describes rules around building endpoints that maintain control over message flow which consists of multiple message processors. In our case the pre-screening flow consists of 3 steps: a) determine the the type of the loan request; b) obtain consumer's credit history and score; c) determine (based on some criteria) the list of channels (each channel corresponds to an individual bank).

Spring Integration allows you to compose complex processors via the <chain> element

<int:chain id="preScreening" input-channel="loanBrokerPreProcessingChannel" output-channel="banksDistributionChannel">
	<int:header-enricher>
		<int:header name="RESPONSE_TYPE"
			expression="headers.history.iterator().next().attributes['method'].equals('getLoanQuote') ? 'BEST' : 'ALL'" />
	</int:header-enricher>
	<int:header-enricher>
		<int:header name="CREDIT_SCORE" ref="creditBureau" method="getCreditScore"/>
	</int:header-enricher>
	<int:header-enricher>
		<int:header name="BANKS" ref="bankSelector" method="selectBankChannels"/>
	</int:header-enricher>
</int:chain>

lb-chain

This will create a bean 'preScreening" as an SI chain endpoint, which also defines an input/output-channel to receive and send messages. The above chain is composed with 3 header-enricher processors. The first one will set RESPONSE_TYPE header by utilizing SpEL while accessing the Message History and determining this header's value based on the Gateway method invoked.

This example illustrates how SpEL can be used to perform simple evaluations while determining the header value, but we do not advocate using SpEL to perform complex business logic

Next we have a header-enricher which is mapped to a process responsible for getting the credit score from the Credit Bureau (currently stub CreditBureauStub) and set the CREDIT_SCORE header. The last header-enricher uses the BankChannelSelector (see the bankSelector config).The implementation of the BankChannelSelector.selectBankChannels(..) method takes a Message as input and returns a Set<String> value containing the name of channels, which will be set as the BANKS header.
This completes our pre-screening process, our Loan Broker is now ready to send a loan request to each selected Bank via the banksDistributionChannel.

The BANKS header defines the dynamically generated and filtered list of channels each of which acts as a recipient representing a Bank. We need an endpoint that allows us to send the same Message to all recipients.

Distribute Loan Quote Requests to Selected Banks - Recipient List

lb-recipientList
EIP defines various types of routing patterns which all derive from Message Router. One of them is the Recipient List router, which routes a message to all recipients in the list. SI provides a <router> element that allows us to configure a router which, in our case, will receive a Message from the bankDistributionChannel. This router will get the list of bank channels from the BANKS Message Header via a SpEL expression (this list is set in the pre-screening step), and will distribute the Message to these channels.

The XML Configuration below shows how this router is configured:

<int:router id="bankRecipientListRouter" input-channel="banksDistributionChannel"
								expression="headers['BANKS']"
								apply-sequence="true"/>

You can clearly see how we are assembling Loan Broker by connecting various endpoints (Filters) via channels (Pipes), while passing Messages. You can also see that we are accomplishing it through POJO-based programming techniques, barely using the Spring Integration API (only BankChannelSelector.java). SI takes care of interfacing our POJOs with the Messaging infrastructure.

One last thing the Loan Broker needs to to is to receive the loan quotes form the banks, aggregate them by consumer (we don't want to show quotes from one consumer to another), assemble the response based on the consumer's selection criteria (single best quote or all quotes) and reply back to the consumer.

Aggregating Loan Quote Responses – Aggregator

An Aggregator pattern describes an endpoint which groups related Messages into a single Message. Criteria and rules can be provided to determine an aggregation and correlation strategy. SI provides several implementations of the Aggregator pattern as well as a convenient name-space based configuration.

lb-complete

Our Loan Broker defines a 'loanQuoteAggregator' bean via the <aggregator> element which provides a default aggregator and correlation strategy. The default correlation strategy correlates messages based on the $corelationId header (see Correlation Identifier pattern). What's interesting is that we never provided the value for this header.  It was set earlier by the Recipient List router automatically, when it generated a separate Message for each Bank.

Once the Messages are correlated they are released to the actual Aggregator implementation. Although default Aggregator is provided by SI, its strategy (gather the list of payloads from all Messages and construct a new Message with this List as payload) does not satisfy our requirement. The reason is that our consumer might require a single best quote or all quotes. To communicate the consumer's request, earlier in the process we set the RESPONSE_TYPE header. Now we have to evaluate this header and return either all the quotes (the default aggregation strategy would work) or the best quote (the default aggregation strategy will not work because we have to determine which loan quote is the best).

<int:aggregator id="loanQuoteAggregator" input-channel="quotesAggregationChannel" method="aggregateQuotes">
	<bean class="org.springframework.integration.loanbroker.LoanQuoteAggregator"/>
</int:aggregator>

Obviously selecting the best quote could be based on complex criteria and would influence the complexity of the aggregator, but for now we are making it simple. If consumer wants the best quote we will select a quote with the lowest interest rate. To accomplish that the LoanQuoteAggregator.java will sort all the quotes and return the first one. The LoanQuote.java implements Comparable which compares quotes based on the rate attribute.

Once the response Message is created it is sent to the default-reply-channel of the Messaging Gateway (thus the consumer) which started the process. Our consumer got the Loan Quote!

One important thing to notice is that we have not defined a default-reply-channel attribute on <gateway> element. In fact we have not defined a single channel explicitly. Similar to other Messaging systems, SI will auto-create input and default reply channels as needed, giving you yet another way to further simplify Spring Application Context configuration.

Conclusion

This reference implementation of the 'Loan Broker' use case was accomplished using the Spring Integration framework; a POJO-based, light weight, embeddable messaging framework with a loosely coupled programming model intended to simplify integration of heterogeneous systems without requiring a heavy-weight ESB-like engine or proprietary development and deployment environment. It is build on top of Enterprise Integration Patterns. "Patterns are meant to describe "building blocks" for YOUR solution – they are not meant to be solutions in of themselves. Patterns therefore lend themselves to be best implemented by lightweight, embeddable frameworks that serve to support your solution, not heavy, commercial-off-the shelf products that aim to control it. This is where the big vendors have all gone wrong with SOA…" – Tom McCuch (SpringSource) commenting on InfoQ article by Joshua Long.
Integration concerns exist in all types of applications (server based and not) and should not require change in design, testing and deployment strategy if such applications need to integrate with one another. I (the developer) should not be porting my SWT or console-based application to an ESB-like server or implementing proprietary interfaces simply because I have an integration concern. I would simply like to have a framework that allows me to address these concerns whenever I have them with minimal to no changes to my code or infrastructure. Spring Integration is that framework.

In the next installment we'll demonstrate various remoting adapters and techniques available in Spring Integration by substituting our stubbed services with these adapters and will introduce an asynchronous style of integration that is relevant to the 'Loan Broker' use case.

Resources:

The 'Loan Broker' Reference Implementation is available with the release of Spring Integration 2.0.M3 (see the Downloads section). It is distributed as an independent Eclipse/Maven project. You can also check it out as a project from our Subversion repository.

$> svn co https://src.springframework.org/svn/spring-integration/trunk/spring-integration-samples/loan-broker/ loan-broker
$> cd loan-broker
$> mvn install

Relevant Links:
Spring Integration
Spring Integration in Action
Enterprise Integration Patterns
Getting Started With Spring Integration (Joshua Long)
Agile SOA – Part 1, 2 and 3 (Tom McCuch)

Thanks to Gary Russel (Spring Source, SI comitter) and Dave Turanski (Spring Source) for helping out with this blog!

SpringSource S2G Forum Munich next week

Juergen Hoeller

Here in the Spring team, we are currently preparing for a busy next week: We have a three-day team meeting coming up from March 15th to 17th, immediately followed by the SpringSource S2G Forum Munich on Thursday, March 18th (overview, agenda, registration).

The S2G Forum series is a new conference concept that we are giving a try in Europe: One-day shows in specific regions, with international speakers, and also some regional-language talks thrown into the mix. Munich is the first of those shows this year; further ones are going to follow in Amsterdam on May 11th and in London on May 13th.

The conference is not only going to feature an "Essential Spring" track but also "Enterprise Productions Systems" and – for the first time at a European SpringSource event – a dedicated "Groovy and Grails" track. You'll hear the project leads presenting in all of those tracks, so there is plenty of first-hand information waiting for you. And since we are coming straight from a team meeting, some new plans and insights might make their way into the public for the very first time at that show! :-)

At this point, there are still a few seats available. If Munich is within your reach, make sure to book your seat while you still can. See you around!

P.S.: Since the team meeting is held in Austria, we are able to provide a "sneak preview" at the eJUG in Linz… Dave and Mark will present an evening session on Spring Batch and Spring Integration on Tuesday, March 16th (eJUG Special).

Introducing SpringSource tc Server 2.0

Bruce Snyder

In the very near future, SpringSource tc Server 2.0™ will be released including a new Spring Edition, representing some big changes for the product and a big step ahead for web application development. This also continues SpringSource's commitment to tc Server being a 100% compatible drop-in replacement for Apache Tomcat that provides the best place to build and run your Spring applications and is ideally suited for modern virtual environments.

Based on the Tomcat server that we all know and love, tc Server adds advanced diagnostics, operational management and mission-critical support capabilities. These features dramatically cut costs and complexity while increasing productivity in comparison to traditional Java EE application servers. SpringSource tc Server is now made available in three different editions: the Spring Edition, the Standard Edition and the Developer Edition. These three editions of tc Server ensure easy access for your development team and provide market leading, enterprise class, production capabilities for both Spring and non-Spring based applications.

Spring Edition

The big news around tc Server is the new distribution we're making available in tc Server Spring Edition. The majority of Tomcat applications out there continue to utilize the Spring Framework, and that’s more true for users of tc Server. For Spring applications running in production, the SpringSource tc Server Spring Edition is the best choice. The advantage of the Spring Edition is the inclusion of the instrumented Spring jars that provide reporting and management via Hyperic HQ, including:

  • Deep visibility into the health and performance of Spring applications
  • Performance and SLA management of Spring applications provides the insight required to ensure application operation
  • Automatically monitor application, data access and custom components
  • Monitor performance inside of Spring and execute control operations in response to changing execution conditions
  • Monitor application server status, health and response times

tc-server-Spring-Edition-Resources-annotated

The Spring Edition builds on top of the new features that have been included in the Standard Edition of tc Server.

Standard Edition

SpringSource tc Server Standard Edition takes a major operational step forward through its integration with the SpringSource Hyperic HQ 4.2 Enterprise monitoring and management system which includes a couple of important enhancements:

  • Rich alert definition, workflows, and flexible control actions for dev-ops to proactively manage application issues
  • Group availability and event dashboards make it easy to see the problem areas and possible root causes of issues

The tc Server Standard Edition also provides the ability to manage and monitor your tc Server applications from the same dashboard that you use to manage and monitor your distributed data center. This gives you a comprehensive view into your data center and allows you to correlate views over a wide variety of metric data. Below is a screenshot depicting a group of tc Server instances being monitored:

tc-server-group-monitor-annotated

In addition, the tc Server Standard Edition offers a download of just the tc Server Runtime, without the extra add-ons. This allows us to provide the leanest possible package of the runtime container.

Developer Edition

SpringSource tc Server Developer Edition is provided as a free development download of the tc Server Runtime. It includes:

  • 100% Apache Tomcat compatibility – use it wherever you use Tomcat
  • Built on the latest production ready Apache Tomcat release at its core
  • Including bug fixes contributed to the Tomcat project by SpringSource
  • Application templating allows you to easily create templates from existing applications which then allow you to easily and quickly spin up new, similar applications in a matter of minutes.
  • Spring Insight performance dashboard for extensive awareness when developing web applications. A screenshot of Spring Insight is provided below, but there's no substitute for trying out the real thing with your own webapp. Download the Developer Edition to take it for a spin and see for yourself.

SpringInsight-recent_activity_screen_with_labels
SpringInsight-trace_details_with_labels

SpringSource tc Server Developer Edition is also bundled within the SpringSource Tool Suite (STS), an Eclipse-based development environment. STS provides visual tools for rapidly building modern applications using Spring, Spring Roo and Groovy/Grails. This allows developers to easily deploy and test their applications with tc Server without leaving STS. Instead of trying to squeeze an image of STS into this blog post, I highly suggest you check out Jon's tc Server and Spring Insight screencast as well as Stefan's Roo, STS and tc Server screencast. These two screencasts really give you a good perspective of these products in action and show how powerful they really are, so be sure to check them out.

The free Developer Edition offers tremendous value to the developer.

Future

We are already deep into planning for the next release of tc Server and we welcome your suggestions via the tc Server Forum . So grab the new version of tc Server and take it for a spin. You won't be disappointed.

Latest comments across all posts

Recent Team Posts

Luke Taylor

post Behind the Spring Security Namespace

With the introduction of the security schema in Spring Security 2, it became much easier to get a simple secured application up and running. In older versions, users had to declare and wire-up all the implementation beans individually, resulting in large and complicated Spring application context files which were difficult to understand and maintain. There [...]


Juergen Hoeller

post Spring Framework 3.0.1 released

After two months of incorporating valuable feedback, it is my pleasure to announce the first Spring 3.0 maintenance release – addressing more than 170 reported issues. Get it from our download page.
Since quite a few users asked for a dependencies distribution (as an alternative to grabbing dependencies via Maven or Ivy), we are providing a [...]


Dave Syer

post Practical Use of Spring Batch and Spring Integration

There are some common concerns of users of Spring Batch and Spring Integration, and we get asked a lot about how they fit together. Spring Batch Admin 1.0.0.M2 was released recently, and it makes heavy use of Spring Integration, so it is a good vehicle for looking at some specific use cases, and that [...]

Older Posts

Ajax Simplifications in Spring 3.0

Introduction To Spring Roo Screencast

dm Server 2.0.0 released

dm Server project moves to Eclipse.org