[
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