Tuscany SCA for C++ - Enabling Axis2C Web Services

This document describes the deployment and use of the Axis2C Web Service (binding.ws) service support in the Apache Tuscany SCA C++ runtime.

The WS service code is based on Apache Axis2C version 0.94 and allows SCA components to be invoked via Web Service calls.

WS service currently supports Document/literal Wrapped style Web Services only. There are also restrictions about the parameter and return types of the operations in SCA components that can be exposed as Web Services, see below for more details.

See the SCA Web Service binding specification for more details about SCA Web Service support.

Also, see the samples for various demonstrations of the use of the binding.ws service support.

Deploying the Tuscany Web Service support to Axis2C

Deploying via scripts

Tuscany provides simple shell scripts to deploy the Web Service support to Axis2C. However, the script will overwrite your Axis2C axis.xml file, so if you have altered your axis2.xml from the default provided by the Axis2C distribution, it is recommended that you follow the manual deployment steps outlined below.

To automatically deploy Tuscany Web Service support to Axis2C on Linux:

  1. The AXIS2C_HOME environment variable is required:
    • set AXIS2C_HOME=<path to axis2c version 0.94>
  2. Use the following command sequence to run the deploy script:
    • cd <tuscany_sca_install_dir>/extensions/ws/service
    • ./deploy.sh

To automatically deploy Tuscany Web Service support to Axis2C on Windows:

  1. The AXIS2C_HOME environment variable is required:
    • export AXIS2C_HOME=<path to axis2c version 0.94>
  2. Use the following command sequence to run the deploy script:
    • cd <tuscany_sca_install_dir>\extensions\ws\service
    • deploy.cmd

Deploying manually

To deploy Tuscany Web Service support to Axis2C manually, use the following steps:

  1. Linux:
    1. cd <axis2c version 0.94>/services
    2. ln -sf <tuscany_sca_install_dir>/extensions/ws/service/services/tuscany
    3. cd <axis2c version 0.94>/modules
    4. ln -sf <tuscany_sca_install_dir>/extensions/ws/service/modules/tuscany
    Windows:
    1. Create a <axis2c version 0.94>\services\tuscany directory
    2. Copy all the files in <tuscany_sca_install_dir>\extensions\ws\service\services\tuscany to the directory created above
    3. Create a <axis2c version 0.94>\modules\tuscany directory
    4. Copy all the files in <tuscany_sca_install_dir>\extensions\ws\service\modules\tuscany to the directory created above
  2. Edit the <axis2c version 0.94>/axis2.xml file to add a <ref module="tuscany"> element. This will register the above module. E.g.:
    ...
        <!-- ================================================= -->
        <!-- Global Modules  -->
        <!-- ================================================= -->
        <!-- Comment this to disable Addressing -->
        <module ref="addressing"/>
    
        <module ref="tuscany"/>
    
    ...              

Defining an SCA Composite with a WS service

In this section we will use the Calculator sample as a worked example. The Calculator code and files can be found at <tuscany_sca_install_dir>samples/Calculator.

Pre-requisites:

  • At least one working component within a composite and solution composite. The component(s) can be implemented in C++, Ruby or Python. If this includes C++ components, the SCAGEN generated Proxy and Wrapper classes and the component class files must have been compiled into a .dll or .so library. The *.composite and *.componentType files must also be available and working.

  1. Optionally, create the WSDL that defines the interface of your SCA component. See the table XML Schema Type to C++ Type Mapping and Notes on creating WSDL below for mapping the parameters and return types of the component operations to XML schema types in the WSDL. This file will need to be accessible from the component, so place it in the same directory as the component or in a subdirectory.
    See the <tuscany_sca_install_dir>/samples/Calculator/sample.calculator/Calculator.wsdl file as an example.
    If you do not provide a WSDL file describing the service interface then the service will accept any incoming document/literal wrapped XML request that matches an operation on the target service (the wrapper element name and types of the sub-elements must match the operation name and its parameter types). Additionally, if the target component is a Python or Ruby scripting component, it will accept any parameter type so you can pretty much pass whatever data you want, as long at the incoming XML request matches to an operation name with the correct number of parameters on the target service.
  2. Add a service definition to the component .composite file. If you have created a WSDL definition, set the interface.wsdl interface attribute to the namespace and port name specified in the WSDL, in the form: "<namespace>#wsdl.interface(<port-name>)". Link a reference from this service definition to your component, give the service a name and set the multiplicity if required.
    E.g. for the Calculator component, based on the Calculator.wsdl file:
    <service name="CalculatorService">
        <interface.wsdl interface="http://sample/calculator#wsdl.interface(Calculator)"/>
        <binding.ws/>
        <reference>CalculatorComponent/CalculatorService</reference>
    </service>
    If the Calculator.wsdl file were not included, the service definition would simply be as follows:
    <service name="CalculatorService">
        <binding.ws/>
        <reference>CalculatorComponent/CalculatorService</reference>
    </service>
  3. You are now ready to start the Axis2C HTTP server. Remember you will need to have the TUSCANY_SCACPP, TUSCANY_SDOCPP and AXIS2C_HOME environment variables set, as well as the SCA and SDO bin directories and the Axis2C lib directory on your PATH on Windows or the SCA, SDO and Axis2C lib directories on your LD_LIBRARY_PATH on Linux. You will also need to set the TUSCANY_SCACPP_SYSTEM_ROOT and TUSCANY_SCACPP_DEFAULT_COMPONENT environment variables to the path to your SCA component directory structure and the default component respectively. E.g. on Windows run the following commands:
    • set TUSCANY_SCACPP=C:/tuscany_sca
    • set TUSCANY_SDOCPP=C:/tuscany_sdo
    • set AXIS2C_HOME=C:/axis2c-bin-0.94-win32
    • set PATH=%PATH%;C:/tuscany_sca/bin;C:/tuscany_sdo/bin;C:/axis2c-bin-0.94-win32/lib
    • set TUSCANY_SCACPP_SYSTEM_ROOT=C:/tuscany_sca/samples/Calculator/deploy
    • set TUSCANY_SCACPP_DEFAULT_COMPONENT=sample.calculator.CalculatorComponent
    • cd %AXIS2C_HOME%/bin/
    • ./axis2_http_server.exe
  4. Optionally, enable Tuscany logging by setting the TUSCANY_SCACPP_LOGGING environment variable with the level you wish to log at (0 for minimal logging, up to 9 for more detailed logging) and the TUSCANY_SCACPP_LOG environment variable to define the file to log to (if this is not set, logging will go to the console). E.g. on Windows run the following commands:
    • set TUSCANY_SCACPP_LOGGING=5
    • set TUSCANY_SCACPP_LOG=C:/tuscany/mylogfile.txt

Your component should now be exposed as an Axis2C Web Service, via the WS service you created. See the Axis2C documentation for writing clients to invoke the Web Service, or you can use any other Web Service client platform (e.g. Axis2 for Java), or you can invoke your service from another SCA application by using Tuscany's WS reference support.

XML Schema Type to C++ Type Mapping

To help define the WSDL that describes the interface of your component, the table below lists how incoming XML data in Web Service messages is mapped to C++ types used in the parameters and return types of your component operations.

This lists the only C++ types that can currently be used on the operations of a component exposed as a Web Service. For other types, use an SDO DataObject to wrap the data, and define that wrapping as a complexType in the WSDL. See the SDO specifications for the C++ types that SDO supports.

XML Schema Type C++ Type
string std::string
int long
integer long
short short
float float
double long double
boolean bool
hexBinary char*
base64Binary char*
byte char
complexType commonj::sdo::DataObjectPtr
any commonj::sdo::DataObjectPtr with OpenDataObjectType

Notes on creating WSDL

Currently only Document/literal Wrapped style Web Services are supported by WS EntryPoint, support for RPC style Web Services is planned for future releases.

See this article for an explanation of Document/literal Wrapped style WSDL and Web Services

Document/literal Wrapped services require that the operation name is used as the name of the incoming element that wraps the operation parameters. Additionally, operation parameter and return messages that are defined in the WSDL must be XML Schema elements containing a complexType.

For example, a component operation defined in C++ as:

long myOperation(std::string arg1, short arg2, DataObjectPtr arg3);
will need to be described in WSDL with messages like:
<wsdl:message name="myOperationRequestMsg">                                               
  <wsdl:part element="tns:myOperation" name="myOperationRequestPart"/>                    
</wsdl:message>                                                                           
<wsdl:message name="myOperationResponseMsg">                                              
  <wsdl:part element="tns:myOperationResponse" name="myOperationResponsePart"/>           
</wsdl:message>
and will need an XML schema to define the types like:
<xsd:element name="myOperation">                                                          
 <xsd:complexType>                                                                       
   <xsd:sequence>                                                                        
     <xsd:element name="arg1" type="xsd:string" minOccurs="1"/>                          
     <xsd:element name="arg2" type="xsd:short" minOccurs="1"/>                           
     <xsd:element name="arg3" minOccurs="1">                                             
       <xsd:complexType>                                                                 
         <xsd:sequence>                                                                  
           <xsd:element name="dataObjectFloatData" type="xsd:float"/>                    
           <xsd:element name="dataObjectStringData" type="xsd:string"/>                  
           <xsd:element name="dataObjectIntData" type="xsd:int"/>                        
         </xsd:sequence>                                                                 
       </xsd:complexType>                                                                
     </xsd:element>                                                                      
   </xsd:sequence>                                                                       
 </xsd:complexType>                                                                      
</xsd:element>                                                                            
                                                                                         
<xsd:element name="myOperationResponse">                                                  
 <xsd:complexType>                                                                       
   <xsd:sequence>                                                                        
     <xsd:element name="result" type="xsd:int" minOccurs="1"/>                           
   </xsd:sequence>                                                                       
 </xsd:complexType>                                                                      
</xsd:element>

Getting Help

First place to look is at the Tuscany FAQ at http://incubator.apache.org/tuscany/faq.html

Any problem with this release can be reported to the Tuscany mailing lists or create a JIRA issue at http://issues.apache.org/jira/browse/Tuscany.