Advertisements
RSS

Category Archives: BPM

How to implement permissions on your activities with Oracle Adaptive Case Management ?

When our Oracle Adaptive Case Management project started we initially used the default permissions on the case (Public, Restricted) to make sure our activities where available to the correct BPM application roles. A complex authorization model of roles, with LDAP groups, with users to allow access to the activities, but also custom UI and human tasks.

default_acm_permissions

An important concept of knowledge worker automation (on which off course our whole case is based) is that the users should not be locked into rigid BPM processes (and access constraints I would like to add) which the IT department came up with. So activities on one hand would be allowed access to by all internal knowledge workers anyway, because: “hey .. they are knowledge workers and know best, right ?”

The first exception

However for some exceptions we got the requirements to only allow a specific role to a specific activity. So what we did was adding a new permission for that role and made sure that the activity was only available for that role.

Screen Shot 2016-07-29 at 11.08.18

new permission for role Senior Employee

Screen Shot 2016-07-29 at 11.08.35

set the permission on the activity

And all was good, for a while …

Challenge accepted

This went pretty well for some time, until we ran into a new requirements which made us rethink our design:

  • We had the requirement that on a specific activity where currently only permRoleSeniorEmployee had access now, we had to add the role Medior Employee. Therefor the original design thought that all activities are available for all employees OR for just 1 specific role (senior) for quality assurance was no longer valid.

So we looked at our options :

  1. We allowed the application role Medior to the permRoleSenior permission for a quick win for now, but looking at our naming convention this would be a bit confusing in the long run. All other options below required a code change, build and deploy so we tried to be smart to prevent this from ever happening again.
  2. The activity sadly doesn’t have a multi-select (both 11g and 12.2.1) so it is not possible to select both permRoleSenior and permRoleMedior
  3. We could add a new permission like permRoleMediorAndSenior, but still limiting ourselves to the code base
  4. In future identical requirements we do not want to change the codebase of our ACM project and permissions should be able to change on runtime. So both option 2 and 3 are not smart in the long run.

Our “Best Practice”

We have long running cases (like, really long) and redeployment of a new version will not fix any new permissions requirements on running instances. However since we have 50+ activities in our case where most of them are (currently) allowed access to by all employee levels (the example here just uses 2, but in reality we have much more roles). So the idea of creating a separate permission for each activity was not appealing, we eventually decided that we just had to. So for each activity we created a unique permission and configured in on the activity.

Screen Shot 2016-07-29 at 11.41.15

new unique permission for the activity

Screen Shot 2016-07-29 at 11.41.20

set the permission on the activity

 

Scripted Configuration

Because know we have a LOT of permissions and roles we are gratefull for having a WLST script to make sure these are automatically configured through our environments. Scripts have some customization, but the main logic was found on the big WWW (sorry, not sure where and who to give credits).

So first we need a property file


permission.total=2

# permActMyProcess2
permission.1.appstripe=OracleBPMProcessRolesApp
permission.1.principalclass=oracle.security.jps.service.policystore.ApplicationRole
permission.1.principalname=RubixCasus_1.0.MediorEmployee
permission.1.permclass=oracle.bpm.casemgmt.permission.CasePermission
permission.1.permtarget=RubixCasus_1.0.PERMACTMYPROCESS2.ACTIVITY
permission.1.permactions=INVOKE
permission.2.appstripe=OracleBPMProcessRolesApp
permission.2.principalclass=oracle.security.jps.service.policystore.ApplicationRole
permission.2.principalname=RubixCasus_1.0.SeniorEmployee
permission.2.permclass=oracle.bpm.casemgmt.permission.CasePermission
permission.2.permtarget=RubixCasus_1.0.PERMACTMYPROCESS2.ACTIVITY
permission.2.permactions=INVOKE

And the WLST script


from java.util import Properties
from java.io import FileInputStream
from java.io import File
from oracle.security.jps.mas.mgmt.jmx.policy import PortablePrincipal
from oracle.security.jps.mas.mgmt.jmx.policy import PortablePermission
from oracle.security.jps.mas.mgmt.jmx.policy.PortablePrincipal import PrincipalType
import os, sys

PROPERTIES = sys.argv[1]

propInputStream = FileInputStream(PROPERTIES)
configProps = Properties()
configProps.load(propInputStream)
propInputStream.close()
pmTotal=configProps.get("permission.total")
print '... property permission.total:',pmTotal

connect('weblogic', 'welcome1', 't3://myserver:7001')

print '============================='
print 'Granting permissions...'
print '============================='
print '... property permission.total:',pmTotal
i=1
while (i <= int(pmTotal)) :

  pmAppStripe=configProps.get("permission."+str(i)+".appstripe")
  pmPrincipalClass=configProps.get("permission."+str(i)+".principalclass")
  pmPrincipalName=configProps.get("permission."+str(i)+".principalname")
  pmPermClass=configProps.get("permission."+str(i)+".permclass")
  pmPermTarget=configProps.get("permission."+str(i)+".permtarget")
  pmPermActions=configProps.get("permission."+str(i)+".permactions")

  domainRuntime()
  jpsBean = ObjectName('com.oracle.jps:type=JpsApplicationPolicyStore')

  print 'INFO - Index:',str(i),'| Name:',pmPrincipalName,'| Target:',pmPermTarget,' |Action:',pmPermActions

  principal = PortablePrincipal(pmPrincipalClass, pmPrincipalName,PrincipalType.CUSTOM)
  params = [pmAppStripe, principal.toCompositeData(None)]
  sign = ["java.lang.String", "javax.management.openmbean.CompositeData"]
  perms = mbs.invoke(jpsBean, "getPermissions", params, sign)

  permExists = false
  for perm in perms:
    p = PortablePermission.from(perm)
    if(p.target==pmPermTarget and p.permissionClassName==pmPermClass and pmPermActions in p.actions):
      permExists = true
      print 'INFO - Permission',pmPermTarget,'(',pmPermActions,') already set for ',pmPrincipalName
      break

    if(permExists==false):
    try:
      grantPermission(appStripe=''+pmAppStripe,principalClass=''+pmPrincipalClass,principalName=''+pmPrincipalName, permClass=''+pmPermClass, permTarget=''+pmPermTarget,permActions=''+pmPermActions)
      print 'INFO - Permission',pmPermTarget,'(',pmPermActions,') set for ',pmPrincipalName
    except:
      print 'ERROR - Failed adding permission ',pmPermTarget,'(',pmPermActions,') to',pmPrincipalName
      dumpStack()
      print sys.exc_info()
      os._exit(1)

  i = i + 1

Conclusion

The longer we thought about this the more we think the current permission solution lacks some maintainability. It would (for instance) be nice if the BPM WorkSpace would allow some graphical interface where all activities could be easily connected to the (already their) BPM Application Roles. So hopefully in the near future ?

Advertisements
 
Leave a comment

Posted by on 29-07-2016 in BPM, Oracle

 

Tags: , , , , ,

Using the Human Task identification key to set your own taskId with Oracle BPM (and BPEL)

Requirement

Our Oracle ACM/BPM system will create tasks which will not only be handled by users in a front-end but also through a B2B connection with our external partners. So we need to publish a message to our B2B partners when a task is available. The challenge here is that the taskId is externally generated in the Human Task component and for the BPM (and BPEL) process the taskId is unknown until the task is closed. So we need to generate our own taskId or a trick to capture and retrieve the taskId outside the process and send it back to the process.

Solution

We first looked at the option to use the Human Task onAssigned event which we could capture through EDN and handle accordingly. However one of the requirements was that we would not communicate an internal (task) ID to our B2B partners so needed to generate our own ID instead. So we thought about generate our own guid() and place it on one of the ProtectedTextAttributes so we could use this to query the correct task. But Laurens van der Starre pointed us out that Oracle actually has a solution for this and we could use the identification key on the Human Task.

So below is an example of a process where our own key (a guid) is generated in the script task and then placed on the human task.

process

Map the generated variable on the Identification Key

task

Runtime

In EM I can see that the generated key is 35373030303632323333383139353637. So we would normally communicate this to our B2B partner. Then on request from our B2B partner to send the details of the task service we can query the correct task using the Oracle TaskQueryService:


<soapenv:Envelope>
 <soapenv:Header/>
 <soapenv:Body>
 <tas:taskListRequest>
 <com:workflowContext>
 <com:credential>
 <com:login>${#Project#username}</com:login>
 <com:password>${#Project#password}</com:password>
 </com:credential>
 </com:workflowContext>
 <tas1:taskPredicateQuery>
 <tas1:displayColumnList>
 <tas1:displayColumn>IDENTIFICATIONKEY</tas1:displayColumn>
 </tas1:displayColumnList>
 <tas1:optionalInfoList>
 <!--tas1:taskOptionalInfo>Comments</tas1:taskOptionalInfo-->
 <!--tas1:taskOptionalInfo>Attachments</tas1:taskOptionalInfo-->
 <!--tas1:taskOptionalInfo>Payload</tas1:taskOptionalInfo-->
 </tas1:optionalInfoList>
 <tas1:predicate>
 <tas1:assignmentFilter>All</tas1:assignmentFilter>
 <tas1:clause>
 <tas1:column>IDENTIFICATIONKEY</tas1:column>
 <tas1:operator>EQ</tas1:operator>
 <tas1:value>35373030303632323333383139353637</tas1:value>
 </tas1:clause>
 </tas1:predicate>
 </tas1:taskPredicateQuery>
 </tas:taskListRequest>
 </soapenv:Body>
</soapenv:Envelope>

Result

 

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
 <env:Header/>
 <env:Body>
 <taskListResponse xmlns="http://xmlns.oracle.com/bpel/workflow/taskQueryService">
 <task xmlns="http://xmlns.oracle.com/bpel/workflow/task">
 <title>task-identification-key</title>
 <ownerRole>task-identification-key.ProcessOwner</ownerRole>
 <priority>3</priority>
 <processInfo/>
 <systemAttributes> ... </systemAttributes>
 <systemMessageAttributes/>
 <identificationKey>35373030303632323333383139353637</identificationKey>
 <percentageComplete>100.0</percentageComplete>
 <sca>
 <compositeDN>default/task-identification-key!1.0*soa_.....</compositeDN>
 </sca>
 <applicationContext>OracleBPMProcessRolesApp</applicationContext>
 <taskDefinitionId>default/task-identification-key!1.0/htMyTask</taskDefinitionId>
 <mdsLabel>soa_...</mdsLabel>
 <customAttributes/>
 </task>
 </taskListResponse>
 </env:Body>
</env:Envelope>

Example / Sources

 

 
1 Comment

Posted by on 29-04-2016 in BPM, Oracle

 

Tags: , ,

How to withdraw tasks and handle them in Oracle BPM

If you want to withdraw a Human Task in Oracle BPM there are multiple options. This blog post will first show 3 options and then explain how to model your Oracle BPM process to anticipate on the result of a withdrawn task.

1. The BPM Workspace

Using the default Oracle BPM WorkSpace to withdraw a task:

withdraw5

2. Using the TaskService

If you use a custom front-end (instead of the default Oracle BPM Workspace) you can use the Oracle SOA Suite TaskQueryService & TaskService to handle your tasks. In the TaskService there are operations named withdraw and withdrawTasks to either withdraw 1 or multiple tasks. The example below shows a withdrawTask operation request message.


<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:tas="http://xmlns.oracle.com/bpel/workflow/taskService"
 xmlns:task="http://xmlns.oracle.com/bpel/workflow/task"
 xmlns:com="http://xmlns.oracle.com/bpel/workflow/common">
 <soapenv:Header/>
 <soapenv:Body>
 <tas:withdrawTask>
 <com:workflowContext>
 <com:credential>
 <com:login>weblogic</com:login>
 <com:password>welcome1</com:password>
 <com:onBehalfOfUser>weblogic</com:onBehalfOfUser>
 </com:credential>
 </com:workflowContext>
 <tas:taskId>a71a4c2b-b121-4cde-91af-79872dbda522</tas:taskId>
 </tas:withdrawTask>
 </soapenv:Body>
</soapenv:Envelope>

This solution is implemented in our Adaptive Case Management project in the case a specific (power)user is logged in and wants to withdraw the current task (and activity) where he/she is working on.

3. Using events/signal

When you want to withdraw a task without actually opening a task (or having access to it’s taskId) you can use a signal subprocess to receive an event.

withdraw4

The event can trigger an Update Task action which calls the withdraw operation from within the BPM process.

withdraw3

The Oracle BPM Process modeling

When using the withdrawTask the task state is set to “WITHDRAWN” when the task is closed. So make sure to use the data association on the output tab of the task to store the state in a process data object.

withdraw1

In the BPM process flow we can use an exclusive gateway to model the logic by checking the value of the taskState process data object.

withdraw2

Often we use gateways in Oracle BPM processes to check the outcome of a human task and model the outcome to different process flows. However keep in mind that the state can also inform about e.g. EXPIRED, ERROR or WITHDRAWN tasks.

withdraw7

References

 
2 Comments

Posted by on 18-06-2015 in BPM, Oracle

 

Tags: ,

First look how to migrate Oracle BPM 10g R3 projects to Oracle BPM 12c

A very interesting feature in the recently released Oracle BPM 12c Suite (12.1.3) is the fact it now supports migration from older BEA Aqualogic BPM (6.0) & Oracle BPM 10g R3 projects. Oracle BPM 12c (and 11g) brought significant enhancements to the original Fuego/BEA product. However Oracle BPM 11g, unlike 12c, had no migration support for customers,

Shipped with Oracle BPM 12c there is a migration utility whicj enables you to migrate a BPM project that you created using Oracle BPM 10gr3 to a 12c BPM project which you can modify then with Oracle JDeveloper 12c. The migration utility creates an exported BPM project and a migration report. The migration report contains detailed information for the elements in the original 10g BPM project. If problems occur the migration utility will log these details in the report. You can find the migration utility (which is actually an ANT build.xml) in the JDEV HOME folder under /soa/plugins/jdeveloper/bpm. To run BPM 10-12 Migration tool, Apache Ant must be installed. The ANT target you will need to run will be migrate10-12.

 


cd C:\ORACLE\middleware_12.1.3\soa\plugins\jdeveloper\bpm
C:\ORACLE\tools\apache-ant-1.8.4\bin\ant migrate10-12 -DprojectLocation=C:\oracle\projects\rubix_ALBPM_pilot_15032010 -Ddestination=c:\oracle\projects\bpm12Export
Unable to locate tools.jar. Expected to find it in C:\Oracle\Java\jre7\lib\tools.jar
Buildfile: C:\ORACLE\middleware_12.1.3\soa\plugins\jdeveloper\bpm\build.xml

check:

migrate10-12:
 [migrate] --- Migration complete ---
 [migrate] --- See log file: 'c:\oracle\projects\bpm12Export\rubix_ALBPM_pilot_15032010.xml' on your browser.

BUILD SUCCESSFUL
Total time: 2 minutes 59 seconds

C:\ORACLE\middleware_12.1.3\soa\plugins\jdeveloper\bpm>

The export folder containts the following files:

  • report (.xml) with stylesheet (reports.xsl)
  • project statistics (.csv)
  • most important, the Oracle BPM 12 export (.exp)
  • SOA folder which contains all the BPM artifacts

export_result

The project statistics shows a simple overview of the groups, elements and quantity of the migration process, where the migration report gives a very detailed overview of all the artifacts during the migration. During this migration I already saw some warnings and objects which could not be migrated. So I naturally was very curious (and I had to admit, a bit sceptic) what the result would be.

So next step, In Oracle JDeveloper 12c we can import the project through File -> Import

export_importBPM

Select the .exp file and press import and the result is a Oracle BPM 12c project with all files: composites.xml, organizations.xml, businessIndicators.bi, etc.

export_composites

export_process

 

I’m actually quite  impressed  by the result. I have to admit that before starting I was a bit sceptic, especially because the old POC project I used contained more then a simple process and is not in a mile in line with the final production release used by the client. However the result seems is a very complete BPM 12c project with all tasks, Business Objects, Schemas and off course processes. Yes, the migration is not 100% successful and a BPM developer still needs to verify the code and make some fixes to the project. However the migration utility surely gives organizations a quick start to migrate their Oracle BPM 10g R3 environment and start making use of all the new 12c features.

References:

 
2 Comments

Posted by on 11-08-2014 in BPM, Oracle

 

Tags: , ,

How to configure Oracle SOA/BPM task auto release

When a Oracle SOA or BPM workflow task is assigned to a role and/or group a user may acquire the task to work on it. Once the task is acquired, other users are not able to work on that specific task. In the Oracle SOA-INFRA, used by both SOA Suite and BPM Suite, there is a feature called ‘task auto release’ which allows to configure the duration before tasks are automatically released and made available for all other users again.

In Enterprise Manager go to soa-infra -> SOA Administration -> Workflow Properties

01

Select the Task tab and expand Advanced. There you can see there are default values for automatically releasing tasks according to their priority. In the screenshot below the default value of P3D (3 Days) is changed to P1TM (1 minute) for testing purposes. This is done for the priority 3 task, which is the default priority.

 


02

Another feature is to use the expiration data (most right column) of tasks. This feature only works when you map the expiration Duration element in your BPEL or BPM tasks. In the example below the duration is set to P2D (2 days) which means with a priority 3 task the task is released after 1 day (50%).

03

 

References:

 
2 Comments

Posted by on 07-04-2014 in BPM, Oracle, SOA Suite

 

Tags: , ,

How to enable automatic startup recovery in Oracle BPM 11g

For some reason the default settings for automatic recovery of instances is different between the Oracle BPEL and Oracle BPMN engine in 11g. We can view and change these setting under SOA Administration in the Oracle Enterprise Manager:

Select the BPMN properties from the menu (or off course BPEL for the BPEL engine)

Soa Administration

Click on “More BPMN Configuration Properties…”:

002

Click on the “RecoveryConfig” setting

003

The zero (or a negetive) value disables startup recovery, so the default of 0 means the BPMN engine will not recover any instances.

004

If you want, you can compare it with the BPEL engine, where the default is 600 seconds (10 minutes)

005_bpel

As the Oracle documentation states:

StartupRecoveryDuration
Specifies the number of seconds that the startup recovery period lasts. After the server starts up, it goes into a startup recovery period. During this period, pending activities and undelivered callback and invocation messages ae resubmitted for processing. The default value is 600 (ten minutes). A negative or zero value disables startup recovery.

References:

 
3 Comments

Posted by on 26-02-2014 in BPM, Oracle

 

Tags: ,

Error with Oracle BPM process metric view during deployment

Since we use BI metrics in our Oracle BPM processes we configure these in JDeveloper. However after adding/renaming/deleting a metric we sometimes discover that we are still able to deploy the BPM composite. However the process specific database view (Analytic View Identifier) is gone.

When we check the Enterprise Manager we discover the following error:

EM Error Message


Component soa_server1
Module oracle.bpm.analytics.cube.persistence
User jzoggel
Thread ID [ACTIVE].ExecuteThread: '13' for queue: 'weblogic.kernel.Default (self-tuning)'
ECID 0000K838zKS8xk35vnT4iX1IRqKb000005
Message SQLException from: CREATE VIEW BPM_ACTV_PERF_MYPROCESS_V AS
Supplemental Detail SELECT
PERF.TASKPERFID AS SEQUENCE_ID,
PERF.PROCESSID AS PROCESS_ID,
PRC.PROCESSNAME AS PROCESS_NAME,
PRC.REVISION AS REVISION,
PERF.ECID AS ECID,
PERF.ACTIVITYID AS ACTIVITY_ID,
ACT.LABEL AS ACTIVITY_LABEL,
PERF.COMPONENTINSTANCEID AS PROCESS_INSTANCE_ID,
PERF.COMPOSITEINSTANCEID AS COMPOSITE_INSTANCE_ID,
PERF.DISCRIMINATOR AS ACTIVITY_DISCRIMINATOR,
PERF.ROLEID AS ACTIVITY_ROLE_ID,
PERF.CREATIONDATETIME AS ACTIVITY_START_TIME,
PERF.COMPLETIONDATETIME AS ACTIVITY_END_TIME,
PERF.TASKTIME AS ACTIVITY_RUNNING_TIME_IN_MSEC,
PERF.PARTICIPANT AS ACTIVITY_PARTICIPANT,
PERF.PRIORITY AS ACTIVITY_PRIORITY,
PERF.TENANTID AS TENANT_ID

FROM BPM_CUBE_TASKPERFORMANCE PERF, BPM_CUBE_PROCESS PRC, BPM_CUBE_ACTIVITY ACT
WHERE
PERF.PROCESSID = 61015 AND
PERF.ACTIVITYID = ACT.ACTIVITYID AND
ACT.PROCESSID = PRC.PROCESSID
UNION ALL
SELECT
PERF.TASKPERFID AS SEQUENCE_ID,
PERF.PROCESSID AS PROCESS_ID,
PRC.PROCESSNAME AS PROCESS_NAME,
PRC.REVISION AS REVISION,
PERF.ECID AS ECID,
PERF.ACTIVITYID AS ACTIVITY_ID,
ACT.LABEL AS ACTIVITY_LABEL,
PERF.COMPONENTINSTANCEID AS PROCESS_INSTANCE_ID,
PERF.COMPOSITEINSTANCEID AS COMPOSITE_INSTANCE_ID,
PERF.DISCRIMINATOR AS ACTIVITY_DISCRIMINATOR,
PERF.ROLEID AS ACTIVITY_ROLE_ID,
PERF.CREATIONDATETIME AS ACTIVITY_START_TIME,
PERF.COMPLETIONDATETIME AS ACTIVITY_END_TIME,
PERF.TASKTIME AS ACTIVITY_RUNNING_TIME_IN_MSEC,
PERF.PARTICIPANT AS ACTIVITY_PARTICIPANT,
PERF.PRIORITY AS ACTIVITY_PRIORITY,
PERF.TENANTID AS TENANT_ID,
PERF.FLEXSTRING03 AS D_USER,
PERF.FLEXSTRING02 AS D_CASENUMBER,
PERF.FLEXSTRING01 AS D_PRODUCT
FROM BPM_CUBE_TASKPERFORMANCE PERF, BPM_CUBE_PROCESS PRC, BPM_CUBE_ACTIVITY ACT
WHERE
PERF.PROCESSID IN (20499,32601,27810,47859,20397,9013,15447,33553,8643,46749,48636,47229,47071,47545,46913,47387,33827,47702,57000,54392,57382,57764,57573) AND
PERF.ACTIVITYID = ACT.ACTIVITYID AND
ACT.PROCESSID = PRC.PROCESSID java.sql.SQLSyntaxErrorException: ORA-01789: query block has incorrect number of result columns

The cause of the problem is due to the auto generated SQL script using a non valid union statement. To quick fix is to manually re-run the script and adding the PERF.FLEXxxxx columns in the SQL statement. Or much better, clean up the old process id references in the table BPM_CUBE_PROCESS. Just check the references of processid in the auto generated statement and remove the invalid references.

 
Leave a comment

Posted by on 13-01-2014 in BPM, Oracle

 

Tags: , ,