Data bindings and their relationship to imports, exports, messages and data objects are discussed in this section.
Data bindings handle the transformation of data passed as a Service Data Object (SDO) in a Service Component Architecture-based (SCA) application and the native format for an EIS J2C or messaging JMS system. The data binding function handles the request and response arguments for both inbound and outbound communication. Data bindings are described in chapter 9 of the Enterprise Metadata Discovery specification. This joint specification from IBM and BEA introduces a new metadata discovery and import model for resource adapters and the enterprise application integration (EAI) tools framework. The model allows resource adapters to plug into an integration framework and improves the usability of adapters within the framework. This specification also includes API information on methods discussed in this section.
public interface DataBinding extends Serializable { public DataObject getDataObject() throws DataBindingException; public void setDataObject(DataObject dataObject) throws DataBindingException; }
From a service binding, there are three specializations provided: one for J2EE Connector Architecture (J2C), one for JMS and one for MQ.
When an EIS or messaging import is invoked, a data binding is used to transform the content of a Service Data Object (SDO) into the native format of the EIS or messaging system by the SCA runtime, and when the reply (if any) is received from the EIS or messaging import, the data binding is used to transform the native data format into an SDO. When an EIS or messaging export is invoked, a data binding is used to transform the native data format into an SDO, and when the reply (if any) is sent back to the caller a data binding is used to transform the content of the SDO into the native format of the EIS or messaging system. SDOs in the SCA environment are business objects.
A data binding can be specified in the root portion of an import or export binding. This simplifies the model when a common data binding is used for all input and output arguments of the binding. A specific data binding can also be specified on the method binding for input and output arguments. A data binding specified at the method level takes precedence over the data binding specified at the root level of the binding.
For EIS, a data binding generator can also be specified for the EIS import or export binding. The data binding generator must be specified in the root portion. The EIS SCA implementation will then use it to generate a data binding for each input and output argument.
A data binding generator can also be used with JMS.
In the case of a JMS export binding, the format and structure of each incoming message must be known by the data binding implementation, which turns it into a data object (DataObject object). In the case of a JMS import binding, the reverse occurs; namely, the outgoing data object is turned into the JMS message that is sent to the external service. The data binding defined for the JMS Service must implement the com.ibm.websphere.sca.jms.data.JMSDataBinding interface shown below.
public interface JMSDataBinding extends DataBinding { public void read(javax.jms.Message message) throws javax.jms.JMSException; public void write(javax.jms.Message message) throws javax.jms.JMSException; public int getMessageType(); public boolean isBusinessException(); public void setBusinessException(boolean isBusinessException); static public int OBJECT_MESSAGE = 0; static public int TEXT_MESSAGE = 1; static public int BYTES_MESSAGE = 2; static public int STREAM_MESSAGE = 3; static public int MAP_MESSAGE = 4; static public int JMS_MESSAGE = 5; }
An example of using the JMSDataBinding can be seen in Creating a user-defined JMS data binding.
Fault handling using these methods could be implemented in a similar manner to the following code:
public class Foo implements JMSDataBinding { private boolean fieldIsBusinessException = false; public boolean isBusinessException() { return fieldIsBusinessException; } public void setBusinessException(boolean isBusinessException) { this.fieldIsBusinessException = isBusinessException; } public void read(Message message) throws JMSException { ... if(message.propertyExists("IsBusinessException")){ this.fieldIsBusinessException = message.getBooleanProperty("IsBusinessException"); } else{ // Unknown other side, default to false this.fieldIsBusinessException = false; } } public void write(Message message) throws JMSException { ... message.setBooleanProperty("IsBusinessException", this.fieldIsBusinessException); } }
com.ibm.websphere.sca.ServiceManager serviceManager = new com.ibm.websphere.sca.ServiceManager(); com.ibm.websphere.bo.BOFactory factory = (com.ibm.websphere.bo.BOFactory)serviceManager.locateService("com/ibm/websphere/bo/BOFactory"); DataObject dataObject = factory.create("http://CICSTest/data", "Taderc99");
The MQ JMS data bindings are similar to the JMS data bindings. The default data bindings are serialized business object using JMSObjectMessage and business object XML using JMSTextMessage, which use the com.ibm.websphere.sca.jms.data.impl.JMSDataBindingImplJava and com.ibm.websphere.sca.jms.data.impl.JMSDataBindingImplXML respectively. A user supplied data binding allows you to specify your own data binding, though it must conform to the JMS data binding interface. The message content of an MQ JMS data binding is accessed through the JMS API.
WebSphere MQ has its own unique set of data bindings, which are discussed in MQ data bindings.
The expected argument that will be passed to the JMSDataBinding and JMSObjectBinding depend on the interface operation and the input, output and fault types. In the export case, this is the expected payload of the JMS message that should be coming on the incoming JMS destination.
For faults, the outDataBindingType specified on the method binding is used. If none is specified, the binding level dataBindingType is used for all serialization and deserialization.
For non-Document-Literal wrapped style interfaces, there is no unwrapping and the expected arguments to the data bindings are the input and output of the operations.
For Document-Literal wrapped style interfaces the argument is unwrapped and the underlying data is passed.
The following sections show the various mappings.
WSDL interface operation for request-response operation using document literal wrapped style with a single argument
<xsd:element name="loginAccount"> <xsd:complexType> <xsd:sequence> <xsd:element name="credentials" nillable="true" type="bons1:CredentialsBO" /> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="loginAccountResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="response" nillable="true" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="loginAccount_fault1" type="xsd:string" /> </wsdl:types> <wsdl:message name="loginAccountRequestMsg"> <wsdl:part element="tns:loginAccount" name="loginAccountParameters" /> </wsdl:message> <wsdl:message name="loginAccountResponseMsg"> <wsdl:part element="tns:loginAccountResponse" name="loginAccountResult" /> </wsdl:message> <wsdl:message name="loginAccount_fault1Msg"> <wsdl:part element="tns:loginAccount_fault1" name="fault1" /> </wsdl:message> <wsdl:operation name="loginAccount"> <wsdl:input message="tns:loginAccountRequestMsg" name="loginAccountRequest" /> <wsdl:output message="tns:loginAccountResponseMsg" name="loginAccountResponse" /> <wsdl:fault message="tns:loginAccount_fault1Msg" name="credentialsError" /> </wsdl:operation>
Operation and input and output type
WSDL interface operation for one-way operation using document literal wrapped style with a single argument
<xsd:element name="selectAccount"> <xsd:complexType> <xsd:sequence> <xsd:element name="accountName" nillable="true" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:element> </wsdl:message> <wsdl:message name="selectAccountRequestMsg"> <wsdl:part element="tns:selectAccount" name="selectAccountParameters" /> </wsdl:message> <wsdl:operation name="selectAccount"> <wsdl:input message="tns:selectAccountRequestMsg" name="selectAccountRequest" /> </wsdl:operation>
Operation and input and output type
WSDL interface operation for request-response operation using document literal wrapped style with multiple arguments
<xsd:element name="updateAccount"> <xsd:complexType> <xsd:sequence> <xsd:element name="performCredit" nillable="true" type="xsd:boolean" /> <xsd:element name="amount" nillable="true" type="xsd:float" /> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="updateAccountResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="balance" nillable="true" type="xsd:float" /> </xsd:sequence> </xsd:complexType> </xsd:element> </wsdl:message> <wsdl:message name="updateAccountRequestMsg"> <wsdl:part element="tns:updateAccount" name="updateAccountParameters" /> </wsdl:message> <wsdl:message name="updateAccountResponseMsg"> <wsdl:part element="tns:updateAccountResponse" name="updateAccountResult" /> </wsdl:message> <wsdl:message name="updateAccount_fault1Msg"> <wsdl:part element="tns:updateAccount_fault1" name="fault1" /> </wsdl:message> <wsdl:operation name="updateAccount"> <wsdl:input message="tns:updateAccountRequestMsg" name="updateAccountRequest" /> <wsdl:output message="tns:updateAccountResponseMsg" name="updateAccountResponse" /> <wsdl:fault message="tns:updateAccount_fault1Msg" name="insufficientFunds" /> </wsdl:operation>
Operation and input and output type
WSDL interface operation for request-response operation using document literal wrapped style with multiple arguments of mixed types
<xsd:element name="updateAccount2"> <xsd:complexType> <xsd:sequence> <xsd:element name="performCredit" nillable="true" type="xsd:boolean" /> <xsd:element name="amount" nillable="true" type="xsd:float" /> <xsd:element name="dummyInfo" nillable="true" type="bons1:DummyBO" /> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="updateAccount2Response"> <xsd:complexType> <xsd:sequence> <xsd:element name="balance" nillable="true" type="xsd:float" /> </xsd:sequence> </xsd:complexType> </xsd:element> </wsdl:message> <wsdl:message name="updateAccount_fault1Msg"> <wsdl:part element="tns:updateAccount_fault1" name="fault1" /> </wsdl:message> <wsdl:message name="updateAccount2RequestMsg"> <wsdl:part element="tns:updateAccount2" name="updateAccountParameters" /> </wsdl:message> <wsdl:message name="updateAccount2ResponseMsg"> <wsdl:part element="tns:updateAccount2Response" name="updateAccountResult" /> </wsdl:message> <wsdl:operation name="updateAccount2"> <wsdl:input message="tns:updateAccount2RequestMsg" name="updateAccount2Request" /> <wsdl:output message="tns:updateAccount2ResponseMsg" name="updateAccount2Response" /> <wsdl:fault message="tns:updateAccount_fault1Msg" name="insufficientFunds" /> </wsdl:operation>
Operation and input and output type
WSDL interface operation for request-response operation using document literal wrapped style with a no arguments
<xsd:element name="getCustomerInfo"> <xsd:complexType> <xsd:sequence /> </xsd:complexType> </xsd:element> <xsd:element name="getCustomerInfoResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="result" nillable="true" type="bons1:CustomerInfoBO" /> </xsd:sequence> </xsd:complexType> </xsd:element> </wsdl:message> <wsdl:message name="getCustomerInfoRequestMsg"> <wsdl:part element="tns:getCustomerInfo" name="getCustomerInfoParameters" /> </wsdl:message> <wsdl:message name="getCustomerInfoResponseMsg"> <wsdl:part element="tns:getCustomerInfoResponse" name="getCustomerInfoResult" /> </wsdl:message> <wsdl:operation name="getCustomerInfo"> <wsdl:input message="tns:getCustomerInfoRequestMsg" name="getCustomerInfoRequest" /> <wsdl:output message="tns:getCustomerInfoResponseMsg" name="getCustomerInfoResponse" /> </wsdl:operation>
Operation and input and output type
WSDL interface operation for request-response operation using document literal wrapped style with a data object
<xsd:element name="updateCustomerInfo"> <xsd:complexType> <xsd:sequence> <xsd:element name="customerInfo" nillable="true" type="bons1:CustomerInfoBO" /> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="updateCustomerInfoResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="result" nillable="true" type="bons1:CustomerInfoBO" /> </xsd:sequence> </xsd:complexType> </xsd:element> </wsdl:message> <wsdl:message name="updateCustomerInfoRequestMsg"> <wsdl:part element="tns:updateCustomerInfo" name="updateCustomerInfoParameters" /> </wsdl:message> <wsdl:message name="updateCustomerInfoResponseMsg"> <wsdl:part element="tns:updateCustomerInfoResponse" name="updateCustomerInfoResult" /> </wsdl:message> <wsdl:operation name="updateCustomerInfo"> <wsdl:input message="tns:updateCustomerInfoRequestMsg" name="updateCustomerInfoRequest" /> <wsdl:output message="tns:updateCustomerInfoResponseMsg" name="updateCustomerInfoResponse" /> </wsdl:operation>
Operation and input and output type
WSDL interface operation for request-response operation using document literal wrapped style with two data object arguments
<xsd:element name="updateCustomerInfo2"> <xsd:complexType> <xsd:sequence> <xsd:element name="customerInfo" nillable="true" type="bons1:CustomerInfoBO" /> <xsd:element name="dummyInfo" nillable="true" type="bons1:DummyBO" /> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="updateCustomerInfo2Response"> <xsd:complexType> <xsd:sequence> <xsd:element name="result" nillable="true" type="bons1:CustomerInfoBO" /> </xsd:sequence> </xsd:complexType> </xsd:element> </wsdl:message> <wsdl:message name="updateCustomerInfo2RequestMsg"> <wsdl:part element="tns:updateCustomerInfo2" name="updateCustomerInfoParameters" /> </wsdl:message> <wsdl:message name="updateCustomerInfo2ResponseMsg"> <wsdl:part element="tns:updateCustomerInfo2Response" name="updateCustomerInfoResult" /> <wsdl:operation name="updateCustomerInfo2"> <wsdl:input message="tns:updateCustomerInfo2RequestMsg" name="updateCustomerInfo2Request" /> <wsdl:output message="tns:updateCustomerInfo2ResponseMsg" name="updateCustomerInfo2Response" /> </wsdl:operation> </wsdl:message>
Operation and input and output type
Object set on JMS data binding and support
WSDL interface operation for request-response operation with a data object representing a JmsQuote data element
<wsdl:types> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:import namespace="http://jms.quote.data" schemaLocation="JmsQuote.xsd"> </xsd:import> </xsd:schema> </wsdl:types> <wsdl:message name="JmsQuoteRequest"> <wsdl:part name="request" element="data:JmsQuote"></wsdl:part> </wsdl:message> <wsdl:message name="JmsQuoteReply"> <wsdl:part name="request" element="data:JmsQuote"></wsdl:part> </wsdl:message> <wsdl:portType name="JmsQuotePT"> <wsdl:operation name="getJmsQuote"> <wsdl:input message="tns:JmsQuoteRequest"></wsdl:input> <wsdl:output message="tns:JmsQuoteReply"></wsdl:output> </wsdl:operation> </wsdl:portType>
Operation and input and output type
A data binding generator is an implementation class, which at application assembly time will generate a type specific data binding implementation for an input or output parameter of a particular operation. The data binding generator generates a standard implementation class unlike the unique custom data binding. It automates the process of implementing a data binding.
The generator is invoked during application assembly, when the artifacts needed to deploy SCA module are generated. This approach ensures the data binding implementation is always matching the latest version of the possibly edited type (schema). The commonj.connector.metadata.description.DataBindingGenerator interface is presented below:
public interface DataBindingGenerator { public DataBindingDescription[] generateDataBinding( QName complexType, URL schema) throws MetadataException; }
For the generateDataBinding() method, it passes as arguments the QName of the input or output complexType and the URL of its schema. The complexType QName refers to a global complexType. The DataBindingGenerator implementation is then responsible for loading the schema, including resolving any schema imported or included. It then finds the complex type definition specified by the QName, and by looking at it or annotations in the schema generates one or more data bindings to handle the complex type definition.
For the generator to be found at application assembly time, it must be registered by using the extension point "connector.metadata.databinding_generator" or be supplied by and be in the classpath of the resource adapter. The class name is specified in the root portion of an import or export binding. The lookup depends if the generator was registered by extension point, or is part of the resource adapter. If it is registered by extension point, the regular Eclipse extension point mechanisms are used to load the class. If the generator is part of the resource adapter, then the lookup for the generator class is done using the class name and looking in the classes supplied by the resource adapter. So the lookup is for a specific class on the classpath of the resource adapter.
An example of this extension is as follows:
<extension point="connector.metadata.databinding_generator"> <databinding_generator class="com.xyz.DataBindingGenerator" name="My Generator" id="com.xyz.DataBindingGenerator"/> </extension>