Angelo van der Sijpt
Thu, 22 May 2008 13:18:23 -0700
Hi Ronan,Skipping through the spec, there seems to be preciously little on the ManagedServiceFactory. So, I whipped up an example that's as small as possible. The syntax of this example assumes that you use the Felix Dependency Manager; the same thing can be done by using the bundle context directly, but that would be more verbose.
First up, we need some service. We start with an empty interface,
public interface MyInterface {
}
and an implementation,
public class MyService implements MyInterface {
private String m_name;
MyService(String name) {
m_name = name;
}
// Called by dependency manager
public void start() {
System.out.println("This is " + m_name + ", starting.");
}
// Called by dependency manager
public void stop() {
System.out.println("This is " + m_name + ", stopping.");
}
}
Nothing special here.
Normally, you would create an Activator, that publishes an instance of
this service. Not this time, we will create a ManagedServiceFactory.
A Managed Service Factory should be published as such, having its own
PID.
Properties props = new Properties();
props.put(Constants.SERVICE_PID, "myPid");
manager.add(createService()
.setInterface(ManagedServiceFactory.class.getName(),
props)
.setImplementation(new Factory(manager)));
We pass in the dependency manager, since the factory will need that
later on to create instances. The factory can be instructed to create
instances on updated(), but also deleted by deleted(). A minimal
service factory would be
public class Factory implements ManagedServiceFactory {
private Map<String, Service> m_instances = new
HashMap<String, Service>();
private final DependencyManager m_manager;
Factory(DependencyManager manager) {
m_manager = manager;
}
@Override
public void deleted(String pid) {
m_manager.remove(m_instances.remove(pid));
}
@Override
public String getName() {
return "Managed Service Factory example";
}
@SuppressWarnings("unchecked")
@Override
public void updated(String pid, Dictionary dict)
throws ConfigurationException {
Service newService = m_manager.createService()
.setInterface(MyInterface.class.getName(), dict)
.setImplementation(new MyService((String)
dict.get("name")));
m_instances.put(pid, newService);
m_manager.add(newService);
}
}
In updated(), we create a new instance of our service, pass in the
name (which we get from the dictionary), and keep both the pid (which
is a generated, unique id) and the service around, so we can pull them
later.
Now, on to using this service. Assuming that we have a ConfigurationAdmin ready (there is an implementation available from Felix) as m_configAdmin, we can do something like
Properties props = new Properties();
props.put("name", "Service one");
Configuration config1 =
m_configAdmin.createFactoryConfiguration("myPid", null);
config1.update(props);
props.put("name", "Service two");
Configuration config2 =
m_configAdmin.createFactoryConfiguration("myPid", null);
config2.update(props);
Thread.sleep(2000);
config2.delete();
Thread.sleep(1000);
config1.delete();
When we now build the factory in one bundle, containing MyService,
MyInterface and Factory with their Activator, and the user in another,
we can start the two bundles in the framework. The output will then be
This is Service one, starting.
This is Service two, starting.
<<two seconds>>
This is Service two, stopping.
<<one second>>
This is Service one, stopping.
If we woud remove the two delete() calls above, and use the Felix
Shell to ask the factory bundle for its services, this will be
something like
-> services 8
Factory bundle (8) provides:
----------------------------
objectClass = org.osgi.service.cm.ManagedServiceFactory
service.id = 23
service.pid = myPid
----
name = Service one
objectClass = factory.MyInterface
service.factoryPid = myPid
service.id = 24
service.pid = myPid.39ff584c-8d99-46e6-9c0b-0ed5512d3d3d
----
name = Service two
objectClass = factory.MyInterface
service.factoryPid = myPid
service.id = 25
service.pid = myPid.0a022def-4afe-4f02-b419-27ee9deb3796
which shows that there are two new services. Note that the new
instances also have the same properties that were passed into the
configuration, they have now become service properties.
There, that was quite something, but I believe this is the most minimal example. I hope this helps!
Angelo van der Sijpt On 22 May 2008, at 18:24, Ronan Dunklau wrote:
Sorry to bother you again, but could you please give me some docs on how touse the configuration admin service, and servicefactory in general ?I noticed the configurationadminfactory in the felix code, and i wondered ifwas supposed to use it directly. Thank you very muchLe Thursday 22 May 2008 17:33:51 Christian van Spaandonk, vous avez écrit :Ronan Dunklau wrote:Thank you for your help, and your clarification about osgi specs. I wanted to install the same bundle several times to create several instances of a UPnP control point, and it seemed that this would fit perfectly for this usage, "isolating" the different instances into separate bundles. I'm looking for a replacement solution.You may want to look into creating a ManagedServiceFactory (covered in compendium spec section 104). It lets you create multiple instances of aservice with different configurations. - ChristianThanks. Ronan Dunklau--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]