Skip navigation.

Darwin IT

Syndicate content
Darwin-IT professionals do ICT-projects based on a broad range of Oracle products and technologies. We write about our experiences and share our thoughts and tips.Martien van den Akkerhttps://plus.google.com/110503432901891966671noreply@blogger.comBlogger232125
Updated: 8 hours 27 min ago

ora:getAttachmentProperty: Failed to decode properties string

Mon, 2014-12-15 11:40
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.

Integrating BPM12c with BAM

Wed, 2014-12-03 07:21
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.

Using DB Adapter to connect to DB2 on AS400

Tue, 2014-11-25 04:37
In my current project I need to connect to a DB2 database on an AS400. To do so is no rocket science, but not exactly a NNF (Next-Next-Finish) config.

First you need to download the IBM JDBC adapter for DB2, which is open souce. Download the JT400.jar  from http://jt400.sourceforge.net/. Place it in a folder on your server. Since it's not an Oracle driver, I don't like to have it placed in the Oracle-Home, so I would put it on a different lib folder, where it is recognisable. Create a logical one, where you place other shared libs as well.

There are several methods to add the lib to your weblogic class path. What worked for me was to add it to the 'setDomainEnv.cmd'/'setDomainEnv.sh' file in the domain home.

(The Default Domain of the integrated weblogic of JDeveloper 12.1.3 under Windows can be found in: “c:\Users\%USER%\AppData\Roaming\JDeveloper\system12.1.3.0.41.140521.1008\DefaultDomain”)
Search for the keyword ‘POST_CLASSPATH’ and add the following at the end of the list of POST_CLASSPATH-additions:
set POST_CLASSPATH=c:\Oracle\lib\jtopen_8_3\lib\jt400.jar;%POST_CLASSPATH%
Where 'c:\Oracle\lib\jtopen_8_3' was the folder where I put it under windows. Then restart your server(s), and create a DataSource. For 'Database Type' as well as for 'Driver' choose 'Other' in the wizard. Then for the following fields enter the corresponding values in the given format (see also the doc.):
FieldValue/FormatURLjdbc:as400://hostname/Schema-Name;translate binary=trueDriver Class
com.ibm.as400.access.AS400JDBCDriver
or
com.ibm.as400.access.AS400JDBCXADataSource
Driver Jar
jt400.jar
or
jt400Native.jar

Since in our case the database apparently has a time out (don't know it this is default behaviour with DB2-AS400), I put in a one-row-query in the Test Table Name-field. And I checked the Test Connections On Reserve-checkbox, because I don't know the time-out frequency.

A description of configuring the library and connection in JDeveloper and the DBAdapter can be found in section 9.6.2 of this doc.

Having the DataSource in Weblogic setup, you can register it in de Database Adapter. Besides provinding the DataSourceName or XADataSourceName you should adapt the PlatformClassName:

The default is 'org.eclipse.persistence.platform.database.oracle.Oracle10Platform' (It only now strikes me that it contains 'org.eclipse.persistence' in the package name). Leaving it like this could have you running in the exception:
ConnectionFactory property platformClassName was set to org.eclipse.persistence.platform.database.oracle.Oracle10Platform but the database you are connecting to is DB2 UDB for AS/400
For DB2 on AS/400, the value should be: 'oracle.tip.adapter.db.toplinkext.DB2AS400Platform', see the docs here.

Reminder to myself: turn off felix service urlhandlers in combined BPM & OSB12c installation

Mon, 2014-11-24 05:12
Last week I started with creating a few OSB services for my current project, which is in fact a BPM12c project that needs to be interated with database services on an AS400, thus DB2. Firstly I found that when I tried to deploy on a standalone wls domain (created with the qs_config script), it lacks an OSB installation. Whereas the integrated weblogic default domain has one.

But when I try to deploy to a pretty simple project I ran into the fault 'The WSDL is not semantically valid: Failed to read wsdl file from url due to -- java.net.MalformedURLException: Unknown protocol: servicebus.'

I even tried to do an import of a configuration.jar into the sbconsole, but same error here.

Frustration all over the place: how hard can it be, beïng quite an experienced osb developer on 11g?

Luckily I wasn't the only frustrated chap in the field: Lucas Jellema already ran into it and found a solution, where he credited Daniel Dias from Middleware by Link Consulting.

OSB12c: Errorhandling in REST

Fri, 2014-10-31 03:39
Yesterday, I had an OSB consulting day at a customer. We looked into a REST service that was to be extended with update functionality. Since calling an update service of an EIS (Enterprise Information System) can go wrong with all sorts of errors, it is important to be able to return a fault-message with the errors, jason format.

Now in OSB12c it's very apparent how you define possible fault-messages and even how the should be formatted in JSON:

In this sample case we created a more or less simple xsd for faults (dutch: fouten). To test with different fault messages we simply duplicated the 'fouten' element in the xsd to 'fouten2'. You can assign different HTTP-status codes to the different fault.

So this is configuration is pretty simple and straight forward. But it is not quite clear in the documents how you would return a specific fault within your error-handlers in the pipeline.

Internally OSB works not only 'XML'-based but actually SOAP-based. So the trick in the end is to replace the body with a soap-fault message and the selection of the REST/JSON errormessage is done based on the structure of the document in the details-section of the SOAP-Fault. In the screen above, you would define for each fault message an xsd-element and apparently it validates the soap-fault-details content against each XSD defined, and the xsd against which the detail-content is valid points to the returned fault, with the corresponding HTTP Status.

So we created a XQuery transformation as follows:
xquery version "1.0" encoding "utf-8";

(:: OracleAnnotationVersion "1.0" ::)

declare namespace ns2="http://darwin-it.nl/doe/mobile/fouten";
(:: import schema at "../PS/Schemas/fouten.xsd" ::)
declare namespace ns1="http://xmlns.oracle.com/adf/svc/errors/";
(:: import schema at "../BS/Schemas/XMLSchema_-130439696.xsd" ::)
declare namespace soap-env="http://schemas.xmlsoap.org/soap/envelope/";

declare variable $input as element() (:: schema-element(ns1:ServiceErrorMessage) ::) external;

declare function local:func($input as element() (:: schema-element(ns1:ServiceErrorMessage) ::)) as element() (:: schema-element(ns2:fouten) ::) {
<soap-env:Fault>
<faultcode>fault</faultcode>
<faultstring></faultstring>
<detail>
<ns2:fouten>
{
for $detail in $input/ns1:detail
return
<ns2:ErrorMessages>
<ns2:ErrorLevel>{fn:data($detail/ns1:severity)}</ns2:ErrorLevel>
<ns2:ErrorMessage>{fn:concat("ERROR: ", fn:data($detail/ns1:message))}</ns2:ErrorMessage></ns2:ErrorMessages>
}
</ns2:fouten>
</detail>
</soap-env:Fault>
};

local:func($input)
Of course the actual fault detail must follow the xsd for that particular fault. We tested but the faultcode or fault string does not have any affect in selection of the REST-fault or HTTP statuscode.
With the xquery above we got the 'fault' returned as defined in the REST definition, as shown in the screendump above.
 In our example, if we would changed the contents of this xquery and replace the tag <ns2:fouten> to <ns2:fouten2> then we got the other fault (fault2), with the corresponding HTTP-status.
A detail with contents that does not correspond to any of the defined fault-xsd's would result in HTTP-status 500: internal server error. So it is important to have a proper transformation where the returning fault-detail is valid to at least one of the fault-xsd's.

Another conclusion is that since the fault selection is apparently based on the detail-contents against the registered fault-xsd-elements, you apperently can't have different faults with the same xsd. Since JSON is 'namespace-less', you probably can solve this by defining several copies of the same xsd with a different namespace, one for each fault. The choosen namespace in the xquery would then be the selector for the fault. But since the underlying element names are the same, it would not differ in the resulting JSON-message. Of course in an XML result it would differ.

BPM & SOA Application missing in JDeveloper 12c gallery

Wed, 2014-10-29 13:48
A few weeks ago I did a BPM12c Quickstart Installation under Oracle Linux 6. Everything went smoothly, as described in the install guide as well as on many blogs already.
But I found that most of those blogs did an installation under Windows, where I did it under Oracle Linux in Virtualbox.

You would think (as I did) that it shouldn't matter. However, it turns out that in JDeveloper I was missing the 'BPM Application' amongst others in the JDeveloper New Gallery. Very inconvenient. I couldn't find any hints on the big internet. My friend Google wasn't very helpful in this.

But I wouldn't write this blog if I did not solve it. It turns out that with an update I got it solved.

It turns out that I lacked the 'Spring & Oracle Weblogic SCA' extension. Using the Help->Update functionality I downloaded and installed that and after restarting JDeveloper my 'New Gallery' was properly filled.

For those not so familiar with the JDeveloper update mechanism, here a step by step guide:
  1. Choose Help->Update:
  2.  Leave the Update Centers checked as default and click Next:
  3. Check 'Spring & Oracle Weblogic SCA' and click Next:
  4. Click Finish:
  5. Confirm when asked for restarting JDeveloper.
Update 2014-12-01, last week I also found this document on oracle support to do a clean of your jdeveloper.

    Demo User Community in BPM 12c Quickstart

    Tue, 2014-10-28 05:34
    When you want to do demo-ing or perform the BPM12c workshops on a BPM12c QuickStart developers installation you'll need the Oracle BPM Demo User community. You know: with Charles Dickens, John Steinbeck and friends.

    How to do so, you can find on the page following this link. You'll need the demo-community scripting that can be found following this link, and then download 'workflow-001-DemoCommunitySeedApp'.

    However, besides adapting the build.properties file, there are a few changes to make in the build.xml.


    First, find the property declaration for 'wls.home', and change it to:
    <property name="wls.home" value="${bea.home}/wlserver"/>
    This is needed, since they renamed the folder for the weblogic server in the FMW12c home. Then, after the comment of 'End Default values for params', add the following

    <!-- Import task def for antcontrib functions as if -->
    <property name="ant-contrib.jar" value="${bea.home}/oracle_common/modules/net.sf.antcontrib_1.1.0.0_1-0b3/lib/ant-contrib.jar"/>
    <taskdef resource="net/sf/antcontrib/antlib.xml">
    <classpath>
    <pathelement location="${ant-contrib.jar}"/>
    </classpath>
    </taskdef>
    This is because the script lacks a definition for the ant-contrib lib, needed amongst others for the 'if' activities. After this change, it worked for me.

    JMS Properties in BPM Suite

    Wed, 2014-09-24 01:58
    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

    Wed, 2014-09-24 01:01
    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 informationThe 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.