Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [virgo-dev] Would you like to try debugging a Gemini Blueprint issue (with ECF)?

Scott,

The sequence of events is:

1 service is publisher on remote host
2 service consumed by ECF on client and proxied
3 blueprint applies its proxy to the ECF proxied object, but only for the interfaces defined in the importing definition that is on <reference/> XML tag.

So, ECF proxy is applied, blueprint finds and delivers correct service reference but it wraps it in its own proxy. greedy-proxy or defining multiple interfaces to proxy (last one cannot be done with the blueprint specification XML as it allows for a single interface only) will work around this situation. 

For greedy-proxy to work all implemented interfaces and non-final classes must be defined in OJECTCLASS property. 

To work around limitations of the spec, the <bean/> definitions can be used to directly register an "import factory" and define missing interfaces. 

Regards,

-- 
Dmitry Sklyut
Sent with Sparrow

On Tuesday, February 5, 2013 at 18:50, Scott Lewis wrote:

Hi Dmitry,

On 2/5/2013 2:48 PM, Dmitry Sklyut wrote:
Scott,

I looked over this issue and here is what can be done (all config examples are based on github example provided in the forum post).

First bad news: I don't think it can be done with vanilla Blueprint xml config.

Good news it can be done with a little help from ECF and change in configuration on the blueprint side.

greedy-proxying is the answer: http://www.eclipse.org/gemini/blueprint/documentation/reference/1.0.2.RELEASE/html/service-registry.html#service-registry:refs:collection:greedy-proxying

BUT for greedy-proxying to work - ECF must publish its proxy with all interfaces advertised in reference.getProperty(Constants.OBJECTCLASS).
Including org.eclipse.ecf.remoteservice.IRemoteServiceProxy

Hmm. I'm not sure if I understand what you are saying. ECF's remote
service admin does create and import the proxy with all interfaces that
are advertised in objectclass. If ECF's remote service admin is used
(e.g. as per the ECF examples), this does happen...but it seems to me
that Gemini is somehow pre-empting and/or circumventing the operation of
the ECF Remote Service Admin on the import side (I'm not sure of this,
it's just a hypothesis). With ECF's proxy creation and publishing,
IRemoteServiceProxy will be automatically added to the proxy...whether
or not it appears in objectclass...and this happens fine in the ECF
remote service examples because the proxy creation and publishing is
done via the ECF remote service admin importService call.

I think the best solution should be to let the ECF remote service admin
create and publish the proxy on the consumer/import side. I'm still not
sure why this isn't just happening in this case...as it does in the
example code (without Gemini). I think it would/will be much
preferable to have ECF create and publish the proxy (as it should for
ECF-exported remote services) than to try to get blueprints impl to
import remote services exported by blueprint (it seems that's what you
are attempting to do below...but I might be mistaken about your intent
though). In any event, my reading of the remote service admin spec
allows multiple distribution providers co-exist and not interfere with
each other...by only responding to the appropriate discovered remote
services (i.e. those exported via a compatible config).

Scott





On blueprint side:

1. use spring osgi namespace and you can change <reference/> to a <list/> and enable greedy-proxying

Instead of <blueprint..></blueprint> use:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:osgi="http://www.springframework.org/schema/osgi"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-2.0.xsd">


Instead of reference
<reference
id="host" interface="org.eclipse.ecf.examples.remoteservices.hello.IHello"
availability="mandatory">
<reference-listener bind-method="bindHello">
<ref component-id="consumer" />
</reference-listener>
</reference>

Use list
<osgi:list id="hostInListWithGreedy"
interface="org.eclipse.ecf.examples.remoteservices.hello.IHello"
greedy-proxying="true" cardinality="1..N">
<osgi:listener bind-method="bindHello">
<ref bean="consumer" />
</osgi:listener>
</osgi:list>

Or use to specify 2 interfaces vs. 1.

<osgi:reference id="host" cardinality="1..1">
<osgi:interfaces>
<value>org.eclipse.ecf.examples.remoteservices.hello.IHello</value>
<value>org.eclipse.ecf.remoteservice.IRemoteServiceProxy</value>
</osgi:interfaces>
<osgi:listener bind-method="bindHello">
<ref bean="consumer"/>
</osgi:listener>
</osgi:reference>


2. Instead of osgi:reference or osgi:list - use bean configuration
(something like this in spring bean style)

<bean id="host2" class="org.eclipse.gemini.blueprint.service.importer.support.OsgiServiceProxyFactoryBean">
<property name="availability" value="MANDATORY"/>
<property name="interfaces">
<list>
<value>org.eclipse.ecf.examples.remoteservices.hello.IHello</value>
<value>org.eclipse.ecf.remoteservice.IRemoteServiceProxy</value>
</list>
</property>
<property name="listeners">
<list>
<bean class="org.eclipse.gemini.blueprint.config.internal.adapter.OsgiServiceLifecycleListenerAdapter">
<property name="bindMethod" value="bindHello"/>
<property name="targetBeanName" value="consumer"/>
<!-- or -->
<property name="target" ref="consumer"/>
</bean>
</list>
</property>
</bean>

There is a similar bean for <list/> OsgiServiceCollectionProxyFactoryBean that can be configured with greedy-proxying also.

I don't think there is anything blueprint can do to expose org.eclipse.ecf.remoteservice.IRemoteServiceProxy without knowing that it exists if it is not in the OBJECTCLASS property.

Another way forward for now is to get the target service object from within Blueprint proxy.

ala.

ServiceReference nativeReference = ((ServiceReferenceProxy)serviceReference).getTargetServiceReference()

This way it is as naked as DS service object.

Hope this is all clear. I forked the blueECF github project and will push changes to it later today.


Regards,


_______________________________________________
virgo-dev mailing list
virgo-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/virgo-dev


Back to the top