[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
| Re: [ecf-dev] Mapping ServiceReferences to FrameworkUUIDs (probable race condition in RSA?) | 
Hi Patrick,
On 4/6/2011 1:09 AM, Patrick D. wrote:
Hello ECF Team,
I'm working on a software that has to know where exactly services are 
and what osgi framework exported them.
It might help if you describe a little more about what your use case 
is.  The reason I say this is that the RSA approach is to allow 
flexibility in exporting and importing of remote services (and therefore 
'knowing' where they are, etc) by allowing new topology managers to be 
created...and the exporting and importing be explicitly controlled (by 
calling RemoteServiceAdmin service's exportService(ServiceReference,Map) 
and importService(EndpointDescription).
ECF currently has a single topology manager:  BasicTopologyManager, 
which implements the service EventHook (to export) and the 
EndpointListener (to discover and import remote services).  But the 
BasicTopologyManager is not at all intended to be the only topology 
manager...others are free to create other topology managers as needed 
(based upon ECF topology managers if they wish, but this is not at all 
required).
As it's not possible to find out what framework a ServiceReference 
points to, the IProxyDistributionListener and the 
IHostDiscoveryListener were used in the past to map ServiceReferences 
to URLs and the URLs to a framework.
That's no longer possible in ECF 3.5, because the listeners were 
removed for being obsolete. I understand, that the RSA is the new way 
to go.
What information are you looking for about the endpoint?  I guess I'm 
not clear on what you want to get from the remote endpoint (via the 
EndpointDescription).  And what do you wish to do with it...e.g. you 
could use it to determine whether a remote service is imported (i.e. 
with your own TopologyManager, you could filter on and/or look at the 
relevant property in the EndpointDescription and then use that to decide 
whether to call RemoteServiceAdmin.importService...or to do something else.
The first thing I tried was using the new EndPointListener. It failed, 
because there's no way to get the corresponding ServiceReference as 
long as the service was not imported.
Right...prior to the service being imported, the only information 
available (via the discovery part of RSA) is the EndpointDescription.
So my new approach is the following using an EventHook:
@Override
public void event(final ServiceEvent pEvent, final Collection pContexts) {
    // If a service was registered
    if (pEvent.getType() == ServiceEvent.REGISTERED) {
        final ServiceReference reference = pEvent.getServiceReference();
        // If the service was imported into the framework
        if (reference.getProperty("service.imported") != null) {
            final RemoteServiceAdmin rsa = getRemoteServiceAdmin();
            for (final ImportReference importReference : 
rsa.getImportedEndpoints()) {
                    if 
(importReference.getImportedService().equals(reference)) {
                        resolved(reference, 
importReference.getImportedEndpoint().getFrameworkUUID());
                    }
                }
            }
        }
    }
}
The idea is to wait for the service to be actually imported into the 
framework, then ask the RSA for the endpoint so I get both the 
endpoint and the ServiceReference. It doesn't work, 
becacuse rsa.getImportedEndpoints() is always empty. I used the 
debugger to step through the code and it seems that the imported 
endpoint does get added, but too late to catch it inside the 
EventHook. This was not what I expected. Shouldn't the RSA reflect the 
imported services as seen by the framework?
Only if the topology manager actually imports them.  It's possible that 
this is a bug, however...if they are actually imported, and 
rsa.getImportedEndpoints() still doesn't return them.  If you think this 
is what you are seeing (i.e. the service does get imported by RSA, but 
then subsequently does not return anything from 
rsa.getImportedEndpoints()...then please open a bug report and it will 
be examined.
If that's how it's supposed to work, do you suggest any other 
strategies to map a ServiceReference to the framework that exported it?
I'm still a little unclear...do you mean the proxy/imported 
ServiceReference...and finding out what framework exported it?  If this 
is what you mean, how do you mean to 'identify' the framework that 
exported it?  The reason I ask about this is that there are several 
pieces of information in the EndpointDescription that *might* satisfy 
your needs...e.g.
endpoint.id   (in ECF's impl this is the provider-defined 'uri' for the 
ECF container)
example:  r-osgi://foo.com:9278
also accessed through EndpointDescription.getId()
endpoint.framework.uuid  RSA-specified unique OSGi framework id
example:  70cd3d4b-4931-0010-1b63-d64101cefd5e
also accessed through EndpointDescription.getFrameworkId()
endpoint.service.id   The id of the ServiceReference on the *exporter*
example:  50
also accessed through EndpointDescription.getServiceId()
Are any of these (or their combination) useful for what you have in mind?
Note that you can also set the OSGi standard service.pid (a persistent 
id for your remote service) on remote service export...if your remote 
service has a persistent id (i.e. one that is durable over framework 
restarts).  You can then detect/filter/use this service.pid.  Also...you 
can explicitly set any custom property on exported remote service...and 
then use that for your application.
Another question...once you have the identification information you are 
looking for...how do you wish to use them?  Reason I ask:  If you want 
to control the import and export yourself, then it would be best to just 
create your own topology manager.
Scott