/ Development  

Play with masterdata webservice in BPM loop

Hi there AppWorks fans,

Welcome to a new installment of AppWorks tips.

In this post we continue with our linked entity (from previous post)…If it’s still linked? Otherwise you need to re-link it! When ready we’ll generate a webservice out of the linked entity. This webservice can than be used in a BPM… And finally,…In that same BPM we’ll loop over the data that we retrieve to fill a dropdown field. This last BPM will be (off-course related) to a dynamic enumerated property with an output message…Hard to do? Not at all if you follow the steps below…watch and learn!


Let get right into it…

Make sure you have your linked entity ready…For me it’s the ‘customer’ linked entity where I also created the forms and lists for so we can see something in the front-end!

Make sure that you can just create new instances of this entity…That’s all (like we learned from the previous post).

Next step is to generate a webservice out of our ‘customer’ table. Right click the ‘customer’ table in the ‘Database Metadata’ structure and choose the option ‘Generate Standard Web Services’

bpm_loop_001

You get a screen that can be left by default and you can click ‘Next’

bpm_loop_002

Select nothing extra and just click ‘Finish’

bpm_loop_003

And see the end-result…How nice!

bpm_loop_004

Now publish this service to the organization.

And after this publish you can test it.

bpm_loop_005

Use this soap message as an example!

1
2
3
4
5
6
7
8
9
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP:Body>
<GetcustomerObjects xmlns="http://schemas.cordys.com/customer">
<cursor id="0" position="0" numRows="5" maxRows="99999" />
<fromid>1</fromid>
<toid>99</toid>
</GetcustomerObjects>
</SOAP:Body>
</SOAP:Envelope>

One thing I see for this example (not a problem for now) but nice to know! When you create a new database table without a ‘primary’ key it generates a webservice without the ‘fromid’ to ‘toid’ parameters so you can retrieve the full table in 1 service call. But when you create such a table (without primary key) you are not allowed to import linked entities from it!…So, every advantage has its disadvantage!

After hitting that ‘Invoke’ button you get your data back in XML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<data>
<GetcustomerObjectsResponse xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://schemas.cordys.com/customer">
<tuple>
<old>
<customer>
<id>1</id>
<cust_name>hello</cust_name>
<cust_address>world</cust_address>
<cust_age>1</cust_age>
</customer>
</old>
</tuple>
...
<cursor xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://schemas.cordys.com/customer" numRows="5" />
</GetcustomerObjectsResponse>
</data>

Create a dynamic enumerated property with a BPM

Pick an entity, in my case the ‘Project’ entity, where we can add a new property. I just create a new ‘proj_customer’ property like this:

bpm_loop_006

And add a new process to it

bpm_loop_007

It’s not depending on other properties, so ‘No’ is the proper option before you click ‘Create new process’

bpm_loop_008

A new BPM is created, and the first thing is to save it in the correct ‘bpms’ folder location for our project structure with a nice name like ‘enum_customers’.

bpm_loop_009

Remove that ‘Activity’ and insert our generate service from the ‘Insert’ tab (at the bottom of the right panel). Jump to the “Web Service Operation’ tab and search for ‘customer’ to get the ‘GetcustomerObjects’

bpm_loop_010

Now click the ‘GetcustomerObjects’ operation and save/publish the ‘Binding’ information

bpm_loop_011

Next you can drag & drop the webservice in place and connect it to the green/start point and the red /end point.

So, it looks like this now…

bpm_loop_012

Go to the ‘Message Map’ in the bottom and make sure you make the input parameters correct for this activity.

bpm_loop_013

Save it, publish it, and do a first run to see if all is running fine with <12> or <Ctrl> + <F12>


Fill the BPM output message with data from a for loop

Let’s extend the BPM with a second activity where we also apply the ‘Group as’ option with the ‘For Each’ action.

bpm_loop_014

And connect the items together again so you have this end-result:

bpm_loop_015

Make sure the arrow-flows are connected to the correct points!

Now open the properties for that ‘For Each’ loop and change this:

  • Description: For Each Customer
  • Iterator Name: IterCustomer
  • Select Condition: Static Value ns2:GetcustomerObjectsOutput/ns2:GetcustomerObjectsResponse/ns2:tuple

bpm_loop_016

Also, rename the other activities like this ‘SaveCustomerToEnum’ and ‘AddEnumToOutput’

bpm_loop_017

Now open the ‘Message Map’ for this BPM and go to the ‘Start’ point. This is where we get a copy of the XML-element that is required for each element in the output message (As we want to have multiple ‘EnumerationValue’ entries. One for each customer)! See it as a temporary variable.

bpm_loop_018

Copy the XML you see now.

1
2
3
4
5
<EnumerationValue xmlns="http://schemas/AppWorksTipsAppWorks/project/enumeration">
<Value>PARAMETER</Value>
<DisplayName>PARAMETER</DisplayName>
<IsDefault>PARAMETER</IsDefault>
</EnumerationValue>

And past it again as new element in the ‘Process Specific Messages’

bpm_loop_019

With an end-result like this where you also see a new namespace ns7 (in my case!)

bpm_loop_020

Now go to your ‘SaveCustomerToEnum’ activity and make a mapping like this

bpm_loop_021

  • The ‘Value’ will be retrieved from instance:IterCustomer/ns2:old/ns2:customer/ns2:id/text()
  • The ‘DisplayName’ will be retrieved from instance:IterCustomer/ns2:old/ns2:customer/ns2:cust_name/text()
  • The ‘IsDefault’ will (for now) be a fixed value of false

You see we get the information from our iterator ‘IterCustomer’ and not from the ‘ns2:GetcustomerObjectsOutput’ message. This last one should also work but is not the ‘logic’ way of thinking!

And not to forget; Use the ‘Replace content With Select’

Now for the ‘AddEnumtoOutput’ activity and it’s mapping like this:

bpm_loop_022

Yes…Just drag & drop both parent nodes

On the left side our already (filled with data from previous activity) temporary XML elements

On the right side our output message element where each temporary element will be added to!

So, don’t forget to change that usage option to Add Select with Target NS

Why ‘with Target NS’? Because the information is saved in namespace ns7 and need to land in namespace bpm…Important!!

Now save and publish and do a first debug/test run where you can check the messages passing by…

You might also do a ‘Validate and Built’ to fix unexpected results.

The output message (for my example) looks (in the end) like this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<GetEnumerationOutputMessage xmlns:instance="http://schemas.cordys.com/bpm/instance/1.0" xmlns:sm="http://www.w3.org/2005/07/scxml" xmlns:bpm="http://schemas/AppWorksTipsAppWorks/project/enumeration" xmlns:ns2="http://schemas.cordys.com/customer" xmlns:ns3="http://schemas.cordys.com/General/1.0/" xmlns:ns4="http://schemas.cordys.com/" xmlns:ns5="http://schemas.cordys.com/General/ClientAttributes/" xmlns:ns6="http://schemas.cordys.com/casemanagement/1.0" xmlns:ns7="http://schemas/AppWorksTipsAppWorks/project/enumeration_08002769-07f1-a1ea-961f-dd598dfb3f59" xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://schemas/AppWorksTipsAppWorks/project/enumeration">
<EnumerationValue xmlns="http://schemas/AppWorksTipsAppWorks/project/enumeration">
<Value>1</Value>
<DisplayName>kjkj</DisplayName>
<IsDefault>false</IsDefault>
</EnumerationValue>
<EnumerationValue xmlns="http://schemas/AppWorksTipsAppWorks/project/enumeration">
<Value>2</Value>
<DisplayName>hello</DisplayName>
<IsDefault>false</IsDefault>
</EnumerationValue>
<EnumerationValue xmlns="http://schemas/AppWorksTipsAppWorks/project/enumeration">
<Value>3</Value>
<DisplayName>asfd</DisplayName>
<IsDefault>false</IsDefault>
</EnumerationValue>
<EnumerationValue xmlns="http://schemas/AppWorksTipsAppWorks/project/enumeration">
<Value>4</Value>
<DisplayName>hello</DisplayName>
<IsDefault>false</IsDefault>
</EnumerationValue>
</GetEnumerationOutputMessage>

Add the ‘proj_customer’ property to the ‘Create’ form and do the final test

I didn’t have the default forms yet, but just create the ‘Default’ and ‘Create’ form where you include the ‘Create’ form in the ‘Default’ form.

Also create a ‘All Projects’ list where you add some nice properties.

And also, update the forms/lists so the ‘proj_customer’ property is usable!

When ready…save the ‘Project’ entity, publish it, and create a new instance in runtime!

And there we go…

bpm_loop_023


When %^#$%$# hits the fan, you can always do…
  • A ‘Validate and Build’ on the BPM
  • ‘Clean Build Output’ for the project and republish
  • Check the logging. Find the latest logfile with sudo find /opt -printf "%T@ %Tc %p\n" | sort -n
  • Restart your browser with a clean session (the dropdown from that webservice is cached!)
  • Check the ‘Process Instance Monitory’ artifact as each new project will trigger the Enum BPM!
  • Check the ‘Define Runtime Security’ option on the webservice and on the BPM
    • Runtime users need explicit permission to execute them in runtime.
    • Always test your solution with a non-administrator user!
  • Is your database table filled with values?
  • Did you select the correct mapping usage in the ‘Message Map’?

Last, but least…Make it a nice BPM! 🤟

Keep these bullets in mind:

  • Proper descriptive naming
  • Use the alignment options
  • Add a descriptive note
  • Mapping activity: WHITE
  • Start subprocess: PURPLE
  • Service activity (default): BLUE

bpm_loop_024


And that brings us to the end of this post where we can give ourselves a “DONE” we can be proud of…again! We really learned valuable information in this post about reading out an external database table; convert it to a webservice and make it accessible from a dynamic dropdown property. A mouth full, but this feature will be a repeating item during your AppWorks journey. BPM to the rescue when the standard functionality might bring you to a stuck situation…Hooray!

Have a great day and I CU in the next post.

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 AppWorks guy”?