Wednesday, 24 September 2014

JMS Properties in BPM Suite

Lately I needed to transfer messages from OSB to BPM Suite. The setup was that OSB calls a Webservice implemented by a Mediator component that publishes the message on a JMS queue. The webservice request contains a mesage header and a message payload. The payload published as the JMS message-content, but the message header elements were added as custom JMS-properties to the message. How to do that is quite easy and described for instance in this blog.
The JMS Adapter forJMS documentation can be found here, and the particular part about the properties here.
In essence, in the Assign Values part of the Mediator configuration, custom JMS-properties can be referrered to as
$in.property.jca.jms.JMSProperty.custompropertyname


The BPM Process listens to the queue and needed to be adapted to read the JMS-properties. I could not find info about that, but it turns out to be simple: in the ServiceCall activity you have the Service Properties link:
 This will bring up the service properties dialog:
The green-plus and pensil icons can be used to add and edit the service property assignments:

The property name is of the same structure as with the mediator: 'jca.jms.JMSProperty.name'.
The expression must denote an automatically instantiated dataobject of type string. I tried to use a structured business object, but then apparently only the root element is instantiated. On run-time I got errors that the assignment of the JMS-property to the particular element failed. So for each JMS-Property I created a separate Dataobject of type string. And that works perfectly.

Service VersionInfo in OSB

When deploying a SCA project (SOASuite or BPMSuite) from JDeveloper you'll be asked to provide a version number. Often when deploying using a script (ANT or Maven) based deployment to a test, acceptance or production environment, the used deployment-framework may use a release number for the versions of the different composites. Besides the support of different versions of composites to reside side-by-side in SOASuite, this is convenient, because this way you know what version of the composite is deployed on the particular server. Then it is certain that a deployment of a particular version has succeeded and that the particular change that you ment to deliver is or is not in use.

In OSB there's no such thing as side-by-side support of versions and also you can't see what particular version of a OSB  Configuration is deployed.

Since I was asked several thimes by project managers to denote different versions of a particular service in different releases I came up with a very simple solution.

First I defined an xml schema, like the following:
<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://xmlns.darwin-it.nl/CDM/xsd/V1/SVC/VersionInfo"
            xmlns:ver="http://xmlns.darwin-it.nl/CDM/xsd/V1/SVC/VersionInfo" elementFormDefault="qualified">
  <xsd:element name="VersionInfo" type="ver:versionInfoType">
    <xsd:annotation>
      <xsd:documentation>Version info</xsd:documentation>
    </xsd:annotation>
  </xsd:element>
  <xsd:complexType name="versionInfoType">
    <xsd:sequence>
      <xsd:element name="versionNr" type="xsd:string"/>
      <xsd:element name="versionDate" type="xsd:string"/>
      <xsd:element name="author" type="xsd:string"/>
      <xsd:element name="change" type="xsd:string"/>
      <xsd:element name="svnId" type="xsd:string"/>
    </xsd:sequence>
  </xsd:complexType>
</xsd:schema>
In my setup this xsd is placed in a separate shared xsd-project.
Then in the root of each OSB Service-project I place an xquery file as follows:
xquery version "1.0" encoding "UTF-8";
<ver:VersionInfo xmlns:ver="http://xmlns.darwin-it.nl/CDM/xsd/V1/SVC/VersionInfo">
  <ver:versionNr>1.50.01</ver:versionNr>
  <ver:versionDate>2014-09-17</ver:versionDate>
  <ver:author>M. van den Akker</ver:author>
  <ver:change>ChangeNr - Particular change</ver:change>  
  <ver:svnId>$Id: versie.xq 1520 2014-09-17 10:25:29Z makker $</ver:svnId>  
</ver:VersionInfo>
This xquery is nothing more than an xml-file with an xquery-prolog, a trick you can use to externalise hardcoded properties from your proxy-services. So it doesn't have input and output variable declarations. You could replace certain fields like versionNr with ant-properties to replace it during an ant deployment. In my current setup I change it by hand when commiting the changes in Subversion.

In my proxyservices at the 'entry points' of the services, the start of the first stage in the message flow, I add an assign and an alert. In the Assign the xquery is executed to a versionInfo variable:
Assign with VersionInfo xquery
 Then an alert is added to have the version info shown after the call of the service. This way you can see with what version of the service the request is handled:
Alert of version information
The expression of the alert is:
concat('Version: ',$versionInfo/ver:versionNr,', date: ',$versionInfo/ver:versionDate)
This is where the xsd comes along, because to help you enter this expression, but especially to get this valid (to get the namespace added), you must add the versionInfo element of the xsd as the versionInfo variable. You could also add the namespace manually, but adding the variable structure is more convenient.

This alert is actually optional, but can be usefull when debugging, investigating services and service executions. The xquery resides after deployment on the OSB Server and can be reviewed using the Project Explorer in the Servicebus console. It can be hard for the system-administrator to conclude from script output if a deployment succeeded. The comparison of the versionInfo.xq on the OSB with the version in a release-document that you deliver with your deployment can help him out. OSB commits the deployment as a whole, so the correct version-number in the versionInfo.xq file indicates a successfull deployment.

Another trick you could notice in the screendump is that I use a seperate alert destination for development/debug messages. I found that you can't set the loglevel on an alert. You need to do that on each proxyservice in a compound service configuration. Because I found that very inconvenient, I added a seperate alert destination for debug messages. On acceptance and/or production you can switch of the logging of debug messages on that particular destination.