38 Using Direct Binding to Invoke Composite Services

This chapter describes the Direct Binding Invocation API and how to invoke a SOA composite application. It describes how to create an inbound direct binding service, how to create an outbound direct binding reference, and how to set an identity for Java 2 Platform, Standard Edition (J2SE) clients invoking direct binding. Samples of using the Direct Binding Invocation API are also provided.

This chapter includes the following sections:

38.1 Introduction to Direct Binding

A common way to invoke a composite is to use SOAP over HTTP. This is enabled by creating a SOAP service for your composite using web service binding. However, you can also use direct binding, which provides a tighter integration alternative. Direct binding enables Java clients to directly invoke composite services, bypassing the intermediate conversion to XML required with web service binding.

Direct binding provides two types of invocation styles:

  • Inbound direct binding

    The direct service binding component allows an external client to send messages using the Direct Binding Invocation API, where the Direct Binding Invocation API takes the JNDI connection parameters and creates a connection object on behalf of the client.

  • Outbound direct binding (or direct reference binding)

    The direct reference binding component provides support for sending SOA messages directly to external services over a remote method invocation (RMI). These external services must implement the SOA invocation API (the same as the direct inbound invocation API).

    In the case of direct outbound binding, the connection object is created with the JNDI name of the external service bean configured for the binding.

Direct binding must be associated with the interface.wsdl, providing the interface clause and, optionally, the callbackInterface clause. The associated WSDL must be imported into the composite.

The service binding component also publishes a modified version of the WSDL that advertises the direct binding.

38.1.1 Direct Service Binding Component

A sample configuration using the direct service binding component is shown in the following example:

<service name="direct2">
      <interface.wsdl
interface="http://xmlns.oracle.com/asyncNonConvDocLit#wsdl.interface(asyncNonConvD
ocLit)"
callbackInterface="http://xmlns.oracle.com/asyncNonConvDocLit#wsdl.interface(async
NonConvDocLitCallback)" xmlns:ns="http://xmlns.oracle.com/sca/1.0"/>
      <binding.direct/>
</service>

38.1.2 Direct Reference Binding Component

The direct reference binding component requires the following information to connect to a user-provided SOA invoker:

  • Properties:

    A set of properties that defines the DirectConnection for the end service (see oracle.soa.management.facade.Locator).

  • ConnectionFactory class name (see oracle.soa.management.facade.Locator).

    The ConnectionFactory class must implement the oracle.soa.api.invocation.DirectConnectFactory interface.

    If the ConnectionFactory class name is not specified, the default oracle.soa.api.JNDIDirectConnectionFactory is used. To use the default connection factory, you must supply the lookup name for the EJB.

  • Address used by the external service:

    This address value is not processed by the binding component, but is passed on to the service bean during invocation.

  • addressingVersion (optional):

    The default addressing version used is 2005/08.

  • useSSLForCallback:

    Use a secure socket layer (SSL) for the callback JNDI connection. If this flag is set to true, then the WS-Addressing replyTo header instructs the service to call back at an SSL JNDI port.

A sample configuration is shown in the following example:

<reference name="HelloReference" ui:wsdlLocation="HelloService.wsdl">
  <interface.wsdl
 interface="http://hello.demo.oracle/#wsdl.interface(HelloInterface)"/>
  <binding.direct connection-factory="oracle.soa.api.JNDIDirectConnectionFactory"
   addressingVersion="http://www.w3.org/2005/08/addressing"
   address="soadirect://syncOut"
   useSSLForCallback="false">
  <property
 name="oracle.soa.api.invocation.direct.bean">MyDirectTestServiceBean#directEjb.Tes
tInvoker</property>
  <property
 name="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</property
>
 <property name="java.naming.provider.url">t3://@host:@port</property>
 </binding.direct>
</reference>

The direct binding components support both synchronous and asynchronous invocation patterns. Figure 38-1 describes a sample synchronous invocation pattern and Figure 38-2 describes a sample asynchronous invocation pattern.

Figure 38-1 Sample Synchronous Invocation Patterns

Description of Figure 38-1 follows
Description of "Figure 38-1 Sample Synchronous Invocation Patterns"

Figure 38-2 Sample Asynchronous Invocation Pattern

Description of Figure 38-2 follows
Description of "Figure 38-2 Sample Asynchronous Invocation Pattern"

38.2 Introduction to the Direct Binding Invocation API

The different packages used in the Direct Binding Invocation API are as follows:

  • oracle.soa.management.facade.Locator

    The oracle.soa.management.facade.Locator interface exposes a method, createConnection, which returns a direct connection. The Locator exposes the method shown in the following example for returning the DirectConnection.

    import java.util.Map;
    public interface DirectConnectionFactory {
        DirectConnection createDirectConnection(CompositeDN compositeDN,
     String serviceName) throws Exception;
    

    You can use the LocatorFactory implementation to obtain the DirectConnection, as shown in the following example:

    Hashtable jndiProps = new Hashtable();
    jndiProps.put(Context.PROVIDER_URL, "t3://" + hostname + ':' + portname + "/soa-infra");
    jndiProps.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
    jndiProps.put(Context.SECURITY_PRINCIPAL,"weblogic");
    jndiProps.put(Context.SECURITY_CREDENTIALS,"welcome1");
    jndiProps.put("dedicated.connection","true");
    Locator locator = LocatorFactory.createLocator(jndiProps);
    CompositeDN compositedn = new CompositeDN(domainName, compositename, version);
    String serviceName = "HelloEntry";
    return locator.createDirectConnection(compositedn, serviceName);
    
  • oracle.soa.api.invocation.DirectConnection

    The DirectConnection interface invokes a composite service using direct binding. For more information, see Java API Reference for Oracle SOA Suite Infrastructure Management.

  • oracle.soa.api.message.Message

    The Message interface encapsulates the data exchanged. For more information, see Java API Reference for Oracle SOA Suite Infrastructure Management.

38.2.1 Synchronous Direct Binding Invocation

Direct binding also supports the synchronous direct invocation with use of the method shown in the following example:

<T> Message<T> request(String operationName, Message<T> message)
 throws InvocationException, FaultException

38.2.2 Asynchronous Direct Binding Invocation

Asynchronous invocation relies on the WS-Addressing headers set on the message instance. All headers must adhere to the WS-Addressing specification.

The Direct Binding Invocation API allows the clients to specify the WS-Addressing ReplyTo SOAP header to communicate a destination by which they can receive responses.

An example of the WS-Addressing header used for asynchronous invocation is shown below:

<wsa:MessageID>D6202742-D9D9-4023-8167-EF0AB81042EC</wsa:MessageID>
   <wsa:ReplyTo xmlns:wsa="http://www.w3.org/2005/08/addressing">
     <wsa:Address>sb://testserver:9001/callback</wsa:Address>
      <wsa:ReferenceParameters>
        <soa:callback xmlns:soa="http://xmlns.oracle.com/soa/direct"
           connection-factory="mytest.MyDirectionConnectionFactory">
        <soa:property name="oracle.soa.api.invocation.direct.bean"
           value="myTest.MyDirectConnectionBean"/>
        <soa:property name="java.naming.provider.url" value="t3://test:8001"/>
        <soa:property name="java.naming.factory.initial"
           value="weblogic.jndi.WLInitialContextFactory"/>
        </soa:callback>
      </wsa:ReferenceParameters>
   </wsa:ReplyTo>

Note:

You must qualify the callback and its property elements properly with the SOA direct namespace.

The direct binding component is responsible for parsing the addressing headers set on the message instance. In this example, there are two headers: wsa:MessageID and wsa:ReplyTo. The service binding component makes the following properties available for the internal SOA components:

  • replyToAddress = sb://testserver:9001/callback

  • replyToReferenceParameter: element of WSA:ReferenceParameters

38.2.3 Required JAR Files for Compiling and Running the Direct Binding Java Client Code

The following JAR file is required for compiling the direct binding Java client code:

  • $FMWHOME/soa/soa/modules/oracle.soa.mgmt_11.1.1/soa-infra-mgmt.jar

The following JAR files are required for running the direct binding Java client code:

  • $FMWHOME/wlserver/server/lib/wlthint3client.jar

  • $FMWHOME/soa/soa/modules/oracle.soa.fabric_11.1.1/oracle-soa-client-api.jar

38.2.4 SOA Direct Address Syntax

The service paths used with the Direct Binding Invocation API follow the SOA direct address pattern:

  • soadirect:/CompositeDN/serviceName, where CompositeDN stands for composite distinguished name

In the SOA direct address, the CompositeDN has the following form (label is optional):

domainName/compositeName[!compositeVersion[*label]]

38.2.5 SOA Transaction Propagation

Direct binding supports the SOA transaction propagation feature. You can invoke this feature from the client in the following ways:

  • Begin the Java transaction from the client and, after performing all the database operations, perform a commit. You should commit the database operations after a successful commit from the client side.

  • Begin the Java transaction from the client side. If a fault is thrown during any operation in the SOA composite, then roll back the transaction from the client side. This rolls back all the database operations.

38.3 Exception Handling with SOA Direct Transport

For Oracle BPEL to be able to catch SOAP faults thrown using the SOA-Direct binding, the SOAP Fault has to follow some guidelines. Suppose your service is defined by the following WSDL port and has a namespace of http://www.example.org/MyService:

<wsdl:portType name="MyServicePortType">
<wsdl:operation name="Execute">
<wsdl:input message="exp:ExecuteRequestMsg"/>
<wsdl:output message="exp:ExecuteResponseMsg"/>
<wsdl:fault name="executeFault" message="exp:ExecuteFaultMsg"/>
<wsdl:fault name="genericFault" message="exp:GenericFaultMsg"/>
</wsdl:operation>
</wsdl:portType>
When throwing a SOAP Fault, you must include the qualified name of the fault as declared in the WSDL port. For SOAP 1.1 messages, the QName of the WSDL port fault should be included in the faultcode element as seen bellow:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
	<soapenv:Body>
		<soapenv:Fault xmlns:ns0="http://www.example.org/MyService">
		<faultcode>ns0:genericFault</faultcode>
		<faultstring/>
		<faultactor/>
		<detail>
			<GenericFault xmlns="http://www.example.org/FaultInfo">
			<FaultInfo>
				<ErrorDescription>Error - soap1.1</ErrorDescription>
			</FaultInfo>
			</GenericFault>
		</detail>
		</soapenv:Fault>
	</soapenv:Body>
</soapenv:Envelope> 
For SOAP 1.2 messages, the QName of the WSDL port fault should be included in the Code/Subcode/Value element as seen below:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
	<soap:Header xmlns:exem="http://www.example.org/MyService"/>
	<soap:Body xmlns:exem="http://www.example.org/MyService">
		<soap:Fault>
			<soap:Fault>
				<soap:Value>soap:Receiver</soap:Value>
				<soap:Subcode>
					<soap:Value  xmlns:ns1=" soap:value>"="" target="_blank">http://www.example.org/MyService">ns1:genericFault</soap:Value>
				</soap:Subcode>
			</soap:Code>
			<soap:Reason>
				<soap:Text xml:lang="pt">Failure calling partner.</soap:Text>
			</soap:Reason>
			<soap:Node>...</soap:Node>
			<soap:Detail>
				<err:GenericFault xmlns:err="http://www.example.org/FaultInfo">
					<err:FaultInfo>
						<err:ErrorDescription>Error Desc</err:ErrorDescription>
					</err:FaultInfo>
				</err:GenericFault>
			</soap:Detail>
		</soap:Fault>

	</soap:Body>
</soap:Envelope>

38.4 Invoking a SOA Composite Application in Oracle JDeveloper with the Invocation API

The Direct icon in the Components window in Oracle JDeveloper, as shown in Figure 38-3, provides support for exchanging SOA messages with SOA over RMI.

Figure 38-3 Direct Binding Option

Description of Figure 38-3 follows
Description of "Figure 38-3 Direct Binding Option"

Oracle JDeveloper supports creating a direct service binding and a direct reference binding that invokes either an Oracle Service Bus or another SOA composite.

Note:

For a client to invoke composite services over direct binding, its class path must include both soa-infra-mgmt.jar, wlthint3client.jar, and oracle-soa-client-api.jar.

For more information about the Direct Binding Invocation API, see Introduction to the Direct Binding Invocation API.

38.4.1 How to Create an Inbound Direct Binding Service

You can invoke a SOA composite application using the Direct icon in the Components window in Oracle JDeveloper.

To create an inbound direct binding service:

  1. Open Oracle JDeveloper.
  2. From the Components window, select SOA.
  3. From the Technology list, drag the Direct icon into the Exposed Services swimlane. The Create Direct Binding dialog appears.
  4. Enter the details shown in Table 38-1.

    Table 38-1 Create Direct Binding Dialog Fields and Values

    Field Value

    Name

    Enter a name.

    Type

    Select Service from the list.

    Reference Target

    This field is disabled when defining this service in the Exposed Services swimlane.

    WSDL URL

    The URL location of the WSDL file. If you have an existing WSDL, then click the Find Existing WSDLs option. Otherwise, click Generate WSDL from schema(s).

    Port Type

    The port type of the WSDL file. You must select a port from the list.

    Callback Port Type

    The callback port type for asynchronous processes.

    Use SSL For Callback

    Select to use SSL for the callback.

    Address

    This field is automatically populated when the WSDL is concrete and it has at least one binding that is direct.

    Provider URL

    This field is automatically populated when the WSDL is concrete and it has at least one binding that is direct.

    Use local JNDI Provider

    Select to use the local JNDI provider.

    copy wsdl and its dependent artifacts into the project

    Deselect this check box. If you select this check box, the local copies of the WSDL file may result in synchronization issues if a remote WSDL is updated.

    When complete, the Create Direct Binding dialog appears as shown in Figure 38-4.

    Figure 38-4 Create Direct Binding Dialog

    Description of Figure 38-4 follows
    Description of "Figure 38-4 Create Direct Binding Dialog"
  5. Click OK.

    The direct binding service displays in the SOA Composite Editor shown in Figure 38-5. The single arrow in a circle indicates that this is a synchronous, one-way, direct binding component.

    Figure 38-5 Direct Binding Service

    Description of Figure 38-5 follows
    Description of "Figure 38-5 Direct Binding Service"

38.4.2 How to Create an Outbound Direct Binding Reference

You can create an outbound direct binding reference using the Direct icon in the Components window in Oracle JDeveloper to either invoke a SOA composite application or an Oracle Service Bus.

Note:

When Oracle SOA Suite and Oracle Service Bus are in different domains, you must enable trust between the domains.

To create an outbound direct binding reference:

  1. Open Oracle JDeveloper.
  2. From the Components window, select SOA.
  3. From the Technology list, drag the Direct icon into the External References swimlane. The Create Direct Binding dialog appears.
  4. Enter the details shown in Table 38-2.

    Table 38-2 Create Direct Binding Dialog Fields and Values

    Field Value

    Name

    Enter a name.

    Type

    Select Reference from the list.

    Reference Target

    Select the reference target on which you want the direct binding service to operate:

    • Oracle SOA Composite: Creates a direct binding with a SOA composite application as a reference target.

    • Oracle Service Bus: Creates a direct binding with an Oracle Service Bus as a reference target.

    WSDL URL

    The URL location of the WSDL file. If you have an existing WSDL, then click the Find Existing WSDLs option.

    Port Type

    The port type of the WSDL file. You must select a port from the list.

    Callback Port Type

    The callback port type for asynchronous processes.

    Use SSL For Callback

    Select to use SSL for the callback.

    Address

    This field is automatically populated when you select a concrete WSDL URL and port type. However, you must manually populate this field if a nonconcrete WSDL is provided.

    Provider URL

    This field is automatically populated when you select a concrete WSDL URL and port type. However, you must manually populate this field if a nonconcrete WSDL is provided.

    Use local JNDI Provider

    Select to use the local JNDI provider.

    copy wsdl and its dependent artifacts into the project

    Deselect this check box. If you select this check box, the local copies of the WSDL file may result in synchronization issues if a remote WSDL is updated.

    When complete, the Create Direct Binding dialog appears as shown in Figure 38-6. For more information about using the Oracle SOA Suite services with Oracle Service Bus, see Chapter "Oracle SOA Suite Transport (SOA-DIRECT)" of Developing Services with Oracle Service Bus.

    Figure 38-6 Create Direct Binding Dialog

    Description of Figure 38-6 follows
    Description of "Figure 38-6 Create Direct Binding Dialog"
  5. Click OK.

    The direct binding reference displays in the designer shown in Figure 38-7. The single arrow in a circle indicates that this is a synchronous, one-way direct binding reference component.

    Figure 38-7 Direct Binding Reference

    Description of Figure 38-7 follows
    Description of "Figure 38-7 Direct Binding Reference"

38.4.3 How to Set an Identity for J2SE Clients Invoking Direct Binding

A user identity can be established when authenticating to the server during the process of JNDI lookup by passing the JNDI security credential, as shown in the following example:

public static void main(String[] args) throws Exception {
    String operation = "process";

    // This is the request message XML
    String ns = "http://xmlns.oracle.com/DirectBinding_jws/EchoBPEL/BPELProcess1";
    String payloadXML = "<ns1:process xmlns:ns1=\"" + ns + "\">\n" +
                        "  <ns1:input>wew</ns1:input>\n" +
                        "</ns1:process>"; 

    String serviceAddress = "soadirect:/default/EchoBPEL!1.0/DService1";

    // Specify the direct binding connection properties
    Map<String, Object> props = new HashMap<String, Object>();
    props.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
    props.put(Context.PROVIDER_URL, "t3://" + hostname + ':' + portname);
    props.put(Context.SECURITY_PRINCIPAL,username);
    props.put(Context.SECURITY_CREDENTIALS, password);

    // Create the direct binding connection, using those context properties
    DirectConnectionFactory factory = JNDIDirectConnectionFactory.newInstance();

    try {
       DirectConnection dc = factory.createConnection(serviceAddress, props);

        // Parse the XML request message
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        Document doc =
          dbf.newDocumentBuilder().parse(new InputSource(new StringReader(payloadXML)));

        // Prepare the payload for inclusion in the Message object
        Map<String, Element> payload = new HashMap<String, Element>();
        payload.put("payload", doc.getDocumentElement());

        Message<Element> request = XMLMessageFactory.getInstance().createMessage(payload);

        Message<Element> response = dc.request(operation, request);
    } finally {
        dc.close();
    }
}

38.4.4 What You May Need to Know About Invoking SOA Composites on Hosts with the Same Server and Domain Names

If one SOA composite application invokes another SOA composite application on another host through direct binding, and both composites are on hosts with the same server name and domain name, the invocation fails.

This is because the Oracle WebLogic Server transaction subsystem requires the domain names and server names to be different for transaction management to work properly. The transaction subsystem uses these names to track the location of a server related to a transaction. If the two servers in the invocation have the same name, the transaction subsystem can mistakenly confuse the two servers.

Ensure that you use hosts with separate server names and domain names.

38.5 Samples Using the Direct Binding Invocation API

This section provides some examples of how the API is used. It describes how the connection parameter can invoke SOA composite applications over direct binding and how message objects can be modified to invoke a direct binding invocation.

// The JNDIDirectConnectionFactory can be used to establish SOA instance
// connections for exchanging messages over the direct binding.
DirectConnectionFactory dcFactory = JNDIDirectConnectionFactory.newInstance();

// Connections are created based on the configuration, which is a map of standard
// naming properties, which will be used for the underlying connection lookup.
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(Context.INITIAL_CONTEXT_FACTORY, jndi.WLInitialContextFactory");
properties.put(Context.PROVIDER_URL, "t3://HOST:PORT");
properties.put(Context.SECURITY_PRINCIPAL, USERNAME); 
properties.put(Context.SECURITY_CREDENTIALS, PASSWORD);
DirectConnection conn =
    dcFactory.createConnection("soadirect:/default/MyComposite!1.0/MyService",
                               properties);
// Messages are created using the MessageFactory
// Message objects are subsequently modified to be used for an invocation.
Message<Element> request = XMLMessageFactory.getInstance().createMessage();

// Define a Map of WSDL part names to matching XML Element objects
Map<String, Element> partData;

Payload<Element> payload = PayloadFactory.createXMLPayload(partData);
request.setPayload(payload);

// One-way invocation
conn.post("onewayoperation", request);

// Request-reply invocation
Message<Element> response = conn.request("requestreplyoperation", request);
Hashtable jndiProps = new Hashtable();
jndiProps.put(Context.PROVIDER_URL, "t3://" + HOST + ':' + PORT);
jndiProps.put(Context.INITIAL_CONTEXT_FACTORY,
              "weblogic.jndi.WLInitialContextFactory");
jndiProps.put(Context.SECURITY_PRINCIPAL,USERNAME); 
jndiProps.put(Context.SECURITY_CREDENTIALS, PASSWORD);
Locator locator = LocatorFactory.createLocator(jndiProps);
CompositeDN compositedn = new CompositeDN(domainName, compositename, version);
String serviceName = "HelloEntry";
DirectConnection conn = locator.createDirectConnection(compositedn, serviceName);