[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [ecf-dev] help

Hi Ronen,

I notice a few things wrong with your client/remote service consumer...and I've put some inline comments...but before that I should ask...why (on the consumer) are you using the ECF remote services API *directly*?  That is, with the OSGi remote services spec/standard, as well as the newly release remote services admin [1], it is quite possible to use the normal OSGi service access mechanisms (e.g. ServiceTracker, getServiceReference, declarative services, other injection frameworks, etc)...and not have to access ECF code at all.  This is what several of the example consumers do (use ds, or ServiceTracker to get the local proxy to the remote service).

However, you should be able to use the ECF remote service API directly on the consumer...if you wish...so I'll provide comments to your code below...but I just wanted to point out that there are other ways.

One other thing I should mention, however...before commenting on your consumer code.  The RSA specification (newly implemented in ECF 3.5) defines a discovery mechanism...and it also defines a file-based discovery...so that you can trigger the OSGi remote service discovery by defining an xml-file that provides meta-data about the remote service...in a standardized format called 'Endpoint Description Extender Format' (edef).   There is now an example consumer that uses the edef file...and some wiki documentation of how to use this format [1].  Note that in accord with the RSA spec, the edef file is read...triggering the remote service discovery...*when the bundle containing the edef is started*.

[1] http://wiki.eclipse.org/File-based_Discovery_with_the_Endpoint_Description_Extender_Format

(e.g. On 3/21/2011 3:20 AM, ronen hamias wrote:

 

Hi,

I am trying to consume a remote service. Note that my environment is entirely server side.

I have implemented a simple hello world service running on tomcat using the bridge.war

 

My service is registered like this:

 

/*

     * (non-Javadoc)

     * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)

     */

    public void start(BundleContext context) throws Exception {

      Properties props = new Properties();

 

      props.put("service.exported.interfaces", "*");

      props.put("service.exported.configs", "ecf.r_osgi.peer");

 

      ServiceRegistration reg =

      context.registerService(IHelloWorld.class.getName(),new HelloServiceImpl(), props);

 

            System.out.println("IHello RemoteService registered");

 

    }

 

I wish to consume this service again from server side environment:

My service client looks like this:

 

public void start(BundleContext context) throws Exception

      {

            _context = context;

 

            // Create R-OSGi Container

            IContainerManager containerManager = getContainerManagerService();

            _container = containerManager.getContainerFactory().createContainer("ecf.r_osgi.peer");

 

            // Get remote service container adapter

          IRemoteServiceContainerAdapter containerAdapter = (IRemoteServiceContainerAdapter) _container

                   .getAdapter(IRemoteServiceContainerAdapter.class); // after this line of code containerAdapter is null


containerAdapter should not be null...as the next line will cause a NPE if it is.   The r-osgi container should return a non-null containerAdapter with this code.  If containerAdapter is null after the call to getAdapter, then something else is wrong.

 

            // Lookup IRemoteServiceReference

            IRemoteServiceReference[] helloReferences = containerAdapter.getRemoteServiceReferences(IDFactory.getDefault()

                        .createID(_container.getConnectNamespace(), GENERIC_SERVICE_HOST), IHelloWorld.class.getName(), null);


GENERIC_SERVICE_HOST will not be correct...as you seem to be using the r-osgi provider (i.e. ecf.r_osgi.peer) on the host.  For r-osgi, this should be something like:

"r-osgi://localhost:9268/" rather than GENERIC_SERVICE_HOST


 

            // Get remote service for reference

            IRemoteService remoteService = containerAdapter.getRemoteService(helloReferences[0]);

 

            // Get the proxy

            IHelloWorld proxy = (IHelloWorld) remoteService.getProxy();

 

            // Call the proxy

            proxy.hello("RemoteService Client via Proxy");

            System.out.println((new Date()) + " RemoteService Called via Proxy");

 

            // Call Sync

            remoteService.callSync(createRemoteCall("RemoteService Client Sync"));

            System.out.println((new Date()) + " RemoteService Called Sync");

 

 

      }

 

The IRemoteServiceContainerAdapter is inherits from IAdaptable (org.eclipse.core) that is a UI dependency?

 

How would I consume a service from a server side environment?


Well, like I said above...there are several ways...including using the ECF remote services API as you try to do above...but there are simpler/easier ways (e.g. OSGi service access mechanisms) if you wish to use them.  The various hello example bundles with 'consumer' in their name show different ways to do this...e.g. o.e.e.e.remoteservices.hello.consumer (ServiceTracker), o.e.e.e.remoteservices.hello.consumer.edef (edef format), o.e.e.e.remoteservices.hello.consumer.rs (ECF remote service api), o.e.e.e.remoteservices.hello.ds.consumer (declarative services).  All of these consumers are as applicable in server environment as they are in client...as they have no UI.

Scott