Thursday, October 11, 2012

BPMN Naming Conventions

So far I have not found many references discussing BPMN naming conventions, and there is no official one. So I thought I share a few of mine that I developed over the years. Hope you can make use of it.

Most of them are captured in the following picture.


Unfortunately I cannot depict them all, so here are a few more:
  • Do not use the component type name in its name, for example do not use Expenses Process, Submit Expenses Activity, Expenses Rejected Exception.
  • Name a process so that its name fits in the following phrase: "the [Process Name] process", for example: "the Order Handling process".
  • Give an activity a short, but meaningful name. So:
    • Don't use uncommon abbreviations,
    • To keep the reader focused on the keywords, do not capitalize prepositions and possessive pronouns ("Review and Finalize Order"),
    • Avoid articles and pronouns ("Add Order Lines" instead of "Add all Lines to the Order").
  • Name Catch Events, Business Exceptions, and Signal Events so that is reads like an answer to the question: "What happened?", "Well the Customer Cancelled".

Like most naming conventions, the prime reason is to have consistency. So don't treat it like a religion, and don't think that mine are better than yours. Of course they are, but just don't think that. Most of them are more like a guideline.

To help you with your choice, consider this:
  • Using active verb-noun phrases is a psychological thing. Don't ask me why but somehow it helps your brains to determine the right scope of an activity. For example, one person may interpret Order Handling as one single activity (done by one person as one logical "transaction") while some other guy considers it to be a complete process. If you call it Handle Order that just "sounds" more like one single activity. It is not for nothing that this also is a de facto standard for use cases.
  • Using the question mark for exclusive gateways helps with limiting the amount of text you have to put in the diagram, as all conditions on the outgoing sequence flows read as a simple answer to the question of the gateway.
Let me know if you have some more, or when yours are better than mine!

Monday, April 23, 2012

When to Use Custom XPath Functions in the SOA Suite

If you want to know how to create custom XPath functions, then have a look for example at Anthony Reynold's Blog entry on the topic. I have little to add to that excellent posting except for how to add parameters, which is done using the <param> tag as in the following example:



And the following simple piece of Java code to get the parameter from the list:

  public static Object compressGuid(IXPathContext iXPathContext, 
                                    List arguments) {
    String guid = (String)(arguments.get(0));
    ...
  }



If you want to know when or why to use custom XPath functions, then read on.

Before I come to some sort of a conclusions, first let's discuss some of the specifics of the mechanism of adding custom XPath functions.


One Function, One Class

First observation is that a custom XPath function is exposed by a class that implements the IXPathFunction interface. This interface enforces implementation of a call() method which executes the XPath function. As there can be only one call() method in the class, it can realize only one function. So if you want to implement more functions you will need to create as many classes as there are functions. To support reuse you can let each of those classes extend an (abstract) super class that will contain the common behavior and (static) reusable attributes.


No Runtime Versioning

A second observation is that the class to implement an XPath function ends up in a jar file that is deployed in the SOA infra structure. A class is not a service, so there can be only one implementation of that class at the same time. If you need to deploy a new version of the XPath function while keeping the previous one, you either need to put it in a different package or give it another name. On top of that you will also have to give the <function> another name (in the example resulting in a compressGuid, and compressGuid2). How ugly do you want it to get? An obvious other aspect is that the XPath function by definition is reusable for everybody that is deploying on the SOA engine on which the jar file is deployed.


No Right-Mouse-Click Deployment

By now you will realize that you cannot simply deploy a new version of the jar file on the server by just right-mouse-clicking it and then choose "deploy", and that this is for a reason. You will have to copy the jar file to a specific folder, run an ant script, and restart the server.


Conclusion

Custom XPath functions is not the silver bullet to do any type of Java embedding in SOA or BPM processes. Especially as a BPM developers you just might have hoped for this as, unlike in BPEL, there is no Java Embedding activity in BPM (also for a good reason you might argue, but that's another blog entry).

You should only create XPath function for specific types of cases, while applying some best practices:

  1. Only use it for XPath functions that clearly fits between all other already available XPath functions. An example is an XPath function I just created (based on the brilliant algorithm of my dear colleague Tonio Voerman), which compresses the 32 character Oracle GUID into 30 characters (because the column in which we have to store it, is only 30 characters long). After all the (existing) oraext:generate-guid() is also an XPath function.
  2. Be sure that the XPath function indeed is an obvious candidate for reuse (our compress-guid() function will be used by every BPM process). Otherwise, other solutions like including a Sprint Context in your composite, probably are better.
  3. Do your utter best to get the proper requirements for the interface, and functionality, to prevent you find yourself in a situation (and trouble) where you have to deploy a new version of the function next to an existing one.
  4. Test the XPath function thoroughly, preferable using some unit-testing framework like JUnit

Unbelievable, this is actually the first time in my life that I manage to post two entries on the same day. Normally I don't even find the time to do two in a week, or even a month for that matter!

OBPM 11g Multi-Langual Process Models

Sometimes simple things are simple!

Take for example creating process models that you can show in 2 different languages. With OBPM this is so simple, that I at first I could not find it because I was looking in the wrong place.

That is: simple if you realize that you can also access (BPM) Project Preferences from the BPM Navigator (next to the Project Properties that can be accessed from the Application Navigator). But once found it's dead simple. Just add an extra language on the languages tab, as shown in the next figure.



You can then enter a second localized label to the pool, events, activities and gateways by going to its properties, and then click on the globe and enter the label.



After that, you can modify the language of your model on the fly by changing the default language, for example from English:


into Dutch:


If you were paying attention, or looked carefully, you will have noticed that I was not mentioning the role and sequence flow. Alas, those are not multilingual.

Oh, and eh... there is a small bug. The label of the pool only refreshes after reopening the model.

Wednesday, February 29, 2012

OBPM 11g And Human Workflow Services

In this posting I describe a case in which I demonstrate the working of the Human Workflow Services of the Oracle BPM Suite 11g. Or rather the SOA Suite 11g, as it is used for human workflow in BPEL as well.

But before I do so, a brief explanation of what the Human Workflow Services is.


So What is it?

It probably is the most used part of what also is known as the SOA Suite API. The Human Workflow Services provide services to, how surprising, handle human tasks. But there also is an API for Oracle Business Rules, B2B, and the User Messaging Services, to mention a few others.

Ever worked with the OBPM's Workspace or Worklist? Just realize that practically all data you see in there and all actions you can perform are provided by the Human Workflow Services. If you ever need to provide a custom worklist, for example to embedded it in some 3rd party application, the Human Workflow Services is what you will be using.

The most commonly used services probably are the following:
  • TaskQueryService To provides operations to query tasks, based upon keywords, category, status, business process, attribute values, etc.
  • TaskService Provides single task operations, to manage task state, to persist, update, complete, reassign, or escalate tasks, etc.
  • IdentityService To authenticate users (when loggin on into the workspace), to lookup user properties, roles, group memberships, etc.
Other services are the TaskMetaDataService, UserMetaDataService, TaskReportService, RuntimeConfigService, and TaskEvidenceService.

Except for the IdentityService all other services have both a SOAP as well as a remote EJB interface. The IdentityService is a thin SOAP layer on top of WebLogic.


How to Use It?

All services require authentication, except for the IdentityService (obviously). Authentication is based upon a user name/password combination or a previously determined login token. It is a best practice to only authenticate the user once per session, using a user name/password combination. The engine will instantiate a workflow context (similar to a servlet context) and returns a token that references the workflow context. This token can then be used in successive calls to the API. This prevents that with every call a new workflow context needs to be instantiated, which is a relatively expensive operation.



It is also a best practice to use identity propagation of an already logged on user, which in case of SOAP can be done by passing on a SAML token. All SOAP services (except for the IdentityService) have two different end points: one that requires a SAML token and one without. To prevent getting frustrated because of problems with authentication, be aware that when using a tool like soapUI the default end point probably is the SAML one. If you cannot use identity propagation, you will be using the TaskQueryService.authenticate operation to get the workflow context token.

A typical pattern to execute a human task, would be as follows:
  1. Requiring a token using the TaskQueryService.authenticate operation,
  2. Getting a list of tasks based upon some filter using the TaskQueryService.queryTasks operation,
  3. Acquiring (locking) a specific task for execution using the TaskService.acquireTask operation,
  4. Updating the payload of the task using the TaskService.updateTask operation,
  5. Setting the outcome (commiting) the task using the TaskService.updateOutcome operation.
Hereafter I will give an example of this 5-step pattern to execute a human task.

The addresses of the WSDL's are not too consistent, I suppose to prevent us from becoming lazy. The address of the TaskQueryService WSDL is:

http://host:port/integration/services/TaskQueryService/TaskQueryService?WSDL

The address of the TaskService WSLD is:

http://host:port/integration/services/TaskService/TaskServicePort?WSDL


Executing a Human Task Example

Step 1

To get a workflow context token, the following request would give me one for the user "cdoyle" with password "welcome1":



The response will be a <workflowContext> element with a <token> in it that can be used in successive calls.


Step 2
Now I can query tasks for the user cdoyle. Let's assume I want to query all tasks that either are assigned to the group cdoyle belongs to or explicitly have been assigned to cdoyle. I can use the TaskQueryService.queryTasks operation with the following query (the simplest I can think of):



As you can see the token has been copied into the request. To get all tasks I have set the <taskPredicateQuery> attributes startRow and endRow to 0. I could also have left these attributes out all together. The startRow and endRow attributes support paging of tasks, which can be handy in case of a custom worklist. The response is a <taskListResponse> with a list of <task> elements. Each <task> element has subelements like <title>,
<priority>, and <taskId>.


Step 3

The <taskId> uniquely identifies the task instance, and is used in the next call to the TaskService.acquire operation, to lock a task, for example:



The response of this operation will contain a <payload> element which is of type anyType and contains the human task payload as configured in the process. In my example the payload concerns a (how original!) a sales

<QuoteReqest> element:



The response also contains a <state>, <substate> and <taskId> elements, that will show that the task has been assigned and acquired:


Step 4

Now let's assume that this is the payload of a Review Quote task, and that I want execute that task by updating the quantity to 2 and setting the status from "new" to "OK".

To update the payload of the task, I use the TaskService.updateTask operation. This has a lot of attributes. I will keep it simple, meaning that I don't add attachments or comments, etc., so for me it suffices to copy and paste the complete <task> element from the response of Step 3 into the <task> element of the request:


In its response it will give the updated payload, and (among a lot of other things) it will say who did the update and when:


Step 5

To commit the task, I use the TaskService.updateOutcome operation. You will also find that this operation has a lot of attributes. I will keep it simple again, and copy and paste the complete <task> element from the response of Step 4 into the <task> element of the request of the TaskService.updateOutcome operation (left out a lot of the elements for reasons of brevity):



If you watch carefully, you will see that the <taskId> is both in the <systemAttributes> subelement of <task> as well as a separate <taskId> element of its own (at the bottom). The latter one is used to determine the task instance.

The value I entered for outcome, has to correspond with the possible outcomes I defined for the Human Task definition:



In its response this operation will give back the changed payload, plus a number of other elements, among them the <state> element that will have the value COMPLETED now:


hAPI programming!