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

  • Share this Post:
    Digg Google Bookmarks reddit Mixx StumbleUpon Technorati Yahoo! Buzz DesignFloat Delicious BlinkList Furl

    61 Responses to “Oracle Service Bus, Generic fault handling”

    commenter

    Hi Eric,

    This is such an informative blog. Amazing read and it also deals with a much talked and blogged about topic of Fault handling in OSB.

    Kudos for taking time out for this amazing post.

    commenter

    Hi Arun!

    Thanks for the nice comment! Always nice to hear the readers like it, appreciated!

    commenter

    Hi Eric,

    Great approach to error management!

    I’ve been doing a similar working with some clients, developing a generic framework for error and audit management. In my case most of the messages are asynchronous and I also use a database to store error and audit metadata.

    commenter

    Hi Eric,
    Very good approach for error management. We have doing this for some of our clients, the only difference being that we have defined all the error codes in a DB.

    commenter

    Eric, Nice article..can you please upload the source code?

    commenter

    I updated the blog with a download link

    commenter

    Thanks Eric for the nice write up for error handling..

    Looking more from you !!

    commenter

    Warning: pack() [function.pack]: Type H: illegal hex digit L in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit R in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit I in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit S in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit G in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit J in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit v in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit p in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit t in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit T in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit R in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit g in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit L in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit h in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit j in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit M in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit I in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit M in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit I in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit o in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit m in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit y in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Hi Eric,Greate job.Can u please send the jar file,it will be helpful for me.I’m fresher for OSB.I tried with the link but I’m not able to get the jar.so please send it to mail:mani...@gmail.com

    Thanks
    Mani

    commenter

    Sended!

    commenter

    Mani,

    You should unzip the file on some location. Then in Eclipse create a new OSB Configuration Project. Now rightmouseclick on this project > Import > Import > General > Existing Projects into Workspace. Select the Error Handling folder and import it. Then you should have a valid osb project.

    commenter

    Nice approach for error handling.. This framework defenetely help in OSB design and can be reusable in multiple projects.
    Please can you send the jar which can be helpful for SOA design interms of OSB.

    commenter

    you should be able to build the jar yourself. When you import the projects from the zip file in Eclipse you can export to the jar

    commenter

    Gr8 Blog

    commenter

    Hi, Thank you for the blog. I have a question: Wouldn’t it be better to use “local transport” instead of HTTP for the error handler?
    If I want process the errors by first writing to a queue what is the best option in OSB, is it to use JMS (t3)?
    Thank you
    Matt

    commenter

    I think local transport is indeed a good option for this. Will try to do some tests later on. When you just want to write to jms by use of the bs, i assume you will only use jms://

    commenter

    Hi,

    Thanks for the great article! Question: is it possible to use this error handling mechanism in case the proxy service is a FTP Adapter and the XML retrieved from the FTP-server isn’t a valid XML (according to the XSD used in the adapter)?

    It seems that this kinds of failures only result in the file being moved to an “error directory” without the possibility to mark this on the OSB dashboard/…, i.e. to make it visible in the OSB console.

    Any suggestions for this?

    Thanks,
    Jan

    Eric Elzinga | May 15th, 2012 at 5:27 am
    commenter

    Hi Jan,

    You could use the ftp transport from osb itself and poll for all the files on a certain location. And in the procesflow itself use the validation activity to validate the xml data itself. In that case you’re able to just implement your own error handling logic and use for example report activities to publish information to the osb console

    commenter

    Hi Eric,

    Thanks for the swift response! We tried that as well, but to get this working, you need to define a FTP transport for plain text-files, so you have no XML to work with (translate etc.) later on in the flow. The validate action allows to save the result of the validation, but not the resulting XML it seems. Or am I missing somethings?

    Kind regards,
    Jan

    Eric Elzinga | May 15th, 2012 at 6:05 am
    commenter

    Hi Jan,

    You could use the function fn-bea:inlinedXML() to transform the string to xml. After that you should be able to validate the xml. In that case the xml itself should contain all the namespace prefixes and namespace definitions.

    commenter

    Hi Eric,

    I tried your suggestion:

    1.) Create a proxy service – FTP Transport for text files

    2.) Add pipeline pair

    3.) Add a stage with a Replace action – Replace “./text()” in variable “body” with “fn-bea:inlinedXML($body)”

    4.) Add a stage with a Validate action – Validate “./org:CORRECTIES” in variable “body” against “correctie” ( Element = “CORRECTIES” )

    5.) Add a stage with a report action

    6.) Add a service error handler with a report action

    This works with XMLs that are valid, but an invalid XML (e.g. missing tag) is not reported, the file is only moved to the error folder, i.e. the same behaviour as with a FTP adapter/transport with validation on XSD.

    So it seems that this problem cannot be resolved this way … Or am I missing an important point?

    XSD:
    —-

    commenter

    Hi Jan,

    I would think the ftp transport should be able to retrieve any kind of file, whether or not it’s valid xml or any other file type.
    When you do an assign of the fn-bea:inlinedXML function to a tempvar and log the content of the file, what do you see in the logging. Or maybe it’s easier to use the sb testconsole and give the invalid xml input over there so you can see the audit trail. We need to find out step by step what step isn’t working. After the assign we can validate our tempvar to see what the result of this will be. We can assign this to a tempvar again or throw a fault. Eventually in the service error handler we could do the report action but after that use a reply with success. Our transaction should be handled correctly in that case, but you still have the result of the report action in the console.

    commenter

    Hi Eric,

    I changed the flow to:
    1.) Create a proxy service – FTP Transport for text files

    2.) Add pipeline pair

    3.) Add a stage with a Assign action – Assign “$body” to variable “temp”
    and a Replace action – Replace “./text()” in variable “temp” with “fn-bea:inlinedXML($body)” with option “Replace node contents”

    4.) Add a stage with a Validate action – Validate “./org:CORRECTIES” in variable “temp” against “correctie” ( Element = “CORRECTIES” )

    5.) Add a stage with a report action

    6.) Add a service error handler with a report action

    In the test console it works – i.e. a report is always created – for valid and invalid XML files (I suppose because the FTP transport is skipped in a way as files are provided by means of the dialog box), but when an invalid file is placed on the FTP directory it fails without a report (the file is only moved to the error folder). In this case the log file contains this error:

    Failed to process request message for service ProxyService Agrimarkt/ProxyService/ftp_in_correcties_plaintext: com.bea.wli.sb.pipeline.PipelineException: OSB Replace action failed updating variable “temp”: Error parsing XML: null com.bea.wli.sb.pipeline.PipelineException: OSB Replace action failed updating variable “temp”: Error parsing XML: null at stages.transform.runtime.ReplaceRuntimeStep.processMessage(ReplaceRuntimeStep.java:166) ….

    So it’s the inlinedXML() function/replace action that is failing, it seems.
    Can this exception be catched in a way?

    Kind regards,
    Jan

    Eric Elzinga | May 16th, 2012 at 4:52 am
    commenter

    Can you add as first step of your process “log $body” and see what’s in it. The inlineXML function will fail if the xml is non-valid.
    What xpath expression are you execution in the report activity?

    Maybe don’t use an xpath expression there and just some static string, just to see if it get’s executed.
    If you try to do something like $body/element1/element2 and the $body doesn’t contain any valid xml, it will fail also.

    So let’s first test this to see where we end up in the message flow.

    commenter

    The report action: Report “$temp” with search keys:
    Name “Bestandsnaam” – Key “./ctx:transport/ctx:request/tp:headers/ftp:localFileName” in variable “inbound”

    So nothing is reported on temp/body.

    I added the log $body as the first step in the flow. Results:
    - BEA-000000 with the SOAP body containing the content of the invalid file
    - BEA-382004 error with stacktrace “Failed to process request message for service ProxyService Agrimarkt/ProxyService/ftp_in_correcties_plaintext: com.bea.wli.sb.pipeline.PipelineException: OSB Replace action failed updating variable “temp”: Error parsing XML: null …”
    - BEA-380003 error with stacktrace “Exception on TransportManagerImpl.receiveMessage, com.bea.wli.sb.pipeline.PipelineException: OSB Replace action failed updating variable “temp”: Error parsing XML: null com.bea.wli.sb.pipeline.PipelineException: OSB Replace action failed updating variable “temp”: Error parsing XML: null at …”
    - BEA-010065 warning with stacktrace “MessageDrivenBean threw an Exception in onMessage(). The exception was: javax.ejb.EJBException: nested exception is: com.bea.wli.sb.transports.TransportException: OSB Replace action failed updating variable “temp”: Error parsing XML: null. javax.ejb.EJBException: nested exception is: com.bea.wli.sb.transports.TransportException: OSB Replace action failed updating variable “temp”: Error parsing XML: null at …”

    Jan

    Eric Elzinga | May 16th, 2012 at 6:58 am
    commenter

    can you try the next assign to $temp

    assign <myroot>{$body/*}</myroot> to $temp and log this one

    commenter

    This is the lof of temp after assigning “{$body/*}” to variable “temp: :

    [PipelinePairNode1, PipelinePairNode1_request, Log temp, REQUEST] Temp :

    commenter

    (Correction)

    [PipelinePairNode1, PipelinePairNode1_request, Log temp, REQUEST] Temp =: &ltmyroot/&gt

    commenter

    Eric,

    Have you got another suggestion for this problem?

    It’s maybe an interesting addition to your – by the way excellent – book :-)

    Thanks,
    Jan

    Eric Elzinga | May 31st, 2012 at 6:36 am
    commenter

    Not really.
    Need to do some testcases myself to investigate it more, just need to find some spare time

    commenter

    Hi,

    I imported the project in eclipse and deployed it , but when i run EmployeeService.proxy i am getting this error:

    Validation of ProxyService ErrorHandling/testService/proxy/EmployeeService : ProxyService ErrorHandling/testService/proxy/EmployeeService does not exist failed

    commenter

    Is this one deployed too :testService/proxy/EmployeeService
    when you test this proxyservice in the testconsole, does it work ?

    commenter

    very nice blog
    When I ran the test case response is different than what you posted on the soapui. In any changes needed on Errorhandling code?

    commenter

    What is the response you get ?

    commenter

    when i click on any expressions popup is not opening on eclipse. I copied ErrorRepository.xq to my local project and its thowing Validation of XqueryExecutorDerivedType error

    commenter

    Validation of XqueryExecutorDerivedType xxxOSBErrorHandler/xsd/ErrorRepository : XqueryExecutorDerivedType xxxOSBErrorHandler/xsd/ErrorRepository does not exist failed

    commenter

    Is the xsd you used for the ErrorRepository valid? and is it avaiable in your osb project? Maybe need a refresh on the folder?

    commenter

    Hello,

    Nice post! Can you explain what is the significance of below 2 transformer file that you used? I understand their usage in general but what is the significance of them in your program. I didn’t see any difference between 2 files, they look same probably

    ErrorHandling/errorRepository/GenericFault_To_SOAPFault
    ErrorHandling/errorRepository/GenericFault_To_SOAPFault2

    commenter

    You’re right. the result of the xquery is just a different element-name in the detail-tag.
    Idea is to show how to make use of different soap fault configurations based on the incoming errorCode (the part you configure in the ErrorRepository.xq). If you only have 1 generic soap fault defined you could also use just 1 soap fault query file, and configure that one in the ErrorRepository.xq.

    commenter

    Warning: pack() [function.pack]: Type H: illegal hex digit L in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit R in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit I in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit S in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit G in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit J in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit v in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit p in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit t in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit T in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit R in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit g in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit L in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit h in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit j in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit M in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit I in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit M in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit I in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit o in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit m in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Warning: pack() [function.pack]: Type H: illegal hex digit y in /home/deb32501/domains/xenta.nl/public_html/blog/wp-content/plugins/wp-recaptcha/recaptchalib.php on line 237

    Hi Eric,

    Thanks for the wonderful post. Can you please send me the zip file of project so I will try to learn from it. Appreciate your hard work on this. pank...@gmail.com

    Best Regards,
    Pankaj

    commenter

    Hi Eric,

    I am just reviewing your example. Its simply good and very helpfull.
    But here I am getting some error in the flow When I have tested it. I am not getting any response back from constructResponse Replace action. Please help.

    commenter

    We need to identify where in the process it fails for you.
    Do you see some error occuring in the logging? When you test the proxy as standalone, do you get a response ?
    When you use the debugger in Eclipse and step through, where does it end ?

    commenter

    Hi Eric,

    I have added one log before the replace action and getting below log

    PipelinePairNode1_request, constructResponse, REQUEST] ####### $errorMetadataDetails_2nd#######:
    BEA-380001
    JCA-11622
    Problem in the Connectionpool/Datasource configuration. Check the connection details
    OSB
    errorRepository/xquery/faults/GenericFault_To_SOAPFault
    Y
    Y
    >

    After that in the replace action its getting error out.

    below error I can get in the log

    xmlns:con=”http://www.bea.com/wli/sb/context”>
    BEA-382513
    OSB Replace action failed updating variable “body”: Error parsing XML: {err}FORG0005: expected exactly one item, got 0 items

    PipelinePairNode1

    under dynamic xquery I have configured
    expression as data($errorMetadataDetails/*:faultTransformer)
    and body as $body/errordata/body/*
    inbound as $body/errordata/inbound/*
    fault as $body/errordata/fault/*

    Under replace action xpath is ./* and invariable is body and entire node contents.

    In ErrorRepository.xq file xquery location is
    errorRepository/xquery/faults/GenericFault_To_SOAPFault

    and GenericFault_To_SOAPFault.xq file is like below

    xquery version “1.0″ encoding “Cp1252″;
    (:: pragma parameter=”$body” type=”xs:anyType” ::)
    (:: pragma parameter=”$inbound” type=”xs:anyType” ::)
    (:: pragma parameter=”$fault” type=”xs:anyType” ::)
    (:: pragma type=”xs:anyType” ::)

    declare namespace xf = “http://tempuri.org/errorRepository/GenericFault_To_SOAPFault/”;
    declare namespace ctx = “http://www.bea.com/wli/sb/context”;
    declare namespace tp = “http://www.bea.com/wli/sb/transports”;
    declare namespace http = “http://www.bea.com/wli/sb/http”;
    declare namespace soapenv = “http://schemas.xmlsoap.org/soap/envelope/”;
    declare namespace err = “http://nl.xenta/services/errorRepository”;

    declare function xf:GenericFault_To_SOAPFault($body as element(*),
    $inbound as element(*),
    $fault as element(*))
    as element(*) {

    soapenv:Server
    some resource path
    {fn:concat($inbound/ctx:transport/ctx:request/tp:headers/http:Host/text(),”/”,$inbound/ctx:transport/ctx:uri/text())}

    {$body, $fault, $inbound}

    };

    declare variable $body as element(*) external;
    declare variable $inbound as element(*) external;
    declare variable $fault as element(*) external;

    xf:GenericFault_To_SOAPFault($body,
    $inbound,
    $fault)

    commenter

    It looks like either one of the variables for in the input of the xquery is empty or the xpath expression to used for one of the variables doesn’t exists.

    can you log every inputvariable of that xquery and verify on every variable if the xpath expression is valid? if either one of the variables is empty it will fail

    commenter

    Hi Eric,

    The problem was their in the variable name. Now its working and I am getting the response also.

    But I have one question. In the xquery file we are setting some customized error reason like “General transport error occured” but in the response which we are getting in the osb console/soapui this message is absent. Also the response which I am getting, except the fault reason everything almost same like your response screenshot though in fault reason I am getting detail and lengthy reason message. Is this due to any misconfiguration.

    commenter

    When you execute the second proxy service directly from soapui or the console, do you see the constructed soap faul of yourself coming back ?

    sagnik sarkar | August 5th, 2013 at 2:48 pm
    commenter

    Do you know how to ensure “At Least Once” pattern in MQ transport of oracle service bus. Need some update on this urgently please. Thanks in advance.

    sagnik sarkar | August 5th, 2013 at 2:49 pm
    commenter

    Do you know how to ensure “At Least Once” pattern in MQ transport of oracle service bus. Need some update on this urgently please. Thanks in advance.

    commenter

    Don’t have any onside experience with it, sorry. I assume you already had a look at this part of the documentation : http://docs.oracle.com/cd/E17904_01/doc.1111/e15866/mq.htm
    What’s the scenario you want to create?

    commenter

    Hi Eric,

    I am getting the soap fault as per the format which we defined in the GenericFault_To_SOAPFault xquery file.

    But in response under payload-body and fault, reason containing the detail errore message. Also I am not getting the customized message like ‘General transport error occured’ which we defined in the xsd xquery file.

    In your example screenshot its showing reason as ‘Length required’. Is it database response or you defined in your file as customized response. Please let me know why we are setting one error description in the errorRepository file.

    commenter

    That’s a messag which is generated by the osb framework itself. Only thing i do is reply back the original fault in my custom soap fault. the message itself i haven’t defined myself

    commenter

    Hi Eric,

    I am not able to see the error code BEA 382505 even after sending the invalid XML as suggested in your test case. Can you please let me know to what could be missing. I didn’t change anything in the project.

    Thanks,
    Moosvi

    commenter

    Hi Moosvi,

    What’s the return message you do see?

    commenter

    Hi Eric,

    Thanks for the reply. The error code that I see in the adminServer.log is perfectly fine, meaning it match the expected result as per the test case describe however this is not the case with SOAP UI. I see the same error code BEA382505 in SOAP UI whether I send the valid or invalid employee ID. Any reason do you know why SOAP is showing the same error code for valid and invalid ID but adminServer.log is showing the correct way.

    Thanks,
    Moosvi

    commenter

    Hi Moosvi,

    Can you try setting up a debug session from within Eclipse and follow the message to see what happens? Hard for me to find out what is going wrong.

    commenter

    Hi Eric,

    Thanks I am able to retrieve the message that I am looking for.

    Another quick one. Do you know the best possible way to extract the SOAP message. Currently I am sending the entire SOAP body and publishing it to my email service but I need a XQuery to just extract errorCode and route node info. I am new to XQuery so need your help.

    Thanks,
    Moosvi

    commenter

    Hi Eric.
    First, thank you very much for your blog. I have read several articles and it have helped me a lot.
    For generic fault handling I followed your instructions and it has worked fine. Now I wonder how I could have the definition of errors in a database.
    I could use a JCA resource for access to DB, ¿is this the best option?, Can you help?

    Greetings from Spain ;)

    commenter

    I think that’s indeed the best and easiest way to make a call to the database. You could add result caching to the db adapter to make it even more faster since most of the error configuration won’t change that often

    commenter

    Thank you very much Eric!.

    I’m trying to centralize in a single proxy (proxy manager), all the monitoring (alerts, reports, logs…), but I have a question:

    Is it possible to find out, a proxys or busines services operational configuration, from their execution context?

    The idea is to call the proxy manager only when the monitored parameter is activated.

    Best regards.

    commenter

    I think you need to create a java callout for that which will use some mbean to retrieve the proxyservice/business info.

    Leave a Reply:

    Name (required):
    Mail (will not be published) (required):
    Website:
    Comment (required):
    XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>