Monday 28 May 2012

Invoking Soa Suite 11g Service from java

Calling a Soa Suite Direct Binding Service from Java & OSB

I was trying to connect Oracle Soa Suite 11G R1 PS1 with the OSB when I saw this new Direct Binding Service in the Soa Suite 11G. This direct binding make it possible to start this RMI service from OSB or Java. In a previous blog I already called a Soa Service from Java using the ADF binding but this direct binding makes it also possible to call this also from OSB using the SB transport . In this Blog I will call this RMI synchronous service from Java, I can not use this binding in OSB 10.3.1, probably in the next version of the OSB I can.

First we add the Direct Binding Service to exposed Services side of the composite and use the WSDL of one of the other exposed services and add a Wire to the Component.
In the source view of the composite xml you can see that this service uses the direct binding.
  1. <service name="RMIService" ui:wsdlLocation="BPELProcess1.wsdl">  
  2. <interface.wsdl interface="http://xmlns.oracle.com/HelloWorld/Helloworld/BPELProcess1#wsdl.interface(BPELProcess1)"/>  
  3. <binding.direct/>  
  4. </service>  

To see the WSDL of this service go to http://localhost:8001/soa-infra/ and select your RMI service.

package nl.whitehorses.soa.client;
import java.io.StringWriter;
import java.io.StringReader;
import java.util.Hashtable;
import java.util.Map;
import java.util.HashMap;
import javax.naming.Context;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import oracle.soa.api.PayloadFactory;
import oracle.soa.api.XMLMessageFactory;
import oracle.soa.api.invocation.DirectConnection;
import oracle.soa.api.message.Message;
import oracle.soa.api.message.Payload;
import oracle.soa.management.CompositeDN;
import oracle.soa.management.facade.Locator;
import oracle.soa.management.facade.LocatorFactory;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Document;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.xml.sax.InputSource;
public class StartRMIProcess {
    public StartRMIProcess() {
        super();
        Hashtable jndiProps = new Hashtable();
        jndiProps.put(Context.PROVIDER_URL, "t3://soaps3.alfa.local:8001/soa-infra");
        jndiProps.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
        jndiProps.put(Context.SECURITY_PRINCIPAL, "weblogic");
        jndiProps.put(Context.SECURITY_CREDENTIALS, "weblogic1");
        jndiProps.put("dedicated.connection", "true");
        Locator locator = null;
        try {
            // connect to the soa server
            locator = LocatorFactory.createLocator(jndiProps);
            // find composite default domain, Helloworld Composite, version 1.0
            CompositeDN compositedn = new CompositeDN("default", "Helloworld", "1.0");
            // call the direct binding of the Helloworld composite
            DirectConnection conn = locator.createDirectConnection(compositedn,"RMIService");
            
            String inputPayload =
            "<client:process xmlns:client=\"http://xmlns.oracle.com/HelloWorld/Helloworld/BPELProcess1\">\n" +
            " <client:input>hello</client:input>\n" +
            "</client:process>\n" ;
            
            DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = docBuilderFactory.newDocumentBuilder();
            Document doc = builder.parse(new InputSource(new StringReader(inputPayload)));
            Element root = doc.getDocumentElement();
            //<wsdl:message name="BPELProcess1RequestMessage">
            // <wsdl:part name="payload" element="client:process"/>
            //</wsdl:message>
            Map<String, Element> partData = new HashMap<String,Element>();
            // have to use payload see BPELProcess1RequestMessage
            partData.put("payload", root);
            Payload<Element> payload = PayloadFactory.createXMLPayload(partData);
            //Messages are created using the MessageFactory
            Message<Element> request = XMLMessageFactory.getInstance().createMessage();
            request.setPayload(payload);
            //<wsdl:portType name="BPELProcess1">
            // <wsdl:operation name="process">
            // <wsdl:input message="client:BPELProcess1RequestMessage" />
            // <wsdl:output message="client:BPELProcess1ResponseMessage"/>
            // </wsdl:operation>
            //</wsdl:portType>
            // this is a request-reply service so we need to use conn.request else use conn.post
            // need to provide operation name so we need to use process
            Message<Element> response = conn.request("process", request);
            TransformerFactory tFactory = TransformerFactory.newInstance();
            Transformer transformer = tFactory.newTransformer();
            transformer.setOutputProperty("indent", "yes");
            StringWriter sw = new StringWriter();
            StreamResult result = new StreamResult(sw);
            //<wsdl:message name="BPELProcess1ResponseMessage">
            // <wsdl:part name="payload" element="client:processResponse"/>
            //</wsdl:message>
            // need to use payload again
            DOMSource source = new DOMSource((Node)response.getPayload().getData().get("payload"));
            transformer.transform(source, result);
            System.out.println("Result\n"+sw.toString());
        
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        StartRMIProcess startRMIProcess = new StartRMIProcess();
    }
}

No comments:

Post a Comment

xslt padding with characters call template for left pad and right pad

  Could a call-template be written that took two parameters ?   a string, and a   number) return the string with empty spaces appended t...