/ Development  

Expose a BPM webservice with custom XML input

Hi there AppWorks fans,

Welcome to a new installment of AppWorks tips.

O boy, O boy…sometimes you see requirements passing by, and you just don’t know where to start thinking!? You get that feeling…right? Let me explain the use-case:

Long, long time ago…There was an “external system” which can push out XML data. This system runs somewhere in your internal intranet! The ‘Analyst guy’ (there he is again!) has the nicest thing thought out. The AppWorks platform should expose a service (based on XML; so, we’re talking SOAP here!) which can be called from that “external system”. The exposed service should be able to accept the pushed XML, so the platform can start some BPM to handle the further actions which partly is defined in the XML.

Right!?…Do you have your diving suit on!? (don’t forget to bring the flippers, and a beer once we’re done!) 🍺


Let get right into it…

First the plan:

  • What XML are we talking about?
  • Our platform is XML based, so just upload it for reusability
  • We need to have a BPM in place to handle the XML data (with a ‘dummy’ activity to be ‘publishable’ valid)
  • The XML data needs to be passed in (I guess as input message on the BPM)
    • Do we also need to return something? Not for this post, but that would be the output message!
  • Once the BPM is ready we need to expose it as a webservice (which includes our XML input message)
  • A BPM webservice can’t be executed without a BPM service container (we’ll create one)
  • Finally, we need to test it (with SoapUI Open Source and also with a regular user account to double-check runtime security issues)

Nice…Plan is ready! Next is the implementation…


The XML

During my vacation (some time ago), I just played a bit with MQTT on my Raspberry Pi Model B V1.2…Interesting stuff!! 🤓

Let’s go for an XML like this:

1
2
3
4
5
6
7
<?xml version="1.0" encoding="UTF-8"?>
<mqtt_data>
<type>subscribe</type>
<broker>south_wing</broker>
<topic>test/all</topic>
<payload>Hello world...</payload>
</mqtt_data>

So, for the good understanding; this XML-chunk needs to be accepted by our beloved platform in some way!? The platform is XML-minded, but because we are not interested in the values of the XML, but only the ‘blueprint’, we convert the XML to an XSD schema via this website. We can use the result to create a new ‘XML schema’ type of document…Just in a ‘schemas’ folder for your project!

1
2
3
4
5
6
7
8
9
10
11
12
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="mqtt_data">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="type"/>
<xs:element type="xs:string" name="broker"/>
<xs:element type="xs:string" name="topic"/>
<xs:element type="xs:string" name="payload"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

input_001

After hitting the ‘Finish’ button, you get a message to fill in a target-namespace-URI. You can just fill-in something you like, but “normally” we would like to use some company URL with some post elements behind it. For AppWorks Tips that could be something like https://appworks-tips.com/xsd/sample. Here you’ll find more about namespace settings and why we do it. Later on you’ll also see the advantage of using XSD schema documents!

Also have a look at the ‘Children’ nodes of this document where you’ll find out we could also build up this XSD ourselves:

input_002


The BPM

The XML needs to trigger a BPM…So, let’s create one (nicely created in the ‘bpms’ folder!)

input_003

The trigger moment (to start this BPM) needs to be a SOAP service call with input of our XML data…Great! as our BPM can have an input message (later on we’ll focus on the service-call part). Open the “Message Map” of our initial BPM and create a new ‘Message’:

input_004

We just update the name to a value like input and next we drag and drop our element of the XSD document into it…watch and learn:

input_005

The end-result will look like this:

input_006

Now that we’re already in the namespace theory…Let’s do that namespace URI trick also for our BPM! (A thing I also always forget, but that’s the difference between the ‘noob’ and the ‘pro’…as my kids always tell me). Just keep on doing it and after some time you eventually do these settings as a second nature (took me 2 years to not forget it!) 💪

input_007

See also that update on the ‘execution mode’ where we move to “Short Lived” as this BPM doesn’t have any manual activities at the moment. On the other hand it would not be that harmful when the BPM was “Long Lived” as it hasn’t any interaction with the UI (yet)!? It all depends…As always!

To make it even 2.0 “name spaced” we even can update the prefix to a nicer value within this BPM:

input_008

Enough about the ‘namespace’ stuff…Back to focus on the post…The input-message!

Get the properties of the green ‘Start’ construct and make sure it accepts our message as trigger:

input_009

Did you notice the ‘envelop’ icon on the ‘Start’ construct? Now you’re on the good track…😉

So far, so good…Save, and publish it. From the project, right-click the BPM and do a run…

input_010

…where we get a nice input screen!

input_011

Time to convert this all into a webservice call…


The (BPM) webservice

Now, our BPM is ready…Let’s generate a webservice out of it!

input_012

You get a modal popup where we can define what needs to be generated (where we save it nicely in our ‘webservices’ folder of the project):

input_013

Hit that ‘Finish’ and see the magic being triggered…with in the project a nice service:

input_014

Before we can test this service (via right-click), we need to do 2 things:

  1. Publish it…Let’s just do it (again from a right-click action)
  2. Make a BPM service container available which can handle this service (you will get an error when you try to test it: Service Group Lookup failure.).

This error will be solved in the next section…


The (BPM) service container

BPM service is ready…Time for a BPM service container to handle the requests! Open the ‘System Resource Manager’ artifact and create a new service group of type BPM:

input_015

Hit ‘Next >’

input_016

Give a nice name and mark our service interface (which is of type BPM!). Hit ‘Next >’ when ready…

input_017

Give a nice name again, mark the options as you like and hit ‘Next >’

input_018

Now three interesting tabs where we can decide where to store BPM information. For now, we just select the ‘system’ organization and we re-use the current AppWorks database. We can do the same for the ‘Scheduler’ and if you mark the ‘Enable Rule Engine’ option in the ‘Process Engine’ tab we can do the same trick.

As I’m as curious as you what information will be saved in these database settings, I made a backlog item out of if for further exploration. A first guess will be the storage of BPM related information like when a BPM starts, who started it, what went wrong, etc…We’ll see!

Hit ‘Next >’

input_019

Finally, we can hit ‘Finish’

OK…Back to our BPM service in the project for a quick test…

input_020

This time we nicely retrieved a message with the instance_id of the just started BPM…This will also be available from the PIM perspective! 🕵


The final external test (with SoapUI)

Time to make a session with our ‘normal’ user as we currently executed everything with the ‘Developer’ role account. My ‘awtest’ account doesn’t have any role applied and with this account I will try to execute our brand-new service from the ‘services time’ of the platform via URL:
http://192.168.56.107:8080/home/appworks_tips/services

I use a new ‘Incognito’ tab in Chrome, so I’m sure to get a fresh login screen as we still need to authenticate!

Have a browser search for ‘mqtt’ to get our service exposed which we will test:

input_021

Insert the request and send it out…

1
2
3
4
5
6
7
8
9
10
11
12
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP:Body>
<invoke_from_mqtt xmlns="https://appworks-tips.com/bpm/sample">
<ns0:mqtt_data xmlns:ns0="https://appworks-tips.com/xsd/sample">
<ns0:type>PARAMETER</ns0:type>
<ns0:broker>PARAMETER</ns0:broker>
<ns0:topic>PARAMETER</ns0:topic>
<ns0:payload>PARAMETER</ns0:payload>
</ns0:mqtt_data>
</invoke_from_mqtt>
</SOAP:Body>
</SOAP:Envelope>

There you have it…A security error (as expected!): Access is denied for the Web service operation 'invoke_from_mqtt'.

OK…Back to design time and have us a “runtime security” in the webservice:

input_022

For this security we need a new ‘role’ with in our case the name ‘resource’…Like this:

input_023

We save it nicely in the ‘roles’ folder of the project, and we also make sure this role can ‘execute’ our webservice:

input_024

Now, let’s publish the role and make sure you assign the ‘awtest’ account to the role from the ‘User Manager’ artifact:

input_025

Time for a retest…Again an error:

1
2
3
Access is denied for the Web service operation 'ExecuteProcess'. 
You do not have permissions to access some of the resources required for your request.
Contact the administrator.

Right, we’re making progress, but this time our ‘awtest’ user also requires a runtime security for the BPM itself. Right-click on our BPM in design-time and do the same trick as we just did for the webservice!

input_026

Again a publication and a retest with (this time) a valid response:

input_027

Green flags! ✅✅✅…time for SoapUI

We use the opensource version which can be downloaded from here.

Once installed and started, we can create a new SOAP project:

input_028

Fill in the information like this:

input_029

The initial WSDL URL can be copied from here:

input_030

Hit that OK button to see some interesting generated stuff!

Once there, we can execute our first request:

input_031

That’s an expected error as we don’t provide any credentials…Time for an update in the request:

input_032

1
2
3
4
5
6
7
8
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:Username>awtest</wsse:Username>
<wsse:Password>admin</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>

Niceeeee, but a bit of cheating…Maybe you noticed it!? Maybe not…Have look again in the security header! There is a small difference in username! From the SoapUI call I use a platform (internal) account. Not the one from OTDS! It doesn’t matter for this post for now (and a bit out of scope), but if you also would like to authenticate with OTDS I recommend diving into this post.


🍺-time, and we can also give this post a “DONE” where we learned about exposing a BPM webservice for the “external system” to give it a call. We even did the external call with the valuable tool SoapUI. Also, this tool is great in use when you would like to play with other SOAP services the platform delivers. If smartly used, you can even replace it for the ‘Web Service Interface’ explorer where you can make webservice calls to a next level! Have a great week-end, and I CU in the next post, 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 AppWorks guy”?