« July 2006 |
Main
August 2006 Archives
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)
| TrackBack (0)
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)
| TrackBack (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.
 |
 |
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
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
|