Oracle BRM Blog Thread

March 2nd, 2010 by Allan Anderson • No Comments

Hey everyone.  SSG Blogs about a number of topics and this thread is about Oracle BRM.

Welcome.  My name is Allan Anderson. I started doing BRM/Portal Infranet implementations for SSG in 1998. Back then, we did many implementations on Infranet versions 4 and 5 (and, of course, upgrades). In the “oughts” we roughed the dot-bomb years working on Infranet release 6 implementations and are currently working on projects that include both versions 6 and 7. I personally have worked on 9 different BRM implementations over the past 12 years, including:

FlashNet
US West
Intel Online Services
InterAccess
TrivNet
ATX
T-Mobile USA
Iridium Sattelite
Savvis

My co-workers at SSG have an even more impressive array of credentials, as many did not take “vacations” from consulting as I did to work full-time at any particular company.

Much of my BRM/Infranet knowledge is due to their expertise and help over the years. In a similar fashion i try to share my knowledge with my SSG colleagues whenever possible or when they need help. This really isnt anything special about me personally, but rather the SSG culture of knowledge and solution sharing responsible for much of our success.

Over the course of the past few weeks, I have given much thought to which blog topics would be most beneficial. The blog will cover both basic and obscure BRM functionality and “features”. As this list of features has evolved over the years, i ask you to bear with me when BRM functionality changes from release to release.

The initial list of blog topics include the following:
De-Mystifying the FLIST
Understanding the BRM Data Model and Database Mapping
Writing a Simple Search Using testnap and C
Scripting using SQL and testnap (loading objects, calling op-codes, etc.)
Migrating Accounts from External Systems
Rating Custom Events
Billing and invoicing for Single Accounts
Partitioning Overview & Common Tasks

I expect many more topics to be added as I or my SSG colleagues can think of new ones.

So welcome! Hopefully you (or someone out there) will find this blog useful.

Blog #1: De-Mystifying the FLIST

So when i was considering writing a blog about BRM, FLISTS jumped into my mind as a requirement for for any in-depth understanding of BRM and its workings, especially if one wants to do development or customizations of any kind. So having said that:

What the Heck is an FLIST??!?

FLIST is short for “Field List”, and its official definition is: A dynamically built structure of Field-Value pairs.

Since this description is pretty broad, a more detailed description of an FLIST is:
• A dynamically built data structure that is made up of one or more fields
• Made up of Fields which are identified by a unique name, ID, and data type (see $PIN_HOME/include/pin_flds.h for a list of the out-of-box fields)
• Used by BRM to represent objects defined in the data dictionary, and stored in the BRM database
• Used by BRM to define input and output to functional operations called op-codes
• May be converted to a string for logging purposes

FLIST Building Blocks: BRM Fields & Data Types:

The field data types are static and defined by BRM version you are running (you can view the types by looking in $PIN_HOME/include/pcm.h):

STRING (PIN_FLDT_STRING)

Your typical garden-variety null-terminated string. The length of the string is only limited when you want to store this to the BRM database, in which case the length is limited by the field length in the data dictionary and the database table.
Example:

0 PIN_FLD_DESCR STR [0] "Field Description"

INTEGER (PIN_FLDT_INT)

A signed Integer. Used by BRM to represent whole numbers.
Example:

0 PIN_FLD_RESOURCE_ID INT [0] 840

DECIMAL (PIN_FLD_DECIMAL)

Used by BRM to represent numbers with any level of required precision. Amounts, Quantities, etc. In C, represented by pin_decimal_t data type. BigDecimal used in Java applications.
Example:

0 PIN_FLD_TOTAL_DUE DECIMAL [0] 9813.2

ENUMERATION (PIN_FLDT_ENUM)

Used to represent natural numbers. Unsigned integer.
Example:

0 PIN_FLD_BILL_TYPE ENUM [0] 10001

BUFFER (PIN_FLDT_BUF)

Represents a sequence of bytes, typically used for strings of very long length. Stored as a blob when stored in the BRM database.
Example:

0 PIN_FLD_BUFFER BUF [0] flag/size/offset 0x0 109 0 data:
x000000 3c3f786d6c2076657273696f6e3d2231 <!--l version="1
x000010 2e302220656e636f64696e673d225554   .0" encoding="UT
x000020 462d3822207374616e64616c6f6e653d   F-8" standalone=
x000030 22796573223f3e0a3c696e766f696365 "yes"?>. x000040 3e0a093c42494c4c5f4e4f3e42312d35 >..B1-5
x000050 37393134363c2f42494c4c5f4e4f3e0a 79146.
x000060 3c2f696e766f6963653e0a0000 ...

POID (PIN_FLDT_POID)

The POID is a special BRM datatype, and is used to identify a specific instance of a BRM object. A POID contains 4 sub-elements:
Database: The database number for the database in which the object is stored. Unsigned Integer Value.
Type: String value representing the BRM object type represented by the POID. “/account” and “/bill” are examples.
ID: Unique value identifying this particular instance of the object type.
Revision: Unsigned Integer value. Incremented every time an objects data is updated.
Example:

0 PIN_FLD_ACCOUNT_OBJ POID [0] 0.0.0.1 /account 85273 3467

TIMESTAMP (PIN_FLDT_TSTAMP)

Timestamps in BRM are represented by the time_t C data structure. They represent a time in UTC. This is basically a number representing the number of seconds since the epoch.
Example:

0 PIN_FLD_START_T TSTAMP [0] (1267430401) Mon Mar 01 00:00:01 2010

SUBSTRUCT (PIN_FLDT_SUBSTR)

Represents a pointer to another single FLIST.
Note: When displayed as a string, sub-flists in SUBSTRUCTS and ARRAYS are indented and have an incremented “level” (the number before the field name) for each field in the flist.
Example:

0 PIN_FLD_PRODUCT SUBSTRUCT [0] allocated 2, used 2
1 PIN_FLD_NODE_LOCATION STR [0] "scl8apportala01#11522/1#20070720-090519.558:scl8apportala01#11522/1#20070720-090519.558"

ARRAY (PIN_FLDT_ARRAY)

Represents a pointer to an indexed array of FLISTS. Each array element has an integer index used to fetch individual flists out of the array.

Example:

0 PIN_FLD_ARGS ARRAY [1] allocated 20, used 1
1    PIN_FLD_AR_BILL_OBJ POID [0] 0.0.0.1 /bill 35677761 0
0 PIN_FLD_ARGS ARRAY [2] allocated 20, used 1
1    PIN_FLD_AR_ACCOUNT_OBJ POID [0] 0.0.0.1 /account 85273 3462
0 PIN_FLD_ARGS ARRAY [3] allocated 20, used 1
1    PIN_FLD_EFFECTIVE_T TSTAMP [0] (1267430401) Mon Mar 01 00:00:01 2010

It is important to note the difference between FLISTS that represent acutal BRM domain objects stored in the database and those representing Op-Code API request and response FLISTs.

FLISTs Representing Database Objects:

FLISTs representing objects in the BRM domain have a fixed structure, defined by the data dictionary. All of the FLISTS in this category contain the PIN_FLD_POID field, which identifies the data stucture (via the BRM data dictionary) for the class (identified in the type field of the poid). All objects of a particular class will have the exact same fields associated with them, for the most part (fields defined as optional may or may not be present in an instance of any particular class). The fields that make up a particular object can be modified, but thats a subject for a different blog.
For Example, an /bill object has different fields than an /account object:

/bill:

0 PIN_FLD_POID POID [0] 0.0.0.1 /bill 35677761 4
0 PIN_FLD_CREATED_T TSTAMP [0] (1267511488) Mon Mar 01 22:31:28 2010
0 PIN_FLD_MOD_T TSTAMP [0] (1270155627) Thu Apr 01 14:00:27 2010
0 PIN_FLD_READ_ACCESS STR [0] "L"
0 PIN_FLD_WRITE_ACCESS STR [0] "L"
0 PIN_FLD_ACCOUNT_OBJ POID [0] 0.0.0.1 /account 85273 3462
0 PIN_FLD_ADJUSTED DECIMAL [0] 0
0 PIN_FLD_BILL_NO STR [0] "B1-579146"
0 PIN_FLD_CURRENCY INT [0] 840
0 PIN_FLD_CURRENCY_OPERATOR ENUM [0] 0
0 PIN_FLD_CURRENCY_RATE DECIMAL [0] 0
0 PIN_FLD_CURRENCY_SECONDARY INT [0] 0
0 PIN_FLD_CURRENT_TOTAL DECIMAL [0] 9813.2
0 PIN_FLD_DISPUTED DECIMAL [0] 0
0 PIN_FLD_DUE DECIMAL [0] 9813.2
0 PIN_FLD_DUE_T TSTAMP [0] (1272697200) Sat May 01 00:00:00 2010
0 PIN_FLD_END_T TSTAMP [0] (1270105200) Thu Apr 01 00:00:00 2010
0 PIN_FLD_FLAGS INT [0] 0
0 PIN_FLD_INVOICE_OBJ POID [0] 0.0.0.1 /invoice 35944328 0
0 PIN_FLD_NAME STR [0] "PIN Bill"
0 PIN_FLD_PARENT POID [0] 0.0.0.0 0 0
0 PIN_FLD_PREVIOUS_TOTAL DECIMAL [0] 19735.4
0 PIN_FLD_RECVD DECIMAL [0] 0
0 PIN_FLD_START_T TSTAMP [0] (1267430400) Mon Mar 01 00:00:00 2010
0 PIN_FLD_SUBORDS_TOTAL DECIMAL [0] 0
0 PIN_FLD_TOTAL_DUE DECIMAL [0] 9813.2
0 PIN_FLD_TRANSFERED DECIMAL [0] 0
0 PIN_FLD_WRITEOFF DECIMAL [0] 0

/account:

# number of field entries allocated 107, used 107
0 PIN_FLD_POID POID [0] 0.0.0.1 /account 85273 3467
0 PIN_FLD_CREATED_T TSTAMP [0] (986025600) Sat Mar 31 00:00:00 2001
0 PIN_FLD_MOD_T TSTAMP [0] (1270154072) Thu Apr 01 13:34:32 2010
0 PIN_FLD_READ_ACCESS STR [0] "L"
0 PIN_FLD_WRITE_ACCESS STR [0] "L"
0 PIN_FLD_AAC_ACCESS STR [0] ""
0 PIN_FLD_AAC_PACKAGE STR [0] ""
0 PIN_FLD_AAC_PROMO_CODE STR [0] ""
0 PIN_FLD_AAC_SERIAL_NUM STR [0] ""
0 PIN_FLD_AAC_SOURCE STR [0] ""
0 PIN_FLD_AAC_VENDOR STR [0] ""
0 PIN_FLD_ACCESS_CODE1 STR [0] ""
0 PIN_FLD_ACCESS_CODE2 STR [0] ""
0 PIN_FLD_ACCOUNT_NO STR [0] "084363"
0 PIN_FLD_ACCOUNT_TAG STR [0] ""
0 PIN_FLD_ACCOUNT_TYPE ENUM [0] 1
0 PIN_FLD_ACTG_CYCLE_DOM INT [0] 1
0 PIN_FLD_ACTG_FUTURE_T TSTAMP [0] (1275375600) Tue Jun 01 00:00:00 2010
0 PIN_FLD_ACTG_LAST_T TSTAMP [0] (1270105200) Thu Apr 01 00:00:00 2010
0 PIN_FLD_ACTG_NEXT_T TSTAMP [0] (1272697200) Sat May 01 00:00:00 2010
0 PIN_FLD_ACTG_TYPE ENUM [0] 1
0 PIN_FLD_ATTRIBUTE INT [0] 0
0 PIN_FLD_BILLING_STATE ENUM [0] 0
0 PIN_FLD_BILLING_STATUS ENUM [0] 0
0 PIN_FLD_BILLING_STATUS_FLAGS INT [0] 0
0 PIN_FLD_BILL_ACTGCYCLES_LEFT INT [0] 1
0 PIN_FLD_BILL_MODE STR [0] ""
0 PIN_FLD_BILL_OBJ POID [0] 0.0.0.1 /bill 35847949 0
0 PIN_FLD_BILL_TYPE ENUM [0] 10001
0 PIN_FLD_BILL_WHEN INT [0] 1
0 PIN_FLD_BRAND_OBJ POID [0] 0.0.0.1 /account 1 1000
0 PIN_FLD_BUSINESS_TYPE ENUM [0] 0
0 PIN_FLD_CLOSE_WHEN_T TSTAMP [0] (0)
0 PIN_FLD_CURRENCY INT [0] 840
0 PIN_FLD_CURRENCY_SECONDARY INT [0] 0
0 PIN_FLD_EFFECTIVE_T TSTAMP [0] (1257877737) Tue Nov 10 10:28:57 2009
0 PIN_FLD_EXEMPT_FROM_COLLECTIONS INT [0] 0
0 PIN_FLD_GL_SEGMENT STR [0] "."
0 PIN_FLD_GROUP_OBJ POID [0] 0.0.0.0 0 0
0 PIN_FLD_INCORPORATED_FLAG ENUM [0] 0
0 PIN_FLD_INTERNAL_NOTES BUF [0] flag/size/offset 0x0 403 0 data:
x000140 3a30383a323720504d0d0a4361746567 :08:27 PM..Categ
x000150 6f72793a20412f522043726564697420 ory: A/R Credit
x000160 4163636f756e740d0a5b437573746f6d Account..[Custom
x000170 6572206e6f7420736174697366696564 er not satisfied
x000180 207769746820736572766963655d2039 with service] 9
x000190 390d0a 9..
0 PIN_FLD_ITEM_POID_LIST STR [0] "0.0.0.1|/item/misc 35844939 0"
0 PIN_FLD_LASTSTAT_CMNT STR [0] ""
0 PIN_FLD_LAST_BILL_OBJ POID [0] 0.0.0.1 /bill 35677761 0
0 PIN_FLD_LAST_BILL_T TSTAMP [0] (1270105200) Thu Apr 01 00:00:00 2010
0 PIN_FLD_LAST_STATUS_T TSTAMP [0] (1001339927) Mon Sep 24 06:58:47 2001
0 PIN_FLD_LINEAGE STR [0] "/0.0.0.1:85273/"
0 PIN_FLD_LOCALE STR [0] "en_US"
0 PIN_FLD_MERCHANT STR [0] "N/A"
0 PIN_FLD_NAME STR [0] "PIN Account Object"
0 PIN_FLD_NEXT_BILL_OBJ POID [0] 0.0.0.0 0 0
0 PIN_FLD_NEXT_BILL_T TSTAMP [0] (1272697200) Sat May 01 00:00:00 2010
0 PIN_FLD_NEXT_ITEM_POID_LIST STR [0] ""
0 PIN_FLD_PARENT POID [0] 0.0.0.0 0 0
0 PIN_FLD_PAYINFO_OBJ POID [0] 0.0.0.1 /payinfo/invoice 26198422 0
0 PIN_FLD_PENDING_RECV DECIMAL [0] 9813.2
0 PIN_FLD_RESIDENCE_FLAG ENUM [0] 1
0 PIN_FLD_SCENARIO_OBJ POID [0] 0.0.0.0 0 0
0 PIN_FLD_STATUS ENUM [0] 10100
0 PIN_FLD_STATUS_FLAGS INT [0] 0
0 PIN_FLD_TIMEZONE_ID STR [0] ""
0 PIN_FLD_VAT_CERT STR [0] ""
0 PIN_FLD_BALANCES ARRAY [840] allocated 8, used 8
1    PIN_FLD_CREDIT_FLOOR DECIMAL [0] NULL
1    PIN_FLD_CREDIT_LIMIT DECIMAL [0] NULL
1    PIN_FLD_CREDIT_THRESHOLDS INT [0] 0
1    PIN_FLD_CURRENT_BAL DECIMAL [0] 17530.08
1    PIN_FLD_FLAGS INT [0] 0
1    PIN_FLD_NEXT_BAL DECIMAL [0] 0
1    PIN_FLD_OPEN_BAL DECIMAL [0] 17530.08
1    PIN_FLD_RESERVED_AMOUNT DECIMAL [0] 0
0 PIN_FLD_NAMEINFO ARRAY [1] allocated 21, used 21
1    PIN_FLD_ADDRESS STR [0] "1475 Veterans Blvd"
1    PIN_FLD_CANON_COMPANY STR [0] "iprint"
1    PIN_FLD_CANON_COUNTRY STR [0] "US"
1    PIN_FLD_CITY STR [0] "REDWOOD CITY"
1    PIN_FLD_COMPANY STR [0] "Company Name"
1    PIN_FLD_CONTACT_TYPE STR [0] "Billing"
1    PIN_FLD_COUNTRY STR [0] "USA"
1    PIN_FLD_EMAIL_ADDR STR [0] "nobody@nowhere.com"
1    PIN_FLD_FIRST_CANON STR [0] "accounts"
1    PIN_FLD_FIRST_NAME STR [0] "Accounts"
1    PIN_FLD_LAST_CANON STR [0] "payable"
1    PIN_FLD_LAST_NAME STR [0] "Payable"
1    PIN_FLD_MIDDLE_CANON STR [0] ""
1    PIN_FLD_MIDDLE_NAME STR [0] ""
1    PIN_FLD_SALUTATION STR [0] ""
1    PIN_FLD_SERVICE_OBJ POID [0] 0.0.0.0 0 0
1    PIN_FLD_STATE STR [0] "CA"
1    PIN_FLD_TITLE STR [0] ""
1    PIN_FLD_ZIP STR [0] "94063"
1    PIN_FLD_PHONES ARRAY [0] allocated 2, used 2
2       PIN_FLD_PHONE STR [0] "2145551212"
2       PIN_FLD_TYPE ENUM [0] 2
1    PIN_FLD_PHONES ARRAY [2] allocated 2, used 2
2       PIN_FLD_PHONE STR [0] "N/A"
2       PIN_FLD_TYPE ENUM [0] 2
0 PIN_FLD_PRODUCTS ARRAY [13] allocated 32, used 32
1    PIN_FLD_CREATED_T TSTAMP [0] (986112000) Sun Apr 01 00:00:00 2001
1    PIN_FLD_CYCLE_DISCOUNT DECIMAL [0] 0
1    PIN_FLD_CYCLE_DISC_AMT DECIMAL [0] 0
1    PIN_FLD_CYCLE_END_T TSTAMP [0] (0)
1    PIN_FLD_CYCLE_FEE_AMT DECIMAL [0] 0
1    PIN_FLD_CYCLE_FEE_FLAGS INT [0] 3
1    PIN_FLD_CYCLE_START_T TSTAMP [0] (986112000) Sun Apr 01 00:00:00 2001
1    PIN_FLD_DEAL_OBJ POID [0] 0.0.0.1 /deal 142006 2
1    PIN_FLD_DESCR STR [0] "1-BMX323"
1    PIN_FLD_FLAGS INT [0] 3
1    PIN_FLD_LAST_MODIFIED_T TSTAMP [0] (0)
1    PIN_FLD_MMC_END_T TSTAMP [0] (992835668) Sun Jun 17 20:41:08 2001
1    PIN_FLD_MMC_START_T TSTAMP [0] (992835668) Sun Jun 17 20:41:08 2001
1    PIN_FLD_MMC_TYPE INT [0] 0
1    PIN_FLD_NODE_LOCATION STR [0] "10333199:10330639"
1    PIN_FLD_PLAN_OBJ POID [0] 0.0.0.0 0 0
1    PIN_FLD_PRODUCT_OBJ POID [0] 0.0.0.1 /product 142012 6
1    PIN_FLD_PURCHASE_DISCOUNT DECIMAL [0] 0
1    PIN_FLD_PURCHASE_DISC_AMT DECIMAL [0] 0
1    PIN_FLD_PURCHASE_END_T TSTAMP [0] (0)
1    PIN_FLD_PURCHASE_FEE_AMT DECIMAL [0] 0
1    PIN_FLD_PURCHASE_START_T TSTAMP [0] (986112000) Sun Apr 01 00:00:00 2001
1    PIN_FLD_QUANTITY DECIMAL [0] 1
1    PIN_FLD_SERVICE_OBJ POID [0] 0.0.0.1 /service/exodus/evolve 10332791 0
1    PIN_FLD_SMC_END_T TSTAMP [0] (1275375600) Tue Jun 01 00:00:00 2010
1    PIN_FLD_SMC_START_T TSTAMP [0] (1272697200) Sat May 01 00:00:00 2010
1    PIN_FLD_SPONSOR_OBJ POID [0] 0.0.0.0 0 0
1    PIN_FLD_STATUS ENUM [0] 1
1    PIN_FLD_STATUS_FLAGS INT [0] 55599999
1    PIN_FLD_USAGE_DISCOUNT DECIMAL [0] 0
1    PIN_FLD_USAGE_END_T TSTAMP [0] (0)
1    PIN_FLD_USAGE_START_T TSTAMP [0] (986112000) Sun Apr 01 00:00:00 2001

FLISTS Representing Op-Code Calls:

FLISTs are also used as a method of representing input and output to BRM Op-Codes. A given op-code will have a specific FLIST format (i.e. set of fields) defined for both input and output. Here are some examples of FLISTS used for Op-Code Calls:

Example:
PCM_OP_FIND_PROFILE Op-Code:
Input:

# number of field entries allocated 20, used 3
0 PIN_FLD_POID POID [0] 0.0.0.1 /account 85273 3467
0 PIN_FLD_ACCOUNT_OBJ POID [0] 0.0.0.1 /account 85273 3467
0 PIN_FLD_RESULTS ARRAY [0] allocated 20, used 1
1    MDS_FLD_CUST_INFO SUBSTRUCT [0] allocated 20, used 0

Output:

# number of field entries allocated 2, used 2
0 PIN_FLD_POID POID [0] 0.0.0.1 /account 85273 3467
0 PIN_FLD_RESULTS ARRAY [0] allocated 9, used 9
1    PIN_FLD_POID POID [0] 0.0.0.1 /profile/misc/customer_info 85273 1028
1    PIN_FLD_CREATED_T TSTAMP [0] (988756868) Tue May 01 15:41:08 2001
1    PIN_FLD_MOD_T TSTAMP [0] (1150839440) Tue Jun 20 14:37:20 2006
1    PIN_FLD_READ_ACCESS STR [0] "G"
1    PIN_FLD_WRITE_ACCESS STR [0] "S"
1    PIN_FLD_ACCOUNT_OBJ POID [0] 0.0.0.1 /account 85273 1000
1    PIN_FLD_NAME STR [0] "Converted Profile"
1    PIN_FLD_SERVICE_OBJ POID [0] 0.0.0.0 0 0
1    MDS_FLD_CUST_INFO SUBSTRUCT [0] allocated 33, used 33
2       PIN_FLD_EFFECTIVE_T TSTAMP [0] (0)
2       PIN_FLD_GEOCODE STR [0] ""
2       MVS_FLD_FINANCIAL_COMPANY_OBJ POID [0] 0.0.0.0 0 0
2       MDS_FLD_ACCT_ORG_ID STR [0] "MSC US"
2       MDS_FLD_ACCT_ROW_ID STR [0] "1+6CN+411"
2       MDS_FLD_ACCT_SALES_TYPE STR [0] "Web Hosting"
2       MDS_FLD_ACCT_TYPE STR [0] "00"
2       MDS_FLD_BILLING_ADDRESS_ID STR [0] "X1-1-1LB9"
2       MDS_FLD_BILLING_CONTACT_ROW_ID STR [0] "X5-1+7+0"
2       MDS_FLD_BILL_HANDLING_TYPE STR [0] "Normal Billing"
2       MDS_FLD_CUST_CLASS STR [0] ""
2       MDS_FLD_CUTOFF_T TSTAMP [0] (0)
2       MDS_FLD_DELIVERY_DEST STR [0] ""
2       MDS_FLD_DELIVERY_OPT STR [0] ""
2       MDS_FLD_DISC_GROUP STR [0] ""
2       MDS_FLD_DOM_RT_TBL STR [0] ""
2       MDS_FLD_EBILL_MEDIA STR [0] ""
2       MDS_FLD_EBILL_ROLL STR [0] ""
2       MDS_FLD_EVENT_RT_TBL STR [0] ""
2       MDS_FLD_IMG_RT_TBL STR [0] ""
2       MDS_FLD_IMG_RT_TBL_OLD STR [0] ""
2       MDS_FLD_INTL_RT_TBL STR [0] ""
2       MDS_FLD_INVOICE_COMMENTS STR [0] ""
2       MDS_FLD_INVOICE_TYPE STR [0] ""
2       MDS_FLD_INV_HOLD INT [0] 0
2       MDS_FLD_LATE_PAYMENT INT [0] 0
2       MDS_FLD_PRIMARY_ADDRESS_ROW_ID STR [0] "X5-1-1LB9"
2       MDS_FLD_PRINT_OPT STR [0] ""
2       MDS_FLD_REPORT_FREQ STR [0] ""
2       MDS_FLD_REPORT_ID STR [0] ""
2       MDS_FLD_SLSREP_FIRST_NAME STR [0] "ADMINISTRATOR"
2       MDS_FLD_SLSREP_LAST_NAME STR [0] "ADMINISTRATOR"
2       MDS_FLD_SLSREP_LOGIN STR [0] "SADMIN"

FLIST Manipulation using C:

We will start with C manipulation because BRM is written in C. Here are just a few examples of how to manipulate FLISTs and associated fields.

Some Local Variables for our examples:

/* Local Variables */
pin_flist_t *pFlist = NULL;
pin_flist_t *pSubFlist = NULL;
pin_flist_t *pSubAFlist = NULL;
pin_flist_t *pSubBFlist = NULL;

poid_t *pDummyPoid = NULL;
poid_t *pGetPoid = NULL;

char szMsg[256];
char *szGetMsg;

int iResourceId = 0;
int *pResourceId = NULL;
/* End Local Variables */

Creating an empty FLIST:

/* Create the FLIST using the PIN_FLIST_CREATE macro */
pFlist = PIN_FLIST_CREATE( pErrorBuffer );

Most FLIST manipulation macros will require the use of an pin error buffer (pin_errbuf_t *). This error buffer is set if problems occur during the operation.

Adding a POID field to an FLIST:

/* add POID to our newly created FLIST. Create a dummy poid to use. */
pDummyPoid = PIN_POID_CREATE( 1, "/search", (int64) -1, pErrorBuffer );
PIN_FLIST_FLD_SET( pFlist, PIN_FLD_POID, pDummyPOID, pErrorBuffer );

/* Now get the POID off of the FLIST for Logging */
pGetPoid = PIN_FLIST_FLD_GET( pFlist, PIN_FLD_POID, 0, pErrorBuffer );
PIN_ERR_LOG_POID( PIN_ERR_LEVEL_DEBUG, "The Poid Value is:", pGetPoid );

Adding a STRING field to an FLIST:

/* Add a string field to our FLIST */
sprintf( szMsg, "Hello, World!" );
PIN_FLIST_FLD_SET( pFlist, PIN_FLD_DESCR, szMsg, pErrorBuffer );

/* Now get the string off of the FLIST again */
szGetMsg = PIN_FLIST_FLD_GET( pFlist, PIN_FLD_DESCR, 0, pErrorBuffer );
PIN_ERR_LOG_MSG( PIN_ERR_LEVEL_DEBUG, szGetMsg );

Adding an INT field to an FLIST:

/* Add an integer field to our FLIST */
iResourceId = 840;
PIN_FLIST_FLD_SET( pFlist, PIN_FLD_RESOURCE_ID, &iResourceId, pErrorBuffer );

/* Now get the String and Print it. Always check pointers before de-referencing */
pResourceId = PIN_FLIST_FLD_GET( pFlist, PIN_FLD_RESOURCE_ID, 0, pErrorBuffer );
if( NULL != pResourceId ) {
sprintf( szMsg, "The Int Value Is: [%d]", *pResourceId );
PIN_ERR_LOG_MSG( PIN_ERR_LEVEL_DEBUG, szMsg );
}

Adding a SUBSTRUCT sub-flist to an FLIST:

/* Create an FLIST that we will store in the SUBSTRUCT */
pSubFlist = PIN_FLIST_CREATE( pErrorBuffer );
PIN_FLIST_FLD_SET( pSubFlist, PIN_FLD_RESOURCE_ID, &iResourceId, pErrorBuffer );

/* Put the SubFlist in the PIN_FLD_PRODUCT substruct */
/* By using the PUT we transfer the memory management of pSubFlist to pFlist */
/* We could have avoided the PUT by using the PIN_FLIST_SUBSTR_ADD() macro. Similar to the array example below */
pFlist = PIN_FLIST_CREATE( pErrorBuffer );
PIN_FLIST_SUBSTR_PUT( pFlist, pSubFlist, PIN_FLD_PRODUCT, pErrorBuffer );

PIN_ERR_LOG_FLIST( PIN_ERR_LEVEL_DEBUG, "FLIST With a SUBSTRUCT:", pFlist );

/* Frees the memory for both pSubFlist and pFlist */
PIN_FLIST_DESTROY_EX( &pFlist, NULL );

Adding Multiple Sub-FLISTs to an FLIST using an Array Field:

/* Create the top-level FLIST */
pFlist = PIN_FLIST_CREATE( pErrorBuffer );

/* Create an FLIST that we will store in the ARRAY */
/* Here we will use the PIN_FLIST_ELEM_ADD(), which keeps us from having to use PIN_FLIST_CREATE() and PIN_FLIST_ELEM_PUT() */
/* Put SubAFlist in Array Element 1, and SubBFlist in Array Element 2 */
iResourceId = 840;
pSubAFlist = PIN_FLIST_ELEM_ADD( pFlist, PIN_FLD_ARGS, 1, pErrorBuffer );
PIN_FLIST_FLD_SET( pSubAFlist, PIN_FLD_RESOURCE_ID, &iResourceId, pErrorBuffer );

iResourceId = 124;
pSubBFlist = PIN_FLIST_ELEM_ADD( pFlist, PIN_FLD_ARGS, 2, pErrorBuffer );
PIN_FLIST_FLD_SET( pSubBFlist, PIN_FLD_RESOURCE_ID, &iResourceId, pErrorBuffer );

PIN_ERR_LOG_FLIST( PIN_ERR_LEVEL_DEBUG, "FLIST with 2 Sub-Array Elements:", pFlist );

These are the most commonly used field types. If you need to use the others, there are out-of-box examples in policy code to look at ($PIN_HOME/src).

If you enjoyed this post, make sure you subscribe to my RSS feed!

No 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

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;

}
}

If you enjoyed this post, make sure you subscribe to my RSS feed!

No Comments

 

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

February 19th, 2010 by Mark Peterson • 2 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

If you enjoyed this post, make sure you subscribe to my RSS feed!

2 Comments

 

Creating Oracle BPM PAPI Clients

February 17th, 2010 by Mark Peterson • No Comments

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.

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;
}

}

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();
}
}
}

If you enjoyed this post, make sure you subscribe to my RSS feed!

No Comments

 

Protected: Leveraging BPM 11g Capabilities – Argument Mapping

February 11th, 2010 by Mark Peterson • Enter your password to view comments

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


If you enjoyed this post, make sure you subscribe to my RSS feed!

Enter your password to view comments

 

Oracle BRM Pipeline Start Up Fix from Dallas Lyon

December 21st, 2009 by Melissa Womack • No Comments

If you have a problem getting a BRM pipeline to start up and get an error, here is a fix to try. Everywhere you see “XXX” is a replacement for the name of the client’s directory structure.

If you get the following message on startup of the pipeline:

bin/XXX: An error occurred during creation.

Originator : XXX.Pipelines.ExceptionPipeline.TransactionManager

Destination :

Message : ERR_TAM_INIT_FAILED

Arguments : XXX.Pipelines.ExceptionPipeline.TransactionManager

State : false

Severity : CRITICAL

Thread : 1

Go look in the $XXX_HOME/log/process/processXXXXX.log file for messages like:

01.12.2009 16:18:16 hostname XXX XXX MAJOR [T:1] 00081 – (XXX.Pipelines.ExceptionPipeline.Output.OutputCollection.EdrOutput.Module.OutputStream.Module) ‘No such file or directory’: Cannot move temporary file ‘./your/path/tmpExceptionPipelineToReplayEdrSerialize_YYYY.edr’ to output file ‘./your /path/ToReplayEdrSerialize_YYYY.edr’.

01.12.2009 16:18:18 hostname XXX XXX CRITICAL [T:1] 00441 – (XXX.Pipelines.ExceptionPipeline.TransactionManager) Failed to init transaction manager ‘XXX.Pipelines.ExceptionPipeline.TransactionManager’.

The tmpExceptionPipelineToReplayEdrSerialize_YYYY.edr file doesn’t exist for some reason, or is un-processable, and you have to remove references to it from the TAM startup files. There are two files that you need to delete:
$XXX_HOME/tam/ TamTransXXXXX.dat
$XXX_HOME/tam/ ExceptionBinaryLogFile.dat

Once you delete these two files, the pipeline should start up again. If it doesn’t, the file referenced may actually exist in the pipeline path. If it does, delete it.

Send questions to jdavis@ssglimited.com

If you enjoyed this post, make sure you subscribe to my RSS feed!

No Comments

 

Cloud Computing 101

November 23rd, 2009 by Robert McMillen • No Comments

I recently ran across a great article by the Burton Group that provides an indepth discussion on Cloud Computing along with definitions.

Quick… Give me a one sentence definition for the term “Cloud Computing”….

If you are like me you think you know what that is but the term is being used so commonly that now you wonder if you really do understand what it is…

In case you’ve not heard about them, the Burton Group provides in-depth, IT research and advisory services to executives and technologists at Global 2000 organizations.

One of the  values to this article is that it provides an ontology on cloud computing which helps define and improve the discussion.

They define Cloud Computing as:

The set of disciplines, technologies, and business models used to render IT capabilities as on-demand services.

They cover a lot of topics about Cloud Computing along with what they expect the futures to be.

For just a taste, here is a  sample  diagram, from the article, describing the tiered architecture that is used in Cloud Computing.

The download page will ask for  information and then send you login information, so be aware.  I opted out of newsletters so hopefully I won’t get spammed.  You can get a fresh copy of the 50 page document on Cloud Computing by going here.

Cloud Computing Tiers

If you enjoyed this post, make sure you subscribe to my RSS feed!

No Comments

 

Understanding the Technology of E-Business Suite 12.1

November 23rd, 2009 by Robert McMillen • No Comments

One of the presentations at Oracle Open World was by Lisa Parekh, who leads the Applications Technology Integration group within the E-Business Suite Development division.

In it, she covered the underlying technology that is used to enable E-Business Suite, Release 12.1.  If you would like to brush up on the technologies, this is a great presentation to review.

She covers a lot of topics including Oracle’s E-Business Suite Release 12’s three-tier architecture, what browsers it supports, the User Interface improvements, SSO, SOA integration, BI, BI Publisher, Oracle Enterprise Manager, Oracle VM, and the upgrade process.  Whew!

You can download the PDF file of her presentation from here.

If you attended Open World you can get the full audio for the presentation by visiting the OnDemand page here.

Thanks to Steven Chan for highlighting this session!

If you enjoyed this post, make sure you subscribe to my RSS feed!

No Comments

 

Upgrading Oracle Virtual Machine Manager – Version 2.2.0

November 23rd, 2009 by Robert McMillen • No Comments

I’ve been running Oracle Virtual Machines internally for several months.  While at Oracle Open World I had a conversation at one of the Oracle kiosks where they recommended I go ahead and upgrade to the latest OVM release 2.2.0  When I first installed OVM I setup the console database and software on my laptop in a VMWare machine .  That was fine initially but it was a hassle always having to startup the VMWare when I wanted to administer the Oracle Virtual Machines.

I was assured that by upgrading to the new release I would be able to easily to migrate the OVM console to another system.  My target system is a 64-bit PC (ABASIN) executing Oracle Enterprise Linux 5.3 which would allow me to just fire up a web browser on my laptop and use ABASIN  as my official OVM system.  Several weeks ago I downloaded the Oracle Virtual Server and Oracle Virtual Manager 2.2.o from E-Delivery (edelivery.oracle.com) and burned them to two CD’s.

I then upgraded the OVM version I had running under VMWare.  That involved mounting the iso file and executing runInstaller.sh.  That all went very well and I’ve provided more details below.

I then used the backup.sh in the /opt/ovs-manager-2.2/bin directory to export my current XE database tables for OVM.  Then I upgraded ABASIN with the same CD and used the same backup script, which has a restore option, to restore the files into that XE database.

Now it was time to upgrade my physical virtual server with the latest Oracle Virtual Server.  That involved shutting down all Virtual Machines and booting the server using the OVS 2.2.0 disk.  That process also went off without a hitch.

I was then able to connect to the updated OVS from ABASIN and do my management via browser without needing to start VMWare locally.  Overall I was surprised how easy the process was and I’m very pleased with the new version!

For those of you who want to see the details of the VMM update I’ve listed the log below.

[root@sunlight ovm]# ./runInstaller.sh
Welcome to Oracle VM Manager 2.2

Please enter the choice: [1|2|3]
1. Install Oracle VM Manager
2. Uninstall Oracle VM Manager
3. Upgrade Oracle VM Manager
[3]

Starting Oracle VM Manager 2.2 upgrade ...

Backup the database before upgrade is highly recommended, to backup the database now, choose 'N' and run:
/opt/ovs-manager-2.1/bin/backup.sh

Are you sure you want to upgrade Oracle VM Manager from version 2.1.2 to 2.2 ? [y|N] [y]
Please enter the password for database account 'OVS': [********]

Now upgrading OC4J ...
Please enter the password for account 'oc4jadmin': [**********]
Starting OC4J ... Done.

Now upgrading the database schema ... Done.

Now upgrading the Oracle VM Manager application ...
Done.

Please enter the keystore password for the Web Service: [********]
Confirm the password: [********]

Setting keystore password for Web Service ... Done
Do you want to use HTTPS access for Oracle VM Manager (Y|n)? [Y]

Configuring OC4J to use HTTPS ... Done
Stopping OC4J ... Done
Starting OC4J ... Done
Upgrade Oracle VM Manager successfully.
Please check the log /var/log/ovm-manager/upgrade_2.1.2_2.2.log for more information.

To access the Oracle VM Manager 2.2 home page go to:
  https://127.0.0.1:4443/OVS

To access the Oracle VM Manager web services WSDL page go to:
  https://127.0.0.1:4443/OVSWS/LifecycleService.wsdl
  https://127.0.0.1:4443/OVSWS/ResourceService.wsdl
  https://127.0.0.1:4443/OVSWS/PluginService.wsdl
  https://127.0.0.1:4443/OVSWS/ServerPoolService.wsdl
  https://127.0.0.1:4443/OVSWS/VirtualMachineService.wsdl
  https://127.0.0.1:4443/OVSWS/AdminService.wsdl

To access the Oracle VM Manager help page go to:
  https://127.0.0.1:4443/help/help
If you enjoyed this post, make sure you subscribe to my RSS feed!

No Comments

 

Oracle Golden Gate and BI

November 10th, 2009 by Paul Scott • No Comments

With Oracle’s acquisition of Golden Gate Software in July, yet another integration offering is available. Golden Gate’s strength (and why it garnered Oracle’s attention) lies in its ability to move transactional data between heterogeneous databases with sub-second latency, transaction integrity, and minimal overhead.  Although Oracle says Streams will continue to be supported, Golden Gate is the strategic direction for real-time integration.

So for Business Intelligence systems, what does this mean?  Historically, data warehouse applications have attempted to answer the question “what happened?”, “why did it happen?” or “what will happen?”.  These are reporting, analytical and predictive type applications.  However, companies want their data warehouse systems to become part of their operational decision making.  They need to answer “what is happening?” — reacting immediately to a change in business.  This is where Golden Gate shines.  Whereas, Oracle Warehouse Builder (OWB) and Oracle Data Integrator (ODI) are better suited for batch-oriented ETL, Golden Gate offers real-time (or near real-time) integration of data and can perform basic transformations.  For more advanced transformation needs, Golden Gate can augment ODI allowing Golden Gate to perform the real-time extraction and ODI performing the transformations and loading.

More info on Golden Gate may be found at http://www.oracle.com/goldengate.

If you enjoyed this post, make sure you subscribe to my RSS feed!

No Comments