Merge "Resolve Bug:853 - remove groovy from config code generator."
[controller.git] / opendaylight / config / config-manager / src / main / java / org / opendaylight / controller / config / manager / impl / ConfigTransactionControllerImpl.java
index 3e53a7a217e1855dedb596a2b5f1dedcd707ca85..3e231201821619d36c95b0cc481938b5eda042f4 100644 (file)
@@ -7,59 +7,58 @@
  */
 package org.opendaylight.controller.config.manager.impl;
 
+import static java.lang.String.format;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.GuardedBy;
+import javax.management.DynamicMBean;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
 import org.opendaylight.controller.config.api.DependencyResolver;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.config.api.ValidationException;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.manager.impl.dependencyresolver.DependencyResolverManager;
+import org.opendaylight.controller.config.manager.impl.dependencyresolver.ModuleInternalTransactionalInfo;
 import org.opendaylight.controller.config.manager.impl.dynamicmbean.DynamicWritableWrapper;
 import org.opendaylight.controller.config.manager.impl.dynamicmbean.ReadOnlyAtomicBoolean;
 import org.opendaylight.controller.config.manager.impl.dynamicmbean.ReadOnlyAtomicBoolean.ReadOnlyAtomicBooleanImpl;
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HierarchicalConfigMBeanFactoriesHolder;
-import org.opendaylight.controller.config.manager.impl.jmx.TransactionJMXRegistrator;
 import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator;
 import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator.TransactionModuleJMXRegistration;
-import org.opendaylight.controller.config.manager.impl.util.LookupBeansUtil;
 import org.opendaylight.controller.config.spi.Module;
 import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
 import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.GuardedBy;
-import javax.management.DynamicMBean;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import static java.lang.String.format;
-
+import static com.google.common.base.Preconditions.checkNotNull;
 /**
  * This is a JMX bean representing current transaction. It contains
- * {@link #transactionIdentifier}, unique version and parent version for
+ * transaction identifier, unique version and parent version for
  * optimistic locking.
  */
 class ConfigTransactionControllerImpl implements
         ConfigTransactionControllerInternal,
         ConfigTransactionControllerImplMXBean,
-        Identifiable<TransactionIdentifier>{
+        Identifiable<TransactionIdentifier> {
     private static final Logger logger = LoggerFactory.getLogger(ConfigTransactionControllerImpl.class);
 
-    private final TransactionIdentifier transactionIdentifier;
+    private final ConfigTransactionLookupRegistry txLookupRegistry;
     private final ObjectName controllerON;
-    private final TransactionJMXRegistrator transactionRegistrator;
-    private final TransactionModuleJMXRegistrator txModuleJMXRegistrator;
+
     private final long parentVersion, currentVersion;
     private final HierarchicalConfigMBeanFactoriesHolder factoriesHolder;
     private final DependencyResolverManager dependencyResolverManager;
@@ -80,28 +79,28 @@ class ConfigTransactionControllerImpl implements
 
     private final boolean blankTransaction;
 
-    public ConfigTransactionControllerImpl(String transactionName,
-                                           TransactionJMXRegistrator transactionRegistrator,
-                                           long parentVersion, long currentVersion,
-                                           Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories,
+    @GuardedBy("this")
+    private final SearchableServiceReferenceWritableRegistry writableSRRegistry;
+
+    public ConfigTransactionControllerImpl(ConfigTransactionLookupRegistry txLookupRegistry,
+                                           long parentVersion, CodecRegistry codecRegistry, long currentVersion,
+                                           Map<String, Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories,
                                            MBeanServer transactionsMBeanServer, MBeanServer configMBeanServer,
-                                           boolean blankTransaction) {
-
-        this.transactionIdentifier = new TransactionIdentifier(transactionName);
-        this.controllerON = ObjectNameUtil
-                .createTransactionControllerON(transactionName);
-        this.transactionRegistrator = transactionRegistrator;
-        txModuleJMXRegistrator = transactionRegistrator
-                .createTransactionModuleJMXRegistrator();
+                                           boolean blankTransaction, SearchableServiceReferenceWritableRegistry  writableSRRegistry) {
+        this.txLookupRegistry = txLookupRegistry;
+        String transactionName = txLookupRegistry.getTransactionIdentifier().getName();
+        this.controllerON = ObjectNameUtil.createTransactionControllerON(transactionName);
         this.parentVersion = parentVersion;
         this.currentVersion = currentVersion;
         this.currentlyRegisteredFactories = currentlyRegisteredFactories;
         this.factoriesHolder = new HierarchicalConfigMBeanFactoriesHolder(currentlyRegisteredFactories);
         this.transactionStatus = new TransactionStatus();
-        this.dependencyResolverManager = new DependencyResolverManager(transactionName, transactionStatus);
+        this.dependencyResolverManager = new DependencyResolverManager(txLookupRegistry.getTransactionIdentifier(),
+                transactionStatus, writableSRRegistry, codecRegistry);
         this.transactionsMBeanServer = transactionsMBeanServer;
         this.configMBeanServer = configMBeanServer;
         this.blankTransaction = blankTransaction;
+        this.writableSRRegistry = writableSRRegistry;
     }
 
     @Override
@@ -126,26 +125,28 @@ class ConfigTransactionControllerImpl implements
 
         List<ModuleFactory> toBeAdded = new ArrayList<>();
         List<ModuleFactory> toBeRemoved = new ArrayList<>();
-        for(ModuleFactory moduleFactory: factoriesHolder.getModuleFactories()) {
-            if (oldSet.contains(moduleFactory) == false){
+        for (ModuleFactory moduleFactory : factoriesHolder.getModuleFactories()) {
+            if (oldSet.contains(moduleFactory) == false) {
                 toBeAdded.add(moduleFactory);
             }
         }
-        for(ModuleFactory moduleFactory: lastListOfFactories){
+        for (ModuleFactory moduleFactory : lastListOfFactories) {
             if (newSet.contains(moduleFactory) == false) {
                 toBeRemoved.add(moduleFactory);
             }
         }
         // add default modules
         for (ModuleFactory moduleFactory : toBeAdded) {
+            BundleContext bundleContext = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
             Set<? extends Module> defaultModules = moduleFactory.getDefaultModules(dependencyResolverManager,
-                    getModuleFactoryBundleContext(moduleFactory.getImplementationName()));
+                    bundleContext);
             for (Module module : defaultModules) {
                 // ensure default module to be registered to jmx even if its module factory does not use dependencyResolverFactory
                 DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(module.getIdentifier());
                 try {
                     boolean defaultBean = true;
-                    putConfigBeanToJMXAndInternalMaps(module.getIdentifier(), module, moduleFactory, null, dependencyResolver, defaultBean);
+                    putConfigBeanToJMXAndInternalMaps(module.getIdentifier(), module, moduleFactory, null,
+                            dependencyResolver, defaultBean, bundleContext);
                 } catch (InstanceAlreadyExistsException e) {
                     throw new IllegalStateException(e);
                 }
@@ -153,7 +154,7 @@ class ConfigTransactionControllerImpl implements
         }
 
         // remove modules belonging to removed factories
-        for(ModuleFactory removedFactory: toBeRemoved){
+        for (ModuleFactory removedFactory : toBeRemoved) {
             List<ModuleIdentifier> modulesOfRemovedFactory = dependencyResolverManager.findAllByFactory(removedFactory);
             for (ModuleIdentifier name : modulesOfRemovedFactory) {
                 destroyModule(name);
@@ -162,22 +163,26 @@ class ConfigTransactionControllerImpl implements
     }
 
 
-    private synchronized void copyExistingModule(
-            ModuleInternalInfo oldConfigBeanInfo)
-            throws InstanceAlreadyExistsException {
+    private synchronized void copyExistingModule(ModuleInternalInfo oldConfigBeanInfo) throws InstanceAlreadyExistsException {
+
         transactionStatus.checkNotCommitStarted();
         transactionStatus.checkNotAborted();
-        ModuleIdentifier moduleIdentifier = oldConfigBeanInfo.getName();
+        ModuleIdentifier moduleIdentifier = oldConfigBeanInfo.getIdentifier();
         dependencyResolverManager.assertNotExists(moduleIdentifier);
 
-        ModuleFactory moduleFactory = factoriesHolder
-                .findByModuleName(moduleIdentifier.getFactoryName());
+        ModuleFactory moduleFactory;
+        BundleContext bc;
+        try {
+            moduleFactory = factoriesHolder.findByModuleName(moduleIdentifier.getFactoryName());
+            bc = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
+        } catch (InstanceNotFoundException e) {
+            throw new IllegalStateException(e);
+        }
 
         Module module;
-        DependencyResolver dependencyResolver = dependencyResolverManager
-                .getOrCreate(moduleIdentifier);
+        DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(moduleIdentifier);
         try {
-            BundleContext bc = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
+
             module = moduleFactory.createModule(
                     moduleIdentifier.getInstanceName(), dependencyResolver,
                     oldConfigBeanInfo.getReadableModule(), bc);
@@ -187,12 +192,12 @@ class ConfigTransactionControllerImpl implements
                     oldConfigBeanInfo, moduleFactory), e);
         }
         putConfigBeanToJMXAndInternalMaps(moduleIdentifier, module, moduleFactory, oldConfigBeanInfo, dependencyResolver,
-                oldConfigBeanInfo.isDefaultBean());
+                oldConfigBeanInfo.isDefaultBean(), bc);
     }
 
     @Override
     public synchronized ObjectName createModule(String factoryName,
-            String instanceName) throws InstanceAlreadyExistsException {
+                                                String instanceName) throws InstanceAlreadyExistsException {
 
         transactionStatus.checkNotCommitStarted();
         transactionStatus.checkNotAborted();
@@ -200,74 +205,93 @@ class ConfigTransactionControllerImpl implements
         dependencyResolverManager.assertNotExists(moduleIdentifier);
 
         // find factory
-        ModuleFactory moduleFactory = factoriesHolder.findByModuleName(factoryName);
+        ModuleFactory moduleFactory;
+        try {
+            moduleFactory = factoriesHolder.findByModuleName(factoryName);
+        } catch (InstanceNotFoundException e) {
+            throw new IllegalArgumentException(e);
+        }
         DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(moduleIdentifier);
+        BundleContext bundleContext = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
         Module module = moduleFactory.createModule(instanceName, dependencyResolver,
-                getModuleFactoryBundleContext(moduleFactory.getImplementationName()));
+                bundleContext);
         boolean defaultBean = false;
         return putConfigBeanToJMXAndInternalMaps(moduleIdentifier, module,
-                moduleFactory, null, dependencyResolver, defaultBean);
+                moduleFactory, null, dependencyResolver, defaultBean, bundleContext);
     }
 
     private synchronized ObjectName putConfigBeanToJMXAndInternalMaps(
             ModuleIdentifier moduleIdentifier, Module module,
             ModuleFactory moduleFactory,
-            @Nullable ModuleInternalInfo maybeOldConfigBeanInfo, DependencyResolver dependencyResolver, boolean isDefaultBean)
+            @Nullable ModuleInternalInfo maybeOldConfigBeanInfo, DependencyResolver dependencyResolver,
+            boolean isDefaultBean, BundleContext bundleContext)
             throws InstanceAlreadyExistsException {
 
         logger.debug("Adding module {} to transaction {}", moduleIdentifier, this);
-        if (moduleIdentifier.equals(module.getIdentifier())==false) {
+        if (moduleIdentifier.equals(module.getIdentifier()) == false) {
             throw new IllegalStateException("Incorrect name reported by module. Expected "
-             + moduleIdentifier + ", got " + module.getIdentifier());
+                    + moduleIdentifier + ", got " + module.getIdentifier());
         }
-        if (dependencyResolver.getIdentifier().equals(moduleIdentifier) == false ) {
+        if (dependencyResolver.getIdentifier().equals(moduleIdentifier) == false) {
             throw new IllegalStateException("Incorrect name reported by dependency resolver. Expected "
                     + moduleIdentifier + ", got " + dependencyResolver.getIdentifier());
         }
         DynamicMBean writableDynamicWrapper = new DynamicWritableWrapper(
-                module, moduleIdentifier, transactionIdentifier,
+                module, moduleIdentifier, getTransactionIdentifier(),
                 readOnlyAtomicBoolean, transactionsMBeanServer,
                 configMBeanServer);
 
         ObjectName writableON = ObjectNameUtil.createTransactionModuleON(
-                transactionIdentifier.getName(), moduleIdentifier);
+                getTransactionIdentifier().getName(), moduleIdentifier);
         // put wrapper to jmx
-        TransactionModuleJMXRegistration transactionModuleJMXRegistration = txModuleJMXRegistrator
+        TransactionModuleJMXRegistration transactionModuleJMXRegistration = getTxModuleJMXRegistrator()
                 .registerMBean(writableDynamicWrapper, writableON);
-        ModuleInternalTransactionalInfo moduleInternalTransactionalInfo = new ModuleInternalTransactionalInfo(
-                moduleIdentifier, module, moduleFactory,
-                maybeOldConfigBeanInfo, transactionModuleJMXRegistration, isDefaultBean);
 
-        dependencyResolverManager.put(moduleInternalTransactionalInfo);
+        dependencyResolverManager.put(
+                moduleIdentifier, module, moduleFactory,
+                maybeOldConfigBeanInfo, transactionModuleJMXRegistration, isDefaultBean, bundleContext);
         return writableON;
     }
 
     @Override
-    public synchronized void destroyModule(ObjectName objectName)
-            throws InstanceNotFoundException {
+    public synchronized void destroyModule(ObjectName objectName) throws InstanceNotFoundException {
+        checkTransactionName(objectName);
+        ObjectNameUtil.checkDomain(objectName);
+        ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(objectName,
+                ObjectNameUtil.TYPE_MODULE);
+        destroyModule(moduleIdentifier);
+    }
+
+    private void checkTransactionName(ObjectName objectName) {
         String foundTransactionName = ObjectNameUtil
                 .getTransactionName(objectName);
-        if (transactionIdentifier.getName().equals(foundTransactionName) == false) {
+        if (getTransactionIdentifier().getName().equals(foundTransactionName) == false) {
             throw new IllegalArgumentException("Wrong transaction name "
                     + objectName);
         }
-        ObjectNameUtil.checkDomain(objectName);
-        ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(objectName,
-                ObjectNameUtil.TYPE_MODULE);
-        destroyModule(moduleIdentifier);
     }
 
     private synchronized void destroyModule(ModuleIdentifier moduleIdentifier) {
         logger.debug("Destroying module {} in transaction {}", moduleIdentifier, this);
         transactionStatus.checkNotAborted();
 
+        ModuleInternalTransactionalInfo found = dependencyResolverManager.findModuleInternalTransactionalInfo(moduleIdentifier);
         if (blankTransaction == false) {
-            ModuleInternalTransactionalInfo found =
-                    dependencyResolverManager.findModuleInternalTransactionalInfo(moduleIdentifier);
+
             if (found.isDefaultBean()) {
                 logger.warn("Warning: removing default bean. This will be forbidden in next version of config-subsystem");
             }
         }
+        // first remove refNames, it checks for objectname existence
+
+        try {
+            writableSRRegistry.removeServiceReferences(
+                    ObjectNameUtil.createTransactionModuleON(getTransactionName(), moduleIdentifier));
+        } catch (InstanceNotFoundException e) {
+            logger.error("Possible code error: cannot find {} in {}", moduleIdentifier, writableSRRegistry);
+            throw new IllegalStateException("Possible code error: cannot find " + moduleIdentifier, e);
+        }
+
         ModuleInternalTransactionalInfo removedTInfo = dependencyResolverManager.destroyModule(moduleIdentifier);
         // remove from jmx
         removedTInfo.getTransactionModuleJMXRegistration().close();
@@ -285,8 +309,9 @@ class ConfigTransactionControllerImpl implements
 
     @Override
     public synchronized void validateConfig() throws ValidationException {
-        if (configBeanModificationDisabled.get())
+        if (configBeanModificationDisabled.get()) {
             throw new IllegalStateException("Cannot start validation");
+        }
         configBeanModificationDisabled.set(true);
         try {
             validate_noLocks();
@@ -297,7 +322,7 @@ class ConfigTransactionControllerImpl implements
 
     private void validate_noLocks() throws ValidationException {
         transactionStatus.checkNotAborted();
-        logger.info("Validating transaction {}", transactionIdentifier);
+        logger.trace("Validating transaction {}", getTransactionIdentifier());
         // call validate()
         List<ValidationException> collectedExceptions = new ArrayList<>();
         for (Entry<ModuleIdentifier, Module> entry : dependencyResolverManager
@@ -317,7 +342,7 @@ class ConfigTransactionControllerImpl implements
             throw ValidationException
                     .createFromCollectedValidationExceptions(collectedExceptions);
         }
-        logger.info("Validated transaction {}", transactionIdentifier);
+        logger.trace("Validated transaction {}", getTransactionIdentifier());
     }
 
     /**
@@ -336,7 +361,7 @@ class ConfigTransactionControllerImpl implements
         try {
             validate_noLocks();
         } catch (ValidationException e) {
-            logger.info("Commit failed on validation");
+            logger.trace("Commit failed on validation");
             configBeanModificationDisabled.set(false); // recoverable error
             throw e;
         }
@@ -359,7 +384,7 @@ class ConfigTransactionControllerImpl implements
                             + "to obtain a lock");
         }
 
-        logger.info("Committing transaction {}", transactionIdentifier);
+        logger.trace("Committing transaction {}", getTransactionIdentifier());
 
         // call getInstance()
         for (Entry<ModuleIdentifier, Module> entry : dependencyResolverManager
@@ -368,24 +393,23 @@ class ConfigTransactionControllerImpl implements
             ModuleIdentifier name = entry.getKey();
             try {
                 logger.debug("About to commit {} in transaction {}",
-                        name, transactionIdentifier);
-                module.getInstance();
+                        name, getTransactionIdentifier());
+                AutoCloseable instance = module.getInstance();
+                checkNotNull(instance, "Instance is null:{} in transaction {}", name, getTransactionIdentifier());
             } catch (Exception e) {
                 logger.error("Commit failed on {} in transaction {}", name,
-                        transactionIdentifier, e);
+                        getTransactionIdentifier(), e);
                 internalAbort();
-                throw new RuntimeException(
+                throw new IllegalStateException(
                         format("Error - getInstance() failed for %s in transaction %s",
-                                name, transactionIdentifier), e);
+                                name, getTransactionIdentifier()), e);
             }
         }
 
         // count dependency order
 
-        logger.info("Committed configuration {}", transactionIdentifier);
+        logger.trace("Committed configuration {}", getTransactionIdentifier());
         transactionStatus.setCommitted();
-        // unregister this and all modules from jmx
-        close();
 
         return dependencyResolverManager.getSortedModuleIdentifiers();
     }
@@ -398,12 +422,14 @@ class ConfigTransactionControllerImpl implements
     }
 
     private void internalAbort() {
+        logger.trace("Aborting {}", this);
         transactionStatus.setAborted();
         close();
     }
 
-    private void close() {
-        transactionRegistrator.close();
+    public void close() {
+        dependencyResolverManager.close();
+        txLookupRegistry.close();
     }
 
     @Override
@@ -413,7 +439,7 @@ class ConfigTransactionControllerImpl implements
 
     @Override
     public String getTransactionName() {
-        return transactionIdentifier.getName();
+        return getTransactionIdentifier().getName();
     }
 
     /**
@@ -421,7 +447,7 @@ class ConfigTransactionControllerImpl implements
      */
     @Override
     public Set<ObjectName> lookupConfigBeans() {
-        return lookupConfigBeans("*", "*");
+        return txLookupRegistry.lookupConfigBeans();
     }
 
     /**
@@ -429,7 +455,7 @@ class ConfigTransactionControllerImpl implements
      */
     @Override
     public Set<ObjectName> lookupConfigBeans(String moduleName) {
-        return lookupConfigBeans(moduleName, "*");
+        return txLookupRegistry.lookupConfigBeans(moduleName);
     }
 
     /**
@@ -438,20 +464,29 @@ class ConfigTransactionControllerImpl implements
     @Override
     public ObjectName lookupConfigBean(String moduleName, String instanceName)
             throws InstanceNotFoundException {
-        return LookupBeansUtil.lookupConfigBean(this, moduleName, instanceName);
+        return txLookupRegistry.lookupConfigBean(moduleName, instanceName);
     }
 
     /**
      * {@inheritDoc}
      */
     @Override
-    public Set<ObjectName> lookupConfigBeans(String moduleName,
-            String instanceName) {
-        ObjectName namePattern = ObjectNameUtil.createModulePattern(moduleName,
-                instanceName, transactionIdentifier.getName());
-        return txModuleJMXRegistrator.queryNames(namePattern, null);
+    public Set<ObjectName> lookupConfigBeans(String moduleName, String instanceName) {
+        return txLookupRegistry.lookupConfigBeans(moduleName, instanceName);
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException {
+        txLookupRegistry.checkConfigBeanExists(objectName);
+    }
+    // --
+
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public Set<String> getAvailableModuleNames() {
         return factoriesHolder.getModuleNames();
@@ -473,11 +508,11 @@ class ConfigTransactionControllerImpl implements
     // @VisibleForTesting
 
     TransactionModuleJMXRegistrator getTxModuleJMXRegistrator() {
-        return txModuleJMXRegistrator;
+        return txLookupRegistry.getTxModuleJMXRegistrator();
     }
 
     public TransactionIdentifier getName() {
-        return transactionIdentifier;
+        return getTransactionIdentifier();
     }
 
     @Override
@@ -487,7 +522,7 @@ class ConfigTransactionControllerImpl implements
 
     @Override
     public TransactionIdentifier getIdentifier() {
-        return transactionIdentifier;
+        return getTransactionIdentifier();
     }
 
     @Override
@@ -498,4 +533,77 @@ class ConfigTransactionControllerImpl implements
         }
         return factoryBundleContextEntry.getValue();
     }
+
+    // service reference functionality:
+
+
+    @Override
+    public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
+        return writableSRRegistry.lookupConfigBeanByServiceInterfaceName(serviceInterfaceQName, refName);
+    }
+
+    @Override
+    public synchronized Map<String, Map<String, ObjectName>> getServiceMapping() {
+        return writableSRRegistry.getServiceMapping();
+    }
+
+    @Override
+    public synchronized Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
+        return writableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceQName);
+    }
+
+    @Override
+    public synchronized Set<String> lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException {
+        return writableSRRegistry.lookupServiceInterfaceNames(objectName);
+    }
+
+    @Override
+    public synchronized String getServiceInterfaceName(String namespace, String localName) {
+        return writableSRRegistry.getServiceInterfaceName(namespace, localName);
+    }
+
+    @Override
+    public synchronized ObjectName saveServiceReference(String serviceInterfaceName, String refName, ObjectName moduleON) throws InstanceNotFoundException {
+        return writableSRRegistry.saveServiceReference(serviceInterfaceName, refName, moduleON);
+    }
+
+    @Override
+    public synchronized void removeServiceReference(String serviceInterfaceName, String refName) throws InstanceNotFoundException {
+        writableSRRegistry.removeServiceReference(serviceInterfaceName, refName);
+    }
+
+    @Override
+    public synchronized void removeAllServiceReferences() {
+        writableSRRegistry.removeAllServiceReferences();
+    }
+
+    @Override
+    public boolean removeServiceReferences(ObjectName objectName) throws InstanceNotFoundException {
+        return writableSRRegistry.removeServiceReferences(objectName);
+    }
+
+    @Override
+    public SearchableServiceReferenceWritableRegistry  getWritableRegistry() {
+        return writableSRRegistry;
+    }
+
+    @Override
+    public TransactionIdentifier getTransactionIdentifier() {
+        return txLookupRegistry.getTransactionIdentifier();
+    }
+
+    @Override
+    public Set<String> getAvailableModuleFactoryQNames() {
+        return txLookupRegistry.getAvailableModuleFactoryQNames();
+    }
+
+    @Override
+    public void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+        writableSRRegistry.checkServiceReferenceExists(objectName);
+    }
+
+    @Override
+    public ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+        return writableSRRegistry.getServiceReference(serviceInterfaceQName, refName);
+    }
 }