Implementing an Enterprise Service Bus in Java

ntegrating old and new components and services using a service-oriented architecture (SOA) requires an infrastructure that can connect any component or service, regardless of location, messaging protocol, and message format. To orchestrate existing services and components via this infrastructure, you must be able to customize it extensively. An SOA infrastructure that fulfills these requirements is called an “enterprise service bus (ESB).”

This article discusses the mechanisms used by an ESB to facilitate cross-protocol messaging, message transformation, message security, service invocation, and other necessary requirements of a service-oriented messaging infrastructure.

The Enterprise Service Bus
An enterprise service bus (ESB) is a centralized, scalable, fault-tolerant, service-messaging framework that:

  • Provides a transparent means for communicating with heterogeneous services over a diverse set of message protocols.
  • Provides a shared messaging layer by which enterprise applications, services, and components can connect and communicate.
  • Can transmit messages synchronously or asynchronously to service endpoints and intelligently transform and secure the message content to meet the requirements of each service endpoint.
  • Should provide sophisticated error recovery, allowing for failed message delivery, scalability problems, duplicate messages, network failure, etc.

Minimum Requirements of ESB Message Delivery
The minimum capability requirements of an ESB as a message delivery system can be remembered using the acronym “TRANS,” which defines an ESB as a software entity that:

  • Transforms messages from one format to another to accommodate the requirements of registered service providers
  • Routes messages to registered services while providing defined Quality-of-Service (QoS) and Service-Level features
  • Augments message content with information such as additional metadata about the message requester. Augments the message protocol to meet service provider requirements.
  • Notifies registered message listeners of specific message requests
  • Secures delivery of messages by enforcing authentication, authorization, non-repudiation, confidentiality, etc.

Transforming ESB Messages
An ESB must be able to transform data into a common data format to enable effective communication between disparate applications, components, and services. Data-format transformation can be simple or very complex; therefore the transformation facilities offered by an ESB should be both pluggable and configurable. An example of ESB transformation is applying an XSLT document defined by the receiving service’s schema against the requester’s XML message content.

Routing ESB Messages
An ESB should be able to determine the destination of a given message based on a number of factors?including the content of the message. This provides the flexibility to route messages to heterogeneous services without coupling the routing logic with the message structure.

Some of the mechanisms used for ESB message routing are:

  • XML-based content routing.
  • Proprietary object-based routing, such as that used by JMS.
  • External routing, where message routing is configured externally, and is therefore disconnected from the message content.

Notifying Message Listeners
An ESB should provide message-based listening capabilities to enable secured management of the message traffic and content.

Securing Message Delivery
An ESB should provide security for each message-request, including authentication, authorization, non-repudiation, confidentiality, and enforcement of security standards such as Kerberos and WS-Security.

The Decentralized Nature of an ESB
An ESB should be designed modularly, around a decentralized model to be able to scale effectively to meet any messaging demands placed on it. The decentralized nature of an ESB is realized in multiple interconnected runtime engines. Each runtime engine is responsible for handling the minimum capabilities defined by TRANS.

Interconnected runtime engines allow applications to interact with the ESB as if it were a single entity, even though it may be distributed across many networks and machines

Each runtime engine consists of:

  • An administrator.
  • A destination-based list of mediators.
  • A namespace directory.
 
Figure 1. ESB Components: The figure shows a high-level view of the relationships and interactions between the components of an ESB.

ESB Administration
Each runtime engine retains an administrator that handles management functionality such as service provisioning, service registration, service discovery, message logging, metering, and monitoring.

Mediation of ESB Messages
Each runtime engine also retains a list of mediators; each mediator is always associated on a one-to-one basis with a destination. A mediator is responsible for acting upon (transforming, augmenting, and securing) a message before it reaches its destination. After transforming, augmenting, and securing each message, the mediator routes the message to the destination.

Figure 1 illustrates a high-level view of the relationships and interactions between components of an ESB.

Introducing Mule
Mule is an ESB messaging platform based on a staged event-driven architecture (SEDA). (See http://www.eecs.harvard.edu/~mdw/proj/seda/ for a complete discussion of SEDA.) Mule can send and receive messages using three processing models: asynchronous, synchronous, and request/response.

Mule provides a container that manages message-capable services known as Universal Message Objects (UMOs). UMOs can be plain old Java objects (POJOs).

UMOs are made available to other UMOs and applications via message endpoints that allow messages to be routed across a wide array of protocols and technologies such as JMS, SMTP, JDBC, TCP, HTTP, file, intra-VM, etc.

Here are the principal ESB Mule components:

  • Mule Manager?The Mule Manager is the primary component for each instance of a Mule server and is used to manage all Mule objects (connectors, endpoints, transformers, etc.) for each Mule server instance.
  • Mule Model?The Mule Model is the container in which user-supplied components are managed and executed. It controls message flow to and from user-supplied components and manages threading, lifecycle, and pooling of the components.
  • UMOs?Universal Message Objects (UMOs) are user-supplied POJOs that can receive and send Mule messages. Mule handles all routing and transformation of events to and from UMOs based on the configuration of the components and/or Java reflection.
  • Endpoints?Endpoints define URI-based communication channels between two or more components, services, or applications. An endpoint can be configured with message filters, security interceptors, and transaction information. Some examples of endpoints are:
    • pop3://user:[email protected]
    • jms://message.queue
    • http://localhost/mule
    • file:///tmp/messages/in
    •  
      Figure 2. Mule Components and Objects: The diagram illustrates the relationships and interactions between Mule components and objects.
    • vm://mypackage.myobject
    • axis:http://localhost/services/mypackage.myobject
  • Transformers?Transformers transform message payloads from one format to another.

The diagram in Figure 2 illustrates the relationships and interactions of the Mule components and objects.

Configuring a Mule Manager Instance
You must configure each Mule Manager instance with specific properties before using it. To configure a Mule Manager instance from a Java application, you can use one of Mule’s configuration builders. For example, to configure a Mule Manager instance from two XML files, you can use the MuleXmlConfigurationBuilder class as follows:

   MuleXmlConfigurationBuilder builder =      new MuleXmlConfigurationBuilder();   UMOManager manager =      builder.configure("mule-main-config.xml,       mule-components.xml);

To configure a Mule Manager instance in a simple fashion with a global endpoint for intra-VM messages, you can use the QuickConfigurationBuilder class in a manner similar to the following:

   QuickConfigurationBuilder builder = new       QuickConfigurationBuilder();   builder.createStartedManager(true,       "vm://tmp/messages");

Sending a Message with Mule
To interact with the Mule server from an application you use the Mule client as shown in the following examples:

   // create a Mule client   MuleClient client = new MuleClient();      // send a JMS message synchronously   Map payloadProps = null;   UMOMessage message client.send("jms://message.queue",      "The data",payloadProps);      // receive a pop3 message   long timeout = 3000;   UMOMessage message = client.receive("pop3://mymail.com", timeout);      // asynchronously dispatch an inter-VM message   client.dispatch("vm://mypackage.myobject", "The data", payloadProps);

Primary Interfaces for a Simple HTTP ESB Using Mule
For the purposes of this article, I’ve used Mule as the messaging framework, but constructed the principal interfaces and classes that define the ESB from scratch. The first order of business is to define the interfaces for the ESB, as described in the following sections.

ESB
The ESB interface defines the contract for each ESB. The ESB interface exposes two simple methods: one (getAdministrator) for retrieving the global administration object and one (transmitMessage) for placing a message on the bus.

 
Figure 3. ESB Interfaces: The figure shows a static model class diagram of the relationships between the ESB interfaces.
   public interface ESB   {     public Administrator getAdministrator();        public void transmitMessage(ServiceMessage message)       throws MessageTransmissionException;   }

Figure 3 shows a static model class diagram of the relationships between the ESB interfaces.

RuntimeEngine
The RuntimeEngine interface defines the contract for each runtime engine used by the ESB. Each ESB instance contains a RuntimeEngine that interacts between service requesters and service providers.

Each instance of the RuntimeEngine class is a processing unit that embodies the functionality of the ESB and directs service interactions between service requesters and service providers.

   public interface RuntimeEngine   {     public Administrator getAdministrator();        public NamespaceDirectory getNamespaceDirectory();        public void transmitMessage(ServiceMessage message)       throws MessageTransmissionException;   }

The Mediator Interface
The Mediator interface defines the contract for a generic mediator. A mediator is responsible for acting upon (transforming, augmenting, and securing) a message before the message reaches its destination.

   public interface Mediator   {      public void addMessageListener(         ServiceMessageListener listener);         public void removeMessageListener(         ServiceMessageListener listener);         /**       * Associates a given Destination with        * this Mediator       *       * @param destination   the Destination       */      public void setDestination(         Destination destination);         /**       * Retrieves the Destination associated with        * this Mediator       *       * @return Destination the Destination        * associated with this Mediator       */      public Destination getDestination();         /**       * Transforms a given message. The transformed        * message is returned.       *       * @param message   the inbound message       * @return ServiceMessage the        * transformed message       */      public ServiceMessage transform(         ServiceMessage message)         throws TransformMessageException;         /**       * routes a message based on content.       *       * @param message   the inbound message       */      public void route(ServiceMessage message)         throws RouteMessageException;         /**       * Augments a given message. The augmented        * message is returned.       *       * @param message   the inbound message       * @return ServiceMessage the        * augmented message       */      public ServiceMessage augment(         ServiceMessage message)         throws AugmentMessageException;         /**       * Secures a given message. The secured message        * is returned.       *       * @param message   the inbound message       * @return ServiceMessage the        * secured message       */      public ServiceMessage secure(         ServiceMessage message)         throws SecureMessageException;      }

NamespaceDirectory
The NamespaceDirectory interface defines the contract for an ESB namespace directory, letting you add and discover message destinations.

   public interface NamespaceDirectory   {      public void addDestination(String namespace,          Destination destination);         public Destination getDestination(         String namespace);   }

SecurityProvider
The SecurityProvider interface handles security for each message-request including authentication, authorization, non-repudiation, confidentiality, and enforcement of security standards such as Kerberos and WS-Security.

   public interface SecurityProvider   {      public void authenticateRequester(         ServiceRequester requester)         throws RequestSecurityException;         public void authorizeRequest(ServiceRequester          requester, ServiceMessage message,         ServiceProvider provider)         throws RequestSecurityException;         public void logRequest(ServiceRequester requester,         ServiceMessage message,         ServiceProvider provider)         throws RequestSecurityException;         public ServiceMessage encryptRequest(         ServiceRequester requester,         ServiceMessage message,         Destination destination)         throws RequestSecurityException;         public ServiceMessage decryptRequest(         ServiceRequester requester,         ServiceMessage message,         Destination destination)         throws RequestSecurityException;   }

Implementation of the ESB
Using the interfaces designed and discussed above, you can construct an implementation for a simple ESB. The rest of this article describes the classes required for a simple HTTP-based ESB. Building it involves using a servlet as the ESB implementation class.

 
Figure 4. Control Flow: The diagram shows how control flows from an HTTP-based client to the ESB servlet and back.

Figure 4 shows how control flows from an HTTP-based client to the ESB servlet and back.

As illustrated in Figure 4:

  1. A browser transmits an HTTP request to the ESB servlet.
  2. The ESB servlet dispatches the message contained in the request to the runtime engine.
  3. The runtime engine hands the message off to the mediator.
  4. The mediator performs any necessary augmentation, transformation, and security on the message.
  5. The mediator routes the message to the destination belonging to a ServiceProvider (in this case, an instance of the MuleEchoMessageService class).

If all goes well, the ESB propagates a success value back up the chain and a passes a success response back to the client.

Here are the primary classes for the HTTP-based ESB, along with links to listings showing the source code. You can download the source to the sample project to experiment with it on your machine.

  • HTTPESB?Encapsulates the data and behavior for an HTTP request/response service bus. HTTPESB contains a RuntimeEngine instance that interacts between service requesters and service providers (see Listing 1).
  • SimpleRuntimeEngine?Encapsulates the data and behavior of the ESB and uses mediators to transform, augment, and secure messages and to route service interactions between service requesters and service providers (see Listing 2).
  • MuleMessageManagerFactory?Creates/returns an instance of MuleMessageManager (see Listing 3).
  • MuleMediator?Encapsulates the data and behavior for a Mule-based mediator (see Listing 4).
  • MuleMessageClient?Encapsulates the data and behavior for a Mule-based message transmitter and service registry (see Listing 5).
  • MuleEchoMessageService?Encapsulates the data and behavior for a Mule UMO that simply holds and echoes a message (see Listing 6).

Installing and Deploying the ESB Web Application
To deploy an ESB Web application you must download and install a J2SE Development Kit (JDK), version 1.4 or greater, from Sun, download the latest version of Mule, download and install a servlet container, and create the necessary files and directories for the Web application. The following sections explain these steps.

Downloading and Installing a JDK
The following steps will walk you through downloading and installing a JDK:

  1. Download a version 1.4 or greater of the JDK from http://java.sun.com/j2se/.
  2. Unpack the downloaded archives to the directories of your choosing.

Downloading and Installing Mule
Follow these steps will to download and install Mule:

  1. Download the latest version of the full Mule distribution and the Mini-Mule distribution from http://mule.codehaus.org/Download.
  2. Unpack the downloaded archives and/or install the JDK to the directories of your choosing.

Downloading and Installing the Tomcat Servlet Container
To download and install a servlet container:

  1. Download a version 5.x or greater of the Tomcat servlet container from http://jakarta.apache.org/tomcat/index.html.
  2. Unpack the downloaded archives and/or install Tomcat to the directories of your choosing.

Creating the HTTPESB Web Application
The HTTPESB demo Web application is composed of one HTML file, the HTTPESB servlet, and the ESB implementation classes.

Create the Web Application Directory Structure

  1. Create a directory in your servlet container’s webapps directory named httpesb.
  2. Create a child directory of httpesb named WEB-INF.
  3. Create a child directory of WEB-INF named classes.
  4. Create a child directory of WEB-INF named lib.

Populate the Web Application Directory Structure

  1. Copy the Mule jar file and DTD file from the Mini-Mule dist directory to the WEB-INF/lib directory.
  2. Copy all the jar files from the Mini-Mule lib directory to the WEB-INF/lib directory.
  3. Compile all the Java files for the ESB to the WEB-INF/classes directory.
  4. Create a text file named web.xml in the “WEB-INF” directory and populate the file as shown in Listing 7.
  5. Create a text file named index.html in the httpesb directory and populate the file as shown below.
         HTTP ESB           
Message:

Testing the ESB


Figure 5. Testing the ESB: After installing and configuring Mule and the sample application, when you run it, you’ll see a page that looks like this.
 
Figure 6. A Successful Message: When you send a message successfully, you’ll see a page similar to the one shown here.

After installing and configuring the application, to test it from your browser, type the following URL into the address field:

   http://localhost:8080/httpesb

You’ll see a page similar to Figure 5.

Type “Hello world!” into the message box and hit the “Send Message” button. You should now see a page similar to Figure 6.

If you now look at the console window for your application server, you should see more detailed messages?something similar to Figure 7.

 
Figure 7. Detailed Output: The sample application displays detailed messages in the console window.

To integrate old and new components and services using a service-oriented architecture requires an infrastructure that can connect any component or service, regardless of location, messaging protocol, and message format. An enterprise service bus fulfills these requirements with a centralized, scalable, fault-tolerant, service-messaging framework. An ESB provides a transparent means for communicating with heterogeneous services over a diverse set of message protocols.

Mule is an ESB messaging platform based on a staged event-driven architecture (SEDA). Mule can send and receive messages using asynchronous, synchronous, and request/response processing models. You can use Mule alone or as a simple messaging framework to build a robust, advanced enterprise service bus.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

The Latest

Top 5 B2B SaaS Marketing Agencies for 2023

In recent years, the software-as-a-service (SaaS) sector has experienced exponential growth as more and more companies choose cloud-based solutions. Any SaaS company hoping to stay ahead of the curve in this quickly changing industry needs to invest in effective marketing. So selecting the best marketing agency can mean the difference

technology leadership

Why the World Needs More Technology Leadership

As a fact, technology has touched every single aspect of our lives. And there are some technology giants in today’s world which have been frequently opined to have a strong influence on recent overall technological influence. Moreover, those tech giants have popular technology leaders leading the companies toward achieving greatness.

iOS app development

The Future of iOS App Development: Trends to Watch

When it launched in 2008, the Apple App Store only had 500 apps available. By the first quarter of 2022, the store had about 2.18 million iOS-exclusive apps. Average monthly app releases for the platform reached 34,000 in the first half of 2022, indicating rapid growth in iOS app development.