summaryrefslogtreecommitdiffstats
path: root/sca-cpp/trunk/contrib/doc/CppExtension.html
blob: 6e7420a9d40522efcd86121e9b68f15ad1bd2873 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<!--
   Licensed to the Apache Software Foundation (ASF) under one
   or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
   regarding copyright ownership.  The ASF licenses this file
   to you under the Apache License, Version 2.0 (the
   "License"); you may not use this file except in compliance
   with the License.  You may obtain a copy of the License at
   
     http://www.apache.org/licenses/LICENSE-2.0
     
   Unless required by applicable law or agreed to in writing,
   software distributed under the License is distributed on an
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   KIND, either express or implied.  See the License for the
   specific language governing permissions and limitations
   under the License.
-->

<HTML>
<HEAD>
   <META CONTENT="text/html; charset=iso-8859-1" HTTP-EQUIV="Content-Type">
   <META CONTENT="text/css" HTTP-EQUIV="Content-Style-Type">
   <STYLE MEDIA="all" TYPE="text/css">
@import url("css/maven-base.css");
@import url("css/maven-theme.css");
   </STYLE> 

    <LINK HREF="css/maven-theme.css" MEDIA="print" REL="stylesheet"
         TYPE="text/css">
   <TITLE>Tuscany SCA Native - Creating C++ SCA Components</TITLE>
</HEAD>

<BODY>
<DIV ID="bodyColumn"> 
   <DIV ID="contentBox"> 
      <DIV CLASS="section"> 
         <H1>Tuscany SCA Native - C++ Extension</H1> 
         <P>The Tuscany C++ extension allows C++ classes to be used as components in
            SCA composites and as clients that can invoke SCA services.
         </P>
         <P>This document describes how to build and install the C++ extension and create and run SCA 
            components in Tuscany SCA Native milestone release 3.
         </P>
         <P>See the <A HREF="http://www.osoa.org/display/Main/Service+Component+Architecture+Specifications">SCA 
            C++ Client and Implementation specification</A> for more details about the SCA C++ 
            programming model.            
         </P>
         <P>See <A HREF="../samples/CppCalculator/README.html">CppCalculator</A> or 
            <A HREF="../samples/CppBigBank/README.html">CppBigBank</A> for samples that 
            demonstrate the use of C++ components                    
         </P>
      </DIV>

      <DIV CLASS="section"> 
         <H2>Contents</H2> 
         <OL>
            <LI><A HREF="#requirements">System Requirements</A></LI>
            <LI><A HREF="#install">Installing the Tuscany SCA C++ Extension..</A>
                <UL>
                    <LI><A HREF="#linuxbin">..from the binary release on Linux and Mac OS X</A></LI>
                    <LI><A HREF="#linuxsrc">..from the source release on Linux and Mac OS X</A></LI>
                    <LI><A HREF="#winbin">..from the binary release on Windows</A></LI>
                    <LI><A HREF="#winsrc">..from the source release on Windows</A></LI>
                </UL></LI>
            <LI><A HREF="#components">Creating and deploying an SCA C++ Component</A></LI>
            <LI><A HREF="#help">Getting help</A></LI>
         </OL>
      </DIV>
     <DIV CLASS="section"> 
         <A NAME="requirements"><H2>System Requirements</H2></A>

         <P>In order to install and use the Tuscany SCA C++ Extension there are some
         extra requirements in addition to the <A HREF="../GettingStarted.html#requirements">Tuscany 
         SCA requirements</A>:</P> 
         <TABLE CLASS="bodyTable">

            <TBODY>
            <TR CLASS="a">
               <TD><B>Software</B></TD>
               <TD><B>Download Link</B></TD>
            </TR>
            <TR CLASS="b">
                <TD>Java SDK 1.4 or later</TD>
                <TD><A HREF="http://java.sun.com/javase/downloads/index.jsp" 
                       TARGET="_blank">http://java.sun.com/javase/downloads</A><BR/>
                    For building and running the SCAGEN code generation tool, which is used when developing 
                    Tuscany SCA C++ components. Please download and follow the installation instructions</TD>
            </TR>        
            <TR CLASS="a">
                <TD>Apache Ant 1.6 or later</TD>
                <TD><A HREF="http://ant.apache.org" TARGET="_blank">http://ant.apache.org</A><BR/>
                    For building the SCAGEN code generation tool. This is only required when building
                    the C++ extension from a source distribution of Tuscany SCA Native.
                    Please download and follow the installation instructions</TD>
            </TR>
            </TBODY>
         </TABLE>
      </DIV> 

      <DIV CLASS="section"> 
         <A NAME="install"><H2>Installing the Tuscany SCA C++ Extension</H2></A>
         <A NAME="linuxbin"><H3>Getting the Tuscany SCA C++ Extension working with the binary release on Linux and Mac OS X</H3></A>
          <OL>
              <LI>Add the &lt;tuscany_sca_install_dir&gt;/extensions/cpp/lib directory to the PATH environment variable</LI>
          </OL>
         <A NAME="linuxsrc"><H3>Getting the Tuscany SCA C++ Extension working with the source release on Linux and Mac OS X</H3></A>
          <OL>
              <LI>You will need the Tuscany SCA kernel and SDO libraries - follow the instructions 
                  <A HREF="../GettingStarted.html">here</A> to build the SCA libraries and default extensions</LI>
              <LI>The following environment variables are required:                                 
                <UL>
                  <LI>TUSCANY_SCACPP=&lt;path to built Tuscany SCA&gt;</LI>
                  <LI>TUSCANY_SDOCPP=&lt;path to installed Tuscany SDO&gt;</LI>
                </UL></LI>
              <LI>Build the C++ source only with the following command sequence:
                  <UL>
                      <LI>cd &lt;tuscany_sca_install_dir&gt;</LI>
                      <LI>./configure --prefix=$TUSCANY_SCACPP --enable-cpp --enable-wsbinding=no</LI>
                      <LI>make</LI>
                      <LI>make install</LI>
                  </UL>
	              NOTE: If you don't provide a --prefix configure option, it will by default install into
                  /usr/local/tuscany/sca</LI>
              </OL>
           
         <A NAME="winbin"><H3>Getting the Tuscany SCA C++ Extension working with the binary release on Windows</H3></A>
          <OL>
              <LI>Add the &lt;tuscany_sca_install_dir&gt;/extensions/cpp/lib directory to the PATH environment variable</LI>
          </OL>
        <A NAME="winsrc"><H3>Getting the Tuscany SCA C++ Extension working with the source release on Windows</H3></A>
           <OL>   
              <LI>Unzip the supplied source zip file</LI>
              <LI>The following environment variables are required:                                 
                <UL>
                  <LI>TUSCANY_SCACPP=&lt;path to built Tuscany SCA&gt;                                      
                  <LI>TUSCANY_SDOCPP=&lt;path to installed Tuscany SDO&gt;                                      
                </UL></LI>
              <LI>You must have set up the environment for Microsoft Visual C++ tools. The build command 
                  will call vcvars32 to set the environment. Ensure the directory containing this is on your path.
                  This will be where you installed the compiler.</LI>
              <LI>Build the source:
                  <UL>
                      <LI>cd &lt;to where you unzipped the source&gt;</LI>
                      <LI>build</LI>                      
                  </UL>
	              This will build all the projects and put the required output into the 'deploy' directory<BR/><BR/>
                  Alternatively, open the workspace at &lt;tuscany_sca_install_dir&gt;/projects/tuscany_sca/tuscany_sca.dsw 
                  in Visual Studio 6 or at at &lt;tuscany_sca_install_dir&gt;/projectsvc7/tuscany_sca/tuscany_sca.sln 
                  in Visual Studio 7.1 - you can build projects individually
              <LI>Set the TUSCANY_SCACPP environment variable to point to the 'deploy' directory that was just created</LI>
          </OL>
      </DIV>

      <DIV CLASS="section"> 
         <A NAME="components"><H2>Creating and deploying an SCA C++ Component</H2></A>
         <P>Each SCA C++ component needs: 
         </P>
         <UL>
             <LI>A service header file that defines the operations that can be invoked on the 
                 component
             </LI>
             <LI>An implementation header file that defines the implementation and extends 
                 the service header file
             </LI>
             <LI>A C++ implementation of the service that implements the operations defined
                 in the service header file
             </LI>
             <LI>Proxy and wrapper header and implementation files generated by the Tuscany
                 C++ SCAGEN tool
             </LI>
             <LI>A service definition in a .componentType file
             </LI>
             <LI>An SCDL component definition within an SCDL composite file. Usually this 
                 composite file will contain multiple components configured and assembled together. 
             </LI>
         </UL>         
         <P>Once these items are in place for each component in your composite, you will need to 
            deploy this composite to your SCA system. In this release we are 
            using the SCA recursive composition model to do this. You simply create another
            SCDL component definition in a separate composite file that will represent the composite 
            you created above in the SCA system. Follow the steps below to see each of these items
            being created and used.
         </P> 
         <P>In this section we will use the Calculator sample as a worked example. 
            The Calculator code and files can be found at samples/CppCalculator and has been 
            developed further than the details specified below. In the interests of 
            readability, the example used below takes the simplest path.
         </P>
         <OL>
             <LI>Create the service header file that defines the operations your component 
                 will implement. E.g. Calculator.h contains the following:<BR/>
                 <PRE>#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</PRE>
             </LI>
             <LI>Create the implementation header file that extends the service header file. 
                 E.g. CalculatorImpl.h contains the following:<BR/>
                 <PRE>#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</PRE>
             </LI>
             <LI>Create the implementation for the component based on the implementation 
                 header file. E.g. CalculatorImpl.cpp contains the following code:<BR/>
                 <PRE>#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;
}</PRE>
             </LI>
             <LI>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:<BR/>
                 <PRE>&lt;componentType xmlns="http://www.osoa.org/xmlns/sca/1.0"&gt;

	&lt;service name="CalculatorService"&gt;
		&lt;interface.cpp header="Calculator.h"/&gt;
	&lt;/service&gt;

&lt;/componentType&gt;</PRE>
             </LI>
             <LI>Create a sample.calculator.composite file for your composite and define your 
                 component within it. The component definition specifies the implementation 
                 library to use (a .dll file on Windows, a .so file on Linux and a .dylib file on Mac OS X) 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 sample.calculator.composite file contains the following XML:<BR/>
                 <PRE>&lt;composite xmlns="http://www.osoa.org/xmlns/sca/1.0" 
	name="sample.calculator"&gt;

	&lt;component name="CalculatorComponent"&gt;
		&lt;implementation.cpp library="Calculator" header="CalculatorImpl.h"/&gt;
	&lt;/component&gt;

&lt;/composite&gt;</PRE>
             </LI>
             <LI>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.composite 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:<BR/>
                 <PRE>./extensions/cpp/bin/scagen.bat -dir ./samples/CppCalculator/sample.calculator -output ./samples/CppCalculator/sample.calculator</PRE>
                 which produces the following files:
                 <UL>
                     <LI>CalculatorImpl_CalculatorService_Proxy.h</LI>
                     <LI>CalculatorImpl_CalculatorService_Proxy.cpp</LI>
                     <LI>CalculatorImpl_CalculatorService_Wrapper.h</LI>
                     <LI>CalculatorImpl_CalculatorService_Wrapper.cpp</LI>
                 </UL>
             </LI>
             <LI>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 sample.calculator.composite file.
             </LI>
             <LI>Create the sample.calculator.solution.composite file and define the Calculator composite 
                 as a component within it. This is used to include the Calculator composite in the SCA system 
                 and should specify the composite name used in the sample.calculator.composite file. 
                 E.g. the Calculator sample.calculator.solution.composite 
                 file contains the following XML:<BR/>
                 <PRE>&lt;composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
	name="sample.calculator.solution"&gt;
	
        &lt;component name="sample.calculator.CalculatorComponent"&gt;
        	&lt;implementation.composite name="sample.calculator" /&gt;
       	&lt;/component&gt;

&lt;/composite&gt;</PRE>
             </LI>
             <LI>Deploy the various files into the SCA directory structure, as follows:
                 <UL>
                     <LI>&lt;deploy_root&gt;/CompositeName/CompositeName.composite              </LI>
                     <LI>&lt;deploy_root&gt;/CompositeName/Implementation.componentType         </LI>
                     <LI>&lt;deploy_root&gt;/CompositeName/Implementation.dll (or .so on Linux and .dylib on Mac OS X) </LI>
                     <LI>&lt;deploy_root&gt;/SolutionName.composite           </LI>
                 </UL>
                 E.g. for the Calculator sample the structure is:
                 <UL>
                     <LI>samples/CppCalculator/deploy/sample.calculator/Calculator.h                </LI>
                     <LI>samples/CppCalculator/deploy/sample.calculator/CalculatorImpl.h            </LI>
                     <LI>samples/CppCalculator/deploy/sample.calculator/sample.calculator.composite </LI>
                     <LI>samples/CppCalculator/deploy/sample.calculator/CalculatorImpl.componentType</LI>
                     <LI>samples/CppCalculator/deploy/sample.calculator/Calculator.dll              </LI>
                     <LI>samples/CppCalculator/deploy/sample.calculator.solution.composite</LI>
                 </UL>
             </LI>
             <LI>Your component, composite and subsystem are now ready to be invoked. Create a 
                 client that will call the service. E.g. the Calculator client (in the 
                 CalculatorClient.cpp file) contains code similar to the following:<BR/>
                 <PRE>try
{
    // Locate the service
    CompositeContext myContext = CompositeContext::getCurrent();
    Calculator *calcService = (Calculator*) myContext.locateService("CalculatorComponent/CalculatorService");
    if (calcService == 0)
    {
        cout &lt;&lt; "calculator_client: Unable to find Calculator service" &lt;&lt; endl;
    }
    else
    {
        float result = calcService-&gt;add(arg1, arg2);
        cout &lt;&lt; "calculator_client add(" &lt;&lt; arg1 &lt;&lt; "," &lt;&lt; arg2 &lt;&lt; ") = " &lt;&lt; result &lt;&lt; endl; 
    }
}
catch (ServiceRuntimeException& ex)
{
    cout &lt;&lt; "calculator_client: Error whilst invoking Tuscany: " &lt;&lt; 
            ex.getMessageText() &lt;&lt; endl; 
}
</PRE>
             </LI>
             <LI>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 and TUSCANY_SDOCPP environment variables set, 
                 as well as the SCA and SDO bin directories on 
                 your PATH on Windows or the SCA and SDO lib directories on your LD_LIBRARY_PATH on Linux 
                 and your DYLD_LIBRARY_PATH on Mac OS X. You will also need to set the TUSCANY_SCACPP_SYSTEM_ROOT
                 and TUSCANY_SCACPP_DEFAULT_COMPONENT environment variables to the 
                 path to your SCA component directory structure and the default component respectively.
                 TUSCANY_SCACPP_SYSTEM_ROOT is the directory where the SCA runtime will look for any 
                 .composite files and TUSCANY_SCACPP_DEFAULT_COMPONENT is the name of the base component 
                 to be used by SCA clients or containers when finding services - this component must be 
                 an instance of a composite (i.e. contain an &lt;implementation.composite&gt; element).
                 <BR/> 
                 E.g. on Windows run the following commands:
                 <UL>
                     <LI>set TUSCANY_SCACPP=C:/tuscany_sca                                         </LI>
                     <LI>set TUSCANY_SDOCPP=C:/tuscany_sdo                                         </LI>
                     <LI>set PATH=%PATH%;C:/tuscany_sca/bin;C:/tuscany_sdo/bin                     </LI>
                     <LI>set TUSCANY_SCACPP_SYSTEM_ROOT=C:/tuscany_sca/samples/CppCalculator/deploy</LI>
                     <LI>set TUSCANY_SCACPP_DEFAULT_COMPONENT=sample.calculator.CalculatorComponent</LI>
                     <LI>./calculator_client.exe                                                   </LI>
                 </UL>
             </LI>
             <LI>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:
                 <UL>
                     <LI>set TUSCANY_SCACPP_LOGGING=5                   </LI>
                     <LI>set TUSCANY_SCACPP_LOG=C:/tuscany/mylogfile.txt</LI>
                 </UL>
             </LI>
         </OL>
      </DIV>              
      <DIV CLASS="section"> 
         <A NAME="help"><H2>Getting Help</H2></A>

         <P>First place to look is at the Tuscany FAQ at 
         <A HREF="http://incubator.apache.org/tuscany/faq.html"
            TARGET="_blank">http://incubator.apache.org/tuscany/faq.html</A> </P>

         <P>Any problem with this release can be reported to the Tuscany 
         <A HREF="http://incubator.apache.org/tuscany/mail-lists.html"
            TARGET="_blank">mailing lists</A> or create a JIRA issue at&nbsp;<A HREF="http://issues.apache.org/jira/browse/Tuscany"
                                                                                TARGET="_blank">http://issues.apache.org/jira/browse/Tuscany</A>.</P>
      </DIV>
   </DIV>
</DIV>
</BODY>

</HTML>