You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@tuscany.apache.org by Florian Rosenberg <fr...@us.ibm.com> on 2007/09/11 19:51:14 UTC

Resolving an calling the target of a reference

hi,

we have created a component implementation for a small RESTful composition
language which does not support references to other components, now we want
to add support for that. The component implementation is similar to BPEL,
but without all the WSDL and partnerlink stuff. Just support for REST and
custom activities to extend the language.

An example of using it in the composite file is:
<component name="FeedsAggregatorComponent">
        <implementation.splice
            baseDir="src/main/resources/flowdir/"
            path="feeds" url="getFeeds"
            contentType="text/xml" />
        <reference name="aggregate" target="AggregateServiceComponent" />

</component>
<!-- other stuff goes here -->


I need to tell our Splice engine where the references are and how it can
resolve it. The problem is that from the Reference instance, I cannot
retrieve an invoker instance to invoke my target as specified in the
<reference /> tag. AFAIK, i need a binding and an operation instance to get
an Invoker instance. The binidng is not a problem is can be retrieved from
the reference instance. Furthermore, I need an operation instance; the name
of the operation corresponds to some value in the process definition that I
know.

To get the operations i need the interface and thus its interface contract
first. When I do a
InterfaceContract contract = _reference.getTargets().get
(0).getInterfaceContract();

it is always null, so I cannot get the interface and iterate over its
operations to find a matching one. If I would have the operation I could
establish a binding.

Invoker invoker = _reference.getInvoker(bindings.get(0), referencedOp);
Message request = _messageFactory.createMessage();
// here the Splice engine can call the reference

I do the whole stuff in the implementation provider class (where I also
configure the engine).

Any help and pointers are highly appreciated. I'm stuck with that for a
couple of times now. By the way, this message occurs in the logs, but I'm
not really sure if it is the source of my problem:
WARNING: [WARNING] Reference not found for component reference:
FeedsAggregatorComponent/aggregate null

If you need more infor let me know.

Best regards,
Florian


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


Re: Resolving an calling the target of a reference

Posted by Florian Rosenberg <fr...@us.ibm.com>.
hi,

first of all the good news. I got rid of the reference warning by
implementing a correct resolving of the component type. I had the
componentType file but the resolving was incorrect. I still have some
issues and comments inline.

Jean-Sebastien Delfino <js...@apache.org> wrote on 09/11/2007 11:17:52
PM:
> Florian Rosenberg wrote:
> > hi,
> >
> > we have created a component implementation for a small RESTful
composition
> > language which does not support references to other components, now we
want
> > to add support for that. The component implementation is similar to
BPEL,
> > but without all the WSDL and partnerlink stuff. Just support for REST
and
> > custom activities to extend the language.
> >
> > An example of using it in the composite file is:
> > <component name="FeedsAggregatorComponent">
> >         <implementation.splice
> >             baseDir="src/main/resources/flowdir/"
> >             path="feeds" url="getFeeds"
> >             contentType="text/xml" />
> >         <reference name="aggregate"
target="AggregateServiceComponent" />
> >
> > </component>
> > <!-- other stuff goes here -->
> >
> >
> > I need to tell our Splice engine where the references are and how it
can
> > resolve it. The problem is that from the Reference instance, I cannot
> > retrieve an invoker instance to invoke my target as specified in the
> > <reference /> tag. AFAIK, i need a binding and an operation instance to
get
> > an Invoker instance. The binidng is not a problem is can be retrieved
from
> > the reference instance. Furthermore, I need an operation instance; the
name
> > of the operation corresponds to some value in the process definition
that I
> > know.
> >
> > To get the operations i need the interface and thus its interface
contract
> > first. When I do a
> > InterfaceContract contract = _reference.getTargets().get
> > (0).getInterfaceContract();
> >
> >
>
> getTargets().get(0).getInterfaceContract() returns the interface on the
> service that the reference is wired to.
>
>  From the component you pasted above I'm guessing that it must be a
> service on the AggregateServiceComponent, and I'm also guessing that
> it's the only service on that component since you didn't specify a
> service name in the reference target attribute.
>
> Can you post the XML describing AggregateServiceComponent?

yes, there is a component called AggregateServiceComponent. I paste the
whole composite file for clarity:

<component name="FeedAggregatorComponent">
  <tuscany:implementation.splice name="feedaggregator"
      baseDir="src/main/resources/flowdir/"
      path="feeds" url="getFeeds"
      contentType="text/xml" />
  <reference name="aggregateSca" target="AggregateComponent" />

</component>

<component name="AggregateComponent">
  <implementation.java class="feedaggregator.FeedAggregateActivity"/>
</component>

> Another comment is that you shouldn't rely on the interface of the
> target service (as there may be no target service if your reference is
> configured to talk to an external endpoint with a binding instead of
> being wired with a target attribute) to determine the interface that
> should be used on the reference.

I understand that I should not rely on the interface contract, but I'm not
sure how to invoke an operation on my reference in a common way without
retrieving the InterfaceContract first. To get an invoker I need to
retrieve a instance of a Binding and an instance of Operation (which I can
get only through the interface, right?

The way I do it now is the following (_reference denote my reference from
the Splice component impl):

List<Binding> bindings = _reference.getBindings();
if (bindings != null && bindings.size() == 0) {
  throw new ServiceRuntimeException(String.format("At least one binding is
needed " +
                        " for the referenced component '%s'.", getName()));
}
Binding b = bindings.get(0);
Interface iface = _reference.getInterfaceContract().getInterface();
List<Operation> operations = iface.getOperations();
Operation targetOp = null;
for (Operation op : operations) { // i require references to implement a
special interface to be called from Splice
  if ("invoke".equals(op.getName())) {
    targetOp = op;
    break;
  }
}

Invoker invoker = null;
if (_reference instanceof RuntimeComponentReference && targetOp != null) {
  ReferenceBindingProvider provider = ((RuntimeComponentReference)
_reference).getBindingProvider(b);
  invoker = provider.createInvoker(targetOp);
}

The above code works fine for references from a Splice workflow. A
reference in the sense of Splice is mainly an extension activity to the
Splice language, such as aggregating RSS feeds in this case. Of course the
component reference are very limited for Splice, by requiring the
implementation of a certain interface (with an invoke method) but that is
fine for this case. We try to leverage as much features as SCA provides ;).

I have tested the above code only with referenced Java components. When
there is no target component, rather an external service - as you said
above - how can I do that or will it work with the above piece of code? I
check some of the existing component implementations but it couldn't found
anything which would make my "invocation of references more clear" to me.

Thanks,
-Florian


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


Re: Resolving an calling the target of a reference

Posted by Jean-Sebastien Delfino <js...@apache.org>.
Florian Rosenberg wrote:
> hi,
>
> we have created a component implementation for a small RESTful composition
> language which does not support references to other components, now we want
> to add support for that. The component implementation is similar to BPEL,
> but without all the WSDL and partnerlink stuff. Just support for REST and
> custom activities to extend the language.
>
> An example of using it in the composite file is:
> <component name="FeedsAggregatorComponent">
>         <implementation.splice
>             baseDir="src/main/resources/flowdir/"
>             path="feeds" url="getFeeds"
>             contentType="text/xml" />
>         <reference name="aggregate" target="AggregateServiceComponent" />
>
> </component>
> <!-- other stuff goes here -->
>
>
> I need to tell our Splice engine where the references are and how it can
> resolve it. The problem is that from the Reference instance, I cannot
> retrieve an invoker instance to invoke my target as specified in the
> <reference /> tag. AFAIK, i need a binding and an operation instance to get
> an Invoker instance. The binidng is not a problem is can be retrieved from
> the reference instance. Furthermore, I need an operation instance; the name
> of the operation corresponds to some value in the process definition that I
> know.
>
> To get the operations i need the interface and thus its interface contract
> first. When I do a
> InterfaceContract contract = _reference.getTargets().get
> (0).getInterfaceContract();
>
>   

getTargets().get(0).getInterfaceContract() returns the interface on the 
service that the reference is wired to.

 From the component you pasted above I'm guessing that it must be a 
service on the AggregateServiceComponent, and I'm also guessing that 
it's the only service on that component since you didn't specify a 
service name in the reference target attribute.

Can you post the XML describing AggregateServiceComponent?

Another comment is that you shouldn't rely on the interface of the 
target service (as there may be no target service if your reference is 
configured to talk to an external endpoint with a binding instead of 
being wired with a target attribute) to determine the interface that 
should be used on the reference.

More below on this subject, and how you can type your reference with an 
interface contract.

> it is always null, so I cannot get the interface and iterate over its
> operations to find a matching one. If I would have the operation I could
> establish a binding.
>
> Invoker invoker = _reference.getInvoker(bindings.get(0), referencedOp);
> Message request = _messageFactory.createMessage();
> // here the Splice engine can call the reference
>
> I do the whole stuff in the implementation provider class (where I also
> configure the engine).
>
> Any help and pointers are highly appreciated. I'm stuck with that for a
> couple of times now. By the way, this message occurs in the logs, but I'm
> not really sure if it is the source of my problem:
> WARNING: [WARNING] Reference not found for component reference:
> FeedsAggregatorComponent/aggregate null
>   

You're seeing this because you declared a ComponentReference declaration 
named aggregate on your Component and we couldn't find a Reference 
definition named aggregate on the ComponentType describing your 
Component. We'll have to make that error message more clear :)

Here's more background on the relationship between a ComponentReference 
and a Reference and a Component and a ComponentType:

- A Component (<component>) is an instance of a ComponentType 
(<componentType>). Basically you can have multiple components of the 
same type, configured differently, with different wiring, bindings or 
property configuration for example.

- A ComponentType is typically reflected from an Implementation. For 
example we can introspect a Java implementation class, or a BPEL process 
implementation and derive a ComponentType from it, describing the 
characteristics of the implementation. In the Tuscany SCA assembly 
model, Implementation extends ComponentType.

- If you don't want to derive the ComponentType from the Implementation, 
you can also just write by hand an XML file, .componentType, describing it.

- In both cases, the ComponentType lists the Properties supported by the 
type, the Services and References supported by the type and their 
InterfaceContracts (Interface and callback Interface).

- A <component> element declares a Component. The Component will have an 
ComponentReference for each Reference on its ComponentType, a 
ComponentService for each Service on the ComponentType, a 
ComponentProperty for each Property on the ComponentType.

An analogy with Java may help describe these:
Component == an Object with field declarations and the ability to set 
values in the fields.
Implementation == a concrete Class that can be instantiated into Objects.
ComponentType == an abstract Class defining the field and its type and 
default value.

So, to summarize:

- The message you're getting complains that you're trying to configure 
ComponentReference "aggregate" on your Component, but your ComponentType 
didn't define any Reference named "aggregate".

- To get an "aggregate" Reference on your ComponentType you can either 
write by hand a .componentType file describing the splice flow in 
src/main/resources/flowdir/ or inspect your splice flow and derive its 
references and populate the references in your splice Implementation 
model object.

Here's a pointer to a sample Implementation extension that does that for 
Services:
http://svn.apache.org/repos/asf/incubator/tuscany/java/sca/samples/implementation-pojo-extension/src/main/java/pojo/impl/POJOImplementationProcessor.java

Creating References should be very similar, I'm thinking that we should 
try to enhance that sample to cover References as well at some point :)

When you create the References objects you can set their 
InterfaceContract like we do for Services in the sample.

Hope this helps...

> If you need more infor let me know.
>
> Best regards,
> Florian
>
>   

-- 
Jean-Sebastien


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