title: How do you properly implement a ManagedServiceFactory as Decalarative Service in OSGi?
body: <p>I have services that need to be created on a per-configuration base, each of which relies on an external resource and thus should manage it's own lifcycle (i.e. (de)register the service). Thus implementing these as DS and let SCR spawn multiple instances does not work.</p>
  
  <p>One can implement a bundle that registers a ManagedServiceFactory to accomplish this task perfectly (see <a href="https://stackoverflow.com/questions/11832204/how-do-you-implement-a-managedservicefactory-in-osgi">my previous post</a>). But as a consequence, if the factory depends on several other services, you need to start tracking those services and write a lot of glue code to get everything running. Instead I'd like to implement the factory as (singleton) declarative service, for which the SCR registers a <code>ManagedServiceFactory</code> at the Service Registry.</p>
  
  <p>Here's my attempt:</p>
  
  <pre><code>import org.osgi.framework.BundleContext;
  import org.osgi.framework.ServiceRegistration;
  import org.osgi.service.cm.ConfigurationException;
  import org.osgi.service.cm.ManagedServiceFactory;
  import org.osgi.service.component.ComponentContext;
  
  @SuppressWarnings({ "rawtypes", "unchecked" })
  public class Factory implements ManagedServiceFactory {
  
  private BundleContext bundleCtxt;
  private Map&lt;String, ServiceRegistration&gt; services;
  
  public void activate(ComponentContext context) throws Exception {
      System.out.println("actiavting...");
      this.bundleCtxt = context.getBundleContext();
      services = new HashMap&lt;String, ServiceRegistration&gt;();
  }
  
  public void deactivate(ComponentContext context) {
      for(ServiceRegistration reg : services.values()) {
          System.out.println("deregister " + reg);
          reg.unregister();
      }
      services.clear();
  }
  
  @Override
  public String getName() {
      System.out.println("returning factory name");
      return "my.project.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, bundleCtxt.registerService(ServiceInterface.class,
                  new Service(), properties));
      } else {
          // i should to some update here
      }
  }
  
  @Override
  public void deleted(String pid) {
      ServiceRegistration reg = services.get(pid);
      if (reg != null) {
          reg.unregister();
          services.remove(pid);
      }
  }
  }
  </code></pre>
  
  <p>and the service description:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" configuration-policy="ignore" name="my.project.servicefactory"&gt;
     &lt;implementation class="my.project.factory.Factory"/&gt;
     &lt;service&gt;
        &lt;provide interface="org.osgi.service.cm.ManagedServiceFactory"/&gt;
     &lt;/service&gt;
     &lt;property name="service.pid" type="String" value="my.project.servicefactory"/&gt;
  &lt;/scr:component&gt;
  </code></pre>
  
  <p>I already found out that the "factory" property in the service description is the wrong path, because this way the component is never registerd as <code>ManagedServiceFactory</code> in the Service Registry, instead it becomes a <code>ComponentFactory</code>.</p>
  
  <p>As a kind of hack, I just added a component property, namely</p>
  
  <pre><code>&lt;property name="service.pid" type="String" value="my.project.servicefactory"/&gt;
  </code></pre>
  
  <p>and added <code>configuration-policy="ignore"</code>. This works: configurations named <code>my.project.servicefactory-foobar.cfg</code> are handed to my service, which registers them as in the Service Registry, everything fine.</p>
  
  <p>But theres two things about it i do not like:</p>
  
  <ol>
  <li>manually setting the property <code>service.pid</code> feels like a dirty hack to me</li>
  <li>setting <code>configuration-policy="ignore"</code> prevents me from configuring the <code>ManagedServiceFactory</code> itsself. If I escape this property or set it to require, I would get one <code>ManagedServiceFactory</code> for a configuration named <code>my.project.servicefactory.cfg</code> and then two services for each configuration named with the pattern <code>my.project.servicefactory-foobar.cfg</code>: one <code>ManagedServiceFactory</code> that the SCR spawns and one <code>ServiceInterface</code> that my first <code>ManagedServiceFactory</code> registers when it gets notified about this new configuration. (At least this is not growing exponetially because SCR overwrites the <code>service.pid</code> property for factory configurations)</li>
  </ol>
  
  <p>So how should I set this up properly?</p>
  
  <p>PS: For those wondering about my reference to configurations on their filenames: I use Felix Fileinstall for the configurations, thus <code>foo.cfg</code> is put to the ConfigAdmin for PID <code>foo</code>, and <code>foo-bar.cfg</code> is put there for <em>factory</em>-pid <code>foo</code>.</p>