SOA Suite 11g – Using Spring Component to mimic Http Binding and integrate RESTful services

In an earlier post, I showed for the Oracle SOA Suite 11g how we can use the Mediator’s Java Callout functionality to integrate RESTful services into our SOA Composite applications, even though we currently have no Http Binding Service nor WSIF support (SOAP Java Binding) at our disposal in the SOA Suite – link to article.  In SOA Suite 11g PS1 – released in November 2009 – is the preview (not yet officially supported and only available for PoC and early trials – of Spring components. This feature provides another way of integrating Java classes into our SOA Composite applications.

This article demonstrates how we can use the Spring component to bind our SOA Composite Application to the RESTful Translation service provided by Google.

SOA Suite 11g - Using Spring Component to mimic Http Binding and integrate RESTful services SpringRestBinding10

Note:
In order to use this preview feature in SOA Suite 11g PS1, you must first enable preview mode. Go to $JDeveloper_HOME/integration/seed/soa/configuration and open soa-config.xml. Search for ${SPRING_COMPONENT_NAME_L} and remove the xml comments (<!– –>) around it. After you’ve saved the file, restart JDeveloper.

Steps for creating the SOA Composite with integrated RESTful Translation Service

1. Create SOA application – with Mediator (Translator)

2. Create Java Interface ITranslator

package nl.amis.soasuite11g.spring;

public interface ITranslator {

  public  String translate(String sourceString, String sourceLanguage, String targetLanguage);
}

3. Create implementation class TranslatorImpl

package nl.amis.soasuite11g.spring;

public class TranslatorImpl implements ITranslator {

  public String translate(String sourceString, String sourceLanguage,
                          String targetLanguage) {
    return extractTranslationFromJSON(translateString(sourceString, sourceLanguage, targetLanguage));
  }

    private static String googleTranslationService =
      "http://ajax.googleapis.com/ajax/services/language/translate";

    private static String extractTranslationFromJSON(String response) {
      final JSONObject jsonObj = (JSONObject)JSONValue.parse(response);
      String translation=null;
      if (jsonObj != null && jsonObj.containsKey("responseData")) {
        final JSONObject responseData = (JSONObject)jsonObj.get("responseData");
        translation=  responseData.get("translatedText").toString();
      }
      return translation;
    }

 private static String translateString(String sourceString,
                                          String sourceLanguage,
                                          String targetLanguage) {
      HttpURLConnection connection = null;
      OutputStreamWriter wr = null;
      BufferedReader rd  = null;
      StringBuilder sb = null;
      String line = null;

      URL serverAddress = null;

      try {
          serverAddress = new URL(googleTranslationService +"?v=1.0&&q="+sourceString.replace(' ', '+')+"&&langpair="+sourceLanguage+"%7C"+targetLanguage);
          //set up out communications stuff
          connection = null;

          //Set up the initial connection
          connection = (HttpURLConnection)serverAddress.openConnection();
          connection.setRequestMethod("GET");

          connection.setDoOutput(true);
          connection.setReadTimeout(10000);

          connection.connect();

          //read the result from the server
          rd  = new BufferedReader(new InputStreamReader(connection.getInputStream()));
          sb = new StringBuilder();

          while ((line = rd.readLine()) != null)
          {
              sb.append(line + '\n');
          }

          return(sb.toString());

      } catch (MalformedURLException e) {
          e.printStackTrace();
      } catch (ProtocolException e) {
          e.printStackTrace();
      } catch (IOException e) {
          e.printStackTrace();
      }
      finally
      {
          //close the connection, set all objects to null
          connection.disconnect();
          rd = null;
          sb = null;
          wr = null;
          connection = null;
      }
      return null;
    }
  }

4. Create Spring Context using the Spring 2.5.6 node under Business Tier in the New Gallery:

SOA Suite 11g - Using Spring Component to mimic Http Binding and integrate RESTful services SpringRestBinding1

Call the Spring Content restful-beans.xml. For example. Or something else.

SOA Suite 11g - Using Spring Component to mimic Http Binding and integrate RESTful services SpringRestBinding2

5. Configure bean translator in the restful-beans.xml Spring context, based on the TranslatorImpl class

 <bean  name="translator"
        class="nl.amis.soasuite11g.spring.TranslatorImpl"  />

6. Configure an sca-service translationService in the restful-beans.xml Spring context,based on the bean translator

<sca:service name="translationService" target="translator"
             type="nl.amis.soasuite11g.spring.ITranslator"/>

 

The Spring Context is immediately added to the composite.xml

SOA Suite 11g - Using Spring Component to mimic Http Binding and integrate RESTful services SpringRestBinding3

 

 

8. Create an XSD for the elements used for the request into and response from the Translation Service:

<schema attributeFormDefault="unqualified"
	elementFormDefault="qualified"
	targetNamespace="http://nl.amis/translation"
	xmlns="http://www.w3.org/2001/XMLSchema">
	<element name="translationResult">
		<complexType>
			<sequence>
				<element name="result" type="string"/>
			</sequence>
		</complexType>
	</element>
	<element name="translationSource">
		<complexType>
			<sequence>
				<element name="input" type="string"/>
				<element name="sourceLanguage" type="string"/>
				<element name="targetLanguage" type="string"/>
			</sequence>
		</complexType>
	</element>
</schema>

9. Create the WSDL for Mediator based on this XSD

Go to the Mediator editor and click on the green plus sign behind the prompt WSDL URL. In the Define Service dialog, click on the generate WSDL icon to create the WSDL based on element definitions in the XSD. Select translationSource for the request message and translationResult for the response.

SOA Suite 11g - Using Spring Component to mimic Http Binding and integrate RESTful services SpringRestBinding4

10. Wire Spring Component restful-beans to Mediator TranslationService in the composite editor:

SOA Suite 11g - Using Spring Component to mimic Http Binding and integrate RESTful services SpringRestBinding5

this causes the Spring Component’s WSDL to be generated based on the Java Interface definition.

SOA Suite 11g - Using Spring Component to mimic Http Binding and integrate RESTful services SpringRestBinding6

11. Create transformations between Mediator and Spring Component

SOA Suite 11g - Using Spring Component to mimic Http Binding and integrate RESTful services SpringRestBinding11

12. Expose Mediator Service as Composite level Service

13. Deploy the Composite application to the SOA Suite

14. Test the Translation Service

SOA Suite 11g - Using Spring Component to mimic Http Binding and integrate RESTful services SpringRestBinding7

The response returned:

SOA Suite 11g - Using Spring Component to mimic Http Binding and integrate RESTful services SpringRestBinding8

The Message Flow Trace:

SOA Suite 11g - Using Spring Component to mimic Http Binding and integrate RESTful services SpringRestBinding9

Resources

JDeveloper 11g (11.1.1.2) Application: HttpBindingUsingSpringComponentSOAApp.zip.

Example of using the SOA Suite 11gt Spring Component (good introductory article!):  http://www.oracle.com/technology/architect/soa-suite-series/wli_custom_control_spring_component.html

Blog article on Mediator Java Callout to Google’s RESTful translation service

One Response

  1. Dan March 10, 2010