From bdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a Mon Sep 17 00:00:00 2001 From: dims Date: Tue, 17 Jun 2008 00:23:01 +0000 Subject: Move Tuscany from Incubator to top level. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@668359 13f79535-47bb-0310-9956-ffa450edef68 --- .../cpp-M1/sca/doc/CreatingSCACPPComponents.txt | 281 +++++++++++++++++++++ branches/cpp-M1/sca/doc/WSEntrypoint.txt | 272 ++++++++++++++++++++ branches/cpp-M1/sca/doc/css/maven-base.css | 147 +++++++++++ branches/cpp-M1/sca/doc/css/maven-theme.css | 125 +++++++++ 4 files changed, 825 insertions(+) create mode 100644 branches/cpp-M1/sca/doc/CreatingSCACPPComponents.txt create mode 100644 branches/cpp-M1/sca/doc/WSEntrypoint.txt create mode 100644 branches/cpp-M1/sca/doc/css/maven-base.css create mode 100644 branches/cpp-M1/sca/doc/css/maven-theme.css (limited to 'branches/cpp-M1/sca/doc') diff --git a/branches/cpp-M1/sca/doc/CreatingSCACPPComponents.txt b/branches/cpp-M1/sca/doc/CreatingSCACPPComponents.txt new file mode 100644 index 0000000000..17f6430b79 --- /dev/null +++ b/branches/cpp-M1/sca/doc/CreatingSCACPPComponents.txt @@ -0,0 +1,281 @@ +Creating SCA Components in Tuscany SCA C++ +========================================== + +This document describes how to create and run SCA components in Tuscany SCA C++ +milestone release 1. + + +Creating and deploying an SCA C++ Component +=========================================== + +Each SCA C++ component needs: + o A service header file that defines the operations that can be invoked on the + component + o An implementation header file that defines the implementation and extends + the service header file + o A C++ implementation of the service that implements the operations defined + in the service header file + o Proxy and wrapper header and implementation files generated by the Tuscany + C++ SCAGEN tool + o A component definition in the module sca.module file + o A service definition in a .componentType file + o A module component definition in a sca.subsystem file + + +In this section we will use the Calculator sample as a worked example. +The Calculator code and files can be found at samples/Calculator and has been +developed further than the details specified below. In the interests of +readability, the example used below takes the simplest path. + + +1. Create the service header file that defines the operations your component + will implement. E.g. Calculator.h contains the following: + +#ifndef CALCULATOR_H +#define CALCULATOR_H +class Calculator +{ +public: + virtual float add(float arg1, float arg2) = 0; + virtual float sub(float arg1, float arg2) = 0; + virtual float mul(float arg1, float arg2) = 0; + virtual float div(float arg1, float arg2) = 0; +}; + +#endif + + +2. Create the implementation header file that extends the service header file. + E.g. CalculatorImpl.h contains the following: + +#ifndef CALCULATORIMPL_H +#define CALCULATORIMPL_H + +#include "Calculator.h" + +class CalculatorImpl : public Calculator +{ +public: + CalculatorImpl(); + virtual ~CalculatorImpl(); + + // Calculator interface + virtual float add(float arg1, float arg2); + virtual float sub(float arg1, float arg2); + virtual float mul(float arg1, float arg2); + virtual float div(float arg1, float arg2); +}; + +#endif + + +3. Create the implementation for the component based on the implementation + header file. E.g. CalculatorImpl.cpp contains the following code: + +#include "CalculatorImpl.h" +#include + +CalculatorImpl::CalculatorImpl() +{ +} + +CalculatorImpl::~CalculatorImpl() +{ +} + +// Calculator interface +float CalculatorImpl::add(float arg1, float arg2) +{ + float result = arg1 + arg2; + + printf("CalculatorImpl::add %f + %f = %f\n", arg1, arg2, result); + return result; +} + +float CalculatorImpl::sub(float arg1, float arg2) +{ + float result = arg1 - arg2; + printf("CalculatorImpl::sub %f - %f = %f\n", arg1, arg2, result); + return result; +} + +float CalculatorImpl::div(float arg1, float arg2) +{ + float result = arg1 / arg2; + printf("CalculatorImpl::div %f / %f = %f\n", arg1, arg2, result); + return result; +} + +float CalculatorImpl::mul(float arg1, float arg2) +{ + float result = arg1 * arg2; + printf("CalculatorImpl::mul %f * %f = %f\n", arg1, arg2, result); + return result; +} + + +4. Create the componentType file for your component to define the service that + your component provides. The file must be named after your implementation + class and specifies the name of the service and the service header file + (which describes the service operations). E.g. CalculatorImpl.componentType + contains the following XML: + + + + + + + + + + +5. Create the sca.module file for your module and define your component within + it. The component definition specifies the implementation library to use (a + .dll file on Windows and a .so file on Linux) and the implementation header + file (which describes the implementation class). Component properties and + references to other services can also be specified here. E.g. the + Calculator sca.module file contains the following XML: + + + + + + + + + + + + + +6. Generate the proxy and wrapper classes and header files using the SCAGEN + tool. These classes are used by the Tuscany SCA C++ runtime to enable + service implementations to be invoked from a client or another component. + Run the SCAGEN tool, specifying the directory where your header files, + sca.module and componentType file are and the directory where you + want the generated files to be placed. E.g. on Windows, the + following command is run from the directory where Tuscany SCA is deployed: + +bin/scagen.cmd -dir samples/Calculator/CalculatorModule -output samples/Calculator/CalculatorModule + + which produces the following files: + +CalculatorImpl_CalculatorService_Proxy.h +CalculatorImpl_CalculatorService_Proxy.cpp +CalculatorImpl_CalculatorService_Wrapper.h +CalculatorImpl_CalculatorService_Wrapper.cpp + + +7. Compile and link the code that has been written and generated. This will + produce a .dll or .so library file. The name should match the library name + specified in the sca.module file. + + +8. Create the sca.subsystem file and define your module component within it. + The module component definition should specify the service name used in the + componentType file and the module name used in the sca.module file. E.g. + the Calculator sca.subsystem file contains the following XML: + + + + + + + + +9. Deploy the various files into the SCA directory structure, as follows: + +/modules/ModuleName/ServiceHeader.h +/modules/ModuleName/ImplementationHeader.h +/modules/ModuleName/sca.module +/modules/ModuleName/Implementation.componentType +/modules/ModuleName/Implementation.dll (or .so on Linux) +/subsystems/SubsystemName/sca.subsystem + + E.g. for the Calculator sample the structure is: + +samples/Calculator/deploy/modules/CalculatorModule/Calculator.h +samples/Calculator/deploy/modules/CalculatorModule/CalculatorImpl.h +samples/Calculator/deploy/modules/CalculatorModule/sca.module +samples/Calculator/deploy/modules/CalculatorModule/CalculatorImpl.componentType +samples/Calculator/deploy/modules/CalculatorModule/Calculator.dll +samples/Calculator/deploy/subsystems/CalculatorSubsystem/sca.subsystem + + +10. Your component, module and subsystem are now ready to be invoked. Create a + client that will call the service. E.g. the Calculator client (in the + Calc.cpp file) contains code similar to the following: + +try +{ + // Define and start the Tuscany runtime: + // Set the system root path that contains the SCA directory structure, set + // the default module component that will be used based on the format + // / and then start the runtime + TuscanyRuntime rt; + rt.setSystemRoot("C:/tuscany_sca/samples/Calculator/deploy"); + rt.setDefaultModuleComponent("CalculatorSubsystem/CalculatorService"); + rt.start(); + + + // Locate the service + ModuleContext myContext = ModuleContext::getCurrent(); + Calculator *calcService = (Calculator*) myContext.locateService("CalculatorServiceComponent"); + if (calcService == 0) + { + cout << "MyCalculatorClient.exe: Unable to find Calculator service" << endl; + } + else + { + result = calcService->add(arg1, arg2); + cout << "Calculator: add(" << arg1 << "," << arg2 << ") = " << result << endl; + } +} +catch (ServiceRuntimeException& ex) +{ + cout << "MyCalculatorClient.exe: Error whilst starting or invoking Tuscany: " << + ex.getMessageText() << endl; +} + + +11. Compile, link and run the client that has been created. You should + (hopefully!) see your component invoked. 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 (or LD_LIBRARY_PATH on Linux). 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.92-win32 +set PATH=%PATH%;C:/tuscany_sca/bin;C:/tuscany_sdo/bin;C:/axis2c-bin-0.92-win32/lib +./MyCalculatorClient.exe + + +12. 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 + + +Further Steps +------------- + +The Calculator sample has been developed further than the details specified +above. In particular, it demonstrates how two services can be wired together +such that one references and invokes the other. It also demonstrates how to +expose the Calculator component service as an Axis2C Web Service. See the +WSEntrypoint.txt document for more details on exposing components as Web +Services. + + + diff --git a/branches/cpp-M1/sca/doc/WSEntrypoint.txt b/branches/cpp-M1/sca/doc/WSEntrypoint.txt new file mode 100644 index 0000000000..7e59008cae --- /dev/null +++ b/branches/cpp-M1/sca/doc/WSEntrypoint.txt @@ -0,0 +1,272 @@ +Web Services EntryPoint +======================= + +This section of the document describes the use of the Web Service EntryPoint +(WS EntryPoint) support in the Apache Tuscany SCA C++ runtime. + +The WS EntryPoint code is based on Apache Axis2C version 0.92 +(http://ws.apache.org/axis2/c) and allows SCA components to be invoked via Web +Service calls. + +WS EntryPoint 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. + + +Defining and deploying an SCA Module with a WS EntryPoint +========================================================= + +In this section we will use the Calculator sample as a worked example. +The Calculator code and files can be found at sca/samples/Calculator. + +Pre-requisites: + + o A working component within a module and subsystem, with SCAGEN generated + Proxy and Wrapper classes and a DLL or SO library compiled from these and + the component class files. The sca.module, *.componentType, *.fragment and + sca.subsystem files must also be available and working + +1. 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 needs to be accessible from the component, +so place it in the same directory as the component or in a subdirectory. + +See the sca/samples/Calculator/CalculatorModule/Calculator.wsdl file as an +example. + + +2. Add an EntryPoint definition to the sca.module file, setting the +interface.wsdl interface attribute to the WSDL file defined above, the +reference element to the name of the component to be invoked and the binding.ws +port attribute to the namespace, service and port name specified in the +WSDL, in the form: "#wsdl.endpoint(/)". +Also give the EntryPoint a name and set the multiplicity. + +E.g. for the Calculator component, based on the Calculator.wsdl file: + + + + + + CalculatorServiceComponent + + + +3. Create a file named Tuscany-model.config in the same directory as your +component. This file defines which WSDL and XML Schema files to include in the +Tuscany runtime environment for this module. Set the contents of the file +using the example below and use the path and name of the WSDL file created +above. + +E.g. for the Calculator component + + + + + + + + + + +These changes are all that are required in the Tuscany runtime environment to +expose a component as a Web Service; the following steps detail how to add the +Web Service to the list of Axis2C services. + + +4. Create a new directory within the Axis2C services directory. The name of +this directory defines the URL of your service. For example, if you create a +directory named "CalcWebService", the URL of the service will be +http://localhost:9090/axis2/services/CalcWebService + + +5. Create a file named services.xml within the new directory. This file defines +the library to use that contains the service code and the operations that the +service exposes. For the Tuscany WS EntryPoint, you also need to add some +Tuscany specific parameters to identify the Tuscany System Root directory and +the EntryPoint that will be invoked. + +The TuscanySystemRoot parameter requires the full path to your system root +directory - this is the directory that contains the "modules" and "subsystem" +directories; which in turn contain your modules and subsystems. + +The TuscanyEntryPoint parameter is of the form +"//", with the subsystem and +service names defined in your sca.subsystem file and the EntryPoint name +defined in the EntryPoint definition you added to your sca.module file above. + +Set the ServiceClass parameter to "tuscany_sca_ws_service" as this library +(tuscany_sca_ws_service.dll on Windows and libtuscany_sca_ws_service.so on +Linux) contains the service code that will invoke your component. + +Finally, add all of the operations that your component defines that you want +to expose as Web Service operations. + +E.g. for the Calculator WS EntryPoint, +axis2c/services/CalcWebService/services.xml contains: + + + + tuscany_sca_ws_service + C:/tuscany/cpp/sca/samples/runtime + CalculatorSubsystem/CalculatorService/WSCalculatorEntrypoint + + + + + + + + + +6. Copy the tuscany_sca_ws_service.dll file (or the +libtuscany_sca_ws_service.so file, if on Linux) to the new service directory +you created above. This library contains the code that Axis2C requires to call +a service implementation and links to the tuscany_sca.dll library (or +libtuscany_sca.so on Linux) which manages the invocation of your component. + + +7. Ensure the TUSCANY_SCACPP, TUSCANY_SDOCPP, AXIS2C_HOME and PATH environment +variables are correctly set + +E.g. on Windows run the following commands with the correct directories: +set TUSCANY_SCACPP=C:/path_to_tuscany/sca/deploy +set TUSCANY_SDOCPP=C:/path_to_tuscany/sdo/deploy +set AXIS2C_HOME=C:/path_to_axis2c0.92 +set PATH=%PATH%;C:/path_to_tuscany/sca/deploy/bin;C:/path_to_tuscany/sdo/deploy/bin;C:/path_to_axis2c0.92/lib + + +8. Optionally, enable logging in Tuscany 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 + +Additionally, Axis2C automatically writes logging files to the Axis2C logs +directory (e.g. C:/path_to_axis2c0.92/logs). In particular the Axis2.log file +may contain useful information about your service. + + +9. Start the Simple Axis server, or your Apache HTTP server if you have +deployed Axis2C to Apache. + +E.g. on Windows run the following commands: +cd C:/path_to_axis2c0.92/bin +./axis2_http_server.exe + + +Your component should now be exposed as an Axis2C Web Service, via the WS +EntryPoint 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: http://ws.apache.org/axis2), or you can invoke your +component from another Tuscany runtime by using Tuscany's WS External Service +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 (available from the Tuscany website) for the C++ types that +SDO supports. + + + XML Schema Type | C++ Type +------------------------------------------------------------- + | + string | char* + | + int | long + | + integer | long + | + short | short + | + float | float + | + double | long double + | + boolean | bool + | + hexBinary | char* + | + base64Binary | char* + | + byte | char + | + complexType | SDO DataObjectPtr + | + any | SDO DataObjectPtr with OpenDataObjectType + + + +Notes on creating WSDL +====================== + + o 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 the article at http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/ + for an explanation of Document/literal Wrapped style WSDL and Web Services + + o Operation parameter and return messages that are defined in the WSDL must be + XML Schema elements containing a complexType - there is currently no + support for simpleTypes or single-level elements. Also, Document/literal + Wrapped services require that the operation name is used as the name of the + incoming element that wraps the operation parameters. + + For example, a component operation defined in C++ as: + + long myOperation(char* arg1, short arg2, DataObjectPtr arg3); + + will need to be described in WSDL with messages like: + + + + + + + + + and will need an XML schema to define the types like: + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/branches/cpp-M1/sca/doc/css/maven-base.css b/branches/cpp-M1/sca/doc/css/maven-base.css new file mode 100644 index 0000000000..314da3a272 --- /dev/null +++ b/branches/cpp-M1/sca/doc/css/maven-base.css @@ -0,0 +1,147 @@ +body { + margin: 0px; + padding: 0px; +} +img { + border:none; +} +table { + padding:0px; + width: 100%; + margin-left: -2px; + margin-right: -2px; +} +acronym { + cursor: help; + border-bottom: 1px dotted #feb; +} +table.bodyTable th, table.bodyTable td { + padding: 2px 4px 2px 4px; + vertical-align: top; +} +div.clear{ + clear:both; + visibility: hidden; +} +div.clear hr{ + display: none; +} +#bannerLeft, #bannerRight { + font-size: xx-large; + font-weight: bold; +} +#bannerLeft img, #bannerRight img { + margin: 0px; +} +.xleft, #bannerLeft img { + float:left; + text-shadow: #7CFC00; +} +.xright, #bannerRight img { + float:right; + text-shadow: #7CFC00; +} +#banner { + padding: 0px; +} +#banner img { + border: none; +} +#breadcrumbs { + padding: 3px 10px 3px 10px; +} +#leftColumn { + width: 150px; + float:left; +} +#bodyColumn { + margin-right: 1.5em; + margin-left: 177px; +} +#legend { + padding: 8px 0 8px 0; +} +#navcolumn { + padding: 8px 4px 0 8px; +} +#navcolumn h5 { + margin: 0; + padding: 0; + font-size: small; +} +#navcolumn ul { + margin: 0; + padding: 0; + font-size: small; +} +#navcolumn li { + list-style-type: none; + background-image: none; + background-repeat: no-repeat; + background-position: 0 0.4em; + padding-left: 16px; + list-style-position: ouside; + line-height: 1.2em; + font-size: smaller; +} +#navcolumn li.expanded { + background-image: url(../images/expanded.gif); +} +#navcolumn li.collapsed { + background-image: url(../images/collapsed.gif); +} +#poweredBy { + text-align: center; +} +#navcolumn img { + margin-top: 10px; + margin-bottom: 3px; +} +#poweredBy img { + display:block; + margin: 20px 0 20px 17px; + border: 1px solid black; + width: 90px; + height: 30px; +} +#search img { + margin: 0px; + display: block; +} +#search #q, #search #btnG { + border: 1px solid #999; + margin-bottom:10px; +} +#search form { + margin: 0px; +} +#lastPublished { + font-size: x-small; +} +.navSection { + margin-bottom: 2px; + padding: 8px; +} +.navSectionHead { + font-weight: bold; + font-size: x-small; +} +.section { + padding: 4px; +} +#footer { + padding: 3px 10px 3px 10px; + font-size: x-small; +} +#breadcrumbs { + font-size: x-small; + margin: 0pt; +} +.source { + padding: 12px; + margin: 1em 7px 1em 7px; +} +.source pre { + margin: 0px; + padding: 0px; +} diff --git a/branches/cpp-M1/sca/doc/css/maven-theme.css b/branches/cpp-M1/sca/doc/css/maven-theme.css new file mode 100644 index 0000000000..5c8e7b4abf --- /dev/null +++ b/branches/cpp-M1/sca/doc/css/maven-theme.css @@ -0,0 +1,125 @@ +body { + padding: 0px 0px 10px 0px; +} +body, td, select, input, li{ + font-family: Verdana, Helvetica, Arial, sans-serif; + font-size: 13px; +} +code{ + font-family: Courier, monospace; + font-size: 13px; +} +a { + text-decoration: none; +} +a:link { + color:#36a; +} +a:visited { + color:#47a; +} +a:active, a:hover { + color:#69c; +} +#legend li.externalLink { + background: url(../images/external.png) left top no-repeat; + padding-left: 18px; +} +a.externalLink, a.externalLink:link, a.externalLink:visited, a.externalLink:active, a.externalLink:hover { + background: url(../images/external.png) right center no-repeat; + padding-right: 18px; +} +#legend li.newWindow { + background: url(../images/newwindow.png) left top no-repeat; + padding-left: 18px; +} +a.newWindow, a.newWindow:link, a.newWindow:visited, a.newWindow:active, a.newWindow:hover { + background: url(../images/newwindow.png) right center no-repeat; + padding-right: 18px; +} +h2 { + padding: 4px 4px 4px 6px; + border: 1px solid #999; + color: #900; + background-color: #ddd; + font-weight:900; + font-size: x-large; +} +h3 { + padding: 4px 4px 4px 6px; + border: 1px solid #aaa; + color: #900; + background-color: #eee; + font-weight: normal; + font-size: large; +} +h4 { + padding: 4px 4px 4px 6px; + border: 1px solid #bbb; + color: #900; + background-color: #fff; + font-weight: normal; + font-size: large; +} +h5 { + padding: 4px 4px 4px 6px; + color: #900; + font-size: normal; +} +p { + line-height: 1.3em; + font-size: small; +} +#breadcrumbs { + border-top: 1px solid #aaa; + border-bottom: 1px solid #aaa; + background-color: #ccc; +} +#leftColumn { + margin: 10px 0 0 5px; + border: 1px solid #999; + background-color: #eee; +} +#navcolumn h5 { + font-size: smaller; + border-bottom: 1px solid #aaaaaa; + padding-top: 2px; + color: #000; +} + +table.bodyTable th { + color: white; + background-color: #bbb; + text-align: left; + font-weight: bold; +} + +table.bodyTable th, table.bodyTable td { + font-size: 1em; +} + +table.bodyTable tr.a { + background-color: #ddd; +} + +table.bodyTable tr.b { + background-color: #eee; +} + +.source { + border: 1px solid #999; +} +dl { + padding: 4px 4px 4px 6px; + border: 1px solid #aaa; + background-color: #ffc; +} +dt { + color: #900; +} +#organizationLogo img, #projectLogo img, #projectLogo span{ + margin: 8px; +} +#banner { + border-bottom: 1px solid #fff; +} -- cgit v1.2.3