 | Level: Intermediate Daniel Lee (LEED@uk.ibm.com), Software Development Engineer,
IBM
Lakshmi Shankar (shankarl@uk.ibm.com), Development Team Lead,
IBM
30 Jul 2007 This is the final article in our series exploring portlet development. As you'll recall, Part 3 of this series showed you how to install and integrate WebSphere Portal Server with WebSphere Process Server. This article shows you how to write, deploy, and run human task portlets that interact with business processes. You'll also learn how to enable security when multiple users are involved. This article also provides a useful look-up table that compares the various user interface options, a best practices guide, and hints and tips that we hope will make your life a little bit easier in your quest to develop business process applications.
Introduction
In this series, you developed a business process to read and update customer data. You designed your own custom Java™ Server Pages (JSPs) to edit and approve changes to a customer's details. Now that you've set up a portal server using IBM® WebSphere® Portal Server with WebSphere Process Server, you can write portlets to gain complete control over the page layout when updating a customer's details and beginning the process (previously performed manually in Business Process Choreographer Explorer).
In this article, you will write portlets for two types of human tasks: Participating and Originating. A Participating Portlet will appear on the task list in
My Tasks and requires human intervention to progress the process workflow. An Originating Portlet begins the workflow process. If you would like to review Parts 1, 2, and 3 of this series, see Resources
Writing human task portlets using the portlet service
This article explains how to produce three portlets: the first two are going to be Participating Portlet versions of the customized JSPs that you previously plugged into the Business Process Choreographer Explorer: one to edit a person's details and another to approve or reject the changes. You will use the third Originating Portlet to start an instance of the business process. Before now, you didn't have a Java Server Page (JSP) equivalent of this and just used the Business Process Choreographer Explorer to initiate the business process. This gives you the ability to demonstrate more of the Task API.
EditPerson and ApproveChanges Portlets
Although these two portlets have different user interfaces, they interact with the Task UI Manager and the Task API in much the same way. The source code for both portlets is provided, but let's look at the EditPerson Portlet as an example. The UI is basically the same as what we developed using JSPs, but implemented as portlets. Here is what the EditPerson Portlet looks like:
Figure 1. EditPerson detail portlet
Provided with Portal is the "My Tasks" Portlet, which is the Portal analogue of the "My Tasks" view we had in the Business Process Choreographer Explorer, and once again shows the list of tasks for the current user.
Figure 2. My Tasks portlet
You can begin by selecting the task(s) you want to work on and click on the Claim button:
Figure 3. Claiming tasks through My Tasks portlet
After you claim the task, the task name changes to a link. Click on the link to allow the user to complete the task by invoking the custom portlet as defined in the business process. When you claim a task, the My Tasks Portlet takes you to the page defined here that should contain our task processing Portlet. When the Portlet is invoked, it needs to get hold of both the Task UI Manager Portlet service that will be used to deal with user interface aspects of process interaction, and the HumanTaskManagerDelegate. The HumanTaskManagerDelegate forms part of the WebSphere Process Server Task API and is what the Portlet will later use to interact with the running process. A Portlet service is provided to help find this. See Listing 1.
Listing 1. Includes the code from the EditPerson Portlet's init method
First, the Portlet looks up the TaskUIManager Portlet service's home, and then uses this to get the service itself storing the reference in the class scoped instance variable taskUIManager. Next, it uses the same procedure to lookup and create the HumanTaskManagerDelegeFactoryService from its home, and from the factory get the HumanTaskManagerDelegate itself, to be stored as taskManager.
Once the My Tasks Portlet has invoked our EditPerson Portlet, it needs to retrieve the input message, which in the case of our process is the "Person" to be edited. We'll get this using the Task API, but first we need to get hold of the Task ID that identifies the task to process. The "My Tasks" Portlet passes this to our Portlet by invoking an action called: "com.ibm.portal.pagecontext.receive" |
Remember that actions are passed through a request parameter called: "com.ibm.portal.action".
Here's the code from the Portlet's processAction method that will be invoked by Portal to process the action:
Listing 2. Code from the Portlet's processAction method
String specialAction = request.getParameter("com.ibm.portal.action");
if (specialAction != null && specialAction.equals("com.ibm.portal.pagecontext.receive")) {
// This indicates context was passed to the launched page
java.util.Map contextMap = (java.util.Map)
request.getAttribute("com.ibm.portal.pagecontext.context");
// Read the information we need
String taskID = (String) contextMap.get("TaskID");
TaskUIHandle taskUIHandle = (TaskUIHandle) contextMap.get("TaskUIHandle");
ObjectID returnPageID = (ObjectID) contextMap.get("ReturnPageID");
// Store the information received in the session
portletSession.setAttribute(SESSION_TASKID, taskID);
portletSession.setAttribute(SESSION_TASKUIHANDLE, taskUIHandle);
portletSession.setAttribute(SESSION_RETURNPAGEID, returnPageID);
return;
}
|
First, you check what the Portlet action is looking for, the action name from the My Tasks Portlet. On finding this, the My Tasks Portlet will also have added a request attribute called, that is a map containing all the information needed to interact with the process. From the map, you retrieve three pieces of information and store these in the session to use later in the Portlet:
-
TaskID. The unique identifier of the task (that is, workflow step) this Portlet needs to process.
-
TaskUIHandle. Identifier will be passed into the Task UI Manager to close down the task user interface and indicate that this Portlet has finished processing.
-
ReturnPageID. ID of the Portal page to return to once processing is complete.
Finally, the Portlet's doView method is called, and you get to retrieve the input message from the Task UI and actually render the output to the user. This is where you use the TaskID obtained in the previous step to query the input message from the HumanTaskManagerDelegate. Here's the code from the doView method:
Listing 3. Code from the doView method
//Obtain the TaskID of the current task
String taskID = (String) session.getAttribute(SESSION_TASKID);
//Read the input message
DataObject message = (DataObject)
(((ClientObjectWrapper) taskManager.getInputMessage(taskID)).getObject());
sessionBean.setPersonID(message.getString("/person/personID"));
sessionBean.setPersonName(message.getString("/person/personName"));
... |
Once the user has completed editing the data, you need to use the Task API once more to finish processing:
Listing 4. Task API to finish processing
//Create the output object & set the new Person values in it
ClientObjectWrapper cow = (ClientObjectWrapper) taskManager.createOutputMessage(taskID);
DataObject message = (DataObject) cow.getObject();
message.createDataObject( "updatePerson" );
message.setString("/updatePerson/personID", request.getParameter(PERSON_ID));
message.setString("/updatePerson/personName", request.getParameter(PERSON_NAME));
message.setString("/updatePerson/gender", request.getParameter(PERSON_GENDER));
message.setString("/updatePerson/dob", request.getParameter(PERSON_DOB));
//Set the output message & mark the task complete using the Task API
taskManager.setOutputMessage(taskID, cow);
taskManager.complete(taskID);
//Shut down the process UI and set the next page to render using
//the IDs stored in processAction()
TaskUIHandle taskUIHandle =
(TaskUIHandle) portletSession.getAttribute(SESSION_TASKUIHANDLE);
ObjectID returnPageID = (ObjectID) portletSession.getAttribute(SESSION_RETURNPAGEID);
taskUIManager.closeDynamicUI(request, response, taskUIHandle);
taskUIManager.setPage(request, response, returnPageID); |
First, create the object message, which is an updatePerson object, as defined in the business process. After setting the edited values in this object, the HumanTaskManagerDelegate is used to set the output message and mark the task "complete."
That's the end of this Portlet's interaction with the Task API, and WebSphere Process Server will now move the process onto its next step, which in our case is the approval human task. All that's left to do is use the Task UI Manager API to move on from our Portlet.
You need to set the next page to render using the returnPageID that was supplied by the "My Tasks" Portlet back at the beginning. This will actually be set so that the user gets taken back to their task list after this Portlet.
From this example, you can see that although there is a little more work to do, we have much more control when it comes to interacting with WebSphere Process Server when compared to the JSPs we plugged into the Business Process Choreographer Explorer. When using the JSPs, in addition to having less user interface flexibility, all you saw were the task input and output messages passed in through request attributes.
As well as the most common interactions we've just seen, the Task API supports a full set of operations for task processing from your portlets. Other capabilities include being able to manage tasks (start, stop, suspend, resume, transfer), get and return faults from tasks, get full information on the task definition from: claim, un-claim and complete tasks, query users that can perform tasks, query user interface settings, manage escalations, and even run custom queries against the task database. For full details, see the Javadoc for the WebSphere Process Server Task API (see Resources).
Process initiation Portlet
Until now, we have been using Business Process Choreographer Explorer to kick-off an instance of our business process. Though this may be appropriate for testing, in a production environment its better to provide a UI for this (and hide this instantiation process from the user).
Therefore when using portlets, you can create a Process Initiation Portlet (shown below in Figure 4) to launch an instance of our process.
Figure 4. Process initiation portlet
The Process Initiation Portlet takes the person ID, entered by the Sales Representative and passes it to method within this portlet class. You can use this class to create several static variables to hold the process name, the host name (of the machine which hosts the business process), and finally the connecting port.
When control passes to the method, you first create the process (using the BusinessFlowManager class) and use this class to get a process template for the business process as shown below:
Listing 5. Create the process using the BusinessFlow Manager class
// Create the process in the local scope
try {
bfm = _bfmh.create();
} catch (CreateException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
// Get process template
ProcessTemplateData templateData = bfm
.getProcessTemplate(PROCESS_NAME);
|
Now, create the necessary input message to get a data object, and set the person ID in the data object. This approach mirrors what happens under the covers when we use the Business Process Choreographer Explorer. Having created this data object and the input messages, you can finally instantiate the business process by calling the method on the BusinessFlowManager object, as shown below.
Listing 6. Instantiate the business process by calling the initiate() method
// Create message
ClientObjectWrapper cow = bfm.createMessage(templateData.getID(),
strInputTypeName);
// Set input message
if (cow.getObject() != null
&& (cow.getObject() instanceof DataObject)) {
DataObject bdo = (DataObject) cow.getObject();
setInputDataObject(bdo, personID);
}
// Initiate process
PIID objPIID = bfm.initiate(templateData.getName(), PROCESS_NAME
+ "-" + System.currentTimeMillis(), cow); |
To verify that our business process has been successfully instantiated, you can go to the process instances in Business Process Choreographer Explorer and check its presence.
Integrating the portlets into the process
Open the human task definitions for both the ChangePersonDetails and ApproveChanges steps and add the Portal client in the "Client settings" section. In the properties for the Portal client, you need to enter a unique name and set the type to "Page definition". Here are the settings for the ChangePersonDetails human task.
Figure 5. Setting ChangePerson Details human task through Portal client settings
Deploying the portlets
Before getting into details about the portlets, let us briefly discuss deployment. You can deploy and run the portlets in four easy steps:
- Install the portlets. Log in to the WebSphere Portal Administration console. Choose Administration => Portlet Management => Web Modules => Install. Install all three Portlets as WAR files.
- Create the new task page definitions for each task processing Portlet. This allows you to claim each Portlet as a task from a list. Choose Administration => Portlet User Interface => Manage Pages => Task Page Definitions => New Page.
- Attach the Portlet to the task page. Go to the task page, click on edit page layout, and add the relevant task processing Portlet. The initiation portlet is required to kick start the process and can be added to an existing page from My Portal.
- Finally, define custom unique names for each task page. This allows the process to know which page it must hand off the task to. Choose Administration => Portlet Settings => Custom Unique Names. Go to the task page, click on edit unique name for page and enter the unique name defined in the process in the previous section.
Enabling security and having multiple users
To add the final touch to our complete working business process we must look at more advanced features of human tasks and, particularly, user specific tasks.
When we were using the Business Process Choreographer Explorer, we just used our Web browser to navigate directly to the page and look at the task list. With Portal, though, we have to authenticate as a particular user, either the default wpsadmin administrator, or as another registered user created post-installation. Something actually happened under the covers when Portal was installed: security was enabled in the application server. If you actually go back to the Business Process Choreographer Explorer now you'll notice that you get prompted to login. So, this means that within the task processing user interface (be it plain Business Process Choreographer Explorer, JSPs, or Portlets) we now know who the user is.
WebSphere Process Server allows this to be exploited to give a user-specific task view. In the case of the UpdatePersonDetails process, what we really want is to have different users, or rather different roles perform the editing and approval steps. For example, anybody in the sales team can update a person's details but only managers can approve the changes. Then, a member of the sales team would see a task list like this:
Figure 7. Shows task list through the My Tasks portlet for an admin team member
While a manager would see something more like this:
Figure 8. Shows task list through the My Tasks portlet for an administrator
Although some operations to support security and permissions are provided by the Task API, you don't actually have to worry about them most of the time as the task list will only display and allow claims for tasks appropriate to the current user and their role(s). You can configure this behavior in the receiver settings section of the human task definition:
Figure 9. Configuring tasks appropriate to roles through the Receiver settings panel
Five different roles are available to represent the different ways a user could need to interact with the task:
- Administrator
- Potential instance creator
- Potential owner
- Editor
- Reader
For each of these roles, you can specify what users or groups are permitted to fulfill that role. Note that the Potential owner role is "potential", because its just talking about how eligible that person is to see a task and claim it. They don't become an actual instance owner until they claim the task. In the above example, the properties for the Potential Owner role (which is the only one defined), specify that Everyone can fulfill that role:
Figure 10. "Potential Owner" panel for the staff role
To make sure that only managers can approve changes, you're going to change the potential owner role's verb to "Group Members", and set the parameters so that only members of the SeniorPersonAdmins group are permitted to claim this task:
Figure 11. "Potential Owner" panel for the senior administrator's role
You need to create the SeniorPersonAdmins group in Portal and assign some managers to it. Check the Information Center (see Resources) for details of how to do this using the "Users and Groups" management Portlet in administration. You also need to create a PersonAdmins group and add some group of sales members, then modify the Changepersondetails human task similarly, so that only members of that group can be potential instance owners.
Table 1. Comparison of UI options
|
Using Business Process Choreographer Explorer's UI
| Using custom JSPs | Using Portlets |
|---|
|
Ease of integration with WebSphere Process Server
|
Very good
|
Very good
|
Very good
Requires Portal server.
| |
Time taken for development
|
Straight forward
|
Involves knowledge of JSPs.
|
Involves knowledge of portlet development.
Needs extensive testing and integration work with the process.
| |
Lead time for deployment
|
Develop and deploy process.
|
Develop and deploy process and JSPs.
|
Develop and deploy process as well as deploy and set up portlets.
| |
Look and feel
|
To be mainly used as a testing framework and not for production use.
|
Gives a limited look and feel.
|
Gives the most professional look & feel (more control over the process).
| |
Richness of functionality
|
None
|
Restricted to JSP tags
|
Portlets can be embellished to suit the business requirements.
|
Best practices
-
Use JSP Standard Tag Library (JSTL). It simplifies Web development by providing a set of standard tags that are commonly used for presentation scripting and supports the idea of reusable components.
-
Use XPATH to access parts of the process messages when creating your customized JSPs. It is a flexible expression language that gives quick access to structured data elements simplifying Web development.
-
Use Portlet helper classes. Although, this article shows all of the Portlet code for this scenario, it is also possible to use helper classes that encapsulate common code used for process initiation and task processing simplifying portlet development. Process messages are stored in session attributes and map interfaces are provided for these messages to get/set message parts.
-
Separate data processing from process choreography. Although you can do some in-process function using Java snippets, try to focus on the coordination and flow aspects of your process in WebSphere Process Server, and use it to compose other services (human or automated) that actually modify or act on your data. In this way you'll end up with more maintainable processes and services you reuse elsewhere in your Services Orientated Architecture (SOA).
-
Separate display and controller logic in your portlets. Try to keep the flow and control logic of your portlets in the portlet classes and dedicate your JSPs to markup generation (that is, the display aspect of your portlet). The portlets will be easier to maintain and to extend in the future if, for example, you want to add support for another markup language such as WML
Hints and tips
- Make use of the remote debugger in the Rational development tools such as Rational Application Developer (RAD). This lets you connect to your Portal application server and step through your portlet code, all remotely!
- Create a new "Remote Java application" debug configuration in your Rational development tool.
- Select the Portlet project you want to debug (this allows the debugger to find the source code).
- Enter the remote debug port, which you can find from the WebSphere Application Server administration console.
- Go to Servers => WebSphere_Portal, then find 'debugging service' under the additional properties section, and write down the value of 'JVM debug port (the default is 7777).
- Don't forget to include the Business Process Application jar file in the runtime classpath of the Portlets as well as task137650.jar and bpe137650.jar that contain the EJB stubs required for remote communication. Both 137650 jar files can be located under wps_root/ProcessChoreographer/client.
- Right-click on the /Web-Content/WEB-INF/lib folder of the Portlet project.
- Select Import from the menu.
- Choose the jar file.
- Click Finish.
- Other jars are provided at runtime by the Portal server but need to be referenced as external jars in the Java Build Path of the Portal project to compile the code. The following jar files are required for the task processing portlets: wp.processintegration.jar located under wp_root/shared/app and taskapi.jar located under wps_root/lib and for the initiation portlet: bpeapi.jar located under wps_root/ProcessChoreographer/client.
- Right-click on the Portlet project and select Properties from the menu. Choose Select Java Build Path => Libraries tab.
- Click Add External Jars.
- Choose the appropriate jar files.
- Click Finish.
Conclusion
This article series examined the array of user interface options available to business process developers when developing human task centric workflows. The hands-on series demonstrated WebSphere Process Server's human task management capabilities and examined the various user interface options from basic JSPs to the more complex Portal-based interfaces. Finally, you examined the more complex aspects of integrating WebSphere Process Server with WebSphere Portal Server and the best practices that developers need to follow to successfully deploy applications.
The authors hope that business process developers have not only found the articles useful but also have helped developers build successful human task-centric business process for their applications.
Downloads | Description | Name | Size | Download method |
|---|
| ApprovePerson Portlet code | ApprovePersonChanges.zip | 786KB | HTTP |
|---|
| Initiation Portlet Code | dwArticle.zip | 516KB | HTTP |
|---|
| EditPerson Portlet code | EditPerson.zip | 597KB | HTTP |
|---|
| UpdatePersonDetails Business Process code | UpdatePersonDetails.zip | 20KB | HTTP |
|---|
| UpdatePerson JSPs code | UpdatePerson.zip | 6KB | HTTP |
|---|
Resources
About the authors  | |  | Daniel Lee is a Development Software Engineer in IBM Hursley Labs, UK. He has worked with WebSphere Voice Technologies, WebSphere Platform Messaging, and Information Management. Daniel is currently working on WebSphere Message Broker. |
 | 
|  | Lakshmi Shankar is a Software Engineer in IBM Hursley Labs, UK. He has worked for IBM for more than three years and has a broad range of experience, having worked in Java performance, test,
and development within Hursley Labs. Until recently he was the Class Loading component owner for IBM's Java technology. He is now a developer working as part of the Information Management
team. |
Rate this page
|  |