¿Cómo implementas un ManagedServiceFactory en OSGi?

Actualmente estoy tratando de configurar mi propia implementación de un ManagedServiceFactory . Esto es lo que estoy tratando de hacer: necesito varias instancias de algún servicio en una base por configuración. Con DS, los componentes funcionaron a la perfección, pero ahora descubrí que estos servicios deberían manejar su propio ciclo de vida (es decir, (des) registro en el registro de servicio) dependiendo de la disponibilidad de algún recurso externo, lo cual es imposible con DS.

Por lo tanto, mi idea fue crear un ManagedServiceFactory , que luego recibiría configuraciones de ConfigurationAdmin y crearía instancias de mi clase. Estos nuevamente intentarán conectarse al recurso en un hilo separado y se registrarán como servicio cuando estén listos para operar.

Como no tuve suerte implementando esto todavía, traté de dividir todo en las partes más básicas, sin siquiera tratar con el registro dynamic (de), solo tratando de hacer que ManagedServiceFacotry funcione:

 package my.project.factory; import java.util.Dictionary; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.ServiceRegistration; import org.osgi.service.cm.ConfigurationException; import org.osgi.service.cm.ManagedServiceFactory; public class Factory implements BundleActivator, ManagedServiceFactory { private ServiceRegistration myReg; private BundleContext ctx; private Map services; @Override public void start(BundleContext context) throws Exception { System.out.println("starting factory..."); this.ctx = context; java.util.Dictionary properties = new Hashtable(); properties.put(Constants.SERVICE_PID, "my.project.servicefactory"); myReg = context.registerService(ManagedServiceFactory.class, this, properties); System.out.println("registered as ManagedServiceFactory"); services = new HashMap(); } @Override public void stop(BundleContext context) throws Exception { for(ServiceRegistration reg : services.values()) { System.out.println("deregister " + reg); reg.unregister(); } if(myReg != null) { myReg.unregister(); } else { System.out.println("my service registration as already null " + "(although it shouldn't)!"); } } @Override public String getName() { System.out.println("returning facotry name"); return "ServiceFactory"; } @Override public void updated(String pid, Dictionary properties) throws ConfigurationException { System.out.println("retrieved update for pid " + pid); ServiceRegistration reg = services.get(pid); if (reg == null) { services.put(pid, ctx.registerService(ServiceInterface.class, new Service(), properties)); } else { // i should do some update here } } @Override public void deleted(String pid) { ServiceRegistration reg = services.get(pid); if (reg != null) { reg.unregister(); } } } 

Ahora, debería recibir configuraciones de ConfigurationAdmin para PID my.project.servicefactory , ¿no es así? Pero no recibe ninguna configuración de ConfigurationAdmin . Se inició el paquete, se registró el servicio y, en la consola web, puedo ver que el administrador de configuración tiene una referencia a mi ManagedServiceFactory. ¿Hay una cierta propiedad que se debe establecer? La especificación de la interfaz no sugiere eso. En realidad, mi implementación es más o menos la misma que la del ejemplo. No tengo idea de lo que estoy haciendo mal aquí, cualquier sugerencia para las soluciones es muy bienvenida.

Además, originalmente pensé en implementar el propio ManagedServiceFactory como DS, lo que también debería ser posible, pero fallé en el mismo punto: ConfigAdmin no entrega ninguna configuración.

actualizar Para aclarar la pregunta: creo que esto es principalmente un problema de configuración. Tal como lo veo, debería poder especificar dos PID para la fábrica, uno que identifique una configuración para la propia fábrica (si existe), y uno que produzca servicios a través de esta fábrica, que creo que debería ser la factory.pid . Pero las constantes del marco no tienen nada de esto.

actualización 2 Después de buscar un poco el código fuente de Felix Fileinstall, descubrí que trata los archivos de configuración de manera diferente cuando hay un - en el nombre del archivo o no. Teniendo el archivo de configuración llamado my.project.servicefactory.cfg no funcionó, pero las configuraciones llamadas my.project.servicefactory-foo.cfg y my.project.servicefactory-bar.cfg se entregaron correctamente a mi ManagedServiceFactory como se esperaba. y se registraron múltiples servicios con ServiceInterface . ¡Viva!

actualización 3 Según lo propuesto por Neil, puse la parte del servicio declarativo en una nueva pregunta para limitar el scope de ésta.

Creo que el problema es que tiene un registro de configuración de singleton en lugar de un registro de fábrica. createFactoryConfiguration llamar a Config Admin con el método my.project.servicefactory usando my.project.servicefactory como factoryPid .

Si está utilizando Apache Felix FileInstall (que es una forma fácil y fácil de crear registros de configuración sin escribir código), entonces necesita crear un archivo llamado my.project.servicefactory-1.cfg en el directorio de load . Puede crear configuraciones adicionales con el mismo factoryPID llamándolos my.project.servicefactory-2.cfg etc.