/ Management  

Shocking Revelation; Do PIM and CIM artifact actions over webservice calls

Hi there “Process Automation” fans,

Welcome to a new installment of “Process Automation” tips.

I had a decent sit with a daily administrator person to conclude that administering the “Process Automation” platform can be a real pain in the ass. Especially when you (as functional admin) can’t access the backend server or the database. In that case you’re limited (or better “crippled”) with the tools/artifacts like the PIM and the CIM…Nice tools, but with massive projects it works against you. Can we do this smarter? Can we do this better? I suppose we can, but for this we require some research where this post is step number one which is figuring out (R&D) the different service calls available for maintaining BPM instances and Case instances (which equal our entity lifecycle instances!).


Let get right into it…

So, it’s service time with lots of Soap messages to research…trying them out requires a small project with a basic implementation for a BPM and an entity ‘Lifecycle’ BB. Let’s spin up the “Process Automation” machine and jump through the hoops to learn the possibilities.

We start with a BPM implementation like this (to trigger some scenario’s):

service_001

Some notes:

  • Make it an eXclusive decision construct (in the ‘General’ tab)
  • Add an entity layout (you can reuse one of the platform entities) to the top activity (otherwise the BPM won’t stop at the activity!); It will land in the inbox at runtime for the current user.
  • The fail-scenario (downwards) requires an error-code and an error-value (see the properties for those constructs)
  • Select the input message in the properties of the green start construct
  • You can create a new input message from the messagemap tab of the BPM
    service_002
  • Save it in the ‘bpms’ folder of the project; Mine is located like this:
    service_003
  • Publish the BPM to make it available from the ‘Deployed Process Models’ artifact for later usage!

We’ll just start the BPM instances from the designer <F12> to get them in different states based on the input message; You’ll get a popup…try it yourself until you get different states in the PIM artifact.

With that BPM ready, we continue with a ‘Project’ entity (use just one property), and a ‘Lifecycle’ BB like this (lean and clean):

service_004

Again, some notes:

  • A lifecycle initiates on entity creation in runtime; So, do a publication and create some ‘project’ entity instances in runtime (under ‘/app/start’)
  • An empty activity (without a layout) like above will land in the inbox of the current user initializing the lifecycle; Yes, that’s a different mindset from the BPM implementation! Don’t shoot the messenger! 🤐
  • You find instances of these lifecycles in the CIM artifact.

With all this in place, we can now continue our journey…Finally, services time!


Services introduction

In the next section we’ll fire Soap requests against the Gateway of the platform (remember the post from last week!). We’ll keep it simple using the ‘Web Service Interface Explorer’ artifact. Looking at the messages below, you can find them by name, and you can trigger them with the ‘test’-action:

service_005

Sometimes you must watch out for the correct naming space which you can see in the messages below; Like for example the space http://schemas.cordys.com/bpm/deployment/1.0. A namespace makes it possible to use similar operation names within the platform without interfering each other; You directly see a good example in the screenshot above!

Finally, in the messages below you’ll find these variables for you (and me) to replace:

  • {process_name} = nl-bos-general/bpms/bmp_demo1 (watch the project structure image above again or dare to use your own!)
  • {process_instance_id} = A unique ID per BPM instance you start
  • {case_model_id} = A unique ID of the case/lifecycle for an entity (not the instance, but the template/model)
  • {case_instance_id} = A unique ID per case/lifecycle instance you start (equals the creation of a new entity instance!)

Time for some action…AND before I forget; Always put the below messages between the body:

1
2
3
4
5
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP:Body>
<!--Put the messages from below in here!-->
</SOAP:Body>
</SOAP:Envelope>

BPM models

These are service calls you can do on a deployed process model. So, there is no need to scroll through endless BPM models in the ‘Deployed Process Models’ artifact to do your tricks.

1
2
3
4
5
6
7
8
9
10
11
<!--
Get BPM models; Be careful on the 'numRows' value.
You can search the response on the <configuration> element on "custom"
logging levels!
-->
<GetAllProcessModels
xmlns="http://schemas.cordys.com/bpm/deployment/1.0">
<cursor id="0" position="0" numRows="5" maxRows="99999" />
<modelSpace>organization</modelSpace>
<detail>false</detail>
</GetAllProcessModels>
1
2
3
4
5
6
7
8
9
10
11
12
13
<!--Get BPM models with specific details by xPath!-->
<GetAllProcessModels
xmlns="http://schemas.cordys.com/bpm/deployment/1.0">
<cursor id="0" position="0" numRows="5" maxRows="99999" />
<modelSpace>organization</modelSpace>
<detail>true</detail>
<details>
<detail id="myRef1"
xpath="processinstance/messagemap/instanceProperties/modelID" />
<detail id="myRef2"
xpath="processinstance/messagemap/instanceProperties/modelID" />
</details>
</GetAllProcessModels>
1
2
3
4
5
6
<!--Get information about a BPM model-->
<GetProcessModel
xmlns="http://schemas.cordys.com/bpm/deployment/1.0">
<processname>{process_name}</processname>
<modelSpace>organization</modelSpace>
</GetProcessModel>
1
2
3
4
5
6
7
8
9
10
11
12
<!--
Set the "custom" monitoring level for a BPM model; 13 equals
"Process status, input, output messages and message-map"
-->
<SaveProcessModelConfiguration
xmlns="http://schemas.cordys.com/bpm/deployment/1.0">
<configuration>
<processName>{process_name}</processName>
<monitorLevel>13</monitorLevel>
<crashRecovery>0</crashRecovery>
</configuration>
</SaveProcessModelConfiguration>
1
2
3
4
5
<!--Reset the monitoring level-->
<DeleteProcessModelConfiguration
xmlns="http://schemas.cordys.com/bpm/deployment/1.0">
<processName>{process_name}</processName>
</DeleteProcessModelConfiguration>

BPM instances

Once BPMs are instantiated from runtime, they will pass by in the PIM artifact. On a smaller scale it’s sufficient, but once going next level you start to see its limitation. So, have a look at the below messages to conquer BPM instances via service calls.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!--
Get a summary of the BPM instances per BPM model by a set of filtered states.
-->
<GetProcessInstanceSummary
xmlns="http://schemas.cordys.com/pim/queryinstancedata/1.0">
<Query xmlns="http://schemas.cordys.com/cql/1.0">
<Select>
<QueryableObject>InstancesSummary</QueryableObject>
<Field>ProcessName</Field>
<Field>ProcessFolder</Field>
<Field>ShortProcessName</Field>
<Field>Version</Field>
<Field>ModelSpace</Field>
<Field>NrTotal</Field>
<Field>NrRunning</Field>
<Field>NrQueued</Field>
<Field>NrWaiting</Field>
<Field>NrTerminated</Field>
<Field>NrSkipped</Field>
<Field>NrReplaced</Field>
<Field>NrComplete</Field>
<Field>NrAborted</Field>
<Field>NrSuspended</Field>
<Field>NrDebug</Field>
<Field>NrDebugReady</Field>
</Select>
<Filters>
<In field="STATUS">
<Value>ABORTED</Value>
<Value>WAITING</Value>
<Value>RUNNING</Value>
<Value>QUEUED</Value>
</In>
</Filters>
</Query>
</GetProcessInstanceSummary>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<!--
Get BPM instances; Be careful on the 'numRows' value!
These are additional field: INSTANCE_ID, DESCRIPTION, IS_ARCHIVED, MODEL_SPACE,
PROCESS_TYPE, SOAP_PROCESSOR, RUNTIME_DOCUMENT_ID, WORKSPACE_ID,
HAS_INPUT_MESSAGE, HAS_OUTPUT_MESSAGE, HAS_MESSAGE_MAP, PARENT_ID, PARENT_TYPE,
ROOT_TYPE, CRASH_RECOVERY, ORIGINAL_ID, SUBSTITUTE_ID, HAS_ERROR
Optionally a filter to show only aborted and duration greater than 5 min.
for a specific process.
-->
<GetProcessInstances
xmlns="http://schemas.cordys.com/pim/queryinstancedata/1.0">
<Query xmlns="http://schemas.cordys.com/cql/1.0">
<Select>
<QueryableObject>PROCESS_INSTANCE</QueryableObject>
<Field>START_TIME</Field>
<Field>PROCESS_NAME</Field>
<Field>STATUS</Field>
<Field>END_TIME</Field>
<Field>USER_NAME</Field>
<Field>TYPE</Field>
<Field>ROOT_ID</Field>
<!-- Add this from the below IDENTIFIER_ID result!
<Field alias="IDENTIFIER_VALUE1">BusinessIdentifierID:{IDENTIFIER_ID}</Field>
-->
</Select>
<Filters>
<And>
<EQ field="PROCESS_NAME">
<Value>{process_name}</Value>
</EQ>
<GT field="DURATION">
<Value>300000</Value>
</GT>
<In field="STATUS">
<Value>ABORTED</Value>
<Value>WAITING</Value>
<Value>RUNNING</Value>
</In>
<!-- Add this from the below IDENTIFIER_NAME result!
<EQ field="BusinessIdentifier:{IDENTIFIER_NAME}">
<Value>{your_value}</Value>
</EQ>
-->
</And>
</Filters>
<Cursor numRows="10" position="0"/>
<OrderBy>
<Property direction="desc">START_TIME</Property>
</OrderBy>
</Query>
</GetProcessInstances>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!--Get the business identifiers which you can use in the above message! -->
<GetBusinessIdentifierDefinitions
xmlns="http://schemas.cordys.com/pim/queryinstancedata/1.0">
<Query xmlns="http://schemas.cordys.com/cql/1.0">
<Select>
<QueryableObject>BusinessIdentifierDefinition</QueryableObject>
<Field>IDENTIFIER_ID</Field>
<Field>IDENTIFIER_NAME</Field>
<Field>IDENTIFIER_DESCRIPTION</Field>
<Field>IDENTIFIER_TYPE</Field>
<Field>IDENTIFIER_PRECISION</Field>
<Field>MODEL_SPACE</Field>
<Field>ORGANIZATION</Field>
</Select>
</Query>
</GetBusinessIdentifierDefinitions>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!--Get the details for a stranded BPM instance (in "Aborted" state)-->
<GetProcessInstances
xmlns="http://schemas.cordys.com/pim/queryinstancedata/1.0">
<Query xmlns="http://schemas.cordys.com/cql/1.0">
<Select>
<QueryableObject>PROCESS_INSTANCE</QueryableObject>
<Field>INSTANCE_ID</Field>
<Field>STATUS</Field>
<Field>PROCESS_TYPE</Field>
<Field>MESSAGE_MAP</Field>
<Field>MESSAGE</Field>
<Field>ERROR_TEXT</Field>
</Select>
<Filters>
<EQ field="INSTANCE_ID">
<Value>{process_instance_id}</Value>
</EQ>
</Filters>
</Query>
</GetProcessInstances>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!--Restart process instances; <receiver> is repeating!-->
<RestartProcess xmlns="http://schemas.cordys.com/bpm/monitoring/1.0">
<receiver>{process_instance_id}</receiver>
<activityID/>
<batch>true</batch>
</RestartProcess>
<!--Suspend process instances -->
<SuspendProcess xmlns="http://schemas.cordys.com/bpm/monitoring/1.0">
<receiver>{process_instance_id}</receiver>
<batch>true</batch>
</SuspendProcess>
<!--Resume process instances -->
<ResumeProcess xmlns="http://schemas.cordys.com/bpm/monitoring/1.0">
<receiver>{process_instance_id}</receiver>
<batch>true</batch>
</ResumeProcess>
<!--Terminate process instances -->
<TerminateProcess xmlns="http://schemas.cordys.com/bpm/monitoring/1.0">
<receiver>{process_instance_id}</receiver>
<batch>true</batch>
</TerminateProcess>
1
2
3
4
5
6
7
<!--
Remove a "completed" from the PIM; Keep in mind there are cleaning
tools available too!
-->
<DeleteInstanceData xmlns="http://schemas.cordys.com/bpm/monitoring/1.0">
<transaction_id>{process_instance_id}</transaction_id>
</DeleteInstanceData>

Read about cleaning the platform here


Case instances

Finally, what we can do for the BPM instances in the PIM is also possible for the Lifecycle/Case instances in the CIM!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!--Get a summary of different type of cases/lifecycles (aka your entities!)-->
<GetCaseInstanceSummary
xmlns="http://schemas.cordys.com/casemanagement/instanceadministration/1.0">
<Query xmlns="http://schemas.cordys.com/cql/1.0">
<Select>
<QueryableObject>BPM_MODEL</QueryableObject>
<Field>MODEL_ID</Field>
<Field>MODEL_NAME</Field>
<Field>CURRENT_REVISION</Field>
<Field alias="CASE_MODEL_STATUS">STATUS</Field>
<Field>CASE_INSTANCE_STATUS</Field>
<Field>COUNT</Field>
</Select>
</Query>
</GetCaseInstanceSummary>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<GetCaseInstances 
xmlns="http://schemas.cordys.com/casemanagement/instanceadministration/1.0">
<Query xmlns="http://schemas.cordys.com/cql/1.0">
<Select>
<QueryableObject>CASE_INSTANCE</QueryableObject>
<Field>CASE_INSTANCE_ID</Field>
<Field>MODEL_REVISION</Field>
<Field>CASE_MODEL</Field>
<Field>MODEL_REVISION</Field>
<Field>STATUS</Field>
<Field>STARTED_ON</Field>
<Field>STARTED_BY</Field>
<Field>LASTMODIFIED_ON</Field>
<Field>LASTMODIFIED_BY</Field>
<Field>DUE_ON</Field>
<!-- Even a function is possible!
<Field alias="CASE_INSTANCE_COUNT" function="count">CASE_INSTANCE_ID</Field>
-->
</Select>
<Filters>
<And>
<EQ field="CASE_INSTANCE_ID">
<Value>{case_instance_id}</Value>
</EQ>
<EQ field="STATUS">
<Value>ABORTED</Value>
</EQ>
</And>
<!-- or filter on model ID (aka your entity!)
<EQ field="CASE_MODEL">
<Value>{case_model_id}</Value>
</EQ>
-->
</Filters>
<OrderBy>
<Property direction="desc">STARTED_ON</Property>
</OrderBy>
</Query>
</GetCaseInstances>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!--Get the state/activity details for a case/lifecycle instance-->
<GetActivities
xmlns="http://schemas.cordys.com/casemanagement/instanceadministration/1.0">
<Query xmlns="http://schemas.cordys.com/cql/1.0">
<Select>
<QueryableObject>ACTIVITY_INSTANCE</QueryableObject>
<Field>ACTIVITY_INSTANCE_ID</Field>
<Field>CORELATION_ID</Field>
<Field>CASE_INSTANCE</Field>
<Field>PLANNED_ON</Field>
<Field>STARTED_ON</Field>
<Field>LASTMODIFIED_ON</Field>
<Field>LASTMODIFIED_BY</Field>
<Field>CURRENT_STATUS</Field>
<Field>STATE_NAME</Field>
<Field>ACTIVITY_NAME</Field>
<Field>ACTIVITY_TYPE</Field>
</Select>
<Filters>
<EQ field="CASE_INSTANCE">
<Value>{case_instance_id}</Value>
</EQ>
</Filters>
</Query>
</GetActivities>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!--Action you can do on a case; Depends on the current state!-->
<!--Restart (an aborted) case instance-->
<RestartCaseInstance
xmlns="http://schemas.cordys.com/casemanagement/instanceadministration/1.0">
<caseinstanceid>{case_instance_id}</caseinstanceid>
</RestartCaseInstance>
<!--Suspend a case instance-->
<SuspendCaseInstance
xmlns="http://schemas.cordys.com/casemanagement/instanceadministration/1.0">
<caseinstanceid>{case_instance_id}</caseinstanceid>
</SuspendCaseInstance>
<!--Resume a case instance-->
<ResumeCaseInstance
xmlns="http://schemas.cordys.com/casemanagement/instanceadministration/1.0">
<caseinstanceid>{case_instance_id}</caseinstanceid>
</ResumeCaseInstance>
<!--Terminate a case instance-->
<TerminateCaseInstance
xmlns="http://schemas.cordys.com/casemanagement/instanceadministration/1.0">
<caseinstanceid>{case_instance_id}</caseinstanceid>
</TerminateCaseInstance>
<!--Delete a case instance-->
<DeleteCaseInstance
xmlns="http://schemas.cordys.com/casemanagement/instanceadministration/1.0">
<caseinstanceid>{case_instance_id}</caseinstanceid>
</DeleteCaseInstance>
<!--Close a case instance-->
<CloseCaseInstance
xmlns="http://schemas.cordys.com/casemanagement/instanceadministration/1.0">
<caseinstanceid>{case_instance_id}</caseinstanceid>
</CloseCaseInstance>

That’s it for this nice overview…


A great “DONE” where we now have a great overview of the possible service calls that we can execute on BPM instance and Lifecycle instances. This gives brilliant input for our next step on crafting our own artifact showing details “the new way”! Keep it locked here as we’ll expose greatness to benefit from. Have a good weekend and I see you next week!

Don’t forget to subscribe to get updates on the activities happening on this site. Have you noticed the quiz where you find out if you are also “The Process Automation guy”?