You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tuscany.apache.org by Jean-Sebastien Delfino <js...@apache.org> on 2007/02/01 03:22:13 UTC

Re: [C++] Interface descriptions and type conversions

Simon Laws wrote:
> I notice in implementing the PHP extension (yes - believe it or not I'm
> nearly ready to make a patch for the next version ;-) that, given the way
> that I have implemented the PHP extension there is insufficient 
> information
> available in the SCA runtime in order to do correct type conversions when
> passing messages between components. I imagine this has been raised 
> before
> but I looked at the archive and couldn't find a relevant thread.
>
> Imagine the scenario:
>
> C++ Component (ComponentA)  ---WireA--->   PHP Component (ComponentB)
> ---WireB----> C++ Component (ComponentC)
>
> Currently the build process looks at the header files described in the
> component type files and generates wrappers and proxies for the C++
> components. I have currently implemented the PHP Extension to use generic
> wrappers and proxies, i.e. it doesn't  use those generated based on the
> interface descriptions,  so they need to dynamically manage the type
> conversions for data coming in and going out of a PHP component.
>
> WireA.
>
> This is OK because the C++ SCA operation object that appears at 
> Component B
> has a set of data/types based on the generated proxy.  The PHP 
> extension can
> look at this and effect the right type conversions.
>
> WireB
>
> This is problematic. The dynamic PHP proxy has to generate an operation
> object to pass to the the wrapper of ComponentC. The issue is that 
> there is,
> as far as I can tell, no dynamic way of getting at the list of types that
> are expected for any particular operation. There is of course a static 
> C++
> proxy/wrapper combination that has been generated but I can't inspect 
> it at
> runtime.
>
> I'm not keen on generating PHP specific interface classes. PHP is a 
> dynamic
> environment and it's a whole stack of extra files we could do without 
> having
> to manage particularly if we have to adapt the generator for every 
> extension
> that's constructed. Can we extend the wrapper/proxy mechanism to 
> encapsulate
> a runtime list of required types alongside the static method descriptions
> that are already generated? We would need this to work for script to 
> script
> calls as well as for the script/C++ combination so maybe we need 
> something
> that hangs off the interface description part of the model. I'm not that
> familiar with how that part of the model is used so a little 
> investigation
> is required.
>
> Thoughts?
>
> Simon
>

Simon,

It's an interesting issue. To explore it let's walk through the wiring 
scenario you describe and assume the following:
- ComponentA (C++) -> WireA -> ComponentB (PHP) -> WireB -> ComponentC (C++)
- ComponentA (C++) passes a short int to ComponentB (PHP)
- ComponentB executes a PHP script which in turn passes a number to 
ComponentC (C++)
- ComponentC expects that number to be given as a long int.

Here's what I think should happen in the runtime:
1. At the source of WireA, a generated C++ CPPServiceProxy adds to our 
Operation object a Parameter of a type decided by the C++ client code: a 
C++ short int, with type == ParameterType::SHORT.
2. At the end of WireA, a PHPServiceWrapper converts that parameter to 
what the PHP script expects, for the sake of simplicity now I am going 
to assume that it needs to convert it to a C++ std::string.
3. The PHP script executes, now passes an std::string containing a 
number to the PHPServiceProxy at the source of WireB.
4. The PHPServiceProxy does not have much type info about that 
std::string parameter and can only add it to the Operation object as a 
std::string with type == ParameterType::STRING.
5. The CPPServiceWrapper at the end of WireB (actually the C++ 
ServiceWrapper generated for ComponentC) receives the std::string and 
should convert it to what ComponentC expects: a long int.

The general idea is that a ServiceProxy sends what it is given (or picks 
the most natural type out of the ParameterTypes that we have defined and 
converts the data to it). A ServiceWrapper converts what it receives to 
the type expected by the code it wraps. I think that the 
CPPServiceWrapper code and the generated C++ ServiceWrappers are simply 
missing the logic to convert data to what the target expects.

At the moment this limitation also prevents a C++ method 
getCustomer(long customerID) to be exposed as a REST service for 
example, as the generated C++ ServiceWrapper is missing the logic to 
convert the customerID received in string form from the REST query 
string to the expected C++ long int.

So we just need to add the missing type conversion logic to the C++ 
ServiceWrappers :)

Thoughts?

-- 
Jean-Sebastien


---------------------------------------------------------------------
To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: tuscany-dev-help@ws.apache.org


Re: [C++] Interface descriptions and type conversions

Posted by Simon Laws <si...@googlemail.com>.
On 2/5/07, Jean-Sebastien Delfino <js...@apache.org> wrote:
>
> Simon Laws wrote:
> > On 2/2/07, Jean-Sebastien Delfino <js...@apache.org> wrote:
> >>
> >> Simon Laws wrote:
> >> > On 2/1/07, Jean-Sebastien Delfino <js...@apache.org> wrote:
> >> >>
> >> >> Simon Laws wrote:
> >> >> > I notice in implementing the PHP extension (yes - believe it or
> not
> >> >> I'm
> >> >> > nearly ready to make a patch for the next version ;-) that,
> >> given the
> >> >> way
> >> >> > that I have implemented the PHP extension there is insufficient
> >> >> > information
> >> >> > available in the SCA runtime in order to do correct type
> >> conversions
> >> >> when
> >> >> > passing messages between components. I imagine this has been
> raised
> >> >> > before
> >> >> > but I looked at the archive and couldn't find a relevant thread.
> >> >> >
> >> >> > Imagine the scenario:
> >> >> >
> >> >> > C++ Component (ComponentA)  ---WireA--->   PHP Component
> >> (ComponentB)
> >> >> > ---WireB----> C++ Component (ComponentC)
> >> >> >
> >> >> > Currently the build process looks at the header files described in
> >> the
> >> >> > component type files and generates wrappers and proxies for the
> C++
> >> >> > components. I have currently implemented the PHP Extension to use
> >> >> generic
> >> >> > wrappers and proxies, i.e. it doesn't  use those generated based
> on
> >> >> the
> >> >> > interface descriptions,  so they need to dynamically manage the
> >> type
> >> >> > conversions for data coming in and going out of a PHP component.
> >> >> >
> >> >> > WireA.
> >> >> >
> >> >> > This is OK because the C++ SCA operation object that appears at
> >> >> > Component B
> >> >> > has a set of data/types based on the generated proxy.  The PHP
> >> >> > extension can
> >> >> > look at this and effect the right type conversions.
> >> >> >
> >> >> > WireB
> >> >> >
> >> >> > This is problematic. The dynamic PHP proxy has to generate an
> >> >> operation
> >> >> > object to pass to the the wrapper of ComponentC. The issue is that
> >> >> > there is,
> >> >> > as far as I can tell, no dynamic way of getting at the list of
> >> types
> >> >> that
> >> >> > are expected for any particular operation. There is of course a
> >> static
> >> >> > C++
> >> >> > proxy/wrapper combination that has been generated but I can't
> >> inspect
> >> >> > it at
> >> >> > runtime.
> >> >> >
> >> >> > I'm not keen on generating PHP specific interface classes. PHP is
> a
> >> >> > dynamic
> >> >> > environment and it's a whole stack of extra files we could do
> >> without
> >> >> > having
> >> >> > to manage particularly if we have to adapt the generator for every
> >> >> > extension
> >> >> > that's constructed. Can we extend the wrapper/proxy mechanism to
> >> >> > encapsulate
> >> >> > a runtime list of required types alongside the static method
> >> >> descriptions
> >> >> > that are already generated? We would need this to work for
> >> script to
> >> >> > script
> >> >> > calls as well as for the script/C++ combination so maybe we need
> >> >> > something
> >> >> > that hangs off the interface description part of the model. I'm
> not
> >> >> that
> >> >> > familiar with how that part of the model is used so a little
> >> >> > investigation
> >> >> > is required.
> >> >> >
> >> >> > Thoughts?
> >> >> >
> >> >> > Simon
> >> >> >
> >> >>
> >> >> Simon,
> >> >>
> >> >> It's an interesting issue. To explore it let's walk through the
> >> wiring
> >> >> scenario you describe and assume the following:
> >> >> - ComponentA (C++) -> WireA -> ComponentB (PHP) -> WireB ->
> >> ComponentC
> >> >> (C++)
> >> >> - ComponentA (C++) passes a short int to ComponentB (PHP)
> >> >> - ComponentB executes a PHP script which in turn passes a number to
> >> >> ComponentC (C++)
> >> >> - ComponentC expects that number to be given as a long int.
> >> >>
> >> >> Here's what I think should happen in the runtime:
> >> >> 1. At the source of WireA, a generated C++ CPPServiceProxy adds to
> >> our
> >> >> Operation object a Parameter of a type decided by the C++ client
> >> code:
> >> a
> >> >> C++ short int, with type == ParameterType::SHORT.
> >> >> 2. At the end of WireA, a PHPServiceWrapper converts that
> >> parameter to
> >> >> what the PHP script expects, for the sake of simplicity now I am
> >> going
> >> >> to assume that it needs to convert it to a C++ std::string.
> >> >> 3. The PHP script executes, now passes an std::string containing a
> >> >> number to the PHPServiceProxy at the source of WireB.
> >> >> 4. The PHPServiceProxy does not have much type info about that
> >> >> std::string parameter and can only add it to the Operation object
> >> as a
> >> >> std::string with type == ParameterType::STRING.
> >> >> 5. The CPPServiceWrapper at the end of WireB (actually the C++
> >> >> ServiceWrapper generated for ComponentC) receives the std::string
> and
> >> >> should convert it to what ComponentC expects: a long int.
> >> >>
> >> >> The general idea is that a ServiceProxy sends what it is given (or
> >> picks
> >> >> the most natural type out of the ParameterTypes that we have defined
> >> and
> >> >> converts the data to it). A ServiceWrapper converts what it
> >> receives to
> >> >> the type expected by the code it wraps. I think that the
> >> >> CPPServiceWrapper code and the generated C++ ServiceWrappers are
> >> simply
> >> >> missing the logic to convert data to what the target expects.
> >> >>
> >> >> At the moment this limitation also prevents a C++ method
> >> >> getCustomer(long customerID) to be exposed as a REST service for
> >> >> example, as the generated C++ ServiceWrapper is missing the logic to
> >> >> convert the customerID received in string form from the REST query
> >> >> string to the expected C++ long int.
> >> >>
> >> >> So we just need to add the missing type conversion logic to the C++
> >> >> ServiceWrappers :)
> >> >>
> >> >> Thoughts?
> >> >>
> >> >> --
> >> >> Jean-Sebastien
> >> >>
> >> >>
> >> >>
> ---------------------------------------------------------------------
> >> >> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
> >> >> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
> >> >>
> >> >> Hi Jean-Sebastien
> >> >
> >> > It could well be simpler if, as you suggest, the conversion happens
> in
> >> > the
> >> > generated wrapper in this case. So we need such type information,
> >> as is
> >> > required to effect the type conversion, to be generated into the
> >> wrapper.
> >> >
> >> Yes, and I think that there are three cases to consider here:
> >> - The wrapper is generated and the type info can be burned into it
> (from
> >> the C++ class/interface of the service for which the wrapper was
> >> generated).
> >> - The wrapper is generic and introspects the component implementation
> >> (incl. the associated .componentType metadata and the service
> interfaces
> >> it declares, if any) to determine the expected data type.
> >> - The wrapper wraps a script written in a language that supports
> dynamic
> >> typing (e.g. Ruby) and best is to not convert and present the data to
> >> the script as-is (e.g. a string, an integer).
> >>
> >> Independent of the type handling, the wrapper is responsible for
> >> presenting the data to the target component implementation in a
> suitable
> >> form, for example with Ruby, this means turn the input data into a Ruby
> >> VALUE object. Again this is independent of the type, as a Ruby VALUE
> can
> >> represent a int, a string etc.
> >>
> >> > However I think we should try and arrange it so that we are not
> trying
> >> > to do
> >> > any more conversions than are necessary so I'm not convinced that the
> >> > proxy
> >> > should be guessing what type to produce only for it to be coerced
> >> > again at
> >> > the wrapper unless this is a natural effect of the transport/protocol
> >> > involved, for example, In your REST example. I.e. we want the proxy
> to
> >> > have
> >> > the best information available to it in marshaling the data it has.
> >> >
> >>
> >> I agree. I was not clear before and by conversions in the proxy I meant
> >> "turn the data into a form that can be carried by our Operation +
> >> Operation::Parameter infrastructure". In the case of a C++ proxy, no
> >> conversion should be necessary. In the case of Ruby the string, int
> etc.
> >> data needs to be extracted of the Ruby VALUE object that wraps it. I'm
> >> not sure about PHP but you probably have a similar mechanism to carry
> >> data and track its usage so you may have to extract the raw data out of
> >> its PHP representation. So in most cases there is no conversion at all
> >> in the proxy or as you said just a natural effect of the
> >> transport/protocol involved (for example with REST we are receiving a
> >> query string and producing XML for the response).
> >>
> >> > I also need to address complex types in the PHP extension. Where a
> >> remote
> >> > interface is used you can imagine the WSDL, SMD or whatever being
> >> > parsed at
> >> > the client component to construct a proxy capable of suitable type
> >> > checking
> >> > and of providing convenience functions such as
> >> > "giveMeAnSDOWithTheRightModelLoaded()". Looking at the code and
> >> > samples at
> >> > the moment it seems that the C++ infrastructure loads available
> >> XSDs and
> >> > provides some handy helper methods for creating SDOs based on the
> >> types
> >> > available. I don't how they are related to particular interfaces
> >> > though. I
> >> > expect I'm overlooking something.
> >> >
> >> We also load WSDL files. A Proxy is created from a Reference, and the
> >> Reference can carry an Interface definition, a WSDL portType for
> >> example. Composite::findWSDLDefinition(namespace) will give you a
> >> WSDLDefinition object from which you can lookup a WSDLPortType and
> >> WSDLOperation and the operation input and output types. You should be
> >> able to use these types to validate the data flowing through the proxy.
> >>
> >> > Regards
> >> >
> >> > Simon
> >> >
> >>
> >> --
> >> Jean-Sebastien
> >>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
> >> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
> >>
> >> OK Jean-Sebastien, I agree with what you have said. So the long and
> >> short
> > of all this is that
> >
> > 1/ the C++ generated wrapper has to be a bit smarter about the type
> > conversions it makes, i.e. it can't assume the values arriving in the
> > Operation object are of the correct type
>
> +1. Until we improve the C++ code generator I'd recommend the following:
> - Write the C++ code to match the data types passed to it
> - Or run your C++ component in a different process and use the WS or the
> SCA default binding for example to communicate between your script and
> the C++ component.
>
> > 2/ proxy code should only take responsibility of populating the
> Operation
> > object and for ensuring there is no loss of data/precision in doing this
>
> +1
>
> > 3/ Look at how we provided WSDL defined type information to script
> > developers. Currently in PHP SCA you can define references using
> > annotations
> > and include WSDL information there so there is a natural bridge to
> > finding
> > the correct type information for a given reference.
>
> +1 but I'd recommend to use WSDL only when you have to, for example to
> interact with a Web Service and the WSDL is given to you and you have to
> comply with its interface definition. I  think we shouldn't try to
> enforce fixed type definitions with script languages that support
> dynamic typing. In other words, if defining a type is not going to help
> the application developer write the script, let's not force him to
> define a type with WSDL, XSD or any other type definition language.
>
> > We haven't however done
> > the piece of work to share meta data between script and runtime so
> > there is
> > work to do here!
>
> Could you describe what you have in mind and what you mean by "share
> metadata between script and runtime"? Thanks
>
> >
> > Simon
> >
>
> --
> Jean-Sebastien
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
>
> In PHP SCA there are a set of annotations that allow service, references
and the bindings associated with the,to be described. We don't read SCDL
files in the current incarnation so all component type information and
assembly is decribed in the source file. For example, you may have a
component that looks like:

/**
 * @service
 * @binding.ws
 * @types http://www.example.org/email email.xsd
 * @types http://www.example.org/email emailresponse.xsd
 * @types http://www.example.org/email emailresponselist.xsd
 */
class MailApplicationService {

    /**
     * @reference
     * @binding.ws ./WebService.wsdl
     */
    public $web_service;

    /**
     * @reference
     * @binding.php LocalService.php
     */
    public $local_service;

    /**
     * A method that sends an email message
     *
     * @param EmailType $email http://www.example.org/email
     * @return EmailResponseListType http://www.example.org/email
     */
    function sendMailMessage(SDO_DataObject $email) {

        $email_response_list = SCA::createDataObject("
http://www.example.org/email","EmailResponseListType");
        $email_response = SCA::createDataObject("
http://www.example.org/email","EmailResponseType");

        $webservice_response =
$this->web_service->sendComplexMessage($email);
        $email_response_list->wsemail = $webservice_response;

        $local_response = $this->local_service->sendComplexMessage($email);
        $email_response_list->localemail = $local_response;

        return $email_response_list;
    }
}


A subset of the meta data you would find in SCDL composite files appears in
the PHP annotations. We would like a PHP developer to be able to describe a
component in this way. We would also like to be able to integrate these
components with SCA assemblies described using SCDL.

Clearly the first level of integration is through remote references, as is
supported at present, where PHP SCA and other SCA compositions remain
separated by a WSDL definition or whatever.

Moving forward I would like to explore tighter integration. In this case I
would like the annotation information to provide the component type
information but also provide a basis for some level of
composition.Thequestion is that if the same configuration is repeated
in SCDL how are any
differences resolved. Thinking aloud I would like any composition
information provided through annotations to result the automatic generation
of appropriate artefacts in the SCA model. It's also attractive to allow
SDCL to override this so that the infrastructure can take control in the
case where SCA is providing distributed runtime, deployment and management
support. Something that seems relatively novel for scrips. As you can tell I
haven't thought this through but these are the kinds of questions that are
raised when we push PHP SCA annotations and SCDL together.

Regards

Simon

Re: [C++] Interface descriptions and type conversions

Posted by Jean-Sebastien Delfino <js...@apache.org>.
Simon Laws wrote:
> On 2/2/07, Jean-Sebastien Delfino <js...@apache.org> wrote:
>>
>> Simon Laws wrote:
>> > On 2/1/07, Jean-Sebastien Delfino <js...@apache.org> wrote:
>> >>
>> >> Simon Laws wrote:
>> >> > I notice in implementing the PHP extension (yes - believe it or not
>> >> I'm
>> >> > nearly ready to make a patch for the next version ;-) that, 
>> given the
>> >> way
>> >> > that I have implemented the PHP extension there is insufficient
>> >> > information
>> >> > available in the SCA runtime in order to do correct type 
>> conversions
>> >> when
>> >> > passing messages between components. I imagine this has been raised
>> >> > before
>> >> > but I looked at the archive and couldn't find a relevant thread.
>> >> >
>> >> > Imagine the scenario:
>> >> >
>> >> > C++ Component (ComponentA)  ---WireA--->   PHP Component 
>> (ComponentB)
>> >> > ---WireB----> C++ Component (ComponentC)
>> >> >
>> >> > Currently the build process looks at the header files described in
>> the
>> >> > component type files and generates wrappers and proxies for the C++
>> >> > components. I have currently implemented the PHP Extension to use
>> >> generic
>> >> > wrappers and proxies, i.e. it doesn't  use those generated based on
>> >> the
>> >> > interface descriptions,  so they need to dynamically manage the 
>> type
>> >> > conversions for data coming in and going out of a PHP component.
>> >> >
>> >> > WireA.
>> >> >
>> >> > This is OK because the C++ SCA operation object that appears at
>> >> > Component B
>> >> > has a set of data/types based on the generated proxy.  The PHP
>> >> > extension can
>> >> > look at this and effect the right type conversions.
>> >> >
>> >> > WireB
>> >> >
>> >> > This is problematic. The dynamic PHP proxy has to generate an
>> >> operation
>> >> > object to pass to the the wrapper of ComponentC. The issue is that
>> >> > there is,
>> >> > as far as I can tell, no dynamic way of getting at the list of 
>> types
>> >> that
>> >> > are expected for any particular operation. There is of course a
>> static
>> >> > C++
>> >> > proxy/wrapper combination that has been generated but I can't 
>> inspect
>> >> > it at
>> >> > runtime.
>> >> >
>> >> > I'm not keen on generating PHP specific interface classes. PHP is a
>> >> > dynamic
>> >> > environment and it's a whole stack of extra files we could do 
>> without
>> >> > having
>> >> > to manage particularly if we have to adapt the generator for every
>> >> > extension
>> >> > that's constructed. Can we extend the wrapper/proxy mechanism to
>> >> > encapsulate
>> >> > a runtime list of required types alongside the static method
>> >> descriptions
>> >> > that are already generated? We would need this to work for 
>> script to
>> >> > script
>> >> > calls as well as for the script/C++ combination so maybe we need
>> >> > something
>> >> > that hangs off the interface description part of the model. I'm not
>> >> that
>> >> > familiar with how that part of the model is used so a little
>> >> > investigation
>> >> > is required.
>> >> >
>> >> > Thoughts?
>> >> >
>> >> > Simon
>> >> >
>> >>
>> >> Simon,
>> >>
>> >> It's an interesting issue. To explore it let's walk through the 
>> wiring
>> >> scenario you describe and assume the following:
>> >> - ComponentA (C++) -> WireA -> ComponentB (PHP) -> WireB -> 
>> ComponentC
>> >> (C++)
>> >> - ComponentA (C++) passes a short int to ComponentB (PHP)
>> >> - ComponentB executes a PHP script which in turn passes a number to
>> >> ComponentC (C++)
>> >> - ComponentC expects that number to be given as a long int.
>> >>
>> >> Here's what I think should happen in the runtime:
>> >> 1. At the source of WireA, a generated C++ CPPServiceProxy adds to 
>> our
>> >> Operation object a Parameter of a type decided by the C++ client 
>> code:
>> a
>> >> C++ short int, with type == ParameterType::SHORT.
>> >> 2. At the end of WireA, a PHPServiceWrapper converts that 
>> parameter to
>> >> what the PHP script expects, for the sake of simplicity now I am 
>> going
>> >> to assume that it needs to convert it to a C++ std::string.
>> >> 3. The PHP script executes, now passes an std::string containing a
>> >> number to the PHPServiceProxy at the source of WireB.
>> >> 4. The PHPServiceProxy does not have much type info about that
>> >> std::string parameter and can only add it to the Operation object 
>> as a
>> >> std::string with type == ParameterType::STRING.
>> >> 5. The CPPServiceWrapper at the end of WireB (actually the C++
>> >> ServiceWrapper generated for ComponentC) receives the std::string and
>> >> should convert it to what ComponentC expects: a long int.
>> >>
>> >> The general idea is that a ServiceProxy sends what it is given (or
>> picks
>> >> the most natural type out of the ParameterTypes that we have defined
>> and
>> >> converts the data to it). A ServiceWrapper converts what it 
>> receives to
>> >> the type expected by the code it wraps. I think that the
>> >> CPPServiceWrapper code and the generated C++ ServiceWrappers are 
>> simply
>> >> missing the logic to convert data to what the target expects.
>> >>
>> >> At the moment this limitation also prevents a C++ method
>> >> getCustomer(long customerID) to be exposed as a REST service for
>> >> example, as the generated C++ ServiceWrapper is missing the logic to
>> >> convert the customerID received in string form from the REST query
>> >> string to the expected C++ long int.
>> >>
>> >> So we just need to add the missing type conversion logic to the C++
>> >> ServiceWrappers :)
>> >>
>> >> Thoughts?
>> >>
>> >> --
>> >> Jean-Sebastien
>> >>
>> >>
>> >> ---------------------------------------------------------------------
>> >> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
>> >> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
>> >>
>> >> Hi Jean-Sebastien
>> >
>> > It could well be simpler if, as you suggest, the conversion happens in
>> > the
>> > generated wrapper in this case. So we need such type information, 
>> as is
>> > required to effect the type conversion, to be generated into the
>> wrapper.
>> >
>> Yes, and I think that there are three cases to consider here:
>> - The wrapper is generated and the type info can be burned into it (from
>> the C++ class/interface of the service for which the wrapper was
>> generated).
>> - The wrapper is generic and introspects the component implementation
>> (incl. the associated .componentType metadata and the service interfaces
>> it declares, if any) to determine the expected data type.
>> - The wrapper wraps a script written in a language that supports dynamic
>> typing (e.g. Ruby) and best is to not convert and present the data to
>> the script as-is (e.g. a string, an integer).
>>
>> Independent of the type handling, the wrapper is responsible for
>> presenting the data to the target component implementation in a suitable
>> form, for example with Ruby, this means turn the input data into a Ruby
>> VALUE object. Again this is independent of the type, as a Ruby VALUE can
>> represent a int, a string etc.
>>
>> > However I think we should try and arrange it so that we are not trying
>> > to do
>> > any more conversions than are necessary so I'm not convinced that the
>> > proxy
>> > should be guessing what type to produce only for it to be coerced
>> > again at
>> > the wrapper unless this is a natural effect of the transport/protocol
>> > involved, for example, In your REST example. I.e. we want the proxy to
>> > have
>> > the best information available to it in marshaling the data it has.
>> >
>>
>> I agree. I was not clear before and by conversions in the proxy I meant
>> "turn the data into a form that can be carried by our Operation +
>> Operation::Parameter infrastructure". In the case of a C++ proxy, no
>> conversion should be necessary. In the case of Ruby the string, int etc.
>> data needs to be extracted of the Ruby VALUE object that wraps it. I'm
>> not sure about PHP but you probably have a similar mechanism to carry
>> data and track its usage so you may have to extract the raw data out of
>> its PHP representation. So in most cases there is no conversion at all
>> in the proxy or as you said just a natural effect of the
>> transport/protocol involved (for example with REST we are receiving a
>> query string and producing XML for the response).
>>
>> > I also need to address complex types in the PHP extension. Where a
>> remote
>> > interface is used you can imagine the WSDL, SMD or whatever being
>> > parsed at
>> > the client component to construct a proxy capable of suitable type
>> > checking
>> > and of providing convenience functions such as
>> > "giveMeAnSDOWithTheRightModelLoaded()". Looking at the code and
>> > samples at
>> > the moment it seems that the C++ infrastructure loads available 
>> XSDs and
>> > provides some handy helper methods for creating SDOs based on the 
>> types
>> > available. I don't how they are related to particular interfaces
>> > though. I
>> > expect I'm overlooking something.
>> >
>> We also load WSDL files. A Proxy is created from a Reference, and the
>> Reference can carry an Interface definition, a WSDL portType for
>> example. Composite::findWSDLDefinition(namespace) will give you a
>> WSDLDefinition object from which you can lookup a WSDLPortType and
>> WSDLOperation and the operation input and output types. You should be
>> able to use these types to validate the data flowing through the proxy.
>>
>> > Regards
>> >
>> > Simon
>> >
>>
>> -- 
>> Jean-Sebastien
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
>> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
>>
>> OK Jean-Sebastien, I agree with what you have said. So the long and 
>> short
> of all this is that
>
> 1/ the C++ generated wrapper has to be a bit smarter about the type
> conversions it makes, i.e. it can't assume the values arriving in the
> Operation object are of the correct type

+1. Until we improve the C++ code generator I'd recommend the following:
- Write the C++ code to match the data types passed to it
- Or run your C++ component in a different process and use the WS or the 
SCA default binding for example to communicate between your script and 
the C++ component.

> 2/ proxy code should only take responsibility of populating the Operation
> object and for ensuring there is no loss of data/precision in doing this

+1

> 3/ Look at how we provided WSDL defined type information to script
> developers. Currently in PHP SCA you can define references using 
> annotations
> and include WSDL information there so there is a natural bridge to 
> finding
> the correct type information for a given reference.

+1 but I'd recommend to use WSDL only when you have to, for example to 
interact with a Web Service and the WSDL is given to you and you have to 
comply with its interface definition. I  think we shouldn't try to 
enforce fixed type definitions with script languages that support 
dynamic typing. In other words, if defining a type is not going to help 
the application developer write the script, let's not force him to 
define a type with WSDL, XSD or any other type definition language.

> We haven't however done
> the piece of work to share meta data between script and runtime so 
> there is
> work to do here!

Could you describe what you have in mind and what you mean by "share 
metadata between script and runtime"? Thanks

>
> Simon
>

-- 
Jean-Sebastien


---------------------------------------------------------------------
To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: tuscany-dev-help@ws.apache.org


Re: [C++] Interface descriptions and type conversions

Posted by Simon Laws <si...@googlemail.com>.
On 2/2/07, Jean-Sebastien Delfino <js...@apache.org> wrote:
>
> Simon Laws wrote:
> > On 2/1/07, Jean-Sebastien Delfino <js...@apache.org> wrote:
> >>
> >> Simon Laws wrote:
> >> > I notice in implementing the PHP extension (yes - believe it or not
> >> I'm
> >> > nearly ready to make a patch for the next version ;-) that, given the
> >> way
> >> > that I have implemented the PHP extension there is insufficient
> >> > information
> >> > available in the SCA runtime in order to do correct type conversions
> >> when
> >> > passing messages between components. I imagine this has been raised
> >> > before
> >> > but I looked at the archive and couldn't find a relevant thread.
> >> >
> >> > Imagine the scenario:
> >> >
> >> > C++ Component (ComponentA)  ---WireA--->   PHP Component (ComponentB)
> >> > ---WireB----> C++ Component (ComponentC)
> >> >
> >> > Currently the build process looks at the header files described in
> the
> >> > component type files and generates wrappers and proxies for the C++
> >> > components. I have currently implemented the PHP Extension to use
> >> generic
> >> > wrappers and proxies, i.e. it doesn't  use those generated based on
> >> the
> >> > interface descriptions,  so they need to dynamically manage the type
> >> > conversions for data coming in and going out of a PHP component.
> >> >
> >> > WireA.
> >> >
> >> > This is OK because the C++ SCA operation object that appears at
> >> > Component B
> >> > has a set of data/types based on the generated proxy.  The PHP
> >> > extension can
> >> > look at this and effect the right type conversions.
> >> >
> >> > WireB
> >> >
> >> > This is problematic. The dynamic PHP proxy has to generate an
> >> operation
> >> > object to pass to the the wrapper of ComponentC. The issue is that
> >> > there is,
> >> > as far as I can tell, no dynamic way of getting at the list of types
> >> that
> >> > are expected for any particular operation. There is of course a
> static
> >> > C++
> >> > proxy/wrapper combination that has been generated but I can't inspect
> >> > it at
> >> > runtime.
> >> >
> >> > I'm not keen on generating PHP specific interface classes. PHP is a
> >> > dynamic
> >> > environment and it's a whole stack of extra files we could do without
> >> > having
> >> > to manage particularly if we have to adapt the generator for every
> >> > extension
> >> > that's constructed. Can we extend the wrapper/proxy mechanism to
> >> > encapsulate
> >> > a runtime list of required types alongside the static method
> >> descriptions
> >> > that are already generated? We would need this to work for script to
> >> > script
> >> > calls as well as for the script/C++ combination so maybe we need
> >> > something
> >> > that hangs off the interface description part of the model. I'm not
> >> that
> >> > familiar with how that part of the model is used so a little
> >> > investigation
> >> > is required.
> >> >
> >> > Thoughts?
> >> >
> >> > Simon
> >> >
> >>
> >> Simon,
> >>
> >> It's an interesting issue. To explore it let's walk through the wiring
> >> scenario you describe and assume the following:
> >> - ComponentA (C++) -> WireA -> ComponentB (PHP) -> WireB -> ComponentC
> >> (C++)
> >> - ComponentA (C++) passes a short int to ComponentB (PHP)
> >> - ComponentB executes a PHP script which in turn passes a number to
> >> ComponentC (C++)
> >> - ComponentC expects that number to be given as a long int.
> >>
> >> Here's what I think should happen in the runtime:
> >> 1. At the source of WireA, a generated C++ CPPServiceProxy adds to our
> >> Operation object a Parameter of a type decided by the C++ client code:
> a
> >> C++ short int, with type == ParameterType::SHORT.
> >> 2. At the end of WireA, a PHPServiceWrapper converts that parameter to
> >> what the PHP script expects, for the sake of simplicity now I am going
> >> to assume that it needs to convert it to a C++ std::string.
> >> 3. The PHP script executes, now passes an std::string containing a
> >> number to the PHPServiceProxy at the source of WireB.
> >> 4. The PHPServiceProxy does not have much type info about that
> >> std::string parameter and can only add it to the Operation object as a
> >> std::string with type == ParameterType::STRING.
> >> 5. The CPPServiceWrapper at the end of WireB (actually the C++
> >> ServiceWrapper generated for ComponentC) receives the std::string and
> >> should convert it to what ComponentC expects: a long int.
> >>
> >> The general idea is that a ServiceProxy sends what it is given (or
> picks
> >> the most natural type out of the ParameterTypes that we have defined
> and
> >> converts the data to it). A ServiceWrapper converts what it receives to
> >> the type expected by the code it wraps. I think that the
> >> CPPServiceWrapper code and the generated C++ ServiceWrappers are simply
> >> missing the logic to convert data to what the target expects.
> >>
> >> At the moment this limitation also prevents a C++ method
> >> getCustomer(long customerID) to be exposed as a REST service for
> >> example, as the generated C++ ServiceWrapper is missing the logic to
> >> convert the customerID received in string form from the REST query
> >> string to the expected C++ long int.
> >>
> >> So we just need to add the missing type conversion logic to the C++
> >> ServiceWrappers :)
> >>
> >> Thoughts?
> >>
> >> --
> >> Jean-Sebastien
> >>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
> >> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
> >>
> >> Hi Jean-Sebastien
> >
> > It could well be simpler if, as you suggest, the conversion happens in
> > the
> > generated wrapper in this case. So we need such type information, as is
> > required to effect the type conversion, to be generated into the
> wrapper.
> >
> Yes, and I think that there are three cases to consider here:
> - The wrapper is generated and the type info can be burned into it (from
> the C++ class/interface of the service for which the wrapper was
> generated).
> - The wrapper is generic and introspects the component implementation
> (incl. the associated .componentType metadata and the service interfaces
> it declares, if any) to determine the expected data type.
> - The wrapper wraps a script written in a language that supports dynamic
> typing (e.g. Ruby) and best is to not convert and present the data to
> the script as-is (e.g. a string, an integer).
>
> Independent of the type handling, the wrapper is responsible for
> presenting the data to the target component implementation in a suitable
> form, for example with Ruby, this means turn the input data into a Ruby
> VALUE object. Again this is independent of the type, as a Ruby VALUE can
> represent a int, a string etc.
>
> > However I think we should try and arrange it so that we are not trying
> > to do
> > any more conversions than are necessary so I'm not convinced that the
> > proxy
> > should be guessing what type to produce only for it to be coerced
> > again at
> > the wrapper unless this is a natural effect of the transport/protocol
> > involved, for example, In your REST example. I.e. we want the proxy to
> > have
> > the best information available to it in marshaling the data it has.
> >
>
> I agree. I was not clear before and by conversions in the proxy I meant
> "turn the data into a form that can be carried by our Operation +
> Operation::Parameter infrastructure". In the case of a C++ proxy, no
> conversion should be necessary. In the case of Ruby the string, int etc.
> data needs to be extracted of the Ruby VALUE object that wraps it. I'm
> not sure about PHP but you probably have a similar mechanism to carry
> data and track its usage so you may have to extract the raw data out of
> its PHP representation. So in most cases there is no conversion at all
> in the proxy or as you said just a natural effect of the
> transport/protocol involved (for example with REST we are receiving a
> query string and producing XML for the response).
>
> > I also need to address complex types in the PHP extension. Where a
> remote
> > interface is used you can imagine the WSDL, SMD or whatever being
> > parsed at
> > the client component to construct a proxy capable of suitable type
> > checking
> > and of providing convenience functions such as
> > "giveMeAnSDOWithTheRightModelLoaded()". Looking at the code and
> > samples at
> > the moment it seems that the C++ infrastructure loads available XSDs and
> > provides some handy helper methods for creating SDOs based on the types
> > available. I don't how they are related to particular interfaces
> > though. I
> > expect I'm overlooking something.
> >
> We also load WSDL files. A Proxy is created from a Reference, and the
> Reference can carry an Interface definition, a WSDL portType for
> example. Composite::findWSDLDefinition(namespace) will give you a
> WSDLDefinition object from which you can lookup a WSDLPortType and
> WSDLOperation and the operation input and output types. You should be
> able to use these types to validate the data flowing through the proxy.
>
> > Regards
> >
> > Simon
> >
>
> --
> Jean-Sebastien
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
>
> OK Jean-Sebastien, I agree with what you have said. So the long and short
of all this is that

1/ the C++ generated wrapper has to be a bit smarter about the type
conversions it makes, i.e. it can't assume the values arriving in the
Operation object are of the correct type
2/ proxy code should only take responsibility of populating the Operation
object and for ensuring there is no loss of data/precision in doing this
3/ Look at how we provided WSDL defined type information to script
developers. Currently in PHP SCA you can define references using annotations
and include WSDL information there so there is a natural bridge to finding
the correct type information for a given reference. We haven't however done
the piece of work to share meta data between script and runtime so there is
work to do here!

Simon

Re: [C++] Interface descriptions and type conversions

Posted by Jean-Sebastien Delfino <js...@apache.org>.
Simon Laws wrote:
> On 2/1/07, Jean-Sebastien Delfino <js...@apache.org> wrote:
>>
>> Simon Laws wrote:
>> > I notice in implementing the PHP extension (yes - believe it or not 
>> I'm
>> > nearly ready to make a patch for the next version ;-) that, given the
>> way
>> > that I have implemented the PHP extension there is insufficient
>> > information
>> > available in the SCA runtime in order to do correct type conversions
>> when
>> > passing messages between components. I imagine this has been raised
>> > before
>> > but I looked at the archive and couldn't find a relevant thread.
>> >
>> > Imagine the scenario:
>> >
>> > C++ Component (ComponentA)  ---WireA--->   PHP Component (ComponentB)
>> > ---WireB----> C++ Component (ComponentC)
>> >
>> > Currently the build process looks at the header files described in the
>> > component type files and generates wrappers and proxies for the C++
>> > components. I have currently implemented the PHP Extension to use
>> generic
>> > wrappers and proxies, i.e. it doesn't  use those generated based on 
>> the
>> > interface descriptions,  so they need to dynamically manage the type
>> > conversions for data coming in and going out of a PHP component.
>> >
>> > WireA.
>> >
>> > This is OK because the C++ SCA operation object that appears at
>> > Component B
>> > has a set of data/types based on the generated proxy.  The PHP
>> > extension can
>> > look at this and effect the right type conversions.
>> >
>> > WireB
>> >
>> > This is problematic. The dynamic PHP proxy has to generate an 
>> operation
>> > object to pass to the the wrapper of ComponentC. The issue is that
>> > there is,
>> > as far as I can tell, no dynamic way of getting at the list of types
>> that
>> > are expected for any particular operation. There is of course a static
>> > C++
>> > proxy/wrapper combination that has been generated but I can't inspect
>> > it at
>> > runtime.
>> >
>> > I'm not keen on generating PHP specific interface classes. PHP is a
>> > dynamic
>> > environment and it's a whole stack of extra files we could do without
>> > having
>> > to manage particularly if we have to adapt the generator for every
>> > extension
>> > that's constructed. Can we extend the wrapper/proxy mechanism to
>> > encapsulate
>> > a runtime list of required types alongside the static method
>> descriptions
>> > that are already generated? We would need this to work for script to
>> > script
>> > calls as well as for the script/C++ combination so maybe we need
>> > something
>> > that hangs off the interface description part of the model. I'm not 
>> that
>> > familiar with how that part of the model is used so a little
>> > investigation
>> > is required.
>> >
>> > Thoughts?
>> >
>> > Simon
>> >
>>
>> Simon,
>>
>> It's an interesting issue. To explore it let's walk through the wiring
>> scenario you describe and assume the following:
>> - ComponentA (C++) -> WireA -> ComponentB (PHP) -> WireB -> ComponentC
>> (C++)
>> - ComponentA (C++) passes a short int to ComponentB (PHP)
>> - ComponentB executes a PHP script which in turn passes a number to
>> ComponentC (C++)
>> - ComponentC expects that number to be given as a long int.
>>
>> Here's what I think should happen in the runtime:
>> 1. At the source of WireA, a generated C++ CPPServiceProxy adds to our
>> Operation object a Parameter of a type decided by the C++ client code: a
>> C++ short int, with type == ParameterType::SHORT.
>> 2. At the end of WireA, a PHPServiceWrapper converts that parameter to
>> what the PHP script expects, for the sake of simplicity now I am going
>> to assume that it needs to convert it to a C++ std::string.
>> 3. The PHP script executes, now passes an std::string containing a
>> number to the PHPServiceProxy at the source of WireB.
>> 4. The PHPServiceProxy does not have much type info about that
>> std::string parameter and can only add it to the Operation object as a
>> std::string with type == ParameterType::STRING.
>> 5. The CPPServiceWrapper at the end of WireB (actually the C++
>> ServiceWrapper generated for ComponentC) receives the std::string and
>> should convert it to what ComponentC expects: a long int.
>>
>> The general idea is that a ServiceProxy sends what it is given (or picks
>> the most natural type out of the ParameterTypes that we have defined and
>> converts the data to it). A ServiceWrapper converts what it receives to
>> the type expected by the code it wraps. I think that the
>> CPPServiceWrapper code and the generated C++ ServiceWrappers are simply
>> missing the logic to convert data to what the target expects.
>>
>> At the moment this limitation also prevents a C++ method
>> getCustomer(long customerID) to be exposed as a REST service for
>> example, as the generated C++ ServiceWrapper is missing the logic to
>> convert the customerID received in string form from the REST query
>> string to the expected C++ long int.
>>
>> So we just need to add the missing type conversion logic to the C++
>> ServiceWrappers :)
>>
>> Thoughts?
>>
>> -- 
>> Jean-Sebastien
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
>> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
>>
>> Hi Jean-Sebastien
>
> It could well be simpler if, as you suggest, the conversion happens in 
> the
> generated wrapper in this case. So we need such type information, as is
> required to effect the type conversion, to be generated into the wrapper.
>
Yes, and I think that there are three cases to consider here:
- The wrapper is generated and the type info can be burned into it (from 
the C++ class/interface of the service for which the wrapper was generated).
- The wrapper is generic and introspects the component implementation 
(incl. the associated .componentType metadata and the service interfaces 
it declares, if any) to determine the expected data type.
- The wrapper wraps a script written in a language that supports dynamic 
typing (e.g. Ruby) and best is to not convert and present the data to 
the script as-is (e.g. a string, an integer).

Independent of the type handling, the wrapper is responsible for 
presenting the data to the target component implementation in a suitable 
form, for example with Ruby, this means turn the input data into a Ruby 
VALUE object. Again this is independent of the type, as a Ruby VALUE can 
represent a int, a string etc.

> However I think we should try and arrange it so that we are not trying 
> to do
> any more conversions than are necessary so I'm not convinced that the 
> proxy
> should be guessing what type to produce only for it to be coerced 
> again at
> the wrapper unless this is a natural effect of the transport/protocol
> involved, for example, In your REST example. I.e. we want the proxy to 
> have
> the best information available to it in marshaling the data it has.
>

I agree. I was not clear before and by conversions in the proxy I meant 
"turn the data into a form that can be carried by our Operation + 
Operation::Parameter infrastructure". In the case of a C++ proxy, no 
conversion should be necessary. In the case of Ruby the string, int etc. 
data needs to be extracted of the Ruby VALUE object that wraps it. I'm 
not sure about PHP but you probably have a similar mechanism to carry 
data and track its usage so you may have to extract the raw data out of 
its PHP representation. So in most cases there is no conversion at all 
in the proxy or as you said just a natural effect of the 
transport/protocol involved (for example with REST we are receiving a 
query string and producing XML for the response).

> I also need to address complex types in the PHP extension. Where a remote
> interface is used you can imagine the WSDL, SMD or whatever being 
> parsed at
> the client component to construct a proxy capable of suitable type 
> checking
> and of providing convenience functions such as
> "giveMeAnSDOWithTheRightModelLoaded()". Looking at the code and 
> samples at
> the moment it seems that the C++ infrastructure loads available XSDs and
> provides some handy helper methods for creating SDOs based on the types
> available. I don't how they are related to particular interfaces 
> though. I
> expect I'm overlooking something.
>
We also load WSDL files. A Proxy is created from a Reference, and the 
Reference can carry an Interface definition, a WSDL portType for 
example. Composite::findWSDLDefinition(namespace) will give you a 
WSDLDefinition object from which you can lookup a WSDLPortType and 
WSDLOperation and the operation input and output types. You should be 
able to use these types to validate the data flowing through the proxy.

> Regards
>
> Simon
>

-- 
Jean-Sebastien


---------------------------------------------------------------------
To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: tuscany-dev-help@ws.apache.org


Re: [C++] Interface descriptions and type conversions

Posted by Simon Laws <si...@googlemail.com>.
On 2/1/07, Jean-Sebastien Delfino <js...@apache.org> wrote:
>
> Simon Laws wrote:
> > I notice in implementing the PHP extension (yes - believe it or not I'm
> > nearly ready to make a patch for the next version ;-) that, given the
> way
> > that I have implemented the PHP extension there is insufficient
> > information
> > available in the SCA runtime in order to do correct type conversions
> when
> > passing messages between components. I imagine this has been raised
> > before
> > but I looked at the archive and couldn't find a relevant thread.
> >
> > Imagine the scenario:
> >
> > C++ Component (ComponentA)  ---WireA--->   PHP Component (ComponentB)
> > ---WireB----> C++ Component (ComponentC)
> >
> > Currently the build process looks at the header files described in the
> > component type files and generates wrappers and proxies for the C++
> > components. I have currently implemented the PHP Extension to use
> generic
> > wrappers and proxies, i.e. it doesn't  use those generated based on the
> > interface descriptions,  so they need to dynamically manage the type
> > conversions for data coming in and going out of a PHP component.
> >
> > WireA.
> >
> > This is OK because the C++ SCA operation object that appears at
> > Component B
> > has a set of data/types based on the generated proxy.  The PHP
> > extension can
> > look at this and effect the right type conversions.
> >
> > WireB
> >
> > This is problematic. The dynamic PHP proxy has to generate an operation
> > object to pass to the the wrapper of ComponentC. The issue is that
> > there is,
> > as far as I can tell, no dynamic way of getting at the list of types
> that
> > are expected for any particular operation. There is of course a static
> > C++
> > proxy/wrapper combination that has been generated but I can't inspect
> > it at
> > runtime.
> >
> > I'm not keen on generating PHP specific interface classes. PHP is a
> > dynamic
> > environment and it's a whole stack of extra files we could do without
> > having
> > to manage particularly if we have to adapt the generator for every
> > extension
> > that's constructed. Can we extend the wrapper/proxy mechanism to
> > encapsulate
> > a runtime list of required types alongside the static method
> descriptions
> > that are already generated? We would need this to work for script to
> > script
> > calls as well as for the script/C++ combination so maybe we need
> > something
> > that hangs off the interface description part of the model. I'm not that
> > familiar with how that part of the model is used so a little
> > investigation
> > is required.
> >
> > Thoughts?
> >
> > Simon
> >
>
> Simon,
>
> It's an interesting issue. To explore it let's walk through the wiring
> scenario you describe and assume the following:
> - ComponentA (C++) -> WireA -> ComponentB (PHP) -> WireB -> ComponentC
> (C++)
> - ComponentA (C++) passes a short int to ComponentB (PHP)
> - ComponentB executes a PHP script which in turn passes a number to
> ComponentC (C++)
> - ComponentC expects that number to be given as a long int.
>
> Here's what I think should happen in the runtime:
> 1. At the source of WireA, a generated C++ CPPServiceProxy adds to our
> Operation object a Parameter of a type decided by the C++ client code: a
> C++ short int, with type == ParameterType::SHORT.
> 2. At the end of WireA, a PHPServiceWrapper converts that parameter to
> what the PHP script expects, for the sake of simplicity now I am going
> to assume that it needs to convert it to a C++ std::string.
> 3. The PHP script executes, now passes an std::string containing a
> number to the PHPServiceProxy at the source of WireB.
> 4. The PHPServiceProxy does not have much type info about that
> std::string parameter and can only add it to the Operation object as a
> std::string with type == ParameterType::STRING.
> 5. The CPPServiceWrapper at the end of WireB (actually the C++
> ServiceWrapper generated for ComponentC) receives the std::string and
> should convert it to what ComponentC expects: a long int.
>
> The general idea is that a ServiceProxy sends what it is given (or picks
> the most natural type out of the ParameterTypes that we have defined and
> converts the data to it). A ServiceWrapper converts what it receives to
> the type expected by the code it wraps. I think that the
> CPPServiceWrapper code and the generated C++ ServiceWrappers are simply
> missing the logic to convert data to what the target expects.
>
> At the moment this limitation also prevents a C++ method
> getCustomer(long customerID) to be exposed as a REST service for
> example, as the generated C++ ServiceWrapper is missing the logic to
> convert the customerID received in string form from the REST query
> string to the expected C++ long int.
>
> So we just need to add the missing type conversion logic to the C++
> ServiceWrappers :)
>
> Thoughts?
>
> --
> Jean-Sebastien
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
>
> Hi Jean-Sebastien

It could well be simpler if, as you suggest, the conversion happens in the
generated wrapper in this case. So we need such type information, as is
required to effect the type conversion, to be generated into the wrapper.

However I think we should try and arrange it so that we are not trying to do
any more conversions than are necessary so I'm not convinced that the proxy
should be guessing what type to produce only for it to be coerced again at
the wrapper unless this is a natural effect of the transport/protocol
involved, for example, In your REST example. I.e. we want the proxy to have
the best information available to it in marshaling the data it has.

I also need to address complex types in the PHP extension. Where a remote
interface is used you can imagine the WSDL, SMD or whatever being parsed at
the client component to construct a proxy capable of suitable type checking
and of providing convenience functions such as
"giveMeAnSDOWithTheRightModelLoaded()". Looking at the code and samples at
the moment it seems that the C++ infrastructure loads available XSDs and
provides some handy helper methods for creating SDOs based on the types
available. I don't how they are related to particular interfaces though. I
expect I'm overlooking something.

Regards

Simon