Thursday, 28 January 2010

Oracle Sun now definitely one team

Today I read the news that the European Commity approved the Sun acquisition without further demands. See webwereld.nl. Actually it is already a week ago. But today I read also the plans of a Web Open Office, or Open Web Office. Or Open Cloud Office. An alternative of Google's Docs. I'm very curious how that would look like and how it will compare to Google Docs. Open Office is a fairly mature Office Suite. So I'm looking forward to see which OpenOffice features will find their way in to the Oracle Cloud.

Further more the clouds are cleared upon MySql.

Another interesting statement I found was that Java SE should support more languages. Probably as an answer to the .Net world where you can develop in multiple languages. So lots of promisses that makes it interesting to "keep an eye in the sail" with Oracle (famous Dutch saying).

Monday, 18 January 2010

Application Server Connection in JDeveloper 10.1.3.x

This is actually a tip from the dusty old box, although I imagine that there are still people around with SoaSuite/Jdeveloper 10g. I got a VMware image with SoaSuite10133. And I couldn't connect to it with JDeveloper from outside the VM. And I should have the solution somewhere but I couldn't reproduce it. The solution lies in the opmn.xml found in $ORACLE_HOME/opmn/conf.

There you'll find a notification-server element. It propbably does not have the ipaddr node below it by default. But add it like below with 0.0.0.0 as ip-addresses. Doing so enables you to connect with a jdeveloper on a remote machine.
<notification-server inter>
<ipaddr remote="0.0.0.0" request="0.0.0.0"/>
<port local="6100" remote="6200" request="6003"/>
<ssl enabled="true" wallet-file="$ORACLE_HOME/opmn/conf/ssl.wlt/default"/>
</notification-server>

I wrote about connecting to an Oracle Application Server/SoaSuite within a VM in greater detail here, but I did not include the actual opmn.xml snippet like above.

Friday, 15 January 2010

It's back: the Business Event System

My first steps on integration were on Oracle AQ (from Oracle 8i onwards) and Oracle Workflow Standalone 2.6.x. One of my big dissapointments were that from Oracle 10g AS and DB, Oracle Workflow is desupported. You may use it as long as the 10g licenses last (either for database or AS). But then it is End of Life time. In 11g Oracle Workflow is not delivered anymore. And that is quite a pity, since it was quite a good Workflow tool, especially for datasbase centric applications. The nice thing is that it recides and runs completely in the database. Also it has a pretty good Eventing system. You can define events on a web-based UI. Then you can subscribe Oracle Workflow processes, Java-classes or pl/sql rule-functions on an event.

The good thing about business events is that you can make applications really independend from each other. If you have an application and you need that something happens if a certain mutation in your application is done, for example on creation of an order, the order should be interfaced to another application or logged, then you would create a function call in a database trigger, or from your ADF-BC entity-object. The side-affect is that if your called-functionality is invalid, not available or gives errors, then your calling-application would not work. Also if it is a long running process that is called, than it will all happen in the session of the end-user, who must wait until all processing is done.

And that all is wrong. The calling application should only notify an infrastructure component (like a business event system) and should not care about what is done with this notification. Doing so the end-user get's his sesson back immediately. The application won't disfunction because of corrupted subscribing applications. The application has done what it's responsible for.

The business event system then will handle all the subscriptions in the back-ground. And handle all errors, throw them to an error hospital for example.

But unfortunately the Oracle Workflow Business Event System is no more. Although it is still available in Oracle's E-Business Suite. But that is quite large to install for only BES. EBS is leaning heavily on BES, since most mutations on EBS entities have Events defined on which as an EBS-developer you can subscribe your custom-code. Even if there is no Event available for what you need to do, you shouldn't code it directly on a trigger, but let a database trigger raise your newly defined custom event. And subscribe your code on that event.

This week I delivered the OPN Bootcamp on SoaSuite11g. It was very nice and I'm looking forward to the next to come (9-11th february in Belgium). There's already written a lot on SoaSuite 11g, but little on the comeback of BES: the Event Delivery Network.
Although I like the SCA/Composite. Although I like the integration of all components. But if I must choose, I would pronounce the EDN as the most interesting and promissing addition.

In the OPN Bootcamp there is a small chapter with a little lab to smell just a little on EDN. See also the chapter in "Getting Started with SoaSuite11g". A larger explanation is found here. And here you can read about the managing of EDN.

Raising/publishing an event from a mediator is really easy. Just a few clicks. Also subscribing on a event is just a few clicks away. Also you can raise/publish events from ADF-BC or from Java. But what I miss is an explanation on how to raise an event from Pl/Sql. It is mentioned that it is possible. And in the managing-guide, you'll see how you can create database-agents. But I have to find out how to do it from Pl/Sql. I'll post it when I've found out the how-to.

I've great expectations on EDN. I hope and expect that Oracle will expand the useability further more with enabling other technologies to be able to publish and subscribe to events, the propagation of events to remote systems over WANs, etc. I think they'll do because they need a good Event System when for example BPEL and/or BPM is to replace Oracle Workflow in E-Business Suite.

But we as SOA/EDA consultants have to train Business Analists to think in events. EDN is targetted to the Business. So they have to embrace the concept of events.

Wednesday, 6 January 2010

Failed to compile the generated BPEL classes

Today I ran in a weird problem, one moment I could compile my bpel process, a minor change later I couldn't. I got the very descriptive error (not):
Error: Failed to compile classes. Failed to compile the generated BPEL classes for %process-name%.

After a little trial and error I ran a expression in a while loop:
condition="bpws:getVariableData('EKDSuccess')=&quot;false&quot; and bpws:getVariableData('EKDTryCount')<=bpws:getVariableData('EKDMaxRetries')" 


It turned out to be the quotes around the word "false". I changed them to single-quotes, like:

condition="bpws:getVariableData('EKDSuccess')='false' and bpws:getVariableData('EKDTryCount')<=bpws:getVariableData('EKDMaxRetries')"


And then it compiled. It was in 10.1.2 (old I know). So maybe in 10.1.3.x it is solved.

Tuesday, 5 January 2010

Passing parameters to an XSLT in BPEL

Yesterday for me it became handy to be able to pass parameters to an XSLT in BPEL. I've seen the need earlier, but solved it a different way. By setting the target element with a default and then over writing that default in a later assign-copy step.

But yesterday I had to transform a document a variable number of times, for a list of elements. In my case I had a document with a list of recipients and I had to transform that to another document for each recipient. Each recipient had a number of elements with personal and address information that had to be transformed to the target. So simply defaulting and overwriting would not work, or was a lot of work.

To pass parameters as arguments to a XSLT is quite easy and neatly described in several blogs, amongst others in Sudheer Dhurjati's Blog.

In my case I had to pass an index to be able to select the particular recipient that I need to transform. And another parameter that holds a number of documents that is determined from another source:
<?xml version="1.0" encoding="UTF-8" ?>
<parameters xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://schemas.oracle.com/service/bpel/common /S:/DEV/Sources/BPEL/Processes/CRMI_COM_VersturenBerichtContactMgt/1.0/src/xsltparameters.xsd"
xmlns="http://schemas.oracle.com/service/bpel/common">
<item>
<name>AantalBijlagen</name>
<value>2</value>
</item>
<item>
<name>OntvangerIndex</name>
<value>1</value>
</item>
</parameters>

In Sudheer's blog (and in other examples) the parameters are initialized by copying an XML fragment with the particular parameters. If you have to change one of the parameters this could be done by doing an indexed xpath-expression in the <to> of the assign step:
[/prm:parameters/prm:item[prm:name='OntvangerIndex']/prm:value]
with [http://schemas.oracle.com/service/bpel/common] as [prm]
<value xmlns="http://schemas.oracle.com/service/bpel/common">1</value>

But for flexibilities sake, I would propose a slightly different approach. And for that I need an adapted version of the XSD:
<?xml version="1.0" encoding="windows-1252" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:bplcmn="http://schemas.oracle.com/service/bpel/common"
xmlns="http://schemas.oracle.com/service/bpel/common"
targetNamespace="http://schemas.oracle.com/service/bpel/common"
elementFormDefault="qualified">
<xsd:element name="parameters">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="bplcmn:item" minOccurs="1" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="item" type="bplcmn:itemType"/>
<xsd:complexType name="itemType">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="value" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>

In this XSD I created 'item' as a seperate element based on a seperated (named) complex-type. I'm actually not so fond of nested complex-types, because it prevents you from using elements lower in the hierarchy for seperate variables.
Using this XSD, you can create a seperate item-variable, based on the item-element.
This is item-variable can be filled with a name and value, just by copying to the particular elements.
The item variable has then to be added to the parameters node using the addChildNode function:
ora:addChildNode(bpws:getVariableData('XsltParams','/bplcmn:parameters'),bpws:getVariableData('item','/bplcmn:item'))
The first argument of the addChildNode function denotes the element under which you want to add a child. In the expression above this is the 'parameters' element in the XsltParams variable. The second argument is the node you want to add as a child, in this case the 'item'-variable. Of course this expression is the <from>-expression in the copy-rule of the assignment step. The <to> will be most of the times the parent element used in the addChildNode expression:
<to variable="XsltParams" query="/bplcmn:parameters"/>
I found the description of the addChildNode function in the expression builder not so clear. So this might also be helpfull for other situations where you have to build up a node structure dynamically.