Add ModuleFactory#getDefaultModules method to config-api. 95/2095/3
authorTomas Olvecky <tolvecky@cisco.com>
Mon, 21 Oct 2013 16:00:05 +0000 (18:00 +0200)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 24 Oct 2013 01:50:32 +0000 (01:50 +0000)
Add method to populate pre-existing state. Modify code generator to generate
a blank implementation. Calling of the method is done by config-manager
every time new ModuleFactory is discovered in OSGi service registry, each time in a separate transaction.
Implement default module functionality in config-manager.
Add DependencyResolverFactory for default modules to be able to lookup dependencies.
Implement new service tracker tracking ModuleFactory instances in order to commit blank transactions
every time ModuleFactory service appears or disappears.
Clean up pom versions: merge config.yangstore.version into config.version.

Change-Id: I47229c9e403b817b24740c8f77ad43abcc720094
Signed-off-by: Tomas Olvecky <tolvecky@cisco.com>
38 files changed:
opendaylight/commons/opendaylight/pom.xml
opendaylight/config/config-api/pom.xml
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/DependencyResolverFactory.java [new file with mode: 0644]
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/spi/ModuleFactory.java
opendaylight/config/config-manager/pom.xml
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerInternal.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ModuleInternalTransactionalInfo.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManager.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/ModulesHolder.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/factoriesresolver/ModuleFactoriesResolver.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BlankTransactionServiceTracker.java [new file with mode: 0644]
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BundleContextBackedModuleFactoriesResolver.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ConfigManagerActivator.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ExtenderBundleTracker.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ClassBasedModuleFactory.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImplTest.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/factoriesresolver/HardcodedModuleFactoriesResolver.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/TestingParallelAPSPModuleFactory.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/MockedDependenciesTest.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/scheduledthreadpool/TestingScheduledThreadPoolModuleFactory.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/TestingFixedThreadPoolModuleFactory.java
opendaylight/config/config-persister-api/pom.xml
opendaylight/config/config-persister-file-adapter/pom.xml
opendaylight/config/config-util/pom.xml
opendaylight/config/logback-config/pom.xml
opendaylight/config/pom.xml
opendaylight/config/yang-jmx-generator-it/pom.xml
opendaylight/config/yang-jmx-generator-plugin/pom.xml
opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/factory_abs_template.ftl
opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGeneratorTest.java
opendaylight/config/yang-jmx-generator/pom.xml
opendaylight/config/yang-store-api/pom.xml
opendaylight/config/yang-store-impl/pom.xml
opendaylight/config/yang-test/pom.xml
opendaylight/distribution/opendaylight/pom.xml
opendaylight/netconf/pom.xml

index 0356f4f..30c0e47 100644 (file)
@@ -76,9 +76,8 @@
     <yangtools.binding.version>0.6.0-SNAPSHOT</yangtools.binding.version>
     <!--versions for bits of the controller -->
     <controller.version>0.4.1-SNAPSHOT</controller.version>
-    <config.version>0.2.1-SNAPSHOT</config.version>
+    <config.version>0.2.2-SNAPSHOT</config.version>
     <netconf.version>0.2.2-SNAPSHOT</netconf.version>
-    <config.yangstore.version>0.2.2-SNAPSHOT</config.yangstore.version>
     <mdsal.version>1.0-SNAPSHOT</mdsal.version>
     <containermanager.version>0.5.1-SNAPSHOT</containermanager.version>
     <switchmanager.api.version>0.5.1-SNAPSHOT</switchmanager.api.version>
index e0f2749..218362a 100644 (file)
@@ -6,13 +6,14 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.1-SNAPSHOT</version>
+        <version>0.2.2-SNAPSHOT</version>
     </parent>
 
     <artifactId>config-api</artifactId>
     <name>${project.artifactId}</name>
     <packaging>bundle</packaging>
 
+
     <dependencies>
         <dependency>
             <groupId>com.google.code.findbugs</groupId>
diff --git a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/DependencyResolverFactory.java b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/DependencyResolverFactory.java
new file mode 100644 (file)
index 0000000..77f40c8
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.api;
+
+public interface DependencyResolverFactory {
+
+    DependencyResolver createDependencyResolver(ModuleIdentifier moduleIdentifier);
+
+}
index 00db2c2..e300523 100644 (file)
@@ -10,9 +10,12 @@ package org.opendaylight.controller.config.spi;
 import javax.management.DynamicMBean;
 
 import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DependencyResolverFactory;
 import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
 import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
 
+import java.util.Set;
+
 /**
  * Factory which creates {@link Module instances. An instance of this interface
  * needs to be exported into the OSGi Service Registry. Such an instance
@@ -88,4 +91,15 @@ public interface ModuleFactory {
     boolean isModuleImplementingServiceInterface(
             Class<? extends AbstractServiceInterface> serviceInterface);
 
+    /**
+     * Called when ModuleFactory is registered to config manager.
+     * Useful for populating the registry with pre-existing state. Since
+     * the method is called for each ModuleFactory separately and transaction
+     * is committed automatically, returned modules MUST be valid and commitable
+     * without any manual intervention.
+     * @param dependencyResolverFactory factory for getting dependency resolvers for each module.
+     * @return set of default modules. Null is not allowed.
+     */
+    public Set<? extends Module> getDefaultModules(DependencyResolverFactory dependencyResolverFactory);
+
 }
index b3a0463..2019cb6 100644 (file)
@@ -4,19 +4,19 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.1-SNAPSHOT</version>
+        <version>0.2.2-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>config-manager</artifactId>
     <name>${project.artifactId}</name>
     <packaging>bundle</packaging>
 
+
     <dependencies>
         <!-- compile dependencies -->
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>config-api</artifactId>
-            <version>0.2.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
             <groupId>com.google.code.findbugs</groupId>
             <artifactId>jsr305</artifactId>
         </dependency>
+        <!--
         <dependency>
             <groupId>com.googlecode.json-simple</groupId>
             <artifactId>json-simple</artifactId>
             <version>1.1</version>
         </dependency>
+        -->
         <dependency>
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
         <dependency>
             <groupId>org.opendaylight.bgpcep</groupId>
             <artifactId>mockito-configuration</artifactId>
-            <version>${bgpcep.version}</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>config-util</artifactId>
-            <version>0.2.1-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>config-util</artifactId>
-            <version>0.2.1-SNAPSHOT</version>
             <scope>test</scope>
             <type>test-jar</type>
         </dependency>
index 97d57a4..18b4d3b 100644 (file)
@@ -45,6 +45,7 @@ import org.opendaylight.controller.config.manager.impl.osgi.BeanToOsgiServiceMan
 import org.opendaylight.controller.config.manager.impl.osgi.BeanToOsgiServiceManager.OsgiRegistration;
 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.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -54,10 +55,8 @@ import org.slf4j.LoggerFactory;
  * Transactions. It is registered in Platform MBean Server.
  */
 @ThreadSafe
-public class ConfigRegistryImpl implements AutoCloseable,
-        ConfigRegistryImplMXBean {
-    private static final Logger logger = LoggerFactory
-            .getLogger(ConfigRegistryImpl.class);
+public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBean {
+    private static final Logger logger = LoggerFactory.getLogger(ConfigRegistryImpl.class);
 
     private final ModuleFactoriesResolver resolver;
     private final MBeanServer configMBeanServer;
@@ -98,6 +97,9 @@ public class ConfigRegistryImpl implements AutoCloseable,
     // internal jmx server shared by all transactions
     private final MBeanServer transactionsMBeanServer;
 
+    @GuardedBy("this")
+    private List<ModuleFactory> lastListOfFactories = Collections.emptyList();
+
     // constructor
     public ConfigRegistryImpl(ModuleFactoriesResolver resolver,
             BundleContext bundleContext, MBeanServer configMBeanServer) {
@@ -130,30 +132,21 @@ public class ConfigRegistryImpl implements AutoCloseable,
 
     private synchronized ConfigTransactionControllerInternal beginConfigInternal() {
         versionCounter++;
-        String transactionName = "ConfigTransaction-" + version + "-"
-                + versionCounter;
+        String transactionName = "ConfigTransaction-" + version + "-" + versionCounter;
         TransactionJMXRegistrator transactionRegistrator = baseJMXRegistrator
                 .createTransactionJMXRegistrator(transactionName);
+        List<ModuleFactory> allCurrentFactories = Collections.unmodifiableList(resolver.getAllFactories());
         ConfigTransactionControllerInternal transactionController = new ConfigTransactionControllerImpl(
                 transactionName, transactionRegistrator, version,
-                versionCounter, resolver.getAllFactories(),
-                transactionsMBeanServer, configMBeanServer);
+                versionCounter, allCurrentFactories, transactionsMBeanServer, configMBeanServer);
         try {
-            transactionRegistrator.registerMBean(transactionController, transactionController.getControllerObjectName
-                    ());
+            transactionRegistrator.registerMBean(transactionController, transactionController.getControllerObjectName());
         } catch (InstanceAlreadyExistsException e) {
             throw new IllegalStateException(e);
         }
 
-        // copy old configuration to this server
-        for (ModuleInternalInfo oldConfigInfo : currentConfig.getEntries()) {
-            try {
-                transactionController.copyExistingModule(oldConfigInfo);
-            } catch (InstanceAlreadyExistsException e) {
-                throw new IllegalStateException("Error while copying "
-                        + oldConfigInfo, e);
-            }
-        }
+        transactionController.copyExistingModulesAndProcessFactoryDiff(currentConfig.getEntries(), lastListOfFactories);
+
         transactionsHolder.add(transactionName, transactionController);
         return transactionController;
     }
@@ -162,20 +155,15 @@ public class ConfigRegistryImpl implements AutoCloseable,
      * {@inheritDoc}
      */
     @Override
-    public synchronized CommitStatus commitConfig(
-            ObjectName transactionControllerON)
+    public synchronized CommitStatus commitConfig(ObjectName transactionControllerON)
             throws ConflictingVersionException, ValidationException {
         final String transactionName = ObjectNameUtil
                 .getTransactionName(transactionControllerON);
-        logger.info(
-                "About to commit {}. Current parentVersion: {}, versionCounter {}",
-                transactionName, version, versionCounter);
+        logger.info("About to commit {}. Current parentVersion: {}, versionCounter {}", transactionName, version, versionCounter);
 
         // find ConfigTransactionController
-        Map<String, ConfigTransactionControllerInternal> transactions = transactionsHolder
-                .getCurrentTransactions();
-        ConfigTransactionControllerInternal configTransactionController = transactions
-                .get(transactionName);
+        Map<String, ConfigTransactionControllerInternal> transactions = transactionsHolder.getCurrentTransactions();
+        ConfigTransactionControllerInternal configTransactionController = transactions.get(transactionName);
         if (configTransactionController == null) {
             throw new IllegalArgumentException(String.format(
                     "Transaction with name '%s' not found", transactionName));
@@ -190,33 +178,28 @@ public class ConfigRegistryImpl implements AutoCloseable,
         }
         // optimistic lock ok
 
-        CommitInfo commitInfo = configTransactionController
-                .validateBeforeCommitAndLockTransaction();
-        final ConfigRegistryImpl a = this;
+        CommitInfo commitInfo = configTransactionController.validateBeforeCommitAndLockTransaction();
+        lastListOfFactories = Collections.unmodifiableList(configTransactionController.getCurrentlyRegisteredFactories());
         // non recoverable from here:
         try {
-            final CommitStatus secondPhaseCommitStatus = secondPhaseCommit(
+            return secondPhaseCommit(
                     configTransactionController, commitInfo);
-
-            return secondPhaseCommitStatus;
         } catch (Throwable t) { // some libs throw Errors: e.g.
                                 // javax.xml.ws.spi.FactoryFinder$ConfigurationError
             isHealthy = false;
-            logger.error(
-                    "Configuration Transaction failed on 2PC, server is unhealthy",
-                    t);
-            if (t instanceof RuntimeException)
+            logger.error("Configuration Transaction failed on 2PC, server is unhealthy", t);
+            if (t instanceof RuntimeException) {
                 throw (RuntimeException) t;
-            else if (t instanceof Error)
+            } else if (t instanceof Error) {
                 throw (Error) t;
-            else
+            } else {
                 throw new RuntimeException(t);
+            }
         }
     }
 
-    private CommitStatus secondPhaseCommit(
-            ConfigTransactionControllerInternal configTransactionController,
-            CommitInfo commitInfo) {
+    private CommitStatus secondPhaseCommit(ConfigTransactionControllerInternal configTransactionController,
+                                           CommitInfo commitInfo) {
 
         // close instances which were destroyed by the user, including
         // (hopefully) runtime beans
index 5038079..5e8fac6 100644 (file)
@@ -9,10 +9,8 @@ package org.opendaylight.controller.config.manager.impl;
 
 import static java.lang.String.format;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
 import java.util.Map.Entry;
-import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import javax.annotation.Nullable;
@@ -50,8 +48,7 @@ import org.slf4j.LoggerFactory;
 class ConfigTransactionControllerImpl implements
         ConfigTransactionControllerInternal,
         ConfigTransactionControllerImplMXBean {
-    private static final Logger logger = LoggerFactory
-            .getLogger(ConfigTransactionControllerImpl.class);
+    private static final Logger logger = LoggerFactory.getLogger(ConfigTransactionControllerImpl.class);
 
     private final TransactionIdentifier transactionIdentifier;
     private final ObjectName controllerON;
@@ -62,6 +59,7 @@ class ConfigTransactionControllerImpl implements
     private final DependencyResolverManager dependencyResolverManager;
     private final TransactionStatus transactionStatus;
     private final MBeanServer transactionsMBeanServer;
+    private final List<ModuleFactory> currentlyRegisteredFactories;
 
     /**
      * Disables ability of {@link DynamicWritableWrapper} to change attributes
@@ -77,7 +75,7 @@ class ConfigTransactionControllerImpl implements
     public ConfigTransactionControllerImpl(String transactionName,
             TransactionJMXRegistrator transactionRegistrator,
             long parentVersion, long currentVersion,
-            List<? extends ModuleFactory> currentlyRegisteredFactories,
+            List<ModuleFactory> currentlyRegisteredFactories,
             MBeanServer transactionsMBeanServer, MBeanServer configMBeanServer) {
 
         this.transactionIdentifier = new TransactionIdentifier(transactionName);
@@ -88,17 +86,69 @@ class ConfigTransactionControllerImpl implements
                 .createTransactionModuleJMXRegistrator();
         this.parentVersion = parentVersion;
         this.currentVersion = currentVersion;
-        this.factoriesHolder = new HierarchicalConfigMBeanFactoriesHolder(
-                currentlyRegisteredFactories);
+        this.currentlyRegisteredFactories = currentlyRegisteredFactories;
+        this.factoriesHolder = new HierarchicalConfigMBeanFactoriesHolder(currentlyRegisteredFactories);
         this.transactionStatus = new TransactionStatus();
-        this.dependencyResolverManager = new DependencyResolverManager(
-                transactionName, transactionStatus);
+        this.dependencyResolverManager = new DependencyResolverManager(transactionName, transactionStatus);
         this.transactionsMBeanServer = transactionsMBeanServer;
         this.configMBeanServer = configMBeanServer;
     }
 
     @Override
-    public synchronized void copyExistingModule(
+    public void copyExistingModulesAndProcessFactoryDiff(Collection<ModuleInternalInfo> existingModules, List<ModuleFactory> lastListOfFactories) {
+        // copy old configuration to this server
+        for (ModuleInternalInfo oldConfigInfo : existingModules) {
+            try {
+                copyExistingModule(oldConfigInfo);
+            } catch (InstanceAlreadyExistsException e) {
+                throw new IllegalStateException("Error while copying " + oldConfigInfo, e);
+            }
+        }
+        processDefaultBeans(lastListOfFactories);
+    }
+
+    private synchronized void processDefaultBeans(List<ModuleFactory> lastListOfFactories) {
+        transactionStatus.checkNotCommitStarted();
+        transactionStatus.checkNotAborted();
+
+        Set<ModuleFactory> oldSet = new HashSet<>(lastListOfFactories);
+        Set<ModuleFactory> newSet = new HashSet<>(currentlyRegisteredFactories);
+
+        List<ModuleFactory> toBeAdded = new ArrayList<>();
+        List<ModuleFactory> toBeRemoved = new ArrayList<>();
+        for(ModuleFactory moduleFactory: currentlyRegisteredFactories) {
+            if (oldSet.contains(moduleFactory) == false){
+                toBeAdded.add(moduleFactory);
+            }
+        }
+        for(ModuleFactory moduleFactory: lastListOfFactories){
+            if (newSet.contains(moduleFactory) == false) {
+                toBeRemoved.add(moduleFactory);
+            }
+        }
+        // add default modules
+        for (ModuleFactory moduleFactory : toBeAdded) {
+            Set<? extends Module> defaultModules = moduleFactory.getDefaultModules(dependencyResolverManager);
+            for (Module module : defaultModules) {
+                try {
+                    putConfigBeanToJMXAndInternalMaps(module.getName(), module, moduleFactory, null);
+                } catch (InstanceAlreadyExistsException e) {
+                    throw new IllegalStateException(e);
+                }
+            }
+        }
+
+        // remove modules belonging to removed factories
+        for(ModuleFactory removedFactory: toBeRemoved){
+            List<ModuleIdentifier> modulesOfRemovedFactory = dependencyResolverManager.findAllByFactory(removedFactory);
+            for (ModuleIdentifier name : modulesOfRemovedFactory) {
+                destroyModule(name);
+            }
+        }
+    }
+
+
+    private synchronized void copyExistingModule(
             ModuleInternalInfo oldConfigBeanInfo)
             throws InstanceAlreadyExistsException {
         transactionStatus.checkNotCommitStarted();
@@ -121,8 +171,7 @@ class ConfigTransactionControllerImpl implements
                     "Error while copying old configuration from %s to %s",
                     oldConfigBeanInfo, moduleFactory), e);
         }
-        putConfigBeanToJMXAndInternalMaps(moduleIdentifier, module,
-                moduleFactory, oldConfigBeanInfo);
+        putConfigBeanToJMXAndInternalMaps(moduleIdentifier, module, moduleFactory, oldConfigBeanInfo);
     }
 
     @Override
@@ -131,17 +180,13 @@ class ConfigTransactionControllerImpl implements
 
         transactionStatus.checkNotCommitStarted();
         transactionStatus.checkNotAborted();
-        ModuleIdentifier moduleIdentifier = new ModuleIdentifier(factoryName,
-                instanceName);
+        ModuleIdentifier moduleIdentifier = new ModuleIdentifier(factoryName, instanceName);
         dependencyResolverManager.assertNotExists(moduleIdentifier);
 
         // find factory
-        ModuleFactory moduleFactory = factoriesHolder
-                .findByModuleName(factoryName);
-        DependencyResolver dependencyResolver = dependencyResolverManager
-                .getOrCreate(moduleIdentifier);
-        Module module = moduleFactory.createModule(instanceName,
-                dependencyResolver);
+        ModuleFactory moduleFactory = factoriesHolder.findByModuleName(factoryName);
+        DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(moduleIdentifier);
+        Module module = moduleFactory.createModule(instanceName, dependencyResolver);
         return putConfigBeanToJMXAndInternalMaps(moduleIdentifier, module,
                 moduleFactory, null);
     }
@@ -151,7 +196,11 @@ class ConfigTransactionControllerImpl implements
             ModuleFactory moduleFactory,
             @Nullable ModuleInternalInfo maybeOldConfigBeanInfo)
             throws InstanceAlreadyExistsException {
-
+        logger.debug("Adding module {} to transaction {}", moduleIdentifier, this);
+        if (moduleIdentifier.equals(module.getName())==false) {
+            throw new IllegalStateException("Incorrect name reported by module. Expected "
+             + moduleIdentifier + ", got " + module.getName());
+        }
         DynamicMBean writableDynamicWrapper = new DynamicWritableWrapper(
                 module, moduleIdentifier, transactionIdentifier,
                 readOnlyAtomicBoolean, transactionsMBeanServer,
@@ -180,11 +229,15 @@ class ConfigTransactionControllerImpl implements
                     + objectName);
         }
         ObjectNameUtil.checkDomain(objectName);
-        transactionStatus.checkNotAborted();
         ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(objectName,
                 ObjectNameUtil.TYPE_MODULE);
-        ModuleInternalTransactionalInfo removedTInfo = dependencyResolverManager
-                .destroyModule(moduleIdentifier);
+        destroyModule(moduleIdentifier);
+    }
+
+    private void destroyModule(ModuleIdentifier moduleIdentifier) {
+        logger.debug("Destroying module {} in transaction {}", moduleIdentifier, this);
+        transactionStatus.checkNotAborted();
+        ModuleInternalTransactionalInfo removedTInfo = dependencyResolverManager.destroyModule(moduleIdentifier);
         // remove from jmx
         removedTInfo.getTransactionModuleJMXRegistration().close();
     }
@@ -395,4 +448,9 @@ class ConfigTransactionControllerImpl implements
     public TransactionIdentifier getName() {
         return transactionIdentifier;
     }
+
+    @Override
+    public List<ModuleFactory> getCurrentlyRegisteredFactories() {
+        return currentlyRegisteredFactories;
+    }
 }
index 58d3bc1..f9699b9 100644 (file)
@@ -7,13 +7,16 @@
  */
 package org.opendaylight.controller.config.manager.impl;
 
+import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.ObjectName;
 
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.config.api.ValidationException;
+import org.opendaylight.controller.config.spi.ModuleFactory;
 
 /**
  * Defines contract between {@link ConfigTransactionControllerImpl} (producer)
@@ -22,11 +25,15 @@ import org.opendaylight.controller.config.api.ValidationException;
 interface ConfigTransactionControllerInternal extends
         ConfigTransactionControllerImplMXBean {
 
+
+
     /**
-     * Copy already committed module to current transaction.
+     * 1, Copy already committed modules to current transaction.
+     * 2, Diff: compute added and removed factories from last run, then create new modules using
+     * {@link org.opendaylight.controller.config.spi.ModuleFactory#getDefaultModules(org.opendaylight.controller.config.api.DependencyResolverFactory)}
+     * and remove modules belonging to removed factories.
      */
-    void copyExistingModule(ModuleInternalInfo oldConfigBeanInfo)
-            throws InstanceAlreadyExistsException;
+    void copyExistingModulesAndProcessFactoryDiff(Collection<ModuleInternalInfo> entries, List<ModuleFactory> lastListOfFactories);
 
     /**
      * Call {@link org.opendaylight.controller.config.spi.Module#validate()} on
@@ -62,4 +69,5 @@ interface ConfigTransactionControllerInternal extends
      */
     boolean isClosed();
 
+    List<ModuleFactory> getCurrentlyRegisteredFactories();
 }
index a1bc59f..571bbad 100644 (file)
@@ -46,7 +46,7 @@ public class ModuleInternalTransactionalInfo {
 
     public DestroyedModule toDestroyedModule() {
         if (maybeOldInternalInfo == null) {
-            throw new IllegalStateException("Cannot destoy uncommitted module");
+            throw new IllegalStateException("Cannot destroy uncommitted module");
         }
         DynamicReadableWrapper oldModule = maybeOldInternalInfo
                 .getReadableModule();
index 34b3093..fe94af8 100644 (file)
@@ -7,15 +7,13 @@
  */
 package org.opendaylight.controller.config.manager.impl.dependencyresolver;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 import javax.annotation.concurrent.GuardedBy;
 import javax.management.InstanceAlreadyExistsException;
 
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DependencyResolverFactory;
 import org.opendaylight.controller.config.api.JmxAttribute;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.config.manager.impl.CommitInfo;
@@ -29,7 +27,7 @@ import org.opendaylight.controller.config.spi.ModuleFactory;
  * transaction. Observes usage of DependencyResolver within modules to figure
  * out dependency tree.
  */
-public class DependencyResolverManager implements TransactionHolder {
+public class DependencyResolverManager implements TransactionHolder, DependencyResolverFactory {
     @GuardedBy("this")
     private final Map<ModuleIdentifier, DependencyResolverImpl> moduleIdentifiersToDependencyResolverMap = new HashMap<>();
     private final ModulesHolder modulesHolder;
@@ -41,6 +39,11 @@ public class DependencyResolverManager implements TransactionHolder {
         this.transactionStatus = transactionStatus;
     }
 
+    @Override
+    public DependencyResolver createDependencyResolver(ModuleIdentifier moduleIdentifier) {
+        return getOrCreate(moduleIdentifier);
+    }
+
     public synchronized DependencyResolverImpl getOrCreate(ModuleIdentifier name) {
         DependencyResolverImpl dependencyResolver = moduleIdentifiersToDependencyResolverMap
                 .get(name);
@@ -128,4 +131,14 @@ public class DependencyResolverManager implements TransactionHolder {
             throws InstanceAlreadyExistsException {
         modulesHolder.assertNotExists(moduleIdentifier);
     }
+
+    public List<ModuleIdentifier> findAllByFactory(ModuleFactory factory) {
+        List<ModuleIdentifier> result = new ArrayList<>();
+        for( ModuleInternalTransactionalInfo  info : modulesHolder.getAllInfos()) {
+            if (factory.equals(info.getModuleFactory())) {
+                result.add(info.getName());
+            }
+        }
+        return result;
+    }
 }
index 7747e55..65cf9bc 100644 (file)
@@ -7,13 +7,7 @@
  */
 package org.opendaylight.controller.config.manager.impl.dependencyresolver;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 import javax.annotation.concurrent.GuardedBy;
 import javax.management.InstanceAlreadyExistsException;
@@ -120,4 +114,8 @@ class ModulesHolder implements TransactionHolder {
                             + moduleIdentifier);
         }
     }
+
+    public Collection<ModuleInternalTransactionalInfo> getAllInfos(){
+        return commitMap.values();
+    }
 }
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BlankTransactionServiceTracker.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BlankTransactionServiceTracker.java
new file mode 100644 (file)
index 0000000..bcc8b11
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.manager.impl.osgi;
+
+import org.opendaylight.controller.config.api.jmx.CommitStatus;
+import org.opendaylight.controller.config.manager.impl.ConfigRegistryImpl;
+import org.opendaylight.controller.config.spi.ModuleFactory;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.management.ObjectName;
+
+/**
+ * Every time factory is added or removed, blank transaction is triggered to handle
+ * {@link org.opendaylight.controller.config.spi.ModuleFactory#getDefaultModules(org.opendaylight.controller.config.api.DependencyResolverFactory)}
+ * functionality.
+ */
+public class BlankTransactionServiceTracker implements ServiceTrackerCustomizer<ModuleFactory, Object> {
+    private static final Logger logger = LoggerFactory.getLogger(BlankTransactionServiceTracker.class);
+
+    private final ConfigRegistryImpl configRegistry;
+
+    public BlankTransactionServiceTracker(ConfigRegistryImpl configRegistry) {
+        this.configRegistry = configRegistry;
+    }
+
+    @Override
+    public Object addingService(ServiceReference<ModuleFactory> moduleFactoryServiceReference) {
+        blankTransaction();
+        return null;
+    }
+
+    private void blankTransaction() {
+        // create transaction
+        ObjectName tx = configRegistry.beginConfig();
+        CommitStatus commitStatus = configRegistry.commitConfig(tx);
+        logger.debug("Committed blank transaction with status {}", commitStatus);
+    }
+
+    @Override
+    public void modifiedService(ServiceReference<ModuleFactory> moduleFactoryServiceReference, Object o) {
+        blankTransaction();
+    }
+
+    @Override
+    public void removedService(ServiceReference<ModuleFactory> moduleFactoryServiceReference, Object o) {
+        blankTransaction();
+    }
+}
index 77bfc49..7c8c4e6 100644 (file)
@@ -30,7 +30,7 @@ public class BundleContextBackedModuleFactoriesResolver implements
     }
 
     @Override
-    public List<? extends ModuleFactory> getAllFactories() {
+    public List<ModuleFactory> getAllFactories() {
         Collection<ServiceReference<ModuleFactory>> serviceReferences;
         try {
             serviceReferences = bundleContext.getServiceReferences(
index 81b9ea9..f567f1b 100644 (file)
@@ -13,8 +13,10 @@ import javax.management.MBeanServer;
 
 import org.opendaylight.controller.config.manager.impl.ConfigRegistryImpl;
 import org.opendaylight.controller.config.manager.impl.jmx.ConfigRegistryJMXRegistrator;
+import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
+import org.osgi.util.tracker.ServiceTracker;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -28,21 +30,24 @@ public class ConfigManagerActivator implements BundleActivator {
 
     @Override
     public void start(BundleContext context) throws Exception {
-        extenderBundleTracker = new ExtenderBundleTracker(context);
-        extenderBundleTracker.open();
-        BundleContextBackedModuleFactoriesResolver bundleContextBackedModuleFactoriesResolver = new BundleContextBackedModuleFactoriesResolver(
-                context);
-
-        MBeanServer configMBeanServer = ManagementFactory
-                .getPlatformMBeanServer();
+        BundleContextBackedModuleFactoriesResolver bundleContextBackedModuleFactoriesResolver =
+                new BundleContextBackedModuleFactoriesResolver(context);
+        MBeanServer configMBeanServer = ManagementFactory.getPlatformMBeanServer();
         configRegistry = new ConfigRegistryImpl(
                 bundleContextBackedModuleFactoriesResolver, context,
                 configMBeanServer);
-        // register config registry to jmx
 
-        configRegistryJMXRegistrator = new ConfigRegistryJMXRegistrator(
-                configMBeanServer);
+        // register config registry to jmx
+        configRegistryJMXRegistrator = new ConfigRegistryJMXRegistrator(configMBeanServer);
         configRegistryJMXRegistrator.registerToJMX(configRegistry);
+
+        // track bundles containing factories
+        extenderBundleTracker = new ExtenderBundleTracker(context);
+        extenderBundleTracker.open();
+
+        BlankTransactionServiceTracker customizer = new BlankTransactionServiceTracker(configRegistry);
+        ServiceTracker<?, ?> serviceTracker = new ServiceTracker(context, ModuleFactory.class, customizer);
+        serviceTracker.open();
     }
 
     @Override
index 22a1216..29e7e3a 100644 (file)
@@ -14,6 +14,8 @@ import java.net.URL;
 import java.util.List;
 
 import org.apache.commons.io.IOUtils;
+import org.opendaylight.controller.config.api.jmx.CommitStatus;
+import org.opendaylight.controller.config.manager.impl.ConfigRegistryImpl;
 import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
@@ -24,20 +26,20 @@ import org.osgi.util.tracker.BundleTracker;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.management.ObjectName;
+
 /**
  * OSGi extender that listens for bundle activation events. Reads file
  * META-INF/services/org.opendaylight.controller.config.spi.ModuleFactory, each
  * line should contain an implementation of ModuleFactory interface. Creates new
  * instance with default constructor and registers it into OSGi service
  * registry. There is no need for listening for implementing removedBundle as
- * the services are unregistered automatically. Code based on
- * http://www.toedter.com/blog/?p=236
+ * the services are unregistered automatically.
+ * Code based on http://www.toedter.com/blog/?p=236
  */
-
 public class ExtenderBundleTracker extends BundleTracker<Object> {
 
-    private static final Logger logger = LoggerFactory
-            .getLogger(ExtenderBundleTracker.class);
+    private static final Logger logger = LoggerFactory.getLogger(ExtenderBundleTracker.class);
 
     public ExtenderBundleTracker(BundleContext context) {
         super(context, Bundle.ACTIVE, null);
@@ -46,10 +48,8 @@ public class ExtenderBundleTracker extends BundleTracker<Object> {
 
     @Override
     public Object addingBundle(Bundle bundle, BundleEvent event) {
-        URL resource = bundle.getEntry("META-INF/services/"
-                + ModuleFactory.class.getName());
-        logger.trace(
-                "Got addingBundle event of bundle {}, resource {}, event {}",
+        URL resource = bundle.getEntry("META-INF/services/" + ModuleFactory.class.getName());
+        logger.trace("Got addingBundle event of bundle {}, resource {}, event {}",
                 bundle, resource, event);
         if (resource != null) {
             try (InputStream inputStream = resource.openStream()) {
@@ -58,29 +58,20 @@ public class ExtenderBundleTracker extends BundleTracker<Object> {
                     registerFactory(factoryClassName, bundle);
                 }
             } catch (Exception e) {
-                logger.error("Error while reading {}, stopping bundle {}",
-                        resource, bundle, e);
-                stopBundleQuietly(bundle);
+                logger.error("Error while reading {}", resource, e);
                 throw new RuntimeException(e);
             }
-
         }
         return bundle;
     }
 
-    private static void stopBundleQuietly(Bundle bundle) {
-        try {
-            bundle.stop();
-        } catch (BundleException e2) {
-            logger.warn(
-                    "Ignoring fact that bundle.stop failed on {}, reason {}",
-                    bundle, e2.toString());
-        }
+    @Override
+    public void removedBundle(Bundle bundle, BundleEvent event, Object object) {
+        super.removedBundle(bundle,event,object);
     }
 
     // TODO:test
-    private static ServiceRegistration<?> registerFactory(
-            String factoryClassName, Bundle bundle) {
+    private static ServiceRegistration<?> registerFactory(String factoryClassName, Bundle bundle) {
         String errorMessage;
         try {
             Class<?> clazz = bundle.loadClass(factoryClassName);
index afc79a5..f0ad562 100644 (file)
@@ -8,11 +8,16 @@
 package org.opendaylight.controller.config.manager.impl;
 
 import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DependencyResolverFactory;
 import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
 import org.opendaylight.controller.config.spi.Module;
 import org.opendaylight.controller.config.spi.ModuleFactory;
@@ -21,8 +26,10 @@ import com.google.common.base.Preconditions;
 import com.google.common.base.Throwables;
 
 /**
- * Creates new Config beans by calling {@link Class#newInstance()} on provided
- * config bean class.
+ * Creates new modules by reflection. Provided class must have this constructor:
+ * ctor(DynamicMBeanWithInstance.class, ModuleIdentifier.class).
+ * When reconfiguring, both parameters will be non null. When creating new
+ * instance first parameter will be null.
  *
  */
 public class ClassBasedModuleFactory implements ModuleFactory {
@@ -51,28 +58,32 @@ public class ClassBasedModuleFactory implements ModuleFactory {
     public Module createModule(String instanceName,
             DependencyResolver dependencyResolver, DynamicMBeanWithInstance old)
             throws Exception {
-        Preconditions.checkNotNull(dependencyResolver);
         Preconditions.checkNotNull(old);
+        return constructModule(instanceName, dependencyResolver, old);
+    }
+
+    private Module constructModule(String instanceName, DependencyResolver dependencyResolver, DynamicMBeanWithInstance old) throws InstantiationException, IllegalAccessException, InvocationTargetException {
+        Preconditions.checkNotNull(dependencyResolver);
+        ModuleIdentifier moduleIdentifier = new ModuleIdentifier(implementationName, instanceName);
         Constructor<? extends Module> declaredConstructor;
         try {
-            declaredConstructor = configBeanClass
-                    .getDeclaredConstructor(DynamicMBeanWithInstance.class);
+            declaredConstructor = configBeanClass.getDeclaredConstructor(DynamicMBeanWithInstance.class, ModuleIdentifier.class);
         } catch (NoSuchMethodException e) {
             throw new IllegalStateException(
                     "Did not find constructor with parameters (DynamicMBeanWithInstance) in "
                             + configBeanClass, e);
         }
         Preconditions.checkState(declaredConstructor != null);
-        return declaredConstructor.newInstance(old);
+        return declaredConstructor.newInstance(old, moduleIdentifier);
     }
 
     @Override
     public Module createModule(String instanceName,
             DependencyResolver dependencyResolver) {
         try {
-            return configBeanClass.newInstance();
-        } catch (Exception e) {
-            throw Throwables.propagate(e);
+            return constructModule(instanceName, dependencyResolver, null);
+        } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
+            throw new RuntimeException(e);
         }
     }
 
@@ -92,4 +103,9 @@ public class ClassBasedModuleFactory implements ModuleFactory {
         }
         return false;
     }
+
+    @Override
+    public Set<Module> getDefaultModules(DependencyResolverFactory dependencyResolverFactory) {
+        return new HashSet<Module>();
+    }
 }
index 593f99f..eceb675 100644 (file)
@@ -61,7 +61,7 @@ public class ConfigTransactionControllerImplTest extends
         baseJMXRegistrator = new BaseJMXRegistrator(
                 ManagementFactory.getPlatformMBeanServer());
         transactionsMBeanServer = MBeanServerFactory.createMBeanServer();
-        List<? extends ModuleFactory> currentlyRegisteredFactories = new ArrayList<>();
+        List<ModuleFactory> currentlyRegisteredFactories = new ArrayList<>();
         TransactionJMXRegistrator jmxRegistrator123 = baseJMXRegistrator
                 .createTransactionJMXRegistrator(transactionName123);
 
index e489a22..04f651f 100644 (file)
@@ -12,16 +12,15 @@ import java.util.List;
 
 import org.opendaylight.controller.config.spi.ModuleFactory;
 
-public class HardcodedModuleFactoriesResolver implements
-        ModuleFactoriesResolver {
-    private final List<? extends ModuleFactory> list;
+public class HardcodedModuleFactoriesResolver implements ModuleFactoriesResolver {
+    private final List<ModuleFactory> list;
 
     public HardcodedModuleFactoriesResolver(ModuleFactory... list) {
         this.list = Arrays.asList(list);
     }
 
     @Override
-    public List<? extends ModuleFactory> getAllFactories() {
+    public List<ModuleFactory> getAllFactories() {
         return list;
     }
 
index 0a53d75..dd83e91 100644 (file)
@@ -11,11 +11,16 @@ import javax.annotation.concurrent.ThreadSafe;
 import javax.management.ObjectName;
 
 import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DependencyResolverFactory;
 import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
+import org.opendaylight.controller.config.spi.Module;
 import org.opendaylight.controller.config.spi.ModuleFactory;
 
+import java.util.HashSet;
+import java.util.Set;
+
 @ThreadSafe
 public class TestingParallelAPSPModuleFactory implements ModuleFactory {
 
@@ -59,4 +64,9 @@ public class TestingParallelAPSPModuleFactory implements ModuleFactory {
             Class<? extends AbstractServiceInterface> serviceInterface) {
         return false;
     }
+
+    @Override
+    public Set<Module> getDefaultModules(DependencyResolverFactory dependencyResolverFactory) {
+        return new HashSet<Module>();
+    }
 }
index c27e01f..29e91fd 100644 (file)
@@ -49,19 +49,20 @@ public class MockedDependenciesTest extends AbstractParallelAPSPTest {
     public static class MockedThreadPoolModule implements Module,
             MockedTestingThreadPoolConfigMXBean,
             TestingThreadPoolServiceInterface {
-        int threadCount;
 
-        public MockedThreadPoolModule() {
-        }
+        private final ModuleIdentifier moduleIdentifier;
+
+        int threadCount;
 
         public MockedThreadPoolModule(
-                DynamicMBeanWithInstance dynamicMBeanWithInstance) {
+                DynamicMBeanWithInstance dynamicMBeanWithInstance, ModuleIdentifier moduleIdentifier) {
             // no reconfiguration / reuse is supported
+            this.moduleIdentifier = moduleIdentifier;
         }
 
         @Override
         public ModuleIdentifier getName() {
-            return new ModuleIdentifier("a", "b");
+            return moduleIdentifier;
         }
 
         @Override
index 8244bc1..c4426d1 100644 (file)
@@ -8,9 +8,12 @@
 package org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool;
 
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DependencyResolverFactory;
 import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
@@ -63,4 +66,8 @@ public class TestingScheduledThreadPoolModuleFactory implements ModuleFactory {
         return configBean;
     }
 
+    @Override
+    public Set<Module> getDefaultModules(DependencyResolverFactory dependencyResolverFactory) {
+        return new HashSet<Module>();
+    }
 }
index ba60b39..2c6ba17 100644 (file)
@@ -8,9 +8,12 @@
 package org.opendaylight.controller.config.manager.testingservices.threadpool;
 
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DependencyResolverFactory;
 import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
@@ -62,4 +65,9 @@ public class TestingFixedThreadPoolModuleFactory implements ModuleFactory {
             Class<? extends AbstractServiceInterface> serviceInterface) {
         return ifc.contains(serviceInterface);
     }
+
+    @Override
+    public Set<Module> getDefaultModules(DependencyResolverFactory dependencyResolverFactory) {
+        return new HashSet<Module>();
+    }
 }
index 867c12c..504c295 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.1-SNAPSHOT</version>
+        <version>0.2.2-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>config-persister-api</artifactId>
@@ -15,7 +15,6 @@
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>config-util</artifactId>
-            <version>0.2.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>com.google.guava</groupId>
index 45683f5..a5c026d 100644 (file)
@@ -6,7 +6,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.1-SNAPSHOT</version>
+        <version>0.2.2-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>config-persister-file-adapter</artifactId>
@@ -18,7 +18,6 @@
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>config-persister-api</artifactId>
-            <version>${project.version}</version>
         </dependency>
         <dependency>
             <groupId>org.apache.commons</groupId>
@@ -37,7 +36,6 @@
         <dependency>
             <groupId>org.opendaylight.bgpcep</groupId>
             <artifactId>mockito-configuration</artifactId>
-            <version>${bgpcep.version}</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
index 443b06c..bf681b1 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.1-SNAPSHOT</version>
+        <version>0.2.2-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>config-util</artifactId>
@@ -16,7 +16,6 @@
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>config-api</artifactId>
-            <version>0.2.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.jolokia</groupId>
index 7b38737..451ac3e 100644 (file)
@@ -6,7 +6,7 @@
     <parent>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>config-subsystem</artifactId>
-        <version>0.2.1-SNAPSHOT</version>
+        <version>0.2.2-SNAPSHOT</version>
     </parent>
     <artifactId>logback-config</artifactId>
     <name>${project.artifactId}</name>
@@ -19,7 +19,6 @@
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>config-api</artifactId>
-            <version>0.2.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
         <dependency>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-classic</artifactId>
-            <version>${logback.version}</version>
         </dependency>
         <dependency>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-core</artifactId>
-            <version>${logback.version}</version>
         </dependency>
 
         <dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>config-manager</artifactId>
-            <version>0.2.1-SNAPSHOT</version>
             <scope>test</scope>
             <type>test-jar</type>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>config-manager</artifactId>
-            <version>0.2.1-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>config-util</artifactId>
-            <version>0.2.1-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.bgpcep</groupId>
             <artifactId>mockito-configuration</artifactId>
-            <version>${bgpcep.version}</version>
             <scope>test</scope>
         </dependency>
         <dependency>
index 1812fbb..1ea922e 100755 (executable)
@@ -10,8 +10,7 @@
     </parent>
 
 
-    <groupId>org.opendaylight.controller</groupId>
-    <version>0.2.1-SNAPSHOT</version>
+    <version>0.2.2-SNAPSHOT</version>
     <artifactId>config-subsystem</artifactId>
     <packaging>pom</packaging>
     <name>${project.artifactId}</name>
                 <artifactId>commons-lang3</artifactId>
                 <version>${commons.lang.version}</version>
             </dependency>
+
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>config-api</artifactId>
+                <version>${config.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>config-util</artifactId>
+                <version>${config.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>config-util</artifactId>
+                <version>${config.version}</version>
+                <type>test-jar</type>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>config-manager</artifactId>
+                <version>${config.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>config-manager</artifactId>
+                <version>${config.version}</version>
+                <type>test-jar</type>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>config-persister-api</artifactId>
+                <version>${config.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.bgpcep</groupId>
+                <artifactId>mockito-configuration</artifactId>
+                <version>${bgpcep.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>binding-generator-spi</artifactId>
+                <version>${opendaylight.binding.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>binding-generator-util</artifactId>
+                <version>${opendaylight.binding.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>yang-parser-impl</artifactId>
+                <version>${opendaylight.yang.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>binding-generator-impl</artifactId>
+                <version>${opendaylight.binding.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>yang-test</artifactId>
+                <version>${config.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.controller</groupId>
+                <artifactId>yang-jmx-generator</artifactId>
+                <version>${config.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.controller</groupId>
+                <artifactId>yang-jmx-generator</artifactId>
+                <version>${config.version}</version>
+                <type>test-jar</type>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>binding-type-provider</artifactId>
+                <version>${opendaylight.binding.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>yang-maven-plugin-spi</artifactId>
+                <version>${opendaylight.yang.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>yang-store-api</artifactId>
+                <version>${config.version}</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 
                 <artifactId>build-helper-maven-plugin</artifactId>
             </plugin>
         </plugins>
+
+
+
         <pluginManagement>
             <plugins>
                 <plugin>
                         <dependency>
                             <groupId>org.opendaylight.controller</groupId>
                             <artifactId>yang-jmx-generator-plugin</artifactId>
-                            <version>0.2.1-SNAPSHOT</version>
+                            <version>${config.version}</version>
                         </dependency>
                     </dependencies>
                 </plugin>
index 6168ea6..336d0c3 100644 (file)
@@ -6,7 +6,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.1-SNAPSHOT</version>
+        <version>0.2.2-SNAPSHOT</version>
     </parent>
 
     <artifactId>yang-jmx-generator-it</artifactId>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>config-api</artifactId>
-            <version>0.2.1-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>yang-test</artifactId>
-            <version>0.2.1-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>config-manager</artifactId>
-            <version>0.2.1-SNAPSHOT</version>
             <scope>test</scope>
             <type>test-jar</type>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>config-manager</artifactId>
-            <version>0.2.1-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>config-util</artifactId>
-            <version>0.2.1-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.bgpcep</groupId>
             <artifactId>mockito-configuration</artifactId>
-            <version>${bgpcep.version}</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
index 48fbe05..eca5037 100644 (file)
@@ -4,10 +4,11 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.1-SNAPSHOT</version>
+        <version>0.2.2-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>yang-jmx-generator-plugin</artifactId>
+
     <dependencies>
 
         <dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>yang-jmx-generator</artifactId>
-            <version>0.2.1-SNAPSHOT</version>
         </dependency>
 
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-maven-plugin-spi</artifactId>
-            <version>${opendaylight.yang.version}</version>
         </dependency>
 
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>binding-type-provider</artifactId>
-            <version>${opendaylight.binding.version}</version>
         </dependency>
 
         <dependency>
@@ -49,7 +47,6 @@
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>config-api</artifactId>
-            <version>0.2.1-SNAPSHOT</version>
         </dependency>
 
         <dependency>
@@ -58,7 +55,6 @@
         </dependency>
 
         <dependency>
-            <!--FIXME two implementations of slf4j on classpath, logback classic from parent-->
             <groupId>com.googlecode.slf4j-maven-plugin-log</groupId>
             <artifactId>slf4j-maven-plugin-log</artifactId>
             <version>1.0.0</version>
@@ -72,7 +68,6 @@
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>yang-jmx-generator</artifactId>
-            <version>0.2.1-SNAPSHOT</version>
             <scope>test</scope>
             <type>test-jar</type>
         </dependency>
@@ -87,7 +82,6 @@
         <dependency>
             <groupId>org.opendaylight.bgpcep</groupId>
             <artifactId>mockito-configuration</artifactId>
-            <version>${bgpcep.version}</version>
             <scope>test</scope>
         </dependency>
 
index adfbceb..5fd1496 100644 (file)
@@ -60,4 +60,9 @@ package ${packageName};
         throw new UnsupportedOperationException("Class reloading is not supported");
     }
 
+    @Override
+    public java.util.Set<${moduleInstanceType}> getDefaultModules(org.opendaylight.controller.config.api.DependencyResolverFactory dependencyResolverFactory) {
+        return new java.util.HashSet<${moduleInstanceType}>();
+    }
+
 }
index 0c2678f..d4e6a22 100644 (file)
@@ -24,14 +24,7 @@ import static org.mockito.Mockito.mock;
 import java.io.File;
 import java.io.IOException;
 import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
@@ -476,8 +469,16 @@ public class JMXGeneratorTest extends AbstractGeneratorTest {
 
         assertEquals(2, fieldDeclarations.size());
 
-        assertEquals("Incorrenct number of generated methods", 5,
-                visitor.methods.size());
+
+        Set<String> expectedMethods = new HashSet<>(Arrays.asList("String getImplementationName()",
+                "org.opendaylight.controller.config.spi.Module createModule(String instanceName,org.opendaylight.controller.config.api.DependencyResolver dependencyResolver)",
+                "org.opendaylight.controller.config.spi.Module createModule(String instanceName,org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,org.opendaylight.controller.config.api.DynamicMBeanWithInstance old)",
+                "org.opendaylight.controller.config.threads.java.NamingThreadFactoryModule handleChangedClass(org.opendaylight.controller.config.api.DynamicMBeanWithInstance old)",
+                "org.opendaylight.controller.config.threads.java.NamingThreadFactoryModule instantiateModule(String instanceName,org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,org.opendaylight.controller.config.threads.java.NamingThreadFactoryModule oldModule,java.lang.AutoCloseable oldInstance)",
+                "org.opendaylight.controller.config.threads.java.NamingThreadFactoryModule instantiateModule(String instanceName,org.opendaylight.controller.config.api.DependencyResolver dependencyResolver)",
+                "java.util.Set<org.opendaylight.controller.config.threads.java.NamingThreadFactoryModule> getDefaultModules(org.opendaylight.controller.config.api.DependencyResolverFactory dependencyResolverFactory)",
+                "boolean isModuleImplementingServiceInterface(Class<? extends org.opendaylight.controller.config.api.annotations.AbstractServiceInterface> serviceInterface)"));
+        assertEquals("Incorrenct number of generated methods", expectedMethods, visitor.methods);
         assertEquals("Incorrenct number of generated method descriptions", 0,
                 visitor.methodDescriptions.size());
         assertEquals("Incorrenct number of generated method javadoc", 0,
@@ -536,8 +537,8 @@ public class JMXGeneratorTest extends AbstractGeneratorTest {
                 visitor.methodDescriptions.size());
         assertEquals("Incorrenct number of generated method javadoc", 3,
                 visitor.methodJavadoc.size());
-        assertNotNull("Missing javadoc for setMaximumSize method",
-                visitor.methodJavadoc.get("setMaximumSize"));
+        assertNotNull("Missing javadoc for setMaximumSize method " + visitor.methodJavadoc,
+                visitor.methodJavadoc.get("void setMaximumSize(java.lang.Long maximumSize)"));
     }
 
     private void assertDeclaredField(Set<String> fieldDeclarations,
@@ -602,7 +603,7 @@ public class JMXGeneratorTest extends AbstractGeneratorTest {
         private String implmts;
         private final Set<String> fieldDeclarations = Sets.newHashSet();
         private final Set<String> constructors = Sets.newHashSet();
-        private final Map<String, String> methods = Maps.newHashMap();
+        private final Set<String> methods = new HashSet<String>();
         private final Map<String, String> requireIfc = Maps.newHashMap();
         private final Map<String, String> methodJavadoc = Maps.newHashMap();
 
@@ -631,10 +632,21 @@ public class JMXGeneratorTest extends AbstractGeneratorTest {
             if (node.isConstructor())
                 constructors.add(node.toString());
             else {
-                String methodName = node.getName().toString();
-                if (node.getJavadoc() != null)
-                    methodJavadoc.put(methodName, node.getJavadoc().toString());
-                methods.put(methodName, node.toString());
+                String methodSignature = node.getReturnType2() + " " + node.getName() + "(";
+                boolean first = true;
+                for (Object o : node.parameters()) {
+                    if (first){
+                        first = false;
+                    } else {
+                        methodSignature += ",";
+                    }
+                    methodSignature += o.toString();
+                }
+                methodSignature += ")";
+                methods.add(methodSignature);
+                if (node.getJavadoc() != null) {
+                    methodJavadoc.put(methodSignature, node.getJavadoc().toString());
+                }
             }
             return super.visit(node);
         }
index 0f7fe6e..3784638 100644 (file)
@@ -6,7 +6,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.1-SNAPSHOT</version>
+        <version>0.2.2-SNAPSHOT</version>
     </parent>
 
     <artifactId>yang-jmx-generator</artifactId>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>binding-generator-spi</artifactId>
-            <version>${opendaylight.binding.version}</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>binding-generator-util</artifactId>
-            <version>${opendaylight.binding.version}</version>
         </dependency>
-
-
         <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
         <dependency>
             <groupId>org.opendaylight.bgpcep</groupId>
             <artifactId>mockito-configuration</artifactId>
-            <version>${bgpcep.version}</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-parser-impl</artifactId>
-            <version>${opendaylight.yang.version}</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>config-api</artifactId>
-            <version>0.2.1-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>binding-generator-impl</artifactId>
-            <version>${opendaylight.binding.version}</version>
             <scope>test</scope>
         </dependency>
         <dependency>
index 4393903..6e850b2 100644 (file)
@@ -4,19 +4,17 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.1-SNAPSHOT</version>
+        <version>0.2.2-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>yang-store-api</artifactId>
     <name>${project.artifactId}</name>
     <packaging>bundle</packaging>
-    <version>${config.yangstore.version}</version>
 
     <dependencies>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>yang-jmx-generator</artifactId>
-            <version>${config.version}</version>
         </dependency>
     </dependencies>
 
index c910526..07ac4d4 100644 (file)
@@ -4,19 +4,17 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.1-SNAPSHOT</version>
+        <version>0.2.2-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>yang-store-impl</artifactId>
     <name>${project.artifactId}</name>
     <packaging>bundle</packaging>
-    <version>${config.yangstore.version}</version>
 
     <dependencies>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>yang-store-api</artifactId>
-            <version>${config.yangstore.version}</version>
         </dependency>
         <dependency>
             <groupId>org.osgi</groupId>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>yang-jmx-generator</artifactId>
-            <version>${config.version}</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>binding-type-provider</artifactId>
-            <version>${opendaylight.binding.version}</version>
         </dependency>
         <dependency>
             <groupId>commons-io</groupId>
@@ -47,7 +43,6 @@
         <dependency>
             <groupId>org.opendaylight.bgpcep</groupId>
             <artifactId>mockito-configuration</artifactId>
-            <version>${bgpcep.version}</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
index 626032f..3de0688 100644 (file)
@@ -5,19 +5,22 @@
     <parent>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>config-subsystem</artifactId>
-        <version>0.2.1-SNAPSHOT</version>
+        <version>0.2.2-SNAPSHOT</version>
     </parent>
 
     <artifactId>yang-test</artifactId>
 
     <description>Artifact that contains only generated code from yang files. Suitable for testing.
     </description>
+    <name>${project.artifactId}</name>
+    <prerequisites>
+        <maven>3.0.4</maven>
+    </prerequisites>
 
     <dependencies>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>config-api</artifactId>
-            <version>0.2.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
         </dependency>
     </dependencies>
 
-    <name>${project.artifactId}</name>
-    <prerequisites>
-        <maven>3.0.4</maven>
-    </prerequisites>
+
 
     <build>
         <plugins>
index 5927d26..81164ae 100644 (file)
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>yang-store-api</artifactId>
-          <version>${config.yangstore.version}</version>
+          <version>${config.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>yang-store-impl</artifactId>
-          <version>${config.yangstore.version}</version>
+          <version>${config.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
index b9f9314..8436a13 100644 (file)
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>yang-store-api</artifactId>
-                <version>${config.yangstore.version}</version>
+                <version>${config.version}</version>
             </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>yang-store-impl</artifactId>
-                <version>${config.yangstore.version}</version>
+                <version>${config.version}</version>
             </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>