Wednesday 17 December 2014

Send HTML Formatted email using SoaSuite 11g/12c

This week I stumbled upon a question on the SOASuite forum, on the Oracle communities, that where the questioner wanted to send HTML-formatted emails.

It happens that I was busy with the email-adapter myself, and it would be nice to have neatly formatted email. It took me some time, but I managed to do it.
It basically consist of:
  1. Define an outbound email adapter config, with Opaque element. This expects an Base64 encoded payload, which enables you to put in everything you want (given it is valid for your receiver)
  2. Create an HTML payload as a string, simply by concatenating all the html code, your content and probaly variable-content.
  3. Use an embedded java activity to unencode the XML encodings and Base64 encode it.
  4. Copy the Base64 encoded payload to the opaque message payload, fill in the subject and the to-email-adres
  5. Invoke the email adapter, with the following properties on the invoke activity:
    1. jca.ums.to -> based on a variable
    2. jca.ums.subject -> based on a variable
    3. jca.ums.msg.content-type -> based on an expression: "text/html"
The last-property is important: it tells the receiving application to interpret the message as html.

Read the complete how-to here.

When I have time, in a later stage I'll update this message to transfer the content to this page.

Monday 15 December 2014

ora:getAttachmentProperty: Failed to decode properties string

Last week I created a process that polls the usermessagingservice-email adapter to read emails and store the email with attachments as Oracle ACM case documents.

For simple e-mails this works fine, but with some emails I get the error:
0An error occurs while processing the XPath expression; the expression is ora:getAttachmentProperty('Content-Type', 'ReceiveMessage_ReceiveNotification_InputVariable','body', '/ns2:message/ns2:attachment[$AttachmentId]').XPath expression failed to execute.

An error occurs while processing the XPath expression; the expression is ora:getAttachmentProperty('Content-Type', 'ReceiveMessage_ReceiveNotification_InputVariable','body', '/ns2:message/ns2:attachment[$AttachmentId]').

The XPath expression failed to execute; the reason was: java.lang.RuntimeException: Failed to decode properties string ,att.contentId=1,Content-Type=multipart/related;

    boundary "---- _Part_188_790028878.1418047669530",.

Check the detailed root cause described in the exception message text and verify that the XPath query is correct.

XPath expression failed to execute

This occurs with both the functions ora:getAttachmentProperty and ora:getAttachmentContent.

It turns out that attachements that fail, are embedded attachments, like company logo's in autographs. They have a content-type like: "multipart/related", see the propertie string like:
,att.contentId=1,Content-Type=multipart/alternative; 
 boundary "---- _Part_21_137200243.1418648527909",/related;
But 'real' attachments did work, and had a properties string like:
Content-Transfer-Encoding=base64,Content-Disposition=attachment,att.contentId=2,Content-ID=<58BB5695B386104EA778D6E3C982C79D@caci.nl>,Content-Type=image/jpeg; name DataSources.jpg,

Apparently, if the content-type in the properties string does not start with 'multipart', then the attachment is processable.
When you open the BPEL ReceiveMessage_ReceiveNotification_InputVariable input variable I got something like:
  <part xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="body">
      <message xmlns="http://platform.integration.oracle/blocks/adapter/fw/metadata/SWKInboundEmail">
         <attachment href="409425ae-8448-11e4-a413-000c297d0a6d"/>
         <attachment href="409907af-8448-11e4-a413-000c297d0a6d"/>
         <attachment href="4099a3f0-8448-11e4-a413-000c297d0a6d"/>
         <attachment href="409a4031-8448-11e4-a413-000c297d0a6d"/>
         <opaqueElement xmlns="http://xmlns.oracle.com/pcbpel/adapter/opaque/">PGh0bWwgeG1sbnM6dj0idXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTp2bWwiIHhtbG5zOm89InVy
bjpzY2hlbWFzLW1pY3Jvc29mdC1jb206b2ZmaWNlOm9mZmljZSIgeG1sbnM6dz0idXJuOnNjaGVt
YXMtbWljcm9zb2Z0LWNvbTpvZmZpY2U6d29yZCIgeG1sbnM6bT0iaHR0cDovL3NjaGVtYXMubWlj
cm9zb2Z0LmNvbS9vZmZpY2UvMjAwNC8xMi9vbW1sIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv
VFIvUkVDLWh0bWw0MCI+DQo8aGVhZD4NCjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIg
... 
.

In the Soa Infra database a table exists named 'ATTACHMENTS', with three columns: 'KEY', 'ATTACHMENT' and 'PROPERTIES'.

When you do a select on that table where the key the @href attribute, then you'll find the attachment. The PROPERTIES column contains the properties string like mentioned above.

So I created a DB Adapter config, with JNDI name 'eis/DB/SOA' (referring to already configured datasource in the DB Adapter), on this table. In the for-each loop I first query the attachment using the href attribute.

Then I extract the content-type using the expression
substring-before(substring-after($InvokeQuerySoaInfraAttachments_QuerySoaInfraAttachmentsSelect_OutputVariable.AttachmentCollection/ns6:Attachment/ns6:properties, 'Content-Type='),';')

In an IF statement using an expression like
not(starts-with($contentType, 'multipart'))
I only process those attachments that has content-type that is not multipart.

Probably a more sophisticated expression can be found.I could check on a list of only supporting mime-types.

To me this seems like a bug: SOASuite should be able to get the available properties out of the string to be able to process this.The main problem is also that the BPEL fault-handler is ignored: when the error occurs, the process fails! So I can't catch the exception and act on it. And honestly: I should not query the table myself, using the DB adapter, do I?

By the way: working with 12c (12.1.3), but I assume the same will occur in 11g.

Wednesday 3 December 2014

Integrating BPM12c with BAM

In BPM12c there is a tight integration with BAM, like it was with 11g. However, BAM is not automatically installed in BPM. You need to do that seperately. But having done that, you need to get BPM acquainted with BAM and instruct it to enable process analytics.

For a greater part the configuration is similar to the 11g story. My former oracle colleague wrote a blog about it: 'Configuration of BAM and BPM for process analytics'.
There is a little difference, because in 12c you won't find the mentioned property 'DisableActions' under the 'oracle.as.soainfra.config' -> 'BPMNConfig'. But you have to enable process analytics on the bpm-server(s). The 12c docs tell you how: '11.1 Understanding Oracle BAM and BPM Integration'.
Taken from that document here a short step-list:
  1. Log in to the Fusion Middleware Control (http:Adminserver-host:port/em) console. 
  2. In the Target Navigation pane, expand the Weblogic Domain node. 
  3. Select the domain in which the Oracle BAM server is installed. 
  4. Open the MBean Browser by right-clicking on the domain and select System MBean Browser. 
  5. Expand the Application Defined MBeans node. 
  6. Navigate to oracle.as.soainfra.config node -> 'Server: server_name' -> AnalyticsConfig -> analytics.
  7. Disable the 'DisableProcessMetrics'-property by setting the value to false. 
  8. You might want to do the same with the 'DisableMonitorExpress'-property.
  9. Click Apply.