Pages

Thursday, April 2, 2009

XSD validation and exception handling in OSB

In OSB ( Oracle Service Bus , aqualogic service bus ) it is relative easy to add schema validation to your proxy service and to make a custom exception handling for this validation. Just follow the next steps. First in this example I use these xml schema's for the request and response operation.
The request xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="http://whitehorses.nl/request"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://whitehorses.nl/request"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:element name="request">
<xs:complexType>
<xs:sequence>
<xs:element name="runid" type="xs:short"/>
<xs:element name="message" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

And the response xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="http://whitehorses.nl/response"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://whitehorses.nl/response"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:element name="response">
<xs:complexType>
<xs:sequence>
<xs:element name="runid" type="xs:short"/>
<xs:element name="message" type="xs:string" minOccurs="0"/>
<xs:element name="errorid" type="xs:string" minOccurs="0"/>
<xs:element name="error" type="xs:anyType" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

When everything goes well I will only return the runid element else we get the full message with the errorcode. With these xsd's I made a simple WSDL which I can use in the proxy service.

First part of this blog entry is to make the happy flow when this works we can add the xsd validation.
Make a new proxy service and use this WSDL.
The next step is to make a simple business service with file transport

In my case I put the request xml in the c drive temp folder.

Go back to your proxy service where we create a new message flow.


Add a route-node to the flow with inside a new routing. This routing will call the file business service.

Add an assign component to request action flow so I can retrieve the runid from the request and add this to the runid variable. This variable I can use for the response.
To make a return message I add an assign to the response action. Now I add the response template xml to the body variable.

Add an insert to the response action after the assign. In this insert we will add the runid of the request to the runid of the response message.


The first part is finished, you service should work now. In the second part we will add the XSD validation.
To make a custom exception handling for the xsd we need to add a Pipeline Pair node.
In the request pipeline I will add a new stage.

In this stage I use the validation component. Now we have to select an element in the body variable which OSB will validate against the XSD. Provide the XSD and use the raise error option.

Add an error handler to this stage.

Add a new stage in the error handler

First we add an assign to the stage to retrieve the runid of the request message so I can use this for the response.

Add a second assign to the stage. In this assign I will add the response template xml to the body variable.

Add the runid to the response xml

Add the error details to the response xml

And the error code



With the reply we can give back the response xml back to the client. Very important report no error because this is a handled exception.

The second part is also finished, we only have to test this proxy service by adding a unknow element to the request and look at the response. Here is a picture of the result.

19 comments:

  1. Could you please post the validation WSDL?

    ReplyDelete
  2. Hi,

    here you have a export of the project.

    http://www.sbsframes.nl/jdeveloper/osbxsd.jar

    thanks

    ReplyDelete
  3. Thank you for posting the project export. Greatly appreciate it.

    Best regards,

    ReplyDelete
  4. Good topic. This is what I was looking for. I will try this out. Do you have any tool to convert xsd to wsdl?

    ReplyDelete
  5. I got the tool:
    xsd2wsdl.

    But when I trying to create proxy from wsdl, it requires port/binding information. But this is not generated as a part of wsdl. I have osb 10.4. Do you have any idea?

    ReplyDelete
  6. Hi,

    just use jdeveloper or xmlspy and create a wsdl with a port and operation.

    Use an element of your xsd as request element and an element for your response.

    thanks

    ReplyDelete
  7. thanks. Got the wsdl from jdev. How did you get the response xml that you are loading into body in soap format. I have response xml in string format.

    ReplyDelete
  8. Thanks for the example. Its highly appreciated. Is there any way of setting the log levels (INFO, DEBUG, ERROR) in OSB Exception handling. How do we provide such configuration using OSB? Also, do you know whether we can propagate exceptions to the top level so that we can trace the exception deep down the hierarchy.

    ReplyDelete
  9. Hi,

    Can you explain this more and provide a use case. then I will take a look at what you want and how you can achieve this

    thanks

    ReplyDelete
  10. Validation is a must in development, but not always desirable in production. Is there an easy way to switch it off without touching the code?

    Thanks

    ReplyDelete
  11. Can you help me by providing a sample with SERVICE CALLOUTS.

    ReplyDelete
  12. Hi Biemond

    I'm getting the following error:

    Request:






    100

    string




    Response:




    soapenv:Server

    BEA-382040: Failed to set the value of context variable "body". Value must be an instance of {http://schemas.xmlsoap.org/soap/envelope/}Body.



    BEA-382040

    Failed to set the value of context variable "body". Value must be an instance of {http://schemas.xmlsoap.org/soap/envelope/}Body.


    RouteNode1
    response-pipeline







    Did I miss anything?

    Please clarify

    Thanks

    ReplyDelete
    Replies
    1. Hi,

      When you do an assign and do a replace of the body you need to set the body element again and add your own payload inside this.

      http://4.bp.blogspot.com/_earSixbe3dw/SdUl9PVIFdI/AAAAAAAACVs/SoqcTCfZZH0/s1600/osb-xsd-4.png

      or use replace activity and replace the body content and not the whole var.

      thanks

      Delete
  13. Is it possible to set the value of "Against Resource" at runtime ?

    ReplyDelete
    Replies
    1. Hi,

      Don't think this is possible. you can only control it with a if condition before it.

      thanks

      Delete
  14. Hi Edwin,

    Thanks for the wonderful post. I want to create generic error handling service. Can you please guide me about it. Atlease some flow steps.

    Best Regards,
    A

    ReplyDelete
    Replies
    1. Hi,

      Easy way is to have only async messages ( with jms ) and for sync always return a soap fault -> let them handle the error.

      Maybe you can make a custom report handler and add a report action in the error stage of a BS or somewhere in the pipeline.
      Or in a error stage you can publish a jms messages, from there you can develop a application or a human workflow which processes these errors and put the original ( or changed) message on a jms queue.

      Good luck

      Delete
    2. Hi Edwin,

      Thanks for your reply. I have created a service but getting one error in assigning value. I have google and tried diffrent option but still not working. Could you please provide me your email ID, so i will send you the zip file.

      Best Regards,
      A

      Delete
    3. Hi

      send it to biemond at gmail dot com

      thanks

      Delete