Clinton Davidson's Blog
Clinton Davidson's Homepage
Clinton Davidson is the lead developer on ALIP. He has been
with Plumtree Software/BEA Systems for almost five years. During that
time, he has worked on BPM, the IDK, the JSR-168 Container and WSRP
Consumer, and Lotus Notes integration. In a previous life, he was a
graduate of the Culinary Institute of America.
Creating a Process using PAPI-WS
Posted by cdavidso on August 17, 2006 at 4:07 PM | Permalink
| Comments (5)
PAPI-WS is very useful for creating a process remotely. Consider the use case of an existing web application that now needs to create a process instance in ALBPM. The existing web application does not need to be recoded to work in ALBPM; only the steps to create a process instance need to be added. In later posts, I will show how to execute an external task remotely. In this post I will walk through the process of creating a process instance by looking at process visibility, the method signature, the appropriate settings in Studio (Process Designer) and the required code using PAPI-WS for .NET and Java.
Determining the list of processes where the current user can create an instance
Unfortunately, there is no PAPI-WS call that gives a list of processes where the current user can create an instance. A user can create a process instance if they belong to any role in the process. This is in contrast to Global Applications- the activities used to create a process instance in ALBPM-, which are only in one role. Creating a process using PAPI-WS means executing the Begin activity, which belongs to the automatic handler role and not to a user-created role. Since no user belongs to the automatic handler role, PAPI-WS looks at all roles in the process, and then checks to see if the current user belongs to any of those roles.
Method signature to create a process instance
The method createInstance takes four parameters: a session id, a process id, the argument set name, and an array of arguments. It returns an InstanceInfo Let's look at each of these in turn.
A remote session is required to do anything with PAPI-WS. This is a call that takes a name and password and returns a String sessionId. Creating a session id is documented in PAPI Web Service.
The process id is the programmatic identifier for the process. The simplest way to find the process id is to right-click the process in Studio, click properties, and the id will be listed at the top. A "/" needs to be added to the process id for it to be used as the process id parameter. See the PAPI Web Service document for more details or if you will specifying a version or organizational unit.
To get the argument set name, go to Studio, right-click the Begin activity, and choose "Argument Mapping". The default argument set name is "BeginIn". However, note that it's possible to add additional argument set names. This is valuable when this process could be created through ALBPM (in a global activity) as well as remotely. If the input arguments for the BeginIn argument set contain arguments that can't be expressed remotely, such as FuegoObjects, the alternative is to create another argument set. In this case the arguments coulc be xml, and the Fuego objects could be created from values in the xml documents in the method window of the Begin activity.
The array of arguments parameter in the createInstance method are an array of KeyValuePairs, where each key corresponds to an argument in the ArgumentMapping window of the BeginActivity, and each value corresponds to the String value of the argument. The document PAPI-WS Extensions for Fuego 5.5 also details how the argument sets and argument names can be retrieved via PAPI-WS.
The InstanceInfo object contains the instance id, the description set in the Begin Activity, and the current activity name. For an external application, the instance id could be stored to retrieve the instance later. For example, an external activity takes an instance id. The description is useful to display to the end-user that the instance has been created. The activity name is the name of the current activity, which is usually the next interactive activity for this process instance. Keep in mind that the activity name could be outdated at any time.
Sample code in Java for creating a process instance
try
{
//endpoint defined in include page
URL endpoint = new URL(WEB_SERVICE_ENDPOINT);
//basic auth username and password defined in include page
//note that this is only required for ALIP, not ALBPM
ProcessServiceServiceLocator locator = new ProcessServiceServiceLocator(BASIC_AUTH_USERNAME, BASIC_AUTH_PASSWORD);
//get the process service
fuego.papi.ws.ProcessService processService = locator.getProcessService(endpoint);
System.out.println("Created the process service");
//get a session id to make further calls
//credentials defined in include.jsp for this lab.
//credentials could also provided through a user prompt, or supplied by other means.
String sessionID = processService.createSessionWithTakeOver(PROCESS_SERVER_USERNAME, PROCESS_SERVER_PASSWORD, true);
System.out.println("Got the session ID");
//creates the instance, using the parameters from the previous page.
//note that the arguments and process name need to be hard-coded
//this could be simplified using java preferences
//Get the process ID.
//Either get the process ID (process name, not project name) in Studio,
//or get the process name via Process Administator by clicking the link under history,
//then the link under Processes,
//and finally viewing the Process Name.
String processID = "/NewEmployee";
//create the key value pair array of arguments
//here we have 4 arguments - ssn, first name, last name, and email
KeyValuePair[] keyValues = new KeyValuePair[4];
keyValues[0] = new KeyValuePair();
keyValues[0].setKey("ssn_arg");
keyValues[0].setValue(ssn);
keyValues[1] = new KeyValuePair();
keyValues[1].setKey("nameFirst_arg");
keyValues[1].setValue(nameFirst);
keyValues[2] = new KeyValuePair();
keyValues[2].setKey("nameLast_arg");
keyValues[2].setValue(nameLast);
keyValues[3] = new KeyValuePair();
keyValues[3].setKey("email_arg");
keyValues[3].setValue(email);
//argument set name. Unless you have created another argument set, the default name is "BeginIn"
String argumentSetName = "BeginIn";
//create the instance, and get back the instance info
InstanceInfo instanceInfo = processService.createInstance(sessionID, processID, argumentSetName, keyValues );
System.out.println("Created new instance");
}
catch (Throwable t)
{
t.printStackTrace();
}
Sample code in C# for creating a process instance
try
{
//get the process service
ProcessServiceService processService = new ProcessServiceService();
Console.WriteLine("Created the process service");
//get a session id to make further calls
//credentials are defined in PageBase.cs for this lab.
//credentials could also provided through a user prompt, or supplied by other means.
String sessionID = processService.createSession(PROCESS_SERVER_USERNAME, PROCESS_SERVER_PASSWORD);
Console.WriteLine("Got the session ID");
//creates the instance, using the parameters from the previous page.
//note that the arguments and process name need to be hard-coded
//this could be simplified using java preferences
//Get the process ID.
//Either get the process ID (process name, not project name) in Process Designer,
//or get the process name via Process Administator by clicking the link under history,
//then the link under Processes,
//and finally viewing the Process Name.
String processID = "/NewEmployee";;
//create the key value pair array of arguments
//here we have 4 arguments - ssn, first name, last name, and email
KeyValuePair[] keyValues = new KeyValuePair[4];
keyValues[0] = new KeyValuePair();
keyValues[0].key = "ssn_arg";
keyValues[0].value = ssn;
keyValues[1] = new KeyValuePair();
keyValues[1].key = "nameFirst_arg";
keyValues[1].value = nameFirst ;
keyValues [2] = new KeyValuePair();
keyValues [2].key = "nameLast_arg";
keyValues [2].value = nameLast;
keyValues[3] = new KeyValuePair();
keyValues[3].key = "email_arg";
keyValues[3].value = email ;
//argument set name. Unless you have created another argument set, the default name is "BeginIn"
String argumentSetName = "BeginIn";
//create the instance, and get back the instance info
InstanceInfo instanceInfo = processService.createInstance(sessionID, processID, argumentSetName, keyValues );
Console.WriteLine("Created new instance");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
Setting Basic Auth Headers with .NET for PAPI-WS
Posted by cdavidso on August 2, 2006 at 3:28 PM | Permalink
| Comments (0)
First, generate the stubs using the .NET tools. As in Java, the credentials have been copied from the file /ptprocess/1.5/tomcat/conf/tomcat-users.xml. The Web service endpoint, and the basic auth username and password were put into a base class called PageBase, but you can supply them any way that suits your needs.
Second, add the following code to the generated constructor for ProcessServiceService, and override the method GetWebRequest(Uri uri):
public ProcessServiceService()
{
//set the web service endpoint- this could also be put into a setter method
this.Url = PageBase.WEB_SERVICE_ENDPOINT;
//add the basic auth credentials
//the credentials could also be supplied in a setter method
//or in an alternate constructor
//be sure to add
//using System.Net;
//to recognize the class NetworkCredential
NetworkCredential networkCredential = new NetworkCredential(PageBase.BASIC_AUTH_USERNAME, PageBase.BASIC_AUTH_PASSWORD);
Uri uri = new Uri(this.Url);
ICredentials credentials =
networkCredential.GetCredential(uri, "Basic");
this.Credentials = credentials;
//set preauthenticate to true, or the
//credentials will not be supplied on the first request, and the //request will fail
this.PreAuthenticate = true;
}
//despite the documentation, it is not enough to set preauthenticate
//to true. You must also override the GetWebRequest method
//to add the basic auth headers or they will not be supplied
//on the first request
protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest request;
request = (HttpWebRequest)base.GetWebRequest(uri);
if (PreAuthenticate)
{
NetworkCredential networkCredentials =
Credentials.GetCredential(uri, "Basic");
if (networkCredentials != null)
{
//be sure to add
//using System.Text;
//to recognize the class UTF8Encoding
byte[] credentialBuffer = new UTF8Encoding().GetBytes(
networkCredentials.UserName + ":" +
networkCredentials.Password);
request.Headers["Authorization"] ="Basic " + Convert.ToBase64String(credentialBuffer);
}
else
{
throw new ApplicationException("No network credentials");
}
}
return request;
}
Setting Basic Auth Headers with Axis for PAPI-WS
Posted by cdavidso on August 2, 2006 at 3:14 PM | Permalink
| Comments (0)
First, generate the stubs using the Axis program WSDL2Java.
Next, open the generated file ProcessServiceServiceLocator and make the following changes:
1. Modify the constructor to take a username and password:
private java.lang.String username;
private java.lang.String password;
public ProcessServiceServiceLocator(java.lang.String username, java.lang.String password)
{
this.username = username;
this.password = password;
}
This allows you to pass in the basic auth username and password. These credentials can be found in the file /ptprocess/1.5/tomcat/conf/tomcat-users.xml. Remove the default constructor.
2. Remove the existing getProcessService methods, and keep the one with the single argument URL portAddress. This way your generated stubs will work with any url, and not just the one that Axis hard-codes when generating the file. The url should be constructed from a string similar to this:
http://<server_name>:8585/portal/webservices/ProcessService
Change the method getProcessService as follows:
public fuego.papi.ws.ProcessService getProcessService(java.net.URL portAddress) throws javax.xml.rpc.ServiceException
{
try
{
fuego.papi.ws.ProcessServiceSoapBindingStub _stub = new fuego.papi.ws.ProcessServiceSoapBindingStub(portAddress, this);
_stub.setPortName(getProcessServiceWSDDServiceName());
_stub._setProperty(javax.xml.rpc.Stub.USERNAME_PROPERTY, username);
_stub._setProperty(javax.xml.rpc.Stub.PASSWORD_PROPERTY, password);
return _stub;
}
catch (org.apache.axis.AxisFault e)
{
return null;
}
}
the only lines that are different are the _stub._setProperty lines.
Compile the classes, jar it up, and you can use this to access PAPI-WS without removing the basic authentication protection from the Process Server portal web-app. Alternatively, you can use this to set basic auth protection on the /webservices url pattern of ALBPM, and then access PAPI-WS with basic authentication.
Using PAPI-WS- the ALBPM Web Services API
Posted by cdavidso on July 18, 2006 at 9:03 AM | Permalink
| Comments (1)
PAPI-WS exposes a subset of PAPI- the ALBPM process API. Although there are only a small number of methods exposed, they are the most useful methods for calling ALBPM remotely. Among the calls are:
- Creating a process instance
- Getting a list of instances from a view
- Getting a list of instances with a filter
- Calling external methods
- Notifying a process.
I’ll cover each of these items in more detail in a later blog, but here's a brief explanation.
Creating a process instance is the same as running the Begin activity of a process programmatically. It's not the same as creating a process instance through the UI, which is a Global Activity.
Getting a list of instances from a view is analagous to going to your inbox in the Work Portal, or the ALIP Worklist portlet.
Getting a list of instances with a filter provides much of the functionality of search.
Calling external methods allows the user to run a method outside of the context of the Execution Dispatcher. This allows a user to run a method in an aspx page.
Notifying a process allows the user to notify a process through a standard wait activity or through one that allows for interruptions.
PAPI-WS Endpoint
The endpoint for PAPI-WS is http://:8585/portal/webservices/ProcessService?wsdl. Use this endpoint to generate stubs using .NET or Axis. See the .NET documentation or WSDL2Java for building stubs on the respective platforms.
If you are accessing PAPI-WS through ALIP, you will need to provide the basic authentication header. I’ll cover this in a later blog.
Additional information
See the following:
Where to find documentation and post questions for ALBPM/ALIP
Posted by cdavidso on June 27, 2006 at 1:49 PM | Permalink
| Comments (0)
After looking at a comment posted on my blog, I realized that it's not that easy to find the documentation or newsgroups for ALBSI and ALBPM. Here's the link to the documentation:
Sample listing of useful documents:
There is a whole series of newsgroups under this category. Individual newsgroups include using the various apis, email notifications, collaboration, IDK integration, and administration. There are many people subscribed to these newgroups, so response times should be reasonable.
How to access the IDK in a jsp screenflow in ALIP
Posted by cdavidso on June 23, 2006 at 10:51 AM | Permalink
| Comments (0)
Accessing the IDK in a jsp screenflow is simple; from the point of view of the portal it is just another jsp page. The page is already gatewayed as it lives in the gateway space of both the worklist portlet and the details portlet.
To get portlet properties, for example portlet preferences, add the Plumtree imports and then retrieve the IPortletRequest:
<%@ page
session="true"
import="java.util.*,
java.text.*,
fuego.portal.*,
fuego.xobject.util.XOContext,
com.plumtree.remote.portlet.*%>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<%@ taglib uri="http://fuego.com/jsp/ftl" prefix="f" %>
<%
// Setting Fuego Object Execution Context.
XOContext.setJSPContext(request.getParameter("xoContextKey"));
%>
<%
IPortletContext portletContext = PortletContextFactory.createPortletContext(request, response);
IPortletRequest portletRequest = portletContext.getRequest();
//get portlet settings values
Map portletSettings = portletRequest.getSettingCollection(SettingType.Portlet);
%>
This approach can also be used to get the image server URI, stylesheet URI, other settings collections, and user information.
A more useful case is to capture the login token and soap endpoint, so the subsequent automatic activity can connect to the IDK. For example, this code was taken from a project to create a Collab discussion. The steps to do capture the login token and soap endpoint are to (1) create a Fuego object that can store the attributes for login token and soap endpoint, (2) set these attributes in the jsp page, and then (3) use these attributes in the automatic activity. Keep in mind that the login token is only good for a few minutes; the default is five minutes, but check the setting in the worklist and details portlet for the exact time. This means that the login token can be used for the next automatic activity, but not others.
Here’s an example of a jsp page that collects the login token and soap endpoint, and sets them in attributes for a Fuego object. The referenced fuego object in the jsp page is called discussion. It starts after getting the IPortletRequest above:
<%
String loginToken = portletRequest.getLoginToken();
//need to turn url into a string to put into hidden field
String soapAPIEndpoint = portletRequest.getRemoteAPIEndpoint().toExternalForm();
%>
Then in the html, add two hidden fields to set the attributes. Note the use of f:fieldName with att and value to set the value of a field:
<!--login token-->
<input type="hidden" <f:fieldName att="discussion.loginToken"/> value="<%=loginToken%>"/>
<!--soap api endpoint-->
<input type="hidden" <f:fieldName att="discussion.soapAPIEndpoint"/> value="<%=soapAPIEndpoint%>"/>
How to view the Process Diagram in AquaLogic Interaction Process
Posted by cdavidso on June 16, 2006 at 1:42 PM | Permalink
| Comments (0)
How to view the Process Diagram
It's not always clear why the Process Diagram does not show in the details portlet in ALIP. This posting describes when the Process Diagram is displayed.
The process diagram in ALIP is the same as the process image in BPM Studio, except that the current activity has a red border and has a red flag on top. The activity with the red flag is the current activity. It's a simple way of saying "You are here". Here’s a trimmed example:
The first step to view the Process Diagram is to create a Global Activity in BPM Studio (Process Designer in ALIP).
Go to the main process, and right-click in the ‘swimlane’ of the role that will have the rights to view the Process Diagram. Generally this is a supervisory role, although it can be given to any user. Choose Add Activity - Global. Give the Activity a name, for example "Process Diagram" or "You Are Here". Click the General tab and select the "Has Instance Access" checkbox. Leave the other checkbox unselected. Click OK.
Go back to the activity, right-click and select "Main Task". For the Implementation Type, choose "Show Process Image".
In order to view the process image in ALIP, the user must have an instance created in the process, and the user must be in the role of the process image activity. That is, the user must have be in the same role as the Process Image Global Activity. Click on the description in the inbox for the appropriate process instance, and the icon to launch the process diagram will show in the details portlet.
Documenting BPM Studio Processes
Posted by cdavidso on June 12, 2006 at 11:33 AM | Permalink
| Comments (4)
I'm the lead developer on ALIP- AquaLogic Interaction Process - and this is my initial posting on ALIP. My focus is going to be on developing projects in Studio/Process Designer and deploying them in Process Server. Later on, I'll talk about BPM in general.
Before I get started, I should clarify some terms. ALIP is the product that integrates ALBPM with ALUI. ALBPM is AquaLogic Business Process Management (the former Fuego product) and ALUI is AquaLogic User Interaction, or much of what used to be known as the Plumtree Portal. BPM Studio (the ALBPM name) or Process Designer (the ALIP name) is the desktop application for designing BPM Processes.
One of the difficulties in working with processes in Studio is that it's hard to see everything in one page. The process diagram is under Processes, the Roles are under organization, the activities are listed under specific processes, and the FBL (Fuego Business Language) is listed under the structure tag. Viewing descriptions and properties means a number of additional clicks.
Process Reports
Process Reports let you see all of this information in one html page. To generate a process report, right-click on the Process and select Process Report. You will see a dialog to include Use cases, Include Implementation Source Code (which means FBL) and Include Variables. In this example, I checked everything; play with the options and see what options you need. Click OK and Studio will generate the Process Report, which is a single HTML file with a folder of images. Here's a shot of the process image and summary for a sample process:
Process Image
The process image on top displays the same way that it does in Studio. In other words, take a little time to clean it up, and don’t make it any wider than you have to. Sometimes people add notes to the process image. While these can help to explain a complicated process, they can also make the process image harder to read. Unless this is a simple process, I'd suggest putting detailed documentation in either of two places: the process documentation for end-user html documentation, and the description textbox for plain text developer documentation.
The summary section should be self-explanatory. Roles are defined using File:Organization. Activities are all the Interactive and Automatic activities defined in the process diagram. Variables are instance variables defined in the Variables tab. And Methods are the FBL language methods that generally correspond to an activity. Note that the methods are listed in sorted order but the activities are not. Each of these sections except Variables are described below.
Role Details
Clicking on an individual role gives you role details, which includes the description and the associated activities.
In this case, the description is empty, as I didn't take the time to fill it in. It’s a good idea to include descriptions for all elements that support it, so later developers can determine your intent.
Activity Details
Clicking on any activity in the process image takes you to activity details. Activity Details includes description, a link to the associated role, the activity type, and activity properties.
The properties of Abortable, Assignable, Auto-complete, User selects transition, and suspendable are set in the general category of activity properties. By default, only auto-complete is true. Also included in activity details are the conditional and unconditional transitions to other activities, and the activity tasks.
Method Details
Method details show the return type, whether the method is static, arguments, and FBL source code. Most methods have a void return type and are not static. For the Begin, End, and NotificationWait activities, arguments are defined in argument mappings. For other activities, arguments are defined on the variables tab associated with the method. Click the structure tab, select the method, and then click the variables tab to see the arguments. Source code includes the FBL code as written, including comments.
Summary
Process Reports are a good way to share information about processes- much simpler than starting up Studio and digging through the project. They are also a good way to see that a process has been well-documented.
Future Postings
While I can't commit to scheduled postings, there are a number of topics that I want to cover as they have confused developers. These include argument mapping, displaying the process image in the details portlet, using the IDK within screenflows, accessing ALIP/ALBPM from an external application, and using PAPI.
 |
 |
March 2008
| Sun |
Mon |
Tue |
Wed |
Thu |
Fri |
Sat |
| |
|
|
|
|
|
1 |
| 2 |
3 |
4 |
5 |
6 |
7 |
8 |
| 9 |
10 |
11 |
12 |
13 |
14 |
15 |
| 16 |
17 |
18 |
19 |
20 |
21 |
22 |
| 23 |
24 |
25 |
26 |
27 |
28 |
29 |
| 30 |
31 |
|
|
|
|
|
Search this blog:
Archives
August 2006
July 2006
June 2006
Categories
Product: AquaLogic BPM Suite
Recent Entries
Creating a Process using PAPI-WS
Setting Basic Auth Headers with .NET for PAPI-WS
Setting Basic Auth Headers with Axis for PAPI-WS

|