Oracle® Fusion Middleware Developer's Guide for Oracle SOA Suite 11g Release 1 (11.1.1.5.0) Part Number E10224-08 |
|
|
View PDF |
This chapter describes the Direct Binding Invocation API and how it can invoke SOA composite applications.
This chapter includes the following sections:
Section 37.2, "Introduction to the Direct Binding Invocation API"
Section 37.3, "Invoking a SOA Composite Application with the Invocation API"
Section 37.4, "Samples Using the Direct Binding Invocation API"
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 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.
Direct Service Binding Component
A sample configuration using the direct service binding component is shown in Example 37-1.
Example 37-1 Direct Service Binding Component
<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>
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.
ConnectionFactory
class name:
The ConnectionFactory
class must implement the oracle.soa.api.invocation.DirectConnectFactory
interface.
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 SSL for the callback JNDI connection. If this flag is set to true
, then the WSA replyTo
header instructs the service to call back at an SSL JNDI port.
A sample configuration is shown in Example 37-2.
Example 37-2 Sample Configuration
<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 37-1 describes a sample synchronous invocation pattern and Figure 37-2 describes a sample asynchronous invocation pattern.
Figure 37-1 Sample Synchronous Invocation Patterns
Figure 37-2 Sample Asynchronous Invocation Pattern
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 Example 37-3 for returning the DirectConnection
.
Example 37-3 oracle.soa.management.facade.Locator
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 Example 37-4.
Example 37-4 LocatorFactory Implementation
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.
The DirectConnection.java
is shown in Example 37-5.
Example 37-5 DirectConnection.java
import oracle.soa.api.message.Message; public interface DirectConnection { <T> Message<T> request(String operationName, Message<T> message) throws InvocationException, FaultException; <T> void post(String operationName, Message<T> message) throws InvocationException; void close();}
oracle.soa.api.message.Message
The Message
interface encapsulates the data exchanged.
The Message
interface.java
is shown in Example 37-6.
Example 37-6 Message interface.java
import java.util.List; import java.util.Map; import org.w3c.dom.Element; public interface Message<T> { // Instance-tracking property names final static String FLOW_ID; final static String CONVERSATION_ID; final static String PARENT_ID; void setPayload(Payload<T> payload); Payload<T> getPayload(); void addAttachment(Attachment attachment); List<Attachment> getAttachments(); void addHeader(Element header); void setHeaders(List<Element> headers); List<Element> getHeaders(); void setProperties(Map<String, Object> properties); void setProperty(String name, Object value); Map<String, Object> getProperties(); Object getProperty(String name); }
For more information about the Facades API, see Oracle Fusion Middleware Infrastructure Management Java API Reference for Oracle SOA Suite.
Direct binding also supports the Synchronous Direct Invocation with the usage of the method shown in Example 37-7.
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.
Note:
The supported addressing version includes:An example of the WS-Addressing header used for asynchronous invocation is shown in Example 37-8.
Example 37-8 WS-Addressing Header
<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:
tracking.conversationId
= D6202742-D9D9-4023-8167-EF0AB81042E
replyToAddress
= sb://testserver:9001/callback
replyToReferenceParameter
: element of WSA:ReferenceParameters
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:
domainName/compositeName[!compositeVersion[*label]]
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 back during any operation in the SOA composite, then roll back the transaction from the client side. This rolls back all the database operations.
The Direct Binding component in Oracle JDeveloper, as shown in Figure 37-3, provides support for exchanging SOA messages with SOA over RMI.
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 bothsoa-infra-mgmt.jar
and oracle-soa-client-api.jar
.For more information about the Direct Binding Invocation API, see Section 37.2, "Introduction to the Direct Binding Invocation API."
You can invoke a SOA composite application using the Direct Binding option in Oracle JDeveloper.
To create an inbound direct binding service:
Open Oracle JDeveloper.
From the Component Palette, select SOA.
From the Service Adapters list, drag the Direct Binding component into the Exposed Services swimlane. The Create Direct Binding dialog appears.
Enter the details shown in Table 37-1.
Table 37-1 Direct Binding Service 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 checkbox. If you select this checkbox, 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 37-4.
Click OK.
The direct binding service displays in the SOA Composite Editor shown in Figure 37-5. The single arrow in a circle indicates that this is a synchronous, one-way, direct binding component.
You can create an outbound direct binding reference, using the Direct Binding option in Oracle JDeveloper, to either invoke a composite application or an Oracle Service Bus.
To create an outbound direct binding reference:
Open Oracle JDeveloper.
From the Component Palette, select SOA.
From the Service Adapters list, drag the Direct Binding component into the External References swimlane. The Create Direct Binding dialog appears.
Enter the details shown in Table 37-2.
Table 37-2 Direct Binding Service 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:
|
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 checkbox. If you select this checkbox, 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 37-6. For more information about using the Oracle SOA Suite services with Oracle Service Bus, see the Oracle SOA Suite Transport (SOA-DIRECT) chapter in Oracle Fusion Middleware Developer's Guide for Oracle Service Bus.
Click OK.
The direct binding reference displays in the designer shown in Figure 37-7. The single arrow in a circle indicates that this is a synchronous, one-way direct binding reference component.
J2SE clients can set an identity while invoking direct binding, as shown in Example 37-9.
Example 37-9 Identity Setup for J2SE Clients Invoking Direct Binding
public static void main(String[] args) throws Exception { Invoker invoker = new Invoker(); String payloadXML="<ns1:process xmlns:ns1=\"http://xmlns.oracle.com/DirectBinding_jws/EchoBPEL/BPELProcess1\"> " +"\n" + "<ns1:input>wew</ns1:input>" + "\n"+ "</ns1:process>" ; String serviceAddress = "soadirect:/default/EchoBPEL!1.0/DService1"; System.out.println("***** test Sync ****"); DirectConnectionFactory factory = JNDIDirectConnectionFactory.newInstance(); Message<Element> m = getAsyncRequest(payloadXML); 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,"xtest-soa1-user"); props.put(Context.SECURITY_CREDENTIALS,"welcome1"); DirectConnection conn = factory.createConnection(serviceAddress, props); DirectConnection conn = getConnection(serviceAddress); Document doc = DirectBindingXMLUtil.getDocumentFromString(payloadXML); Element element = doc.getDocumentElement(); Map<String, Element> payload = new HashMap<String, Element>(); payload.put("payload", element); Message<Element> m = XMLMessageFactory.getInstance().createMessage(payload); List<Element> headers = createWSAHeaders("payload:BPELSyncTest:msgID:1234567"); for( Element e : headers) m.addHeader(e); try { ctx = new InitialContext(props); conn.request("process", m); } finally { if (null != ctx) ctx.close(); } //System.out.println(ret); }
The key points in the above example are as follows:
The creation of an InitialContext
with the security principal/principal credentials before invoking the direct connection; this achieves a login.
The close of the InitialContext
; this achieves the log out.
try { ctx = new InitialContext(props); conn.request("process", m); } finally { if (null != ctx) ctx.close(); }
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.
Example 37-10 through Example 37-12 provide some examples of how the API is used. This section 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.
Example 37-10 Usage of a Connection Parameter
// 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, "weblogic.jndi.WLInitialContextFactory"); properties.put(Context.PROVIDER_URL, "t3://HOST:PORT"); DirectConnection conn = dcFactory.createConnection("soadirect:/default/MyComposite!1.0/MyService", properties);
Example 37-11 Usage of Messages
//Messages are created using the MessageFactory Message<Element> request = XMLMessageFactory.getInstance().createMessage(); //Message objects are then modified to be used for an invocation Map<String, Element> partData; // Define a Map of WSDL part names to matching XML Element objects 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);
Example 37-12 Usage of LocatorFactory
//A Sample Java Code 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);