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.
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:
Call the Spring Content restful-beans.xml. For example. Or something else.
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
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.
10. Wire Spring Component restful-beans to Mediator TranslationService in the composite editor:
this causes the Spring Component’s WSDL to be generated based on the Java Interface definition.
11. Create transformations between Mediator and Spring Component
12. Expose Mediator Service as Composite level Service
13. Deploy the Composite application to the SOA Suite
14. Test the Translation Service
The response returned:
The Message Flow Trace:
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
Can you make a call to the SpringBean directly from BPEL or must you use a Mediator?