Wednesday, September 16, 2015

Oracle SOA/BPM: What are Business Faults Really?

You may have read that it is a best practice to let a service return a "business fault" as a fault. In this article I point out some pitfalls with this "best practice", and will argue that you should have a clear understanding of what "business fault" means before you start applying it. The examples are based upon the Oracle SOA Suite 11g, but apply as well to 12c.

To allow the consumer to recognize a specific fault, you add it as a fault to the WSDL. This looks similar to the following:

Sometimes you see that for every individual error situation a specific fault is defined, in some other cases you might find that all errors are wrapped in some generic fault with a code to differentiate between them. In the example above two different, specific faults are defined.

What you should realize is how a business fault manifests itself in Enterprise Manager. When you throw a fault from a service, it will be represented as a BusinessFault in the flow trace of the consumer (but not in the Recent Faults and Rejected Messages section):

Any instance of the consumer that threw a fault will have an instance state that is flagged as faulted.

Now, if the fault really concerns an error, meaning some system exception or an invalid invocation of the service by the consumer (e.g. wrong values for some of the arguments), than that probably is exactly how you would like it to respond. Such errors should stand out in EM because you probably either have some issue in the infrastructure (e.g. some service not being available), or some coding error. However, what I also see in some of the examples you can find on the internet as well as in practice, is that faults are thrown in situations that do not really concern an error. For example, for some CustomerService.find() operation a fault is returned when no customer could be found.

The problem with such a practice is that this type of error generally is of no interest to the systems administrator. In the Oracle SOA/BPM Suite 11g there is an option to search on Business Faults Only or System Faults Only but that does not work. So when thrown enough, these "pseudo errors" start cluttering their view. The log files are equally cluttered:

This cluttering in EM and logs introduces the risk that systems administrators can no longer tell the real errors from the faults, and may no longer takes them very serious. Exactly the opposite of what you want.

But system administrators are not the only ones suffering from this. Also BPM developers very often are confronted with tough challenges when integrating such services in their process model. For example look at the following model:

In this example the service throws 2 faults that are not really errors, but just some result that you may expect from the service. Each fault has to be handled, but in a different way. At the top of the service calls are two Boundary Error events, one for each type of error. In case of BusinessFaults you either have to catch each one individually, or have one to catch all business faults:

Unlike with system exceptions, there is no way to do both at the same time.

A BusinessFault manifest itself as a fault in the flow trace of the business process, suggesting that something went wrong while that is not the case at all.

Given this issue with of making the process model less clear, and cluttering the flow trace, I therefore prefer handling such "errors" as a normal response instead, as is done on the right-hand side of the service call in the process model. I used an exclusive gateway to filter them out from the normal flow, making it easier to follow how the process responds to it.

By the way, the "faultCode" and "faultString" elements are available because I defined them as element of the fault thrown from the BPEL process I use in the example. When you define a Business Exception object in BPM, then by default you only have one single "errorInfo" element at your disposal:

As I explain in this article, you can customize a Business Exception object by manually modifying its XSD.

I included handling of system exceptions (remoteFault and other system exceptions at the bottom) in the process model only for the sake of example. Rather than handling system faults in the process, you should use the Fault Management Framework. However, using this framework is not an option for the 2 BusinessFaults in the example.

In case of a system exception you have a couple of out-of-the-box elements at your disposal, but unfortunately this is not the same for a specific exception compared to a catch all:

Conclusion: the (real) best practice is to only throw a fault when it really concerns an error that is of interest to a systems administrator. Any other type of error should be returned as a normal response.

For example, for the CustomerService.find() operation you could choose to return an element that only contains a child node when one found, and that has an extra element "noOfCustomersFound" that returns 0 when none exists, or use some choice element that either returns the customers found, or some other element with a text like "customer not found".

More information:
"Fault Handling and Prevention, Part 1", Guide Smutz & Ronald van Luttikhuizen
"SOAP faults or results object", discussion on The Server Side

Wednesday, August 12, 2015

Oracle SOA/BPM 12c: Propagation of Flow Instance Title and Instance Abortion

Recently I wrote this posting regarding an improvement for setting the title of a flow instance in Oracle BPEL, and BPMN 12c. In this posting I will discuss two related improvements that comes with SOA/BPM Suite 12c, being that the flow instance abortion is automatically propagated from one instance to the other, as well as the flow instance title. Or more precisely, for every child instance the initiating instance is shown together with its name.

Since 12c the notion of composite instance is superseded by that of flow instance, which refers to the complete chain of calls starting from one main instance to any other composite, and further. Every flow has a unique flowId which is automatically propagated from one instance to the other.

Propagation of Flow Instance Title

This propagation does not only apply to the flowId, but also to the flowInstanceTitle, meaning that if you set the flowInstanceTitle for the main instance all called composites automatically get the same title.

So if the flowInstanceTitle is set on the main instance:

Then you will automatically see it for every child instance as well:

Trust but verify is my motto, so I tried it for a couple of combinations of composite types calling each other, including:
  • BPM calling BPEL calling another BPEL
  • BPM initiating a another composite with a Mediator and BPEL via an Event
  • Mediator calling BPEL

Flow Instance Abortion

When you abort the instance of the parent, then all child instances are aborted as well.

In the following flow trace you see a main BPM process that kicks of:
  1. A (fire&forget) BPEL process
  2. Throws an Event that is picked up by a Mediator
  3. Calls another BPM process
  4. Schedules a human task

On its turn the BPEL process in step 1 kicks of another BPEL process (request/response). Finally the BPM process in step 3 also has a human task:

Once the instance of the main process is aborted, all child instances are automatically aborted as well, including all Human Tasks and composites that are started indirectly.

The flip-side of the coin is that you will not be able to abort any individual child instance. When you go to a child composite, select a particular child instance and abort, the whole flow will be aborted. That is different from how it worked with 11g, and I can imagine this will not always meet the requirements you have.

Another thing that I find strange is that the Mediator that is started by means of an event, even is aborted when the consistency level is set to 'guaranteed' (which means that event delivery happens in a local instead of a global transaction). Even though an instance is aborted, you may have a requirement to process that event.

But all in all, a lot easier to get rid of a chain of processes instances than with 11g!!

Thursday, July 16, 2015

How to Hide Actions in OBPM 12c Workspace

In this article I explain how to hide the actions in the drop-down in Workspace.

In some situations you may need to hide the actions that are shown in the Actions drop-down in Workspace.

One way to do so is by configuring the access that users with a specific Workspace role have for a specific task (not to be confused with a swim-lane role), by going to the task definition -> Access -> Actions. For example, if you want to disable that an assignee can acquire or reassign a task, you can uncheck the "Acquire" and "Reassign" check boxes in the "Assignees" column.

You can also uncheck the outcomes, for example like the "APPROVE" and "REJECT" actions in the picture above. However, this will make that the assignee cannot choose the outcomes at all, because then the buttons are not rendered either. When you uncheck all outcomes this will practically make that the assignee cannot execute the activity at all, which is probably not what you want. As a matter of fact, you will also not be able to commit the task using the updateTaskOutcome() operation on the TaskService, as you will get an error when tying to do so.

A more practical case for hiding the outcomes from the drop-down menu is where the user should not be able to chose them from there, but should be able to chose the actions using buttons on the screen. An example would be where you need to submit data through the form, because it has to update data in the database directly (instead of via a service call in the process). This you can do through the Configure option in the task definition.

When you check "Require payload review before approval" the user will not be able to chose any action from the drop down. However, the buttons will be available on the screen.

Wednesday, July 15, 2015

Starting a Process using a Timer with a Duration in Oracle BPM

In this blog article I explain three options to configure a timer start event based upon some configurable duration.

As far as I know firing a timer based on a duration is only applicable in case of a Timer Event Sub-process. Let me know if you think otherwise.

In case of an Event Sub-process the timer starts at the same moment when the process instance starts. There is no way to change it at any point after that. Given this , you can use one of the following three options that I discuss below. If you know of some oher way, again: let me know!

Input Argument

You can use an element that is part of the request of the process. In the following example there is one input argument called 'expiry' of type duration which is mapped to a process variable:

The process variable can then used to start the timer using an straightforward simple XPath assignment:

Preference in composite.xml

You can also configure a preference in the composite.xml file. Such a preference belongs to a specific component, and starts with "preference" (or "bpel.preference", but you can leave "bpel." out). Using the dot as a delimiter you can post-fix that with the preference name to use:

You can then set the timer using the ora:getPreference() XPath function. All these preferences are strings, but if the value is an ISO duration it will automatically be converted to a duration.

Domain Value Map

A third option is to configure the duration using a Domain Value Map or DVM for short. In the following example a DVM file is used for configuration parameters as a name-value pair:


The timer can be instantiated using the dvm:lookupValue() XPath function, as show in the following picture:

What to Choose?

This depends on the requirements.

If your consumer should be able to determine the duration, you should pass it on as a request parameter.

If the business wants to change it run-time than using the DVM is the best option. The initial value is determined design-time but can be changed run-time via SOA Composer (the same tool via which business rules can be changed).

Otherwise the composite preference is your weapon of choice. Also for this preference the initial value is determined design-time, but can still be changed after deployment by IT using the MBean Browser in Enterprise Manager.

Thursday, July 09, 2015

Using a Parallel Gateway without a Merge in OBPM

In this blog article I give a brief explanation regarding some aspect of the behavior of the parallel gateway in Oracle BPM. It has been changed on September 15 2015 by adding the remark at the end regarding a Complex Merge (thanks to Martien van den Akker).

For the BPMN modelers among us, I have a small quiz.

Given a process model like this, what would be the behavior of Oracle BPM?

  1. It does not compile because OBPM thinks it is not valid BPMN
  2. The flows with Activity 1 and 2 are merged, the token moves to the End event of the process, and then the instance finishes.
  3. Activity 1 and 2 are executed, and then OBPM waits in the merge because to continue all tokens have to reach the merge.
  4. The flows with Activity 1 and 2 are merged, the token moves to the End event of the process, and in the meantime waits until the timer expires. It will not end before the token reached the Terminate end event, because not all flows from the split are explicitly merged the whole process itself serves as an implicit merge.

If this would be some magazine, I would now tell you to go to the last page and turn it upside down to read the answer. Or wait until the next issue in which I announce the prize winners.

Alas, no such thing here so let me give you the answer straight away, which is answer 4:

I must admit I was a bit surprised, as I seem to remember that some bundle patches or patch sets ago it would have been a. But when you look at the BPMN specification there is nothing that says that a parallel gateway always has to have a merge. Strange then that OBPM does not let you draw a model without one, but at least it works with a merge with just one ingoing flow.

As a matter of fact, to make the End even actually end the instance, you should change it into an Intermediate Message Throw event, and end the process with a Terminate End event as well. Run-time that looks awkward, because even when your process ends successfully it has the state Terminated.

Fir this reason and and perhaps because your audience might just not understand this model, specifically when it concerns a larger one, the following alternative perhaps is easier to understand. You now can choose if and which flow you want to end with a Terminate End event.

To force that the process continues after the merge, a Complex Merge is used that aborts all other pending parallel flows when the timer expires.

Wednesday, June 24, 2015

Groovy Time! How to use XML dateTime and duration in BPM 12c

In this article I show some examples of handling XML dateTime and durations in Groovy in the context of a Oracle BPM 12c application.

Working with dates and durations in Java has always been painful. Mainly because date and time is a complex thing, with different formats and time zones and all, but I sometimes wonder if it has not been made overly complex. Anyway. Working with XML dates is even more complex because the limited support by XPath functions. Too bad because in BPM applications that work with dates this has to be done very often, and as a result I very often see the need to create all kinds of custom XPath functions to mitigate that.

This issue of complexity is no different for Groovy scripting in Oracle BPM 12c. And let handling of dates be a typical use case for using Groovy scripting because of this limited support by XPath. Therefore, to get you started (and help myself some next time) I would like to share a couple of Groovy code snippets for working with XML dates and durations that may be useful. These example are based on working with the XML dateTime type, and do not handle with the complexity of time zones and different formats. In my practice this is 99% of the use cases that I see.

In my opinion you still should limit using Groovy to handle dates and to the minimum, and rather use custom XPath functions, or create a Java library which you can can import in Groovy. But when you have to, this just might come in handy.

Instantiate an XML Date

If you have an XML element of type dateTime, you use an XmlCalender object. An XmlCalender object with the current time can instantiated as shown below:

Date now = new Date()
GregorianCalendar gregorianNow = new GregorianCalendar()
XmlCalendar xmlDate = XmlCalendarFactory.create(gregorianNow)

Instantiate a Duration and Add it to the Date

To instantiate a duration you use an XmlDuration object. In the code below a duration of one day is added to the date:

XmlDuration xmlDuration = new XmlDuration("P1D")

The string to provide is of type ISO duration.

The imports to use can also be a pain to find. That actually took me the most time of all, but that can just be me. The ones needed for the above are shown in the following picture (you can get to it by using clicking on Select Imports on the top-right corner of the Groovy script.

Monday, June 22, 2015

Oracle BPEL & BPM 12c Set Flow Instance Title

In this article I describe how to set the instance title for a composite in Oracle BPEL or BPM 12c.

Sometimes little, annoying things that are fixed with a new release can give great joy. With 11g you could set the composite instance title using the (advanced) XPath function setCompositeInstanceTitle(). This helps to find or identify instances in Enterprise Manager. However, for high volume composites you may want to configure in-memory-optimization as well by adding the following properties to the BPEL process in the composite.xml:

The problem is that when you configure in-memory-optimization, that setCompositeInstanceTitle() fails because there is a relation with auditing.

In 12c the composite instance does no longer have such a prominent role in the SOA/BPM Suite. Instead the flow instance now has that role. And with that setCompositeInstanceTitle() has been deprecated, and setFlowInstanceTitle() should be used instead:

You can set the flow instance title by adding a script activity right after the Receive with assign to some dummy string variable, using the setFlowInstanceTitle() as show above. To make it work I had to wrap the string variable in a string function.

Unlike the setCompositeInstanceTitle(), with the setFlowInstanceTitle() you can configure in-memory-optimization and still display the title in Enterprise Manager:

Setting the title for a BPM flow instance can be done using the same XPath function and use it in an assignment to some dummy variable in the start event.