一、How to call Web Service Using JBPM 5, designer
https://204.12.228.236/browse.php?u=ObFK10b3HDFCQUNPNMI9E9mVwaCq3FwkaoL99tqkn%2Bip0N%2B93A%3D%3D&b=15
wtorek, 31 lipca 2012
Service Task with web service implementation
Invocation of web services as part of business process is common and most likely because of that default implementation of Service Task in BPMN2 specification is web service. Recently (5.4) jBPM5 has gotten support for such activity.
jBPM5 web service support is based on Apache CXF dynamic client. It provides dedicated Service Task handler (that implements WorkItemHandler interface).
Worth noting is that this handler is capable of invoking both web service end points and simple Java based services as with previous ServiceTask handler (org.jbpm.bpmn2.handler.SendTaskHandler) based on the implementation attribute of service task node
web service implementation
implementation="##WebService" operationRef="_2_ServiceOperation">
java implementation
implementation="Other" >
ServiceTaskHandler can invoke web service operations in three modes:
Let's try to go through this implementation with example. We are going to build a process that will get weather forecast for given zip codes in US. So process will look like this:
This process will:
But how does it know it is web service and even more important what web service it is? This is configured as part of process definition using few dedicated constructs:
1. first of all we need to tell the engine where is our WSDL so it can be read and operations from it can be invoked - this is done with BPMN2 import:
2. next message, interface and operations must be defined:
implementationRef="Weather">
Important: make sure that implementationRef for both interface and operations point to valid service and operation in WSDL.
3. Next use defined operation in your service task and set implementation as web service (or don't specify that attribute at all so default will be taken):
operationRef="_2-2-4_ServiceOperation" implementation="##WebService" >
NOTE: Unfortunately tooling does not support this yet so the bpmn2 file needs to be edited by hand. Soon tooling will provide this as well.
Yet another important thing here is that if you plan to use request or response object of the service in your process as variables make sure that all of them implement java.io.Serializable interface so they can be properly persisted. One way to do this (used in the example) is to provide additional configuration to tell JAXB to add Serializable while generating classes from WSDL and generate classes as part of the build:
Complete source code can be found here. It comes with test cases that uses this example as well as local service that can be used to illustrate difference between sync and async modes.
This example can be executed on jbpm-console when build from master, as it already has this service task handler configured. Here is a short guide on how to do it:
1. clone jbpm master and build it with mvn clean install -DskipTests -Dfull (alternatively download latest build from build server)
2. clone jbpm-examples and build jbpm-ws-example project with mvn clean install
3. copy result of build in point 2 (jbpm-ws-sample-1.0-SNAPSHOT.jar) into jbpm-installer/dependencies
4. copy WeatherWSServiceProcess.bpmn2 into jbpm-installer/sample/evaluation/src/main/resource
5. copy all archives from jbpm-distribution into jbpm-installer/lib
6. use jbpm-installer to install jbpm into jboss AS7 - ant install.demo.noeclipse
7. start demo server - ant start.demo.noeclipse
then go to jbpm-console and run the process with name WeatherWSServiceProcess.
Have fun!
jBPM5 web service support is based on Apache CXF dynamic client. It provides dedicated Service Task handler (that implements WorkItemHandler interface).
org.jbpm.process.workitem.bpmn2.ServiceTaskHandler
Worth noting is that this handler is capable of invoking both web service end points and simple Java based services as with previous ServiceTask handler (org.jbpm.bpmn2.handler.SendTaskHandler) based on the implementation attribute of service task node
web service implementation
ServiceTaskHandler can invoke web service operations in three modes:
- synchronous (sends request and waits for response before continuing)
- asynchronous (sends request and uses callback to get response)
- one way (sends request and does not wait for any response)
Let's try to go through this implementation with example. We are going to build a process that will get weather forecast for given zip codes in US. So process will look like this:
- ask for couple of zip codes on the first human task (task is assigned to john)
- next transform result of the user task to a collection that will be used as input for multi instance service task
- then based on the input collection process will create several instances of service task to query the weather forecast service
- once all service task instances are completed it will log result to the console
- and create another human task to show the weather forecast for selected zip codes (task is assigned to john)
But how does it know it is web service and even more important what web service it is? This is configured as part of process definition using few dedicated constructs:
1. first of all we need to tell the engine where is our WSDL so it can be read and operations from it can be invoked - this is done with BPMN2 import:
2. next message, interface and operations must be defined:
implementationRef="GetCityWeatherByZIP" name="hello">
_2-2-4_InMessage
Important: make sure that implementationRef for both interface and operations point to valid service and operation in WSDL.
3. Next use defined operation in your service task and set implementation as web service (or don't specify that attribute at all so default will be taken):
........
NOTE: Unfortunately tooling does not support this yet so the bpmn2 file needs to be edited by hand. Soon tooling will provide this as well.
Yet another important thing here is that if you plan to use request or response object of the service in your process as variables make sure that all of them implement java.io.Serializable interface so they can be properly persisted. One way to do this (used in the example) is to provide additional configuration to tell JAXB to add Serializable while generating classes from WSDL and generate classes as part of the build:
- create extra binding file
- configure cxf codegen maven plugin
Complete source code can be found here. It comes with test cases that uses this example as well as local service that can be used to illustrate difference between sync and async modes.
This example can be executed on jbpm-console when build from master, as it already has this service task handler configured. Here is a short guide on how to do it:
1. clone jbpm master and build it with mvn clean install -DskipTests -Dfull (alternatively download latest build from build server)
2. clone jbpm-examples and build jbpm-ws-example project with mvn clean install
3. copy result of build in point 2 (jbpm-ws-sample-1.0-SNAPSHOT.jar) into jbpm-installer/dependencies
4. copy WeatherWSServiceProcess.bpmn2 into jbpm-installer/sample/evaluation/src/main/resource
5. copy all archives from jbpm-distribution into jbpm-installer/lib
6. use jbpm-installer to install jbpm into jboss AS7 - ant install.demo.noeclipse
7. start demo server - ant start.demo.noeclipse
then go to jbpm-console and run the process with name WeatherWSServiceProcess.
Have fun!
二、、http://duncandoyle.blogspot.com/2012/10/jbpm5-calling-webservices-from-your.html
Wednesday, October 3, 2012
jBPM5: Calling WebServices from your business processes
In one of my previous blog posts on Business Process Management (BPM) I outlined the important role that BPM plays in a Service Oriented Architecture (SOA), and how a well defined SOA is a prerequisite for successful Cloud implementations.
In this example, the process runs in a simple Java client application (the 'Simple_jBPM_Process' project), which creates the jBPM5 KnowledgeBase, containing the BPMN2 process definition, creates the StatefulKnowledgeSession, registers our custom JAX-WS WorkItemHandlers and starts the process instance. See the 'org.jboss.ddoyle.howtojboss.jbpm5webservices.Main' class for the example code.
The jBPM5 engine, part of the JBoss BRMS platform, is a highly flexible and versatile BPM engine based on open standards like BPMN2 and WS-HumanTask. This article will show how the jBPM5 platform can integrate with WebServices by utlizing the JAX-WS API.
The jBPM5 platform provides a simple, but very powerful, extension mechanism to add domain specific service nodes and their implementations to a business process. This allows us to plug our own, custom, logic into the business process runtime system. The extension mechanism is based on the jBPM5 WorkItemHandler API. The WorkItemHandler interface declares 2 methods which need to be implemented by the domain specific WorkItemHandler implementation:
-
public void executeWorkItem(WorkItem workItem, WorkItemManager workItemManager): Is called by the process engine when a service node is executed.
-
public void abortWorkItem(WorkItem workItem, WorkItemManager workItemManager): Can be implemented to signal the workitem to be aborted.
In this example we will utilize this WorkItemHandler API to implement our own custom service nodes which use the JAX-WS API to call external WebServices. This article will not cover how to define and use custom nodes in your business process editor (i.e. the JBoss BRMS BPMN2 Web editor, the JBoss Tools Eclipse BPMN2 editor, etc.). For inforrmation on how to define and use custom process nodes in your BPMN2 process, please consult:
- http://vimeo.com/29457538
- http://salaboy.com/2011/03/09/jbpm5-community-training-%E2%80%93-module-5-domain-specific-processes/
The source codes of the examples in this blogpost are available in my Github repository. The code also contains the WorktemDefinitions file which contains the definitions of the 'PaymentService' and 'JAX-WS-Dispatcher-Service' workitems. These definitions can, for example, be used in the JBoss BRMS system to add the custom service nodes to the BPMN2 web-editor palet.
The Process
The process used in this example is a simple process which calls a PaymentService to check whether a payment-type (e.g. VISA, MasterCard, etc.) is valid and which, if the payment-type is valid, calls an OrderService to place a specific order. The process contains additional ScriptTask nodes which provide debug output which is written to System.out.
The BPMN2 process definition of this specific process can be found here.
In this example, the process runs in a simple Java client application (the 'Simple_jBPM_Process' project), which creates the jBPM5 KnowledgeBase, containing the BPMN2 process definition, creates the StatefulKnowledgeSession, registers our custom JAX-WS WorkItemHandlers and starts the process instance. See the 'org.jboss.ddoyle.howtojboss.jbpm5webservices.Main' class for the example code.
WebServices
This example contains a WAR project (the 'SimpleWebServicesWeb' project) that can be directly deployed on a JBoss BRMS 5.3 platform (or EAP 5.1.x with the JBossWS-CXF WebService stack) and which contains both the implementation of the 'PaymentService' and the 'OrderService'. The WSDL files of these services can either be obtained from the project's 'src/main/resources' folder or, at runtime, via the JBossWS console at http://localhost:8080/jbossws/services.
JAX-WS
JAX-WS provides two client APIs which can be used to execute WebService calls, the Dispatch API and the Proxy API.
The Proxy API provides a Java proxy object representing the WebService endpoint to be called. The JAXB2 library is utilized to marshall and unmarshall Java objects to and from XML. This client mode can be used when one wants to operate on Java objects.
The Dispatch API is a dynamic API in which the client code which uses this API is responsible for the creation of the XML payload or even the entire SOAP message that will be sent to the WebService endpoint. This API can be used when one wants to operate on the XML message level.
In this example we will use both client modes. We will call the 'PaymentService' using a JAX-WS Proxy client and the 'OrderService' via a JAX-WS Dispatch client.
JAX-WS Proxy Client: PaymentServiceJaxWsProxyWorkItemHandler
JBoss BRMS (and any other JBoss platform for that matter) provides a utility that is able to generate the JAX-WS annotated Java code from a given WSDL file. This utility, called 'wsconsume', is located in the 'jboss-as/bin' directory of your JBoss BRMS (or EAP) platform. The utility can be used as follows: ./wsconsume.sh -kn {WSDL-file}. This will generate the JAX-WS annotated client and server code which can be used to both implement the webservice provider and a webservice consumer. Both the 'Simple_jBPM_Process' (consumer) and the 'SimpleWebServicesWeb' (provider) contain the JAX-WS code generated from the 'PaymentService' and 'OrderService' WSDL files.
The 'PaymentServiceJaxWsProxyWorkItemHandler' uses the generated JAX-WS Proxy client to call the PaymentService. As can be seen from the code, the WorkItemHandler is, because it directly uses the generated PaymentService proxy classes, tightly coupled to the PaymentService. I.e. This WorkItemHandler implementation is specifically created to call a PaymentService WebService. In general, a WorkItemHandler which uses a JAX-WS Proxy client can only be used to call that specific service. This implies that one has to define and create a WorkItemHandler per service, and thus a domain specific process node per service.
The jBPM5 WorkItemHandler API provides the ability to pass parameters from the jBPM5 process instance to the WorkItemHandler via a parameter Map. In the jBPM5 BPMN2 process definition, a mapping needs to be defined on the 'PaymentService' node which maps the process instance data onto the parameters required by the WorkItemHandler.
In the case of the 'PaymentServiceJaxWsProxyWorkItemHandler', 2 parameters can (must) be passed to the WorkItemHandler:
The 'endpointAddress' parameter allows us to configure the actual location of the PaymentService endpoint. This makes it possible to use the same WorkItemHandler to point to different endpoint locations of the PaymentService, which is specifically useful when one has to deploy the process in multiple environments (i.e. Development, Test, Production).
In the case of the 'PaymentServiceJaxWsProxyWorkItemHandler', 2 parameters can (must) be passed to the WorkItemHandler:
- input: a String object containing the input value for the PaymentService.
- endpointAddress: the URL of the location of the PaymentService.
The service response data is returned to the process instance via the 'paymentServiceResponse' parameter in the returned parameter Map. This response can then be mapped back onto a process instance variable.
JAX-WS Dispatch Client: JaxWsDispatcherWorkItemHandler
The 'JaxWsDispatcherWorkItemHandler' uses the JAX-WS Dispatch API to, in this process definition, call the OrderService. The JAX-WS Dispatch API allows us to work on XML structures directly. The responsibility of providing the correct XML SOAP-message payload (or the entire SOAP-message itself, depending on whether the Dispatch client is used in PAYLOAD or MESSAGE mode) lies now with the code that uses the Dispatch API.
In this example we've tried to make this WorkItemHandler as generic as possible, so it can be used to call any webservice and can be reused in various projects. This is done by parameterizing the name and location of the service to be called, as well as by providing a simple 'injection' mechanism to inject the RequestMapper and ResponseMapper objects responsible for marshalling and unmarshalling the XML payload from and to jBPM5 WorkItemHandler parameters (which are passed via the WorkItemHandler parameter Map).
The WorkItemHandler requires the following parameters to be passed by the process instance:
-
serviceNamespace: the namespace of the service to be called. I.e. The namespace defined in the services' WSDL file.
-
serviceName: The name of the service as defined in the services' WSDL file.
-
portTypeNamespace: The namespace of the PortType.
-
portTypeName: The name of the PortType.
-
soapAction: The soapAction value of the service operation to be called.
-
endpointAddress: The URL of the service endpoint.
-
requestMapper: The name of the request-mapper which will be used to lookup a RequestMapper instance via the 'RequestMapperFactory'.
- responseMapper: The name of the response-mapper which will be used to lookup a ResponseMapper instance via the 'ResponseMapperFactory'.
- input: The input data for the WebService call.
The service response data is returned to the process instance via the 'response' parameter in the returned parameter Map.
These parameters make this WorkItemHandler very generic. One can call different services, inject specific RequestMappers and ResponseMappers, etc. The picture below shows how the mapping of jBPM5 process instance data to WorkItemHandler parameters is configured in the JBoss BRMS BPMN2 web editor:
If required, the WorkItemHandler can be extended to support additional WS-* features like WS-Security, WS-Addressing, etc.
Running the example.
If required, the WorkItemHandler can be extended to support additional WS-* features like WS-Security, WS-Addressing, etc.
Running the example.
To run the example, first the project containing the OrderService and PaymentService implementations needs to be build using Maven. To do this, execute the command 'mvn clean install' in the 'SimpleWebServicesWeb' directory. This will build the WAR file and add it to your local Maven repository. Deploy this WAR file on a JBoss BRMS 5.3 platform (or any JBoss platform with a JBossWS-CXF WebServices stack) of which the HTTP connector is bound to 'localhost:8080'. The WSDL files of the WebServices can now be accessed at:
-
http://localhost:8080/SimpleWebServicesWeb/PaymentService?wsdl
-
http://localhost:8080/SimpleWebServicesWeb/OrderService?wsdl
Next, build the 'Simple_jBPM_Process' client project by again executing 'mvn clean install' in the 'Simple_jBPM_Process' directory. This will produce a JAR file which contains all the jBPM5 and Drools dependencies required to run the process instance.
To run the client, simply execute the command 'java -jar Simple_jBPM_Process-0.0.1-SNAPSHOT.jar JBoss_T-Shirt VISA' from a terminal. If everything exectutes correctly, this will produce the following output:
Loading StatefulKnowledgeSession.
Starting Process Instance.
Payment type: VISA
PaymentService response: VALID
Payment approved!
Oct 4, 2012 12:39:43 AM org.jboss.ddoyle.howtojboss.jbpm5webservices.workitemhandlers.JaxWsDispatcherWorkItemHandler executeWorkItem
INFO: Calling Service: http://impl.orderservice.howtojboss.ddoyle.jboss.org/:SimpleOrderServiceService
Oct 4, 2012 12:39:43 AM org.jboss.ddoyle.howtojboss.jbpm5webservices.workitemhandlers.JaxWsDispatcherWorkItemHandler executeWorkItem
INFO: Received response from Service: http://impl.orderservice.howtojboss.ddoyle.jboss.org/:SimpleOrderServiceService
Order 'JBoss_T-Shirt' submitted successfully
Finished Process Instance with id: 1
If another payment-type then VISA is entered, the process will show the following output.
Loading StatefulKnowledgeSession.
Starting Process Instance.
Payment type: MasterCard
PaymentService response: INVALID
Payment not approved. Order cancelled.
Finished Process Instance with id: 1
Starting Process Instance.
Payment type: MasterCard
PaymentService response: INVALID
Payment not approved. Order cancelled.
Finished Process Instance with id: 1
Conclusion
jBPM5 is a highly versatile and flexible Business Process Management platform which can be easily extended, customized and integrated with a vast array of external systems. In this example we combined the JAX-WS API and the jBPM5 WorkItemHandler API to integrate WebServices with our business processes. The WorkItemHandler API is a simple, yet powerful, construct that can be used to integrate business processes with almost any (external) system, as long as that system provides a Java client API (or as long as a Java client can be written for it). This implies that we can use the same mechanism to, from our business process, call RESTful services, send JMS messages to message queues (e.g. JBoss HornetQ), etc. As such, the jBPM5 platform can be easily integrated in almost any IT landscape.