|
|
||||||||||||||
by Binildas Christudas | ||||||||||||||
| ||||||||
As per "the boundary-less organization" invented by Jack Welch in General Electric, organizations should not only be boundary-less, but should also be made permeable. "Integrated information" and "integrated access to integrated information" are two key features any enterprise should aim for in order to improve organizational business processes. A boundary-less organization isn't one without boundaries; it means that there's smooth and efficient flow of information across boundaries. While enterprise portals and web services gives a new face for this emerging paradigm, the skeleton of this "open enterprise" is provided by open IT infrastructure and the flesh is provided by emerging trends in Enterprise Application Integration (EAI) practice. Thus EAI is the use of software and architectural principles to wire together a set of services.
When it comes to integration, it is more easily said than done. This is because there exists no de-facto standard for integration end points. The scenario worsens when we try to do integration at the enterprise level or across enterprises. Each application will have its own way of exposing services. And we cannot revamp all of these applications in a day or two. Instead, the practical approach is to define a top-level integration infrastructure. The Enterprise Service Bus (ESB) is one such middleware infrastructure that provides, at the application platform level, pipes for information to flow and handshake with applications in silos. This article features one such ESB implementation in J2EE, Mule by SymphonySoft, with the help of concrete examples.
The main functionality of ESB is to abstract application endpoint definitions from the physical deployment platform and wire protocols. ESB provides the backbone for information flow across heterogeneous applications: the applications can be within an enterprise or across enterprises. Data flows from information provider applications to the ESB using open interfaces. There can be multiple information-provider data sources. ESB architecture components aggregate services from these multiple data sources. Thus, information from multiple data sources is integrated and is then passed to information consumers. As is the case with information providers, there can be multiple information consumer clients, too.

Figure 1. Hub and spoke architecture
Figure 1 shows a typical hub and spoke architecture. The centralized integration broker links applications in this architecture. This is the traditional way to connect systems and applications, but when the application spans across enterprises, this architecture will inhibit the amount of autonomy required by individual applications. Individual applications need to have lot of freedom in terms of integration and management, and still need to aid information flow in harmony. Without the required amount of freedom and autonomy, we will inhibit innovation and improvisation, which will kill the applications and the organizations using them in the long run. Hence, there should be room for the enterprise application portfolio to grow on an as-needed basis--it is very difficult (if not impossible) to forecast tomorrow's network and protocol requirements. This is where the ESB architecture is going to play its role. The ESB architecture is shown in Figure 2 and functions similar to the traditional hub and spoke architecture, but exhibits the following characteristics:

Figure 2. ESB architecture
Distribution and federation are the key characteristics enabled by the ESB architecture. Distribution is achieved by abstracting services as abstract end points. This means services are separated from their protocol definitions and network requirements. Federation is achieved by the ability to propagate context across application, security, and transaction boundaries. Due to this flexibility, the ESB architecture will scale up as enterprises grow, adding more applications and boundaries to the portfolio.
We will now explore the binding pieces in an ESB architecture with examples. Imagine a typical business scenario in the telecom industry: selling voice over IP (VOIP) services to customers. We will consider a single process of order generation, which is a core item in an order management system (OMS). The process accepts and issues orders. This process itself can be divided into activities like order entry, validation, etc. If we consider a single activity such as the validation alone, many times decomposition of an order into order items is required to separate out service-oriented validation activities. This makes sense in today's service-oriented environment, where services are provided by multiple vendors and a single aggregate service may have to be composed of multiple line-item services offered by multiple vendors. In our example scenario, let us consider three validation services to be done:
The above fine-grained services are offered by different third-party vendors. Hence, as per industry standards, the best way to
access those services is using Simple Object Access
Protocol (SOAP) over HTTP. The
AddressValidationService validates the address entered
by the user and also checks to see whether the VOIP service is
available in the concerned area.
PaymentValidationService is a composite service, and
the successful operation of this service depends upon the responses
from two other third-party vendor services called
CreditAgencyService and
BankAgencyService. CreditAgencyService
checks for the credit worthiness of the customer, and
BankAgencyService checks for the customer's banking
transactions history.
In order to frame the ESB solution architecture for the sample scenario, we will first list the individual components required. Individual ESB components are to be chosen based on the transport requirements to facilitate information flow.
PaymentValidationService
depends upon the combined outcome of two other services
(CreditAgencyService and
BankAgencyService), we need to use a stateful filter
to collect and store individual messages until a complete set of
related messages has been received. An aggregator does this job by
combining the results of individual, but related, messages so that
they can be processed as a whole.Once the individual components have been identified, we will wire them together to form the solution architecture. Figure 3 shows the solution architecture for the above business scenario. This diagram is made using the Enterprise Integration Patterns Visio stencil provided in the download pack for the book Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions.

Figure 3. Validation service solution architecture
Since contacting multiple vendor services is a tedious task and involves knowledge of those third-party vendor service details, a broker encapsulates all of those interactions. Thus, the broker service by itself is a coarse-grained service, and since this service is in our run time environment, we can invoke the service using the local virtual machine (vm://) protocol. As is evident in the below configuration, exposing this validation service itself to other clients across network is a matter of changing some configurations in the run time. So, as per the current architecture, we have the following end point definitions in our Mule configuration file:
<endpoint-identifiers>
<endpoint-identifier name="VoipBrokerRequests"
value="vm://VoipBrokerRequests"/>
<endpoint-identifier name="AddressValidation"
value="axis:http://localhost:18080/mule/
AddressValidationService?method=validateAddress"/>
<endpoint-identifier name="AddressValidationReceiver"
value="axis:http://localhost:18080/mule"/>
<endpoint-identifier name="PaymentValidation"
value="vm://localhost/PaymentValidationService?
method=getCreditVendors"/>
<endpoint-identifier name="CreditAgency"
value="axis:http://localhost:18081/mule/
CreditAgencyService?method=getCreditProfile"/>
<endpoint-identifier name="CreditAgencyReceiver"
value="axis:http://localhost:18081/mule"/>
<endpoint-identifier name="BankAgency"
value="axis:http://localhost:18082/mule/
BankAgencyService?method=getAuthorisedStatus"/>
<endpoint-identifier name="BankAgencyReceiver"
value="axis:http://localhost:18082/mule"/>
<endpoint-identifier name="PaymentValidationResponse"
value="vm://PaymentValidationResponse"/>
</endpoint-identifiers>
As is evident from the Mule end point configuration, externalizing a service access protocol different from the service definition is one of the advantages of the ESB architecture. This is because how to expose a service (for example, deciding which protocol to use) or how to access a service is a transport concern, not the concern of the service component itself. To put it in simple terms, connectivity can be attained using Java Message Service (JMS) for Message-Oriented Middleware (MOM), the J2EE Connector Architecture (JCA) for connecting to resource adaptors, and remoting for connecting to .NET C#, VB components, etc. Needless to say, SOAP and web services are the most interoperable way of connecting to services. Thus, components and services are abstract end points. These end points are tied together statically or dynamically (on an as-needed basis) to form aggregate or composite services performing business functionality. Thus, the integration architect usually weaves orchestration, message translation, and routing logic to connect the end points to the ESB, as shown in the solution architecture in Figure 3.
Message translation is done using Java serialization, SOAP parsers, encryption/decryption packages etc. Message translation is also beyond the component's concern. Instead, the ESB sockets will perform message translations depending upon the service binding option selected. For example, messages need to be translated to XML format for SOAP binding, and to technology-specific binary formats for a CORBA binding.
A message itinerary contains the main routing logic and depicts how the inputs and outputs of services are sequenced and orchestrated in a highly flexible manner for composing services. The message itinerary for our validation service is shown below:
<mule-descriptor name="VoipBroker"
implementation="com.example.voipservice.
service.SyncVoipBroker">
<inbound-router>
<endpoint address="VoipBrokerRequests"/>
</inbound-router>
<outbound-router>
<router className="org.mule.routing.outbound.
FilteringOutboundRouter">
<endpoint address="AddressValidation"/>
<filter expectedType="com.example.voipservice.
to.AddressTO" className="org.mule.routing.
filters.PayloadTypeFilter"/>
</router>
<router className="org.mule.routing.outbound.
StaticRecipientList">
<filter expression="recipients!=null"
className="org.mule.routing.filters.
MessagePropertyFilter"/>
<properties>
<property name="replyTo"
value="PaymentValidationResponse"/>
</properties>
</router>
<router className="org.mule.routing.outbound.
FilteringOutboundRouter">
<endpoint address="PaymentValidation"/>
<filter expectedType="java.lang.String"
className="org.mule.routing.filters.PayloadTypeFilter"/>
</router>
</outbound-router>
<response-router>
<endpoint address="PaymentValidationResponse"/>
<router className="com.example.voipservice.routers.
PaymentValidationResponseAggregator"/>
</response-router>
</mule-descriptor>
Message itineraries can contain the abstract end points towards which messages are to be routed and rules to be evaluated along the way of message flow. The rules can be message content validation or routing logic. Pluggable filters provides for message content validation.
Having seen the various architectural pieces and the different configurations required, we will now move on to implementing the sample architecture in the Mule ESB run time. For this, we encapsulate various components in a set of Java files, as shown in Figure 4.

Figure 4. Validation service design
The client or consumer application contacts a broker for the
validation service. The broker first validates the address
information entered by user calling the
AddressValidationService. Depending upon the outcome
of address validation, the broker has to do a payment validation.
The payment validation is done by
PaymentValidationService. For the payment validation
service to decide on the success or failure of the validation, it
has to depend on the outcome of two composed services,
BankAgencyService and
CreditAgencyService. StaticRecipientList
can be used to send the same event to multiple endpoints over the
same provider. The outcomes of BankAgencyService and
CreditAgencyService are then combined by the
PaymentValidationResponseAggregator.
public class SyncVoipBroker{
public UMOMessage validate(ServiceParamTO
serviceParamTO) throws Exception {
UMOMessage msg = null;
List endPoints = null;
UMOEventContext umoEventContext =
RequestContext.getEventContext();
UMOMessage umoMessage = umoEventContext.sendEvent
(serviceParamTO.getCustomer().getAddress());
Integer isValidAddress = (Integer)
umoMessage.getPayload();
if(isValidAddress.intValue() ==
AddressValidation.SUCCESS){
umoMessage = umoEventContext.sendEvent(
serviceParamTO.getCreditCard().getCardType());
endPoints = (List) umoMessage.getPayload();
Map props = new HashMap();
props.put("recipients", endPoints);
msg = new MuleMessage(new CreditProfileTO
(serviceParamTO.getCustomer()), props);
umoEventContext.dispatchEvent(msg);
umoEventContext.setStopFurtherProcessing(true);
}
return msg;
}
}
Thus, service definitions or service protocols are not specified while composing aggregate services but they are externalized to configuration. This gives us the flexibility to swap services with similar services, provided the service interface remains same. Also, there is no location-specific dependency while composing; instead, all distribution details are specified in configuration.
The sample application is implemented following the samples in the Mule distribution. Detailed below are the step-by-step instructions to run the sample application.
MULE_HOME.

Figure 5. Mule distribution unzipped with sample
application
MULE_HOME\samples.MULE_HOME and JAVA_HOME
environment variables pointing to the path where we extracted the Mule
distribution and installed JDK, respectively, in the following files:
cd
MULE_HOME\samples\voipservice\bin.voipservice
application.voipservice
application. A successful run will give the following, along with
other logs in the console:INFO: Sending Request...
INFO: Inside AddressValidationService.validateAddress()
INFO: Inside PaymentValidationService.getCreditVendors()
INFO: Inside BankAgencyService.getAuthorisedStatus()
INFO: --- *** --- shouldAggregate = false --- *** ---
INFO: Inside CreditAgencyService.getCreditProfile()
INFO: --- *** --- shouldAggregate = true --- *** ---
INFO: SyncVoipConsumer.requestSend. valid = true
INFO: Request Completed.
ESB has evolved out of necessity, and hence there are no issues of adoption and acceptance. ESB has been successfully implemented in many verticals, like finance, retail, and manufacturing. Equally important is the evolution of related technology standards and platform support. Java Business Integration (JBI) is one amongst the most promising movements in the direction. JBI, also known as JSR-208, extends J2EE with business integration SPIs. These SPIs enable the creation of a Java business integration environment for specifications such as Web Service Choreography Interface (WSCI), Business Process Execution Language for Web Services (BPEL4WS), and the W3C Choreography Working Group. ServiceMix recently brought out their open source Enterprise Service Bus (ESB) and SOA toolkit, built from the ground up on the semantics and APIs of the JBI specification. The BEA AquaLogic Service Bus delivers intelligent message brokering, dynamic routing, and transformation integrated with service lifecycle management capabilities, including service registration, monitoring, and threshold-defined service level agreement (SLA) enforcement. BizTalk is a Microsoft product to integrate systems, employees, and trading partners through manageable business processes.
Similar to SOA, ESB is neither a technology nor a product in itself, but a platform, a set of tools, and a design philosophy. Using ESB, we can deploy SOA components in an autonomous but federated manner. This allows easy growth for applications, application boundaries, and enterprises. Recent industry trends incorporate the platform and tool support for ESB into product stacks. This means the way we architect and design components and how we weave them together to realize services are going to change--change in such a way that we have to connect together abstract end points and associate them with context information to form loosely coupled solutions.
Binildas Christudas currently works as a Principal Architect for Infosys Technologies, where he heads the J2EE Architects group servicing Communications Service Provider clients.
View all java.net Articles.
|
|