package org.switchyard.userguide; public interface MyService { public void start(String data); public void signal(String data); public void abort(String data); }
The BPM Component is a pluggable container in SwitchYard which allows a business process to be exposed as a service. One fronts their business process with a custom interface and, if desired, can easily annotate it's methods to define which should start a process, signal a process event, or abort a process.
A BPM Service is a type of Knowledge Service (the other type being a Rules Service). Thus, it is strongly suggested you familiarize yourself with the shared configuration capabilities of Knowledge Services.
To create a new BPM service in SwitchYard, you'll need the following information:
File Name : the file name that will be used to create a new, empty BPMN 2 Process definition.
Interface Type : the contract for the service being provided. BPM supports Java, WSDL, and ESB contract types.
Service Name : the name of the service your process will provide.
After clicking Finish, you will have a new service component definition for your process service and an empty BPMN process definition. The next phase in developing your BPM service is to author the BPMN 2 process definition (details outside the scope of this documentation) and then configure the BPM service component to interact with that process definition.
Interaction with a process is defined via actions on a BPM service component. Take the following service contract as an example:
package org.switchyard.userguide; public interface MyService { public void start(String data); public void signal(String data); public void abort(String data); }
Actions allow you to map an operation in the service contract to one of the following interactions with a business process:
START_PROCESS
SIGNAL_EVENT
SIGNAL_EVENT_ALL
ABORT_PROCESS_INSTANCE
Operations configured with the START_PROCESS action type will start new process instances.
When you start your process (actually, any interaction with a service whose implementation is bpm), the processInstanceId will be put into the Switchyard Context at Scope.MESSAGE, and will be fed back to your client in a binding-specific way. For soap, it will be in the form of a soap header in the soap response envelope:
<soap:Header> <bpm:processInstanceId xmlns:bpm="urn:switchyard-component-bpm:bpm:1.0">1</bpm:processInstanceId> </soap:Header>
In future process interactions, you will need to send back that same processInstanceId, so that the correlation is done properly. For soap, that means including the same soap header that was returned in the response to be sent back with subsequent requests.
If you are using persistence, the sessionId will also be available in the Context, and will need to be fed back as well. It would look the same way in the soap header as the processInstanceId does.
If you do not want to track the processInstanceId, however need to have multiple interactions with the same process instance, you can start the process with your own application-specific correlation key, and include that same correlation key for future interactions. Here is an example of including in a a soap request:
<soap:Header> <bpm:correlationKey xmlns:bpm="urn:switchyard-component-bpm:bpm:1.0">MY-APP-KEY-0123456789</bpm:correlationKey> </soap:Header>
Operations configured with the SIGNAL_EVENT operation type will have the associated process instance signaled. As above, the processInstanceId will need to have been available in the Context so the correct process instance is correlated.
There are two other pieces of information when signaling an event:
The "event id". In BPMN2 lexicon, this is known as the "signal id", but in jBPM can also be known as the "event type". This is set as the eventId in the configuration.
Note: In BPMN2, a signal looks like this: <signal id="foo" value="bar"/> In jBPM, it is the signal id that is respected, not the name. This might require you to tweak a tooling-generated id to whatever you want it called.
The "event object". This is the data representing the event itself, coming from the Message content object itself (your payload).
Operations configured with the SIGNAL_EVENT_ALL operation type will have all process instances signaled.
Operations configured with the ABORT_PROCESS_INSTANCE operation type will cause associated process instances to be aborted. As above, the processInstanceId will need to have been available in the Context so the correct process instance is correlated.
SwitchYard provides a flexible way to map data in and out service operation invocations via MVEL expressions. First, please familiarize yourself with the general Knowledge Services documentation, specifically the sections related to what Globals, Faults, Inputs and Outputs are. Next, consider the following tooling screenshot:
The above will create XML configuration like this:
<operation name="process" type="START_PROCESS"> <inputs> <input from="message.content.policy" to="Policy"/> <input from="message.content.driver" to="Driver"/> </inputs> <outputs> <output from="Policy" to="message.content"/> </outputs> <faults> <fault from="ProcessingFault" to="message.content"/> </faults> </operation>
If your process executes business rules, you can use global mappings to access data in your rules which do not trigger rule execution themselves.
For the BPM component, inputs are used to set process instance variables that can later be referenced by nodes within your process.
For you to be able to use variables inside your process, you have to declare your variable names at the process level, as well as in the Parameter Mapping (and possibly Result Mapping) of any process node that wants access to those variables. This can be done easily in the BPMN2 Eclipse tooling by using the Properties view when clicking on either the whitespace around the process, or on any of your process nodes.
Outputs are used to extract process instance variables so that they can be set in the outgoing SwitchYard Message content.
Fault mapping is similar to Output mapping, however the data represents an Exception or data that will be wrapped in an Exception.
There are two ways of consuming Services with the SwitchYard BPM component:
Invoking the BPM implementation through a gateway binding. Since the BPM component exposes a java interface fronting the business process, you can use any of the bindings provided by SwitchYard. This could be a SOAP Binding or a Camel Binding, for example. (Please refer to those sections of this guide for more information.)
Invoking other SwitchYard Services from inside a BPM process itself. To do this, you can use the SwitchYardServiceTaskHandler, which is provided out-of-the-box, and auto-registered with the runtime. To make authoring BPMN2 processes easier, SwitchYard provides a new widget for the Eclipse BPMN2 Modeler visual editor palette. Here is a screenshot from the "Help Desk" demo quickstart:
On the bottom right hand side under "Custom Task", you can see the SwitchYard Service widget. On the left hand side, you can see the various points of the business process where SwitchYard Services are being invoked. Once you have dropped a SwitchYard Service task in the main window, you can customize it via the Eclipse Properties Editor:
The following are properties you can use to configure the SwitchYard Service task (a.k.a. the "Dynamic" SwitchYard Service task):
Service Naming Properties
ServiceName: (required) The name of the SwitchYard service to invoke.
OperationName: (optional; default=use the single method name in the service interface, if there is just one) The name of the operation within the SwitchYard service to invoke.
Content I/O Properties
ParameterName: (optional; default=Parameter) The process variable which the message content will be placed in.
ResultName: (optional; default=Result) The process variable which the message content will be gotten from.
Fault-Handling Properties (see SwitchYard Service Fault Handling below)
FaultName: (optional; default=Fault) The name of the output parameter (result variable) the fault (Exception) will be stored under.
FaultEventId: (optional) The bpmn signal id ("event type" in jbpm lingo) that will be used to signal an event in the same process instance. The event object will be the fault (Exception). Please see Signaling a Process above.
FaultAction: (optional; default=null) After a fault occurs, what should be done? If null, nothing is done. If complete, the current work item (SwitchYard Service task) is completed. If abort, the current work item is aborted. If throw, an exception is thrown.
You can read a more detailed explanation of the Help Desk quickstart demo, as well as how to set up Eclipse to make use of new widget, on this wiki page.
During your process execution, the SwitchYardServiceTaskHandler class is used to handle Switchyard Service tasks. It executes service references, per the properties specified in the panel above. Pay particular attention to the list of Fault-Handling Properties. These properties define the behavior of the SwitchYardServiceTaskHandler in the case were a fault is encountered when executing the service reference. There are 3scenarios that the fault-handling covers:
"In my process flow, after the SwitchYard Service task, I would like a split gateway where I can inspect a process variable (a "flag") that can tell me that a fault occurred, so that I can diverge one way or another."
To do this, specify the FaultName property. The SwitchYardServiceTaskHandler will make the fault itself available as an output parameter of the task, so that it can be associated with a process variable, and inspected for existence in your split gateway. You must also set the FaultAction property to complete, so that the process will continue on to your split gateway!
An example bpmn2 process can be found in our JUnit test suite here: BPMServiceTests-FaultResultProcess.bpmn
"In my process flow, I have multiple places where faults could occur, and I want to have one shared path of fault-handling."
To do this, specify the FaultEventId property. This must match a signal id you specify in your bpmn2 process definition. You can then add an event node in your process that is triggered with this signal id; the flow from that event node on is your fault-handling path. The SwitchYardServiceTaskHandler will then signal the proper event with the configured id.
An example bpmn2 process can be found in our JUnit test suite here: BPMServiceTests-FaultEventrocess.bpmn
"In my process flow, I want to bubble an Exception back out to the process, so it can be handled with a boundary event."
To do this, set the FaultAction property to throw, so that an exception will be thrown.
Whether which scenario above you choose, the question remains "What next?" If you don't specify a FaultAction property, nothing is done. The work item is not completed, nor is it aborted. You can set the property to complete to complete the work item after a fault, or you can set the property to abort to abort the work item after a fault.
It is possible to invoke SwitchYard Services using the standard BPMN2 Service Task <serviceTask>. It is conceptually similar, however you will use the Service Task icon from the BPMN2 Editor palette, and configure it slightly differently:
The <serviceTask> knows to invoke SwitchYard when it has an implementation="##SwitchYard" attribute.
The ServiceName is derived from the BPMN2 interface or interfaceImplementationRef.
The OperationName is derived from the BPMN2 operation or operationImplementationRef.
The ParameterName is always called Parameter.
The ResultName is always called Result.
A Resource represents an artifact that is required by your BPM process. It could be anything you could think of, including a properties file, a Drools Rule Language file, or whatever. But it needs to be available to the BPM component's runtime for that process. The list of resources available to your process is a configurable aspect of the BPM service component.
A WorkItemHandler is a way for you to add your own code into the business process. Simply implement the org.kie.api.runtime.process.WorkItemHandler interface and add it to your BPM service component.
By default, the SwitchYardServiceTaskHandler is always added for you by the SwitchYard Maven plugin. That handler allows you to easily call out to other SwitchYard services by name within your business process. Please see the section "Consuming a BPM Service" below for more information.
A UserGroupCallback is a way for you to specify how to access user and group information. jBPM provides several implementations out of the box, including ones for DB, JAAS, Properties, LDAP and MVEL. Simply implement the org.kie.internal.task.api.UserGroupCallback interface and add it to your BPM service component.
Please see the Listeners and Loggers sections found in the Knowledge Services documentation.