Hi All,
I've been thinking a bit more about how we could do extensions.
Specifically, I've been working through what would be needed to add a new
component language binding in to Tuscany. I'm basing this on adding support
for components written in Python, as this is a language that is widely used,
extensible, embeddable and includes introspection.
To call a method in a Python module all we would need in the .composite file
is something like the following information:
<component name="DivideServiceComponent">
<implementation.python module="DivideModule"
path="/path/to/python/module"/>
</component>
The Python module will be in a file at
"/path/to/python/module/DivideModule.py" and would have a method that
implements a divide operation.
Python's introspection can find the correct method and describe the method
arguments and return types, so there is no requirement for code generated
via SCAGEN here (other languages may well need generated code).
We therefore need a way to extend the assembly model with the <
implementation.python> element and a way to extend Tuscany so that when it
finds an <implementation.python> element, it knows to call a library that
will invoke the Python code.
So to list things out we need to:
1) Define extensions for Tuscany in some way - perhaps a "Tuscany.config"
file that could have a schema like:
<tuscany-config>
<extension type="implementation or servicebinding or referencebinding or
interface"
suffix="xs:NCName"
library="xs:NCName"
path="xs:NCName"?
schema="xs:NCName"?>*
<parameter name="xs:NCName">*
some-parameter-value
</parameter>
</extension>
</tuscany-config>
So for example, a Python component langauge implementation extension like
this:
<tuscany-config>
<extension type="implementation" suffix="python" library="tuscany-python"
path="/path/to/python/tuscany/extension/library"
schema="xsd/tuscany-impl-python.xsd">
<parameter name="pythonroot">/path/to/python/installation</parameter>
</extension>
</tuscany-config>
would have a library named
/path/to/python/tuscany/extension/library/libtuscany-python.so and a schema
to define the <implementation.python> element at
/path/to/python/tuscany/extension/library/xsd/tuscany-impl-python.xsd. The
library would be initialised with a parameter named pythonroot with value
/path/to/python/installation.
2) Tuscany will need changing to:
a) register any schemas named in the "Tuscany.config" file
b) when the .composite files are read, notice the <implementation.python>
element and load and initialise the specified extension library with the
contents of the <implementation.python> element and the parameters from the
"Tuscany.config" file
c) when the component is invoked, call the extension library with a
tuscany::sca::Operation object. The extension will find the appropriate
operation in the Python module, find the parameter and return types that the
operation expects, map the C++ types to Python types, invoke the operation
and finally map the return type from Python to C++.
3) Create an extension to Python that will add support for invoking
references from Python components.
e.g. enable the Python equivalent of:
// Get the current ComponentContext
osoa::sca::ComponentContext myContext =
osoa::sca::ComponentContext::getCurrent();
// Find the required service, as referenced in
CalculatorImpl.componentType
DivideService* divideService =
(DivideService*)myContext.getService("divideService");
// Finally, invoke the service
result = divideService->divide(arg1, arg2);
How does this sound as a start to enabling some extensions in SCACPP?
I'm happy to get going implementing this, but it may be worth me working in
a branch as there'll be lots of changes (& I don't yet have my committer
access).
Cheers
Andrew