Wednesday, January 11, 2012

Event-driven Publish-Subscribe SOAP over http messaging in Oracle OSB



This blog discuss how to implement Publish-Subscribe (one producer, multi subscribers) channel in Oracle OSB. This system embodies Event-driven architecture: the consumers listen to event-messages, published to a topic, by the producer. This channel is reliable, i.e. it implements:
durable subscriber: to avoid missing messages when the consumer is not listening (e.g. disconnect for maintenance)
guarantee delivery: to make sure that all messages are delivered even when the consumer fail
idempotent receiver: dealing with duplicate messages (receive no duplicate messages)
We use SOAP with WSDL since it's a good practice to define your interfaces with WSDL. We use http since in our existing system we use a lot of RPI-style web services over http.

How
1. build a jms producer business service (BS): SOAP based on the jmssimple.wsdl (downloadable below)
transport tab: jms protocol and the queue address (please read my other blog about how to setup jms resources in Weblogic)
jms transport tab: topic type, message type: text... handy for test since it's readable,no response
2. build one or more jms consumer proxy: SOAP also based on the jmssimple.wsdl,
transport tab: jms protocol and the queue address (same as the address in the BS),
jms transport tab: topic type and message type: text, durable susbcription, XA enable
message handling tab: enable transaction & same transaction response. The transaction will rollback (i.e. put the message back to the queue) in case if a fail consumer, thus this enables guarantee delivery.
3. wrap the producer BS with a proxy: SOAP with a wsdl, http transport.
Add a routing options in the request routing in the proxy message flow, enable the Quality of Service in this option.
4. make a consumer BS point to other webservice (e.g. a FileWriter in my example.)


Test:
1. Send a http message (e.g. using SOAPUI) to the producer proxy, the FileWriter service will write a file containing the message from the consumer BS.
2. Disable the FileWriter service
3. Send a http message to the producer proxy again.
4. After awhile turn on the FileWriter service service again, this service will catch up with the messages he missed and write these in the files.

Logging
You can watch the jms message in the jms log files: /servers / /logs/ jmsServers/ . By default the jms logging is off, so you may need to turn on the jms logging (console: JMS resource > Configuration > Logging tab.)

Retrial
You can define also how many times OSB will retry to deliver the messages and define a retrial time out. You may define also an error-channel queue to contain your undelivered messages (after fail retrial attempts.)

Please download the example here (osb 11.1.3 config export).

Using Oracle OSB is an easy way to learn SOA (click here there and voila... your SOA solution is ready.) In the future I will discuss how to implement this using open source ActiveMQ & Spring framework.

Note about terminologies:
I tried to use consistent terminologies (e.g. producer, consumer) while discussing point-to-point queue and publish-subscribe topic in my blogs. In practice, while discussing publish-subscribe topic people use publisher instead of producer and
subscriber instead of consumer.




See also blogs compilation about messaging for integration: http://soa-java.blogspot.nl/2012/01/asynchronous-messaging-for-integration.html


Please share comment.

Source: Steve's blog http://soa-java.blogspot.com

References
http://eaipatterns.com/
Hohpe's Enterprise Integration Patterns... one of the most popular SOA books in the market


The Definitive Guide to SOA: Oracle Service Bus

Reliable SOAP over http in Oracle OSB: Point-to-Point Channel

This blog discuss how to implement Point-to-Point (one producer, one consumer) channel in Oracle OSB. This channel is reliable, i.e. it implements:
durable subscriber: to avoid missing messages when the consumer is not listening (e.g. disconnect for maintenance)
guarantee delivery: to make sure that all messages are delivered even when the consumer fail
idempotent receiver: dealing with duplicate messages (receive no duplicate messages)
We use SOAP with WSDL since it's a good practice to define your interfaces with WSDL. We use http since in our existing system we use a lot of RPI-style web services over http.



How:
1. build a jms producer business service (BS): SOAP based on the jmssimple.wsdl (downloadable below)
transport tab: jms protocol and the queue address (please read my other blog about how to setup jms resources in Weblogic)
jms transport tab: queue type, message type: text... handy for test since it's readable,no response
2. build a jms consumer proxy: SOAP also based on the jmssimple.wsdl,
transport tab: jms protocol and the queue address (same as the address in the BS),
jms transport tab: queue type and message type: text, durable susbcription, XA enable
message handling tab: enable transaction & same transaction response. The transaction will rollback (i.e. put the message back to the queue) in case if a fail consumer, thus this enables guarantee delivery.
3. wrap the producer BS with a proxy: SOAP with a wsdl, http transport.
Add a routing options in the request routing in the proxy message flow, enable the Quality of Service in this option.
4. make a consumer BS point to other webservice (e.g. a FileWriter in my example.)



Test:
1. Send a http message (e.g. using SOAPUI) to the producer proxy, the FileWriter service will write a file containing the message from the consumer BS.
2. Disable the FileWriter service
3. Send a http message to the producer proxy again.
4. After awhile turn on the FileWriter service service again, this service will catch up with the messages he missed and write these in the files.

Logging
You can watch the jms message in the jms log files: /servers / /logs/ jmsServers/ . By default the jms logging is off, so you may need to turn on the jms logging (console: JMS resource > Configuration > Logging tab.)

Retrial
You can define also how many times OSB will retry to deliver the messages and define a retrial time out. You may define also an error-channel queue to contain your undelivered messages (after fail retrial attempts.)

Please download the example here(osb 11.1.3 config export).

Using Oracle OSB is an easy way to learn SOA (click here there and voila... your SOA solution is ready.) In the future I will discuss how to implement this using open source ActiveMQ & Spring framework.




See also blogs compilation about messaging for integration: http://soa-java.blogspot.nl/2012/01/asynchronous-messaging-for-integration.html


Please share comment.

Source: Steve's blog http://soa-java.blogspot.com

References
http://eaipatterns.com/
Hohpe's Enterprise Integration Patterns... one of the most popular SOA books in the market


The Definitive Guide to SOA: Oracle Service Bus

Friday, January 6, 2012

Gotchas with XQuery: 4 cases


1. In Xquery (and also XSLT) once you defined a variable you can't change its value. This is due to the properties of declarative programming languages. A common workaround is by redefining the variable.

2. A boolean variable can't be compared with a string 'true' (or 'false')
e.g. if ($aboolvariable='true') will not work
solution: if ($aboolvariable= xs:boolean('true'))

3. If you use if you need to use else even if it's empty
e.g. if ($theanswer='true') then 'the answer is true' else ()

4.. Computed constructor element and the attribute string
Given <media type="book" title="Improve your intelligence for dummies"/>, suppose you want to construct an xml element using: element {$media/@type}{$media/@title}. Recall that the definition of the computed constructor element {name}{content}, so we expect to get: <book> Improve your intelligence for dummies </book > but instead we get: <book title="Improve your intelligence for dummies" />. To solve this problem use: element {$media/@type}{ string($media/@title)}.
Source: Steve's blogs http://soa-java.blogspot.com/

Any comments are welcome :)




References:
Common Xquery mistakes by James Fuller

Saturday, December 31, 2011

XQuery vs XSLT comparison: which to use?


The advantages of XSLT:
* XSLT is in xml format, thus XSLT files can be parsed, validated, dynamically created (e.g. using templates) using xml / soa tools.
* Pull/program-driven approach: XSLT works well to query high structured / predictable documents (e.g. a WSDL-defined SOAP message)
* The template is the strong point of XSLT, although it's possible to simulate this with a user-defined xquery function using tree transversal.
* With xsl:import you can override templates, thus improving reusability (analogous to inheritance & polymorphism in OO languages.)

The advantages of Xquery:
* Push/content-driven approach: Xquery is easier than XSLT to deal with loose structure / less predictable documents (e.g. html) where the stylesheets have to react dynamically to the content of the child elements.
* Xquery is less verbose and less cumbersome compared with XSLT, thus it's easier to learn.
* Xquery applies type strictness using the datatype definitions in the schemas.

Other factors to decide is the supports in the tools you used, e.g. Oracle Soa suite has better xslt editor, no xquery editor. On the other hand, the Oracle OSB has better xquery support than xslt. In general XSLT is better adopted in the SOA tools than Xquery, especially the old tools.

My experience: in my job I need to learn them both, when I started to use xml transformation in my job (about 2006) xquery was not exist, so xslt was the only option. Nowadays people in my office use xquery instead of xslt since they use oracle osb more, which has better xquery support, so I need to learn to adopt xquery more.

Source: Steve's blogs http://soa-java.blogspot.com/

Any comments are welcome :)




References:

XSLT: Axis and Predicate power!

This blog shows you about how to take advantage of axis and predicate in xpath expression: axis::test[predicate].
For example you have this XML:

<Projects>
<Project>
<ProjectName> Teach my toddler computer </ProjectName>

<ProjectActivities>
<ProjectActivity>
<ActivityName> Install Qimo Linux </ActivityName>
</ProjectActivity>
<ProjectActivity>
<ActivityName> Teach mouse game for mouse training </ActivityName >
</ProjectActivity>
</ProjectActivities>

<Elements>
<ProjectElement>
<ElementName>mouse skills</ElementName>
</ProjectElement>
<ProjectElement>
<ElementName>menu navigation</ElementName>
</ProjectElement>
</Elements>
</Project>

<Project>

<ProjectName> Make my wife happy</ProjectName>

<ProjectActivities>
<ProjectActivity>
<ActivityName> Buying flowers </ActivityName>
</ProjectActivity>
<ProjectActivity>
<ActivityName> Morning kiss </ActivityName >
</ProjectActivity>
</ProjectActivities>

<Elements>
<ProjectElement>
<ElementName>love</ElementName>
</ProjectElement>
</Elements>
</Project>

<Projects>

you want to transform this XML to this text:

Project: Teach my toddler computer
*Activities: Install Qimo Linux
**Elements: mouse skills, menu navigation
*Activities: Teach mouse game for mouse
**Elements: mouse skills, menu navigation
Project: Make my wife happy
*Activities: Buying flowers
**Elements: love
*Activities: Morning kiss
**Elements: love

using this xslt:


<xsl:for-each select="//Projects/Project">
<xsl:variable name="nuproj" select="ProjectName"/>
Project:<xsl:value-of select="ActivityName"/>,
<xsl:for-each select="ProjectActivities/ProjectActivity">
*Activities:<xsl:value-of select="ActivityName"/>,
<xsl:text></xsl:text>
<xsl:for-each select="following::Elements[parent::Project/ProjectName=$nuproj]/ProjectElement">
**Elements:<xsl:value-of select="ElementName"/> ,
</xsl:for-each>
<xsl:text></xsl:text>
</xsl:for-each>
<xsl:text></xsl:text>
</xsl:for-each>



In this xsl we iterate over ProjectActivity within each Project. So during this iteration the current context is in a ProjectActivity, while you want also to iterate over each Elements/ProjectElement. We solve this using xpath expression in the form of axis::test[predicate] :

following::Elements[parent::Project/ProjectName=$nuproj]/ProjectElement

so the "following" is the axis which tells that we select the Elements/ProjectElement located following the current context ProjectActivity. There many as other axis expression such as preceding, parents, descendants, etc which specifies the location relative to the current context.

[parent::Project/ProjectName=$nuproj] is the predicate, which specifies the condition of which Elements node to be selected (since there are more than one Elements nodes located following the current context ProjectActivity. In this case we specify that the Elements node to be selected should have a parent Project which has Project/ProjectName node with value equal to the variable $nuproj, i.e. the Elements node that belongs to the same Project with the current context ProjectActivity.

Source: Steve's blogs http://soa-java.blogspot.com/

Any comments are welcome :)




References:


Jesper Tverskov's axis tutorial
XSLT 2.0 and XPath 2.0 Programmer's Reference

Testing for Empty Elements in XSLT & Xquery


While processing an XML with XSLT sometimes you need to access a node but you want to make sure that that node exists otherwise the XSLT processor will complain (analogous to the infamous null point exception in Java).

For example using this XML:

<Projects>
<Project>
<ProjectName> Teach my toddler computer </ProjectName>
<ProjectActivities>
<ProjectActivity>
<ActivityName> Install Qimo Linux </ActivityName>
</ProjectActivity>
<ProjectActivity>
<ActivityName> Teach mouse game for mouse training </ActivityName >
</ProjectActivity>
</ProjectActivities>
</Project>

<Project>
<ProjectName> Teach my kids piano </ProjectName>
<ProjectActivities/>
</Project>

<Projects>

Suppose you want to iterate over ProjectActivity within project, but some project has no ProjectActivity (such as the "Teach my kids piano" project above).

XSLT solution
* To test if the element exists in XSLT you can use: xsl:if test="ProjectActivities/ProjectActivity".
*
To test if the element exists and non-empty: xsl:if test="string(ProjectActivities/ProjectActivity)".
*To test that the element exists and has text or any element content (e.g. subnodes or attributes): xsl:if test=" ProjectActivities/ProjectActivity/text() or ProjectActivities/ProjectActivity/*"

So for example using this test in this XSL:

<xsl:for-each select="//Projects/Project">
<xsl:variable name="nuproj" select="ProjectName"/>
Project:<xsl:value-of select="ActivityName"/>
<xsl:if test="ProjectActivities/ProjectActivity">
<xsl:for-each select="ProjectActivities/ProjectActivity">
To do:<xsl:value-of select="ActivityName"/>
<xsl:text></xsl:text>
</xsl:for-each>
</xsl:if>
<xsl:text></xsl:text>
</xsl:for-each>

you will expect this result:

Project: Teach my toddler computer
To do: Install Qimo Linux
Project: Teach my kids piano

Xquery solution:
* To test if the element exists :exists($ProjectVariable/ProjectActivities/ProjectActivity)
or using similar strategy used by xslt above:
if ($ProjectVariable/ProjectActivities/ProjectActivity) then ... else ...

*To test if the string non-empty:string-length($ProjectVariable/ProjectActivities/ProjectActivity) != 0)
or using similar strategy used by xslt above:
if (string($ProjectVariable/ProjectActivities/ProjectActivity)!="") then ... else ...

Source: Steve's blogs http://soa-java.blogspot.com/

Any comments are welcome :)




References:
XSLT Empty Element tutorial

Beginning XSLT and XPath: by Ian Williams

Tuesday, December 20, 2011

Maven, Artifactory and Hudson for Oracle OSB Continuous Integration

In the previous blog we discussed about using Ant and Hudson/Jenkins for continuous integration. What hasn't been explicitly discussed is about dependency management, that Maven can handsomely handle.

The benefits of using Maven instead of Ant:
1. standardization following best practices (e.g. directory structure) that leads to shorter/simpler configuration file (pom.xml), less maintenance, and higher reusability
2. transitive dependency management: Maven will find and solve the conflicts of the libraries needed. Perhaps you know this concept already if you've used ivy framework with Ant, but this concept is central in Maven so that lots of innovations has been implemented regarding this feature (e.g. enterprise repositories).
For example I just made adjustment and commited StudentRegistrationService-ver2.0 which depends on LDAPService-ver2.0 and hibernate-ver3.jar. When I deploy the StudentRegistrationService-ver2.0, Maven will include also the LDAPService-ver2.0 and hibernate-ver3.jar from a enterprise repository that stores all the libraries used in your company. If the build & test processes success, the artifact of my new StudentRegistrationService-ver2.0 will be included in the repository, so other services which consume my service will be able to use this version 2.0 of my service. Strong enough, you can specify the version dependencies using ranges (e.g. min version, max version), so I can specify that my service depends on LDAPService max version 2.0 (since I don't support the new interface of the newer LDAPService yet) and also depends on PaymentService min version 3.1.1 since there is a payment bug in the PaymentService version lower than 3.1.1. Here is an example of defining these dependencies in the pom.xml of the StudentRegistrationService:

<dependency>
<groupId>TUD</groupId>
<artifactId>LDAPService</artifactId>
<version>[0,2.0]</version>
</dependency>

<dependency>
<groupId>TUD</groupId>
<artifactId>PaymentService</artifactId>
<version>[3.1.1,)</version>
</dependency>

An illustration about how it works:


1. Using Hudson/Jenkins to let the svn commit trigger the Maven build
Please see the previous blog about how to install and setup Hudson/Jenkins.

For this example, I specify Hudson/Jenkins to pool the svn server every minute (set by the schedule "* * * * *" using cron format). When there is a new commit in the mysvnproject, the Maven "install" goal (along with its previous lifecycles phases i.e. compile, test) will be invoked.


2a. Checkout using mvn-scm plugin

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-scm-plugin</artifactId>
<version>1.1</version>
<configuration>
<username>username</username>
<password>password</password>
</configuration>
<execution>
<id>checkout</id>
<configuration>
<connectionUrl>mysvnserver</connectionUrl>
<checkoutDirectory>mysvndir</checkoutDirectory>
<excludes>folder2exclude/*</excludes>
</configuration>
<phase>compile</phase>
<goals>
<goal>checkout</goal>
</goals>
</execution>
</plugin>

2b. Build the OSB, you can use the same ant task as in my previous blog, wrapped with maven-antrun-plugin.

3a. Obtain the dependencies from the repositories, using dependency:copy-dependencies or dependency:copy.

3b. Deploy the OSB project and its dependencies, you can use the same ant task as in my previous blog, wrapped with maven-antrun-plugin.

4. Run SOAP UI web service test using maven-soapui-plugin (or alternatively you can use testrunner.bat / testrunner.sh similar to my other blog)

<plugin>
<groupId>eviware</groupId>
<artifactId>maven-soapui-plugin</artifactId>
<version>3.0</version>
<executions>
<execution>
<phase>test</phase>
<id>soapuitest</id>
<configuration>
<projectFile>${mysoapuitestfile}</projectFile>
<outputFolder>${testreportdir} </outputFolder>
<junitReport>true</junitReport>
<exportwAll>true</exportwAll>
<printReport>true</printReport>
<settingsFile>${soapuisettingfile}</settingsFile>
</configuration>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>

5. Archieving the artifact using an enterprise repository.
The benefit of using enterprise repository:
• your developers don't have to search, download and install the libs manually
• it's faster & more reliable than downloading the libs from internet, the concept is similar to proxy server that cache the internet.
• it will store the artifacts of your company projects from ant/maven builds, so they will be readily available for testing and shipping
• web administration interface, search, backup, import/exports

I chose Artifactory as enterprise repository since it has more features than other products, such as: xpath search inside XML/POM, hudson integration (e.g. for build promotion), conn to ldap, cloud (saas) possibility, easy install (running in an embedded jetty server or as service in Windows/Linux.)
You can use Hudson artifactory plugin to integrate Artifactory to Hudson/Jenkins process.

I use 3 local repositories inside your Artifactory for different library categories:
open source/ibibliolibraries (e.g. apache common jars), the Artifactory can download these automatically
proprietary libraries (e.g. oracle jdbc jar), you need to install these manually (e.g. via Artifactory web interface)
company libraries, you need to install these manually or via Hudson build as done in this example. For the company repository, I define such that the repository cab handle both the release/stable version (e.g. the PaymentService-ver3.1.1 which is already well tested and approved) as well as the snapshot version (e.g. I am not finished with my StudentRegistrationService-2.0 yet but I want to make it available for other projects which depend on it). For example in the artifactory.config.xml:

<localRepository>
<key>tud-repo</key>
<description>mycompany-libs</description>
<handleReleases>true</handleReleases>
<handleSnapshots>true</handleSnapshots>
</localRepository>

<localRepository>
<key>ibiblio-repo</key>
<description>stable-opensource-libs</description>
<handleReleases>true</handleReleases>
<handleSnapshots>false</handleSnapshots>
</localRepository>

You need to declare these repositories in your pom.xml (or with similar approach in settings.xml for all of your projects):

<repositories>
<repository>
<id>ibiblio-repo</id>
<url>http://myreposerver:port/artifactory/repo</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>tud-repo</id>
<url>http://myreposerver:port/artifactory/repo</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>ibiblio-repo</id>
<url>http://myreposerver:port/artifactory/repo</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>tud-repo</id>
<url>http://myreposerver:port/artifactory/repo</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories&gt

For the sake of clarity there are some details omitted from this blog. The concepts in this blog work also for non OSB projects (e.g. Java/J2EE applications).

Any comments are welcome :)



See also: http://soa-java.blogspot.nl/2011/03/soa-continuous-integration-test.html


References:
Setting Up a Maven Repository
Comparison Maven repository: Archiva, Artifactory, Nexus
Amis blog: Soapui test with maven