John Gilbert

Subscribe to John Gilbert: eMailAlertsEmail Alerts
Get John Gilbert: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn


Related Topics: SOA & WOA Magazine

SOA & WOA: Article

AOP-Enabled ESB

Updating The Enterprise Nervous System

Service Oriented Architecture (SOA) is not so much a new technology as a new state of mind. Technology for implementing business logic in the middle tier and exposing it as a service has been around for years. Yes, the technology is more standardized now and more widely accepted. What's really new is the growing practice of approaching SOA with an enterprise-wide mindset in which an organization takes a holistic approach to identifying the services they provide.

The rise of the Enterprise Service Bus (ESB) is linked to this new enterprise-wide view. ESB and SOA are complementary. One of the tenets of SOA is loosely coupling services. Message-Oriented Middleware (MOM) is used to connect decoupled systems. An ESB is created by using standards-based MOM providers consistently across an enterprise to glue decoupled services together. When used together this ESB-powered SOA enables the real-time enterprise.

The exact nature of an ESB is widely debated. Some people see it as a product, others as just an architectural design pattern. But most agree that an ESB can be thought of as the nervous system of the enterprise. It's the enterprise state machine that gets its stimulus in the form of business events as actors invoke services or exceptional conditions arise. These events flow across the bus and are evaluated based on business rules. The rules glue the decoupled services together to create a business process. As the rules invoke additional services more events are triggered and the whole cycle begins again.

The simplest way to explain the execution of a state machine is seen in Figure 1. An actor invokes an action that then fires an event. The event is evaluated against the state of the system based on the conditions or rules of the system. Conditions that evaluate to true then invoke another action and so on.

Regardless of whether an ESB is a product or not it's imperative that services are designed so they can plug easily into the ESB ensuring that all services publish an event to the ESB when they're invoked. This kind of crosscutting concern is best done using Aspect Oriented Programming (AOP), which dynamically inserts new code into existing code. As a result legacy code can be enhanced and new code can be developed more cleanly.

This AOP-enabled ESB can be explained best by an example. There are several AOP frameworks available. Which one you choose depends on how well it's already integrated with the tools used in your environment. For this article I used the AOP features included in the new EJB 3.0 specification and the JBoss preview implementation of the spec. I implemented several services using EJB 3.0 stateless session beans. The services are decorated with an AOP Interceptor. This interceptor gathers the method's invocation data and publishes it as an event to the ESB. The service bus is implemented using a JMS Topic and a Message Driven Bean (MDB) that subscribes to the topic and passes the event to a JSR-94 compliant Rules Engine. Example rules are provided that further invoke additional EJB services. The complete code example can be downloaded from this articles' source code.

Example

For the example, let's say BT is a supplier of Bluetooth gadgets. It has modeled its business process (Figure 2) and its business entities (Figure 3) and want to implement them with an ESB powered SOA.

In their business process customers submit orders via a portal. Once received, an order is provisioned, the customer is notified, and the shipping department is told to ship the order. Shipping is a manual task. This means the process won't move forward until an employee from the shipping department marks the task complete. Then the customer is notified and the order and the product quantities are updated.

Four business entities are needed to enable the business process. The company maintains a list of products. Customers create their accounts through the portal and then submit orders with line items.

The data model sufficiently dictates what entity beans will need to be created and the process model provides the rules for the rules engine. However, the actual services need to be defined (Figure 4). Each step in the business process is modeled by a service operation. The operations are then grouped into services based on functional or data cohesion. For example, all the operations that act on Order entities are put in the OrderService.

Several additional components are needed to provide a framework (Figure 5). An Event object is needed to carry information on the bus. A Task entity is needed to store data about the manual steps in the process and a TaskService is defined so users can manipulate the tasks. Finally, a message-driven bean is needed to invoke the rules engine.

Service Implementation

The services provide the actions in the enterprise state machine. Each service is implemented as a Stateless Session Bean by implementing a local and/or remote interface and using the @Stateless annotation (see Listing 1). JSR-181 (Web Services Metadata for Java) will soon let stateless session beans be annotated with a @WebService attribute so an application server can generate WSDL and expose them via SOAP. The @Interceptor annotation defines the point-cut for inserting the EventInterceptor advice around each method of the session bean.

Each of the classes in the business entity class diagram is implemented as a plain old Java object (POJO) and decorated with the @Entity annotation so it can persist. The entity beans will also be used as arguments of the session bean methods. The new POJO nature of the EJB 3.0 entity beans lets them be used outside the container. This simplifies the code necessary to create services because an additional Value object class hierarchy isn't needed to transport the data from the entity beans.

The new EJB 3.0 Entity Manager class is used to persist the entity beans. The @Inject annotation instructs the EJB container to assign the appropriate manager. The manager's persist() method is used to insert the object into the database. The merge() method is used to update the database.

AOP Interceptor

Interceptors facilitate firing events in the enterprise state machine. AOP interceptors are a kind of advice that's used to insert code around the invocation of a method dynamically and ensure that every service invocation publishes an event to the ESB. The EventInterceptor class takes all the invocation data from the method and puts it in an Event POJO (see Listing 2). An interceptor class must define an invoke() method that's annotated with the @AroundInvoke attribute. Each session bean is annotated with the @Interceptor attribute. (See Listing 1). When each method on the annotated session bean is executed the interceptor is invoked first and passed the invocation context. The interceptor extracts the context information and puts it in the Event POJO. It then tells the method to proceed with its execution. Once the method completes, the output is also put in the event. If an exception is caught then it's put in the event instead and the event name is appended with a Fault suffix to facilitate the error-handling rules. The finally block handles publishing the event to the topic.

ESB Implementation

The rules provide the conditions in the enterprise state machine. To implement the ESB and orchestrate the business process a JSR-94-compliant rules engine is used. I used Drools because of its native support for Java syntax. An MDB is used for the execution environment. (See Listing 3). The @MessageDriven and @ActivationConfigProperty annotations are used to replace the deployment descriptor. The MDB will be activated by a topic destination called topic/net.jcg.EventTopic and its subscription is durable so no events are dropped. The @Inject annotation is used to access the rules engine from the JNDI tree. The onMessage() method extracts the Event object from the message, passes it to the onEvent() method, and gracefully handles exceptions. The onEvent() method uses the RuleRuntime object to create a StatelessRuleSession. A stateless session is used so the session's memory starts fresh for each event. The session is created with the name of the rule set that will be evaluated, "OrderProcess." Once the session is created the rules are executed by passing the event object as input to the executeRules() method.

More Stories By John Gilbert

John Gilbert is a consultant with 12 years of experience as an architect of service oriented systems. He holds a master's degree in software engineering from George Mason University and is an avid proponent of open source software.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.