Showing posts with label JDeveloper. Show all posts
Showing posts with label JDeveloper. Show all posts

Saturday, November 24, 2012

Eventing Hello World

This week I presented the "Introduction in Eventing in Oracle SOA Suite 11g" session at the DOAG conference in Nürnberg. I used several demos in this session to show the eventing capabilities of SOA Suite. This blog contains the source code and accompanying explanation so you can replay the demo yourself.

Introduction
An event is the occurrence of something relevant, signals a change in state that might require an action. Examples of events are: an invoice that has been paid, a customer that moved to a new address, a new purchase order, and so on. Events are complimentary to processes and services: processes and services describe what should be done, events about when something important occurs. SOA is not only about (synchronous) services and processes (what); but also about events (when). Eventing improves decoupling in your SOA landscape.

Slides
The presentation slides can be viewed and downloaded from my SlideShare account. The presentation introduces the concept of eventing, discusses some basic eventing patterns, and talks about the implementation of eventing in SOA Suite using AQ, JMS, and EDN.




Code
You can download a zipfile containing the JDeveloper workspaces for the SOA Composites (DOAG2012_Eventing_SOASuite) and Java projects (DOAG2012_Eventing_Java) used in the demo here.

Prerequisites
You'll need an Oracle SOA Suite 11g runtime to deploy and run the SOA Composites. Oracle provides a pre-built SOA and BPM virtual machine for testing purposes that is easy to install.

Download JDeveloper 11g (11.1.1.6) or later from Oracle Technology Network to inspect and modify the SOA Composite and Java projects.

Setup
In order for the demos to run some plumbing needs to be done for AQ and JMS:

  • The configuration steps required for the AQ demos are listed in the aq_configuration.txt file that is part of the Queuing_Utilities JDeveloper project.
  • The configuration steps required for the JMS demos are listed in the jms_configuration.txt file that is part of the Queuing_Utilities JDeveloper project.
  • In JDeveloper modify the existing Database Connection to point to your DOAG12_JMSUSER database schema.
  • In JDeveloper modify the GenerateInvoice File Adapter of the Billing SOA Composite to write the invoice file to an existing directory of the SOA Suite runtime.
  • In JDeveloper modify the WriteSensorToFile File Adapter of the ProcessSensors SOA Composite to write sensor values to an existing directory of the SOA Suite runtime.
  • Use Enterprise Manager to create a partition in SOA Suite called doag2012_eventing.
  • Deploy the following SOA Composites to the doag2012_eventing partition of the SOA Suite runtime using JDeveloper, Enterprise Manager or scripts: Order2Cash, Dunning, Billing, and ProcessSensors.
  • Deploy the Java application CRM to the WebLogic Server.

Advanced Queuing (AQ)
The first demo shows the queuing capabilities of AQ and shows how to integrate SOA Composites with AQ queues:

  1. Insert a record in the ORDERS table in the DOAG12_WEBSHOP schema. 
  2. The BIT_ENQUEUE_NEW_ORDER_EVENT trigger will execute the ENQUEUE_NEW_ORDER_EVENT procedure that enqueues a message to the NEW_ORDER_QUEUE
  3. You should see a new event in the NEW_ORDER_QT queue table of the DOAG12_JMSUSER schema.
  4. If the Order2Cash SOA Composite is deployed you should see a new instance in Enterprise Manager. This process is started by receiving events from the NEW_ORDER_QT queue using an AQ Resource Adapter.

Java Message Service (JMS)
The next demo shows the publish/subscribe capabilities of JMS and shows how to integrate SOA Composites with JMS:

  1. Complete the Book Order Human Task of the Order2Cash process instance that was started in the previous step.
  2. The Order2Cash instance will use a JMS Adapter to publish an event to the JMS topic DOAG12_BillingTopic. You can inspect the topic in WebLogic Console and see that an event has been published. There are two subscribers to the JMS topic: the Billing SOA Composite (using a JMS Adapter) and the CRM Java application (using a Message-Driven Bean or MDB).
  3. In Enterprise Manager you should see a new instance of the Billing SOA Composite that is started through the JMS Adapter. The instance should have written an invoice file using the File Adapter.
  4. In the SOA Suite log file (e.g. user_projects/domains/[domain]/servers/[server]/logs) you should see a log statement produced by the CRM application that indicates that the event is received.

Event Delivery Network (EDN)
This demo shows the publish/subscribe capabilities of EDN and shows how to use EDN from SOA Composites:

  1. Wait for 5 minutes after the billing event has been published from the Order2Cash process instance using JMS. The OnAlarm branch will be activated and publish a DunningEvent using a Mediator component.
  2. The Dunning SOA Composite is subscribed to the DunningEvent, a new instance of this SOA Composite will be started and can be inspected from Enterprise Manager.
A second usage of EDN is demonstrated using the following steps:
  1. Start a new instance of the Order2Cash process by inserting a new order in the database. Complete the Human Task again. Only this time use Enterprise Manager to fire a PaymentEvent to EDN. This can be done by right-clicking the soa-infra node and selecting Business Events. Select the PaymentEvent and hit the Test button. You can use the PaymentExample.xml file from the Order2Cash JDeveloper project as example event payload. 
  2. Using correlation the running Order2Cash process instance will receive an in-flight event and will continue without starting the Dunning process.

Sensors and Composite Sensors
The last demo shows the sensor and composite sensor capabilities of SOA Suite. Composite sensors are used to add metadata to running instances so they are easier to find in Enterprise Manager or via the Java APIs of SOA Suite:
  1. Inspect the composite sensors of the Order2Cash SOA Composite in JDeveloper.
  2. In Enterprise Manager navigate to the instances of the Order2Cash SOA Composite. Use the Add Fields button to search for instances based on functional data such as customer name and order id. 
Alternatively, composite sensors can also be published using JMS.

Sensors and monitoring objects can be used to feed runtime data of BPEL component instances into Oracle BAM, or publish this data to JMS, Database, or AQ in a non-intrusive way. Sensors are based on configuration instead of adding additional activities and components to your SOA Composites:
  1. Inspect the sensor configuration of the Dunning BPEL component in JDeveloper. These sensors publish to the DOAG12_SensorQueue queue.
  2. In Enterprise Manager navigate to the instances of the ProcessSensors SOA Composite. You should see new instances that are started based on the published sensor events.

Conclusion
The presentation and the demos in this blog give you an overview of the eventing capabilities of SOA Suite. The demo is stuffed with different eventing techniques (AQ, JMS, EDN), this should not be considered a best-practice ;-) Analyze what the best eventing implementation is for your specific scenario.

Some best-practices:
  • Model events in your BPM and SOA projects;
  • Use events to notify running processes;
  • Expand the service registry to include events;
  • Use events for additional decoupling between processes and services;
  • Events is not just queuing, also consider publish/subscribe and event stream processing;
  • There is not a single best technology for eventing implementation in SOA Suite.

Wednesday, October 10, 2012

Compensation Hello World

There were several questions about compensation after the Effective Fault Handling in SOA Suite 11g session that Guido Schmutz and I presented at Oracle OpenWorld last week. The presentation included a live demo that showed how compensation can be used to undo previously executed actions in processes and services that are implemented in SOA Suite. Based on the questions, this blog explains the concepts of compensation, gives you an overview of the demo, and provides a download link to the JDeveloper demo project so you can play around with the demo yourself.

Concept

Process and service activities can be divided into unit-of-works, called transactions that are either executed (i.e. committed) as a whole or undone as a whole (i.e. rollbacked) due to some error or an explicit rollback command. When the activities within the same unit-of-work span multiple resources (databases, Java components, JMS topics, and so on) these resources all need to support global (XA) transactions and need to enlist in the global transaction, to support commits and rollbacks on the transaction as a whole.

It is not always possible to use transactions as a means to commit, or rollback related activities as a whole. For example when the invoked services do not support global transactions. Next to this, long running processes execute several (implicit) commits since transactions shouldn't be kept open too long: this degrades performance and causes completed activities to remain invisible to others. Once a commit has been executed, the committed activities cannot be rollbacked. Consider an Order-to-Process in which we book the customer's credit card in advance and deliver the ordered goods a few days later. The process will dehydrate at some point causing a commit on the active transaction. If delivery of the ordered goods fails we cannot rollback the credit card booking.

Compensation provides a mechanism to undo already committed activities by means of invoking opposite activities (i.e. compensation) in reverse order. For example booking the opposite amount of money to the credit card that was initially charged. SOA Suite provides the following activities to support compensation:

  • Compensation handler. Compensation handlers contain the activities that need to be executed as part of the compensation flow. These handlers are defined per scope, similar to catch blocks. Per scope you need decide if you need a compensation handler. 
  • Compensate activity. The activity that triggers compensation for a SOA Composite. Executing this activity will cause the invocation of compensation handlers for all successfully completed scopes that have defined a handler, and are not yet compensated. Only compensation handlers of scopes that are directly enclosed by the scope that contains the compensate activity will be executed. The handlers are executed in reverse order, so the handler of the last completed scope is executed first. 
Before we jump to the demo some considerations when using compensation:
  • Compensate activities can only be executed from catch blocks and compensation handlers.
  • Compensation activities either trigger compensation for all enclosed and completed scopes using the compensate activity (supported in BPEL 1.1 and 2.0), or can trigger compensation for one specific scope using the compensateScope activity (only BPEL 2.0).
  • Compensation handlers can only be defined on scope level, not on sequence level.

Demo

The demo consists of a SOA composite that implements a simplified Order-to-Cash process. The composite contains a single, asynchronous BPEL component called CompensationExample. After receiving the input message the process executes the following scopes and sequences:

  • Scope Register_Order. This scope simulates the registration of the new order using an Empty activity called Dummy_Register_Order. The scope defines a compensation handler that simulates an undo activity by updating the order with a new status (e.g. cancelled).
  • Scope Invoke_CreditCardService. This scope simulates the registration of the new order using an Empty activity called Dummy_Book_CreditCard. The scope defines a compensation handler that simulates an undo activity by charging the opposite amount to the credit card.
  • Sequence Throw_Fault. This sequence is added for demonstration purposes and throws a fault in case "compensate" is passed as input to the SOA composite; otherwise the process will complete normally. The fault is caught by the Catch_All sequence.
  • Sequence Catch_All. This sequence includes a Wait activity before triggering compensation using a Compensate activity. The wait enables you to inspect the process instance in Enterprise Manager before the compensation logic is executed. After the compensation is completed, the process will send a callback message to the client indicating a fault occurred for this process instance.

Process flow of the Compensation Hello World example

After the wait has finished the compensation handler of the Invoke_CreditCardService is executed. Finally, the compensation of the Register_Order scope is executed. Again, by including Wait activities you can inspect the sequence of events in Enterprise Manager.

The flow of events is shown in the following figures:


Process instance after fault is thrown, but before compensation is triggered
Process instance after compensation is triggered and the compensation handler for the Invoke_CreditCard_Scope is completed. The compensation handler for the  Register_Order scope is still active.
Process instance after all compensation handlers have been executed.
Process instance after compensation has finished and the callback message has been send to the client invoking the process.

Code

You can download the JDeveloper project for the Compensation Hello World example here.

Real-life

In real-life projects you wouldn't add Throw activities to your SOA composites to trigger compensation and test your compensation logic. In such cases you can best use the out-of-the-box SOA Suite Test Framework and BPEL Test Framework to simulate errors (e.g. unreachable services) in unit tests to inspect and test the compensation logic of your SOA composites.

Friday, April 20, 2012

Live Fusion Middleware Development Session @ OBUG Connect 2012

The MECC in Maastricht will host the 5th edition of the OBUG (Oracle Benelux User Group) Connect conference on tuesday the 24th of April. This conference will be the third time that a group of Fusion Middleware specialists from different companies such as AMIS Services, Vennster, Veriton, and Oracle Consulting Services team up to present a live application development session after successful performances at ODTUG Kaleidoscope 2011 and UKOUG 2011. The goal for these events is to build and demo a working application in just half a day using JDeveloper, ADF, Oracle Service Bus, Oracle SOA Suite, and Oracle BPM Studio. At the upcoming OBUG Connect 2012 conference the team will consist of Steven Davelaar, Lucas Jellema, Edwin Biemond, Luc Bors, Lonneke Dikmans, and Ronald van Luttikhuizen.

Attendees can walk in and out of the session, ask questions, interact and comment on the way developers build the application, and see how Fusion Middleware can be used to build an application based on SOA and BPM principles in a productive and iterative way. Thanks to Murphy and his law, at each development session unexpected things happen that need to be dealt with by the development team and session moderators in a short time frame. So come and see!

FMW development session at UKOUG 2011

Read more about the OBUG Benelux Connect 2012 program here.

Saturday, January 28, 2012

Start Small, Grow Fast | Companion Checklist

A companion checklist that summarizes the Oracle SOA Suite best practices contained in the "Start Small, Grow Fast" Oracle whitepaper by Demed L'Her, Edwin Biemond, and Ronald van Luttikhuizen at bit.ly/soa-start-small.



Administrative considerations

  • Involve operations teams from the beginning.
  • Make sure your organization has dedicated middleware administrators.
  • Prefer scripting for deployment of composites.
  • Use SOA Suite configuration plans to capture all environment-specific information instead of hardcoding them in your composites.
  • Avoid creating a separate configuration plan per composite per environment - consolidate these to a few or a single configuration plan per environment.
  • Script as many configuration tasks as possible from the beginning.
  • Document configurations in a well-known central location such as a team Wiki, readily available to all stakeholders.
  • Consider using NFS shares for JCA adapter configuration plans.
  • Use partitions to categorize composites and execute various tasks for multiple composites at once.
  • Use composite sensors to enable the search of specific instances.
  • Negative testing is an absolute requirement.


Infrastructure considerations

  • Build a cluster from the start -even if only with a single node. Think of the following when configuring a cluster:
    • Use individual IP addresses for all components (WebLogic Admin Server, Node Manager, and the Managed Servers).
    • Use the JRockit JVM and Mission Control to detect problems and perform tuning.
    • Leverage WebLogic channels to separate cluster traffic from production traffic.
    • Use a load balancer to divide traffic between services and detect outages of servers in the cluster.
  • Think about your domains. There is no such thing as a “one-size fits all” domain topology; however there are a few tips and guidelines in this area:
    • Always setup Node Manager.
    • Do not combine Admin and Managed Servers; except maybe in non-critical environments such as development.
    • Deploy your software and services to Managed Servers.
    • Leverage domains to partition environments with different lifecycles or significant functional differences.
    • Dedicate the most performant hardware to Managed Servers.
  • Linux x86 is a great entry-level platform for Oracle SOA Suite.
  • Favor Oracle Database as infrastructure database.
  • Perform realistic load tests.
  • Define and test a purging procedure well before going live.


Design-time considerations

  • Use MDS to centrally store artifacts and avoid duplication.
  • Have a canonical model for your core objects to ensure future re-use and consistency.
  • Consider taking a contract-first or meet-in-the-middle approach for interfaces exposed to the outside world.
  • Formulate and adhere to a small set of service design guidelines and naming conventions:
    • Language conventions
    • Naming conventions for composites, services, references and components
    • Naming conventions for BPEL and BPM components and activities
    • Naming conventions for composite sensors
  • Wrap frequently used SOA Suite APIs in simpler custom APIs.
  • Use Domain-Value Maps (DVM) and Business Rules to improve flexibility and agility.
  • Use fault policy files to separate exception and fault handling from “normal” process logic. Centrally store them in MDS to enable re-use across composites.
  • Unit test your composites using SOA Suite’s test framework as you would unit test your Java code using e.g. JUnit.


Architectural considerations

  • Use a simple and concrete service categorization.
  • Spend some time thinking about the granularity of your services to avoid too frequent refactoring. Reusability is a key factor. Other factors are rate of change, availability, and ownership.
  • Building asynchronicity through business events or messaging will improve loose-coupling, ease of deployment and administration and enable throttling.
  • Consider supporting multiple versions of the same service in production to allow service consumers to upgrade at their own pace.
  • SOA governance is needed but can start very simply with a wiki. Consider a full-fledge repository as you grown your SOA efforts.

Tuesday, January 24, 2012

Oracle, Webservices, and PL/SQL

There are many ways you can publish or consume Web Services or XML Documents in an Oracle environment. The other day an organization asked me to evaluate the solution they had chosen to expose PL/SQL packages as Web Service and to consume Web Services from PL/SQL. Not because they experienced problems, but because they wanted to know the 'current state of affairs' in Oracle and XML and evaluate if their way of solving this was the most efficient way.

Not surprisingly, the possibilities are endless, depending on your environment. In this blog, I have listed the possibilities I know of for PL/SQL and added some details about when you would like to use the feature.

Publishing Web services
The following frameworks are available to publish a PL/SQL procedure or function as a web service:

Framework
Infrastructure
Features
Native Database web services Oracle Database 11g Oracle XML DB 11g
PL/SQL Webservices Oracle Applicatieserver JPublisher, SQLUTL
Eclipselink-DBWS JEE Applicatieserver
  • DBWSBuilder (DesignTime)
  • JAX-WS (Runtime)
Oracle DB Adapater Oracle SOA Suite Toplink
Integrated SOA Gateway Oracle E-Business Suite 12  Oracle SOA Suite 10g

The Integrated SOA Gateway is only a viable option, if you are exposing PL/SQL APIs that are part of EBS 12.

If you don't have an JEE Application server (for example because you are in a .NET programming environment), Native Database web services are a viable option.

Of course, you can also program a web service in .NET or Java and call the PL/SQL procedure or function using Object Relational mappings.

Consuming Web services
The other way around, calling a Web Service from the database is also a common use case if you have a lot of logic in your database.

Framework
Infrastructure
Features
PL/SQL Oracle Database 11g UTL_HTTP
Java Oracle Database 11g Java stored procedures, JAX-WS
JPublisher Oracle Database11g UTL_DBWS

Although I think that BPEL, Java and .Net frameworks are a better fit for this type of thing, it sometimes is not feasible to change the entire software architecture. Using a utility like UTL_DBWS and JPublisher is very convenient and less error prone than coding all the XML by hand in the database.
If you are planning to move to JEE or SOA, using PL/SQL Webservices, EclipseLink or the Oracle database adapter is a good step to start this endeavor.

Friday, December 23, 2011

Wednesday Wizardry - Small encore

Just a small encore on my blog post about the Wednesday Wizardry session at UKOUG 2011. Thanks to Simon Haslam we have a 180 degree view on the setting and team. Based on the frowning and dislayed code on the screen the team was in the final stage of the session.

180 degree view of the Wednesday Wizardry session at UKOUG 2011

Sunday, December 18, 2011

Vennster @ UKOUG 2011

The UK Oracle User Group (UKOUG) Conference 2011 in Birmingham is a wrap! Well, at least it was when I started writing this blog :-) Now it has been over a week since I returned on a bumpy flight from Birmingham from my first UKOUG conference which I really enjoyed! Good atmosphere, friendly people, quality presentations, lots of familiar people, and surprisingly good food (at some places at least).

Here's a short summary of the sessions that were hosted by Vennster. Due to last minute cancellations we were asked to fill in for some of the speakers that couldn't attend and presented some more sessions than expected.

BPA Suite to BPEL case study
Lonneke presented on how to model business processes in Oracle BPA Suite and how to transform business process definitions from BPMN to BPEL along with the advantages and disadvantages of this approach. You can find the slides and more background information in this previous blog post.

Effective Fault Handling in Oracle SOA Suite 11g
I presented on fault prevention and handling in SOA and BPM environments and the mechanisms Oracle SOA Suite 11g offers for fault handling. A fault can be defined as something that happened outside the expected operational activity or “happy flow”. Faults can be categorized into:

  • Technical faults (network errors, full tablespace, etc.)
  • Programming faults (nullpointer exception, cursor not closed, etc.)
  • Business faults (credit check failure, invoice amount higher than the ordered amount, etc.)
  • Faulty user input (return date of a flight before the departure date, wrong credit card number, etc.).

To prevent faults you can apply various techniques: configure a robust infrastructure to avoid technical errors (clustering, redundancy, high availability), use pair-programming and peer-reviews to avoid programming errors, identify business requirements and implement these to avoid and correctly deal with business faults, and apply user experience techniques to lower the chance of faulty user input and its impact. This session mostly focused on fault prevention and handling for technical and business faults.

Event-Driven SOA: Events meet Services
Lonneke and I presented (unexpectedly since the would-be presenter was unable to attend) the use of events and how events, services, and processes can work together to provide flexibility, decoupling, and realize business requirements. Events are important from a business as well as technology perspective. Oracle SOA Suite supports eventing through several implemenations such as Advanced Queuing (AQ), Java Message Service (JMS), and the Event Delivery Network (EDN).

I included the slides from my earlier eventing presentation at Kaleidoscope 2011 which was quite similar to the UKOUG session.

Overview of Eventing in Oracle SOA Suite 11g

Some background information can be found in this 2008 blog post explaining the importance of events.

Approach to SOA: Making This a Successful Endeavor for the Whole Organization
Lonneke was asked last-minute to present on why and when to use SOA and what will makes it successful using the (according to some) infamous "breakfast" example. At the end of this session, you will know what SOA means, when it is best used, and how you can get there. 

Wednesday Wizardry
Lonneke, Lucas, and Ronald showed how to rapidly build an enterprise application based on SOA and BPM principles using Oracle Fusion Middleware in only a couple of hours. Read all about it in this blog post.

Other sessions
Due to the unexpected sessions we needed to host I wasn't able to attend that many other presentations. However, I did visit and enjoyed the "WebLogic Server and Oracle RAC" session by Simon Haslam and Frances Zhao on the integration between Oracle WebLogic Server and the Oracle (RAC) Database; especially Active GridLink and the enhancements it offers.

Christmas in Birmingham: Lonneke in front of a square with a giant polar bear and snooker on the big screen

As for me, until next year at UKOUG 2012!

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.

Sunday, August 1, 2010

Fault handling in Oracle SOA Suite 11g - Part II

This previous blog explained why it is a good idea to address -and handle- business faults separately from technical errors. It also introduced a mechanism used in real life Oracle SOA Suite 11g projects to deal with technical errors in a generic way without having to add this functionality to all our SCA composites again and again. Now it is time to dive into the technical implementation of that mechanism and some nitty gritty details.

First things first: How do we get a hold of these technical errors and how can we determine what to do with them?

Oracle SOA Suite 11g offers a unified fault handling framework for SCA composites and their references, service adapters and components such as BPEL and Mediator components. The framework provides hooks you can use to configure fault handling and possibly call out to your own fault handling code. The unified framework is an improvement compared to the SOA Suite 10g stack that consisted of less integrated components (ESB, BPEL) that had their own fault handling mechanisms. The framework is heavily based on BPEL PM’s 10g fault handling framework.

In SOA Suite 11g you configure the fault handling framework on the level of SCA composites using two files: fault-policies.xml and fault-bindings.xml. By default these files need to be in the same directory as the composite.xml file.

Note that you can place these files somewhere else and have multiple SCA composites point to the same fault handling configuration. MDS is a nice candidate since it is a repository for shared artefacts such as reusable XSD’s, DVM’s, and so on. To do this you need to set the “oracle.composite.faultPolicyFile” and “oracle.composite.faultBindingFile” properties in the composite.xml files and point them to fault binding and policy files in the central MDS location. Whether you use this feature mostly depends on how unique your fault handling per SCA composite will be. For now, we will continue with the basic scenario in which we define fault policies per SCA composite.

First of all we will configure the fault-bindings.xml file. This file defines what elements are bound to what fault policy. Elements can be components, references, service adapters or an entire composite. The actual fault policy that is referred to will be defined later on in the fault-policies.xml file. Since business faults can be dealt with using BPEL activities such as Throw and Catch activities we want to have all remaining faults (all unexpected faults) in the entire composite to be handled the same way.

Let’s say we have a simple SCA composite with an inbound file adapter called “MyInboundFileService” and some other components such as a BPEL and Mediator components. Our fault-bindings.xml file could look like the following:


<?xml version="1.0" encoding="UTF-8"?>
<faultPolicyBindings version="2.0.1"
                     xmlns="http://schemas.oracle.com/bpel/faultpolicy">
    <composite faultPolicy="MyCompositeFaultPolicy"/>
</faultPolicyBindings>


In this example we bind fault handling for the entire composite to the -yet to be defined- policy “MyCompositeFaultPolicy”. Instead of the “composite” element you can use the “component” or “reference” elements to apply fault handling on a more granular level.

Next we need to define the fault-policies.xml file. This file defines the actual policies and the conditions when these policies should be executed.

Following the example we will define a single policy, namely “MyCompositeFaultPolicy”:



As you can see from the example we first define the criteria when the policy should be executed. In this case we want it to be executed in case of any technical error. More specifically in case the error is of type “mediatorFault”, “bindingFault” or “runtimeFault”. Note that we can define more intelligent conditions that can be content-based (e.g. based on process instance variables).


<?xml version="1.0"?>
<faultPolicies xmlns="http://schemas.oracle.com/bpel/faultpolicy">
  <faultPolicy version="2.0.1" id="Subsidie_FaultPolicy">
    <Conditions>
      <faultName xmlns:medns="http://schemas.oracle.com/mediator/faults"
 name="medns:mediatorFault">
        <condition>
          <action ref="MyFaultPolicyJavaAction"/>
        </condition>
      </faultName>
      <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
 name="bpelx:bindingFault">
        <condition>
          <action ref="BPELJavaAction"/>
        </condition>
      </faultName>
      <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
 name="bpelx:runtimeFault">
        <condition>
          <action ref="MyFaultPolicyJavaAction"/>
        </condition>
      </faultName>
    </Conditions>
    <Actions>
      <Action id="ora-terminate">
        <abort/>
      </Action>     
      <Action id="MyFaultPolicyJavaAction">
        <javaAction className="nl.vennster.MyFaultPolicyJavaAction"
                    defaultAction="ora-terminate">
          <returnValue value="ora-terminate" ref="ora-terminate"/>
        </javaAction>
      </Action>
    </Actions>
  </faultPolicy>
</faultPolicies>


When the error meets any of these criteria the actions within the “Actions” element will be executed. Instead of configuring default actions such as abort, retry or rethrow we redirect the fault to our own Java class called “MyFaultPolicyJavaAction”. This is allowed as long as such a class implements the “IFaultRecoveryJavaClass” class containing the methods “handleFault” and “handleRetrySuccess”. Since the fault may occur within synchronous processes the fault handling framework needs to know what to do after it delegates the fault to some external piece of code. In order to do so the “handleFault” method needs to return the outcome as String. This outcome should map to a predefined fault action. In our example we abort the process instance after our custom Java class has been executed by returning “ora-terminate” that is mapped to the default abort action. Next to that, Java actions need to define a “defaultAction” attribute in case the outcome cannot be mapped to a predefined fault policy.

For some reason rejected messages need to be defined separately. In other words, such faults remain uncaught when using the above fault handling configuration. An example of a rejected message can be an inbound file that cannot be parsed correctly by a File Adapter. To have rejected messages handled we need to specifically include it using the exact name of the adapter service or reference. In our case the inbound file adapter is named “MyInboundFileService”. Our fault-bindings.xml file now looks like this:


<?xml version="1.0"?>
<faultPolicyBindings version="2.0.1"
                     xmlns="http://schemas.oracle.com/bpel/faultpolicy">
    <composite faultPolicy="MyCompositeFaultPolicy"/>
    <service faultPolicy="RejectedMessages">
        <name>MyInboundFileService</name>
    </service>
</faultPolicyBindings>


Note that you can add more than one adapter name to the “service” element. That way all rejected messages of all adapters can be handled the same way. So for instance you can add “MyOutboundDatabaseService” to the “RejectedMessages” policy too.


<?xml version="1.0" encoding="UTF-8"?>
<faultPolicyBindings version="2.0.1"
                     xmlns="http://schemas.oracle.com/bpel/faultpolicy">
    <composite faultPolicy="MyCompositeFaultPolicy"/>
    <service faultPolicy="RejectedMessages">
        <name>MyInboundFileService</name>
<name>MyOutboundDatabaseService</name>
    </service>
</faultPolicyBindings>


We need to add a fault policy to the fault-policies.xml file so our Java class is executed:


<?xml version="1.0"?>
<faultPolicies xmlns="http://schemas.oracle.com/bpel/faultpolicy">
  <faultPolicy version="2.0.1" id="Subsidie_FaultPolicy">
    <Conditions>
      <faultName xmlns:medns="http://schemas.oracle.com/mediator/faults"
 name="medns:mediatorFault">
        <condition>
          <action ref="MyFaultPolicyJavaAction"/>
        </condition>
      </faultName>
      <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
 name="bpelx:bindingFault">
        <condition>
          <action ref="BPELJavaAction"/>
        </condition>
      </faultName>
      <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
 name="bpelx:runtimeFault">
        <condition>
          <action ref="MyFaultPolicyJavaAction"/>
        </condition>
      </faultName>
    </Conditions>
    <Actions>
      <Action id="ora-terminate">
        <abort/>
      </Action>     
      <Action id="MyFaultPolicyJavaAction">
        <javaAction className="nl.vennster.MyFaultPolicyJavaAction"
                    defaultAction="ora-terminate">
          <returnValue value="ora-terminate" ref="ora-terminate"/>
        </javaAction>
      </Action>
    </Actions>
  </faultPolicy>
  <faultPolicy version="2.0.1" id="RejectedMessages">
    <Conditions>
      <faultName xmlns:rjm="http://schemas.oracle.com/sca/rejectedmessages">
        <condition>
          <action ref="MyFaultPolicyJavaAction"/>
        </condition>
      </faultName>
    </Conditions>
    <Actions>
      <Action id="ora-terminate">
        <abort/>
      </Action>
      <Action id="MyFaultPolicyJavaAction">
        <javaAction className="nl.vennster.MyFaultPolicyJavaAction"
                    defaultAction="ora-terminate">
          <returnValue value="ora-terminate" ref="ora-terminate"/>
        </javaAction>
      </Action>
    </Actions>
  </faultPolicy>  
</faultPolicies>

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

Thursday, July 1, 2010

Fault handling in Oracle SOA Suite 11g - Part I

You generally want to differentiate between technical errors and functional faults within your processes and services. Functional faults are those that have meaning to the business and might be expected. Functional faults and handling these faults can be part of a process. Consider the example of electronic invoice handling in which an invoice is processed that has a total amount of $2000 while an organization only approved an amount of $1500. In this scenario we can use a human task to halt this particular process instance and assign it to the finance department. An employee of the finance department acquires the task and investigates the issue. He or she may conclude that the client sending the invoice was mistaken, that the invoice approval was not entered correctly in our backend IT-systems or that someone put a coffee mug on the invoice and hence the amount was wrongly interpreted by our scanning and OCR software. In any case, after this human intervention the process may continue again and follow the “happy flow” in our BPEL or BPM processes.

When it comes to technical faults you probably do not want to design error handling in the process itself. If you do, your processes and services will end up being cluttered with all kinds of additional process logic such as while loops, gotos, catches, event handling, and so on to try to recover from technical errors. Technical errors might not be recoverable at all; think of an invoice file that is incorrectly formatted, an invoice file that contains negative numbers while your service or process only accepts positive values, or an invoice file that is mangled during transport. Besides, trying to handle these errors makes your SCA composites look like a mix of spaghetti and circuit boards. Not exactly flexible, agile and manageable: the things we wanted to achieve with service- and process-orientation in the first place.

This blog series contains a possible mechanism to generically handle technical errors in your processes and services -that are wrapped as SCA composites- in Oracle SOA Suite 11g.

In one of our projects we came across a scenario in which administrators need to be notified in case of technical errors in any of the SCA composites. Next to the notification they want the corresponding composite to be terminated. Administrators then investigate the cause of the problem and possibly restart the process instances that are involved. Since every employee uses a task-driven portal, administrators want the error to be presented as a human task in this portal instead of receiving a bunch of e-mails. This needed to be implemented with a minimum of additional (business or process) logic.

To achieve this the following mechanism is used:

  • Use Oracle SOA Suite’s Fault Management Framework to redirect (technical) errors to a custom Java class;
  • Have the Java class fire an event containing the unique id of the instance using the Event Delivery Network (EDN) or Advanced Queuing (AQ);
  • Terminate the composite instance by using the Fault Management Framework and the outcome of the custom Java class;
  • Create a single SCA composite to handle all technical errors. This composite subscribes to the event, gathers information on the faulted composite instance, and presents this information as a human task that is assigned to administrators.


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