You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cz...@apache.org on 2018/01/24 14:11:33 UTC

svn commit: r1822105 - in /felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl: ./ persistence/

Author: cziegeler
Date: Wed Jan 24 14:11:33 2018
New Revision: 1822105

URL: http://svn.apache.org/viewvc?rev=1822105&view=rev
Log:
FELIX-5778 : Refactor factory configuration handling

Removed:
    felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/Factory.java
Modified:
    felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationImpl.java
    felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
    felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/persistence/CachingPersistenceManagerProxy.java
    felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/persistence/ExtPersistenceManager.java
    felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/persistence/PersistenceManagerProxy.java

Modified: felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationImpl.java?rev=1822105&r1=1822104&r2=1822105&view=diff
==============================================================================
--- felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationImpl.java (original)
+++ felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationImpl.java Wed Jan 24 14:11:33 2018
@@ -389,12 +389,6 @@ public class ConfigurationImpl extends C
             // finally assign the configuration for use
             configure( newProperties );
 
-            // if this is a factory configuration, update the factory with
-            // do this only after configuring with current properties such
-            // that a concurrently registered ManagedServiceFactory service
-            // does not receive a new/unusable configuration
-            updateFactory();
-
             // update the service and fire an CM_UPDATED event
             getConfigurationManager().updated( this, true );
         }
@@ -472,39 +466,6 @@ public class ConfigurationImpl extends C
     }
 
 
-    /**
-     * Makes sure the configuration is added to the {@link Factory} (and
-     * the factory be stored if updated) if this is a factory
-     * configuration.
-     *
-     * @throws IOException If an error occurrs storing the {@link Factory}
-     */
-    private void updateFactory() throws IOException {
-        String factoryPid = getFactoryPidString();
-        if ( factoryPid != null )
-        {
-            Factory factory = getConfigurationManager().getOrCreateFactory( factoryPid );
-            synchronized (factory) {
-                if ( factory.addPID( getPidString() ) )
-                {
-                    // only write back if the pid was not already registered
-                    // with the factory
-                    try
-                    {
-                        factory.store();
-                    }
-                    catch ( IOException ioe )
-                    {
-                        Log.logger.log( LogService.LOG_ERROR,
-                            "Failure storing factory {0} with new configuration {1}", new Object[]
-                                { factoryPid, getPidString(), ioe } );
-                    }
-                }
-            }
-        }
-    }
-
-
     @Override
     void store() throws IOException
     {

Modified: felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java?rev=1822105&r1=1822104&r2=1822105&view=diff
==============================================================================
--- felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java (original)
+++ felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java Wed Jan 24 14:11:33 2018
@@ -27,10 +27,10 @@ import java.util.Collection;
 import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.Hashtable;
-import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Random;
+import java.util.Set;
 
 import org.apache.felix.cm.PersistenceManager;
 import org.apache.felix.cm.impl.helper.BaseTracker;
@@ -116,9 +116,6 @@ public class ConfigurationManager implem
      */
     private final ExtPersistenceManager persistenceManager;
 
-    // the cache of Factory instances mapped by their factory PID
-    private final HashMap<String, Factory> factories = new HashMap<>();
-
     // the cache of Configuration instances mapped by their PID
     // have this always set to prevent NPE on bundle shutdown
     private final HashMap<String, ConfigurationImpl> configurations = new HashMap<>();
@@ -151,7 +148,7 @@ public class ConfigurationManager implem
     {
         // set up some fields
         this.bundleContext = bundleContext;
-        this.dynamicBindings = new DynamicBindings( bundleContext, persistenceManager );
+        this.dynamicBindings = new DynamicBindings( bundleContext, persistenceManager.getDelegatee() );
         this.persistenceManager = persistenceManager;
     }
 
@@ -253,12 +250,6 @@ public class ConfigurationManager implem
         {
             configurations.clear();
         }
-
-        // just ensure the factory cache is empty
-        synchronized ( factories )
-        {
-            factories.clear();
-        }
     }
 
 
@@ -322,33 +313,6 @@ public class ConfigurationManager implem
     }
 
 
-    Factory getCachedFactory( String factoryPid )
-    {
-        synchronized ( factories )
-        {
-            return factories.get( factoryPid );
-        }
-    }
-
-
-    Factory[] getCachedFactories()
-    {
-        synchronized ( factories )
-        {
-            return factories.values().toArray( new Factory[factories.size()] );
-        }
-    }
-
-
-    void cacheFactory( Factory factory )
-    {
-        synchronized ( factories )
-        {
-            factories.put( factory.getFactoryPidString(), factory );
-        }
-    }
-
-
     // ---------- ConfigurationAdminImpl support
 
     void setDynamicBundleLocation( final String pid, final String location )
@@ -477,7 +441,7 @@ public class ConfigurationManager implem
 
         if ( this.persistenceManager.exists( pid ) )
         {
-            final Dictionary props =this.persistenceManager.load( pid );
+            final Dictionary props = this.persistenceManager.load( pid );
             config = new ConfigurationImpl( this, this.persistenceManager, props );
             Log.logger.log( LogService.LOG_DEBUG, "Found existing configuration {0} bound to {1}", new Object[]
                     { pid, config.getBundleLocation() } );
@@ -830,117 +794,39 @@ public class ConfigurationManager implem
      * Configuration Admin 1.5 specification for targeted PIDs (Section
      * 104.3.2)
      *
-     * @param rawFactoryPid The raw factory PID without any targetting.
+     * @param rawFactoryPid The raw factory PID without any targettng.
      * @param target The <code>ServiceReference</code> of the service to
      *      be supplied with targeted configuration.
      * @return A list of {@link Factory} instances as listed above. This
      *      list will always at least include an instance for the
      *      <code>rawFactoryPid</code>. Other instances are only included
      *      if existing.
-     * @throws IOException If an error occurrs reading any of the
+     * @throws IOException If an error occurs reading any of the
      *      {@link Factory} instances from persistence
      */
-    List<Factory> getTargetedFactories( final String rawFactoryPid, final ServiceReference target ) throws IOException
+    List<String> getTargetedFactories( final String rawFactoryPid, final ServiceReference target ) throws IOException
     {
-        LinkedList<Factory> factories = new LinkedList<>();
+        List<String> factories = new LinkedList<>();
 
         final Bundle serviceBundle = target.getBundle();
         if ( serviceBundle != null )
         {
             final StringBuilder targetedPid = new StringBuilder( rawFactoryPid );
-            factories.add( getOrCreateFactory( targetedPid.toString() ) );
+            factories.add( targetedPid.toString() );
 
             targetedPid.append( '|' ).append( serviceBundle.getSymbolicName() );
-            Factory f = getFactory( targetedPid.toString() );
-            if ( f != null )
-            {
-                factories.add( 0, f );
-            }
+            factories.add( 0, targetedPid.toString() );
 
             targetedPid.append( '|' ).append( serviceBundle.getVersion().toString() );
-            f = getFactory( targetedPid.toString() );
-            if ( f != null )
-            {
-                factories.add( 0, f );
-            }
+            factories.add( 0, targetedPid.toString() );
 
             targetedPid.append( '|' ).append( serviceBundle.getLocation() );
-            f = getFactory( targetedPid.toString() );
-            if ( f != null )
-            {
-                factories.add( 0, f );
-            }
+            factories.add( 0, targetedPid.toString() );
         }
 
         return factories;
     }
 
-
-    /**
-     * Gets the factory with the exact identifier from the cached or from
-     * the persistence managers. If no factory exists already one is
-     * created and cached.
-     *
-     * @param factoryPid The PID of the {@link Factory} to return
-     * @return The existing or newly created {@link Factory}
-     * @throws IOException If an error occurs reading the factory from
-     *      a {@link PersistenceManager}
-     */
-    Factory getOrCreateFactory( String factoryPid ) throws IOException
-    {
-        Factory factory = getFactory( factoryPid );
-        if ( factory != null )
-        {
-            return factory;
-        }
-
-        return createFactory( factoryPid );
-    }
-
-
-    /**
-     * Gets the factory with the exact identifier from the cached or from
-     * the persistence managers. If no factory exists <code>null</code>
-     * is returned.
-     *
-     * @param factoryPid The PID of the {@link Factory} to return
-     * @return The existing {@link Factory} or <code>null</code>
-     * @throws IOException If an error occurs reading the factory from
-     *      a {@link PersistenceManager}
-     */
-    Factory getFactory( String factoryPid ) throws IOException
-    {
-        // check for cached factory
-        Factory factory = getCachedFactory( factoryPid );
-        if ( factory != null )
-        {
-            return factory;
-        }
-
-        // try to load factory from persistence
-        if ( Factory.exists( this.persistenceManager, factoryPid ) )
-        {
-            factory = Factory.load( this, this.persistenceManager, factoryPid );
-            cacheFactory( factory );
-            return factory;
-        }
-
-        // no existing factory
-        return null;
-    }
-
-
-    /**
-     * Creates a new factory with the given <code>factoryPid</code>.
-     */
-    Factory createFactory( String factoryPid )
-    {
-        Factory factory = new Factory( this, this.persistenceManager, factoryPid );
-        cacheFactory( factory );
-        return factory;
-    }
-
-
     /**
      * Calls the registered configuration plugins on the given configuration
      * properties from the given configuration object.
@@ -1248,72 +1134,46 @@ public class ConfigurationManager implem
             for ( String factoryPid : this.factoryPids )
             {
 
-                List<Factory> factories = null;
                 try
                 {
-                    factories = getTargetedFactories( factoryPid, sr );
-                    for ( Factory factory : factories )
+                    final List<String> targetedFactoryPids = getTargetedFactories( factoryPid, sr );
+                    final Set<String> pids = persistenceManager.getFactoryConfigurationPids(targetedFactoryPids);
+                    for ( final String pid : pids )
                     {
-                        synchronized (factory) {
-                            for ( Iterator<String> pi = factory.getPIDs().iterator(); pi.hasNext(); )
-                            {
-                                final String pid = pi.next();
-                                ConfigurationImpl cfg;
-                                try
-                                {
-                                    cfg = getConfiguration( pid );
-                                }
-                                catch ( IOException ioe )
-                                {
-                                    Log.logger.log( LogService.LOG_ERROR, "Error loading configuration for {0}", new Object[]
-                                            { pid, ioe } );
-                                    continue;
-                                }
-
-                                // sanity check on the configuration
-                                if ( cfg == null )
-                                {
-                                    Log.logger.log( LogService.LOG_ERROR,
-                                            "Configuration {0} referred to by factory {1} does not exist", new Object[]
-                                                    { pid, factoryPid } );
-                                    factory.removePID( pid );
-                                    factory.storeSilently();
-                                    continue;
-                                }
-                                else if ( cfg.isNew() )
-                                {
-                                    // Configuration has just been created but not yet updated
-                                    // we currently just ignore it and have the update mechanism
-                                    // provide the configuration to the ManagedServiceFactory
-                                    // As of FELIX-612 (not storing new factory configurations)
-                                    // this should not happen. We keep this for added stability
-                                    // but raise the logging level to error.
-                                    Log.logger.log( LogService.LOG_ERROR, "Ignoring new configuration pid={0}", new Object[]
-                                            { pid } );
-                                    continue;
-                                }
-
-                                /*
-                                 * this code would catch targeted factory PIDs;
-                                 * since this is not expected any way, we can
-                                 * leave this out
-                                 */
-                                /*
-                                else if ( !factoryPid.equals( cfg.getFactoryPid() ) )
-                                {
-                                    log( LogService.LOG_ERROR,
-                                        "Configuration {0} referred to by factory {1} seems to belong to factory {2}",
-                                        new Object[]
-                                            { pid, factoryPid, cfg.getFactoryPid() } );
-                                    factory.removePID( pid );
-                                    factory.storeSilently();
-                                    continue;
-                                }
-                                 */
+                        ConfigurationImpl cfg;
+                        try
+                        {
+                            cfg = getConfiguration( pid );
+                        }
+                        catch ( IOException ioe )
+                        {
+                            Log.logger.log( LogService.LOG_ERROR, "Error loading configuration for {0}", new Object[]
+                                    { pid, ioe } );
+                            continue;
+                        }
 
-                                provide( factoryPid, cfg );
-                            }
+                        // sanity check on the configuration
+                        if ( cfg == null )
+                        {
+                            Log.logger.log( LogService.LOG_ERROR,
+                                    "Configuration {0} referred to by factory {1} does not exist", new Object[]
+                                            { pid, factoryPid } );
+                            continue;
                         }
+                        else if ( cfg.isNew() )
+                        {
+                            // Configuration has just been created but not yet updated
+                            // we currently just ignore it and have the update mechanism
+                            // provide the configuration to the ManagedServiceFactory
+                            // As of FELIX-612 (not storing new factory configurations)
+                            // this should not happen. We keep this for added stability
+                            // but raise the logging level to error.
+                            Log.logger.log( LogService.LOG_ERROR, "Ignoring new configuration pid={0}", new Object[]
+                                    { pid } );
+                            continue;
+                        }
+
+                        provide( factoryPid, cfg );
                     }
                 }
                 catch ( IOException ioe )
@@ -1610,26 +1470,6 @@ public class ConfigurationManager implem
                     }
                 }
             }
-
-            final TargetedPID factoryPid = config.getFactoryPid();
-            if ( factoryPid != null )
-            {
-                // remove the pid from the factory
-                final String pid = config.getPidString();
-                try
-                {
-                    Factory factory = getOrCreateFactory( factoryPid.toString() );
-                    synchronized (factory) {
-                        factory.removePID( pid );
-                        factory.store();
-                    }
-                }
-                catch ( IOException ioe )
-                {
-                    Log.logger.log( LogService.LOG_ERROR, "Failed removing {0} from the factory {1}", new Object[]
-                            { pid, factoryPid, ioe } );
-                }
-            }
         }
 
         @Override

Modified: felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/persistence/CachingPersistenceManagerProxy.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/persistence/CachingPersistenceManagerProxy.java?rev=1822105&r1=1822104&r2=1822105&view=diff
==============================================================================
--- felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/persistence/CachingPersistenceManagerProxy.java (original)
+++ felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/persistence/CachingPersistenceManagerProxy.java Wed Jan 24 14:11:33 2018
@@ -25,17 +25,20 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Dictionary;
 import java.util.Enumeration;
-import java.util.Hashtable;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import org.apache.felix.cm.PersistenceManager;
 import org.apache.felix.cm.impl.CaseInsensitiveDictionary;
-import org.apache.felix.cm.impl.Factory;
 import org.apache.felix.cm.impl.SimpleFilter;
 import org.osgi.framework.Constants;
+import org.osgi.service.cm.ConfigurationAdmin;
 
 
 /**
@@ -46,13 +49,14 @@ import org.osgi.framework.Constants;
  */
 public class CachingPersistenceManagerProxy implements ExtPersistenceManager
 {
-    /** the actual PersistenceManager */
+
+    /** The actual PersistenceManager */
     private final PersistenceManager pm;
 
-    /** cached dictionaries */
-    private final Hashtable<String, CaseInsensitiveDictionary> cache;
+    /** Cached dictionaries */
+    private final Map<String, CaseInsensitiveDictionary> cache = new HashMap<>();
 
-    /** protecting lock */
+    /** Protecting lock */
     private final ReadWriteLock globalLock = new ReentrantReadWriteLock();
 
     /**
@@ -62,6 +66,8 @@ public class CachingPersistenceManagerPr
      */
     private volatile boolean fullyLoaded;
 
+    /** Factory configuration cache. */
+    private final Map<String, Set<String>> factoryConfigCache = new HashMap<>();
 
     /**
      * Creates a new caching layer for the given actual {@link PersistenceManager}.
@@ -70,7 +76,6 @@ public class CachingPersistenceManagerPr
     public CachingPersistenceManagerProxy( final PersistenceManager pm )
     {
         this.pm = pm;
-        this.cache = new Hashtable<>();
     }
 
     @Override
@@ -91,7 +96,23 @@ public class CachingPersistenceManagerPr
         try
         {
             lock.lock();
-            cache.remove( pid );
+            final Dictionary props = cache.remove( pid );
+            if ( props != null )
+            {
+                final String factoryPid = (String)props.get(ConfigurationAdmin.SERVICE_FACTORYPID);
+                if ( factoryPid != null )
+                {
+                    final Set<String> factoryPids = this.factoryConfigCache.get(factoryPid);
+                    if ( factoryPids != null )
+                    {
+                        factoryPids.remove(pid);
+                        if ( factoryPids.isEmpty() )
+                        {
+                            this.factoryConfigCache.remove(factoryPid);
+                        }
+                    }
+                }
+            }
             pm.delete(pid);
         }
         finally
@@ -138,6 +159,33 @@ public class CachingPersistenceManagerPr
         return Collections.enumeration(getDictionaries( null ));
     }
 
+    private final CaseInsensitiveDictionary cache(final Dictionary props)
+    {
+        final String pid = (String) props.get( Constants.SERVICE_PID );
+        CaseInsensitiveDictionary dict = null;
+        if ( pid != null )
+        {
+            dict = cache.get(pid);
+            if ( dict == null )
+            {
+                dict = new CaseInsensitiveDictionary(props);
+                cache.put( pid, dict );
+                final String factoryPid = (String)props.get(ConfigurationAdmin.SERVICE_FACTORYPID);
+                if ( factoryPid != null )
+                {
+                    Set<String> factoryPids = this.factoryConfigCache.get(factoryPid);
+                    if ( factoryPids == null )
+                    {
+                        factoryPids = new HashSet<>();
+                        this.factoryConfigCache.put(factoryPid, factoryPids);
+                    }
+                    factoryPids.add(pid);
+                }
+            }
+        }
+        return dict;
+    }
+
     @Override
     public Collection<Dictionary> getDictionaries( final SimpleFilter filter ) throws IOException
     {
@@ -146,7 +194,7 @@ public class CachingPersistenceManagerPr
         {
             lock.lock();
             // if not fully loaded, call back to the underlying persistence
-            // manager and cach all dictionaries whose service.pid is set
+            // manager and cache all dictionaries whose service.pid is set
             if ( !fullyLoaded )
             {
                 lock.unlock();
@@ -158,20 +206,7 @@ public class CachingPersistenceManagerPr
                     while ( fromPm.hasMoreElements() )
                     {
                         Dictionary next = (Dictionary) fromPm.nextElement();
-                        String pid = (String) next.get( Constants.SERVICE_PID );
-                        if ( pid != null )
-                        {
-                            cache.put( pid, new CaseInsensitiveDictionary( next ) );
-                        }
-                        else
-                        {
-                            pid = (String) next.get( Factory.FACTORY_PID );
-                            if ( pid != null )
-                            {
-                                pid = Factory.factoryPidToIdentifier( pid );
-                                cache.put( pid, new CaseInsensitiveDictionary( next ) );
-                            }
-                        }
+                        this.cache(next);
                     }
                     this.fullyLoaded = true;
                 }
@@ -224,12 +259,11 @@ public class CachingPersistenceManagerPr
                     final Dictionary props = pm.load( pid );
                     if ( props != null )
                     {
-                        loaded = new CaseInsensitiveDictionary( props );
-                        cache.put( pid, loaded );
+                        loaded = this.cache(props);
                     }
                 }
             }
-            return new CaseInsensitiveDictionary(loaded);
+            return loaded == null ? null : new CaseInsensitiveDictionary(loaded);
         }
         finally
         {
@@ -250,16 +284,61 @@ public class CachingPersistenceManagerPr
     @Override
     public void store( final String pid, final Dictionary properties ) throws IOException
     {
-        Lock lock = globalLock.writeLock();
+        final Lock lock = globalLock.writeLock();
         try
         {
             lock.lock();
             pm.store( pid, properties );
-            cache.put( pid,  new CaseInsensitiveDictionary( properties ) );
+            this.cache.remove(pid);
+            this.cache(properties);
+        }
+        finally
+        {
+            lock.unlock();
+        }
+    }
+
+    @Override
+    public Set<String> getFactoryConfigurationPids(final List<String> targetedFactoryPids )
+    throws IOException
+    {
+        final Set<String> pids = new HashSet<>();
+        Lock lock = globalLock.readLock();
+        try
+        {
+            lock.lock();
+            if ( !this.fullyLoaded )
+            {
+                lock.unlock();
+                lock = globalLock.writeLock();
+                lock.lock();
+                if ( !this.fullyLoaded )
+                {
+                    final Enumeration fromPm = pm.getDictionaries();
+                    while ( fromPm.hasMoreElements() )
+                    {
+                        Dictionary next = (Dictionary) fromPm.nextElement();
+                        this.cache(next);
+                    }
+                    this.fullyLoaded = true;
+                }
+                lock.unlock();
+                lock = globalLock.readLock();
+                lock.lock();
+            }
+            for(final String targetFactoryPid : targetedFactoryPids)
+            {
+                final Set<String> cachedPids = this.factoryConfigCache.get(targetFactoryPid);
+                if ( cachedPids != null )
+                {
+                    pids.addAll(cachedPids);
+                }
+            }
         }
         finally
         {
             lock.unlock();
         }
+        return pids;
     }
 }

Modified: felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/persistence/ExtPersistenceManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/persistence/ExtPersistenceManager.java?rev=1822105&r1=1822104&r2=1822105&view=diff
==============================================================================
--- felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/persistence/ExtPersistenceManager.java (original)
+++ felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/persistence/ExtPersistenceManager.java Wed Jan 24 14:11:33 2018
@@ -21,6 +21,8 @@ package org.apache.felix.cm.impl.persist
 import java.io.IOException;
 import java.util.Collection;
 import java.util.Dictionary;
+import java.util.List;
+import java.util.Set;
 
 import org.apache.felix.cm.PersistenceManager;
 import org.apache.felix.cm.impl.SimpleFilter;
@@ -32,5 +34,8 @@ public interface ExtPersistenceManager e
 {
     Collection<Dictionary> getDictionaries( SimpleFilter filter ) throws IOException;
 
+    Set<String> getFactoryConfigurationPids( List<String> targetedFactoryPids )
+    throws IOException;
+
     PersistenceManager getDelegatee();
 }

Modified: felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/persistence/PersistenceManagerProxy.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/persistence/PersistenceManagerProxy.java?rev=1822105&r1=1822104&r2=1822105&view=diff
==============================================================================
--- felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/persistence/PersistenceManagerProxy.java (original)
+++ felix/trunk/osgi-r7/configadmin/src/main/java/org/apache/felix/cm/impl/persistence/PersistenceManagerProxy.java Wed Jan 24 14:11:33 2018
@@ -35,6 +35,7 @@ import org.apache.felix.cm.PersistenceMa
 import org.apache.felix.cm.impl.CaseInsensitiveDictionary;
 import org.apache.felix.cm.impl.SimpleFilter;
 import org.osgi.framework.Constants;
+import org.osgi.service.cm.ConfigurationAdmin;
 
 /**
  * The <code>PersistenceManagerProxy</code> proxies a persistence
@@ -69,7 +70,7 @@ public class PersistenceManagerProxy imp
      * manager.
      */
     @Override
-    public void delete( String pid ) throws IOException
+    public void delete( final String pid ) throws IOException
     {
         Lock lock = globalLock.writeLock();
         try
@@ -127,8 +128,8 @@ public class PersistenceManagerProxy imp
         Lock lock = globalLock.readLock();
         try
         {
-            final Set<String> pids = new HashSet<String>();
-            final List<Dictionary> result = new ArrayList<Dictionary>();
+            final Set<String> pids = new HashSet<>();
+            final List<Dictionary> result = new ArrayList<>();
 
             lock.lock();
             Enumeration fromPm = pm.getDictionaries();
@@ -206,4 +207,41 @@ public class PersistenceManagerProxy imp
             lock.unlock();
         }
     }
+
+    @Override
+    public Set<String> getFactoryConfigurationPids(List<String> targetedFactoryPids) throws IOException {
+        final Set<String> pids = new HashSet<>();
+        Lock lock = globalLock.readLock();
+        try
+        {
+            lock.lock();
+            final Enumeration fromPm = pm.getDictionaries();
+            while ( fromPm.hasMoreElements() )
+            {
+                final Dictionary next = (Dictionary) fromPm.nextElement();
+                final String pid = (String)next.get(Constants.SERVICE_PID);
+                if ( pid != null )
+                {
+                    final String factoryPid = (String)next.get(ConfigurationAdmin.SERVICE_FACTORYPID);
+                    if ( factoryPid != null )
+                    {
+                        for(final String targetFactoryPid : targetedFactoryPids)
+                        {
+                            if ( targetedFactoryPids.equals(factoryPid) )
+                            {
+                                pids.add(pid);
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        finally
+        {
+            lock.unlock();
+        }
+        return pids;
+    }
+
 }