Efficient collaboration in the workplace contributes greatly to a company's success. But knowledge sharing and information are often lost when people cannot collaborate effectively, either within the same department or across departments. This results in dissatisfied customers and eventually leads to loss of revenue.
Today, most enterprise content management solutions provide a means for information to flow seamlessly to the intended recipient. The key to a successful business practice in a highly collaborative environment is the ability to route information, documents, and memos in a timely manner to users or groups of users holding different roles.
Workflow is an integral part of the IBM Enterprise Content Management solution. And there are different flavors of workflow available. IBM DB2® Content Manager® offers an integrated workflow solution, namely, built-in document routing. For more complex environments, customers can opt for WebSphere® MQ Workflow. This series of three articles will bring you a deeper understanding of IBM DB2 Content Manager document routing. They also provide a comparison between IBM DB2 Content Manager document routing and WebSphere MQ Workflow to help you better understand the differences and capabilities of each. The series of three articles are broken down as follows:
- IBM DB2 Content Manager document routing, Part 1: A guided tour to process modeling
- Introduction to IBM DB2 Content Manager document routing
- Capabilities of IBM DB2 Content Manager document routing
- What is new in IBM DB2 Content Manager document routing
- Case Study - Claim Process
- Implementation - Claim Process
- Table of Comparisons - WebSphere MQ Workflow vs IBM DB2 Content Manager document routing
-
IBM DB2 Content Manager document routing, Part 2: A guided tour to API usage
Using the same case study, this article demonstrates the usage of APIs for solution development. -
IBM DB2 Content Manager document routing, Part 3: A guided tour to client usage
Then experience the fruits of your labor by actually using the workflow defined in the same case study. The following client applications are considered in this article:
- eClient - Web based client
- pClient - Windows based client
- CM Portlet - Portlet based client
Overview of the IBM DB2 Content Manager document routing API
Part 1 of this series discussed the capabilities of process modeling in DB2 Content Manager document routing. Much of the process modeling can be carried out through the graphical process builder in the System Administration Client. For client-related document routing tasks, a runtime API is provided for customers who wish to customize their applications. Though the default DB2 Content Manager Windows Client, eClient, and portlet exercise the runtime API, there are times when customers choose to develop their own client from scratch. This article, however, touches on the fundamentals of the document routing runtime API without getting into the very nitty-gritty aspect of it. You can use the walkthrough presented in the next section to jump-start a customized project.
We will briefly discuss the different classes and their main functions (refer to Resources section for the complete list)
DKDocRoutingServiceICM- This class provides the methods for routing and accessing workpackages and container data through a process. For example: start, terminate, continue, suspend, resume, listWorkPackages, and setWorkPackageContainerData.DKDocRoutingServiceMgmtICM- This class provides the methods to manage the document routing definition classes:DKProcessICM,DKWorkNodeICM,DKWorkListICM,DKWorkFlowActionICM, andDKWorkFlowActionListICM.DKProcessICM- This class represents a process definition, which contains the process diagram and route list of the process.DKWorkNodeICM- This class represents a work node definition which details the expected or applicable tasks (such as workflow action list and library server exit) to perform at that particular step in a process.DKWorkPackageICM- This class represents a work package for a routing task. It contains a persistent identifier for the document being routed, and information on the routing state (such as process name, worknode name, and completion time).DKWorkListICM- This class represents a filtered view (based on criteria such as worknode and priority) for a collection of workpackages.DKWorkFlowActionListICM- This class contains a collection of workflow actions. This enables a client application to display applicable workflow actions at a worknode.DKWorkFlowActionICM- This class defines a workflow action that can be a dynamic linking library (DLL), an executable, a Java class file, and so on. This enables a client application to execute its own operation.
In order to run the sample code provided in this article, you must:
- Build the Claim Scenario from Part 1.
- Set up a proper environment to run the code.
- Windows® - Run cmbenv81.bat under the %IBMCMROOT%\BIN directory
IBM DB2 Content Manager Document Routing custom code walkthrough
This section shows you how Content Manager document routing can be used to accomplish various client tasks. The focus is on API calling with explanations given along the way. You can download the complete sample code from the Download section.
The sample program is written to exercise the simple auto claim process defined in the previous article, "IBM DB2 Content Manager document routing, Part 1: A guided tour to process modeling". The process diagram is shown in Figure 1 as a reference.
Figure 1. A sample claim process workflow
Connect to the Content Manager datastore.
// Connect to CM
dsICM = new DKDatastoreICM();
dsICM.connect(db,userid,pw,"SCHEMA=icmadmin");
System.out.println("datastore connected db " + db + " userid " + userid );
|
Create a folder named XYZClaimFolder.
// Create a folder XYZClaimFolder
ddo = dsICM.createDDO("XYZ_ClaimFolder", DKConstant.DK_CM_FOLDER);
|
The generateClaimAmount method computes the claim amount based on two random numbers R1 and R2, where 0.0 < = R1, R2 < = 1.0
- The first random number (R1) determines if the claim amount is less than $500 or greater than $500.
- If less than $500, the claim amount is set to R2 * $500.
- If larger than or equal to $500, the claim amount is set to $500 + R2 * $500.
private static double generateClaimAmount() {
double randomNumber1 = Math.random();
double randomNumber2 = Math.random();
double claim_amount = 0;
if (randomNumber1 >= 0.5) {
claim_amount = 500 + Math.round(randomNumber2 * 500);
} else {
claim_amount = Math.round(randomNumber2 * 500);
}
return claim_amount;
|
Set the CLAIM_AMOUNT and XYZ_ClaimNumber attributes of the folder, and add the folder to the persistent datastore. The value of CLAIM_AMOUNT is set to the claim amount generated through the generateClaimAmount() method. The value of XYZ_ClaimNumber is set to an arbitrary string "2-123456".
1 claim_amount = generateClaimAmount();
System.out.println("*** generated claim amount = " + claim_amount);
2 ddoFolder.setData((short)ddoFolder.dataId("CLAIM_AMOUNT"), new Double(claim_amount));
3 ddoFolder.setData((short)ddoFolder.dataId("XYZ_ClaimNumber"), new String("2-123456"));
4 ddoFolder.add();
|
In this example:
- Calculates the claim amount based on two random numbers (see "Calculating the claim amount" above for more information).
- Sets the claim amount.
- Sets the claim number.
- Adds the folder to the persistent datastore.
Creating a routing service object
Obtain a routing service object.
System.out.println("Creating Routing Service Object");
1 DKDocRoutingServiceICM routingService = new DKDocRoutingServiceICM(dsICM);
System.out.println("Created Routing Service Object");
|
In this example:
- Creates a DKDocRoutingServiceICM object.
Clean up all workpackages. This step is to make sure that there are no running processes.
System.out.println("Deleting all workpackages...");
1 DKSequentialCollection coll = (DKSequentialCollection)routingService.listWorkPackages("AllWorklist", "");
dkIterator iter = null;
if (coll != null) {
2 iter = coll.createIterator();
while (iter.more()) {
DKWorkPackageICM wp = (DKWorkPackageICM)iter.next();
3 routingService.terminateProcess(wp.getPidString());
}
}
System.out.println ("All workpackages were deleted");
|
In this example:
- Creates a collection.
- Creates an iterator to loop through.
- Terminates the process.
Start the SimpleAutoClaimProcess process with the folder.
String workPackagePidStr = routingService.startProcess(pn,
ddoFolder.getPidObject().pidString(),
100,
userid,
null);
System.out.println("Started an instance of process "
+ pn
+ " Workpackage PID ="
+ workPackagePidStr);
|
Prior to this, the folder is empty.
// Add documents into the folder
1 addItemsToFolder(dsICM, ddoFolder);
System.out.println("*** Documents were added into the folder");
|
In this example:
- Calls the method
addItemsToFolderto add two documents into the folder. TheaddItemsToFolderwrapper code can be found insampleDocRouting.java.
Query the AllWorklist worklist and locate the workpackage at the "SubmitClaim" worknode.
// at the SubmitClaim worknode
coll = null;
iter = null;
System.out.println("-------- Calling listWorkPackages --------");
1 coll = (DKSequentialCollection)routingService.listWorkPackages("AllWorklist", "");
if (coll != null) {
iter = coll.createIterator();
while (iter.more()) {
DKWorkPackageICM wp = (DKWorkPackageICM)iter.next();
2 displayWorkPackageInfo(wp);
// Query the AllWorklist worklist and locate the workpackage on the
// "SubmitClaim" worknode.
// If process name is SimpleAutoClaimProcess and worknode name is
// SubmitClaim then continue the process
3 if (wp.getProcessName().equals("SimpleAutoClaimProcess")
&& wp.getWorkNodeName().equals("SubmitClaim")) {
4 routingService.continueProcess(wp.getPidString(), "Continue", userid);
System.out.println("*** Called continueProcess on SubmitClaim");
break;
}
}
}
|
In this example:
- Creates a collection and later an iterator to loop through.
- Calls the method
displayWorkPackageInfo. The displayWorkPackage wrapper code can be found insampleDocRouting.java. It displays the information of the workpackage. The information includes the following:- Persistent ID
- Priority
- Time last moved
- Suspend state
- Notify state
- Notify time
- Resume time
- Process completion time
- Persistent ID of the item
- Process name
- Worknode name
- Owner
- Container data
- Queries the AllWorklist worklist and locates the workpackage at the SubmitClaim worknode. If the process name is SimpleAutoClaimProcess and the worknode name is SubmitClaim, continue the process.
- Continues the process.
WaitForReportAndEstimate collection point
At the collection point WaitForReportAndEstimate, the following code snippet will move the workpackage forward, if the criteria of the collection point are not satisfied.
coll = null;
iter = null;
System.out.println("-------- Calling listWorkPackages --------");
coll = (DKSequentialCollection)routingService.listWorkPackages("AllWorklist", "");
if (coll != null) {
iter = coll.createIterator();
while (iter.more()) {
DKWorkPackageICM wp = (DKWorkPackageICM)iter.next();
displayWorkPackageInfo(wp);
if (wp.getProcessName().equals("SimpleAutoClaimProcess")
&& wp.getWorkNodeName().equals("WaitForReportAndEstimate")) {
routingService.continueProcess(wp.getPidString(), "Continue", userid);
System.out.println("*** Called continueProcess on WaitForReportAndEstimate");
break;
}
}
}
|
Decision point 1: claim amount
At the first decision point of the simple auto claim process, the flow can either follow the path for claim amounts greater than $500, or follow the other path for claim amounts less than or equal to $500.
In this sample program, the approval decision is simulated based on random numbers. The method shown below simulates the approval decision.
private static DKNVPair generateApprovalDecision() {
DKNVPair decision = null;
double randomNumber = Math.random();
if (randomNumber >= 0.5) {
decision = new DKNVPair("APPROVE","ACCEPT");
} else {
decision = new DKNVPair("APPROVE","REJECT");
}
return decision;
}
|
The example below shows the program logic at the first decision point. It uses the generateApprovalDecision method to accept or reject the claims based on a random number, according to the following algorithm:
- If the process name is SimpleAutoClaimProcess and the worknode name is ReviewCredit, continue the process.
- If the process name is SimpleAutoClaimProcess and the worknode name is ReviewLargerClaim:
- Set the APPROVE value based on a random number (Accept if random number > = 0.5, Reject if random number < 0.5)
- Continue the process.
- If the process name is SimpleAutoClaimProcess and the worknode name is ReviewSmallClaim:
- Set the APPROVE value based on a random number (Accept if random number > = 0.5,Reject if random number < 0.5)
- Continue the process.
// at the first decision point
coll = null;
iter = null;
System.out.println("-------- Calling listWorkPackages --------");
coll = (DKSequentialCollection)routingService.listWorkPackages("AllWorklist", "");
if (coll != null) {
boolean ReviewCreditFound = false;
boolean ReviewLargeClaimFound = false;
iter = coll.createIterator();
while (iter.more()) {
DKWorkPackageICM wp = (DKWorkPackageICM)iter.next();
displayWorkPackageInfo(wp);
1 if (wp.getProcessName().equals("SimpleAutoClaimProcess")
&& wp.getWorkNodeName().equals("ReviewCredit")) {
ReviewCreditFound = true;
routingService.continueProcess(wp.getPidString(), "Continue", userid);
System.out.println("*** Called continueProcess on ReviewCredit");
if (ReviewCreditFound && ReviewLargeClaimFound) break;
}
2 if (wp.getProcessName().equals("SimpleAutoClaimProcess")
&& wp.getWorkNodeName().equals("ReviewLargeClaim")) {
ReviewLargeClaimFound = true;
DKSequentialCollection CNTcoll = new DKSequentialCollection();
decision = generateApprovalDecision();
CNTcoll.addElement(decision);
dkIterator CNTiter = null;
if (CNTcoll != null) {
CNTiter = CNTcoll.createIterator();
System.out.println("-------- container data --------");
while (CNTiter.more()) {
DKNVPair CNTData = (DKNVPair)CNTiter.next();
System.out.println(" Name=["
+ CNTData.getName()
+ "] Value=["
+ CNTData.getValue()
+ "]");
CNTData = null;
}
}
routingService.continueProcess(wp.getPidString(), "Continue", userid, CNTcoll);
System.out.println("*** Called continueProcess on ReviewLargeClaim");
if (ReviewCreditFound && ReviewLargeClaimFound) break;
}
3 if (wp.getProcessName().equals("SimpleAutoClaimProcess")
&& wp.getWorkNodeName().equals("ReviewSmallClaim")) {
DKSequentialCollection CNTcoll = new DKSequentialCollection();
decision = generateApprovalDecision();
CNTcoll.addElement(decision);
dkIterator CNTiter = null;
if (CNTcoll != null) {
CNTiter = CNTcoll.createIterator();
System.out.println(" Container data:");
while (CNTiter.more()) {
DKNVPair CNTData = (DKNVPair)CNTiter.next();
System.out.println(" --- Name=["
+ CNTData.getName()
+ "] Value=["
+ CNTData.getValue()
+ "]");
CNTData = null;
}
}
routingService.continueProcess(wp.getPidString(), "Continue", userid, CNTcoll);
System.out.println("*** Called continueProcess on ReviewSmallClaim");
break;
}
}
}
|
CheckFraudHistory business application node
At the business application node CheckFraudHistory, if the user exit fails, continue the process.
// at the business application node
// if user exit fails, this will continue the process
coll = null;
iter = null;
System.out.println("-------- Calling listWorkPackages --------");
coll = (DKSequentialCollection)routingService.listWorkPackages("AllWorklist", "");
if (coll != null) {
iter = coll.createIterator();
while (iter.more()) {
DKWorkPackageICM wp = (DKWorkPackageICM)iter.next();
displayWorkPackageInfo(wp);
if (wp.getProcessName().equals("SimpleAutoClaimProcess")
&& wp.getWorkNodeName().equals("CheckFraudHistory")) {
routingService.continueProcess(wp.getPidString(), "Continue", userid);
System.out.println("*** Called continueProcess on CheckFraudHistory");
break;
}
}
}
|
Decision point 2: accept or reject
At the second decision point.
// at the second decision point
coll = null;
iter = null;
System.out.println("-------- Calling listWorkPackages --------");
coll = (DKSequentialCollection)routingService.listWorkPackages("AllWorklist", "");
if (coll != null) {
iter = coll.createIterator();
while (iter.more()) {
DKWorkPackageICM wp = (DKWorkPackageICM)iter.next();
displayWorkPackageInfo(wp);
1 if (wp.getProcessName().equals("PayClaimSubProcess")
&& wp.getWorkNodeName().equals("PayClaim")) {
routingService.continueProcess(wp.getPidString(), "Continue", userid);
System.out.println("*** Called continueProcess on PayClaim");
break;
}
2 if (wp.getProcessName().equals("SimpleAutoClaimProcess")
&& wp.getWorkNodeName().equals("SendRejectionLetter")) {
routingService.continueProcess(wp.getPidString(), "Continue", userid);
System.out.println("*** Called continueProcess on SendRejectionLetter");
break;
}
}
}
|
In this example:
- If process name is PayClaimSubProcess process and the worknode name is PayClaim, continue the process.
- If process name is SimpleAutoClaimProcess process and the worknode name is SendRejectionLetter, continue the process. The process is terminated.
Calling Continue at SendThankYouLetter.
// at the SendThankYouLetter worknode
coll = null;
iter = null;
System.out.println("-------- Calling listWorkPackages --------");
coll = (DKSequentialCollection)routingService.listWorkPackages("AllWorklist", "");
if (coll != null) {
iter = coll.createIterator();
while (iter.more()) {
DKWorkPackageICM wp = (DKWorkPackageICM)iter.next();
displayWorkPackageInfo(wp);
1 if (wp.getProcessName().equals("SimpleAutoClaimProcess")
&& wp.getWorkNodeName().equals("SendThankYouLetter")) {
routingService.continueProcess(wp.getPidString(), "Continue", userid);
System.out.println("*** Called continueProcess on SendThankYouLetter");
break;
}
}
}
|
In this example:
- If the process name is SimpleAutoClaimProcess and the worknode name is SendThankYouLetter, continue the process. The process is terminated.
Disconnecting from the datastore
Disconnect from the CM datastore.
dsICM.disconnect();
System.out.println("disconnected from ICM");
|
Note: a typical execution of the sample program will generate the following output. Your Pid String, Item ID, and Component ID could be different of course.
datastore connected db icmnlsdb userid icmadmin
*** generated claim amount = 518.0
*** A folder was created
Item Pid string =95 3 ICM8 icmnlsdb15 XYZ_ClaimFolder59 26 A1001001A05F20B51410I8968818
A05F20B51410I896881 14 1025
Item ID = A1001001A05F20B51410I89688
Component ID = A05F20B51410I89688
Version ID = 1
Creating Routing Service Object
Created Routing Service Object
Deleting all workpackages...
All workpackages were deleted
Started an instance of process SimpleAutoClaimProcess Workpackage PID =90 3 ICM8 icmnlsdb11
WORKPACKAGE58 26 A1001001A05E06B64714I6505618...
*** Documents were added into the folder
-------- Calling listWorkPackages --------
-------- Workpackage Query --------
PID = 90 3 ICM8 icmnlsdb11 WORKPACKAGE58 26 A1001001A05E06B64714I6505618
A05F20B51411D360121 13 204
Priority = 100
Last Moved time = 2005-06-20-22.14.11.326000
Suspend state = 0
Notify state = 0
Item PID = 95 3 ICM8 icmnlsdb15 XYZ_ClaimFolder59 26 A1001001A05F20B51410I8968818
A05F20B51410I896881 14 1025
Process name = SimpleAutoClaimProcess
Worknode name = SubmitClaim
Owner = ICMADMIN
*** Called continueProcess on SubmitClaim
-------- Calling listWorkPackages --------
-------- Workpackage Query --------
PID = 90 3 ICM8 icmnlsdb11 WORKPACKAGE58 26 A1001001A05E24B71046G2636118
A05F20B51412E676731 13 204
Priority = 100
Last Moved time = 2005-06-20-22.14.12.458000
Suspend state = 0
Notify state = 0
Item PID = 95 3 ICM8 icmnlsdb15 XYZ_ClaimFolder59 26 A1001001A05F20B51410I8968818
A05F20B51410I896881 14 1025
Process name = SimpleAutoClaimProcess
Worknode name = ReviewCredit
Owner = ICMADMIN
-------- Workpackage Query --------
PID = 90 3 ICM8 icmnlsdb11 WORKPACKAGE58 26 A1001001A05E06B65354A8617918
A05F20B51412E562781 13 204
Priority = 100
Last Moved time = 2005-06-20-22.14.12.448000
Suspend state = 0
Notify state = 0
Item PID = 95 3 ICM8 icmnlsdb15 XYZ_ClaimFolder59 26 A1001001A05F20B51410I8968818
A05F20B51410I896881 14 1025
Process name = SimpleAutoClaimProcess
Worknode name = ReviewLargeClaim
Owner = ICMADMIN
-------- Calling listWorkPackages --------
-------- Workpackage Query --------
PID = 90 3 ICM8 icmnlsdb11 WORKPACKAGE58 26 A1001001A05E24B71046G2636118
A05F20B51412E676731 13 204
Priority = 100
Last Moved time = 2005-06-20-22.14.12.458000
Suspend state = 0
Notify state = 0
Item PID = 95 3 ICM8 icmnlsdb15 XYZ_ClaimFolder59 26 A1001001A05F20B51410I8968818
A05F20B51410I896881 14 1025
Process name = SimpleAutoClaimProcess
Worknode name = ReviewCredit
Owner = ICMADMIN
*** Called continueProcess on ReviewCredit
-------- Workpackage Query --------
PID = 90 3 ICM8 icmnlsdb11 WORKPACKAGE58 26 A1001001A05E06B65354A8617918
A05F20B51412E562781 13 204
Priority = 100
Last Moved time = 2005-06-20-22.14.12.448000
Suspend state = 0
Notify state = 0
Item PID = 95 3 ICM8 icmnlsdb15 XYZ_ClaimFolder59 26 A1001001A05F20B51410I8968818
A05F20B51410I896881 14 1025
Process name = SimpleAutoClaimProcess
Worknode name = ReviewLargeClaim
Owner = ICMADMIN
-------- container data --------
Name=[APPROVE] Value=[REJECT]
*** Called continueProcess on ReviewLargeClaim
-------- Calling listWorkPackages --------
-------- Workpackage Query --------
PID = 90 3 ICM8 icmnlsdb11 WORKPACKAGE58 26 A1001001A05E06B65840A5228118
A05F20B51411D360121 13 204
Priority = 100
Last Moved time = 2005-06-20-22.14.12.899000
Suspend state = 0
Notify state = 0
Item PID = 95 3 ICM8 icmnlsdb15 XYZ_ClaimFolder59 26 A1001001A05F20B51410I8968818
A05F20B51410I896881 14 1025
Process name = SimpleAutoClaimProcess
Worknode name = SendRejectionLetter
Owner = ICMADMIN
Container data:
--- Name=[APPROVE] Value=[REJECT]
-------- Calling listWorkPackages --------
-------- Workpackage Query --------
PID = 90 3 ICM8 icmnlsdb11 WORKPACKAGE58 26 A1001001A05E06B65840A5228118
A05F20B51411D360121 13 204
Priority = 100
Last Moved time = 2005-06-20-22.14.12.899000
Suspend state = 0
Notify state = 0
Item PID = 95 3 ICM8 icmnlsdb15 XYZ_ClaimFolder59 26 A1001001A05F20B51410I8968818
A05F20B51410I896881 14 1025
Process name = SimpleAutoClaimProcess
Worknode name = SendRejectionLetter
Owner = ICMADMIN
Container data:
--- Name=[APPROVE] Value=[REJECT]
*** Called continueProcess on SendRejectionLetter
-------- Calling listWorkPackages --------
disconnected from ICM
|
The user exit code shown below is compiled as a dynamic linking library (for example: DLL).
#include <stdio.h>
1 #include "WXV2TUE.h"
#include <windows.h>
#include <process.h>
extern long WXV2TBAUE (ICMUSERSTRUCT *pCMStruct) {
char envStr[256];
2 ICMCONTAINERDATA_STRUCT * pContainerDataStruct;
FILE *_file;
3 strcpy(envStr, "c:\\temp\\test.txt");
4 pContainerDataStruct =
(ICMCONTAINERDATA_STRUCT *) malloc (sizeof(ICMCONTAINERDATA_STRUCT) * pCMStruct->sNumContainerData);
_file = fopen(envStr, "aw");
fprintf(_file, "*** Enterint Business Application node user exit\n");
5 fprintf(_file, "*** The number of container data structures from LS is: %d \n",
pCMStruct->sNumContainerData);
6 fprintf(_file,"*** WP Comp ID from LS is: %s \n", pCMStruct->szWPCompID );
7 fprintf(_file,"*** WP Item ID from LS is: %s \n", pCMStruct->szWPItemID );
8 strcpy(pCMStruct->szRouteSel, "Continue");
fprintf(_file,"*** Routed to the next node\n");
fprintf(_file, "*** Leaving Business Application node user exit\n");
9 if (pContainerDataStruct != 0) free(pContainerDataStruct);
fclose(_file);
return 0;
}
|
In this example:
- Includes the WXV2TUE.h header file.
- Declares a pointer to container structure, ICMCONTAINERDATA_STRUCT.
- Sets the output file path to "c:\temp\test.txt".
- Allocates memory to the container structure based on the number of container data.
- Prints the number of container data.
- Prints the component ID of the workpackage.
- Prints the item ID of the workpackage.
- Sets the route selection to "Continue".
- Frees the memory of the container structure.
The test.txt file will be created under the directory c:\temp by the user exit code.
*** Enterint Business Application node user exit *** The number of container data structures from LS is: 0 *** WP Comp ID from LS is: A05F20B82328A18196 *** WP Item ID from LS is: A1001001A05E06B72338I29494 *** Routed to the next node *** Leaving Business Application node user exit |
This second article in a 3-part series on document routing serves as an introduction for those who are interested in developing document routing applications through application programming interfaces. It presented an overview on the DB2 Document Routing API, walking you through annotated sample code based on the simple auto claim process presented in Part 1. Whether you are a beginner or a workflow expert, this article on document routing API will benefit you.
Now that we have covered process modeling and API usage, the next article in this series will focus on client usage of document routing.
Special thanks to Ying-Pong Chen, Content Management Development, IBM Silicon Valley Laboratory, for taking his time to review this article.
| Description | Name | Size | Download method |
|---|---|---|---|
| C code sample | WXV2TBAUE.c | 2KB |
FTP
|
| document rounting sample | sampleDocRouting.java | 29KB |
FTP
|
Information about download methods
Learn
- Visit the IBM DB2 Content Manager support site for further help.
- Find more documentation in the IBM DB2 Content Manager Enterprise Edition Version 8.3 publication library.
- Visit the Content Management Information Center to access the information that you need for DB2 Content Manager.
- Find IBM Redbooks about DB2 Content Manager on a variety of subjects.
- Visit the developerWorks DB2 zone to learn more about DB2. You'll find technical documentation, how-to articles, education, downloads, product information, and more.
Discuss
- Visit the developerWorks blogs to get involved in the developerWorks community.
Alan Yaung is a senior software engineer of Content Management Development at IBM Silicon Valley Laboratory. He leads the Content Management Workflow Team. He has more than eight years of experience in product development of enterprise content management solutions. Alan is a Content Manager Certified Solution Designer. He also has over 20 granted and pending patents.

Allan Tham works as a DB2 Content Manager Technical Presales Support Specialist for Business Partners. He helps business partners solve a wide range of technical problems. Allan is certified for DB2 Content Management administration. Prior to joining IBM, Allan worked in an end-user environment, where he was an Oracle DBA for three years.
Comments (Undergoing maintenance)





