Friday, September 24, 2010

Random thoughts about Oracle OpenWorld, Oracle Develop and JavaOne 2010

Today was the last day of Oracle OpenWorld. It was the fifth time for me, so the amazing crowd that floods San Francisco doesn’t surprise me anymore. There was a big difference this time, though: it was the first time that JavaOne was part of the conference. I had visited JavaOne twice before. Both times the conference was in Moscone. For obvious reasons, this was not possible this time. Moscone is big, but not that big….

They moved JavaOne over to the Hilton, Park 55 hotel, and Nikko hotel where Oracle Develop also took place. Being in these hotel feels smaller and less ‘buzzing with energy’ compared to Moscone. It didn’t bother me, because I am used to it: they did this before with Oracle Develop. But for the JavaOne visitors, it was a step back. I attended a session about SOAP versus REST webservices. The session was very well attended, it was a repeat from the day before. The room was small and one of the presenters had to leave early because he had a plane to catch. I think that if this session would have been located at Moscone, it would probably have fitted all the people that wanted to attend on Wednesday. This would have improved the quality: the story became a little one-sided because the SOAP guy left..

The problem of finding sessions that you want to attend was even bigger this time than last year: adding JavaOne to the mix increased the amount of sessions you have to chose from to an incredible number. The schedulebuilder doesn’t help. In fact it seems to deteriorate evey year: I missed some sessions I would have liked to attend: for example the session by Mark Simpson on Governance. Some sessions ‘dispappeared’ from the schedule: for example the ADF session by Sten Vesterli.

Now let’s take a look at the bright side:


I loved meeting all the Oracle Ace Directors, Oracle Productmanagers and the people from Oracle Technology Network again. Meeting here every year really makes the community sustainable. You can do a lot of stuff online, but it really helps if you meet people in person once or twice a year. I even bumped into some Dutch people I hadn’t seen in a while. It feels like one big reunion all week long.

We had our first ‘official’ session of the new SOA BPM enterprise methodology group at the unconference sessions. We talked about best practices for using existing database logic in a SOA environment, and tips for communication with .NET services in your enterprise.

I attended interesting sessions (in random order, since this blog contains random thoughts):

  • Dirk Staehler showed the methodology Opitz uses with Oracle BPA Suite for enterprise architecture, SOA and BPM.
  • A nice overview of use cases for SOAP and use cases for REST webservices
  • A demo showing the use of UCM, more specifically the imaging solution with the prebuilt integration with Oracle BPM for invoice processing
  • The BPM CAB where I met with the people responsible for the integration between Oracle BPA Suite11g and Oracle SOA suite11g and Oracle BPM Suite11g.
  • The partner council that was organized by Juergen Kress. Dave Shaffer was doing a great job getting the feedback from the partners and explaining the roadmap and other stuff that I can’t talk about ;-)

Of course, it was not all work: I had great breakfast, lunches, dinners and coffees with friends. I visited the Oakland museum to check out the awesome Pixar exposition and of course went to the appreciation event at Treasure Island!

All in all, the conference was a huge success for me and I am already looking forward to next year!

Monday, September 20, 2010

Fault handling in Oracle SOA Suite 11g - Part IV

See part I, part II, and part III of this blog for more information on fault handling. The last component of our fault handling framework is the SCA composite that acts as generic fault handler. An example of such a composite would roughly do the following:

  • Dequeue an event from the fault queue causing an instance of this composite to be created;
  • Retrieve the fault information using the event payload and Oracle SOA Suite API’s;
  • Initiate a Human Task to notify administrators a fault has occurred in some composite instance.

You could either choose to pass the fault information to the Human Task itself or leave this to the application displaying the Human Task and the relevant information to deal with this task. In this case the fault information.

Since most of the above is straight-forward we will focus on retrieving the fault information using the Oracle SOA Suite API’s.

Retrieving fault information
Here are some snippets from a Java class that retrieves the fault information. This Java class could be exposed as Web Service, EJB Session Bean, or some other technology so it can be invoked from SCA composites.

Locator locator = LocatorFactory.createLocator();
FaultFilter faultFilter = new FaultFilter();
faultFilter.setECID(ecid);
List faults = locator.getFaults(faultFilter);

You could extend this example and use the Locator API to retrieve additional information such as the composite sensor data belonging to the composite instance that faulted. That way the administrators will have more information on the SCA composite instance.

Locator locator = LocatorFactory.createLocator();
Composite composite = locator.lookupComposite(compositeDN);
CompositeInstanceFilter compositeInstanceFilter = new CompositeInstanceFilter();
compositeInstanceFilter.setECID(ecid);
List instances = composite.getInstances(compositeInstanceFilter);
List sensors = instances.get(0).getSensorData();

And that concludes the final component of our generic fault handler!

Some notes that were acquired during the further implementation of this fault handler:

Faults that occur in BPEL flows -other then Invoke activities- will not be caught by the fault handling framework. An example would be an incorrect XPath expression in an Assign activity. You will need to use some other mechanism such as the Catch and CatchAll activities for that. These handlers could then enqueue an event on the same fault queue as our fault handler does. Or you could test your SCA composites using the out-of-the-box SOA Suite’s test framework to minimize the chance of errors in the BPEL flow itself. Usually there is a higher occurrence of runtime or unexpected faults when invoking external components such as Web Services then in your own BPEL components (given of course that you test your software).

It seems that not all faults are registered in the SOAINFRA database when “ora-terminate” is used as fault action. Especially faults that occur in Invoke activities of BPEL flows (compared to faults in Mediators and Adapters). When switching to “ora-retry” instead, faults and their information are stored in the COMPOSITE_INSTANCE_FAULT table. Switching from terminate to retry as outcome would mean the SOA composite in which the fault occurred will remain in “RUNNING” state according to the Enterprise Manager and will not be terminated.

Wednesday, September 15, 2010

Fault handling in Oracle SOA Suite 11g - Part III

Let's pick up the previous posts on fault handling (part I and part II) from where we left off: our custom Java class that handles faults. Remember that our class is supposed to enqueue an event containing the fault’s identifier and return the action to be executed by Oracle SOA Suite’s fault handling framework. Retrieval of the fault information itself is done by the SCA composite that acts as generic fault handler. This composite will be initiated based on the fault event and retrieve the fault information based on its identifier in the event payload using the Oracle SOA Suite API’s. The composite will then initiate a Human Task to notify administrators that there was a fault in one our composite instances.

Note that we enqueue a fault identifier (its ECID) instead of the fault information itself. When executing the Java class, Oracle SOA Suite is still in the middle of the fault handling mechanism. That means the fault and its corresponding information is not yet fully stored and accessible. After the event is published and control is returned from the Java fault handler class, Oracle SOA Suite will complete the fault handling mechanism and all fault information will be accessible using for instance the SOA Suite API’s.

The Java code
The Java class needs to implement the “IFaultRecoveryJavaClass” interface and its handleFault method. This method receives the fault context. The method enqueues an event on an AQ queue containing the fault identifier and returns “ora-terminate” to the fault handling framework. Alternatively you can also use JMS or EDN as queuing infrastructure. The choice depends on requirements, durability, personal flavor, and so on. For an example on publishing events on the Event Delivery Network using Spring you can read this blog by Guido Schmutz.

You will need to import the following libraries and JAR files to make the class compile:

  • SOA Runtime
  • Oracle JDBC
  • Java EE 1.5 API
  • Oracle XML Parser v2
  • SOA Designtime
  • SOA Workflow
  • WebLogic 10.3 Remote-Client


The class roughly looks like this:

package nl.vennster;


public class MyFaultPolicyJavaAction implements IFaultRecoveryJavaClass {

public String handleFault(IFaultRecoveryContext ctx) {
    UUID uuid = UUID.randomUUID();
    enqueueAqEvent(createEventPayload(ctx), uuid);
    return "ora-terminate";
}

}

The helper method to create the AQ event looks like the following:

private String createEventPayload(IFaultRecoveryContext context) {


String eventPayload = " UNKNOWN_ECID";
if (context instanceof RejectedMsgRecoveryContext) {
RejectedMsgRecoveryContext rejectedMessageContext = (RejectedMsgRecoveryContext) context;
String ecid = null;
if (rejectedMessageContext.getRejectedMessage() != null &&
    rejectedMessageContext.getRejectedMessage().getEcid() != null) {
    ecid = rejectedMessageContext.getRejectedMessage().getEcid();
}
else if (rejectedMessageContext.getFault() != null &&
    rejectedMessageContext.getFault().getECID() != null) {
    ecid = rejectedMessageContext.getFault().getECID();
    eventPayload = eventPayload.replace("UNKNOWN_ECID", ecid);
}
else if (context instanceof BPELFaultRecoveryContextImpl) {
    BPELFaultRecoveryContextImpl bpelFaultRecoveryContextImpl = (BPELFaultRecoveryContextImpl) context;
    eventPayload = eventPayload.replace(“UNKNOWN_ECID”, bpelFaultRecoveryContextImpl.getECID());
}

return eventPayload;
}

Finally, the helper method to enqueue the event on AQ:

public void enqueueAqEvent(String input, UUID uuid) throws JMSException, NamingException, IOException {
Session session = null;
MessageProducer publisher = null;
TextMessage message = null;
Context context = new InitialContext();
Properties properties = new Properties();
InputStream is = this.getClass().getClassLoader().getResourceAsStream(“aq.datasource.properties”);
properties.load(is);
QueueConnectionFactory connectionFactory = (QueueConnectionFactory)context.lookup((String) properties.get(“aq.queueconnectionfactory”));
javax.jms.Connection connection = connectionFactory.createConnection();
Queue queue = (Queue) context.lookup((String) properties.get(“aq.queue”));
session = connection.createSession(true, 0);
publisher = session.createProducer(queue);
message = session.createTextMessage(input);
message.setJMSCorrelationID(uuid.toString());
publisher.send(message);
}

I used the following properties file that defines the AQ connection factory and queue itself. You need to make sure these JNDI destinations exist on the Oracle WebLogic Server on which Oracle SOA Suite runs:

aq.queueconnectionfactory = aqjms/XAQueueConnectionFactory
aq.queue = eis/aqjms/ALG_ADMIN_QUEUE

Deploying the Java Fault Handler
You cannot just deploy the resulting JAR file containing the above Java class to Oracle SOA Suite. As documented in the Oracle Fusion Middleware Developer’s Guide for Oracle SOA Suite 11g you need to do the following:
You can add custom classes and JAR files to an SOA composite application. A SOA extension library for adding extension classes and JARs to an SOA composite application is available in the $ORACLE_HOME/soa/modules/oracle.soa.ext_11.1.1 directory. 
To add custom JARs:
  1. Copy the JAR files to this directory or its subdirectory.
  2. Run ant.
  3. Restart Oracle WebLogic Server.
This is required because of library classloading among others.

Read more on fault handling in part IV of this blog series.