Add Set<String> getAvailableModuleFactoryQNames() to config-api. 75/3675/1
authorTomas Olvecky <tolvecky@cisco.com>
Thu, 12 Dec 2013 13:22:58 +0000 (14:22 +0100)
committerTomas Olvecky <tolvecky@cisco.com>
Thu, 12 Dec 2013 13:22:58 +0000 (14:22 +0100)
Allow querying Config Registry and each transaction for set of qnames belonging to ModuleFactory classes.
This is helpful for netconf - allows checking for race conditions between yang store and config-manager.
Modify config code generator to add @ModuleQName annotation to each abstract factory class.

Change-Id: I6e8f972708883137610c09d274d52aedb1380120
Signed-off-by: Tomas Olvecky <tolvecky@cisco.com>
27 files changed:
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ConfigRegistry.java
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/LookupRegistry.java
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/ConfigTransactionLookupRegistry.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImpl.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/factoriesresolver/HierarchicalConfigMBeanFactoriesHolder.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/util/ModuleQNameUtil.java [new file with mode: 0644]
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/ConfigRegistryImplTest.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImplLookupTest.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/testingservices/threadpool/AbstractTestingFixedThreadPoolModuleFactory.java [new file with mode: 0644]
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/TestingFixedThreadPoolModuleFactory.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/test/SimpleConfigurationTest.java
opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigRegistryJMXClient.java
opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigTransactionJMXClient.java
opendaylight/config/config-util/src/test/java/org/opendaylight/controller/config/util/TestingConfigRegistry.java
opendaylight/config/config-util/src/test/java/org/opendaylight/controller/config/util/TestingConfigTransactionController.java
opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/AbstractFactoryTemplate.java
opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/TemplateFactory.java
opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Annotation.java
opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/factory_abs_template.ftl
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntry.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleUtil.java [new file with mode: 0644]
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ServiceInterfaceEntry.java

index 56b96e97bba0ccaad7e45cdd9b2f96dace898c6c..d81c48a6020b6854cc75603a0513a27f8c41da9b 100644 (file)
@@ -62,8 +62,13 @@ public interface ConfigRegistry extends LookupRegistry, ServiceReferenceReadable
      */
     boolean isHealthy();
 
+    /**
+     * @return module factory names available in the system
+     */
     Set<String> getAvailableModuleNames();
 
+
+
     /**
      * Find all runtime beans
      *
index 897547135341a5d60216e6e6b5cabfca5ecc7bce..772617e97d8492898d2e587ba804798cfbd9d643 100644 (file)
@@ -65,4 +65,9 @@ public interface LookupRegistry {
      */
     void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException;
 
+    /**
+     * @return qnames of all ModuleFactory instances in the system
+     */
+    Set<String> getAvailableModuleFactoryQNames();
+
 }
index 18326d91f21b8df58afd905746b2efc606ebb1ce..e3311c747f872f601b0448e01d7e864163a15a75 100644 (file)
@@ -25,6 +25,7 @@ import org.opendaylight.controller.config.manager.impl.jmx.TransactionJMXRegistr
 import org.opendaylight.controller.config.manager.impl.osgi.BeanToOsgiServiceManager;
 import org.opendaylight.controller.config.manager.impl.osgi.BeanToOsgiServiceManager.OsgiRegistration;
 import org.opendaylight.controller.config.manager.impl.util.LookupBeansUtil;
+import org.opendaylight.controller.config.manager.impl.util.ModuleQNameUtil;
 import org.opendaylight.controller.config.spi.Module;
 import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.osgi.framework.BundleContext;
@@ -61,9 +62,6 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
     private final ModuleFactoriesResolver resolver;
     private final MBeanServer configMBeanServer;
 
-    @GuardedBy("this")
-    private final BundleContext bundleContext;
-
     @GuardedBy("this")
     private long version = 0;
     @GuardedBy("this")
@@ -101,6 +99,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
     // internal jmx server shared by all transactions
     private final MBeanServer transactionsMBeanServer;
 
+    // Used for finding new factory instances for default module functionality
     @GuardedBy("this")
     private List<ModuleFactory> lastListOfFactories = Collections.emptyList();
 
@@ -109,18 +108,17 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
 
     // constructor
     public ConfigRegistryImpl(ModuleFactoriesResolver resolver,
-            BundleContext bundleContext, MBeanServer configMBeanServer) {
-        this(resolver, bundleContext, configMBeanServer,
+            MBeanServer configMBeanServer) {
+        this(resolver, configMBeanServer,
                 new BaseJMXRegistrator(configMBeanServer));
     }
 
     // constructor
     public ConfigRegistryImpl(ModuleFactoriesResolver resolver,
-            BundleContext bundleContext, MBeanServer configMBeanServer,
+            MBeanServer configMBeanServer,
             BaseJMXRegistrator baseJMXRegistrator) {
         this.resolver = resolver;
         this.beanToOsgiServiceManager = new BeanToOsgiServiceManager();
-        this.bundleContext = bundleContext;
         this.configMBeanServer = configMBeanServer;
         this.baseJMXRegistrator = baseJMXRegistrator;
         this.registryMBeanServer = MBeanServerFactory
@@ -156,10 +154,10 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
             }
         };
 
-        ConfigTransactionLookupRegistry txLookupRegistry = new ConfigTransactionLookupRegistry(new TransactionIdentifier(
-                transactionName), factory);
         Map<String, Map.Entry<ModuleFactory, BundleContext>> allCurrentFactories = Collections.unmodifiableMap(
                 resolver.getAllFactories());
+        ConfigTransactionLookupRegistry txLookupRegistry = new ConfigTransactionLookupRegistry(new TransactionIdentifier(
+                transactionName), factory, allCurrentFactories);
         ServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry(
                 readableSRRegistry, txLookupRegistry, allCurrentFactories);
 
@@ -550,6 +548,12 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
     public synchronized String getServiceInterfaceName(String namespace, String localName) {
         return readableSRRegistry.getServiceInterfaceName(namespace, localName);
     }
+
+    @Override
+    public Set<String> getAvailableModuleFactoryQNames() {
+        return ModuleQNameUtil.getQNames(resolver.getAllFactories());
+    }
+
 }
 
 /**
@@ -607,6 +611,8 @@ class ConfigHolder {
         Collections.sort(result);
         return result;
     }
+
+
 }
 
 /**
index 36485b1abfe032d27f57169310cea285233b959b..17ce0781546e231a5f81b2a8ca1b276f5a046d74 100644 (file)
@@ -33,13 +33,13 @@ import javax.management.InstanceAlreadyExistsException;
 import javax.management.InstanceNotFoundException;
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
+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.ArrayList;
-import java.util.Collection;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import static java.lang.String.format;
@@ -576,4 +576,9 @@ class ConfigTransactionControllerImpl implements
         return txLookupRegistry.getTransactionIdentifier();
     }
 
+    @Override
+    public Set<String> getAvailableModuleFactoryQNames() {
+        return txLookupRegistry.getAvailableModuleFactoryQNames();
+    }
+
 }
index 5d1f0b39760b3453a0e1fc9f6b34f0bd15a939d3..12db6c8f89e489114d0ad96b3e5e88ed1a97a4f3 100644 (file)
@@ -12,11 +12,16 @@ import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 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.util.LookupBeansUtil;
+import org.opendaylight.controller.config.manager.impl.util.ModuleQNameUtil;
+import org.opendaylight.controller.config.spi.ModuleFactory;
+import org.osgi.framework.BundleContext;
 
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.InstanceNotFoundException;
 import javax.management.ObjectName;
 import java.io.Closeable;
+import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 
 /**
@@ -27,12 +32,14 @@ class ConfigTransactionLookupRegistry  implements LookupRegistry, Closeable {
     private final TransactionJMXRegistrator transactionJMXRegistrator;
     private final TransactionIdentifier transactionIdentifier;
     private final TransactionModuleJMXRegistrator txModuleJMXRegistrator;
+    private final Map<String, Map.Entry<ModuleFactory, BundleContext>> allCurrentFactories;
 
     ConfigTransactionLookupRegistry(TransactionIdentifier transactionIdentifier,
-                                    TransactionJMXRegistratorFactory factory) {
+                                    TransactionJMXRegistratorFactory factory, Map<String, Entry<ModuleFactory, BundleContext>> allCurrentFactories) {
         this.transactionIdentifier = transactionIdentifier;
         this.transactionJMXRegistrator = factory.create();
         this.txModuleJMXRegistrator = transactionJMXRegistrator.createTransactionModuleJMXRegistrator();
+        this.allCurrentFactories = allCurrentFactories;
     }
 
     private void checkTransactionName(ObjectName objectName) {
@@ -104,6 +111,12 @@ class ConfigTransactionLookupRegistry  implements LookupRegistry, Closeable {
     public void registerMBean(ConfigTransactionControllerInternal transactionController, ObjectName controllerObjectName) throws InstanceAlreadyExistsException {
         transactionJMXRegistrator.registerMBean(transactionController, controllerObjectName);
     }
+
+    @Override
+    public Set<String> getAvailableModuleFactoryQNames() {
+        return ModuleQNameUtil.getQNames(allCurrentFactories);
+    }
+
 }
 
 interface TransactionJMXRegistratorFactory {
index 2fd1ca6c2c617777901857b98fdb5ea50613a186..7fedcdf71ce7ce28974cc06a1e72c42720b04248 100644 (file)
@@ -75,6 +75,11 @@ public class ServiceReferenceRegistryImpl implements ServiceReferenceReadableReg
             public void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException {
                 throw new InstanceNotFoundException("Cannot find " + objectName);
             }
+
+            @Override
+            public Set<String> getAvailableModuleFactoryQNames() {
+                throw new UnsupportedOperationException();
+            }
         };
         return new ServiceReferenceRegistryImpl(Collections.<String, ModuleFactory>emptyMap(), lookupRegistry,
                 Collections.<String /* qName */, Map<String /* refName */, ModuleIdentifier>>emptyMap());
index f82a7295aaeaa47e4e7169e86dd5452666a7fd16..16f7cf024a40958118467641736eae6ebecfcd98 100644 (file)
@@ -13,6 +13,7 @@ import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Map.Entry;
 import java.util.Set;
 import java.util.List;
 import java.util.Map;
@@ -76,4 +77,7 @@ public class HierarchicalConfigMBeanFactoriesHolder {
         return moduleFactories;
     }
 
+    public Map<String, Entry<ModuleFactory, BundleContext>> getModuleNamesToConfigBeanFactories() {
+        return moduleNamesToConfigBeanFactories;
+    }
 }
index ab81143170b91d3c4565049539b16bc410469abe..1ee6cca7e22f86b1eb634b3c94c71ee503cd1a84 100644 (file)
@@ -36,8 +36,7 @@ public class ConfigManagerActivator implements BundleActivator {
                 new BundleContextBackedModuleFactoriesResolver(context);
         MBeanServer configMBeanServer = ManagementFactory.getPlatformMBeanServer();
         configRegistry = new ConfigRegistryImpl(
-                bundleContextBackedModuleFactoriesResolver, context,
-                configMBeanServer);
+                bundleContextBackedModuleFactoriesResolver, configMBeanServer);
 
         // register config registry to OSGi
         configRegistryServiceRegistration = context.registerService(ConfigRegistryImpl.class, configRegistry, null);
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/ModuleQNameUtil.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/ModuleQNameUtil.java
new file mode 100644 (file)
index 0000000..e843377
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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.util;
+
+import org.opendaylight.controller.config.spi.ModuleFactory;
+import org.opendaylight.yangtools.yang.binding.annotations.ModuleQName;
+import org.osgi.framework.BundleContext;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+public class ModuleQNameUtil {
+
+    public static Set<String> getQNames(Map<String, Entry<ModuleFactory, BundleContext>> resolved) {
+        Set<String> result = new HashSet<>();
+        for (Entry<ModuleFactory, BundleContext> entry : resolved.values()) {
+            Class<?> inspected = entry.getKey().getClass();
+            if (inspected.isInterface()) {
+                throw new IllegalArgumentException("Unexpected interface " + inspected);
+            }
+            ModuleQName annotation = null;
+            while(annotation == null && inspected != null) {
+                annotation = inspected.getAnnotation(ModuleQName.class);
+                inspected = inspected.getSuperclass();
+            }
+            if (annotation != null) {
+                // FIXME
+                String qName = "(" + annotation.namespace() + "?revision=" + annotation.revision() + ")" + annotation.name();
+                result.add(qName);
+            }
+        }
+        return result;
+    }
+
+}
index ccb67d371e5e63b9abac0be0a6baeba85f9a352b..e6b07bab645fff3e4e0fe2e781dbafad457e964f 100644 (file)
@@ -40,7 +40,7 @@ public class ConfigRegistryImplTest extends
                     factory, factory);
 
             configRegistry = new ConfigRegistryImpl(resolver,
-                    context, ManagementFactory.getPlatformMBeanServer());
+                    ManagementFactory.getPlatformMBeanServer());
 
             configRegistry.beginConfig();
             fail();
index 5ed56bd2bf6f81081be3369a9fa7ffc848c33ace..a7e3fa6c6fa29343f62bffb163fb35719aadae88 100644 (file)
@@ -70,7 +70,7 @@ public abstract class AbstractConfigTest extends
         internalJmxRegistrator = new InternalJMXRegistrator(platformMBeanServer);
         baseJmxRegistrator = new BaseJMXRegistrator(internalJmxRegistrator);
 
-        configRegistry = new ConfigRegistryImpl(resolver, mockedContext,
+        configRegistry = new ConfigRegistryImpl(resolver,
                 platformMBeanServer, baseJmxRegistrator);
         try {
             configRegistryJMXRegistrator.registerToJMX(configRegistry);
index 6dddc62f67914c989f22e2cace7e4df08918dadc..a522356a276fe1bb39f1289b9bb8c65915d81039 100644 (file)
@@ -66,7 +66,7 @@ public class ConfigRegistryImplLookupTest extends
 
     @Before
     public void setUp() throws Exception {
-        configRegistryImpl = new ConfigRegistryImpl(null, null,
+        configRegistryImpl = new ConfigRegistryImpl(null,
                 ManagementFactory.getPlatformMBeanServer());
         Field field = configRegistryImpl.getClass().getDeclaredField(
                 "baseJMXRegistrator");
index 43c75ef1e7b2b1797415fa196b00f6370e3eec0d..50f5742149176ef0052235593651392d57f72541 100644 (file)
@@ -68,7 +68,7 @@ public class ConfigTransactionControllerImplTest extends
             public TransactionJMXRegistrator create() {
                 return baseJMXRegistrator.createTransactionJMXRegistrator(transactionName123);
             }
-        });
+        }, currentlyRegisteredFactories);
 
         ServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry(
                 ServiceReferenceRegistryImpl.createInitialSRLookupRegistry(), txLookupRegistry, currentlyRegisteredFactories);
diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/AbstractTestingFixedThreadPoolModuleFactory.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/AbstractTestingFixedThreadPoolModuleFactory.java
new file mode 100644 (file)
index 0000000..0286400
--- /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.manager.testingservices.threadpool;
+
+import org.opendaylight.yangtools.yang.binding.annotations.ModuleQName;
+
+@ModuleQName(namespace = "namespace", revision = "revision", name = "name")
+public abstract class AbstractTestingFixedThreadPoolModuleFactory {
+}
index b749ea751151e2280d06938e4708c61ce62ddc23..bec28685576aba673422c32222acafc6aca34a23 100644 (file)
@@ -23,7 +23,7 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 
-public class TestingFixedThreadPoolModuleFactory implements ModuleFactory {
+public class TestingFixedThreadPoolModuleFactory extends AbstractTestingFixedThreadPoolModuleFactory implements ModuleFactory {
     public static final String NAME = "fixed";
 
     private static Set<Class<? extends AbstractServiceInterface>> ifc = Collections.unmodifiableSet(Sets.newHashSet(
index 13bb84040a10d7d7e4bc4aabfde2401408f11c5b..441de36db07655558a3f882e7ebbb9ba929e964f 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.controller.config.manager.testingservices.threadpool.test;
 
+import com.google.common.collect.Sets;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -34,6 +35,7 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ThreadPoolExecutor;
 
 import static org.junit.Assert.assertEquals;
@@ -384,4 +386,11 @@ public class SimpleConfigurationTest extends AbstractConfigTest {
     }
 
 
+    @Test
+    public void testQNames() {
+        Set<String> availableModuleFactoryQNames = configRegistryClient.getAvailableModuleFactoryQNames();
+        String expected = "(namespace?revision=revision)name";
+        assertEquals(Sets.newHashSet(expected), availableModuleFactoryQNames);
+    }
+
 }
index 4ecc7c3a5c572cfc50fb2a90ef5b08bf35a7d537..8badb75f05c26f0082f00b627eedd91836bd28d5 100644 (file)
@@ -7,10 +7,11 @@
  */
 package org.opendaylight.controller.config.util;
 
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import org.opendaylight.controller.config.api.ConflictingVersionException;
+import org.opendaylight.controller.config.api.ValidationException;
+import org.opendaylight.controller.config.api.jmx.CommitStatus;
+import org.opendaylight.controller.config.api.jmx.ConfigRegistryMXBean;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 
 import javax.management.AttributeNotFoundException;
 import javax.management.InstanceNotFoundException;
@@ -21,12 +22,10 @@ import javax.management.MBeanServer;
 import javax.management.ObjectInstance;
 import javax.management.ObjectName;
 import javax.management.ReflectionException;
-
-import org.opendaylight.controller.config.api.ConflictingVersionException;
-import org.opendaylight.controller.config.api.ValidationException;
-import org.opendaylight.controller.config.api.jmx.CommitStatus;
-import org.opendaylight.controller.config.api.jmx.ConfigRegistryMXBean;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 public class ConfigRegistryJMXClient implements ConfigRegistryClient {
     private final ConfigRegistryMXBean configRegistryMXBeanProxy;
@@ -198,4 +197,8 @@ public class ConfigRegistryJMXClient implements ConfigRegistryClient {
         }
     }
 
+    @Override
+    public Set<String> getAvailableModuleFactoryQNames() {
+        return configRegistryMXBeanProxy.getAvailableModuleFactoryQNames();
+    }
 }
index bd6f6fa884fe0521bff93d8e0fc665e78c529dd7..0db1e5b8224761bc8dbb091f22c1513cf6d5216a 100644 (file)
@@ -233,4 +233,9 @@ public class ConfigTransactionJMXClient implements ConfigTransactionClient {
                     + attrName + " for " + on, e);
         }
     }
+
+    @Override
+    public Set<String> getAvailableModuleFactoryQNames() {
+        return configTransactionControllerMXBeanProxy.getAvailableModuleFactoryQNames();
+    }
 }
index ba6262780c5767ae206a712a4eeb076b19832aaf..65341714df22e7e13315fbcbd6ca44120bf74664 100644 (file)
@@ -173,4 +173,9 @@ public class TestingConfigRegistry implements ConfigRegistryMXBean {
     public String getServiceInterfaceName(String namespace, String localName) {
         throw new UnsupportedOperationException();
     }
+
+    @Override
+    public Set<String> getAvailableModuleFactoryQNames() {
+        throw new UnsupportedOperationException();
+    }
 }
index 1c522f17b03803cf758829d5fd9a37472732b25d..44eb73af79e9c098b343ec7a4debb995e6e44337 100644 (file)
@@ -160,4 +160,9 @@ public class TestingConfigTransactionController implements
     public boolean removeServiceReferences(ObjectName objectName) throws InstanceNotFoundException {
         throw new UnsupportedOperationException();
     }
+
+    @Override
+    public Set<String> getAvailableModuleFactoryQNames() {
+        throw new UnsupportedOperationException();
+    }
 }
index 47b68ebf9a86c0447c25d503fe87dfd7f0102e4e..35dc7a36007c8fb31a0ecc05239b1b8986335c07 100644 (file)
@@ -14,6 +14,7 @@ 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 org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Constructor;
 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Field;
 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Header;
@@ -33,11 +34,12 @@ public class AbstractFactoryTemplate extends GeneralClassTemplate {
 
     private final String globallyUniqueName, moduleInstanceType;
     private final List<String> providedServices;
+    private final ModuleMXBeanEntry mbe;
 
     public AbstractFactoryTemplate(Header header, String packageName,
-            String abstractFactoryName, String globallyUniqueName,
-            String moduleInstanceType, List<Field> fields,
-            List<String> providedServices) {
+                                   String abstractFactoryName, String globallyUniqueName,
+                                   String moduleInstanceType, List<Field> fields,
+                                   List<String> providedServices, ModuleMXBeanEntry mbe) {
         super(header, packageName, abstractFactoryName, Collections
                 .<String> emptyList(), implementedIfcs, fields, Collections
                 .<MethodDefinition> emptyList(), true, false, Collections
@@ -45,6 +47,7 @@ public class AbstractFactoryTemplate extends GeneralClassTemplate {
         this.globallyUniqueName = globallyUniqueName;
         this.moduleInstanceType = moduleInstanceType;
         this.providedServices = providedServices;
+        this.mbe = mbe;
     }
 
     public String getGloballyUniqueName() {
@@ -92,4 +95,7 @@ public class AbstractFactoryTemplate extends GeneralClassTemplate {
         return "factory_abs_template.ftl";
     }
 
+    public ModuleMXBeanEntry getMbe() {
+        return mbe;
+    }
 }
index 115bb85b618020b61282c83c3c692c9dafca6251..28e0256c05b0cbd055636aa8cf391be97fba6d21 100644 (file)
@@ -210,8 +210,7 @@ public class TemplateFactory {
             sieTemplate.getAnnotations().add(
                     Annotation.createDescriptionAnnotation(sie
                             .getNullableDescription()));
-        sieTemplate.getAnnotations().add(Annotation.createSieAnnotation(sie.getQName(), sie.getExportedOsgiClassName
-                ()));
+        sieTemplate.getAnnotations().addAll(Annotation.createSieAnnotations(sie));
 
         return sieTemplate;
     }
@@ -236,7 +235,7 @@ public class TemplateFactory {
                 mbe.getPackageName(), mbe.getAbstractFactoryName(),
                 mbe.getGloballyUniqueName(), mbe.getFullyQualifiedName(mbe
                         .getStubModuleName()), attrProcessor.getFields(),
-                Lists.newArrayList(transformed));
+                Lists.newArrayList(transformed), mbe);
     }
 
     public static AbstractModuleTemplate abstractModuleTemplateFromMbe(
index 59368e8e498754b559096425c75eb0b45f5af058..7cf241725d78674cd6f7ca9e16aa3cebcc0f7be4 100644 (file)
@@ -7,13 +7,15 @@
  */
 package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model;
 
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 
 import org.opendaylight.controller.config.api.annotations.Description;
 import org.opendaylight.controller.config.api.annotations.RequireInterface;
 import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
+import org.opendaylight.yangtools.yang.binding.annotations.ModuleQName;
 import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry;
-import org.opendaylight.yangtools.yang.common.QName;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
@@ -42,22 +44,36 @@ public class Annotation {
                 Lists.newArrayList(new Parameter("value", q(description))));
     }
 
-    public static Annotation createSieAnnotation(QName qname,
-            String exportedClassName) {
-        Preconditions.checkNotNull(qname,
+    public static Collection<Annotation> createSieAnnotations(ServiceInterfaceEntry sie){
+
+        String exportedClassName = sie.getExportedOsgiClassName();
+        Preconditions.checkNotNull(sie.getQName(),
                 "Cannot create annotation from null qname");
         Preconditions.checkNotNull(exportedClassName,
                 "Cannot create annotation from null exportedClassName");
+        List<Annotation> result = new ArrayList<>();
+        {
+            List<Parameter> params = Lists.newArrayList(new Parameter("value", q(sie.getQName().toString())));
+            params.add(new Parameter("osgiRegistrationType", exportedClassName + ".class"));
 
-        List<Parameter> params = Lists.newArrayList(new Parameter("value", q(qname.toString())));
-        params.add(new Parameter("osgiRegistrationType", exportedClassName + ".class"));
+            params.add(new Parameter("namespace", q(sie.getQName().getNamespace().toString())));
+            params.add(new Parameter("revision", q(sie.getQName().getFormattedRevision())));
+            params.add(new Parameter("localName", q(sie.getQName().getLocalName())));
 
-        params.add(new Parameter("namespace", q(qname.getNamespace().toString())));
-        params.add(new Parameter("revision", q(qname.getFormattedRevision())));
-        params.add(new Parameter("localName", q(qname.getLocalName())));
+            Annotation sieAnnotation = new Annotation(ServiceInterfaceAnnotation.class.getCanonicalName(), params);
+            result.add(sieAnnotation);
 
-        return new Annotation(
-                ServiceInterfaceAnnotation.class.getCanonicalName(), params);
+        }
+        {
+            List<Parameter> params = new ArrayList<>();
+            params.add(new Parameter("namespace", q(sie.getYangModuleQName().getNamespace().toString())));
+            params.add(new Parameter("revision", q(sie.getYangModuleQName().getFormattedRevision())));
+            params.add(new Parameter("name", q(sie.getYangModuleQName().getLocalName())));
+
+            Annotation moduleQNameAnnotation = new Annotation(ModuleQName.class.getCanonicalName(), params);
+            result.add(moduleQNameAnnotation);
+        }
+        return result;
     }
 
     public static Annotation createRequireIfcAnnotation(
index 37fd05bc5232eb85c51f0bc0c4e071f440e185d8..b9bbf1f1b564fdc9e8238d30e486ed6234190b69 100644 (file)
@@ -2,6 +2,7 @@
 package ${packageName};
 
 <@javadocD object=javadoc/>
+@org.opendaylight.yangtools.yang.binding.annotations.ModuleQName(namespace="${mbe.getYangModuleQName().getNamespace().toString()}",revision="${mbe.getYangModuleQName().getFormattedRevision()}",name="${mbe.getYangModuleQName().getLocalName()}")
 <@typeDeclarationD object=typeDeclaration/>
 {
 
index 4eba739b469d52b675b7208e0621c9ddc9f4a845..869488e777350e08106d786e85fd648f5c1028a3 100644 (file)
@@ -136,11 +136,13 @@ public class ModuleMXBeanEntry extends AbstractEntry {
     private final Map<String, QName> providedServices;
 
     private Collection<RuntimeBeanEntry> runtimeBeans;
+    private final QName yangModuleQName;
 
     public ModuleMXBeanEntry(IdentitySchemaNode id,
             Map<String, AttributeIfc> yangToAttributes, String packageName,
             Map<String, QName> providedServices2, String javaNamePrefix,
-            String namespace, Collection<RuntimeBeanEntry> runtimeBeans) {
+            String namespace, Collection<RuntimeBeanEntry> runtimeBeans,
+            QName yangModuleQName) {
         this.globallyUniqueName = id.getQName().getLocalName();
         this.yangToAttributes = yangToAttributes;
         this.nullableDescription = id.getDescription();
@@ -149,6 +151,7 @@ public class ModuleMXBeanEntry extends AbstractEntry {
         this.namespace = checkNotNull(namespace);
         this.providedServices = Collections.unmodifiableMap(providedServices2);
         this.runtimeBeans = runtimeBeans;
+        this.yangModuleQName = yangModuleQName;
     }
 
     public String getMXBeanInterfaceName() {
@@ -395,7 +398,8 @@ public class ModuleMXBeanEntry extends AbstractEntry {
                                 moduleIdentity, yangToAttributes, packageName,
                                 providedServices, javaNamePrefix, currentModule
                                         .getNamespace().toString(),
-                                runtimeBeans);
+                                runtimeBeans,
+                                ModuleUtil.getQName(currentModule));
                         moduleMXBeanEntry.setYangModuleName(currentModule
                                 .getName());
                         moduleMXBeanEntry
@@ -730,6 +734,10 @@ public class ModuleMXBeanEntry extends AbstractEntry {
         return nullableDescription;
     }
 
+    public QName getYangModuleQName() {
+        return yangModuleQName;
+    }
+
     @Override
     public String toString() {
         return "ModuleMXBeanEntry{" + "globallyUniqueName='"
diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleUtil.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleUtil.java
new file mode 100644 (file)
index 0000000..5fea8fd
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * 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.yangjmxgenerator;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.Module;
+
+public class ModuleUtil {
+
+    public static QName getQName(Module currentModule){
+        return new QName(currentModule.getNamespace(), currentModule.getRevision(), currentModule.getName());
+    }
+}
index 71cd0900eb6f985521257cc552faead563f8eba1..aa2d6a5d7f044dde8d84b49fff2d8fa3ed28f383 100644 (file)
@@ -57,13 +57,14 @@ public class ServiceInterfaceEntry extends AbstractEntry {
     private final String exportedOsgiClassName;
     private final QName qName;
     private final String nullableDescription, packageName, typeName;
+    private final QName yangModuleQName;
 
-    private ServiceInterfaceEntry(IdentitySchemaNode id, String packageName) {
-        this(Optional.<ServiceInterfaceEntry> absent(), id, packageName);
+    private ServiceInterfaceEntry(IdentitySchemaNode id, String packageName, QName yangModuleQName) {
+        this(Optional.<ServiceInterfaceEntry> absent(), id, packageName, yangModuleQName);
     }
 
     private ServiceInterfaceEntry(Optional<ServiceInterfaceEntry> base,
-            IdentitySchemaNode id, String packageName) {
+            IdentitySchemaNode id, String packageName, QName yangModuleQName) {
         checkNotNull(base);
         this.maybeBaseCache = base;
         List<UnknownSchemaNode> unknownSchemaNodes = id.getUnknownSchemaNodes();
@@ -93,6 +94,7 @@ public class ServiceInterfaceEntry extends AbstractEntry {
         nullableDescription = id.getDescription();
         typeName = getSimpleName(exportedOsgiClassName) + CLASS_NAME_SUFFIX;
         this.packageName = packageName;
+        this.yangModuleQName = yangModuleQName;
     }
 
     private static final String getSimpleName(String fullyQualifiedName) {
@@ -120,14 +122,14 @@ public class ServiceInterfaceEntry extends AbstractEntry {
      * @return Map of QNames as keys and ServiceInterfaceEntry instances as
      *         values
      */
-    public static Map<QName, ServiceInterfaceEntry> create(Module module,
+    public static Map<QName, ServiceInterfaceEntry> create(Module currentModule,
             String packageName) {
         logger.debug("Generating ServiceInterfaces from {} to package {}",
-                module.getNamespace(), packageName);
+                currentModule.getNamespace(), packageName);
 
         Map<IdentitySchemaNode, ServiceInterfaceEntry> identitiesToSIs = new HashMap<>();
         Set<IdentitySchemaNode> notVisited = new HashSet<>(
-                module.getIdentities());
+                currentModule.getIdentities());
         int lastSize = notVisited.size() + 1;
         while (notVisited.size() > 0) {
             if (notVisited.size() == lastSize) {
@@ -148,18 +150,18 @@ public class ServiceInterfaceEntry extends AbstractEntry {
                 } else if (identity.getBaseIdentity().getQName()
                         .equals(SERVICE_TYPE_Q_NAME)) {
                     // this is a base type
-                    created = new ServiceInterfaceEntry(identity, packageName);
+                    created = new ServiceInterfaceEntry(identity, packageName, ModuleUtil.getQName(currentModule));
                 } else {
                     ServiceInterfaceEntry foundBase = identitiesToSIs
                             .get(identity.getBaseIdentity());
                     // derived type, did we convert the parent?
                     if (foundBase != null) {
                         created = new ServiceInterfaceEntry(
-                                Optional.of(foundBase), identity, packageName);
+                                Optional.of(foundBase), identity, packageName, ModuleUtil.getQName(currentModule));
                     }
                 }
                 if (created != null) {
-                    created.setYangModuleName(module.getName());
+                    created.setYangModuleName(currentModule.getName());
                     // TODO how to get local name
                     created.setYangModuleLocalname(identity.getQName()
                             .getLocalName());
@@ -190,6 +192,10 @@ public class ServiceInterfaceEntry extends AbstractEntry {
         return typeName;
     }
 
+    public QName getYangModuleQName() {
+        return yangModuleQName;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o)