From 8759a126a1bb9eec550c37b5b14642b0cfeb797b Mon Sep 17 00:00:00 2001 From: jsdelfino Date: Mon, 16 Nov 2009 06:23:13 +0000 Subject: Cleaning up SVN structure, moving branch under sca-cpp/branches. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@880612 13f79535-47bb-0310-9956-ffa450edef68 --- .../cpp-M1/sca/doc/CreatingSCACPPComponents.txt | 281 +++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 sca-cpp/branches/cpp-M1/sca/doc/CreatingSCACPPComponents.txt (limited to 'sca-cpp/branches/cpp-M1/sca/doc/CreatingSCACPPComponents.txt') diff --git a/sca-cpp/branches/cpp-M1/sca/doc/CreatingSCACPPComponents.txt b/sca-cpp/branches/cpp-M1/sca/doc/CreatingSCACPPComponents.txt new file mode 100644 index 0000000000..17f6430b79 --- /dev/null +++ b/sca-cpp/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. + + + -- cgit v1.2.3