Featured Posts

Uncategorized

Oracle Service Bus 11g Development Cookbook is added to the OSB OTN Learn More page

Our book “Oracle Service Bus 11g Development Cookbook” has been added by Oracle to the “Learn More About Oracle Service Bus” section on OTN.
You can find it over here together with other usefull resources.

books

OTN Article : Three Recipes for Oracle Service Bus 11g got published

“Whip up a fresh batch of service- and message-oriented solutions with these recipes from the Oracle Service Bus 11g Development Cookbook”

Today two new items related to the Oracle Service Bus 11g Development Cookbook got published

OTN Article : Three Recipes for Oracle Service Bus 11g

Podcast Show Notes: Author Interview: Oracle Service Bus 11g Cookbook

Uncategorized

Oracle Fusion Middleware Partner Community Forum Malage, the overview

On the 7th and 8th of februari i attended the Oracle Fusion Middleware Partner Community Forum in Malaga.
A 4 day during event with other Oracle colleagues from other companies and from Oracle itself.

After taking a early flight from Schiphol Amsterdam, we arrived on time in Malaga. Great weather, compared to the -12 degrees in The Netherlands.

The agenda for the 4 days
The first day started with the next list of session :

  • Keynote Oracle Middleware Sales Strategy, Opportunities and Go-to-Market
  • Keynote Oracle Fusion Middleware Strategy & Direction
  • Partner SOA & BPM & Webcenter Reference Case
  • Keynote Automatic and Dynamic Publishing using Semantics and Webcenter Content
  • WebLogic 12c & Enterprise Manager 12c & ExaLogic for Fusion Middleware
  • ADF overview and roadmap

The day ended with the so called ‘Socal Network Event’. As usual Jurgen planned a great evening again for all of us.
Starting in El Pimpi restaurant with some drinks, delicious snacks and live music!

.. and to end up in Aleas Restaurant for a great dinner. Ideal moment to find out more about the new ps5/12c features and to finally get in contact with some friends of twitter.

The second day would be the more interested day with presentation about the new upcoming releases. Ideal to get in touch with the right persons and try to find out what’s coming up for us.
The interesting ones for me :

  • WebLogic what’s new in 12c
  • SOA Suite 11g overview, latest new features and directions
  • iAs to Wls
  • WebLogic automation & first WebLogic impressions

For the overall agenda see here.

The last 2 days we could follow the next hands-on trainings :

  • ADF & WebCenter MasterClass by Red Samurai, VASS, InfoMentum and Oracle
  • WebLogic 12c: Maciej Gruszka
  • SOA: Simone Geib & James

A list of upcoming features in one of the next minor upcoming releases (no guarantees, no dates!). Besides that some notes i made myself

SOA

  • Oracle Service Bus will make use of the ECID, so we will be able to trace down to OSB in the audit trial of the instances in the EM
  • Unified exception handling framework (“Error hospital”) (search/delete/recover failed instances)
  • Alerts for stuck messages (eventually these alerts will have the same destinations like the alerts from OSB), extra search options in the EM for these type of instances (stuck messages, ECID, etc)
  • Testing individuals bpel processes from the composite. Support for assertions, fast forward for wait activities
  • New transactions properties (required/requiresNew) for sync and oneway bpel processes (initiating calls). Able to set those on creation of the process instead of in the xml after creating.
  • New delivery proprties (async.persists/async.cache/sync) for async and oneway processes. (async.persist = save message in delivery store before picked up by engine, async.cache = in memory and sync = no save al all)
  • New property inspector for composite properties, instead of xml editing
  • Support for bpel 2.0 Dynamic Partnerlinks
  • Skip Condition on activities for bpel 2.0
  • Throw faults on failed assertions
  • Set timeouts on request/reply and in-only operations
  • Copy/paste functionality, for copying parts of your process in design time
  • Reduced memory footprint (let’s hope this time it will run fine on my mega dell laptop)
  • Enhanced purging strategies (
  • Out of the box integration with WebLogic Diagnostic Framework (WLDF) and Diagnostics Framework(DFW)
  • Coherence integration with DB adapter (cache usage = read/read-write)
  • Template support for composites
  • Besides XSLT also support for XQuery (like in OSB)
  • Out of the box scheduler (ESS) for scheduling webservices, adapters, ejb, plsql, etc

OSB

  • Improved RESTful webservices
  • Assign Transport Policies via OWSM
  • Apply policy to local proxies
  • Optimization importing jars containing an big amount of artificats
  • New console with OSB Designer and OSB Dashboard
  • OSB service will get same kind of composite overview in JDeveloper (Exposed services/Components/External Services)

JDeveloper

  • OSB, CEP, Composites, etc in 1 IDE
  • Better support for debug and tracing in JDEV
  • AIA support in OSB

Weblogic

  • Java EE 6 and Developer Productivity
  • Integrated Traffic Management
  • Better performance
  • Oracle Virtual Assembly Builder (OVAB) support
  • Better Maven integration
  • Latest Spring framework support
  • -Dservertype=wlx, launch instance without ejb, jms and jca containers
  • FastSwap
  • Option for storing transactions logs in de DB instead of filestore
  • Enhanced Disaster Recovery and High Availability
  • Deploy Glassfish application on Weblogic (detection of Glassfish descriptor)

Overall a great event again.
Thanks go out to Jürgen Kress and Hans Blaas for organizing it!

books, osb

Oracle Service Bus 11g Development Cookbook has been published!

Good news today from the publisher!
The book of which i’m coauthor of has been published! After months of hard work it’s finally there.

Oracle Service Bus 11g Development Cookbook : http://www.packtpub.com/oracle-service-bus-11g-development-cookbook/book

I hope you will all like it.

Thanks to the other authors (Guido, Edwin, Jan and Mischa) for all their hard work and for the great few months of working together to establish this great piece of work.
Special thanks go out to Guido for guiding the whole process of making this book. All the hours of hard work and organizing everything, i hope it was worth it!

The book

Something about the book (which i nicely copy/pasted from Guido his blog)

The book contains more than 80 practical recipes to develop service- and message-oriented solutions on the Oracle Service Bus 11g.

This cookbook is full of immediately usable recipes showing how to efficiently develop on the Oracle Service Bus. In addition to its cookbook style, which ensures the solutions are presented in a clear step-by-step manner, the explanations go into great detail, which makes it good learning material for everyone who has experience with the OSB and wants to improve. Most of the recipes are designed in such a way that each recipe is presented as a separate, standalone entity and reading of prior recipes is not required. The finished solution of each recipe is also made available electronically.

The 80+ recipes are organized into the following chapters (the digit behind the title showing the number of recipes in that chapter):

  • Creating a basic OSB service (13)
  • Working efficiently with OSB artifacts in Eclipse OEPE (7)
  • Messaging with JMS transport (9)
  • Using EJB and JEJB transport (5)
  • Using HTTP transport (5)
  • Using File and Mail transports (5)
  • Using JCA adapter to communicate to the database (6)
  • Using SOA Direct transport to communicate with SOA Suite (4)
  • Communication, Flow Control and Message Processing (10)
  • Reliable communication with OSB (5)
  • Handling Message-Level Security requirements (9)
  • Handling Transport-Level Security requirements (4)

Happy reading!

Reviews

AMIS blog : Review of Oracle Service Bus 11g Development Cookbook (Packt Publishing) by Edwin Biemond, Guido Schmutz, Eric Elzinga et. al.
SOA@Oracle SCA, BPEL, BPM & Service Bus blog

osb

Oracle Service Bus : Using custom xpath functions in xslt

One of the readers of my blog post ‘Oracle Service Bus 11g, Using Custom Xpath Functions asked we can reuse the custom xpath functions in a xsl transformation.

It’s possibel to reuse the jar and calll the custom functions from within a xsl transformation.

Starting with creating the resources needed for the custom xpath function :

  1. XML Configuration file (osb-custom.xml)
  2. Property file (optional, osb-custom.properties)
  3. Custom Function Class (jar package)

Restart the osb service so the new jar will get loaded.

– Create a new osb project
– Create a new xslt

	<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:cust="xalan://nl.xenta.osb.custom.functions.OsbUtils">
		<xsl:variable name="param1" select="string('the beginning')"/>
		<xsl:variable name="param2" select="string('the end')"/>
		<xsl:template match="/">
			<xsl:variable name="my_custom_concat" select="cust:customConcat($param1,$param2)" />
			<the_result><xsl:value-of select="$my_custom_concat"/></the_result>
		</xsl:template>
	</xsl:stylesheet>

To be able to call a custom xpath function with the Xalan engine we need to add a new namespace_prefix + definition the the xsl

xmlns:cust="xalan://tests.pipeline.CustomXQFunctions"

– Start with xalan://
– Then the java package + classname, nl.xenta.osb.custom.functions.OsbUtils
– In the select of the value-of we eventually use the namespace-prefix + java method interface to call the java method, cust:customConcat($param1,$param2)

Create a new proxy service and use the xsl in for example an assing activity.
Deploy the service and use the testconsole to test it.

soasuite

Oracle SOA Suite : import in xsl from mds location

In one of my xsl transformations i needed to import a generic xsl from the mds store.
For this i created a new jdeveloper application with a soa sar deployment descriptor and jar descriptor in it.

Contents of the jar :

	SharedMDSResources/generic.xsl

When i browse the mds repository i see the SharedMDSResources folder in the root of the tree (instead of in the apps folder).

For testing i deployed the jar manually in the EM.


In my xsl i use the next import :

  <xsl:import href="oramds:/SharedMDSResources/generic.xsl"/>

Resulting in the next stacktrace :

The following exception occurred while attempting to execute operation copy at line 389
<exception class="com.collaxa.cube.xml.xpath.XPathException">
<parsererror style="display: block; white-space: pre; border: 2px solid #c77; padding: 0 1em 0 1em; margin: 1em; background-color: #fdd; color: black">
<h3>This page contains the following errors:</h3>
<div style="font-family:monospace;font-size:12px">
error on line 7 at column 1: Extra content at the end of the document
</div>
<h3>Below is a rendering of the page up to the first error.</h3>
</parsererror>
XPath expression failed to execute.
An error occurs while processing the XPath expression; the expression is ora:doXSLTransformForDoc('xsl/format_dates.xsl', $csvXml).
The XPath expression failed to execute; the reason was: XML-22000: (Fatal Error) Error while parsing XSL file (oramds:/deployed-composites/default/mycomposite_rev1.0/xsl/my_process.xsl<Line 3, Column 46>: XML-22002: (Fatal Error) Error while processing include XSL file (oramds:/SharedMDSResources/generic.xsl).)..
Check the detailed root cause described in the exception message text and verify that the XPath query is correct.
<stack>
<f>com.collaxa.cube.xml.xpath.BPELXPathUtil.evaluate#262</f>
<f>com.collaxa.cube.engine.ext.bpel.common.BPELWMPHelper.evalFromValue#339</f>
<f>com.collaxa.cube.engine.ext.bpel.v1.wmp.BPEL1AssignWMP.__executeStatements#137</f>
<f>com.collaxa.cube.engine.ext.bpel.common.wmp.BaseBPELActivityWMP.perform#158</f>
<f>com.collaxa.cube.engine.CubeEngine._performActivity#2463</f>
<f>com.collaxa.cube.engine.CubeEngine.performActivity#2334</f>
<f>com.collaxa.cube.engine.CubeEngine.handleWorkItem#1115</f>
<f>com.collaxa.cube.engine.dispatch.message.instance.PerformMessageHandler.handleLocal#73</f>
<f>com.collaxa.cube.engine.dispatch.DispatchHelper.handleLocalMessage#220</f>
<f>com.collaxa.cube.engine.dispatch.DispatchHelper.sendMemory#328</f>
<f>com.collaxa.cube.engine.CubeEngine.endRequest#4350</f>
<f>com.collaxa.cube.engine.CubeEngine.endRequest#4281</f>
<f>com.collaxa.cube.engine.CubeEngine.createAndInvoke#679</f>
<f>com.collaxa.cube.engine.delivery.DeliveryService.handleInvoke#654</f>
<f>com.collaxa.cube.engine.ejb.impl.CubeDeliveryBean.handleInvoke#293</f>
<f>sun.reflect.GeneratedMethodAccessor944.invoke</f>
<f>...</f>
</stack>
</exception>

Problem

Since i deployed the jar manually from within the EM the SharedMDSResources folder will not be created in the apps-dir but in the root of the tree.
The oramds imports can only import from within the apps folder structure.

Solution

When manually creating the jar archive make sure the contributor has the apps-directory already in the path

Path : d:\SharedMDS\apps\SharedMDSResources\

After the import the mds repository will contain the path ‘oramds:/apps/SharedMDSResources/generic.xsl’

Or keep the jar as it was (folder/file structure = SharedMDSResources/generic.xsl) and use the scripts from for example Edwin and setup the ‘mds.reposistory’ correctly (ending with the apps-directory in it).

example topfragment of a xslt we currently use (this is not the xslt mentioned in the blog, but just a working example with oramds import)

<xsl:stylesheet version="1.0"
                xmlns:xp20="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.Xpath20"
                xmlns:oraext="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.ExtFunc"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:dvm="http://www.oracle.com/XSL/Transform/java/oracle.tip.dvm.LookupValue"
                exclude-result-prefixes="xsl hr xp20 oraext dvm">
    <xsl:import href="oramds:/apps/sharedResources/generic.xsl"/>
    <xsl:output method="xml" indent="yes"/>
    <!-- -->
    <xsl:param name="param1"/>
    <xsl:param name="param2"/>
    <!-- -->

oracle

Invitation to Fusion Middleware Partner Community Forum

INVITATION TO


FUSION MIDDLEWARE PARTNER COMMUNITY FORUM 
SOA & WebCenter & BPM & WebLogic Partner Communities

Do you want to learn about how to sell the value of Fusion Middleware by combining SOA, BPM and WebCenter Solutions?

We would like to invite you to become updated and trained at our Fusion Middleware Partner Community Forum on February 7th and 8th 2011 at the NH Hotel in Malaga, Spain.



The event is a wonderful opportunity to:
  • learn how to sell the value of Fusion Middleware by combining SOA and WebCenter solutions
  • meet with Oracle SOA, BPM and WebCenter Product management
  • exchange knowledge and have access to competitive intelligence
  • learn from successful SOA, BPM, WebCenter and ADF implementations
  • learn about WebCenter Sites
  • network within the Oracle SOA Partner Community and the Oracle WebCenter Partner Community
During this highly informative event you can learn about partner success stories, participate in an array of break out sessions and exchange information with other partners.

osb

Oracle Service Bus, Request Entity Too Large

In the osb we use business services (http transport + wsdl) to call our composites on the soa suite.
In a few situations the routing in the osb fail with the next error

<con:fault xmlns:con="http://www.bea.com/wli/sb/context">
	<con:errorCode>BEA-380000</con:errorCode>
	<con:reason>Request Entity Too Large</con:reason>
	<con:location>
		<con:node>RouteNodeLeesDeclaratieCompleet</con:node>
		<con:path>response-pipeline</con:path>
	</con:location>
</con:fault>

Looking in the list of instances in the soa suite we see the instances over there just complete in a valid way but still the routing in the osb fails.

Solution

  • Go to the configuration of the business service
  • Go to the HTTP Transport tab
  • Disable “Use Chunked Streaming Mode”

See also this blog for some extra explanation

osb

Oracle Service Bus, Generic fault handling

For a usecase i needed a construction which would give me the option to implemenent generic service error handling in which i could conditionally execute activities like alerts, reports, logging, etc
One place which will contain all the error handling logic and which could be easily extended both in implementation of the logic for handling errors and being able to easily add new errors to be handle which the metadata for this error.

In case third party applications decide to trigger new type of exceptions/faults i don’t want to change the fault handling logic of all the process which do a call to this service. I want to be able to add the to be executed logic for this new specific error to some sort of error repository together with some setup-settings.

Definition of the error repository
In our case the error repository is nothing more then a xml metadata storage which stores settings for the errors to be handled.
The definition of the metadata can be extended with other settings which can be retrieved at one central place again and logic for handling the settings will also be centrally defined.

Definition of the error handling service
In our case the error handling service will be the central point in which we retrieve instance data from the process in which the occured fault.
Based on this data we will retrieve metadata for the fault and decide in the message flow handling what the logic will be to execute.

Error Repository

Schema definition

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="http://nl.xenta/services/errorRepository" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://nl.xenta/services/errorRepository">
	<xs:element name="service_error_handling">
		<xs:complexType>
			<xs:sequence>
				<xs:element ref="error" maxOccurs="unbounded"/>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
	<xs:element name="indReporting">
		<xs:simpleType>
			<xs:restriction base="xs:string">
				<xs:enumeration value="Y"/>
				<xs:enumeration value="N"/>
			</xs:restriction>
		</xs:simpleType>
	</xs:element>
	<xs:element name="description">
		<xs:simpleType>
			<xs:restriction base="xs:string"/>
		</xs:simpleType>
	</xs:element>
	<xs:element name="sourceSystem">
		<xs:simpleType>
			<xs:restriction base="xs:string">
				<xs:enumeration value="SYSTEM-X"/>
				<xs:enumeration value="OSB"/>
				<xs:enumeration value="NA"/>				
			</xs:restriction>
		</xs:simpleType>
	</xs:element>
	<xs:element name="indLogging">
		<xs:simpleType>
			<xs:restriction base="xs:string">
				<xs:enumeration value="Y"/>
				<xs:enumeration value="N"/>
			</xs:restriction>
		</xs:simpleType>
	</xs:element>
	<xs:element name="faultTransformer">
		<xs:simpleType>
			<xs:restriction base="xs:string"/>
		</xs:simpleType>
	</xs:element>
	<xs:element name="externalCode">
		<xs:simpleType>
			<xs:restriction base="xs:string">
				<xs:enumeration value="XXX_DEFAULT_ERROR"/>
				<xs:enumeration value="GENERIC-1234"/>
				<xs:enumeration value="VALIDATE-9999"/>
			</xs:restriction>
		</xs:simpleType>
	</xs:element>
	<xs:element name="error">
		<xs:complexType>
			<xs:sequence>
				<xs:element ref="code"/>
				<xs:element ref="externalCode"/>
				<xs:element ref="description"/>
				<xs:element ref="sourceSystem"/>
				<xs:element ref="faultTransformer"/>
				<xs:element ref="indAlert"/>
				<xs:element ref="indAlertOverwriteDestionation"/>
				<xs:element ref="alertDestination"/>
				<xs:element ref="indLogging"/>
				<xs:element ref="indReporting"/>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
	<xs:element name="code">
		<xs:simpleType>
			<xs:restriction base="xs:string">
				<xs:enumeration value="BEA-382505"/>
				<xs:enumeration value="DEFAULT"/>
				<xs:enumeration value="BEA-380000"/>
			</xs:restriction>
		</xs:simpleType>
	</xs:element>
	<xs:element name="indAlertOverwriteDestionation">
		<xs:simpleType>
			<xs:restriction base="xs:string">
				<xs:enumeration value="Y"/>
				<xs:enumeration value="N"/>
			</xs:restriction>
		</xs:simpleType>
	</xs:element>
	<xs:element name="indAlert">
		<xs:simpleType>
			<xs:restriction base="xs:string">
				<xs:enumeration value="Y"/>
				<xs:enumeration value="N"/>
			</xs:restriction>
		</xs:simpleType>
	</xs:element>
	<xs:element name="alertDestination">
		<xs:complexType/>
	</xs:element>
</xs:schema>

Modeling the error handling proxy service

The error handling proxy service will be the central point of executing location based on the incoming occured fault.

  • Create a new proxy service called ErrorHandler of Service Type ‘Any XML Service’

    The input we will send to this service will be in the format of

    <errorData>
    	<body>{$body}</body>
    	<inbound>{$inbound}</inbound>
    	<fault>{$fault}</fault>
    </errorData>
    

    The flow will eventually look something like this

    Let’s look at the individual steps

    1. retrieveErrorMetadata

    The first step will contain 2 assigns.

    The first assign will assign the ErrorRepository.xq to variable errorList

    The content of the ErrorRepository.xq is the next

    xquery version "1.0" encoding "Cp1252";
    (:: pragma  type="xs:anyType" ::)
    
    declare namespace xf = "http://nl.xenta/services/errorRepository";
    
    declare function xf:service_error_handling()
        as element(*) {
    		<service_error_handling xmlns="http://nl.xenta/services/errorRepository" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    			<error>
    				<code>BEA-382505</code>
    				<externalCode>VALIDATE-9999</externalCode>
    				<description>Validation of the XML payload failed</description>
    				<sourceSystem>OSB</sourceSystem>
    				<faultTransformer>ErrorHandling/errorRepository/GenericFault_To_SOAPFault</faultTransformer>
    				<indAlert>Y</indAlert>
    				<indAlertOverwriteDestionation>N</indAlertOverwriteDestionation>
    				<alertDestination/>
    				<indLogging>Y</indLogging>
    				<indReporting>Y</indReporting>
    			</error>
    			<error>
    				<code>BEA-380000</code>
    				<externalCode>GENERIC-1234</externalCode>
    				<description>General transport error occured</description>
    				<sourceSystem>SYSTEM-X</sourceSystem>
    				<faultTransformer>ErrorHandling/errorRepository/GenericFault_To_SOAPFault2</faultTransformer>
    				<indAlert>Y</indAlert>
    				<indAlertOverwriteDestionation>N</indAlertOverwriteDestionation>
    				<alertDestination/>
    				<indLogging>Y</indLogging>
    				<indReporting>Y</indReporting>
    			</error>
    			<error>
    				<code>DEFAULT</code>
    				<externalCode>XXX_DEFAULT_ERROR</externalCode>
    				<description>Something went wrong!</description>
    				<sourceSystem>NA</sourceSystem>
    				<faultTransformer>ErrorHandling/errorRepository/GenericFault_To_SOAPFault</faultTransformer>
    				<indAlert>Y</indAlert>
    				<indAlertOverwriteDestionation>N</indAlertOverwriteDestionation>
    				<alertDestination/>
    				<indLogging>Y</indLogging>
    				<indReporting>Y</indReporting>
    			</error>
    		</service_error_handling>
    };
    
    xf:service_error_handling()
    
    

    At this point we have the list of faults together with metadata about what to execute when they occure available in the Message Flow.

    In the second assign we retrieve only the the metadata from our occured fault, so we just retrieve 1 error-element from the list.

    For this we execute the lookupError xquery which receives the errorList content and the errorCode and will return the error-element.
    If we can’t retrieve any metadata based on the errorCode we will return a default set of metadata (the error-element of which the code = DEFAULT).
    The result we will assign to the errorMetadataDetails variable.

    Content of lookupError xquery

    (:: pragma bea:global-element-parameter parameter="$errorList" element="err:service_error_handling" location="ErrorRepository.xsd" ::)
    (:: pragma bea:global-element-return element="ns0:error" location="ErrorRepository.xsd" ::)
    
    declare namespace err = "http://nl.xenta/services/errorRepository";
    declare namespace xf = "http://nl.xenta/services/faults/lookupError/";
    
    declare function xf:lookupError2($errorCode as xs:string,
        $errorList as element(err:service_error_handling))
        as element(err:error) {
        
    		if(string-length($errorList/err:error[err:code=$errorCode]) > 0)
       		then (
    			let $resolvedError := $errorList/err:error[err:code=$errorCode]
    	   		return $resolvedError
       		) else (
       			let $resolvedError := $errorList/err:error[err:code='DEFAULT']
       			return $resolvedError
       		)    
    };
    
    declare variable $errorCode as xs:string external;
    declare variable $errorList as element(err:service_error_handling) external;
    
    xf:lookupError2($errorCode,$errorList)
    

    2. conditionalReporting

    In all the conditional stages we will now re-use the errorMetadataDetails variable to verify if we want to execute certain login.

    If we configurated the indReporting=Y in the error repository xquery file then the if-then loginc will evaluate to the if-tree and the Report-activty will be executed.
    In the same way all the other condition stages (conditionalAlert, conditionalSomethingElse) will work. We re-use the errorMetadataDetails-variable and just do a simple if-then check to see if certain logic needs to be executed.

    3. constructResponse

    The last step of the message flow is the step in which we construct the response of the errorHandler process back to the client process.
    In this step we will be using Dynamic Xquery to be able the construct response messages based on the incoming fault.
    The example of our ErrorReposity defines 2 faults and 1 default.
    In case for example error BEA-380000 occures, we will use the xquery located at ErrorHandling/errorRepository/GenericFault_To_SOAPFault2 to be executed. This xquery will construct our soap fault.

    To be able to use Dynamic Xquery all the to be used xquery transformations need to have the same interface. Depending on the backend system and the returning faults from it we will use different tranformation files.
    But all of them will be using the input paramters ‘body, inbound and fault’. In the expression field we will use the faultTransformer-element from the errorMetadataDetails. So for every fault for which we want to create a
    different fault response we do need to define a faultTransformer-value in the errorRepository.

    And that’s all what is needed to implement in the errorHandler process to receive the metadata, handle the fault and construct the response.

    Testcase

    For this testcase we created a simple EmployeeService. Create a new proxy service based on the next wsdl/xsd content.

    <?xml version="1.0" encoding="UTF-8"?>
    <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://new.webservice.namespace" xmlns:ns="http://nl.xenta/services/employee" targetNamespace="http://new.webservice.namespace">
    	<wsdl:import namespace="http://nl.xenta/services/employee" location="EmployeeService.xsd"/>
    	<wsdl:message name="NewMessageRequest">
    		<wsdl:part name="parameter" element="ns:employee_request"/>
    	</wsdl:message>
    	<wsdl:message name="NewMessageResponse">
    		<wsdl:part name="parameter" element="ns:employee_response"/>
    	</wsdl:message>
    	<wsdl:portType name="EmployeeServicePort">
    		<wsdl:operation name="getEmployee">
    			<wsdl:input message="tns:NewMessageRequest"/>
    			<wsdl:output message="tns:NewMessageResponse"/>
    		</wsdl:operation>
    	</wsdl:portType>
    	<wsdl:binding name="EmployeeServiceBinding" type="tns:EmployeeServicePort">
    		<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    		<wsdl:operation name="getEmployee">
    			<soap:operation soapAction="urn:#NewOperation"/>
    			<wsdl:input>
    				<soap:body use="literal"/>
    			</wsdl:input>
    			<wsdl:output>
    				<soap:body use="literal"/>
    			</wsdl:output>
    		</wsdl:operation>
    	</wsdl:binding>
    	<wsdl:service name="EmployeeService">
    		<wsdl:port name="EmployeeServiceSOAPPort" binding="tns:EmployeeServiceBinding">
    			<soap:address location="No Target Adress"/>
    		</wsdl:port>
    	</wsdl:service>
    </wsdl:definitions>
    
    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://nl.xenta/services/employee" attributeFormDefault="unqualified">
    	<xs:element name="employee_request">
    		<xs:annotation>
    			<xs:documentation>Comment describing your root element</xs:documentation>
    		</xs:annotation>
    		<xs:complexType>
    			<xs:sequence>
    				<xs:element name="emp_id" type="xs:int"/>
    			</xs:sequence>
    		</xs:complexType>
    	</xs:element>
    	<xs:element name="employee_response">
    		<xs:complexType>
    			<xs:sequence>
    				<xs:element name="employee">
    					<xs:complexType>
    						<xs:sequence>
    							<xs:element name="firstname"/>
    							<xs:element name="lastname"/>
    							<xs:element name="birthdate" type="xs:date"/>
    						</xs:sequence>
    					</xs:complexType>
    				</xs:element>
    			</xs:sequence>
    		</xs:complexType>
    	</xs:element>
    </xs:schema>
    

    And the message flow will eventually look like this

    The first assign will assign the body to body_temp so in case of an error situation we still have the original body content stored

    The second activity is the validation activity. This one we will be using lateron to trigger a fault which will be processed by the errorHandler process.
    Based on the same wsdl as the proxy service i defined a new business service. In the EmployeeService proxy we will be routing to this business service.
    Since we won’t be implementing any logic on this side we just update the endpoint of the business service to something useless so the route will fail on this one.

    This part is used to the second fault triggering moment in our process. Also this situation will fail and the occured fault will get processed by the errorHandler.

    The ‘normal’ message flow of our proxy service is now done.
    Let’s have a look at the service error handler.

    The first assign will use the next xquery and assign the result to errorhandler_request

    xquery version "1.0" encoding "Cp1252";
    (:: pragma  parameter="$body" type="xs:anyType" ::)
    (:: pragma  parameter="$fault" type="xs:anyType" ::)
    (:: pragma  parameter="$inbound" type="xs:anyType" ::)
    (:: pragma  type="xs:anyType" ::)
    
    declare namespace xf = "http://tempuri.org/ErrorHandling/proxy/constructErrorHandlingInput/";
    
    declare function xf:constructErrorHandlingInput($body as element(*),
        $fault as element(*),
        $inbound as element(*))
        as element(*) {
            <errorData>
    			<body>{$body}</body>
    			<inbound>{$inbound}</inbound>
    			<fault>{$fault}</fault>
    		</errorData>
    };
    
    declare variable $body as element(*) external;
    declare variable $fault as element(*) external;
    declare variable $inbound as element(*) external;
    
    xf:constructErrorHandlingInput($body, $fault, $inbound)
    

    In the binding we will use the body_temp variable so we have the original body content of the process.

    The next activity is the service callout to the errorHandler process

    The third activity is an assign which will assign the constructed body from the errorHandler process to the body variable

    And the last activity will be a ‘Reply with Failure’

    Testrun

    In the ErrorRepository we defined 2 faults, BEA-382505 and BEA-380000.
    For both faults we defined a different faultTransformer.

    BEA-382505 = ErrorHandling/errorRepository/GenericFault_To_SOAPFault
    BEA-380000 = ErrorHandling/errorRepository/GenericFault_To_SOAPFault2

    GenericFault_To_SOAPFault will return

    		<soapenv:Fault>
    		<faultcode>soapenv:Server</faultcode>
    		(:<faultstring>{data($errorMetadataDetails/err:omschrijving)}</faultstring>:)
    		<faultstring>some resource path</faultstring>
    		<faultactor>{fn:concat($inbound/ctx:transport/ctx:request/tp:headers/http:Host/text(),"/",$inbound/ctx:transport/ctx:uri/text())}</faultactor>
    		   <detail>
    				<custom_details>
    					<payload>{$body, $fault, $inbound}</payload>
    				</custom_details>				
    		   </detail>
    		</soapenv:Fault>	
    

    GenericFault_To_SOAPFault2 will return

    		<soapenv:Fault>
    		<faultcode>soapenv:Server</faultcode>
    		(:<faultstring>{data($errorMetadataDetails/err:omschrijving)}</faultstring>:)
    		<faultstring>some resource path</faultstring>
    		<faultactor>{fn:concat($inbound/ctx:transport/ctx:request/tp:headers/http:Host/text(),"/",$inbound/ctx:transport/ctx:uri/text())}</faultactor>
    		   <detail>
    				<custom_details2>
    				  <payload>{$body, $fault, $inbound}</payload>
    				</custom_details2>				
    		   </detail>
    		</soapenv:Fault>	
    

    Deploy the process.

    Now test the process either by using the testconsole of some testclient.

    The first testcase will have a valid input message. So the process will pass the Validation activity and will fail when routing to the business service.
    Since we used a non-existing host in here the process will trigger a BEA-380000 fault. As we defined in the errorRepository this errorCode will have the next set of metadata configured

    			<error>
    				<code>BEA-380000</code>
    				<externalCode>GENERIC-1234</externalCode>
    				<description>General transport error occured</description>
    				<sourceSystem>SYSTEM-X</sourceSystem>
    				<faultTransformer>ErrorHandling/errorRepository/GenericFault_To_SOAPFault2</faultTransformer>
    				<indAlert>Y</indAlert>
    				<indAlertOverwriteDestionation>N</indAlertOverwriteDestionation>
    				<alertDestination/>
    				<indLogging>Y</indLogging>
    				<indReporting>Y</indReporting>
    			</error>
    

    The generated soap fault is correct. It contains the custom_details2-element, which is generated by the GenericFault_To_SOAPFault2 transformer.
    Next check the sbconsole to see if there is also a report triggered for this error (indReporting=Y).

    Next check the weblogic console to see if the alert got executed (indAlert=Y). For this one i created an alert with JMS Destionation.

    For the second testcase we will use an invalid input message. The validation will throw an error (BEA-382505).
    Check the generated soap fault (custom_details-element should get generated now).

    And verify the alert and report too, to see if they got handled correctly.

    Extensibility

    In our xsd definition of the errorRepository we only defined a few settings just to show how it could work.
    Eventually this model can be extend with every setting you need in your error handling processes. Since all the logic of reading those settings and decide what logic to execute is defined on only
    one place, the errorHandler proxy service itself, it’s little work to extend the current logic for handlin the errors with new functionality. Just a new if-then activities for new settings and you’re ready to go.

    Conclusion

    The functionality as defined in the blog for handling the errors and creating a single point of error processing was enough for my testcase.
    I needed all the logic on one place and not in every process. I needed a single place in which i could define all the errors i wanted to handle and what actions to execute when such an error occurs.
    Besides that i needed a way in which other persons could easily add new defined errors to the file and the process would just ‘handle’ them without adding extra logic to processes.
    In case you don’t want someone else to manipulate the errorRepository file directly from within the sbconsole itself we could also just read the content of this file from some other external location by use of the doc() function, see this blog.

    I hope the solution described will help you a bit on implementation error handling in the Oracle Service Bus.
    As i’m always keen on learning from others, please leave comments on how to make the implementation better, or if the solution is totally useless please say so too 🙂

    download : OracleServiceBusGenericErrorHandling.zip

  • osb

    Oracle Service Bus, The number of parameters for registered XQuery resource System1_To_Fault does not match that given to it at runtime

    To be able to make use of Dynamic Xquery the xqueries itself all need to have the same defined interface.

    So after defining the different xqueries and test them one by one in Eclipse all seem to work.
    On runtime i get the next error :

    The number of parameters for registered XQuery resource System1_To_Fault does not match that given to it at runtime
    

    I was pretty sure after logging all the binded input variables they were all containing data.

    Lesson learned : Make sure you both bind all the variables but also ‘use’ them in the xquery itself.
    OSB will return this fault either when you don’t bind all the variables but also if you don’t use all of them in the xquery

    xquery1 fragment (will work):

    xquery version "1.0" encoding "Cp1252";
    
    declare function xf:System1_To_Fault(
        $metadata1		      as xs:string,
        $metadata2		      as xs:string,
    	$metadata3		      as xs:string)
        as element(soapenv:Fault) {
    		<soapenv:Fault>
    		<faultcode>soapenv:Server</faultcode>
    		<faultstring>some description</faultstring>
    		<faultactor>some string to the resource</faultactor>
    		   <detail>
    				<info1>{$metadata1}</info1>
    				<info2>{$metadata2}</info3>
    				<info3>{$metadata3}</info3>
    		   </detail>
    		</soapenv:Fault>
    };
    
    declare variable $metadata1 as xs:string external;
    declare variable $metadata2 as xs:string external;
    declare variable $metadata3 as xs:string external;
    
    xf:System1_To_Fault($metadata1, $metadata2, $metadata3)
    

    xquery2 fragment (will fail):

    		<soapenv:Fault>
    		<faultcode>soapenv:Server</faultcode>
    		<faultstring>some description</faultstring>
    		<faultactor>some string to the resource</faultactor>
    		   <detail>
    				<info1>{$metadata1}</info1>
    				<info2>{$metadata2}</info2>
    				<info3/>
    		   </detail>
    		</soapenv:Fault>
    

    inputvariable ‘metadata3’ isn’t used in the xquery itself, so the dynamix xquery will fail on runtime
    either make sure you always use all the input variables in the xquery (or do an expression on it, for example assign it to an temp variable but don’t use it for generating your target xml)
    something like this

        	let $temp := $metadata3
        	return 
       			<soapenv:Fault>
    			<faultcode>soapenv:Server</faultcode>
    			<faultstring>some description</faultstring>
    			<faultactor>some string to the resource</faultactor>
    		   	<detail>
    				<info1>{$metadata1}</info1>
    				<info2>{$metadata2}</info2>
    				<info3/>
    		   	</detail>
    			</soapenv:Fault>
    

    I’m not sure what this assign will do (performance-wise) when you assign a big dom-tree variable, in that case you could just assign the deepest childnode to the temp variable.
    Eventually it’s just a dirty fix to be able to use the xqueries in combination with dynamic xquery and still be able to not use all of the incoming parameters.

    Page 2 of 1112345...10...Last »