Consuming a service in Oracle Service Bus 12C using the REST adapter

In a previous post I have shown how to create a REST service in 12C. That was easy. But how do we consume a REST service? In this next bit I will show how to do that. The REST service we are going to use is Google’s Geocoding API. You can use this API to input address data and retrieve geo data in both JSON or XML. For example:

GoogleGeo

To consume this service in 11G we had to do quite some work….see here. Lets see if it has become more easy now in 12C.

First we are going to create the service how we are going to expose our service. We have the XSD and WSDL from the previous project so we are just going to reuse that. Create a new ServiceBus project GeoService and drag a new Pipeline onto your canvas. Name your pipeline GeoServicePipeline and click next. Next define its interface by selecting the WSDL using the icon with the green arrow. As you can see my WSDL is located in a folder called wsdl. Also check the box below ‘Expose as a Proxy Service’ and click Finish.

WSDL

As you can see we have now a simple proxy service doing nothing.

Skeleton

We now have to hook it up to the Google backend. As seen in the previous post, a WADL is a description of how to use a REST service, comparable to a WSDL for SOAP services. So basically I am looking for a WADL for the Geocode API. After some looking around I found a SoapUI project containing a few Google API services with their created WADL’s in there. So basically I grabbed the WADL from there and I did some tweaking and tuning as I saw that when creating the REST adapter in JDeveloper, it was picky with some settings. The WADL I created looks as followed:

<application xmlns="http://wadl.dev.java.net/2009/02"
    xmlns:soa="http://www.oracle.com/soa/rest" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:sch="http://www.google.com/geocode/service/schema">
   <doc xml:lang="en" title="Geocoding API"/>
   <grammars>
      <xsd:schema targetNamespace="http://www.google.com/geocode/service/imports" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
            <xsd:import schemaLocation="GoogleGeocode.xsd" namespace="http://www.google.com/geocode/service/schema"/>
        </xsd:schema>
   </grammars>
   <resources base="http://maps.googleapis.com">
      <resource path="maps/api/geocode/xml" id="geocode">
         <doc xml:lang="en" title="geocode"/>
         <param name="address" style="query" soa:expression="$msg.parameters/sch:address" default="" type="xsd:string"/>
         <param name="sensor" style="query" soa:expression="$msg.parameters/sch:sensor" default="false" type="xsd:string"/>
         <param name="language" style="query" soa:expression="$msg.parameters/sch:language" default="EN" type="xsd:string"/>
         <method name="GET" id="GET">
            <doc xml:lang="en" title="GET"/>
            <request/>
            <response status="200">
               <representation mediaType="application/xml" element="sch:GeocodeResponse" xmlns:sch="http://www.google.com/geocode/service/schema"/>
            </response>
         </method>
      </resource>
   </resources>
</application>

with matching XSD:

<?xml version = '1.0' encoding = 'UTF-8'?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
            xmlns:nxsd="http://xmlns.oracle.com/pcbpel/nxsd" nxsd:encoding="US-ASCII"
            xmlns:tns="http://www.google.com/geocode/service/schema"
            targetNamespace="http://www.google.com/geocode/service/schema">
  <xsd:element name="address" type="xsd:string"/>
  <xsd:element name="language" type="xsd:string"/>
  <xsd:element name="sensor" type="xsd:string"/>
  <xsd:element name="GeocodeResponse">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="status" type="xsd:string"/>
        <xsd:element name="result">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="type" type="xsd:string"/>
              <xsd:element name="formatted_address" type="xsd:string"/>
              <xsd:element name="address_component" maxOccurs="unbounded">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="long_name" type="xsd:string"/>
                    <xsd:element name="short_name" type="xsd:string"/>
                    <xsd:element name="type" maxOccurs="unbounded" type="xsd:string"/>
                  </xsd:sequence>
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="geometry">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="location">
                      <xsd:complexType>
                        <xsd:sequence>
                          <xsd:element name="lat" type="xsd:double"/>
                          <xsd:element name="lng" type="xsd:double"/>
                        </xsd:sequence>
                      </xsd:complexType>
                    </xsd:element>
                    <xsd:element name="location_type" type="xsd:string"/>
                    <xsd:element name="viewport">
                      <xsd:complexType>
                        <xsd:sequence>
                          <xsd:element name="southwest">
                            <xsd:complexType>
                              <xsd:sequence>
                                <xsd:element name="lat" type="xsd:double"/>
                                <xsd:element name="lng" type="xsd:double"/>
                              </xsd:sequence>
                            </xsd:complexType>
                          </xsd:element>
                          <xsd:element name="northeast">
                            <xsd:complexType>
                              <xsd:sequence>
                                <xsd:element name="lat" type="xsd:double"/>
                                <xsd:element name="lng" type="xsd:double"/>
                              </xsd:sequence>
                            </xsd:complexType>
                          </xsd:element>
                        </xsd:sequence>
                      </xsd:complexType>
                    </xsd:element>
                  </xsd:sequence>
                </xsd:complexType>
              </xsd:element>
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

Stick these 2 files in a folder thirdparty under you project. Now open your composite and drag the REST Adapter component to the External Service swimlane.

RestAdapter

Input the name and then click the green + at the bottom and select ‘Add operations based on WADL service’. Now select the WADL in the thirdparty folder and click OK. As you can see, the resource path and operation bindings are filled in. Also when you select the GET binding and click the pencil. You can see that both the request and response parameters are set.

RequestResponse

Now click on OK and JDeveloper will generate a business service, a WADL and a WSDL for you. The WADL and WSDL are under Resources but the business service is in the root. To keep it clean I move the business service to the business folder. It might disappear from your swim lane but you can just drag it onto it again from your project.

Composite

Now lets hook at all together. Connect the Pipeline with the REST adapter and open the pipeline. Add a Replace action in the Request route pipeline with the following xpath.

XpathInput

Don’t forget the namespaces. Now also input a Replace action in the Response route pipeline with the following xpath.

OutputXpath

In the Route set the Operation to GET.

Route

Save the whole project and deploy it. Open your EM and lets see if the service works.

Test

As you can see, the longitude and latitude are returned in the correct manner.

So, basically the conclusion is that the new 12C REST Adapter really makes your life easier when consuming a REST service. The only thing you might struggle with a bit is to get the WADL correct but once you get the hang if it, it is not too bad.

7 Replies to “Consuming a service in Oracle Service Bus 12C using the REST adapter”

  1. Hi Hugo,

    Thank you for the post. Using your examples I managed to call Google’s Geocoding API with the Rest Adapter of Service Bus 12c, so it works here as well.

    I assume you also set the Routing in your Pipeline to GET to make it work. I could not find this in the blog.

    The default is “Use inbound operation for outbound” which can also work, if you replace the operation GET by GetGeoCode in the generated WSDL. The generated WADL will link the operation GetGeoCode to the method GET in that case.

  2. Hey Joeri,

    Glad to see it also works for other people 🙂

    Very true. In the Route I set the operation to GET. I will add a screenshot to the post. Thanks for the feedback!

  3. Great work buddy. Was indeed very helpful, Just a bit of feedback. The payload for inbound call to Rest business service is a bit unclear. It would be nice to know where is the Get_params element or which wsdl specified the namespace and the element name. Anyways, I am sure you are pretty but whenever you have time. Thanks again 🙂

  4. Could you put the text of the replace actions in this article so we don’t have to type it all out while looking at an image? I’m lazy! 🙂

  5. Which owsm policy to be used for front proxy service ( exposed to consumers), I used Oracle/wss_http_token_service_polciy, it is working fine in my local machine server but not supporting in the dev/test server, so what extra settign is required here?

    • Hi Subash,

      You can use the oracle/wss_http_token_service_policy which will require your clients to add a soap security header to the soap request. If it doesn’t work on your dev/test machines, make sure owsm is installed and configured on those machines.

  6. both types are string

    { “errorMessage” : “Translation Failure.
    Failed to translate XML to JSON. Cannot write start element: getClienteReq
    The data does not conform to the NXSD schema. Please correct the problem.
    “, “errorCode” : “OSB-382000” }

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.