Advertisements

Posts Tagged 'routing'

Using Dynamic Routing in OSB

Dynamic Routing in OSB can be used when we want to determine the business service at runtime in the message flow. To store the information about the business services that can be used, we can use XQuery resource.

Consider a scenario where OSB has to route the incoming requests to 2 different services based on the CustomerType element value sent in the payload. So create a XQuery resource with the following contents. Observe that we are using the absolute path of business service in configuration as required by dynamic routing.

<Configuration>
<CustomerType value =’Privileged’>
<Service>DynamicRoute/BSSystem1</Service>
</CustomerType>

<CustomerType value =’Ordinary’>
<Service>DynamicRoute/BSSystem2</Service>
</CustomerType>
</Configuration>

Following is the XML schema that we use.

<xsd:schema targetNamespace=”http://xmlns.oracle.com/schema/Customer”
    xmlns:xsd=”http://www.w3.org/2001/XMLSchema” xmlns:ns1=”http://xmlns.oracle.com/schema/Customer”>

    <xsd:complexType name=”Customer”>
<xsd:sequence>
<xsd:element name=”CustomerId” type=”xsd:string” />
<xsd:element name=”FirstName” type=”xsd:string” />
<xsd:element name=”LastName” type=”xsd:string” />
<xsd:element name=”MiddleName” minOccurs=”0″ type=”xsd:string” />
<xsd:element name=”CustomerType” type=”xsd:string” />
<xsd:element name=”Email” minOccurs=”0″ type=”xsd:string” />
<xsd:element name=”Mobile” minOccurs=”0″ type=”xsd:string” />
</xsd:sequence>
</xsd:complexType>

    <xsd:complexType name=”StatusMsg”>
<xsd:sequence>
<xsd:element name=”CustomerId” type=”xsd:string” />
<xsd:element name=”Response” type=”xsd:string” />
<xsd:element name=”ErrorCode” type=”xsd:string” minOccurs=”0″/>
<xsd:element name=”ErrorMessage” type=”xsd:string” />
</xsd:sequence>
</xsd:complexType>

    <xsd:element name=”Customer” type=”ns1:Customer” />
<xsd:element name=”StatusMsg” type=”ns1:StatusMsg” />
</xsd:schema>

Following is the WSDL that we will use for the proxy service:

<wsdl:definitions name=”CustomerService”
targetNamespace=”http://xmlns.oracle.com/wsdl/CustomerService”         xmlns:wsdl=”http://schemas.xmlsoap.org/wsdl/”
    xmlns:ns1=”http://xmlns.oracle.com/schema/Customer” xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
    xmlns:tns=”http://xmlns.oracle.com/wsdl/CustomerService” xmlns:soap=”http://schemas.xmlsoap.org/wsdl/soap/”>
<wsdl:types>
<xsd:schema>
<xsd:import namespace=”
http://xmlns.oracle.com/schema/Customer”
                schemaLocation=”Customer.xsd” />
</xsd:schema>
</wsdl:types>

    <wsdl:message name=”CustomerCreate”>
<wsdl:part name=”parameters” element=”ns1:Customer” />
</wsdl:message>
<wsdl:message name=”CustomerCreateResponse”>
<wsdl:part name=”parameters” element=”ns1:StatusMsg” />
</wsdl:message>

    <wsdl:portType name=”CustomerServicePort”>
<wsdl:operation name=”CustomerCreate”>
<wsdl:input message=”tns:CustomerCreate” />
<wsdl:output message=”tns:CustomerCreateResponse” />
</wsdl:operation>
</wsdl:portType>

    <wsdl:binding name=”CustomerServiceBinding” type=”tns:CustomerServicePort”>
<soap:binding style=”document”
transport=”
http://schemas.xmlsoap.org/soap/http” />

        <wsdl:operation name=”CustomerCreate”>
<soap:operation soapAction=”CustomerCreate” />
<wsdl:input>
<soap:body use=”literal” />
</wsdl:input>
<wsdl:output>
<soap:body use=”literal” />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
</wsdl:definitions>

Create the required resources a proxy service based on the above WSDL, 2 business services and a XQuery resource with the contents shown above.

image

Create the message flow as shown below.

image

The first assign activity loads the XQuery resource and stores the contents of the file in variable ‘varConfig’. The second assign activity stores the value of customer type element in the payload in ‘varType’ variable using the xpath expression $body/cus:Customer/CustomerType/text().

For the dynamic routing the expression should resolve to the following XML snippet. The attribute isProxy has to be set to ‘true’ if routing the request to proxy service or ‘false’ if routing the request to business service. Operation name is optional as business service might  not be WSDL service always.

<ctx:route>
<ctx:service isProxy=’false’>absolute path of business service</ctx:service>
<ctx:operation>operation name</ctx:operation>
</ctx:route>

So for our case use the XML contents as shown in the below screenshot along with the XPath expressions to get the required values.

image

Deploy the configuration jar and test it from test console to verify its working as expected.

The sample jar can be download from the following location.

Advertisements

Fault Handling in OSB

As we know, service provider can send the error back to the consumer in the following ways:

  • As a normal response, by populating the fields like “ErrorNumber” and “ErrorMesssage”. Assuming that these fields are defined in the response message structure in WSDL.
  • As a SOAP fault

Typically when OSB is mediating between service consumer and service provider, we might have to transform this error response or fault response to the response structure defined in the proxy WSDL. So we need to understand on what message context variables can be used for this transformation.

As per WS-I BP, the service provider should send the HTTP response code as 200 when the error is being sent back as normal response and 500 should be sent when the error being sent back in form of the SOAP fault.

When HTTP response code 200 is received, OSB treats it as a normal response and $body will have the received response. And when response code 500 is received, the OSB runtime control goes  to the ‘Service Error Handler’ if present or to ‘System Error Handler’. That means OSB considers the fault response also as a normal response and populates $body, when response code is 200 is received for fault response.

And OSB populates different message context variables in case of fault response with 500 code depending on whether Routing or Service Callout are used to call the business service. When routing is used, the variable $body will have the fault response. When service callout is used, the variable $fault will have the fault response in ‘ReceivedFaultDetail’ structure.

For demonstrating the same, the following SOAP fault structure is used as a response in SOAP UI mock service.

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema">
   <SOAP-ENV:Body>
      <SOAP-ENV:Fault>
         <faultcode>SOAP-ENV:Client</faultcode>
         <faultstring>Failed to locate method (ValidateCreditCard) in class</faultstring>
         <detail>
              <ValidationError>
                   <ErrorCode>78970989</ErrorCode>
                   <ErrorMessage>Validation failed.Credit Card Expired.</ErrorMessage>
              </ValidationError>
     </detail>
      </SOAP-ENV:Fault>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Create 2 proxy services with routing and service callout as shown below.

Proxy with Routing

                      image

Proxy with Service Callout

                      image

The log activities in the error handler are used to log the contents of $body and $fault variable for demonstration purpose.

Create a business service by giving the mock service endpoint which returns a SOAP fault as shown below.

                      image

In case of routing, the following screenshot confirms that $body has the received fault response. So the expression fn:empty($body/soap-env:Fault) can be used to find out whether we have received the fault or not.

                     Routing

In case of service callout, the following screenshot confirms that $fault has the received fault response. So the expression fn:empty($fault/ctx:details/con1:ReceivedFaultDetail) can be used to find out whether we have received the fault or not. We can come up with similar kind of expressions for all other OSB faults that are described in the link.

                    Service Callout

In case where both service callout and routing are used in single proxy service, a combination of both of above expressions has to be used.

Also look at the note given here that talks about fault handling in OSB.


Advertisements

Pages

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 372 other followers

Enter your email address to follow this blog and receive notifications of new posts by email.

Advertisements