Java CAPS Tip : Implementing a Vendor Relationship Management Portal (Part 1)

This blog entry takes the process implemented in "Simple Visual Web Pack Implementation of the Work List Manager GUI" and attempts to relate it to a real world example. The example chose is that of a Vendor Management Process (VRMP) where a given company would like to raise all its Purchase Orders (PO), to suppliers, over the internet and allow them the Accept / Reject and then Raise associated Advanced Shipment Note (ASN) for the PO. I will initially build the User Process using the classic Java CAPS 6 Repository style eInsight, within this blog entry, as Part 1 of a three part trail. In Part 2 I will extend this so that it is integrated into the new BPEL 2.0 style process and them finally, in Part 3, implement the process using using the Open ESB WLM SE.

The overall workflow to be implemented is shown below.

Workflow



VRMP Trail

Resources

eInsight Workflow Implementation


Although the logical Workflow is depicted above the physical implementation will be split into two parts. This is because the GUI user will have the ability to create multiple ASNs for each PO and these will need to be processed separately. In addition the actual Workflow User API (UA) calls will be placed within small eInsight (Sub)-Processes which will be called from the main process. Their are two reasons for this:

  1. Because eInsight WLM processes are kept in memory whilst paused awaiting a response this does have the potential to use a large amount of memory. Therefore splitting out the UA calls into smaller business processes will allow the memory to be freed earlier.
  2. I will be using these in Part 2.

I will therefore implement the following business processes within eInsight:
  1. bpPOWorkflow
    1. bpAcceptPOUA
    2. bpCreateASNUA
  2. bpASNWorkflow
    1. bpAuthoriseASNUA
    2. bpAuthoriseASNFLSLUA

Throughout the processes we will assume the following (bases on xml below).

  • PONumber - Purchase Order Number being processed
    • Maps the WLM Flex String1
  • SupplierName - Name of the Supplier for which the PO is being raised.
    • Maps to the WLM Flex String 2
    • Will be used to dynamically assign the UA
  • PODescription - Short Description of the PO
    • Map to the WLM Flex String 3
  • Accept - Flag to indicate the result of the UA
    • Maps to the WLM Output
  • ASNNumber - ASN Number being Processed
    • MAPs to the WLM Flex String 5
  • Action - Indicate the Action Required
    • Accept PO / Create ASN / Authorise ASN
    • Maps to WLM Flex String 6

In addition to this I will assume that the processes are set as persistent, although this is not required for Workflow it is to allow the processes to be restarted after a server crash, and the database structures require for eInsight and WLM have been created.

Purchase Order Workflow


The bpPOWorkflow, defined below, is used to implement the Supplier portion of the overall process; i.e. the portion of the process where the supplier has to Accept the PO and then raise the associated ASN(s).

PO Workflow
bpPOWorkflow

The actual User Activities are are implemented as the (Sub)-processes bpAcceptPOUA and bpCreateASNUA .

Accept PO
bpAcceptPOUA

Create ASN
bpCreateASNUA

Because we want to keep the amount of memory to a minimum we will not be passing the actual PO around the system. Instead we will pass the minimum amount of information, in the following XML, and only access the full details when required. I assume that the PO will be store in some back-end system such as SAP but for simplicity I will store them within a simple database.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="urn:xsd.wlm.po.processing" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="urn:xsd.wlm.po.processing" targetNamespace="urn:xsd.wlm.po.processing" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:complexType name="PurchaseOrderComplexType">
<xs:sequence>
<xs:element name="PONumber" type="xs:string"/>
<xs:element name="SupplierName" type="xs:string"/>
<xs:element name="PODescription" type="xs:string"/>
</xs:sequence>
<xs:attribute name="Accept" type="xs:boolean"/>
</xs:complexType>
<xs:complexType name="ASNComplexType">
<xs:complexContent>
<xs:extension base="PurchaseOrderComplexType">
<xs:sequence>
<xs:element name="ASNNumber" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="PurchaseOrder" type="PurchaseOrderComplexType"/>
<xs:element name="ASN" type="ASNComplexType"/>
</xs:schema>

Therefore the bpPOWorkflow will be initiate by a message, of the above structure, arriving on a queue (qStartPOWorkflow), and initiate the appropriate User Activities.

cmPOWorkflow
cmPOWorkflow

The bpPOWorkflow will simply unmarshal the Text Message Received from the inbound queue directly into the input for the bpAcceptPOUA and wait for this process to return. Once it has return it will check the value of the Accept attribute within the message and then proceed or abort the process based on the result. If the PO is Accepted them the result of the bpAcceptPOUA will be mapped to the input of the bpCreateASNUA and await its return. On completion of this step it will simply terminate. This process specifically does not do anything to initiate the ASN Workflow because the Visual Web Pack (VWP) application will look after the messaging associated with that process. This is because multiple ASNs may be created for a PO and we want to initiate a Workflow for each.

The bpAcceptPOUA and bpCreateASNUA are essentially the same, as can be seen above, and once create these will need to be configured as per the images below.

Map Input
UA Input Mapping

Ouput Mapping
UA output Mapping

Assignments
Timeouts
Email

WLM SEIt can be seen from the configuration above that the actual destination for the UA is defined as part of the input message within the SupplierName XML element. The value within the SupplierName must match a Group Entry within the WLM LDAP structure and given that it does it will send  emails / associated the Task with all members of the Group.

To test the Purchase Order Workflow process the Java CAPS Project contains a simple JCD that will load the appropriate information from the following XML into the supporting Database Tables, defined below, and then place a message on the qStartPOWorkflow Queue to initiate the process.

Supporting Tables

CREATE TABLE PO_STORE (
PONumber VARCHAR(20) NOT NULL,
Payload VARCHAR(2000) NOT NULL
);

CREATE TABLE ASN_STORE (
ASNNumber VARCHAR(20) NOT NULL,
Payload VARCHAR(2000) NOT NULL
);

Input XML (C:/Temp/po00001.xml)

<?xml version="1.0" encoding="UTF-8"?>
<tns:PurchaseOrder xsi:schemaLocation="http://xml.netbeans.org/schema/PsudoPOComplexTypes PsudoPOComplexTypes.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://xml.netbeans.org/schema/PsudoPOComplexTypes">
<tns:PONumber>PO00001</tns:PONumber>
<tns:SupplierName>Supplier A</tns:SupplierName>
<tns:PODescription>Simple PO</tns:PODescription>
<tns:Amount>3.142</tns:Amount>
<tns:Line>
<tns:ItemNumber>1</tns:ItemNumber>
<tns:Description>Steak and Onion</tns:Description>
<tns:Quantity>0</tns:Quantity>
<tns:Amount>3.142</tns:Amount>
</tns:Line>
<tns:Line>
<tns:ItemNumber>2</tns:ItemNumber>
<tns:Description>Meat and Potato</tns:Description>
<tns:Quantity>0</tns:Quantity>
<tns:Amount>3.142</tns:Amount>
</tns:Line>
</tns:PurchaseOrder>


Having placed the above file in the appropriate location, to be picked up by the Load Process, the bpPOWorkflow will be initiated and will suspend within the bpAcceptPOUA process. At this point an entry will be written to the WLM Database with a Task assigned to the Group "Supplier A" (I am assuming you are using the above file). To review this Task you will need to logon to the WLM application as a user associated with "Supplier A". If you are using the attached ldif then you should login as Andrew/Andrew and this will allow you to see all "Supplier A" Purchase Orders.
LoginTask List

It can be seen that the only PO within the list requires that the User Accept the PO. What we can do is view the contents of the PO by selecting the "View" Button. At this point the VWP Application will call the supporting Web Service "GetPODetails" which will retrieve the actual PO from its host system say SAP, but for simplicity the Database Table PO_STORE, for the given PO Number. This processing allows for the actual data passed around the eInsight process to be kept to a minimum. Pressing View will display the following:

Details

If the User accept to PO, either here or on the previous screen, the WLM activity will update the task as completed. This will case control to be return to the bpPOWorkflow process that will check the result (Accept / Reject) and then, if appropriate, proceed to the next Step. The result of this will be the execute of the bpCreateASNUA process that will cause a new entry to be written into the WLM tables. Again this entry will be associated with "Supplier A" and can be seen within the Task List.

Task List

If the User Selects "Create ASN" or enters the View Page and Selects "Create ASN" then the VWP page will Create an Appropriate ASN by executing the Support Process bpCreateASN. This will insert a record for the ASN into the ASN_STORE Table and then place a record on the qStartASNWorkflow Queue to initiate the next process. At this point the Task will be marked as completed allowing the bpPOWorkflow eInsight process to run to completion.

ASN Workflow


The cpASNWorkflow, defined below, is used to implement the Vendor portion of the overall process; i.e. the portion following the acceptance of the PO by the supplier and the creation of the associated ASNs. It is assumed that the Vendor acceptance of the ASN is done in two stages by two different Groups before the ASN is passed onto subsequent processing. This application does not do any followon processing but simple places the ASN on the Queue qEndWorkflow.

ASN Workflow
bpASNWorkflow

The actual User Activities are implemented in the Sub Processes bpAuthoriseASNUA and bpAuthoriseASNFLSLUA.

Authroise
bpAuthoriseASNUA

Authorise
bpAuthoriseASNFLSLUA

Again to keep memory consumption low we will be passing around the minimum amount of information. The bpASNWorkflow will simply unmarshal the input message directly to the input of the bpAuthoriseASNUA sub process and await its return. On completion of this and assuming the ASN is Authorised the process will pass the output details directly to the next sub process where it can be further Authorised. It can be see that this process is essentially the same as the bpPOWorkflow and hence I will not go into to much detail. The key differences are the Assignments made within the the User Activities within the sub processes because in this flow we do not use the SupplierName as the input but instead use Static Assignments, because we know which groups must Authorise the ASN, one for each of the two processes. These are as follows:

bpAuthoriseASNUA

Authorise

It can be seen that for this process we have decided to pass all Authorisation request through to the "ASN Authorisers" Group.

bpAuthoriseASNFLSLUB

Authorise

For final Authorisation this process passes all requests through to the Group Final Authorisers.

The reason for implementing this is that we can now see how the Workflow process can be split across multiple Groups / Departments with differing levels of Authorisation capabilities. Following on from the previously Accepted PO / Create ASN process we will need to logon to the Web Application as a member of the "ASN Authorisers" Group and assuming you are using the attached WLM ldif we can use scarter/scarter to display the awaiting Tasks.

Task List

When the User "Authorises ASN" or Views and Authorises the Task will me marked as completed allowing the bpASNWorkflow to move onto the next step in the process. This will send the processing to the "Final Authorisers" group and to view their tasks we will need to logon as a member of that group. Therefore logout of scarter and logon as kwinters/kwinters to view the final Authorisation Tasks.

Authoriase

Selecting either Authorise or viewing the ASN and then Authorising will cause the task to be completed and allow the bpASNWorkflow to continue and write the record to the qEndWorkflow Queue thus completing the whole process.



Configuring the Environment


Java CAPS WLM Environment


Although some of the configuration information defaults to the correct value I prefer to specify the information explicitly, as can be seen in the image below, with the following being the key configuration parameters:

  • Users ParentDN : ou=People,dc=wlm,dc=sun,dc=com
  • Roles ParentDN : dc=wlm,dc=sun,dc=com
  • Group ParentDN : ou=Groups,dc=wlm,dc=sun,dc=com
  • The value for the Subordinate entry is changed from the default "directReports" because this is not available within the Sun DSEE as a default attribute for inetOrgPerson.
EnvironmentDB Environment

Once created your JavaCAPS environment is configured to interface with you DSEE instance. When adding WLM API components within you eInsight process the Directory can be accessed using the parameters specified above.

WorkflowService.jar

To allow you to access the WLM functionality from an externally developed web application you will need to configure the connection properties of the WorkflowServices.jar, which can be downloaded from you repository, and then install this in you Glassfish instance. When you have downloaded the Workflow Service API from the repository you will need to extract the zip which will create a number of directoriesand the WorkflowService.jar file. You will need to expand the WorkflowService.jar and edit the connection.properties contained in the package com.stc.bpms.wlm. Given the information and DSEE structure we have your connection.properties should contain the following:

# -------------------
# JDBC DB Connection:
# -------------------
# false - allow DAO XA, true(default) - allow db auto commit



#---------------------------------------------------------
# Connection to DB: Recommened way: Create Connection pool
# in the applicatin server and provide that JNDI name here
#---------------------------------------------------------

dbConnectionPoolRefName=jdbc/WLM6OraclePool
dbType=oracle

#---------------------------------------------------------
# Connection to DB: Alternate way
#---------------------------------------------------------
#daoAutoCommit=false
#dbType=oracle
#dbDriverName=oracle.jdbc.driver.OracleDriver
#dbUrl=jdbc:oracle:thin:@wlmhost:1521:AndrewHo
#userId=wlm51
#password=wlm51


#---------------------------------------------------
# Connection to EMail Server
#---------------------------------------------------
emailServer=mailserver
emailUser=wlm
emailPassword=wlm


# -------------------------------------------------
# Connection to Security Manager.
# -------------------------------------------------
# securityManager=com.stc.bpms.wlm.security.OpenLdapSecurityManager
# securityManager=com.stc.bpms.wlm.security.EnvUserSecurityManager
securityManager=com.stc.bpms.wlm.security.SunOneSecurityManager
# securityManager=com.stc.bpms.wlm.security.ActiveDirectorySecurityManager

# -------------------------------------------------
# OpenLdap Connection Properties: MegaNova schema
# -------------------------------------------------
#ldap.Version=3
#ldap.Context.INITIAL_CONTEXT_FACTORY=com.sun.jndi.ldap.LdapCtxFactory
#ldap.Context.PROVIDER_URL=ldap://localhost:389

#ldap.rootName=MegaNova
#ldap.searchFilter=(o=Mega Nova)
#ldap.searchDN=ou=People,o=MegaNova,c=US
#ldap.attribute.role=stcWFRole
#ldap.attribute.manager=stcWFManager
#ldap.attribute.group=stcWFGroup
#ldap.attribute.email=mail
#ldap.attribute.givenName=givenName

# ------------------------------------------------------------
# Sun Java System Directpry Server / ADS Connection Properties
# ------------------------------------------------------------

java.naming.provider.url=ldap://dseehost:1389
java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
java.naming.security.authentication=simple
java.naming.security.principal=cn=Directory Manager
java.naming.security.credentials=adminadmin

UsersParentDN=ou=People,dc=wlm,dc=sun,dc=com
UserDNAttributeNameInUser=entrydn
UserIDAttributeNameInUser=uid

RolesParentDN=dc=wlm,dc=sun,dc=com
RoleNameAttributeNameInUser=nsroledn
RoleNameFieldInRoleDN=cn

GroupsParentDN=ou=Groups,dc=wlm,dc=sun,dc=com
GroupDNAttributeNameInGroup=entrydn
GroupNameFieldInGroupDN=cn
GroupsOfUserFilterUnderGroupsParentDN=uniquemember={0}

ldap.attribute.manager=manager
ldap.attribute.directReports=entrydn
ldap.attribute.email=mail
ldap.attribute.givenName=givenName
ldap.attribute.group=o



# -------------------------------------------------
# WLM Internal: Don't alter this property
# -------------------------------------------------
wlmApi=true


Once the connection.properties has been modified to match the DSEE information the WorkflowService.jar needs to be recreated and then deployed to Glassfish; as follows :

  1. JAR Modified contents of the previously extracted WorkflowService.jar into a new version.
  2. Deploy to Glassfish using : <GF Install Dir>/bin/asadmin deploy --user admin --generatermistubs=true WorkflowService.jar
  3. Get Client Stubs using : <GF Install Dir>/bin/asadmin get-client-stubs --user admin --appname WorkflowService <Destination Dir>
  4. The previous line will generate the file WorkflowServiceClient.jar that can be imported into your IDE; say NB 6 and used with Visual Web Pack (a future blog)

 In addition to allow the WLM API to access the WLM database you will need to add the following JDBC Resources:

<jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="auto-commit" datasource-classname="oracle.jdbc.pool.OracleDataSource" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="false" is-isolation-level-guaranteed="false" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="WLM6OraclePool" non-transactional-connections="false" pool-resize-quantity="2" res-type="javax.sql.DataSource" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" wrap-jdbc-objects="false">
<property name="PortNumber" value="1521"/>
<property name="Password" value="WLM6USER"/>
<property name="DatabaseName" value="AndrewHo"/>
<property name="User" value="WLM6USER"/>
<property name="DataSourceName" value="OracleDataSource"/>
<property name="url" value="jdbc:oracle:thin:@wlmdb:1521:AndrewHo"/>
</jdbc-connection-pool>
<jdbc-resource enabled="true" jndi-name="jdbc/WLM6OraclePool" object-type="user" pool-name="WLM6OraclePool"/>

Visual Web Pack

If you are using the default Glassfish installed with Java CAPS 6 you will need to modify the sun-web.xml so that the WorkflowService reference point to the correct port; as below:

Workflow Service


Trail
Resources


Comments:

Hi Andrew,
Thanks for the help. We are not able to view the jsp pages(VWP project) in design mode.
Can you please guide us on this?

Posted by Nirav Shah on August 13, 2008 at 08:29 AM GMT #

I suspect this is because the WorkflowServiceClient.jar is missing from the WLMPOWebApplication/lib/ejb-sources directory. If you import the client into NB this will create the appropriate files and then you can move the file to the specified directory or just drop the one previously created intot he ejb-sources dir

Posted by guest on September 01, 2008 at 03:30 AM GMT #

Post a Comment:
Comments are closed for this entry.
About

As a member of the Oracle A-Team we specialise in enabling and supporting the Oracle Fusion Middleware communities.

Search

Archives
« April 2014
MonTueWedThuFriSatSun
 
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
    
       
Today