Skip to main content

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

Hi Scott,
 
thanks for the tips, i have changed my implementation to use the OSGi service access mechanisms.
 
and now my code looks like this:
Provider:

public

class Activator implements BundleActivator{

private static final String containerType = "ecf.r_osgi.peer";

@Override

public void start(BundleContext context) throws Exception{

Properties props =

new Properties();

// add OSGi service property indicated export of all interfaces exposed by service (wildcard)

props.put(IDistributionConstants.

SERVICE_EXPORTED_INTERFACES,IDistributionConstants.SERVICE_EXPORTED_INTERFACES_WILDCARD);

// add OSGi service property specifying config

props.put(IDistributionConstants.

SERVICE_EXPORTED_CONFIGS, containerType);

context.registerService(IHelloWorld.

class.getName(), new HelloServiceImpl(), props);

System.

out.println("IHello RemoteService registered");

}

/*

* (non-Javadoc)

* @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)

*/

@Override

public void stop(BundleContext context) throws Exception{

}

}

Consumer:

public

class Activator implements BundleActivator, ServiceTrackerCustomizer {

private BundleContext _context;

private ServiceTracker containerFactoryServiceTracker;

private ServiceTracker helloServiceTracker;

public static final String CONSUMER_NAME = "pt.hello.client";

private String containerType = "ecf.r_osgi.peer";

private IHelloWorld _proxy;

/*

* (non-Javadoc)

* @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)

*/

@Override

public void start(BundleContext context) throws Exception{

_context= context;

// Create ECF container of appropriate type. The container instance

// can be created in a variety of ways...e.g. via code like the line below,

// via the new org.eclipse.ecf.container extension point, or automatically

// upon discovery via the IProxyContainerFinder/DefaultProxyContainerFinder.

getContainerFactory().createContainer(

containerType);

// Create service tracker to track IHello instances that have the 'service.imported'

// property set (as defined by OSGi 4.2 remote services spec).

helloServiceTracker = new ServiceTracker(context, IHelloWorld.class.getName(), this);

helloServiceTracker.open();

if(_proxy!=null){

String value =

this._proxy.hello("ronen");

System.

out.println(value);

}

else

System.

out.println("the proxy is not set");

}

 

private IContainerFactory getContainerFactory() {

if (containerFactoryServiceTracker == null) {

containerFactoryServiceTracker = new ServiceTracker(_context,

IContainerFactory.

class.getName(),

null);

containerFactoryServiceTracker.open();

}

return (IContainerFactory) containerFactoryServiceTracker.getService();

}

@Override

public void stop(BundleContext arg0) throws Exception {

if (helloServiceTracker != null) {

helloServiceTracker.close();

helloServiceTracker = null;

}

if (containerFactoryServiceTracker != null) {

containerFactoryServiceTracker.close();

containerFactoryServiceTracker = null;

}

this._context = null;

}

/**

* Method called when a REMOTE IHello instance is registered.

*/

public Object addingService(ServiceReference reference) {

System.

out.println("IHello service proxy being added");

// Since this reference is for a remote service,

// The service object returned is a proxy implementing the

// IHello interface

IHelloWorld proxy = (IHelloWorld)

_context.getService(reference);

// Call proxy synchronously. Note that this call may block or fail due to

// synchronous communication with remote service

System.

out.println("STARTING remote call via proxy...");

proxy.hello(

CONSUMER_NAME+" via proxy");

System.

out.println("COMPLETED remote call via proxy");

System.

out.println();

// Call other helloMessage method

System.

out.println("STARTING remote call via proxy...");

proxy.hello(

CONSUMER_NAME+" via proxy howdy");

System.

out.println("COMPLETED remote call via proxy");

System.

out.println();

this._proxy = proxy;

return proxy;

}

public void modifiedService(ServiceReference reference, Object service) {

}

public void removedService(ServiceReference reference, Object service) {

this._proxy = null;

System.

out.println("IHello Service proxy removed");

}

 

}

few questions:
i wish to distribute the consumer and provider remotly i dont see how the consumer is aware of its providers location...
1. what methods should i use for dynamic discovery of endpoints?
2. what happen if i have 3 instances of my service on 3 diffrent nodes how the consumer will locate these 3 instances and which of them will he invoke?
 
Ronen.
On Mon, Mar 21, 2011 at 5:36 PM, Scott Lewis <slewis@xxxxxxxxxxxxx> wrote:
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


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




--
Ronen Hamias
Cell Phone: +972-50-2289988

Back to the top