Posts Tagged ‘Mark’


Using WAPI in Oracle BPM

April 14th, 2010 by Mark Peterson • No Comments »

There are many business use cases that require using WAPI  to implement Oracle BPM. WAPI is a low-level API that involves some basic web related tools to provide special functionality needed for your business process.  Just providing these tools without explaining why they are needed won’t help you learn how to use these tools when they are needed. There are probably many more applications for using WAPI. These are just some of the use cases I’ve come upon that required me to use WAPI.
  • The business has implemented business processes that have work items that are somehow related to each other. These business processes may be hierarchical in nature such as flight planning, trips and legs; or contains work items that are related together such as line items of a particular invoice or order.
  • Business organizations wish to group tasks according to management oversight, region or by some other factor.
  • The business wants to provide short-cuts to users so they don’t have to jump around to find related instances and have special UI requirements to provide this functionality. This functionality may require implementing special graphical UIs such as adobe FLEX or require jumping around from one particular work item to another. Going through the in-box view to open an instance each time is not desired or  feasible .
WAPI provides a mechanism to create a list of related instance that you can navigate in and out of from virtually anywhere within the business process. This could be from within a screenflow, some external UI, COTS applet, or Adobe FLEX. I have used WAPI from all of these types of examples and it is easy to do once you know how these tools work.

WAPI provides an mechanism to launch into a particular instance from HTML using javascript or hidden forms.  I have two versions of this code, one for BPM version 5.x and the other for 6.x. The two key components is the action URL link and the instance stamp.

BPM version 5.x:

<form method="post" action="<%= URLForAction.instanceProcess(request)%>" name="instanceActionsForm">
<input type="hidden" name="instanceStampId" />
<input type="hidden" name="nextInstanceStampId" />
<input type="hidden" name="actionId" />
</form>

BPM version 6.x:


function runTask(id) {
 var baseUrl = "<%=UrlActions.runTask()%>";
 var instanceStampId = id;
 var itemId = 0;
 var url = "<%=request.getContextPath()%>" + baseUrl +  "&<%=UrlActions.INSTANCE_STAMP_ID%>" + "=" +  encodeURIComponent(instanceStampId) +  "&<%=UrlActions.ITEM_ID%>" + "=" + itemId;
 window.open(url);
 }
 

Getting a list of related instances and pulling the instanceStamp from the instances is complicated.  I’ll have to address that later in a separate blog. It involves using BusinessProcess.getInstanceByActivity or BusinessProcess.getInstanceByFilter. There’s a lot to know about using these methods so I won’t go into it now. If you know how to use these methods then all you may need help on is creating an instance stamp. This can be done from the list of instances returned from these methods. To create the instance Stamp just use:

InstanceStamp instanceStamp =InstanceStamp.create(instanceId : instance.id, activityName : instance.activityName).getId();

Using WAPI to open instances can be dangerous. BPM keeps track of open instances. These open instances are locked. When you jump from instance to instance without closing out of the associated screen-flow you’ll lock up a bunch of instances. This will preventing people from gaining access to them later on.  The way to avoid this is to submit or post to the open instance before you open another one. This creates problems if you can’t simply cancel out of the open instance.

If you can simply cancel the open instance and you can be sure the cancel will work in most all cases, then you simply need to submit to the form before you open the new instance. If you can’t be certain of this, then I recommend you use a simple AJAX method to do this. You just need to parse the return document to be sure the post worked before you open a new instance. Here’s some code you can use to do this:

postLoc = "<f:postResults/>";
function cancelScreenFlow() {
    var xmlHTTP = new ActiveXObject("Microsoft.XMLHTTP");
    xmlHTTP.open("POST",postLoc,false);
    xmlHTTP.send();
    var xslresponse = xmlHTTP.responseText;
}

Hopefully you find this blog useful. I'm not sure BPM product management realizes how common these use cases are. So please let me know if you have any interesting use cases and how WAPI was used to solve your problem.  Solving certain BPM use cases with WAPI has been indispensable to me.  I'm always excited to learn of similar situations as the ones I've identified here.

No Comments »

 

How to Get BRM Pipeline Working

April 9th, 2010 by Mark Peterson • 2 Comments »

I recently installed and configured the BRM pipeline rating using BRM’s optional Wireless Suite.  I had a difficult time getting it to work because it requires installing many interdependent components and many manual configuration steps. Hopefully this blog will help you get it working without much difficulty. Most of the difficulty has to do with figuring out what steps are needed and why.  The BRM documentation has most of the information you need but it is not in one place and it simply tells you to do this or that. It doesn’t do a good job at explaining what is needed to get the pre-configured wireless pipeline to work.  It also doesn’t explain how to create accounts and CDRs that work with the these pre-configured items.  I learned out a lot from getting it to work though. So here’s what I learned.

Pipeline rating is a completely standalone rating engine. These steps take you through the process of configuring the pipeline and BRM system so you can create accounts that the pipeline can work process and then create, rate and load CDRs into BRM. The pipeline needs to have rate plans, zones and other features loaded in the IFW database. BRM needs new event, service, device and item class-types configured.  The pipeline uses some BRM database configuration items to work whereas BRM needs some FMs to handle functionality around the Customer Center extensions. You’ll also need to install the Telephone and SIM Card Administrator.

The basic steps to get it to work are listed here. More details are broken out in the section that follow.

  • Install Customer Center Extensions.
  • Install Server-side Components.
  • Configuring the Wireless Registry File
  • Configure the IFW Database with Default Rate Plans and Settings.
  • Run pin_setup Scripts
  • Configure PIN_REL
  • Load the Telco GSM Event Map
  • Merge and Load Telco Event Notification
  • Create Portal Products, Deal, Plan and add to Plan List
  • Load Device Service Map
  • Load Item Type Mapping
  • Setting up GSM Accounts and Services.
  • Process CDR File
  • Testing and Troubleshooting Pipeline Rating

Install Customer Center Extensions

The first things you’ll need to do is install a panel and it’s associated dialog boxes into Customer Center. This panel is needed to create accounts with telephony services. These services require phone numbers, SIM cards and IMEI numbers in order to maintain, rate, bill and provision the service. BRM added this panel so Customer Service Reps (CSRs) can select telephone numbers, SIM cards and IMEI numbers when creating new accounts.

You will also need to install admin tools used for creating blocks of telephone numbers and SIM cards. The install scripts for these admin tools and the Customer Center extensions are located on http://edelivery.oracle.com.  Select “Oracle Communications Applications” in the drop-down and the OS you’re working with; e.g. Microsoft Windows 32-bit platform. Select search.

Select the “BRM Media Pack for Microsoft Windows (32-bit)” and download Oracle BRM clients for Windows.  After it downloads unzip the file and install these three client components on your PC.

GSM_Mgr_CustCtrExt
NumberAdminCtr
SIMAdminCtr

The install scripts assume you have Customer Center already installed and it usually finds the installation directory by itself. The installation of these client side components is easy. After you unzip the packages, just execute the setup.exe file and follow the instructions.

Install Server-side Components

Since the pipeline rating engine is not part of BRM, some some new op-codes are needed by BRM.   Although you have installed the pipeline rating engine on the server, you not done yet. There are several more components you will need. If you haven’t installed the pipeline rating engine, I blogged about it in, Common BRM Pipeline Installation Issues.

If you don’t have the install scripts shown below, you’ll need to go to Oracle e-delivery site and download the optional BRM components. It’s under the Oracle BRM Media Pack ->Oracle BRM Extensions.

Unzip the file and run these install scripts as the PIN user. The actual names may be a little different depending upon the version and platform you’re using.

7.4_WirelessSuite_linux_32_opt.bin
7.4_SIMMgr_linux_32_opt.bin
7.4_NumberMgr_linux_32_opt.bin
7.4_GPRS_Mgr_30_linux_32_opt.bin
7.4_GSM_Mgr_linux_32_opt.bin

Configuring the Wireless Registry File

When you install the Wireless Suite component, it comes with a pre-configured wireless pipeline. The registry for this pipeline is located in the the IFW_HOME/conf directory and is called wireless.reg.  You will need to edit this file by entering the connection information you used for setting up the IFW and PIN database. It needs the database alias, and user name and passwords you used. There is one entry for the IFW database and two entries for the PIN database. You will need to encrypt the passwords using AES encryption.

Next you will need to create an IFW synchronization queue.  The wireless pipeline registry, wireless.reg,  calls the sync queue IFW_SYNC_QUEUE. It is created by running the pin_ifw_sync_oracle.pl scripts. I couldn’t get it to work taking some of the default values as shown in the script usage syntax.

pin_ifw_sync_oracle.pl create [-l username/password@databaseAlias] [-q queue_name -t queue_table]

After including the following command line options, I was able to get it to work. You will need to modify this for your particular environment.

perl pin_ifw_sync_oracle.pl create -l pin74/pin74@pindb -r 300 -s ‘tablespace PIN74 initrans 5 storage (initial 200k next 200k maxextents unlimited pctincrease 0 )’

Configure the IFW Database with Default Rate Plans and Settings.

The BRM Wireless Suite comes with a pre-configured set of rate plans, discounts, impact categories, etc.  These settings are stored in the IFW_HOME/conf/pricingcenter/Oracle directory.

Edit the perl script called insertWIRELESS_SAMPLE.pl in this directory. Change the oracle connection properties to use the IFW database alias and user name and password you chose. When you run this script it will execute the insert statements contained in the SQL scripts located in this directory. You will notice that each SQL script is named after the IFW table it updates. This makes it very easy to see what is being added to the IFW database. As you can see, there are a lot of tables  affected by running this perl script.

ifw_alias_map.sql ifw_apn_group.sql ifw_apn_map.sql
ifw_calendar.sql ifw_daycode.sql ifw_destinationdesc.sql
ifw_discarding.sql ifw_discountbalimpact.sql ifw_discountcondition.sql
ifw_discountdetail.sql ifw_discountmaster.sql ifw_discountmdl_cnf.sql
ifw_discountmdl_ver.sql ifw_discountmodel.sql ifw_discountrule.sql
ifw_discountstep.sql ifw_discounttrigger.sql ifw_edrc_desc.sql
ifw_edrc_field.sql ifw_exchange_rate.sql ifw_glaccount.sql
ifw_holiday.sql ifw_icproduct_all.sql ifw_impact_category.sql
ifw_map_group.sql ifw_mostcalled.sql ifw_networkmodel.sql
ifw_networkoper.sql ifw_pipeline.sql ifw_pricemodel.sql
ifw_pricemodel_step.sql ifw_rateplan_cnf.sql ifw_rateplan.sql
ifw_rateplan_ver.sql ifw_ref_map.sql ifw_resource.sql
ifw_rsc_group.sql ifw_seqcheck.sql ifw_serviceclass.sql
ifw_servicecode_map.sql ifw_service.sql ifw_specialday_lnk.sql
ifw_specialdayrate.sql ifw_splittingtype_all.sql ifw_standard_zone.sql
ifw_taxcode.sql ifw_taxgroup.sql ifw_tax.sql
ifw_timeinterval.sql ifw_timemodel_lnk.sql ifw_timemodel.sql
ifw_timezone.sql ifw_uom.sql ifw_usageclass_map.sql
ifw_usageclass.sql ifw_usagescenario_map.sql ifw_usagetype.sql
ifw_usc_group.sql ifw_zonemodel.sql

To run this command, be sure to redirect the output to a file. It streams a bunch of information to the standard output. It doesn’t output to a log file so you may want to look back this file to be sure it ran properly.

Run pin_setup Scripts

As a pin user, go to $PIN_HOME/setup/scripts

Run the pin_cmp_tcframework.pl file. This install script creates a bunch of new classes (tables) in the PIN database. Expand the nodes below to see what tables where created:

Service Objects:

/service/telco/
/service/telco/gsm/roaming

Event Objects

/event/activity/telco
/event/session/telco
/event/delayed/activity/telco
/event/delayed/session/telco
/event/delayed/activity/telco/roaming
/event/delayed/session/telco/gsm/roaming
/event/svc_order
/event/svc_order/attribute
/event/provisioning
/event/provisioning/service_order

Config Objects:

/config/telco/provisioning
/config/telco/provisioning/fieldlist
/config/telco/service_order_state
/config/telco/service_order_state/telco
/config/service_framework
/config/service_framework/permitted_service_types/
/config/account_era

Run the perl pin_cmp_gsm.pl script Expand the following nodes to see what tables (classes) are created.

Service Objects

/service/settlement
/service/settlement/roaming
/service/telco/gsm
/service/telco/gsm/data
/service/telco/gsm/fax
/service/telco/gsm/sms
/service/telco/gsm/telephony
/service/telco/gsm/roaming
/service/settlement/roaming
/service/settlement/roaming/incollect
/service/settlement/roaming/outcollect

Event Objects:

/event/activity/settlement
/event/session/telco/gsm
/event/delayed/session/telco/gsm
/event/delayed/session/telco/gsm/roaming
/event/provisioning/service_order/telco/gsm
/event/provisioning/service_order/telco/gsm/data
/event/provisioning/service_order/telco/gsm/fax
/event/provisioning/service_order/telco/gsm/sms
/event/provisioning/service_order/telco/gsm/telephony

Config Objects:

/config/telco/gsm
/config/telco/gsm/data
/config/telco/gsm/fax
/config/telco/gsm/sms
/config/telco/gsm/telephony
/config/telco/service_order_state/gsm
/config/telco/service_order_state/data
/config/telco/service_order_state/fax
/config/telco/service_order_state/sms
/config/telco/service_order_state/telephony

Active_session objects:

/active_session/telco/gsm
/active_session/telco
/active/session/telco/gsm

Run the pin_cnf_tcframework.pl script. This will add the following FMs to the CM pin.conf file. These FMs contain opcodes used by the Customer Center.

fm_prov fm_prov_pol
fm_tcf fm_tcf_pol
fm_trans_pol

Run the pin_cmf_dm_prov_telco.pl and pin_cnf_dm_prov_telco.pl

This will configure the CM pin.conf file and dm_prov_telco pin.conf file. You may also want to edit the start_all and stop_all script so that dm_prov_telco start and stops with the rest of the CM and DMs.

Configure PIN_REL

There are several traps you can fall into trying to get the pin_rel utility to work for the first time. You will need to run some setup/scripts, modify the user $PATH and make sure Oracle sqlldr is installed on the server.  This section will help you avoid some common problems.

First, the pin_rel utility requires some new tables in the database schema to operate. Go to the setup/scripts directory and run the pin_cmf_rel.pl and pin_cnf_rel.pl. Next add the $PIN_HOME/apps/pin_rel to the pin user $PATH.  And finally be sure Oracle sqlldr is installed on the server.

The pin_rel utility use SQL Loader (sqlldr) to load events into the BRM database. To see if it is installed on your server, executing sqlldr from the command line as the pin user. If it can’t be found check to be sure the $ORACLE_HOME/bin directory is in the path. If sqlldr isn’t in the bin directory, then install it. It’s part of the Oracle database installation so you will basically have to install Oracle on the server. Since you don’t actually need a configured database on the server, skipping this step during installation will save you some time.

For performance reasons you may want to run on the database server. When you run CDRs through the pipeline, you can map the output to a network drive or copy the files to database server.  For our testing purposes  running it on the BRM server is sufficient. If you have a large amounts of EDRs to process in production and to load into BRM, then you may need to move the pin_rel app over to the database server.

Load the Telco GSM Event Map

The Pricing Center needs to be configured to recognize the new event and service objects loaded in prior steps. Fortunately the new event map is created for you. This event map comes already merged with BRM base-line event maps. If you’re working with a baseline BRM installation,  you just have to load them into the database.

Change directory to sys/data/config directory and run the command:

load_event_map -dv pin_event_map_telco_gsm

If you have custom events already loaded, then be sure to edit the pin_event_map_telco_gsm file before you run this command. This command will overright the changes made to the default event map, if you don’t. If you forget, just rerun the command with custom events added to this file.

Merge and Load Telco Event Notification

The Telco provisioning is integrated through the event notification framework. When new products and services are purchased for an account, the event notification framework needs to fire-off these op-codes. These op-codes will perform functionality required to provisioning the new telephony services through BRMs provisioning framework.

PCM_OP_TELCO_SVC_LISTENER 4008
PCM_OP_TELCO_APPLY_PARAMETER 4009
PCM_OP_TELCO_PROPAGATE_STATUS 4010
PCM_OP_TELCO_PROV_CREATE_SVC_ORDER 4016
PCM_OP_TELCO_PROV_HANDLE_SVC_ORDER 4017
PCM_OP_TELCO_PROV_UPDATE_PROV_OBJECT 4019

To enable the provisioning framework, change to following directory to sys/data/config and execute

load_pin_notify pin_notify_telco

Create Portal Products, Deal, Plan and add to Plan List

In this section you will create a product, deal and a plan that can be purchased against accounts and rate CDRs through the pipeline.  We will use one of the rate plans inserted in the pipeline database with the insertWIRELESS_SAMPLE.pl script described above.  Start Pricing Center and connect to the PIN database. Click on the create product icon, enter a name and select in the drop-down list Applies To: /service/telco/gsm/telephony.

Accept all the default values and when you get the prompt, “Do you want to add or change rates and folds for this product?”, click on “Yes”. Now add an Event Map and locate “Delayed Session GSM Session”.  This should give you a menu of Pipeline Single Rate Plans. Click on “Search/Reload” This pop-up window should look like this:

Click and then “Select” the GSM Sample Rate Plan. Apply changes. Next create a deal and a plan for this product. Add the Plan to the default plan list. Commit changes to the database.

Load Device Service Map

load_pin_device_permit_map pin_device_permit_map_sim_telco_gsm

load_pin_device_permit_map pin_device_permit_map_num_telco_gsm

Load Item Type Mapping

The events rated by the pipeline engine requires an /item object to associate these charges together for an account. The documentation provides examples for associating charge from New York or California to /item/gsm/new_york or item/gsm/california. For sake of simplicity we will just associate all pipeline rates events to /item/usage/gsm. To do this,   you will need to edit two xml files in the $PIN_HOME/sys/data/pricing/examples directory; config_item_tags.xml and config_item_types.xml.  Add the contents for <ItemTagElement> to the following files as shown below:

config_item_tags.xml

<ItemTagElement>
<ItemTag>gsm</ItemTag>
<EventType>/event/delayed/session/telco/*</EventType>
<ServiceType>/service/telco/gsm/*</ServiceType>
</ItemTagElement>

config_items_types.xml

<ItemTypeElement>
<ItemTag>gsm</ItemTag>
<ItemDescription>GSM Usage</ItemDescription>
<ItemType precreate=”true” type=”cumulative”>/item/usage/gsm</ItemType>
</ItemTypeElement>

To load these configuration files using the following utilities:

load_config_item_tags -dv config_item_tags.xml

load_config_item_types -dv config_item_types.xml

Using Developer Center extend the /item/usage to /item/usage/gsm. To do this start Developer Center, click on the Storable Class Editor   and click on the /item/usage class in the class window.  Then click File->New->Class and add “/gsm” to the base class.  And finally click on File->Commit Class to Database

If you get a permission error message committing these changes, recall that the DM_ORACLE pin.conf file needs to be set to enabled to changes to the class and field definitions, see below:

- dm dd_write_enable_fields 1

- dm dd_write_enable_objects 1

You will have to restart the BRM to load these changes.

Setting up GSM Accounts and Services.

Before you can create accounts using the GSM plan created in Pricing Center, you will need to load up a set of test phone numbers and SIM cards to use. What SIM card and phone number you specify will matter for testing. For instance, the pipeline will not rate any out of network calls. So all the CDRs you create to test in the pipeline will have to use phone numbers associated with accounts and services setup in BRM. But before you can do that you will need to establish a block of available numbers to select from.

I found the documentation very good for learning how to use the Number and SIM Card Administrator. These applications are used to set up a block of numbers and SIM cards that can be consumed by account telephony services in BRM. The Number Administrator was straight forward and easy to use. There are a couple things to note, however, when using the Number and SIM Card Administrator.

1) Load SIM Card types before running the SIM Card Administrator. From the PIN_HOME/sys/msgs/simcardtypes directory load the SIM card types by using the load_localized_string utility from the command line:

load_localized_strings sim_card_types.en_US

2) Use known good test SIM cards numbers.  To create a block of SIM cards you first have to order them in the SIM Card Administrator. After they are ordered you will need to fulfill the order. To make this easier, refer to the end of documentation for configuring the SIM Card Administrator. It contains a set of test SIM card numbers you can use to test with. If you don’t use these numbers, you’ll have to figure out valid fulfillment data used to activate the order.

Normally you would export a file and send this file to a supplier of SIM cards. The SIM card manufacturer would return an order fulfillment so you can activate the numbers for BRM to consume.  For testing purposes you will export the order and modify the order with test data provided in the documentation. As described in the documentation, it involves appending some order fulfillment code to the end of the exported order and then loading them back into the SIM Card Administrator.

3) Set the status to “Not Specified” when searching for SIM cards in the Customer Administrator.  When you search for SIM cards in the Customer Center, it searches through available devices (/device/sim) for SIM cards with a status of released. You can either configure the SIM Card Administrator to include “New” status, or change the status to “Not Specified”.

4) Coordinate test phone numbers with zone mapping values and CDR test data. If you plan to leverage pre-configured zone mappings and sample CDRs then you might consider creating a block of phone numbers to include these numbers. If you don’t you’ll have to edit the sample CDRs to include the ones you did use and determine how the numbers are rated and mapped in the zone map.  For reference, I included some phone numbers used in the sample CDRs. These CDRs I found in the IFW_HOME/data/in directory in a file called test_cdr.orig. The second and third field in the files are the source and destination numbers of the CDR. Again, both source and destination numbers need to be used by accounts in BRM for them to rate. No out of network phone calls will work.

TEL;00491732410;004941067600;20011114184300;300;0;0;NORM;123456;
TEL;00491732411;004941067600;20011114184300;270;0;0;NORM;123456;
TEL;00491732412;004941067600;20011114184300;110;0;0;NORM;123456;
DAT;00491732413;004941067600;20011114184300;50;0;0;NORM;123456;
FAX;00491732414;004941067600;20011114184300;12;0;0;NORM;123456;
TEL;00491732415;004941067600;20011114184300;1;0;0;NORM;123456;
SMS;00491732416;004941067600;20011114184300;63;0;0;NORM;123456;
TEL;00491732417;004941067600;20011114184300;37;0;0;NORM;123456;
TEL;00491732418;004941067600;20011114184300;132;0;0;NORM;123456;
TEL;00491732419;004941067600;20011114184300;60;0;0;NORM;123456;
TEL;00491732420;004941067600##;20040601184300;300;0;0;NORM;123456;
GPRT;00491732410;0049;20011114184510;300;78965;5054;;001121;hamburg.portal.com
GPR;00491732410;0049;20011114184510;300;78965;5054;;001121;hamburg.portal.com

And these where pulled out of the wireless.readme file:

TEL;00491729183333;004941067600;20011114184510;300;0;0;;;
TEL;00491729183333;004941067600;20011114184510;300;0;0;Mail;47113;
TEL;00491729183333;004941067600;20011114184510;300;0;0;Conf;98765; TEL;00491729183333;004941067600;20011114184510;300;0;0;MOC;238476;

Once you have a block of numbers and SIM cards configured, you can create accounts. Using Customer Center, create accounts to include phone numbers you plan to use for testing.

Process CDR File

Start up pipeline using the following command in $IFW_HOME.

ifw -r /conf/wireless.reg

Create CDR file and place into /conf/data/in

Testing and Troubleshooting Pipeline Rating

The error messages provided by the Pipeline Rating engine makes is somewhat easy locate problems. The most helpful messages are located in the $IFW_HOME/log/stream directory.  You will find two sets of logs for each input file, Stream_test_XXXX.edr.log and log_test_XXXX.edr.log. If you have CDRs in the data/in directory that don’t make it to the data/out/gsm/* check here for errors. The most common errors I found where problems with the ITEM_TAG value (being null) and problems with out of network phone numbers.  If you’re having trouble with ITEM_TAG numbers, review the section on Item Tag Mapping. If you have error message for out of network phone numbers, remember that both source and destination phone numbers need to be consumed by accounts  (in network) in order for them to be rated.

2 Comments »

 

Common BRM Pipeline Installation Issues

March 24th, 2010 by Mark Peterson • 8 Comments »

There are a lot of moving parts associated with the BRM Pipeline. Installing it can be very difficult. This blog should remove some of the obstacles you face in installing and configuring BRM pipeline.

Before we get into the installation there are a few important points to consider about Pricing Center (PC). First, the pipeline has it’s own schema where it locates and stores pipeline pricing information.  PC makes a direct connection to this schema; bypassing CM and DM_ORACLE. The PC gets the pipeline connection properties from an extension of /config object or /config/pricing_admin. This database object, PRICING_ADMIN_CONFIG_INFO_T, is created and populated using a BRM (PIN) setup script located in the $PIN_HOME/setup/scripts directory. The pipeline connection password is encrypted using AES encryption. DM_ORACLE needs to be configured properly to encrypt and decrypt this password. This blog will take you through this and other key installation steps needed to run the pipeline in BRM.

The basic steps are quite simple. However each step has several environmental traps you can fall into if you are not careful. I will list the steps and then break them down into more detail below.

1. Run the pipeline installation scripts
2. Execute the pipeline database setup scripts
3. Setup DM_ORACLE for AES encryption
4. Create the IFW Database Connection object; /config/pricing_admin.
5. Add pricing center permissions.

Run Pipeline Installation Scripts

The BRM and Pipeline code can be downloaded from the http://edelivery.oracle.com/. You will need to find and select Oracle Communication Applications and the platform you’re using. The download you need is located in  Oracle Communications Billing and Revenue Management Media Pack.

After you download the file, unzip the file into a staging directory and create a user called IFW. You may want to create a user like IFW74, if you have different versions of  the pipeline installed on your server.

Depending on the version and platform you should see a installation file called like this:

7.4_Pipeline_linux_64_opt.bin

Execute this file as the IFW user.  The installation uses X-windows so on you may need to run the following command as the root user before you’ll see the installation UI.

xhost +

Likewise, be sure you have turned on X-windows for you IFW users. This can be done by setting the following environment variable

export DISPLAY=:1.0

Specify the location of the IFW installation directory and allow the installation to complete. This installation is just unpacking files into your installation directory.  To set up the IFW user, you can execute one of these environment scripts.

source.me.csh

source.me.sh

These files are located in the IFW installation directory, $IFW_HOME.  I recommend merging the contents of this file with your login profile scripts. On linux that may be the .bash_profile file located in the IFW default user home directory.

Execute The Pipeline Database Setup Scripts

There are 4 IFW database scripts and 5 JSA database setup scripts you will need to run. These are located in the $IFW_HOME/database/Oracle/Scripts directory and they are called:

ifw_Tablespaces.sql       ifw_Create.sql               ifw_Roles.sql              ifw_Synonyms.sql

JSA_Tablespaces.sql     JSA_Create.sql            JSA_Roles.sql             JSA_Synonyms.sql            JSA_Prepare.sql

Three important tables need to be populated correctly; JSA_USER, JSA_MODULES and JSA_USERRIGHT.  Running the setup script, pricing_admin.pl script as describe below, can do this for you, but it requires SYSDBA access to do so.  A DBA can use the scripts in the Appendix to populate them with data. Be sure to edit them first with schema names you picked.

Setup DM_Oracle for AES encryption

As the pin user create an AES encryption key using the following application:

pin_crypt_app -genkey

This will create an output that looks like this:

Generation of Encrypted AES key is successful Encrypted key is --->&aes|0D5E11BFDD97D2769D9B0DBFBD1BBF7E29943F470AE3525E8BFDE27A5F7ED93AF0C343CF7CE98A5255D38D903FA8820<---

Copy the lines between the —>   and <—- and place them into the sys/oracle/pin.conf file as shown:

- crypt aes| ${PIN_HOME}/lib/${LIBRARYPREFIX}pin_crypt_aes4dm${LIBRARYEXTENSION} "&aes|0D5E11BFDD97D2769D9B0DBFBD1BBF7E925A04A595DD6EEF9FEC7453C1C83C7C0BD82702ABFE9CB01C7D39F9D56"

Do not copy the key I used here. Substitute the key for the one you created with the pin_crypt_app. Bounce the CBRM using stop_all and start_all and make sure the DM_Oracle comes up again.

Create the IFW Database Connection object; /config/pricing_admin

Locate the pin.conf file in the $PIN_HOME/setup/scripts directory

Edit the following entries to contain the proper IFW connection information

- pipeline login_name IFW74
- pipeline login_pw IFW74
- pipeline port 1521
- pipeline db_type oracle
- pipeline db pindb
- pipeline admin system
- pipeline admin_pw manager
- pipeline db_alias pindb

Run the pricing admin_perl script using the following command line:

perl pricing_admin.pl -init

This will use the values in the pin.conf file and create and populate the PRICING_ADMIN_CONFIG_INFO_T table in the PIN DB schema.  Allow this perl script to set the AES encryption directly. If you try to do this with direct sql updates, this will cause problems with DM_ORACLE when it tries to read the object.  Allow DM_ORACLE to encrypt the password. DM_ORACLE will decrypt the password before it passes it to client application through the CM.

This perl script will also create the JSA USER and roles in the JSA tables and schema. In order for it to do this you must give it a sysdba admin user and password. The perl script creates the user, creates synonyms and grants the user permissions to create tables, views, indexes, etc.  This may not be acceptable in some organizations. The appendix contains scripts that can be used by a DBA to do this according to corporates policies and procedures.

Add Pricing Center Permissions

Using Customer Center or Permission Center add the following read/write permissions to the root.0.0.0.1 user:

/pricingcenter/databaseaccess
/pricingcenter/filesystemaccess
/appcenter/pricingcenter
/loadpricelist/access
/appcenter/provisioningtags
/appcenter/pcenter

Test the configuration by bringing up the Pricing Center. Verify that you have access to the pipeline configuration tools in the pricing center.

Troubleshooting Pricing Center

If  you may get the error message “Unable to connect to the pipeline database.  Please contact your administrator”. when starting up Pricing Center,  check to be sure you can connect to the Pipeline database using the connection properties specified in the config/pricing_admin object.

You may also get this error message if you can log into the pipeline database, but the user cannot access the JSA_USER, JSA_MODULE, or JSA_USERRIGHT tables.

Appendix A. SQL Scripts for JSA_USER

Insert into JSA_USER (USER_ID,LEADER_ID,ACTIVE,LOGIN,USR_FIRSTNAME,USR_LASTNAME,USR_AUTHID,ENTRYDATE,ENTRYBY, MODIFDATE,MODIFBY,MODIFIED,RECVER) values (0,null,1,'JSA','Default','JSA ADMIN',null,to_timestamp('16-MAR-10','DD-MON-RR HH.MI.SSXFF AM'),0,null,null,1,0);
Insert into JSA_USER (USER_ID,LEADER_ID,ACTIVE,LOGIN,USR_FIRSTNAME,USR_LASTNAME,USR_AUTHID,ENTRYDATE,ENTRYBY, MODIFDATE,MODIFBY,MODIFIED,RECVER) values (100,null,1,'IFW74','Default','IntegRate DB Admin',null,to_timestamp('16-MAR-10','DD-MON-RR HH.MI.SSXFF AM'),0,null,null,1,0);

Appendix B. SQL Scripts for JSA_USERRIGHT


Insert into JSA_USERRIGHT (USER_ID,MODULE_ID,CANINSERT,CANUPDATE,CANDELETE,CANREAD,CANPRINT,ENTRYDATE,ENTRYBY, MODIFDATE,MODIFBY,MODIFIED,RECVER) values (100,102,1,1,1,1,1,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,1,0);
Insert into JSA_USERRIGHT (USER_ID,MODULE_ID,CANINSERT,CANUPDATE,CANDELETE,CANREAD,CANPRINT,ENTRYDATE,ENTRYBY, MODIFDATE,MODIFBY,MODIFIED,RECVER) values (100,104,1,1,1,1,1,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,1,0);
Insert into JSA_USERRIGHT (USER_ID,MODULE_ID,CANINSERT,CANUPDATE,CANDELETE,CANREAD,CANPRINT,ENTRYDATE,ENTRYBY, MODIFDATE,MODIFBY,MODIFIED,RECVER) values (100,105,1,1,1,1,1,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,1,0);
Insert into JSA_USERRIGHT (USER_ID,MODULE_ID,CANINSERT,CANUPDATE,CANDELETE,CANREAD,CANPRINT,ENTRYDATE,ENTRYBY, MODIFDATE,MODIFBY,MODIFIED,RECVER) values (100,106,1,1,1,1,1,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,1,0);
Insert into JSA_USERRIGHT (USER_ID,MODULE_ID,CANINSERT,CANUPDATE,CANDELETE,CANREAD,CANPRINT,ENTRYDATE,ENTRYBY, MODIFDATE,MODIFBY,MODIFIED,RECVER) values (100,107,1,1,1,1,1,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,1,0);
Insert into JSA_USERRIGHT (USER_ID,MODULE_ID,CANINSERT,CANUPDATE,CANDELETE,CANREAD,CANPRINT,ENTRYDATE,ENTRYBY, MODIFDATE,MODIFBY,MODIFIED,RECVER) values (100,108,1,1,1,1,1,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,1,0);
Insert into JSA_USERRIGHT (USER_ID,MODULE_ID,CANINSERT,CANUPDATE,CANDELETE,CANREAD,CANPRINT,ENTRYDATE,ENTRYBY, MODIFDATE,MODIFBY,MODIFIED,RECVER) values (100,109,1,1,1,1,1,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,1,0);
Insert into JSA_USERRIGHT (USER_ID,MODULE_ID,CANINSERT,CANUPDATE,CANDELETE,CANREAD,CANPRINT,ENTRYDATE,ENTRYBY, MODIFDATE,MODIFBY,MODIFIED,RECVER) values (100,110,1,1,1,1,1,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,1,0);
Insert into JSA_USERRIGHT (USER_ID,MODULE_ID,CANINSERT,CANUPDATE,CANDELETE,CANREAD,CANPRINT,ENTRYDATE,ENTRYBY, MODIFDATE,MODIFBY,MODIFIED,RECVER) values (100,111,1,1,1,1,1,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,1,0);
Insert into JSA_USERRIGHT (USER_ID,MODULE_ID,CANINSERT,CANUPDATE,CANDELETE,CANREAD,CANPRINT,ENTRYDATE,ENTRYBY, MODIFDATE,MODIFBY,MODIFIED,RECVER) values (100,112,1,1,1,1,1,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,1,0);
Insert into JSA_USERRIGHT (USER_ID,MODULE_ID,CANINSERT,CANUPDATE,CANDELETE,CANREAD,CANPRINT,ENTRYDATE,ENTRYBY, MODIFDATE,MODIFBY,MODIFIED,RECVER) values (100,113,1,1,1,1,1,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,1,0);

Appendix C. SQL Scripts for JSA_MODULES


Insert into JSA_MODULE (MODULE_ID,MODULENAME,NAME,DESCRIPTION,ENTRYDATE,ENTRYBY,MODIFDATE,MODIFBY,MODIFIED, RECVER) values (100,'accessmanagement','accessmanagement','accessmanagement',to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),null,1,0);
Insert into JSA_MODULE (MODULE_ID,MODULENAME,NAME,DESCRIPTION,ENTRYDATE,ENTRYBY,MODIFDATE,MODIFBY,MODIFIED,RECVER) values (101,'toolbarconfiguration','toolbarconfiguration','toolbarconfiguration',to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),null,1,0);
Insert into JSA_MODULE (MODULE_ID,MODULENAME,NAME,DESCRIPTION,ENTRYDATE,ENTRYBY,MODIFDATE,MODIFBY,MODIFIED,RECVER) values (102,'databasebrowser','databasebrowser','databasebrowser',to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),null,1,0);
Insert into JSA_MODULE (MODULE_ID,MODULENAME,NAME,DESCRIPTION,ENTRYDATE,ENTRYBY,MODIFDATE,MODIFBY,MODIFIED,RECVER) values (103,'bulletinboard','bulletinboard','bulletinboard',to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),null,1,0);
Insert into JSA_MODULE (MODULE_ID,MODULENAME,NAME,DESCRIPTION,ENTRYDATE,ENTRYBY,MODIFDATE,MODIFBY,MODIFIED,RECVER) values (104,'IntSmacc.Product','IntSmacc.Product','IntSmacc.Product',to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),null,1,0);
Insert into JSA_MODULE (MODULE_ID,MODULENAME,NAME,DESCRIPTION,ENTRYDATE,ENTRYBY,MODIFDATE,MODIFBY,MODIFIED,RECVER) values (105,'IntSmacc.Mapping','IntSmacc.Mapping','IntSmacc.Mapping',to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),null,1,0);
Insert into JSA_MODULE (MODULE_ID,MODULENAME,NAME,DESCRIPTION,ENTRYDATE,ENTRYBY,MODIFDATE,MODIFBY,MODIFIED,RECVER) values (106,'IntSmacc.Zone','IntSmacc.Zone','IntSmacc.Zone',to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),null,1,0);
Insert into JSA_MODULE (MODULE_ID,MODULENAME,NAME,DESCRIPTION,ENTRYDATE,ENTRYBY,MODIFDATE,MODIFBY,MODIFIED,RECVER) values (107,'IntSmacc.Rating','IntSmacc.Rating','IntSmacc.Rating',to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-00','DD-MON-RR HH.MI.SSXFF AM'),null,1,0);
Insert into JSA_MODULE (MODULE_ID,MODULENAME,NAME,DESCRIPTION,ENTRYDATE,ENTRYBY,MODIFDATE,MODIFBY,MODIFIED,RECVER) values (108,'IntSmacc.Time','IntSmacc.Time','IntSmacc.Time',to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),null,1,0);
Insert into JSA_MODULE (MODULE_ID,MODULENAME,NAME,DESCRIPTION,ENTRYDATE,ENTRYBY,MODIFDATE,MODIFBY,MODIFIED,RECVER) values (109,'IntSmacc.Interconnection','IntSmacc.Interconnection','IntSmacc.Interconnection',to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),null,1,0);
Insert into JSA_MODULE (MODULE_ID,MODULENAME,NAME,DESCRIPTION,ENTRYDATE,ENTRYBY,MODIFDATE,MODIFBY,MODIFIED,RECVER) values (110,'IntSmacc.Discount','IntSmacc.Discount','IntSmacc.Discount',to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),null,1,0);
Insert into JSA_MODULE (MODULE_ID,MODULENAME,NAME,DESCRIPTION,ENTRYDATE,ENTRYBY,MODIFDATE,MODIFBY,MODIFIED,RECVER) values (111,'IntSmacc.Aggregate','IntSmacc.Aggregate','IntSmacc.Aggregate',to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),null,1,0);
Insert into JSA_MODULE (MODULE_ID,MODULENAME,NAME,DESCRIPTION,ENTRYDATE,ENTRYBY,MODIFDATE,MODIFBY,MODIFIED,RECVER) values (112,'IntSmacc.UniversalMapping','IntSmacc.UniversalMapping','IntSmacc.UniversalMapping',to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),null,1,0);
Insert into JSA_MODULE (MODULE_ID,MODULENAME,NAME,DESCRIPTION,ENTRYDATE,ENTRYBY,MODIFDATE,MODIFBY,MODIFIED,RECVER) values (113,'IntSmacc.MISC','IntSmacc.MISC','IntSmacc.MISC',to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),100,to_timestamp('25-AUG-09','DD-MON-RR HH.MI.SSXFF AM'),null,1,0);

8 Comments »

 

Customizing Oracle BPM using Worklist Decorator

February 19th, 2010 by Mark Peterson • No Comments »

Customizing the Oracle BPM Worklist can be done by creating and adding a Worklist Decorator class to your configuration. There are many reasons why you may want to do this. You may want to color code low, medium and high priority work items, format a display value with an icon or image, or you may just want to alternately shade lines in the BPM workspace as shown below.

dec_worklist

Oracle BPM versions 6.x to 10g (Aqualogic BPM )  allow you to do this.  For the complete java class see WorkListDecorator Sample Code below. This code implements three methods that can be used to alter the way the work list appears these methods are as follows:

public String getCellStyle(String viewName, InstanceInfo instance, Column columnInfo, int rowNo) ;

public String getRowStyle(String viewName, InstanceInfo instance, int rowNo) ;

public String getValue(String viewName, InstanceInfo instance, Column columnInfo, Locale locale, String value, int rowNo) ;

These three methods are call-back methods used by the BPM Workspace application to get custom attributes associated with the work-list.  The input parameters contain pertinent important information you can use to decorate the work-list as required. This information is described in the table below.

Field Name Description
String viewName Name of the view. The default work-list name is unified-inbox. If you create custom views, this will be populated with the name of the custom view.
InstanceInfo  instanceInfo Contains detailed information about the instance; like activity name, instance name, instance variables and process details.
Column Contains information about the column, like column size, format and ID.
Locale locale Contains information about the locale
String value Contains the display value (String contents) of the field value.
int rowNo The row number starting with zero.

<br/>

To register your custom decorator object with your workspace, locate the workspace.properties files and modify the entry as show below. This file is located in the <BPM_HOME>/webapps/workspace/WEB-INF directory

fuego.workspace.worklist.styleResolverClassname=com.ssglimited.workspace.view.WorkListDecoratorImpl

You will need to compile your WorkListDecorator object and place the complied java object (.class) or jar file in the <BPM_HOME>/webapps/workspace/WEB-INF/classes or <BPM_HOME>/webapps/workspace/WEB-INF/lib directory. If you are using BPM in an application server like Weblogic, you will need to re-build the workspace and redeploy the workspace ear file. This can be done in the Process Administrator.

If you are having difficulty getting this to work, turn on the Workspace log. For enterprise versions, simply look in the App Server console or edit the logging in the workspace.properties file. For Studio, refer to my blog post on Workspace Logging.

WorkListDecorator Sample Code for Shading lines in the Work-list

</code>

package com.ssglimited.workspace.view;

import java.util.Locale;

import fuego.workspace.model.view.WorkListDecorator;
import fuego.papi.InstanceInfo;
import fuego.papi.Presentation.Column;
public class WorkListDecoratorImpl implements WorkListDecorator{

public String getCellStyle(String viewName, InstanceInfo instanceInfo, Column columnInfo, int rowNo) {
return "";
}
public String getRowStyle(String viewName, InstanceInfo instanceInfo, int rowNo) {
String inlineStyle="background-color: #ffff"; //White
if (rowNo % 2 > 0) {
inlineStyle="background-color: #f8f8f8"; //Gray
}
return inlineStyle;
}

public String getValue(String viewName, InstanceInfo instance, Column columnInfo, Locale locale, String value, int rowNo) {
// System.out.println("***Mark Test **** "+viewName+" column"+ arg2.getId()+"arg4"+ value +" "+rowNo);
return value;

}
}

No Comments »

 

How to Turn on Workspace Logging in Oracle BPM Studio (10g or 6.x)

February 19th, 2010 by Mark Peterson • 3 Comments »

If you are having trouble with the Workspace in Oracle BPM Studio, it is easy to turn on logging – once you know how.  You might need to do this if you are customizing the workspace or adding a custom decorator to the worklist panel.

To access the logs, locate the eclipse.ini file and add the following line to the beginning of the file. Do not add any blank lines or spaces before or after this entry. This file is located in the <OracleBPMStudioHome>/eclipse directory.

-consoleLog

Next time you restart BPM studio, a console window will open with Studio. Logging from the workspace, Tomcat and eclipse will go into the console. This works with all versions of Oracle BPM running in eclipse; Oracle BPM 10g and Aqualogic BPM 6.x

3 Comments »

 

Creating Oracle BPM PAPI Clients

February 17th, 2010 by Mark Peterson • 1 Comment »

To interface Oracle BPM 10g (or AquaLogic BPM 6.x or Fuego) to external systems you may want to use PAPI.  PAPI is the name for the BPM API. It is a carry over from the Fuego days and stood for Portal API.  This is a good name for the API  since the Portal (or workspace) uses PAPI to interface with the BPM engine. This API is available for you to use as well.

Since the workspace uses it, anything you can do from the workspace you can do through PAPI. Likewise most things you can do from the Process Administrator, you can do from PAPI as well. Some common things you can do through PAPI.

  • Create a new process instance or work item.
  • Pause, suspend and resume process instances.
  • Interact with an external UI activity from an external UI.
  • Notify a process that some event occurred and pass in arguments to the process.
  • Create user, roles and assign users to roles.

PAPI is the most versatile tool to use to interface client apps to BPM.  If you just want to notify an instance, you can expose the process and notification waits using BPM web-services. You just have to set a switch to do this and use the WSDL to interface with the process. But you can’t do much more than this with BPM web-services. If you need more functionality, you will need to use PAPI.

I will give you the basic tools to do these things and more from a PAPI client. At the end of this blog, you will find a sample PAPI client Java code. I’ve used this client object to develop client applications. Over the years I’ve added some functionality and taken some away. This has most of what you’ll need.

Running a PAPI Client against Enterprise Standalone

It is difficult to use PAPI to interact with a process running in Studio. You will need to deploy your process to Enterprise Standalone or WebLogic. If you deploy your process to Enterprise Standalone, you will be able to connect to PAPI simply by referring to a copy of directory.properties file.  This file is located in the BPM installation directory.  Before you copy this file be sure it is valid.  This file is created by the Admin tool when it creates and configures the directory.  If you can connect to the directory and processes are being deployed and working then you have a valid directory.properties file.

Running a PAPI Client against a Weblogic Server

If  you’re trying to connect to a process running inside WLS, you need to provide a JNDI name and context factory. All you need to do is include the weblogic.jar file (or wlclient.jar)  with your PAPI client code and specify the connection properties.  The connection properties are stored in a file and referenced by the JNDI context using the following JRE system property.

-Dfuego.j2ee.initialctx.file=c:\bea\config\papiJndi.properties

Place these contents into the referenced file; i.e. papiJndi.properties.  You’ll need to modify the host name and port number according to the Weblogic container settings used by the BPM engine.

# Weblogic JNDI configuration to connect to the weblogic server
java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory
java.naming.provider.url=t3://localhost:7001
# example java.naming.provider.url=t3://localhost:7001

You will also need to do this if your PAPI client is running in a different container than where the PAPI engine is running.  To make this work all you have to do is modify the setDomainEnv.cmd file by adding the JRE system property. This file is located next to the startWeblogic script,  in the user_projects/domains/<your-domain>/bin directory.

Sample PAPI Client Code (Java)

Here’s an example Java client class I find helpful getting started. It contains methods for connecting to PAPI,  searching for instances, executing global activities, and call-back methods for interacting with external interactive activities.  This code will compile if you include the fuegopapi-client.jar file with your code.

</code>

package com.ssglimited.businessServices;

import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import fuego.lang.ConnectionPassport;
import fuego.papi.Arguments;
import fuego.papi.BatchOperationException;
import fuego.papi.Comparison;
import fuego.papi.Filter;
import fuego.papi.InstanceInfo;
import fuego.papi.OperationException;
import fuego.papi.ProcessService;
import fuego.papi.ProcessServiceSession;
import fuego.papi.SearchScope;
import fuego.papi.VarDefinition;

/**
*
* Provide convenience for creating ALBPM PAPI Web Service objects needed
* to utilize External Task functionality.
*
* @author Mark Peterson
*
*/
public class PapiServiceHelper {

//    private static final Log log = LogFactory.getLog(PapiServiceHelper.class);
//    private ProcessService service = null;
private String endPointUrl = "", userId="", password="";
private ProcessServiceSession session = null;
private String directoryFile;

/**
*
* Construction will initialize the necessary PAPI objects for subsequent usage
*
* @param String containing URL of ALBPM engine SOAP server
* @param String containing userid for PAPI connection
* @param String with password
* @throws IllegalStateException if private variables not initialized
* @throws RemoteException as a consequence of using PAPI service
* @throws OperationException
*/
public PapiServiceHelper (){

}

/**
*
* Initializes the necessary PAPI objects for subsequent usage
*
* @return ProcessService used in subsequent operations
* @throws IllegalStateException if private variables not initialized
* @throws RemoteException as a consequence of using PAPI service
* @throws OperationException
*/
private void initSession() throws RemoteException, OperationException {

// Creates the properties to create the ProcessService.
Properties properties = new Properties();

// Set the directory Id that we use.
properties.setProperty(ProcessService.DIRECTORY_ID, "default");

// Set the directory file that we use, this file is in the classpath.
// The directory properties can either be in the classpath, or be a file location.
properties.setProperty(ProcessService.DIRECTORY_PROPERTIES_FILE, "C:\\workspace\\papiSample\\config\\directory.properties");

// Set the maximum size of the instance cache per process.
properties.setProperty(ProcessService.INSTANCES_CACHE_SIZE, "50000");

// Set the folder where PAPI will store catalogs and temporary files.
properties.setProperty(ProcessService.WORKING_FOLDER, "c:\\bea\\temp");

// Set that the sessions will be notified when an instance is updated.
properties.setProperty(ProcessService.UPDATE_SESSIONS_VIEWS, "true");

System.out.println("ProcessService properties=\n"+properties);
// Creates the ProcessService.
ProcessService processService = ProcessService.create(properties);

// Creates the passport for the user which will connect.
ConnectionPassport passport = processService.createPassport(userId);

// Sets the passpord of the user.
passport.setPassword(password);

// Completes the given passport for authentication purposes.
passport.fillPassport();

// Creates a new session.
// The arguments are the passport of the user and the host where the user is connected from.
session = processService.createSession(passport, "localhost");

}

public Map runGlobal(String processId, Map params) throws RemoteException, OperationException {
if (session==null) initSession();

Arguments args = Arguments.create();
Iterator itParams = params.keySet().iterator();
while(itParams.hasNext()) {
String key = (String)itParams.next();
args.putArgument(key, params.get(key));
}

session.runGlobalActivity(processId, args);

Map returnMap = new HashMap();
String[] argNames = args.getArgumentsName();
for(int i=0;i<argNames.length;i++){
returnMap.put(argNames[i], args.getArgument(argNames[i]));
}
return (Map)returnMap;
}

public List getCodes( String type ) throws OperationException, RemoteException {
if (session==null) initSession();

Arguments args = Arguments.create();
args.putArgument("type", type);

session.runGlobalActivity("/StaffReviewProcess/GetCodes", args);

List codesList = (List) args.getArgument("codesList");
System.out.println("CodesList="+codesList);
return codesList;
}

/**
*
* The PAPI <code>prepareExternalActivity</code> service is invoked for the input instance/activity.
*
* @param String containing instance ID
* @param String containing External Task activity name
* @param KeyValuePair array with input arguments of prepare method
* @return KeyValuePair containing PAPI session ID
* @throws IllegalStateException if private variables not initialized
* @throws RemoteException passed along from PAPI
* @throws OperationException
*/
public Arguments runPrepare(String instanceId,String activityNm,Arguments inArgs) throws IllegalStateException, RemoteException, OperationException {

if (session==null) initSession();
Arguments outArgs = session.prepareExternalActivity(instanceId, activityNm, inArgs);
return outArgs;
}

/**
*
* The PAPI <code>commitExternalActivity</code> service is invoked for the input instance/activity.
*
* @param String containing instance ID
* @param String containing External Task activity name
* @param KeyValuePair array with input arguments of commit method
* @throws IllegalStateException if private variables not initialized
* @throws RemoteException passed along from PAPI
* @throws OperationException
*/
public InstanceInfo runCommit(String instanceId,String activity,Arguments inArgs) throws IllegalStateException, RemoteException, OperationException {
if (session==null) initSession();
return session.commitExternalActivity(instanceId, activity, inArgs);
}

public InstanceInfo[] findInstanceByFilter(String activity) throws BatchOperationException, RemoteException, OperationException {
if (session==null) initSession();
String[] processes = session.getProcessIds();
System.out.println("Processes="+processes);
// Search instances which begin with a specific string in an external variable value and
// stay in a specific activity.
Filter filter = ProcessService.createFilter();
SearchScope searchScope = new SearchScope(fuego.papi.ParticipantScope.PARTICIPANT_ROLES,
fuego.papi.StatusScope.ALL);
filter.setSearchScope(searchScope);
filter.setMatchAll(true);
//         filter.addAttribute(session.getVar("MyExternalVariable"), Comparison.BEGIN_WITH, "Fuego");
filter.addAttribute(session.getVar(VarDefinition.ACTIVITY_ID), Comparison.IS, activity);

// Search instances.
InstanceInfo[] instances = session.getInstancesByFilter(processes, filter);
//         instances[0].getVar(arg0, arg1)
return instances;
}

}

<code>

package com.bea.bootcamp.businessServices;//import javax.xml.rpc.ServiceException;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;import fuego.lang.ConnectionPassport;
import fuego.papi.Arguments;
import fuego.papi.BatchOperationException;
import fuego.papi.Comparison;
import fuego.papi.Filter;
import fuego.papi.InstanceInfo;
import fuego.papi.OperationException;
import fuego.papi.ProcessService;
import fuego.papi.ProcessServiceSession;
import fuego.papi.SearchScope;
import fuego.papi.VarDefinition;

/**
*
* Provide convenience for creating ALBPM PAPI Web Service objects needed
* to utilize External Task functionality.
*
* @author BEA Professional Services
*
*/
public class PapiServiceHelper {

//    private static final Log log = LogFactory.getLog(PapiServiceHelper.class);
//    private ProcessService service = null;
private String endPointUrl = “”, userId=”", password=”";
private ProcessServiceSession session = null;
private String directoryFile;

/**
*
* Construction will nitialize the necessary PAPI objects for subsequent usage
*
* @param String containing URL of ALBPM engine SOAP server
* @param String containing userid for PAPI connection
* @param String with password
* @throws IllegalStateException if private variables not initialized
* @throws RemoteException as a consequence of using PAPI service
* @throws OperationException
*/
public PapiServiceHelper (){

}

/**
*
* Initializes the necessary PAPI objects for subsequent usage
*
* @return ProcessService used in subsequent operations
* @throws IllegalStateException if private variables not initialized
* @throws RemoteException as a consequence of using PAPI service
* @throws OperationException
*/
private void initSession() throws RemoteException, OperationException {

// Creates the properties to create the ProcessService.
Properties properties = new Properties();

// Set the directory Id that we use.
properties.setProperty(ProcessService.DIRECTORY_ID, “default”);

// Set the directory file that we use, this file is in the classpath.
// The directory properties can either be in the classpath, or be a file location.
properties.setProperty(ProcessService.DIRECTORY_PROPERTIES_FILE, “C:\\workspace\\FtMeade\\papiSample\\config\\directory.properties”);

// Set the maximum size of the instance cache per process.
properties.setProperty(ProcessService.INSTANCES_CACHE_SIZE, “50000″);

// Set the folder where PAPI will store catalogs and temporary files.
properties.setProperty(ProcessService.WORKING_FOLDER, “c:\\bea\\temp”);

// Set that the sessions will be notified when an instance is updated.
properties.setProperty(ProcessService.UPDATE_SESSIONS_VIEWS, “true”);

System.out.println(“ProcessService properties=\n”+properties);
// Creates the ProcessService.
ProcessService processService = ProcessService.create(properties);

// Creates the passport for the user which will connect.
ConnectionPassport passport = processService.createPassport(userId);

// Sets the passpord of the user.
passport.setPassword(password);

// Completes the given passport for authentication purposes.
passport.fillPassport();

// Creates a new session.
// The arguments are the passport of the user and the host where the user is connected from.
session = processService.createSession(passport, “localhost”);

}

public Map runGlobal(String processId, Map params) throws RemoteException, OperationException {
if (session==null) initSession();

Arguments args = Arguments.create();
Iterator itParams = params.keySet().iterator();
while(itParams.hasNext()) {
String key = (String)itParams.next();
args.putArgument(key, params.get(key));
}

session.runGlobalActivity(processId, args);

Map returnMap = new HashMap();
String[] argNames = args.getArgumentsName();
for(int i=0;i<argNames.length;i++){
returnMap.put(argNames[i], args.getArgument(argNames[i]));
}
return (Map)returnMap;
}

public List getCodes( String type ) throws OperationException, RemoteException {
if (session==null) initSession();

Arguments args = Arguments.create();
args.putArgument(“type”, type);

session.runGlobalActivity(“/StaffReviewProcess/GetCodes”, args);

List codesList = (List) args.getArgument(“codesList”);
System.out.println(“CodesList=”+codesList);
return codesList;
}

/**
*
* The PAPI <code>prepareExternalActivity</code> service is invoked for the input instance/activity.
*
* @param String containing instance ID
* @param String containing External Task activity name
* @param KeyValuePair array with input arguments of prepare method
* @return KeyValuePair containing PAPI session ID
* @throws IllegalStateException if private variables not initialized
* @throws RemoteException passed along from PAPI
* @throws OperationException
*/
public Arguments runPrepare(String instanceId,
String activityNm,
Arguments inArgs)
throws IllegalStateException, RemoteException, OperationException {

if (session==null) initSession();
Arguments outArgs = session.prepareExternalActivity(instanceId, activityNm, inArgs);
return outArgs;
}

/**
*
* The PAPI <code>commitExternalActivity</code> service is invoked for the input instance/activity.
*
* @param String containing instance ID
* @param String containing External Task activity name
* @param KeyValuePair array with input arguments of commit method
* @throws IllegalStateException if private variables not initialized
* @throws RemoteException passed along from PAPI
* @throws OperationException
*/
public InstanceInfo runCommit(String instanceId,
String activity,
Arguments inArgs)
throws IllegalStateException, RemoteException, OperationException {
if (session==null) initSession();
return session.commitExternalActivity(instanceId, activity, inArgs);
}

/**
*
* Kill PAPI session
* @throws BatchOperationException
* @throws OperationException
* @throws RemoteException
*
* @throws RemoteException passed along from PAPI
*
*/
//    public void closeSession() throws RemoteException {

//        if (service != null && sessionId != null) {
//        service.close(sessionId);
//            log.info(“service session closed…”);
//        }

//    }
public InstanceInfo[] findInstanceByFilter(String activity) throws BatchOperationException, RemoteException, OperationException {
if (session==null) initSession();
String[] processes = session.getProcessIds();
System.out.println(“Processes=”+processes);
// Search instances which begin with a specific string in an external variable value and
// stay in a specific activity.
Filter filter = ProcessService.createFilter();
SearchScope searchScope = new SearchScope(fuego.papi.ParticipantScope.PARTICIPANT_ROLES,
fuego.papi.StatusScope.ALL);
filter.setSearchScope(searchScope);
filter.setMatchAll(true);
//         filter.addAttribute(session.getVar(“MyExternalVariable”), Comparison.BEGIN_WITH, “Fuego”);
filter.addAttribute(session.getVar(VarDefinition.ACTIVITY_ID), Comparison.IS, activity);

// Search instances.
InstanceInfo[] instances = session.getInstancesByFilter(processes, filter);
//         instances[0].getVar(arg0, arg1)
return instances;
}

/**
* @return the endPointUrl
*/
public String getEndPointUrl() {
return endPointUrl;
}

/**
* @return the password
*/
public String getPassword() {
return password;
}

/**
* @param password the password to set
*/
public void setPassword(String password) {
this.password = password;
}

/**
* @return the userId
*/
public String getUserId() {
return userId;
}

/**
* @param userId the userId to set
*/
public void setUserId(String userId) {
this.userId = userId;
}

/**
* @param endPointUrl the endPointUrl to set
*/
public void setEndPointUrl(String endPointUrl) {
this.endPointUrl = endPointUrl;
}

public String getDirectoryFile() {
return directoryFile;
}

public void setDirectoryFile(String directoryFile) {
this.directoryFile = directoryFile;
}

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
PapiServiceHelper helper = new PapiServiceHelper();
helper.setPassword(“p”);
helper.setUserId(“Colleen”);
try {
helper.findInstanceByFilter(“WorkOnTask”);
} catch (BatchOperationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (OperationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

1 Comment »

 

Protected: Coming Soon: Leveraging BPM 11g Capabilities – Argument Mapping

February 11th, 2010 by Mark Peterson • Comments Off

This post is password protected. To view it please enter your password below:


Comments Off

 

Agent-based Models Gaining Interest for Enterprise Transformations

October 14th, 2009 by Mark Peterson • No Comments »

Agent-based modeling seems to be gaining a lot of attention. Bo Parker, PricewaterhouseCoopers, presented how agent-based modeling is helping transform business enterprise by modeling and acurately predicting the outcome of complex adaptive systems. The presentation was given at a packed audience at the Nouvelle Theatre during Oracle Open World 2009. The material applies to nearly all aspects of an enterprise.

Complex adaptive systems relate to social networks, customer behaviour, game theory and process improvements. Agent-based modeling is used to predict the outcome of the systems as-they-are or when changes are introduced into the system. It has been used primarily for academic purposes but with new visualization based tools such as AnyLogic, XJ Technologies, they are becoming more common-place in industry as well.

Mr. Parker presented several case-studies involving capacity planning for health care facilities and predicting tragic events as occurred at a British-Patroleum refinery in Texas City, Texas.

March 2005, an explosion rocked the small town of Texas City, killing 15 people and injured 150. The agent-based model was used to model simple human behavoiur mechanism such as how long it takes to return phone calls and distribute emails. The simulation was run over several scenarios to determine how and why a company like BP with good process controls and good safety records, fell prey to such a catastrophe. The models showed how insignificant behaviour like responding to email messages and phone calls in relation to process improvement initiatives, caused the failure. Without such models something as seemingly insignificant would have been over-looked

Mr. Parker sees a growing trend to use these models to transform the enterprise allowing to be more adaptive, anticipate change; without adverse affects. A company like 3M would have benefited by this when it began 6-sigma improvements.

In the 1990′s after major successes in innovation, 3M began suffering from poor profits. They brought in a new CEO with proven 6-sigma credentials who cut costs, improved quality and regained profitability; only to see a sudden drop in innovation. Agent-based modeling could have predicted and avoided this harmful side-affect.

As agent-based models become prolific, Mr Parker expects a convergence of models. Models for Operations, Enterprise Architectures and Business Process Management will converge as they take advantage of the predictive abilities of agent-based models. This will be evident, Mr Parker believes, as the semantics of these tools begin to blur the current boundaries of these tools.

No Comments »

 

Oracle BPM 11g Preview at Oracle Open World 2009

October 13th, 2009 by Mark Peterson • 4 Comments »

I think the wait was worth it. After BEA’s AquaLogic BPM (formerly Fuego) was purchased by Oracle, the product became part of the Oracle Fusion Middleware suite. But instead of being in the lime-light of Fusion, for the past year it was hardly mentioned. The Marketing story focused on SOA, Tuxedo, WebCenter and WebLogic. For BPM pure-plays, BPM has its own story, a good story; one with business centered not IT centered values.

Well there it is! It re-appeared in a General Session at Oracle Open World 2009 with all the other Fusion Middleware products. The product development team must have been busy. They took Aqualogic BPM apart and re-assemble it with more features and benefits for the business than ever before. Eduardo Chiocconi and Mariano Benitez demonstrated the new version of BPM at the Moscone West Exhibit hall. The product has been integrated with JDeveloper and Enterprise Manager. It is part of the Fusion middleware product suite and seems to have more capability than before.

For businesses, the need for a rich user-experience has been achieved. The BPM studio is integrated with the ADF development environment; a JSF-based technology. You can develop UIs from studio or import ADF projects and use them in interactive BPM activities. This segmentation of the business process from the UI should also allow the UI to take advantage of externally developed UIs; something that was lacking before in BPM. This segmentation may make it easier to integrate legacy UI applications, perhaps even UIs not based in ADF.

BPM 11g has also improved on the type of roles available for activities. You can now specify interactive tiers for approval or review activities. For instance, if the CFO needs to approve purchases over $100,000, then the work-item can be escalated without coding specialized escalation processes to route the purchase orders based on these rules. These rules of who and when people need to review or approve work can change. BPM now handles this without the need for re-writing and re-deploying the new processes. An administrator can simple re-configure the user-roles.

BPM 11g has many other features as well. It has a state-of-the-art rules engine. It can handle most business rules and conditional requirements without the need to integrate third-party rules engines. It has a new milestone activity switch to enhance business activity monitoring and instance processing by the workspace. It also has integrated Oracle BAM to enhance the ability to obtain information about the business process.

BPM 11g adds these features on top of the 10g BPM feature set, so the return for implementing BPM is improved. I was only able to get a glimpse of the new Oracle BPM 11g, but from this glimpse I am excited about the possibilities. Oracle 11g will not be available for download until Feb 2010. I am looking forward to getting my hands on the new version and feel at this time, the wait will be worth it.

4 Comments »

 

Oracle 11g Strategies for BPM: A Step in the Right Direction?

October 9th, 2009 by Mark Peterson • No Comments »

With Oracle Open World 2009 around the corner, it will be interesting to see how the BPM community reacts to the changes being offered. I have found the story around Oracle Fusion a bit confusing, especially how it plays in BPM solution space. The BPM pure plays, like AquaLogic and Lambardi had a clear vision and strategy. Now that Oracle has acquired Aqualogic (formerly Fuego) BPM, Oracle should have a strong hold on this market. Without some course correction on Oracles part, I feel the BPM strategy may get blurred. The jury is still out. I am hopeful but concerned.

More to come.

No Comments »