[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [ecf-dev] Using a container multiple times

Thanks Scott.


So if I am publishing the SharedObject *as well as* the Remote Service
via the same container, what's the best way of picking up the
container which the ECF implementation of OSGI 4.2 has created under
the bonnet, in order to adapt it to a  ISharedObjectContainer? Can I
pick it up from the OSGI framework?



Robert

On Thu, Nov 4, 2010 at 5:23 PM, Scott Lewis <slewis@xxxxxxxxxxxxx> wrote:
> Hi Robert,
>
> On 11/4/2010 9:18 AM, Robert Onslow wrote:
>>
>> Dear All
>>
>> On the server side, I have create a container and registered a shared
>> object on it.
>>
>> I would like to publish a remote service over it as well. I tried:
>>
>> final IContainer container =
>> manager.getContainerFactory().createContainer("ecf.generic.server");
>> final ISharedObjectContainer sharedObjectContainer =
>> (ISharedObjectContainer)
>> container.getAdapter(ISharedObjectContainer.class)
>> ISharedObjectManager manager1 =
>> sharedObjectContainer.getSharedObjectManager();
>> Properties props = new Properties();
>> props.put(EventConstants.EVENT_TOPIC, "uk_co_xlegal_xbundle3_remote");
>>
>> manager1.addSharedObject(IDFactory.getDefault().createStringID("uk.co.xlegal.xbundle3.remote"),
>> (ISharedObject) admin, props);
>>
>> //now share the StateProvider service
>>
>> IRemoteServiceContainerAdapter rsc = (IRemoteServiceContainerAdapter)
>> ((IAdaptable) container).getAdapter(IRemoteServiceContainerAdapter.class);
>> StateProvider provider = (StateProvider)
>> localStateServiceTracker.getService();
>>
>>
>> rsc.registerRemoteService(new String[]{StateProvider.class.getName()},
>> provider, null);
>>
>> ...
>>
>> I am not seeing the service on the client side. I have connected, and
>> am successfully synchronizing the EventAdmin.
>> But if I register a tracker for the remote service, the remote service
>> is never found.
>>
>> remoteStateProviderTracker = new ServiceTracker(context,
>> StateProvider.class.getName(), new ServiceTrackerCustomizer() {
>>
>>                        @Override
>>                        public Object addingService(ServiceReference
>> reference) {
>> //never reaching here
>>
>>                                StateProvider provider = (StateProvider)
>> context.getService(reference);
>>                                Map<String, Object>  state =
>> provider.provideState();
>>                                List<String>  openBundleURIs =
>> (List<String>) state.get("openBundleURIs");
>>
>>                                for (String uri : openBundleURIs)
>>                                        syncWithBundleURI(uri);
>>                                return provider;
>>
>>
>>                        }
>>
>>                        @Override
>>                        public void modifiedService(ServiceReference
>> reference,
>>                                        Object service) {
>>                                // TODO Auto-generated method stub
>>
>>                        }
>>
>>                        @Override
>>                        public void removedService(ServiceReference
>> reference,
>>                                        Object service) {
>>
>>                        }
>>
>>                });
>>
>> remoteStateProviderTracker.open();
>>
>> Is it possible to use a server container in this way?
>
>
> The short answer to your question is 'yes'.
>
> But I'll give a slightly longer answer...and of course answer any follow up
> questions as needed.
>
> One thing I should briefly explain about remote services...the ECF remote
> services API pre-dated the OSGi 4.2 remote services spec implementation.  In
> fact, the OSGi remote services implementation actually *uses* the ECF remote
> services API to expose OSGi services remotely.  One implication of this
> layering (which is described graphically here [1]), is that it's possible to
> use ECF remote services *without* the OSGi 4.2 remote services
> implementation.
>
> So on your service host/server side, when you call
>
> rsc.registerRemoteService(new String[]{StateProvider.class.getName()},
> provider, null);
>
> this makes the StateProvider service available to the ECF remote service API
> on the client side...but *not* the OSGi service registry.  So, on the
> client, you could call something like this
>
> IRemoteServiceReference[] refs =
> rsc.getRemoteServiceReferences(StateProvider.class.getName(),null);
>
> Note that there is also a RemoteServiceTracker class
> (org.eclipse.ecf.remoteservice.util.tracker.RemoteServiceTracker).
>  Instances of RemoteServiceTracker have the same general behavior as OSGi
> ServiceTrackers, but are based upon the ECF remote service API (rather than
> the OSGi service registry).
>
> With the code above, I believe that's why your ServiceTracker doesn't
> discover the service...because the OSGi ServiceTracker only tracks service
> that are in the OSGi service registry.  And you are registering the remote
> service via rsc.registerRemoteService (the ECF remote service API directly).
>
> The ECF implementation of the OSGi 4.2 remote services specification,
> however, makes *any* direct use of the ECF remote services API unnecessary.
>  That is, on the host/server-side, as per the OSGI spec, when an OSGi
> registration like this is done:
>
> props.put("service.exported.configs","ecf.generic.server");
> props.put("service.exported.interfaces","*");
> ServiceRegistration reg =
> bundleContext.registerService(StateProvider.class.getName(),service, props);
>
> the ECF impl of OSGi remote services intercepts this call..and ends up
> calling the ECF registerRemoteService method *for you* (as well as
> publishing the meta-data about the remote service via some discovery).
>
> Then on the client/proxy side, the ECF implementation of OSGi 4.2 remote
> services uses the discovery to asynchronously discover the remote service
> meta-data, and then it turns around and calls the ECF
> getRemoteServiceReferences method for you, creates a proxy, and registers
> this proxy in the OSGi service registry...thus triggering detection by
> ServiceTrackers that are responding to the given service.  Just for
> reference, the ECF impl of OSGi 4.2 remote services is in the bundles:
>  org.eclipse.ecf.osgi.services.discovery and
> org.eclipse.ecf.osgi.services.distribution.
>
> So in short, you can use the ECF remote services API directly, by using
> registerRemoteService (as you are doing on the host above), and
> getRemoteServiceReferences/RemoteServiceTracker on the client, or you can
> use the ECF impl of the OSGi 4.2 remote services specification (i.e. in the
> bundles given above)...along with some discovery, and use
> BundleContext.registerService (host), and
> getServiceReferences/ServiceTracker/DS on the client.  Both mechanisms are
> available...and things are layered as shown in this diagram [1].
>
> Scott
>
> [1] http://wiki.eclipse.org/OSGi_4.2_Remote_Services_and_ECF
>
>
> _______________________________________________
> ecf-dev mailing list
> ecf-dev@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/ecf-dev
>



-- 
Robert Onslow
XLegal Limited