Use a top-down approach to develop SCA components that use SDO
Use a top-down approach that starts from WSDL or XML definition files to develop Service Component Architecture (SCA) component implementations that use Service Data Objects (SDO) 2.1.1 (JSR 235).
Consider installing a Rational Application Developer product with SCA Development Tools that we can use to assemble service-oriented application components based on open SCA specifications. See the Rational Application Developer documentation.
Access the default HelperContext programmatically in a Java or JEE (Java EE) component implementation type. Complete step 1 of Use SDO 2.1.1 in SCA applications.
The steps describe how to develop SCA composites that use SDO following a top-down approach.
Unless otherwise specified, the steps describe how to develop both OSOA and OASIS SCA composites that use SDO.
- Describe the service interface in the WSDL and XSD definition files.
The following example WSDL and XSD files describe a service interface.
- Example WSDL file, test.wsdl
<?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions targetNamespace="http://test" xmlns:tns="http://test" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="Test"> <wsdl:types> <schema targetNamespace="http://test" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:p="http://person"> <import namespace="http://person" schemaLocation="person.xsd"/> <element name="updateAccount"> <complexType> <sequence> <element name="person" type="p:Person"/> <element name="code" type="xsd:string"/> </sequence> </complexType> </element> <element name="updateAccountResponse"> <complexType> <sequence> <element name="response" type="p:Status"/> </sequence> </complexType> </element> </schema> </wsdl:types> <wsdl:message name="PersonRequestMessage"> <wsdl:part element="tns:updateAccount" name="parameters"/> </wsdl:message> <wsdl:message name="PersonResponseMessage"> <wsdl:part element="tns:updateAccountResponse" name="parameters"/> </wsdl:message> <wsdl:portType name="Test"> <wsdl:operation name="updateAccount"> <wsdl:input message="tns:PersonRequestMessage" name="ReqMsgName"/> <wsdl:output message="tns:PersonResponseMessage" name="RespMsgName"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="TestSoapBinding" type="tns:Test"> <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="updateAccount"> <wsdlsoap:operation soapAction="urn:updateAccount"/> <wsdl:input name="ReqMsgName"> <wsdlsoap:body use="literal"/> </wsdl:input> <wsdl:output name="RespMsgName"> <wsdlsoap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="TestService"> <wsdl:port binding="tns:TestSoapBinding" name="TestSoapPort"> <wsdlsoap:address location=""/> </wsdl:port> </wsdl:service> </wsdl:definitions>
- Example XSD file, person.xsd, that test.wsdl imports
<?xml version="1.0" encoding="UTF-8"?> <schema targetNamespace="http://person" xmlns="http://www.w3.org/2001/XMLSchema"> <complexType name="Person"> <sequence> <element name="firstName" type="string"/> <element name="lastName" type="string"/> </sequence> </complexType> <complexType name="Status"> <sequence> <element name="statusCode" type="int"/> <element name="message" type="string"/> </sequence> </complexType> </schema>
- Produce a corresponding Java interface.
For an IBM Rational tool that supports SCA, we do not need to complete this step. The tool generates the code for you. Proceed to step 3.
If we are not using a Rational tool that supports SCA, we can manually produce a Java interface from a WSDL file by completing this step 2, which provides an example that modifies generated code. There is not an automated tool to produce a Java interface from a command-line interface.
- Identify the WSDL and XSD files from which to produce Java interfaces.
This example uses the test.wsdl and person.xsd files in step 1.
- Run the wsimport command with the -s option to save source files.
wsimport.bat -s . test.wsdl
- Among the generated Java files, identify the SEI.
The SEI is a Java interface, and not a class file, with a class-level @WebService annotation, javax.jws.WebService.
In this example, the Java interface is the test/Test.java file. Running the wsimport command produces the following output:
// // Generated By:JAX-WS RI, IBM 2.1.1 in JDK 6 (JAXB RI, IBM JAXB 2.1.3 in JDK 1.6) // package test; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.xml.bind.annotation.XmlSeeAlso; import javax.xml.ws.RequestWrapper; import javax.xml.ws.ResponseWrapper; import person.Person; import person.Status; @WebService(name = "Test", targetNamespace = "http://test") @XmlSeeAlso({ person.ObjectFactory.class, test.ObjectFactory.class }) public interface Test { /** * * @param person * @param code * @return * returns person.Status */ @WebMethod(action = "urn:updateAccount") @WebResult(name = "response", targetNamespace = "") @RequestWrapper(localName = "updateAccount", targetNamespace = "http://test", className = "test.UpdateAccount") @ResponseWrapper(localName = "updateAccountResponse", targetNamespace = "http://test", className = "test.UpdateAccountResponse") public Status updateAccount( @WebParam(name = "person", targetNamespace = "") Person person, @WebParam(name = "code", targetNamespace = "") String code); }
- Modify the SEI.
- For all parameter and return values of generated (JAXB) types, change the Java type to commonj.sdo.DataObject. All complex schema types must map to commonj.sdo.DataObject Java types. Also, remove all imports of these generated JAXB types.
- For each @RequestWrapper and @ResponseWrapper annotation, change the value of the className element to commonj.sdo.DataObject. Otherwise, leave the JAX-WS annotations because they are significant.
- Remove or comment out the @XmlSeeAlso block.
Complete these steps results in the following Java interface:
// // Generated By:JAX-WS RI, IBM 2.1.1 in JDK 6 (JAXB RI, IBM JAXB 2.1.3 in JDK 1.6) // package test; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.xml.bind.annotation.XmlSeeAlso; import javax.xml.ws.RequestWrapper; import javax.xml.ws.ResponseWrapper; import commonj.sdo.DataObject; @WebService(name = "Test", targetNamespace = "http://test") public interface Test { /** * * @param person * @param code * @return * returns person.Status */ @WebMethod(action = "urn:updateAccount") @WebResult(name = "response", targetNamespace = "") @RequestWrapper(localName = "updateAccount", targetNamespace = "http://test", className = "commonj.sdo.DataObject") @ResponseWrapper(localName = "updateAccountResponse", targetNamespace = "http://test", className = "commonj.sdo.DataObject") public DataObject updateAccount( @WebParam(name = "person", targetNamespace = "") DataObject person, @WebParam(name = "code", targetNamespace = "") String code); }The following example shows the resulting code with JAX-WS annotations removed for readability only. Do not remove the annotations before compiling to use the example code.
package test; import commonj.sdo.DataObject; public interface Test { public DataObject updateAccount(DataObject person, String code); }
- Write the SCA Java client or component implementation using the dynamic SDO programming model.
The following example code shows a service implementation in Java. Read the source comments carefully to see the differences between OSOA and OASIS.
package test.impl; import test.Test; // FOR OSOA import org.osoa.sca.annotations.Service; // FOR OASIS, commented out // import org.oasisopen.sca.annotation.Service; import commonj.sdo.DataObject; import commonj.sdo.helper.DataFactory; import commonj.sdo.helper.HelperContext; import com.ibm.websphere.soa.sca.sdo.DefaultHelperContext; @Service(Test.class) public class TestImpl implements Test { @DefaultHelperContext protected HelperContext myDefaultHC; public DataObject updateAccount(DataObject person, String code) { String error_msg = null; if (code.equals("ERROR_STRING_IN_FIELD1")) { error_msg = "ERROR firstName: " + person.getString("firstName"0); HelperContext defaultHC = ContextHelper.getCurrentHelperContext(); DataFactory dataFactory = myDefaultHCdefaultHC.getDataFactory(); DataObject returnDO = dataFactory.create("http://person","Status"); returnDO.setInt("statusCode", -1); returnDO.setString("message", error_msg); return returnDO; } else { // process(person); ... } } }The input person DataObject is of type {http://person}Person. The returned output DataObject is of type {http://person}Status. Both the input and output are registered in the SCA application default HelperContext that is accessed using the myDefaultHC object.
- In a composite definition, declare the component reference or component service interface with an <interface.wsdl> element that refers to the original portType value.
- Example accountTest.composite file for OSOA
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" targetNamespace="http://www.ibm.com/test/soa/sca/sdo/" name="AccountTestComposite"> <component name="AccountTestComponent"> <implementation.java class="test.impl.TestImpl"/> <service name="Test"> <interface.wsdl interface="http://test#wsdl.interface(Test)"/> </service> ... </component> </composite>
- Example accountTest.composite file for OASIS
<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" targetNamespace="http://www.ibm.com/test/soa/sca/sdo/" name="AccountTestComposite"> <component name="AccountTestComponent"> <implementation.java class="test.impl.TestImpl"/> <service name="Test"> <interface.wsdl interface="http://test#wsdl.interface(Test)"/> </service> ... </component> </composite>
- Package the composite and deploy the component with the authored implementation along with the WSDL or XSD files into a single contribution JAR file.
Suppose the example files are packaged into a single file, MyAccountTestContribution.jar. A listing of the JAR file contents from the command line is as follows:
$ jar tf MyAccountTestContribution.jar wsdl/test.wsdl wsdl/person.xsd test/Test.class test/impl/TestImpl.class META-INF/accountTest.composite META-INF/sca-contribution.xml
Results
You have developed an SCA composite that uses SDO following a top-down approach.
What to do next
Optionally, implement shared scopes. See the topic on using SDO 2.1.1 in SCA applications.
Deploy the files that use SDO in an SCA business-level application.
Related concepts
SDO data binding for SCA applications
Related tasks
Use SDO 2.1.1 in SCA applications
Related information: