summaryrefslogtreecommitdiffstats
path: root/sca-cpp/branches/cpp-M1/sca/doc/CreatingSCACPPComponents.txt
diff options
context:
space:
mode:
Diffstat (limited to 'sca-cpp/branches/cpp-M1/sca/doc/CreatingSCACPPComponents.txt')
-rw-r--r--sca-cpp/branches/cpp-M1/sca/doc/CreatingSCACPPComponents.txt281
1 files changed, 281 insertions, 0 deletions
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 <stdio.h>
+
+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:
+
+<?xml version="1.0" encoding="ASCII"?>
+<componentType xmlns="http://www.osoa.org/xmlns/sca/0.9"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <service name="CalculatorService">
+ <interface.cpp header="Calculator.h"/>
+ </service>
+</componentType>
+
+
+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:
+
+<?xml version="1.0" encoding="ASCII"?>
+<module xmlns="http://www.osoa.org/xmlns/sca/0.9"
+ xmlns:v="http://www.osoa.org/xmlns/sca/values/0.9"
+ name="CalculatorModule">
+
+ <!-- The Calculator component -->
+ <component name="CalculatorServiceComponent">
+ <implementation.cpp dll="Calculator.dll" header="CalculatorImpl.h"/>
+ <properties></properties>
+ <references></references>
+ </component>
+</module>
+
+
+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:
+
+<?xml version="1.0" encoding="ASCII"?>
+<subsystem xmlns="http://www.osoa.org/xmlns/sca/0.9"
+ name="CalculatorSubsystem">
+
+ <moduleComponent name="CalculatorService" module="CalculatorModule"/>
+</subsystem>
+
+
+9. Deploy the various files into the SCA directory structure, as follows:
+
+<deploy_root>/modules/ModuleName/ServiceHeader.h
+<deploy_root>/modules/ModuleName/ImplementationHeader.h
+<deploy_root>/modules/ModuleName/sca.module
+<deploy_root>/modules/ModuleName/Implementation.componentType
+<deploy_root>/modules/ModuleName/Implementation.dll (or .so on Linux)
+<deploy_root>/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
+ // <SubsystemName>/<ModuleComponentName> 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.
+
+
+