Table of Contents Previous Next PDF


Oracle SALT SCA Programming

Oracle SALT SCA Programming
This chapter contains the following topics:
Overview
One important aspect of Service Component Architecture (SCA) is the introduction of a new programming model. As part of the Oracle Tuxedo architecture, SCA allows you to better blend high-output, high-availability and scalable applications in an SOA environment.
SCA components run on top of the Oracle Tuxedo infrastructure using ATMI binding. The ATMI binding implementation provides native Oracle Tuxedo communications between SCA components, as well as SCA components and Oracle Tuxedo programs (clients and servers).
In addition to the programming model, the Service Component Definition Language (SCDL) describes what components can perform in terms of interactions between each other, and instructs the framework to set-up necessary links (wires).
SCA Utilities
The following utilities are used in conjunction with Oracle SALT SCA programming:
buildscaclient: Builds client processes that call SCA components.
buildscacomponent: Builds SCA components.
buildscaserver: Builds an Oracle Tuxedo server containing SCA components.
SCAHOST: Generic server for Python, Ruby or PHP SCA components.
scatuxgen: Generates Oracle Tuxedo Service Metadata Repository interface information from an SCA interface.
scastructc32,scastructc: Structure description file compiler.
scastructdis32, scastructdis: Binary structure and view files disassembler.
tuxscagen: Generates SCA, SCDL, and server-side interface files for Oracle Tuxedo services.
For more information, see the Oracle SALT Command Reference.
SCA Client Programming
The runtime reference binding extension is the implementation of the client-side aspect of the SCA container. It encapsulates the necessary code used to call other services, SCA components, Oracle Tuxedo servers or even Web services, transparently from an SCA-based component.
SCA Client Programming Steps
Developing SCA client programs requires the following steps:
1.
2.
3.
4.
5.
6.
Setting Up the Client Directory Structure
You must define the applications physical representation. Strict SCA client applications are SCA component types. Listing 7‑1shows the directory structure used to place SCA components in an application.
Listing 7‑1 SCA Component Directory Structure
myApplication/ (top-level directory, designated by the APPDIR environment variable)
    root.composite (SCDL top-level composite, contains the list of components in this application)
    myClient/ (directory containing actual client component described in this section)
        myClient.composite (SCDL for the client component)
        myClient.cpp (client program source file)
        TuxService.h (interface of component called by client program)
 
Listing 7‑2 shows an example of typical root.composite content.
Listing 7‑2 root.composite Content
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
       name="simple.app">
       <component name="myClientComponent">
              <implementation.composite name="myClient"/>
       </component>
</composite>
 
The implementation.composite@name parameter references the directory that contains the component named 'myClientComponent'. This value is required at runtime. For more information, see Running the Client Application.
Developing the Client Application
Client programs are required to implement a call to a single API. This following call is required in order to set up the SCA runtime:
...
       CompositeContext theContext = CompositeContext::getCurrent();
...
Actual calls are based on an interface. This interface is usually developed along with the component being called. In the case of existing Oracle Tuxedo ATMI services, this interface can be generated by accessing the Oracle Tuxedo METADATA repository. For more information, see the
Oracle SALT Administration Guide and tuxscagen, scatuxgen in the Oracle SALT Reference Guide.
In the case of calling external Web services, an interface matching the service WSDL must be provided. For more information, see SCA Data Type Mapping for the correspondence between WSDL types and C++ types.
Listing 7‑3 shows an interface example.
Listing 7‑3 Interface Example
#include <string>
/**
       * Tuxedo service business interface
       */
       class TuxService
       {
       public:
       virtual std::string TOUPPER(const std::string inputString) = 0;
       };
 
In the interface shown in Listing 7‑3, a single method TOUPPER is defined. It takes a single parameter of type std::string, and returns a value of type std::string. This interface needs to be located in its own .h file, and is referenced by the client program by including the .h file.
Listing 7‑4 shows an example of a succession of calls required to perform an invocation.
Listing 7‑4 Invocation Call Example
// SCA definitions
// These also include a Tuxedo-specific exception definition: ATMIBindingException
#include "tuxsca.h"
// Include interface
#include "TuxService.h"
...
       // A client program uses the CompositeContext class
       CompositeContext theContext = CompositeContext::getCurrent();
...
       // Locate Service
       TuxService* toupperService =
              (TuxService *)theContext.locateService("TOUPPER");
...
       // Perform invocation
       const std::string result = toupperService->TOUPPER("somestring");
...
 
Notes:
For detailed code examples, see the SCA samples located in following directories:
UNIX samples: $TUXDIR/samples/salt/sca
Windows samples: %TUXDIR%\samples\salt\sca
Composing the SCDL Descriptor
The link between the local call and the actual component is made by defining a binding in the SCDL side-file. For example, Listing 7‑4 shows a call to an existing Oracle Tuxedo ATMI service, the SCDL descriptor shown in Listing 7‑5 should be used. This SCDL is contained in a file called <componentname>.composite.
Listing 7‑5 SCDL Descriptor
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
          name="simpapp.client">
     <reference name="TOUPPER">
        <interface.cpp header="TuxService.h"/>
        <binding.atmi requires="legacy">
           <inputBufferType target="TOUPPER">STRING</inputBufferType>
           <outputBufferType target="TOUPPER">STRING</outputBufferType>
        </binding.atmi>
    </reference>
</composite>
 
This composite file indicates that a client component may perform a call to the TOUPPER reference, and that this call is performed using the ATMI binding. In effect, this results in a tpcall() to the "TOUPPER" Oracle Tuxedo service. This Oracle Tuxedo service may be an actual existing Oracle Tuxedo ATMI service, or another SCA component exposed using the ATMI binding. For more information, see SCA Component Programming.
The inputBufferType and outputBufferType elements are used to determine the type of Oracle Tuxedo buffer used to exchange data. For more information, see SCA Data Type Mapping and the ATMI Binding Element Reference for a description of all possible values that can be used in the binding.atmi element.
Building the Client Application
Once all the elements are in place, the client program is built using the buildscaclient command. You must do the following steps:
1.
2.
$ buildscaclient -c myClientComponent -s . -f myClient.cpp
This command verifies the SCDL code, and builds the following required elements:
If no syntax or compilation error is found, the client program is ready to use.
Running the Client Application
To execute the client program, the following environment variables are required:
APPDIR - designates the application directory; in the case of SCA this typically contains the top-level SCDL composite.
SCA_COMPONENT - the default SCA component (the value 'myClientComponent' in the example shown in Listing 7‑2). It tells the SCA runtime where to start when looking for services in the locateService() call.
Invoking Existing Oracle Tuxedo Services
Access to existing Oracle Tuxedo ATMI services from an SCA client program can be simplified using the examples shown in Listing 7‑6, Listing 7‑7, and Listing 7‑8.
Note:
Starting from a Oracle Tuxedo METADATA repository entry as shown in Listing 7‑6, the tuxscagen command can be used to generate interface and SCDL.
Listing 7‑6 SCA Components Calling an Existing Oracle Tuxedo Service
service=TestString
tuxservice=ECHO
servicetype=service
inbuf=STRING
outbuf=STRING

service=TestCarray
tuxservice=ECHO
servicetype=service
inbuf=CARRAY
outbuf=CARRAY
 
Listing 7‑7 Generated Header
#ifndef ECHO_h
#define ECHO_h
#include <string>
#include <tuxsca.h>
class ECHO
{
public:
    virtual std::string TestString(const std::string arg) = 0;
    virtual std::string TestCarray(const struct carray_t * arg) = 0; }; #endif /* ECHO_h */
 
Listing 7‑8 Generated SCDL Reference
<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
name="ECHO">
  <reference name="ECHO">
    <interface.cpp header="ECHO.h"/>
    <binding.atmi requires="legacy">
      <serviceType target="TestString">RequestResponse</serviceType>
      <inputBufferType target="TestString">STRING</inputBufferType>
      <outputBufferType target="TestString">STRING</outputBufferType>
      <serviceType target="TestCarray">RequestResponse</serviceType>
      <inputBufferType target="TestCarray">CARRAY</inputBufferType>
      <outputBufferType target="TestCarray">CARRAY</outputBufferType>
    </binding.atmi>
  </reference>
</composite>
 
The steps used to invoke these services are identical to the examples shown in Listing 7‑6 through Listing 7‑8.
Handling TPFAIL Data
Invoking a non-SCA Oracle Tuxedo ATMI service may return an error, but still send back data by using tpreturn(TPFAIL, …). When this happens, an SCA client or component is interrupted by the ATMIBindingException type.
The data returned by the service, if present, can be obtained by using the ATMIBindingException.getData()API. For more information see, TPFAIL Return Data.
The example in Listing 7‑9 corresponds to a binding.atmi definition as shown in Listing 7‑10.
Listing 7‑9 Invocation Interruption Example
...
        try {
          const char* result = toupperService->charToup("someInput");
        } catch (tuscany::sca::atmi::ATMIBindingException& abe) {
          // Returns a pointer to data corresponding to
          // mapping defined in <errorBufferType> element
          // in SCDL
          const char* *result = (const char **)abe.getData();
          if (abe.getData() == NULL) {
              // No data was returned
          } else {
              // Process data returned
              ...
          }
        } catch (tuscany::sca::ServiceInvocationException& sie) {
          // Other type of exception is returned
        }
...
 
Listing 7‑10 /binding.atmi Definition
...
        <binding.atmi requires="legacy">
              <inputBufferType target="charToup">STRING</inputBufferType>
              <outputBufferType target="charToup">STRING</outputBufferType>
              <errorBufferType target="charToup">STRING</errorBufferType>
<binding.atmi/>
...
 
Other returned data types must be cast to the corresponding type. For example, an invocation returning a commonj::sdo::DataObjectPtr as shown in Listing 7‑11.
Listing 7‑11 SCDL Invocation Example
...
       <errorBufferType target="myMethod">FML32/myType</errorBufferType>
...
 
The ATMIBindingException.getData() result is shown in Listing 7‑12.
Listing 7‑12 ATMIBindingException.getData() Results
...
              catch (tuscany::sca::atmi::ATMIBindingException& abe) {
              const commonj::sdo::DataObjectPtr *result =
              (const commonj::sdo::DataObjectPtr *)abe.getData();
...
 
The rules for returning TPFAIL data to the calling application are as follows:
For each <errorBufferType>, a canonical type is defined, where <errorBufferType> is converted. When the <errorBufferType> is equal to the <outputBufferType>, the canonical type is the same C++ type that is returned in a successful service implementation.
When the <errorBufferType> is different from the <outputBufferType>, the canonical type is as follows:
For STRING buffers, a C++ char* or char[ ]data type.
For MBSTRING buffers, a C++ wchar_t* or wchar_t[ ].
For CARRAY buffers, a C++ CARRAY_PTR.
For X_OCTET buffers, a C++ X_OCTET_PTR.
In each case, the value returned by getData() is a pointer to one of the types listed above.
For more conversion rules between Oracle Tuxedo buffer types and C++ data information, see SCA Data Type Mapping.
SCA Component Programming
The SCA Component terminology designates SCA runtime artifacts that can be invoked by other SCA or non-SCA runtime components. In turn, these SCA Components can perform calls to other SCA or non-SCA components. This is different from strict SCA clients which can only make calls to other SCA or non-SCA components, but cannot be invoked.
The Oracle SALT SCA container provides the capability of hosting SCA components in an Oracle Tuxedo server environment. This allows you to take full advantage of proven Oracle Tuxedo qualities: reliability, scalability and performance.
Figure 7‑1 summarizes SCA components and Oracle Tuxedo server mapping rules.
Figure 7‑1 SCA Component and Oracle Tuxedo Server Mapping Rules
While SCA components using Oracle Tuxedo references do not require special processing, SCA components offering services must still be handled in an Oracle Tuxedo environment.
The mapping is as follows:
An SCA composite declaring one or more services with a <binding.atmi> definition maps to a single Oracle Tuxedo server advertising the same number of services as the SCA composite.
Interfaces may declare multiple methods. Each method is linked to an Oracle Tuxedo native service using the /binding.atmi/@map attribute. A method not declared via the /binding.atmi/@map attribute is not accessible through Oracle Tuxedo. The use of duplicate service names are detected at server generation time, so that Oracle Tuxedo service names-to-interface method mapping in a single Oracle Tuxedo server instance is 1:1.
SCA composites are deployed in an Oracle Tuxedo application by configuring instances of generated SCA servers in the UBBCONFIG file. Multiple instances are allowed. Multi-threading capabilities are also allowed and controllable using already-existing Oracle Tuxedo features.
SCA Component Programming Steps
The steps required for developing SCA component programs are as follows:
1.
2.
3.
4.
5.
Setting Up the Component Directory
You must first define the applications physical representation. Listing 7‑13 shows the directory structure used to place SCA components in an application:
Listing 7‑13 SCA Component Directory Structure
myApplication/ (top-level directory, designated by the APPDIR environment variable)
    root.composite (SCDL top-level composite, contains the list of components in this application)
    myComponent/ (directory containing actual component described in this section)
        myComponent.composite (SCDL for the component)
        myComponent.componentType
        myComponentImpl.cpp (component implementation source file)
        TuxService.h (interface of component being exposed)
        TuxServiceImpl.h (component implementation definitions)
 
Listing 7‑14 shows typical root.composite content.
Listing 7‑14 root.composite Content
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
       name="simple.app">
       <component name="myComponent">
              <implementation.composite name="myComponent"/>
       </component>
</composite>
 
The implementation.composite@name parameter references the directory that contains the 'myComponent' component.
Developing the Component Implementation
Components designed to be called by other components do not need to be aware of the SCA runtime. There are, however, limitations in terms of interface capabilities, such as:
C++ classes (other than std::string and commonj::sdo::DataObjectPtr) cannot be used as parameters or return values
For more information, see SCA Data Type Mapping.
Listing 7‑15 shows an example of an interface implemented for a client program.
Listing 7‑15 Component Implementation Interface
#include <string>
/**
  * Tuxedo service business interface
  */
  class TuxService
  {
  public:
       virtual std::string TOUPPER(const std::string inputString) = 0;
  };
 
The component implementation then generally consists of two source files (as shown Listing 7‑16 and Listing 7‑17 respectively):
Listing 7‑16 Example (TuxServiceImpl.h):
#include "TuxService.h"
 
      /**
       * TuxServiceImpl component implementation class
       */
      class TuxServiceImpl: public TuxService
      {
      public:
       virtual std::string toupper(const std::string inputString);
      };
 
Listing 7‑17 Example (TuxServiceImpl.cpp):
#include "TuxServiceImpl.h"
 #include "tuxsca.h"
 
using namespace std;
using namespace osoa::sca;
 
/**
* TuxServiceImpl component implementation
*/
std::string TuxServiceImpl::toupper(const string inputString)
{
    string result = inputString;
        
    int len = inputString.size();

    for (int i = 0; i < len; i++) {
       result[i] = std::toupper(inputString[i]);
    }
 
    return result;
}
 
Additionally, a side-file (componentType), is required. It contains the necessary information for the SCA wrapper generation and possibly proxy code (if this component calls another component).
This componentType file (<componentname>Impl.componentType)is an SCDL file type. Listing 7‑18 shows an example of a componentType file (TuxServiceImpl.componentType).
Listing 7‑18 componentType File Example
<?xml version="1.0" encoding="UTF-8"?>
 <componentType xmlns="http://www.osoa.org/xmlns/sca/1.0" >
       <service name="TuxService">
              <interface.cpp header="TuxService.h"/>
       </service>
 </componentType>
 
Composing the SCDL Descriptor
The link between the local implementation and the actual component is made by defining a binding in the SCDL side-file. For example, for the file type in Listing 7‑18 to be exposed as an Oracle Tuxedo ATMI service, the SCDL in Listing 7‑19 should be used. This SCDL is contained in a file called <componentname>.composite (for example, myComponent.composite).
Listing 7‑19 Example SCDL Descriptor
<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" name="myComponent">
<service name="TuxService">
<interface.cpp header="TuxService.h"/>
<binding.atmi requires="legacy"/>
<map target="toupper">TUXSVC</map>
<inputBufferType target="toupper">STRING</inputBufferType>
<outputBufferType target="toupper">STRING</outputBufferType>
<reference>MYComponent</reference>
</service>
<component name="MYComponent">
<implementation.cpp library="TuxService" header="TuxServiceImpl.h"/>
</component>
</composite>
 
This composite file indicates that the service, mySVC, can be invoked via the Oracle Tuxedo infrastructure. It further indicates that the toupper() method is advertised as the TUXSVC service in the Oracle Tuxedo system. Once initialized, another SCA component may now call this service, as well as a non-SCA Oracle Tuxedo ATMI client.
The inputBufferType and outputBufferType elements are used to determine the type of Oracle Tuxedo buffer used to exchange data. For more information, see SCA Data Type Mapping and the ATMI Binding Element Reference for a description of all possible values that can be used in the binding.atmi element.
Note:
The mycomponent.componentType service name should be same as the composite file, otherwise an exception is thrown.
Compiling and Linking the Components
Once all the elements are in place, the component is built using the buildscacomponent command. The steps are as follows:
1.
Navigate to the APPDIR directory. The component and side files should be in its own directory one level down
2.
$ buildscacomponent -c myComponent -s . -f TuxServiceImpl.cpp
This command verifies the SCDL code, and builds the following required elements:
Building the Oracle Tuxedo Server Host
In order for components to be supported in an Oracle Tuxedo environment, a host Oracle Tuxedo server must be built. This is achieved using the buildscaserver command.
For example: $ buildscaserver -c myComponent -s . -o mySCAServer
When the command is executed, mySCAServer is ready to be used. It automatically locates the component(s) to be deployed according to the SCDL, and performs the appropriate Oracle Tuxedo/SCA associations.
SCA Python, Ruby, and PHP Programming
This section contains the following topics:
SCA Python, Ruby, and PHP Programming Overview
Integration of Python, Ruby or PHP scripts in an environment such as Oracle Tuxedo via SALT, is intended for providing additional flexibility in terms of program development.
Python, Ruby, and PHP are comparable object-oriented scripting languages that offer many advantages over C/C++:
SALT SCA Python, Ruby, and PHP support provides a set of APIs to perform SCA calls from Python, Ruby or PHP client programs, and language extensions to call Python, Ruby or PHP components. For more information, see Python, Ruby, and PHP Client Programming and Python, Ruby, and PHP Component Programming.
The buildscaclient, buildscaserver and buildscacomponent commands do not need adapting for use with Python, Ruby or PHP programs, as they are not be required to produce executables or component libraries.
Note:
A system server, SCAHOST, is provided to correctly marshal requests and responses to and from Python, Ruby or PHP scripts. It contains Python, Ruby, and PHP scripts exposed as SCA services (via the Oracle Tuxedo Metadata Repository). The definitions describe the parameters and return types of the corresponding exposed Python, Ruby or PHP functions.
For more information, see Python, Ruby, and PHP Data Type Mappingfor Service Metadata Repository entry examples.
Available bindings are used from Python, Ruby or PHP programs, or are used to invoke Python, Ruby or PHP components. Like C++, the Python, Ruby, and PHP language extension is binding-independent.
Figure 7‑2 provides an overview of the SALT SCA environment Python, Ruby, and PHP support architecture.
Figure 7‑2 SALT SCA Python, Ruby, and PHP Programming Support Architecture
Python, Ruby, and PHP Client Programming
SCDL Clients
From a client component perspective, the SCDL code only has to mention the referenced component and possibly the binding used (that is, no interface element is required).
For example, the following snippet allows a Python, Ruby or PHP client to make an invocation to an SCA component via ATMI binding, and using the default buffer type (STRING input, STRING output):
<reference name="CalculatorComponent">
     <binding.atmi/>
</reference>
Python Clients
To invoke an SCA component from a Python program, you must do the following:
1.
import sca
2.
calc = sca.locateservice("CalculatorComponent")
The calc object is used to invoke the “add” operation (for example, result = calc.add(val1, val2)).
Ruby Clients
To invoke an SCA component from a Ruby program, you must do the following:
1.
require("sca_ruby")
2.
calculator = SCA::locateService("CalculatorComponent")
The calculator object is used to invoke the “add” operation (for example, x = calculator.add(3, 2)).
PHP Clients
To invoke an SCA component from a PHP program, you must do the following:
1.
<?php
dl('sca.so');
2.
$svc = Sca::locateService("uBikeService");
At this point the svc object can be used to invoke the searchBike operation, for instance:
$ret = $svc->searchBike('YELLOW');
Python, Ruby, and PHP Component Programming
SCDL Components
In order to use Python, Ruby or PHP scripts in SCA as components, you must use the implementation.python, implementation.ruby and implementation.php parameters.
Note:
implementation.python implementation.ruby and implementation.php usage is similar to the implementation.cpp element (see Listing 7‑19 and Listing 7‑31); the difference is that the interface.python and interface.ruby elements, or .componentType are not required.
Their syntax and attributes are as follows:
<implementation.python
     module="string"
     scope="scope"? >
<implementation.python/>
The implementation.python element has the following attributes:
Name of the Python module (.py file) containing the operation(s) that this component offers in the form of module-level function(s).
Identifies the scope of the component implementation. The default is stateless, indicating that there is no correlation between implementation instances used to dispatch service requests. A composite value indicates that all service requests are dispatched to the same implementation instance for the lifetime of the containing composite.
<implementation.ruby
     script="string"
     class="string"
     scope="scope"? >
<implementation.ruby/>
The implementation.ruby element has the following attributes:
Name of the Ruby script (.rb file) containing the operation(s) that the component offers in the form of methods of a class contained in the script file. The name of the script is its full name (that is, it also includes the .rb extension).
Name of the Ruby class (.rb file) containing the operation(s) that the component offers.
Identifies the scope of the component implementation. The default is stateless, indicating that there is no correlation between implementation instances used to dispatch service requests. A composite value indicates that all service requests are dispatched to the same implementation instance for the lifetime of the containing composite.
<implementation.php
     script="string"
     class="string"
     scope="scope"? >
<implementation.php/>
The implementation.php element has the following attributes:
Name of the PHP script (.php file) containing the operation(s) that this component will offer, in the form of methods of a class contained in the script file. The name of the script is its full name, i.e. it also includes the .php extension.
Name of the PHP class (.php file) containing the operation(s) that this component will offer.
Identifies the scope of the component implementation. The default is stateless, indicating that there is no correlation between implementation instances used to dispatch service requests. A value of composite indicates that all service requests are dispatched to the same implementation instance for the lifetime of the containing composite.
Listing 7‑20 shows an example of a Python component in an SCA composite accessible using the ATMI binding. In this example, runtime looks for a Python component located in a file named ToupperService.py in the same location as the composite file.
Similarly, a Ruby component is required in a file named ToupperService.rb, in the same location as the composite file.
Listing 7‑20 Python Component in an SCA Composite
<?xml version="1.0" encoding="UTF-8"?>

<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
              name="simpapp.server">

       <service name="SCASVC">
              <binding.atmi/>
              <reference>ToupperServiceComponent</reference>
</service>

<component name="ToupperServiceComponent">
       <implementation.python module="ToupperService"
                                   scope="composite"/>
</component>
       
</composite>
 
Listing 7‑21 shows an example of a PHPcomponent in an SCA composite accessible using the ATMI binding
Listing 7‑21 PHP Component in an SCA Composite
<?xml version="1.0" encoding="UTF-8"?>
 
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
name="simpapp.PHP">
 
<service name="TESTPHP">
<!-- No interface, it is contained in TMMETADATA -->
<binding.atmi>
<map target="charToup">TOUPPHP</map>
<inputBufferType target="charToup">STRING</inputBufferType>
<outputBufferType target="charToup">STRING</outputBufferType>
</binding.atmi>
<reference>ToupperServiceComponent</reference>
</service>
 
<component name="ToupperServiceComponent">
<implementation.php script="toupper.php"
class="Toupper"/>
scope="composite"/>
</component>
</composite>
 
Python Components
Python operations are exposed as module-level functions contained in a Python module file. For example, a ToupperService.py file would contain the code shown in Listing 7‑22.
Listing 7‑22 Python Module File
def charToup(val1):
    print "input: " + val1
    result = "result"
    print "Python - toupper"
    return result
 
Parameter and return values types are dynamically determined at runtime. Application exceptions are caught by the extension runtime and re-thrown as tuscany::sca::ServiceInvocationException.
During input, unsupported types or an error processing an input DataObject results in the following exception:
a
tuscany::sca::ServiceDataException.
During output, simple return types are always processed. An error generating a DataObject (from XML data) results in the following exception:
tuscany::sca::ServiceDataException.
For more information, see Python, Ruby, and PHP Data Type Mapping.
Ruby Components
Ruby operations are exposed as methods of an implementation class contained in a Ruby script file (.rb extension). For example, a ToupperService.rb file would contain the code shown in Listing 7‑23.
Listing 7‑23 Ruby Script File
class ToupperService

  def initialize()
    print "Ruby - ToupperService.initialize\n"
  end

  def charToup(arg1)
    print "Ruby - ToupperService.div\n"
    arg1.ToUpper()
  end

end
 
Parameter and return values types are dynamically determined at runtime. Application exceptions are caught by the extension runtime and re-thrown as tuscany::sca::ServiceInvocationException.
During input, unsupported types or an error processing an input DataObject results in the following exception:
a
tuscany::sca::ServiceDataException.
During output, simple return types are always processed. An error generating a DataObject (from XML data) results in the following exception: tuscany::sca::ServiceDataException.
For more information, see Python, Ruby, and PHP Data Type Mapping.
PHP Components
PHP operations are exposed as functions contained in a PHP class. For example, a toupper.php file would contain the code shown in Listing 7‑24
Listing 7‑24 PHP Class
<?php
class MyClass {
public static function toupper(val) {
print "PHP - toupper";
return val.toupper();
}
}
?>
 
Parameter and return values types are dynamically determined at runtime. Application exceptions are caught by the extension runtime and re-thrown as tuscany::sca::ServiceInvocationException.
During input, unsupported types or an error processing an input DataObject results in the following exception:
a
tuscany::sca::ServiceDataException.
During output, simple return types are always processed. An error generating a DataObject (from XML data) results in the following exception: tuscany::sca::ServiceDataException.
For more information, see Python, Ruby, and PHP Data Type Mapping.
SCA Structure Support
This section contains the following topics:
Note:
SCA Structure Support Overview
SCA Structure support provides:
You must use the struct data type specified in the SCA method parameter definition or in the definition of a return value from an SCA method as follows:
struct structurename *
struct structurename &
Elements within the structure can be any of the following simple data types/arrays that are supported as an SCA parameter:
struct nestedstructurename
Note:
The scagen utility parses typedef and struct keywords. For more information, see the Oracle SALT Command Reference Guide.
SCA Structure Limitations
std::string or a std::wstring
struct carray_t, struct_x_octet_t, or struct xml_t
.h and .cpp files referencing the use of structures are required to include a definition for the structure being used and for any nested structures contained within that structure.
Using SCA Structure Description Files
A structure description file may be used to describe the format of an SCA structure parameter. Structure description files are very similar to Oracle Tuxedo viewfiles, with additional capabilities added for SCA.
Note:
If no structure description file is provided for a particular structure, then the structure definition used in application code is used, and FML field names in SCA-ATMI mode are the same as structure element names. Since field numbers are generated automatically for SCA-SCA applications, these applications do not need to specify a structure description file.
The structure description file format is identical to the Oracle Tuxedo viewfile format, with the following exceptions:
The type parameter in column 1 allows the additional values bool, unsignedchar, signedchar, wchar_t, unsignedint, unsignedlong, longlong, unsignedlonglong, longdouble, and struct.
If the value in column1 is struct, then the cname value in column 2 is the name of a previously defined VIEW that describes a nested structure. In this case, the count value in column 4 may optionally be specified to specify the number of occurrences of the nested structure.
If a structure described in a structure description file is converted to (or from) an FML32 or FML buffer at runtime in an SCA-ATMI application, then the name of the corresponding FML field is the fbname value specified in column 3, if any, and is the cname value specified in column 2 (if no value is specified in column 3). When compiled, the structure description file produces a binary structure description file as shown in Listing 7‑25. The binary structure header file is shown in shown in Listing 7‑26.
Note:
Listing 7‑25 SCA Structure Description File
VIEW empname
#TYPE       CNAME     FBNAME        COUNT      FLAG      SIZE      NULL
string      fname     EMP_FNAME       1          -        25        -
char        minit     EMP_MINI       1          -         -        -
string      lname     EMP LNAME       1          -        25        -
END

VIEW emp
struct         empname      ename     1          -         -        -
unsignedlong   id           EMP_ID    1          -         -        -
long           ssn          EMP_SSN   1          -         -        -
double         salaryhist   EMP_SAL   10         -         -        -
END
 
Listing 7‑26 Binary Structure Header File
struct empname {
  char fname[25];
  char minit;
  char lname[25];
};

struct emp {
  struct empname ename;
  unsigned long id;
  long ssn;
  double salaryhist[10];
}
 
The scastructc32 and scastructc commands are used to convert a source structure description file into a binary structure description file and to generate a header file describing the structure(s) in the structure description file. The scastructdis32 and scastructdis commands accept the same arguments as viewdis32 and viewdis. For more information, see the Oracle SALT Command Reference.
Notes:
scastructc32 and scastructc generate a binary file with suffix .V on Unix and suffix .VV on Windows.
If the structure description file contains no SCA extensions that are not available in Oracle Tuxedo views, then the magic value for the binary structure description file shall be the same as the magic value used by viewc32. If any SCA specific extensions are used, then a different magic value shall be used for the binary structure description file.
Using tuxscagen to Generate Structures
When invoked with the option -S, tuxscagen generates a structure for any function parameter or return value that would otherwise have been passed using DataObjectPtr.
Note:
If tuxscagen -S is run, then simple data types are generated just as they would have been if tuxscagen were run without the -S option. It is possible to mix simple data types, structures, and other complex data types within a single metadata repository. In order to use simple data types in an application that also uses structures, it is not necessary to run tuxscagen without -S.
SCA Remote Protocol Support
SCA Oracle Tuxedo invocation supports the following remote protocols:
/WS
SCA invocations made using the SCA container have the capability of being performed using the Oracle Tuxedo WorkStation protocol (/WS). This is accomplished by specifying the value WorkStation (not abbreviated so as not to confuse it with WebServices) in the <remoteAccess> element of the <binding.atmi> element.
Only reference-type invocations are be available in this mode. Service-type invocations may be performed using the /WS transparently (there is no difference in behavior or configuration, and setting the <remoteAccess> element to WorkStation for an SCA service has no effect).
Since native and WorkStation libraries cannot be mixed within the same process, client processes must be built differently depending on the type of remote access chosen.
Note:
When using the value propagatesTransaction in /binding.atmi/@requires, the behavior of the ATMI binding does not actually perform any transaction propagation. It actually starts a transaction, since the use of this protocol is reserved for client-side access to Oracle Tuxedo (SCA or non-SCA) applications only. For more information, see ATMI Binding.
/Domains
SCA invocations made using the SCA container have the capability of being performed using the Oracle Tuxedo /Domains protocol. No additional configurations are necessary on <binding.atmi> declarations in SCDL files.
Note:
The SCA service name configured for Oracle Tuxedo /Domains is as follows:
SCA -> SCA mode - /binding.atmi/service/@name attribute followed by a '/' and method name
Legacy mode (SCA -> Tux interop mode) - /binding.atmi/service/@name attribute.
For more information, see SCA and Oracle Tuxedo Interoperability.
SCA Binding
Oracle SALT supports
ATMI Binding
Oracle Tuxedo communications are configured in SCDL using a <binding.atmi> element. This allows you to specify configuration elements specific to the ATMI transport, such as the location of the TUXCONFIG file, the native Oracle Tuxedo buffer types used, Oracle Tuxedo-specific authentication or /WS (WorkStation) configuration elements, etc.
Listing 7‑27 shows a summary of the <binding.atmi> element.
Note:
? refers to a parameter that can be specified 0 or 1 times.
* refers to a parameter that can be specified 0 or more times.
For more information, see Appendix F: Oracle SALT SCA ATMI Binding Reference in the Oracle SALT Reference Guide.
Listing 7‑27 ATMI Binding Pseudoschema
<binding.atmi requires="transactionalintent legacyintent"?>
       <tuxconfig>...</tuxconfig>?
       <map target="name">...</map>*
       <serviceType target="name">...</serviceType>*
       <inputBufferType target="name">...</inputBufferType>*
       <outputBufferType target="name">...</outputBufferType>*
       <errorBufferType target="name">...</errorBufferType>*
       <workStationParameters>?
              <networkAddress>...</networkAddress>?
              <secPrincipalName>...</secPrincipalName>?
              <secPrincipalLocation>...</secPrincipalLocation>?
              <secPrincipalPassId>...</secPrincipalPassId>?
              <encryptBits>...</encryptBits>?
       </workStationParameters>
       <authentication>?
              <userName>...</userName>?
              <clientName>...</clientName>?
              <groupName>...</groupName>?
              <passwordIdentifier>...</passwordIdentifier>?
              <userPasswordIdentifier>...
                                          </userPasswordIdentifier>?
       </authentication>
       <fieldTablesLocation>...</fieldTablesLocation>?
       <fieldTables>...</fieldTables>?
       <fieldTablesLocation32>...</fieldTablesLocation32>?
       <fieldTables32>...</fieldTables32>?
       <viewFilesLocation>...</viewFilesLocation>?
       <viewFiles>...</viewFiles>?
       <viewFilesLocation32>...</viewFilesLocation32>?
       <viewFiles32>...</viewFiles32>?
       <remoteAccess>...</remoteAccess>?
       <transaction timeout="xsd:long"/>?
</binding.atmi>
 
Java ATMI (JATMI) Binding
Java ATMI (JATMI) binding allows SCA clients written in Java to call Oracle Tuxedo services or SCA components. It provides one-way invocation of Oracle Tuxedo services based on the Oracle Tuxedo WorkStation protocol (/WS). The invocation is for outbound communication only from a Java environment to Oracle Tuxedo application acting as a server. Apart from a composite file for SCDL binding declarations, no external configuration is necessary. The service name, workstation address and authentication data are provided in the binding declaration.
Note:
Most of the Oracle Tuxedo CPP ATMI binding elements support JATMI binding and have the same usage. However, due to different underlying technology and running environment differences, some elements are not supported and some that are supported but have different element names.
The following Oracle Tuxedo CPP ATMI binding elements are not supported:
The following Oracle Tuxedo CPP ATMI binding workStationParameters elements are not supported:
The following Oracle Tuxedo CPP ATMI binding element is supported in a limited fashion.
Note:
Only the value "WorkStation" is allowed. If not specified, "WorkStation" is assumed.
All the classes in the elements mentioned below must be specified in Java CLASSPATH:
binding.atmi/fieldTables - Specifies a comma-separated list of Java classes that are extended from the weblogic.wtc.jatmi.TypedFML base class.
binding.atmi/fieldTables32 - Specifies a comma-separated list of Java classes that are extended from the weblogic.wtc.jatmi.TypedFML32 base class.
binding.atmi/viewFiles - Specifies a comma-separated list of Java classes that are extended from the weblogic.wtc.jatmi.TypedView base class. These derived classes usually are generated from an Oracle Tuxedo VIEW file using the weblogic.wtc.jatmi.viewj compiler. These also includes derived from weblogic.wtc.jatmi.TypedXCType and weblogic.wtc.jatmi.TypedXCommon.
For more information, see How to Use the viewj Compiler in the Oracle Tuxedo WebLogic Tuxedo Connector Programmer's Guide.
binding.atmi/viewFiles32 - Specifies a comma-separated list of Java classes that are extended from the webogic.wtc.jatmi.TypedView32 base class. These derived classes usually are aslo generated from an Oracle Tuxedo VIEW file using the weblogic.wtc.jatmi.viewj32 compiler.
Listing 7‑28 shows an example of composite file for binding declaration of an Oracle Tuxedo service named "ECHO“.
Listing 7‑28 ECHO Composite File
<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:f="binding-atmi.xsd"
name="ECHO">
    <reference name="ECHO" promote="EchoComponent/ECHO">
       <interface.java interface="com.abc.sca.jclient.Echo" />
       <f:binding.atmi requires="legacy">
       <f:inputBufferType target="echoStr">STRING</f:inputBufferType>
         <f:outputBufferType target="echoStr">STRING</f:outputBufferType>
           <f:errorBufferType target="echoStr">STRING</f:errorBufferType>
            <f:workStationParameters>

<f:networkAddress>//STRIATUM:9999,//STRIATUM:1881</f:networkAddr
ess>
            </f:workStationParameters>
            <f:remoteAccess>WorkStation</f:remoteAccess>
        </f:binding.atmi>
    </reference>
    <component name="EchoComponent">
      <implementation.java class="com.abc.sca.jclient.EchoComponentImpl" />
    </component>
</component>
 
Listing 7‑29 shows the interface for the example mentioned in Listing 7‑28.
Listing 7‑29 ECHO Interface
package com.abc.sca.jclient;

import com.oracle.jatmi.AtmiBindingException;

public interface Echo {
        String echoStr(String requestString) throws AtmiBindingException;
}
 
Listing 7‑30 shows an example of an SCA client implementation.
Listing 7‑30 SCA Client Implementation
package com.abc.sca.jclient;

import org.osoa.sca.annotations.Constructor;
import org.osoa.sca.annotations.Reference;
import com.oracle.jatmi.AtmiBindingException;

/**
* A simple client component that uses a reference with a JATMI binding.
*/
public class EchoComponentImpl implements Echo {

       private Echo echoReference;

        @Constructor
       public EchoComponentImpl(@Reference(name = "ECHO", required = true) Echo
 echoReference) {
                this.echoReference = echoReference;
       }

        public String echoStr(String requestString) throws AtmiBindingException {
                return echoReference.echoStr(requestString);
        }
}
 
Python, Ruby, and PHP Binding
The Python, Ruby, and PHP language extensions are binding-independent, meaning that binding extensions are not aware of the language of clients or components. Language extensions are not aware of the binding used.
Binding extensions are not modified to comply with Python, Ruby, and PHP program support. Note the following:
Python, Ruby or PHP programs with a composite scope require an Oracle Tuxedo server reload when the script is modified. A stateless scope allows dynamic reloading of modified scripts.
In order to expose Python, Ruby or PHP scripts as Web services, the SCAHOST command must use the -w option in order to load the correct service binding during initialization.
Note:
SCAHOST does not allow mixing both ATMI and Web services binding types in one SCAHOST instance.
For more information, see the Oracle SALT Command Reference.
TMMETADATA server is required in order to expose Python, Ruby, and PHP components.
Python, Ruby, and PHP Binding Limitations
Using Python, Ruby, and PHP bindings have the following limitations:
When using the ATMI binding for interoperability calls (that is, when requires="legacy" is set), mixing named and non-named parameters is not allowed (for example, Python: def func(a, *b, **c), Ruby: def func(a, *b, hash)), since there is no mechanism to restore the parameter names.
The names of the parameters must be configured in FML32 tables (ATMI binding), or by way of WSDL (Web services binding). It is not possible to interoperate with lists of non-named parameters because such calls cannot be accurately mapped to C++ or WSDL interfaces due to the lack of guaranteed ordering of FML/FML32 Oracle Tuxedo buffers.
The supported modes are:
Multiple parameters: def func(a, b, c) (same syntax for Python, Ruby, and PHP)
Multiple parameters and list of parameters: def func(a, *b) (same syntax for Python and Ruby)
Named parameters: PHP - $svc->searchBike(array('COLOR' => 'RED', 'TYPE' => 'MTB')). For more information, see PHP Data Type Mapping.
Dictionary or hash: Python: def func(**a), Ruby: def func(hash)
Note:
Python parameters defined with ** are considered named parameters. Ruby parameters defined with hash are considered named parameters. For more information, see Python Parameters and Ruby Parameters.
Unicode strings are not supported; accordingly MBSTRING buffers or FLD_MBSTRING fields are not supported.
Web Services Binding
The Web services binding (binding.ws) leverages previously existing Oracle SALT capabilities by funneling Web service traffic through the GWWS gateway. SCA components are hosted in Oracle Tuxedo servers, and communications to and from those servers are performed using the GWWS gateway.
SCA clients using a Web services binding remain unchanged whether the server is running in an Oracle Tuxedo environment or a native Tuscany environment (for example, exposing the component using the Axis2 Web services binding).
Note:
When SCA components are exposed using the Web services binding (binding.ws), tooling performs the generation of WSDF information, metadata entries and FML32 field definitions.
When SCDL code of SCA components to be hosted in an Oracle Tuxedo domain (for example, service elements) contains <binding.ws> elements, the buildscaserver command generates an WSDF entry in a file named service.wsdf where 'service' is the name of the service exposed. An accompanying service.mif and service.fml32 field table files are also generated, based on the contents of the WSDL interface associated with the Web service. You must compose a WSDL interface. If no WSDL interface is found, an error message is generated.
Web services accessed from an Oracle Tuxedo domain using a Web services binding (for example, reference elements found in SCDL) require the following manual configuration steps:
1.
Convert the WSDL file into a WSDF entry by using the wsdlcvt tool. Simultaneously, a Service Metadata Entry file (.mif), and fml32 mapping file are generated.
2.
Make sure that the UBB source has the TMMETADATA and GWWS servers configured
3.
4.
Convert the SALTDEPLOY file into binary using wsloadcf.
5.
Load the Service Metadata Entry file (.mif) into the Service Metadata Repository using the tmloadrepos command.
6.
The Web services binding reference extension initiates the Web services call.
Listing 7‑31 shows an SCA component service exposed as a Web service.
Listing 7‑31 Example SCA Component Service Exposed as a Web Service
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
       name="bigbank.account">
...
   <service name="AccountService">
       <interface.wsdl interface="http://www.bigbank.com/AccountService
              #wsdl.interface(AccountService)"/>
       <binding.ws/>
       <reference>AccountServiceComponent</reference>
   </service>

   <component name="AccountServiceComponent">
       <implementation.cpp
                     library="Account" header="AccountServiceImpl.h"/>
       <reference name="accountDataService">
              AccountDataServiceComponent
       </reference>
   </component>
...
</composite>
 
The steps required to expose the corresponding service are as follows:
1.
2.
Use buildscacomponent to build the application component runtime, similar to building a regular SCA component.
3.
buildscaserver -w is used to convert SCDL code into a WSDF entry, and produce a deployable server (Oracle Tuxedo server + library + SCDL).
The service from the above SCDL creates a WSDF entry as shown in Listing 7‑32.
Listing 7‑32 WSDF Entry
<Definition>
       <WSBinding id="AccountService_binding">
              <ServiceGroup id="AccountService">
                     <Service name="TuxAccountService"/>
              </ServiceGroup>
       </WSBinding>
</Definition>
 
4.
buildscaserver -w also constructs a Service Metadata Repository entry based by parsing the SCDL and interface. The interface needs to be in WSDL form, and manually-composed in this release.
5.
Make sure that the UBB source has the TMMETADATA and GWWS servers configured.
6.
7.
The WSDF file must be imported into the SALTDEPLOY file and SALTDEPLOY converted into binary using wsloadcf.
8.
The Service Metadata Entry file (.mif) is loaded into the Service Metadata Repository.
9.
10.
These steps are required, in addition to the SALTDEPLOY configuration, in order to set up the GWWS gateway for Web services processing (for example, configuration of GWInstance, Server Level Properties, etc.). When completed, Web service clients (SCA or other) have access to the Web service.
Listing 7‑33 shows a reference accessing a Web service.
Listing 7‑33 Example Reference Accessing a Web Service
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
       name="bigbank.account">
...
       <reference name="StockQuoteWebService">
              <interface.wsdl interface="http://www.webserviceX.NET/#
                            wsdl.interface(StockQuoteSoap)"/>
              <binding.ws endpoint="http://www.webserviceX.NET/#
                            wsdl.endpoint(StockQuote/StockQuoteSoap)"/>
       </reference>
...
</composite>
 
The steps required to access the Web service are as follows:
1.
2.
The WSDL file must be converted into a WSDF entry using the wsdlcvt tool. At the same time a Service Metadata Entry file (.mif), and fml32 mapping file is generated.
3.
The WSDF file must be imported into the SALTDEPLOY file and SALTDEPLOY converted into binary using wsloadcf.
4.
The Service Metadata Entry file (.mif) is loaded into the Service Metadata Repository using the tmloadrepos command.
5.
These steps are required, in addition to the SALTDEPLOY configuration, in order to set up the GWWS gateway for Web services processing (for example, configuration of GWInstance, Server Level Properties, etc.). When completed, the SCA client has access to the Web service.
The process is the same, whether the client is stand-alone SCA program or an SCA component (already a server) referencing another SCA component via the Web service binding.
SCA Data Type Mapping
Using ATMI binding leverages the Oracle Tuxedo infrastructure. Data exchanged between SCA components, or Oracle Tuxedo clients/services and SCA clients/components is performed using Oracle Tuxedo typed buffers. Table 7‑1 through Table 7‑10 summarize the correspondence between native types and Oracle Tuxedo buffers/types, as well as SOAP types when applicable.
In the example shown in Listing 7‑34, implementations send and receive an Oracle Tuxedo STRING buffer. To the software (binding and reference extension implementations), the determination of the actual Oracle Tuxedo buffer to be used is provided by the contents of the /binding.atmi/inputBufferType, /binding.atmi/outputBufferType, or /binding.atmi/errorBufferType elements in the SCDL configuration, and the type of buffer returned (or sent) by a server (or client). It does not matter whether client or server is an ATMI program or an SCA component.
Notice that the Oracle Tuxedo simpapp service has its own namespace within namespace services. A C++ method toupper is associated with this service.
Listing 7‑34 C++ Interface Example
#include <string>
namespace services
{
    namespace simpapp
    {
        /**
         * business interface
         */
           class ToupperService
        {
        public:

        virtual std::string
           toupper(const std::string inputString) = 0;
        };

    } // End simpapp
} // End services
 
The following data type mapping rules apply:
Run-Time Data Type Mapping
Simple Oracle Tuxedo Buffer Data Mapping
The following are considered to be simple Oracle Tuxedo buffers:
CARRAY (and X_OCTET)
Table 7‑1 lists simple Oracle Tuxedo buffer types that are mapped to SCA binding.
 
char*, char array or std::string
wchar_t * or wchar_t array
When a service called by an SCA client returns successfully, a pointer to the service return data is passed back to the Proxy stub generated by buildscaclient. The Proxy stub then de-references this pointer and returns the data to the application.
Table 7‑1 can be interpreted as follows:
When the reference or service binding extension runtime sees an Oracle Tuxedo STRING buffer, it looks for either a char*, char array, std::string parameter or return type (depending on the direction). If a different type is found, an exception is thrown with a message explaining what happened.
When the reference or service binding extension runtime sees a char* (for example) as a single parameter or return type, it looks for STRING as the buffer type in the binding.atmi element. If a different Oracle Tuxedo buffer type is found, an exception is thrown with a message explaining what happened.
Multibyte String Data Mapping
Oracle Tuxedo uses multibyte strings to represent multibyte character data with encoding names based on iconv (as defined by Oracle Tuxedo). C++ uses a wstring, wchar_t*, or wchar_t[] data type to represent multibyte character data with encoding names (as defined by the C++ library).
Oracle Tuxedo and C++ sometimes use different names to represent a particular multibyte encoding. Mapping between Oracle Tuxedo encoding names and C++ encoding names is as follows:
When an SCA client or server receives an MBSTRING buffer or an FML32 buffer with a FLD_MBSTRING field, it considers the encoding for that multibyte string to be the first locale from the following cases:
a.
Locale associated with the FLD_MBSTRING field, if present.
Note:
b.
Locale associated with the MBSTRING or FML32 buffer.
c.
If case a or b is matched, Oracle Tuxedo invokes the setlocale() function for locale type LC_CTYPE with the locale for the received buffer. If setlocale() fails (indicating there is no such locale) and an alternate name has been associated with this locale in the optional $TUXDIR/locale/setlocale_alias file, Oracle Tuxedo attempts to set the LC_CTYPE locale to the alternate locale.
The $TUXDIR/locale/setlocale_alias file may be optionally created by the Oracle Tuxedo administrator. If present, it contains a mapping of Oracle Tuxedo MBSTRING codeset names to an equivalent operating system locale accepted by the setlocale() function.
Lines consist of an Oracle Tuxedo MBSTRING codeset name followed by whitespace and an OS locale name. Only the first line in the file corresponding to a particular MBSTRING codeset name are considered. Comment lines begin with #.
The $TUXDIR/locale/setlocale_alias file is used by the SALT SCA software when converting MBSTRING data into C++ wstring or wchar_t[] data. If setlocale() fails when using the Oracle Tuxedo MBSTRING codeset name, then the SALT SCA software attempts to use the alias name, if present. For example, if the file contains a line 'GB2312 zh_CN.GB2312' then if setlocale(LC_CTYPE, 'GB2312') fails, the SALT SCA software attempts setlocale(LC_CTYPE, 'zh_CN.GB2312').
When an SCA client or server converts a wstring, wchar_t[], or wchar_t* to an MBSTRING buffer or a FLD_MBSTRING field, it uses the TPMBENC environment variable value as the locale to set when converting from C++ wide characters to a multibyte string. If the operating system does not recognize this locale, Oracle Tuxedo uses the alternate locale from the $TUXDIR/locale/setlocale_alias file, if any.
Note:
It is possible to transmit multibyte data retrieved from an MBSTRING buffer, an FML32 FLD_MBSTRING field, or a VIEW32 mbstring field. It is also possible to transmit multibyte data entered using the SDO setString() method.
However, it is not possible to enter multibyte characters directly into an XML document and transmit this data via SALT. This is because multibyte characters entered in XML documents are transcoded into multibyte strings, and SDO uses wchar_t arrays to represent multibyte characters.
Complex Return Type Mapping
The following C++ built-in types (used as return types) are considered complex and automatically encapsulated in an FML/FML32 buffer as a single generic field following the complex buffer mapping rules described in Complex Oracle Tuxedo Buffer Data Mapping. This mechanism addresses the need for returning types where a corresponding Oracle Tuxedo buffer cannot be used.
Note:
Interfaces returning any of the built-in types assume that FML/FML32 is the output buffer type. The name of this generic field is TUX_RTNdatatype based on the type of data being returned. TUX_RTNdatatype fields are defined in the Usysflds.h/Usysfl32.h and Usysflds/Usysfl32 shipped with Oracle Tuxedo.
bool : maps to TUX_RTNCHAR field
char: maps to TUX_RTNCHAR field
signed char: maps to TUX_RTNCHAR field
unsigned char: maps to TUX_RTNCHAR field
short: maps to TUX_RTNSHORT field
unsigned short: maps to TUX_RTNSHORT field
int: maps to TUX_RTNLONG field
unsigned int: maps to TUX_RTNLONG field
long: maps to TUX_RTNLONG field
unsigned long: maps to TUX_RTNLONG field
long long: (maps to TUX_RTNLONG field
unsigned long long: maps to TUX_RTNLONG field
float: maps to TUX_RTNFLOAT field
double: maps to TUX_RTNDOUBLE field
long double: maps to TUX_RTNDOUBLE field
Complex Oracle Tuxedo Buffer Data Mapping
The following are considered to be complex Oracle Tuxedo buffers:
VIEW (and X_* equivalents)
Table 7‑2 lists the complex Oracle Tuxedo buffer types that are mapped to SCA binding.
For FML and FML32 buffers, parameter names in interfaces must correspond to field names, and follow the restrictions that apply to Oracle Tuxedo fields (length, characters allowed). When these interfaces are generated from metadata using tuxscagen(1), the generated code contains the properly formatted parameter names.
If an application manually develops interfaces without parameter names, manually develops interfaces that are otherwise incorrect, or makes incompatible changes to SALT generated interfaces, then incorrect results are likely to occur.
VIEW (and X_* equivalents) and VIEW32 buffers require the use of SDO DataObject wrappers.
Listing 7‑35 shows an interface example. The associated field definitions (following the interface) must be present in the process environment.
 
An unsigned int being converted to FML or FML32 is cast to a long before being converted to FLD_LONG or long. An unsigned int being converted to a VIEW or VIEW32 member is cast to an int.
An exception is thrown if the value of a 64-bit long does not fit into a FLD_LONG or long on a 32-bit platform. An unsigned long is cast to long before being converted to FLD_LONG or long.
An exception is thrown if the data value does not fit within a FLD_LONG or long. An unsigned long long is cast to long long before being converted to FLD_LONG or long.
Generate a data transformation exception, which is translated to an ATMIBindingException before being returned to the application, when:
struct structurename
Listing 7‑35 Interface Example
...
int myService(int param1, float param2); ...
Field table definitions
#name         number type          flag comment
#---------------------------------------------------------
param1 20     int           -     Parameter 1
param2 30     float         -     Parameter 2
...
 
SDO Mapping
C++ method prototypes that use commonj::sdo::DataObjectPtr objects as parameter or return types are mapped to an FML, FML32, VIEW, or VIEW32 buffer.
You must provide an XML schema that describes the SDO object. The schema is made available to the service or reference extension runtime by placing the schema file (.xsd file) in the same location as the SCDL composite file that contains the reference or service definition affected. The schema is used internally to associate element names and field names.
Note:
When using view or view32, a schema type (for example, complexType) which name matches the view or view32 used is required.
For more information, see mkfldfromschema and mkfld32fromschema in the SALT 11g Release 1 (11.1.1.2) Command Reference.
For example, a C++ method prototype defined in a header such as:
long myMethod(commonj::sdo::DataObjectPtr data);
Listing 7‑36 shows the associated schema.
Listing 7‑36 Schema
<xsd:schema xmlns:xsd=http://www.w3.org/2001/XMLSchema
     xmlns="http://www.example.com/myExample"
     targetNamespace="http://www.example.com/myExample">

     <xsd:element name="bike" type="BikeType"/>
     <xsd:element name="comment" type="xsd:string"/>

     <xsd:complexType name="BikeType">
         <xsd:sequence>
             <xsd:element name="serialNO" type="xsd:string"/>
             <xsd:element name="name" type="xsd:string"/>
             <xsd:element name="type" type="xsd:string"/>
             <xsd:element name="price" type="xsd:float"/>
         </xsd:sequence>
     </xsd:complexType>
</xsd:schema>
 
Table 7‑3 shows the generated field table.
 
The following restrictions in XML schemas apply:
SCA Utility Data Type Mapping
The scatuxgen and tuxscagen utilities are used to generate manual SCA data type mapping. The scatuxgen mapping rules are as follows:
Note:
The mapping rules for tuxscagen are executed in the reverse direction (Oracle Tuxedo Buffer Type -> C++ Parameter Type).
C++ Parameter/Return Type and Oracle Tuxedo Buffer Type Mapping
Table 7‑4 shows the correspondence between parameter/return types and Oracle Tuxedo buffer types (inbuf service-level keyword).
 
X_COMMON, X_C_TYPE, VIEW, VIEW32, FML, or FML32 depending on intputBufferType setting
X_COMMON, X_C_TYPE, VIEW, VIEW32, FML, or FML32 depending on intputBufferType setting
Table 7‑5shows the correspondence between parameter/return types and Oracle Tuxedo buffer types (outbuf or err buf service-level keywords).
 
X_COMMON, X_C_TYPE, VIEW, VIEW32, FML or FML32 depending on the binding.atmi/outputBufferType or binding.atmi/errorBufferType setting.
FML32 if no binding.atmi is set, or binding.atmi is set and binding.atmi/outputBufferType or binding.atmi/errorBufferType aren't specified.
X_COMMON, X_C_TYPE, VIEW, VIEW32, FML or FML32 depending on the binding.atmi/outputBufferType or binding.atmi/errorBufferType setting.
struct structurename
FML32 if no binding.atmi is set, or binding.atmi is set and binding.atmi/outputBufferType or binding.atmi/errorBufferType are not specified.
C++ Parameter Type and Oracle Tuxedo Parameter Type Mapping
Table 7‑7 shows how scatuxgen handles interface parameter types and converts them to an Oracle Tuxedo Service Metadata Repository parameter-level keyword value when more than one parameter is used in the method signature.
 
struct structurename
C++ Parameter Type and Oracle Tuxedo Complex Type Mapping
This section contains the following topics:
SDO Mapping
When a method takes an SDO object as an argument, or returns an SDO object, for example as follows: commonj::sdo::DataObjectPtr myMethod(commonj::sdo::DataObjectPtr input).
The corresponding runtime type may be described by an XML schema as shown in Listing 7‑37 and then referenced in the binding as shown in Listing 7‑38.
Listing 7‑37 XML Schema
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="tuxedo" targetNamespace="tuxedo">

    <xsd:complexType name="BikeInventory">
        <xsd:sequence>
           <xsd:element name="BIKES" type="Bike"
                       minOccurs="0" maxOccurs="unbounded"/>
           <xsd:element name="STATUS" type="xsd:string" maxOccurs="1"/>
        </xsd:sequence>
    </xsd:complexType>

    <xsd:complexType name="Bike">
        <xsd:sequence>
           <xsd:element name="SERIALNO" type="xsd:string"/>
           <xsd:element name="SKU" type="xsd:string"/>
           <xsd:element name="NAME" type="xsd:string"/>
           <xsd:element name="TYPE" type="xsd:string"/>
           <xsd:element name="PRICE" type="xsd:float"/>
           <xsd:element name="SIZE" type="xsd:int"/>
           <xsd:element name="INSTOCK" type="xsd:string"/>
           <xsd:element name="ORDERDATE" type="xsd:string"/>
           <xsd:element name="COLOR" type="xsd:string"/>
           <xsd:element name="CURSERIALNO" type="xsd:string"/>
        </xsd:sequence>
    </xsd:complexType>

</xsd:schema>
 
Listing 7‑38 Binding
...
  <reference name="UBIK">
    <interface.cpp header="uBikeService.h"/>
    <binding.atmi>
       <inputBufferType>FML32/Bike</inputBufferType>
       <outputBufferType>FML32/BikeInventory</outputBufferType>
    </binding.atmi>
  </reference>
  ...
 
When such a schema is present, scatuxgen parses it and generates the corresponding parameter-level mapping entries as listed in Table 7‑7.
 
mbstring(FLD_MBSTRING) when -t option is specified
C Struct Mapping
When a method takes a C struct as an argument, or returns a C struct (for example, as shown in Listing 7‑39), scatuxgen parses it and generates the corresponding parameter-level mapping entries listed in Table 7‑8.
Listing 7‑39 C Struct
struct customer {
    char firstname[80];
    char lastname[80];
    char address[240];
};

struct id {
    int SSN;
    int zipCode;
};

struct customer* myMethod(struct *id input);
 
 
struct nestedstructname (for more information, see SCA Structure Support)
Parameter and Return Types to Parameter-Level Keyword Restrictions
For parameter-level keywords, the Oracle Tuxedo buffer type/parameter type restrictions are consistent with the contents expected by tmloadrepos. An error message is returned when an attempt to match any combinations that are not listed in Table 7‑9 and Table 7‑10.
 
 
Python, Ruby, and PHP Data Type Mapping
The following sections describe the supported data types in Python, Ruby, and PHP clients or components with respect to the native, C/C++ based environment, and in order to give the correspondence for writing the Oracle Tuxedo Service Metadata Repository interface required by the ATMI binding. Corresponding Oracle Tuxedo buffer and field type are also indicated for uses with the ATMI or Web Services binding.
Python Data Type Mapping
In Python, clients or components only use parameters and return values which types are listed in Table 7‑11. Multiple parameters are supported (in the same way that multiple parameters are supported in C++), using FML32 Oracle Tuxedo buffers.
Note:
 
Notes:
In order to map a string of length 1 to a char*/std::string/STRING, the originating Python variable will have to have 2 ending zeroes (for example, 't = "a\x00").
Supported XML objects in Python must be xml.etree.ElementTree objects, (that is, the language extension converts xml.etree.ElementTree objects into commonj::sdo::DataObjectPtr objects, and commonj::sdo::DataObjectPtr objects into xml.etree.ElementTree objects.
Using lists and dictionaries are also supported, as detailed in Python Parameters and Dictionaries.
Note:
Some limitations concerning multiple parameters and lists will stand with respect to using bindings. For more information, see Python, Ruby, and PHP Binding.
Python Parameters
You can use the list notation (*) to pass an undetermined number of parameters to/from a Python program. For example:
def test(*params)
for p in params:
print "parameter:", p
and an example of call: test(1, 2, 3, 4, 5)
This notation is equivalent to having an actual list of parameters, such as:
def test(parm1, parm2, parm3, parm4, parm5)
...
Individual supported types are limited to the types listed in Table 7‑11.
Exposing a Python function as an SCA service with ATMI or Web services binding requires an interface. This interface is stored in the Oracle Tuxedo Service Metadata Repository as outlined in Python, Ruby, and PHP Component Programming.
When called, the Python function receives a list of parameters corresponding exactly to what the interface specifies. Any extra parameters passed by the client are ignored, and any type mismatch results in a data mapping exception.
Note:
For local calls (no binding specified), or references, no interface is required.
Dictionaries
You can use the named parameters notation (** ) to pass name/value pairs, also known as dictionaries, to/from Python programs. For example:
def test(**params):
for p in params.keys():
print "key:", p, " parameter:", params[p]
and an example of call: test(a=1, b=2)
Individual supported types are limited to the types listed in Table 7‑11.
Exposing a Python function as an SCA service with the ATMI or Web Services binding requires an interface. This interface is stored in the Oracle Tuxedo Service Metadata Repository as outlined in Python, Ruby, and PHP Component Programming.
For example, consider the Oracle Tuxedo Service Metadata Repository entry shown in Listing 7‑40
Listing 7‑40 Oracle Tuxedo Service Metadata Repository Entry for Python
##
service=testPython2
tuxservice=TESTPT
inbuf=FML32
outbuf=FML32

param=NUMBER
type=long
access=in

param=TEXT
type=string
access=in

param=FNUMBER
type=double
access=in
##
 
When called, the Python function receives a list of parameters corresponding exactly to what the interface specifies. Any extra parameters passed by the client are ignored, and any type mismatch results in a data mapping exception.
The names of the parameters match the key names passed to the Python function. The interface is obtained by making an internal call to the TMMETADATA server. The TMMETADATA server must be running in order to make calls to Python, Ruby or PHP functions.
A Python function called with the interface is equivalent to the following Python call:
test(a=1, b=2)
Ruby Data Type Mapping
Table 7‑12 lists supported Ruby, C/C++ and Oracle Tuxedo buffer types. Multiple parameters are supported (in the same way that multiple parameters are supported in C++), using FML32 Oracle Tuxedo buffers.
Arrays are not supported as they are not supported by bindings or the C++ language extension.
 
Notes:
Possible loss of precision when the Ruby Bignum is bigger than a C++ double.
Float (float) is allowed in C++ to Ruby direction only.
There is no mapping to single character (char/FLD_CHAR) possible in Ruby.
Supported XML objects in Ruby must be REXML (that is, the language extension converts REXML::Document objects into commonj::sdo::DataObect objects, and commonj::sdo::DataObjectPtr objects into REXML::Document objects.
Using variable argument lists and hashes are also be supported, as detailed in the following paragraphs.
Note:
Some limitations concerning multiple parameters and lists will stand with respect to using bindings. For more information, see Python, Ruby, and PHP Binding.
Ruby Parameters
You can use the list notation (*) to pass an undetermined number of parameters to/from a Ruby script. For example:
def func(a, b, *otherargs)
puts a
puts b
otherargs.each { |arg| puts arg }
end
which can be called like this: func(1, 2, 3, 4, 5)
Individual supported types are limited to the types listed in Table 7‑12.
Exposing a Ruby function as an SCA service with the ATMI or Web Services binding requires an interface. This interface is stored in the Oracle Tuxedo Service Metadata Repository as outlined in Python, Ruby, and PHP Component Programming.
For example, consider the Oracle Tuxedo Service Metadata Repository entry shown in Listing 7‑41
Listing 7‑41 Oracle Tuxedo Service Metadata Repository Entry for Ruby
##
service=testRuby
tuxservice=TESTRU
inbuf=FML32
outbuf=FML32

param=first
type=char
access=in

param=next
type=long
access=in

param=last
type=string
access=in
##
 
When called, the Ruby function receives a list of parameters corresponding exactly to what the interface specifies. Any extra parameters passed by the client are ignored, and any type mismatch results in a data mapping exception.
Notes:
Local calls (no binding specified), or references, do not require an interface.
Hash
You can use named parameters in the form of hash type parameters to pass name/value pairs to/from Ruby scripts. For example:
def func2(hash)
hash.each_pair do |key, val|
puts "#{key} -> #{val}"
end
end
which can be called like this: func2("first" => true, "next" => 5, "last" => "hi")
Individual supported types are limited to the types listed inTable 7‑12.
When exposing a Ruby function as an SCA service with the ATMI or Web Services binding, an interface is required. This interface is stored in the Oracle Tuxedo Service Metadata Repository as outlined in Python, Ruby, and PHP Component Programming.
When called, the Ruby function receives a list of parameters corresponding exactly to what the interface specifies. Any extra parameters passed by the client are ignored, and any type mismatch results in a data mapping exception.
The names of the parameters match the key names passed to the Ruby function (that is, a Ruby function called with the above interface is equivalent to the following Ruby client call:
func2("first" => true, "next" => 5, "last" => "hi")
where the values 'true', 5 and 'hi' are arbitrary, not the keys.
PHP Data Type Mapping
Table 7‑13 lists supported Ruby, C/C++ and Oracle Tuxedo buffer types. Multiple parameters are supported (in the same way that multiple parameters are supported in C++), using FML32 Oracle Tuxedo buffers.
Arrays are not supported as they are not supported by bindings or the C++ language extension.
 
Returning XML data in PHP is done by returning a STRING object which is then converted into a SimpleXMLElement as follows:
$ret = $svc->searchBike('YELLOW');
$xml = new SimpleXMLElement($ret, LIBXML_NOWARNING);
Once the XML object constructed, it will be accessed as follows:
echo "First serialno:".$xml->BIKES[0]->SERIALNO."\n";
echo "Second serialno:".$xml->BIKES[1]->SERIALNO."\n";
List of Parameters
You are permitted to pass an undetermined number of parameters when making an SCA reference using the PHP extension. For example:
test(1, 2, 3, 4, 5);
Individual supported types are limited to the types listed in Listing 7‑13, with the exception of types originating from or becoming commonj::sdo::DataObjectPtr objects.
Note:
No interface is required.
Named Parameters
You can use named parameters to pass name/value pairs using the PHP SCA extension. For example:
$svc->searchBike(array('COLOR' => 'RED', 'TYPE' => 'MTB'));
Individual supported types are limited to the types listed in Table 7‑13.
SCA Structure Data Type Mapping
In SCA-ATMI applications, an SCA structure parameter can be mapped to an ATMI FML32, FML, VIEW32, VIEW, X_COMMON, or X_C_TYPE data type, and this is the data type that is specified in the SCA composite file.
If a VIEW32, VIEW, X_COMMON, or X_C_TYPE data type is specified, then this view must exactly match the structure used as an SCA parameter or return type.
Note:
SCA Structure and FML32 or FML Mapping
If the SCA structure parameter is mapped to FML32 or FML, then the field type of the associated FML32 or FML field is a type that can be converted to and from the SCA structure data type For more informations, see SCA Data Type Mapping.
FML Field Naming Requirements
In SCA-SCA applications, fields are identified by field number, and FML32 field numbers are automatically generated. In the case of nested structures, field numbers are assigned as if the fields in the inner structure had occurred as flat fields in the outer structure in the place where the inner structure is defined in the outer structure.
In SCA-ATMI applications, the FML32 or FML field name associated with a structure element shall be obtained from the structure description file. For more information, see Using SCA Structure Description Files.
Long Element Truncation
When converting an FML32 or FML string, carray, or mbstring field to a structure element, any data that does not fit in the structure element is truncated (without warning) to the provided length.
For example, if a structure element is char COMPANY_NAME[20]; and FML field COMPANY_NAME with value "International Business Machines" is mapped to this structure element, then "International Busine" is copied to the structure element with no trailing null character.
SCA Structure and VIEW32, VIEW, X_OCTET, or X_C_TYPE Mapping
If an SCA structure is mapped to a VIEW32, VIEW, X_OCTET, or X_C_TYPE data type, then the structure used for the Oracle Tuxedo view-based type must exactly match the SCA structure, and is copied byte-by-byte. In other words, no marshalling of data is done when converting between an SCA structure, and a view. FML32 or FML should be used if data marshalling is required.
When an SCA structure is mapped to a view-based Oracle Tuxedo type, you cannot specify bool, wchar_t, long long, unsigned long long, long double, or nested structure data types within the SCA structure since corresponding data types do not exist within Oracle Tuxedo views. Elements corresponding to any Oracle Tuxedo Associated Count Member or Associated Length Member fields must be provided. Appropriate values for any such elements must also be provided by the application if converting an SCA structure to an Oracle Tuxedo view.
SCA Structure and Mbstring Mapping
An mbstring field type currently exists in VIEW32 (for more information, see tpconvvmb32). SCA structures treat the mbstring field type in the same way as in VIEW32. The encoding information is part of an mbstring structure element, and Fmbunpack32() and Fmbpack32() must be used in application programs using mbstring data in structures.
TPFAIL Return Data
You can specify a structure pointer as data returned on TPFAIL if the same structure pointer is also returned on successful output. Since SCA must store internal information describing the returned structure along with the application data, <tuxsca.h> is used to define the structure and typedef as shown in Listing 7‑42.
Listing 7‑42 <tuxsca.h> SCA Structure and Typedef Definition
struct scastruct_t {
  void *data;
  void *internalinfo;
};
typedef struct scastruct_t *SCASTRUCT_PTR;
 
If an application normally returns "struct mystruct *" data, it accesses TPFAIL data as shown in Listing 7‑42.
Listing 7‑43 TPFAIL Example
… catch (Tuscany::sca::atmi::ATMIBindingException& abe) {
  SCASTRUCT_PTR *scap = (SCASTRUCT_PTR *)abe.getData();
  struct mystruct *result = (struct mystruct *)scap->data;
}
 
SCA and Oracle Tuxedo Interoperability
Existing Oracle Tuxedo service interoperability is performed by using the /binding.atmi/@requires attribute with the legacy value. When a legacy value is specified, invocations are performed using the following behavior:
If a <map> element is present in either a <reference> or a <service>, that value is used to determine which Oracle Tuxedo service is associated with the specified method name to call or advertise.
Otherwise:
In a <reference> element: the value specified in the /reference/@name element is used to perform the Oracle Tuxedo call, with semantics according to the interface method used.
In a <service> element: the Oracle Tuxedo service specified in the /binding.atmi/map element is advertised, and mapped to the method specified in the /binding.atmi/map/@target attribute.
Additionally, the /binding.atmi/@requires attribute is used to internally control data mapping, such that FML32 or FML field tables are not required.
Note:
When not specified, communications are assumed to have SCA -> SCA semantics where the actual Oracle Tuxedo service name is constructed from /service/@name or /reference/@name and actual method name (see the pseudo schema shown Listing 7‑27).
SCA Transactions
The ATMI binding schema supports SCA transaction policies by using the /binding.atmi/@requires attribute and three transaction values. These transaction values specify the transactional behavior that the binding extension follows when ATMI binding is used (see the pseudo schema shown Listing 7‑27).
The transaction values are as follows:
All transactional behavior is left up to the Oracle Tuxedo configuration. If the Oracle Tuxedo configuration supports transactions, then a transaction can be propagated if it exists.
If the Oracle Tuxedo configuration does not support transactions and a transaction exists, then an error occurs.
Note:
When specified, the transaction context is not propagated to the service called. For a <service>, the transaction (if present), is automatically suspended before invoking the application code, and resumed afterwards, regardless of the outcome of the invocation. For a <reference>, equivalent to making a tpcall() with the TPNOTRAN flag.
Only applicable to <reference> elements, ignored for <service> elements. Starts a new transaction if one does not already exist, otherwise participate in existing transaction. Such a behavior can be obtained in a component or composite <service> by configuring it AUTOTRAN in the UBBCONFIG. An error is generated if an Oracle Tuxedo server hosts the SCA component implementation and is not configured in a transactional group in the UBBCONFIG.
SCA Security
SCA references pass credentials using the <authentication> element of the binding.atmi SCDL element.
SCA services can be ACL protected by referencing their internal name: /binding.atmi/service/@name attribute followed by a '/' and method name in SCA -> SCA mode, /binding.atmi/service/@name attribute in legacy mode (SCA -> Tux interop mode).
For more information, see SCA and Oracle Tuxedo Interoperability.
See Also
http://www.osoa.org/download/attachments/36/CPP-SDO-Spec-v2.1.0-FINAL.pdf?version=2
http://www.osoa.org/download/attachments/35/SCA_AssemblyModel_V096.pdf?version=1
http://www.osoa.org/download/attachments/35/SCA_ClientAndImplementationModelforCpp_V0.95.pdf?version=1

Copyright © 1994, 2017, Oracle and/or its affiliates. All rights reserved.