Monday, March 17, 2008

Using an EJB3 Interceptor in Seam

For one of the demos for the NEJUG presentation we integrated the JPetStore (Spring based) and the DVDStore (Seam based) with JBossESB. The idea is that when orders are placed in either store the orders are processed in some ESB based Order Processing Service, using jBPM for the Orchestration. Here I want to show what you need to do to intercept a the order when the user hits the 'confirm' button in the Seam based DVD Store. For this we use an EJB3 interceptor. The beauty of this solution is that no code changes are needed in the DVD Store itself.

1. Modify the ejb-jar.xml
First we need to add some configuration to the ejb-jar.xml, as shown in Figure 1.


Figure 1. Add the interceptor to the ejb-jar.xml


So first we define the interceptor class by referencing
com.jboss.dvd.seam.CheckoutInterceptor
, next we need to specify when this class should be called, which is done by adding the second piece of xml which specifies the bean name for which the interceptor should fire. Here we want it to fire when the
CheckoutAction
is called.

2. Add the interceptor class

The interceptor class itself looks like

package com.jboss.dvd.seam;

import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

public class CheckoutInterceptor {

@AroundInvoke
public Object sendOrderToESB(InvocationContext ctx) throws Exception {

System.out.println("*** Entering CheckoutInterceptor");
Object target = ctx.getTarget();
//Just making sure
if (target instanceof CheckoutAction) {
if (ctx.getMethod().getName().equals("submitOrder")) {
System.out
.println("We will send the following completedOrder object to ESB");
Order completedOrder = ((CheckoutAction) target).currentOrder;
Customer customer = ((CheckoutAction) target).customer;
completedOrder.setCustomer(customer);
System.out.println("Completed Order= " + completedOrder);
}
}
try {
return ctx.proceed();
} finally {
System.out.println("*** Exiting CheckoutInterceptor");
}
}
}

Figure 2. The CheckoutInterceptor Code

And that is all there is to it. In the interceptor we check which method is called, and if it is the
submitOrder
method we print out the order. In the demo we added code to serialize the order to XML, and then dropped in onto a gateway Queue, on its way to the ESB.

4 comments:

Anonymous said...

Where can I get a copy of this demo application, so that I can learn ejb3?

Kurt Stam said...

It's one of the seam examples. Just download one of their release bundles at http://www.seamframework.org/Download.

Marcos Jara said...

Hello

I have an sales EJB project which controls the inventory, in and out of stock.

I want to add extra functionality to the EJB, such as payment and billing.

For this I want to use Interceptor in Session Bean class. I want to implement the new functionality as a component, decoupled from the current implementation.

But I have not access to the current session bean or Xml (ejb-jar), so I can not put the @ Interceptor in the class or method! how I can solve my problem?

Can I add @ Interceptor from another location, class or session? There is another way of doing?

Thanks for your help.

Kurt Stam said...

Sorry Marcos,

I don't know, I think you need access to the class or the XML descriptor. I was going to suggest adding an AOP hack, but I'm guessing that if you don't have access to the class you won't be able to do that either.

--Kurt