[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [ecf-dev] Fun with remote services part 1

Hi Scott,

thanks for explaining the issues regarding OSGi and credentials for authentication.

1) An explicit connect...i.e. the code that you use above to create and connect a container. 2) Implementing and registering your own IProxyContainerFinder, so that upon discovery (and container creation, and connect), that your credentials can be provided.
Say I will choose solution #1. 

Once I've created an IContainer instance, how would I now tell my services that they can be used remotely. I've read that I need to register the IContainer instance as a service in the host side OSGi service registry? The IContainer implementation will then listen for service registrations containing e.g. the following  properties and publish my service: 

   <property name="service.exported.interfaces" type="String" value="*"/>
   <property name="service.exported.configs" type="String" value="ecf.xmpp.smack"/>
   <property name="org.eclipse.ecf.containerFactoryArgs" type="String" value="jabber-server.de"/>

Is this the way it works? Would the IContainer implementation listen for my custom service registrations and check according to the provided properties whether to publish a service remotely or not? I've done this so far programmatically using the IContainer instance: 

public synchronized void registerRemoteService(String serviceName, Object impl,
ID[] targetIDs) {

Dictionary<String, ID[]> props = new Hashtable<String, ID[]>();
props.put(Constants.SERVICE_REGISTRATION_TARGETS, targetIDs);

// register ECF remote service
getRemoteServiceContainerAdapter().registerRemoteService(
new String[] { serviceName }, impl, props);
}

In case this is the way it works: can I provide the properties above at runtime using the ConfigAdminService?

On the client side the hello.ds.consumer bundle only describes that it requires an IHello service. But I was not able to find out how the service is configured: server url, username, password.

The server url and username (for xmpp) would be conveyed in what's called the 'endpointID' in discovery...e.g. for the XMPP provider the endpoint id would be an XMPP account:  'scottslewis@xxxxxxxxx'

My question focused on how do consumer retrieve a remote service proxy  using DS. So far I wrote a util class that can retrieve remote services for a specific XMPP ID in this way:

public synchronized <T> List<T> getRemoteService(Class<T> service, ID[] filterIDs,
String filter) throws ECFException, InvalidSyntaxException {
List<T> remoteServices = new ArrayList<T>();

IRemoteServiceContainerAdapter remoteServiceContainerAdapter = getRemoteServiceContainerAdapter();

/* 1. get available services */
IRemoteServiceReference[] refs = remoteServiceContainerAdapter
.getRemoteServiceReferences(filterIDs, service.getName(),
filter);

/* 2. get the proxies for service references */
for (int serviceNumber = 0; serviceNumber < refs.length; serviceNumber++) {

IRemoteService remoteService = remoteServiceContainerAdapter
.getRemoteService(refs[serviceNumber]);

T castedService = service.cast(remoteService.getProxy());
assert castedService != null : "castedService != null";
remoteServices.add(castedService);
}

return remoteServices;
}

What I did not understand is how does DS retrieve remote service proxies? As OSGi has no standard way to provide credentials I guess this won't work for me using XMPP. But in case the IContainer solution I've mentioned above works, could it be a solution to:
1. create an IContainer instance with credentials
2. register the instance as an OSGi service in a client side service registry
2. create DS components with the properties I've mentioned above?

I'm sorry for all these questions but it is still difficult for me to understand how ECF works with DS  and whether I can use it for my work.

Regards,
Eugen


Am Jun 14, 2010 um 15:54  schrieb Scott Lewis:

Hi Eugen,

Eugen Reiswich wrote:
Hi Scott, hi Wim,

I've also checked out the hello.ds examples and tried to understand how this example works. As I understand the host has to provide specific server properties within the service component. And as far as I understand these properties will trigger ECF to make a service remotely available (I didn't really get what exactly happens here).  In my XMPP case I've changed the example to:
<property name="service.exported.interfaces" type="String" value="*"/>
<property name="service.exported.configs" type="String" value="ecf.xmpp.smack"/>
<property name="org.eclipse.ecf.containerFactoryArgs" type="String" value="jabber-server.de <http://-server.de>"/>

If I got you right Scott I do no longer need to create an instance of IContainer like I did before:
IContainer container = ContainerFactory.getDefault().createContainer(protocol);
XMPPID xmppid = new XMPPID(container.getConnectNamespace(), userName + "@" + server);
IConnectContext connectContext = ConnectContextFactory.createUsernamePasswordConnectContext(userName, password);
container.connect(xmppid, connectContext);

But how do I now  provide with DS username and password in order to be able to connect to a server?

Because OSGi 4.2 provides no standard way to provide credentials for connect authentication, and the XMPP provider and service obviously require such credentials, it's necessary to use some mechanism not exposed by OSGi service properties.  There are a couple of ways provided by ECF's implementation:

1) An explicit connect...i.e. the code that you use above to create and connect a container. 2) Implementing and registering your own IProxyContainerFinder, so that upon discovery (and container creation, and connect), that your credentials can be provided.

I would say, that given that you already have the code for 1, that 1 seems more appropriate for you...since you are already doing it.

Nevertheless, I'll describe 2 a little bit here.  The easiest way to customize the proxy container find/creation/connect is to extend  org.eclipse.ecf.osgi.services.distribution.DefaultProxyContainerFinder and override this method (actually declared in AbstractProxyContainerFinder):

  protected IConnectContext getConnectContext(IContainer container,
          ID connectTargetID) {
      return null;
  }

Then, to have your proxy container finder used rather than the default one, simply register your instance as an OSGi service using the whiteboard pattern:

context.registerService(IProxyContainerFinder.class.getName(), new MyProxyContainerFinder(), null);
(you can do the registration with ds if you prefer)

By overriding this method (getConnectContext) you can provide the appropriate credentials for the connect that happens within the proxy container finder during the OSGi 4.2 consumer-side discovery.  So, for example

public class MyProxyContainerFinder extends DefaultProxyContainerFinder {

private String username;
private String password;

public MyProxyContainerFinder(String username, String password) {
 this.username = username;
 this.password = password;
}

protected IConnectContext getConnectContext(IContainer container, ID connectTargetID) {
 if (container and connectTargetID are appropriate types/values)
    return ConnectContextFactory.createUsernamePasswordConnectContext(this.username, this.password);
}

}

There is a little more documentation on the host and proxy container finder...and customizing the ECF impl of OSGi remote services:

http://wiki.eclipse.org/Customizing_and_Extending_ECF_Remote_Services

Note that depending upon how you are doing host registration and discovery, you will also have to specify (in service properties) the connectTargetID...which is used by the DefaultProxyContainerFinder.findProxyContainers method (which ultimately calls the getConnectContext when creating and then connecting a container).
So like I mentioned before, it seems to me that method 1 may be the easiest/quickest route for you (rather than method 2), but I wanted to use the opportunity to explain method 2 a little, since it provides quite a lot of flexibility for use cases that don't fit into the default OSGi 4.2 rs mold...like the use of XMPP.

Incidently...another thing to mention...it's also possible to override DefaultProxyContainerFinder.findProxyContainers and change the entire implementation of how an ECF container is selected/created/connected during OSGi 4.2 discovery.  For some use cases, this might be desired.


On the client side the hello.ds.consumer bundle only describes that it requires an IHello service. But I was not able to find out how the service is configured: server url, username, password.

The server url and username (for xmpp) would be conveyed in what's called the 'endpointID' in discovery...e.g. for the XMPP provider the endpoint id would be an XMPP account:  'scottslewis@xxxxxxxxx'

Scott


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