Persist service references as separate MBeans. 46/3746/3
authorTomas Olvecky <tolvecky@cisco.com>
Mon, 16 Dec 2013 10:39:41 +0000 (11:39 +0100)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 17 Dec 2013 01:31:54 +0000 (01:31 +0000)
Create dummy MBean - ServiceReferenceMXBean - that contains link to implementation of the service as an attribute.
Add support for resolving of SR to dependency resolver. Each time user saves SR, create MBean and
add the interface QName together with user defined reference name to ObjectName of the newly created SR MBean.

Change-Id: I71ddb762e00d9be8b426fb979ff5ade046d46050
Signed-off-by: Tomas Olvecky <tolvecky@cisco.com>
36 files changed:
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ConfigTransactionController.java
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/LookupRegistry.java
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ServiceReferenceReadableRegistry.java
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ServiceReferenceWritableRegistry.java
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/jmx/ObjectNameUtil.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/CloseableServiceReferenceReadableRegistry.java [new file with mode: 0644]
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/ModuleInternalInfo.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/dependencyresolver/DependencyResolverImpl.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/jmx/BaseJMXRegistrator.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/NestableJMXRegistrator.java [new file with mode: 0644]
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReference.java [new file with mode: 0644]
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReferenceMXBean.java [new file with mode: 0644]
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReferenceMXBeanImpl.java [new file with mode: 0644]
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReferenceRegistrator.java [new file with mode: 0644]
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/TransactionModuleJMXRegistrator.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/ServiceReferenceRegistryImplTest.java [new file with mode: 0644]
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManagerTest.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/util/ObjectNameUtilTest.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/TestingParallelAPSPModule.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/AbstractParallelAPSPTest.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/DependentWiringTest.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/TestingScheduledThreadPoolConfigBeanMXBean.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/scheduledthreadpool/TestingScheduledThreadPoolModule.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/seviceinterface/TestingThreadPoolServiceInterface.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/resources/freeMarker/module_abs_template_new.ftl

index c257e55dc088b7b7d80bb99fea333e5aacc33c6e..264751318c3570415f412a82b4df7d992853c451 100644 (file)
@@ -16,7 +16,7 @@ import javax.management.ObjectName;
 /**
  * Represents functionality provided by configuration transaction.
  */
-public interface ConfigTransactionController extends LookupRegistry, ServiceReferenceReadableRegistry, ServiceReferenceWritableRegistry {
+public interface ConfigTransactionController extends LookupRegistry, ServiceReferenceWritableRegistry {
 
     /**
      * Create new configuration bean.
index 772617e97d8492898d2e587ba804798cfbd9d643..376ecdb52a2f7324a1c5a9d02e2c9dea3f871a80 100644 (file)
@@ -65,8 +65,9 @@ public interface LookupRegistry {
      */
     void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException;
 
+
     /**
-     * @return qnames of all ModuleFactory instances in the system
+     * @return qNames of all ModuleFactory instances in the system
      */
     Set<String> getAvailableModuleFactoryQNames();
 
index f84fcd48c9b871913554b26d18b2ef8b945f48f5..d7e94e8a7631d64a55eb43729cfc83d6bd823e6a 100644 (file)
@@ -16,24 +16,24 @@ public interface ServiceReferenceReadableRegistry {
 
     /**
      * Lookup object name by fully qualified service interface name and service reference name.
-     * @param serviceInterfaceName service interface name
+     * @param serviceInterfaceQName service interface name
      * @param refName service reference name supplied in
      * {@link org.opendaylight.controller.config.api.ConfigTransactionController#saveServiceReference(String, String, javax.management.ObjectName)}
      * @throws java.lang.IllegalArgumentException if module not found
      */
-    ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName);
+    ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName);
 
     /**
      * Get mapping of services to reference names and module object names.
      */
-    Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> getServiceMapping();
+    Map<String /* serviceInterfaceQName */, Map<String/* refName */, ObjectName>> getServiceMapping();
 
     /**
      * Get current mapping between reference names and module object names for given service interface name.
-     * @param serviceInterfaceName service interface name
+     * @param serviceInterfaceQName service interface name
      * @throws IllegalArgumentException if there is a mismatch between serviceInterfaceName and objectName
      */
-    Map<String /* refName */, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName);
+    Map<String /* refName */, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName);
 
     /**
      * Find all available service interface names of a module.
@@ -50,4 +50,13 @@ public interface ServiceReferenceReadableRegistry {
      */
     String getServiceInterfaceName(String namespace, String localName);
 
+    /**
+     * @return ObjectName with type=Service that was created using
+     * {@link org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry#saveServiceReference(String, String,
+     * javax.management.ObjectName)}
+     */
+    ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException;
+
+    void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException;
+
 }
index f3d6d16d6c1e0660874551785f443fe18976089c..fa2aa1f56e0d1fe5eef418038ccd3c39a80260a7 100644 (file)
@@ -13,17 +13,18 @@ import javax.management.ObjectName;
 public interface ServiceReferenceWritableRegistry extends ServiceReferenceReadableRegistry {
     /**
      * Create or update reference name to objectName. Reference name is unique per service interface name.
+     * @return created or updated object name containing service name and reference name
      * @throws IllegalArgumentException if there is a mismatch between serviceInterfaceName and objectName
      * @throws InstanceNotFoundException if search did not find exactly one instance
      */
-    void saveServiceReference(String serviceInterfaceName, String refName, ObjectName objectName) throws InstanceNotFoundException;
+    ObjectName saveServiceReference(String serviceInterfaceName, String refName, ObjectName moduleON) throws InstanceNotFoundException;
 
     /**
      * Remove service reference.
      * @return true iif removed
      * @throws IllegalArgumentException if service interface name is not advertised by any module
      */
-    boolean removeServiceReference(String serviceInterfaceName, String refName);
+    void removeServiceReference(String serviceInterfaceName, String refName) throws InstanceNotFoundException;
 
     /**
      * Remove all service references.
index cc1d89761c2ef8784b6f79019101fa76a21361c1..3baa1039e0bd1c868c28b6d8d5f7ea35c8da3dc7 100644 (file)
@@ -25,21 +25,23 @@ import java.util.Set;
  * is defined as {@link #ON_DOMAIN} and at least one key-value pair. The only
  * mandatory property is {@link #TYPE_KEY}. All transaction related mbeans have
  * {@link #TRANSACTION_NAME_KEY} property set.
- *
  */
 @ThreadSafe
 public class ObjectNameUtil {
 
     public static final String ON_DOMAIN = ConfigRegistryConstants.ON_DOMAIN;
     public static final String MODULE_FACTORY_NAME_KEY = "moduleFactoryName";
+    public static final String SERVICE_QNAME_KEY = "serviceQName";
     public static final String INSTANCE_NAME_KEY = "instanceName";
     public static final String TYPE_KEY = ConfigRegistryConstants.TYPE_KEY;
     public static final String TYPE_CONFIG_REGISTRY = ConfigRegistryConstants.TYPE_CONFIG_REGISTRY;
     public static final String TYPE_CONFIG_TRANSACTION = "ConfigTransaction";
     public static final String TYPE_MODULE = "Module";
+    public static final String TYPE_SERVICE_REFERENCE = "ServiceReference";
     public static final String TYPE_RUNTIME_BEAN = "RuntimeBean";
-
     public static final String TRANSACTION_NAME_KEY = "TransactionName";
+    public static final String REF_NAME_KEY = "RefName";
+    private static final String REPLACED_QUOTATION_MARK = "\\?";
 
     public static ObjectName createON(String on) {
         try {
@@ -57,10 +59,10 @@ public class ObjectNameUtil {
         return ConfigRegistryConstants.createON(name, key, value);
     }
 
-    public static ObjectName createON(String name, Map<String, String> attribs) {
+    public static ObjectName createON(String domain, Map<String, String> attribs) {
         Hashtable<String, String> table = new Hashtable<>(attribs);
         try {
-            return new ObjectName(name, table);
+            return new ObjectName(domain, table);
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
@@ -76,21 +78,21 @@ public class ObjectNameUtil {
     }
 
     public static ObjectName createTransactionModuleON(String transactionName,
-            ModuleIdentifier moduleIdentifier) {
+                                                       ModuleIdentifier moduleIdentifier) {
         return createTransactionModuleON(transactionName,
                 moduleIdentifier.getFactoryName(),
                 moduleIdentifier.getInstanceName());
     }
 
     public static ObjectName createTransactionModuleON(String transactionName,
-            String moduleName, String instanceName) {
-        Map<String, String> onParams = createModuleON(moduleName, instanceName);
+                                                       String moduleName, String instanceName) {
+        Map<String, String> onParams = createModuleMap(moduleName, instanceName);
         onParams.put(TRANSACTION_NAME_KEY, transactionName);
         return createON(ON_DOMAIN, onParams);
     }
 
     public static ObjectName createTransactionModuleON(String transactionName,
-            ObjectName on) {
+                                                       ObjectName on) {
         return createTransactionModuleON(transactionName, getFactoryName(on),
                 getInstanceName(on));
     }
@@ -101,14 +103,73 @@ public class ObjectNameUtil {
                 moduleIdentifier.getInstanceName());
     }
 
+    public static ObjectName createReadOnlyServiceON(String serviceQName, String refName) {
+        Map<String, String> onParams = createServiceMap(serviceQName, refName);
+        return createON(ON_DOMAIN, onParams);
+    }
+
+    public static ObjectName createTransactionServiceON(String transactionName, String serviceQName, String refName) {
+        Map<String, String> onParams = createServiceON(transactionName, serviceQName, refName);
+        return createON(ON_DOMAIN, onParams);
+    }
+
+    public static String getServiceQName(ObjectName objectName) {
+        checkType(objectName, TYPE_SERVICE_REFERENCE);
+        String quoted = objectName.getKeyProperty(SERVICE_QNAME_KEY);
+        String result = unquoteAndUnescape(objectName, quoted);
+        return result;
+    }
+
+    // ObjectName supports quotation and ignores tokens like =, but fails to ignore ? sign.
+    // It must be replaced with another character that hopefully does not collide
+    // with actual value.
+    private static String unquoteAndUnescape(ObjectName objectName, String quoted) {
+        if (quoted == null) {
+            throw new IllegalArgumentException("Cannot find " + SERVICE_QNAME_KEY + " in " + objectName);
+        }
+        if (quoted.startsWith("\"") == false || quoted.endsWith("\"") == false) {
+            throw new IllegalArgumentException("Quotes not found in " + objectName);
+        }
+        String substring = quoted.substring(1);
+        substring = substring.substring(0, substring.length() - 1);
+        substring = substring.replace(REPLACED_QUOTATION_MARK, "?");
+        return substring;
+    }
+
+    private static String quoteAndEscapeValue(String serviceQName) {
+        return "\"" + serviceQName.replace("?", REPLACED_QUOTATION_MARK) + "\"";
+    }
+
+    public static String getReferenceName(ObjectName objectName) {
+        checkType(objectName, TYPE_SERVICE_REFERENCE);
+        return objectName.getKeyProperty(REF_NAME_KEY);
+    }
+
+    private static Map<String, String> createServiceON(String transactionName, String serviceQName,
+                                                       String refName) {
+        Map<String, String> result = new HashMap<>(createServiceMap(serviceQName, refName));
+        result.put(TRANSACTION_NAME_KEY, transactionName);
+        return result;
+    }
+
+    private static Map<String, String> createServiceMap(String serviceQName,
+                                                        String refName) {
+        Map<String, String> onParams = new HashMap<>();
+        onParams.put(TYPE_KEY, TYPE_SERVICE_REFERENCE);
+        onParams.put(SERVICE_QNAME_KEY, quoteAndEscapeValue(serviceQName));
+        onParams.put(REF_NAME_KEY, refName);
+        return onParams;
+    }
+
+
     public static ObjectName createReadOnlyModuleON(String moduleName,
-            String instanceName) {
-        Map<String, String> onParams = createModuleON(moduleName, instanceName);
+                                                    String instanceName) {
+        Map<String, String> onParams = createModuleMap(moduleName, instanceName);
         return createON(ON_DOMAIN, onParams);
     }
 
-    private static Map<String, String> createModuleON(String moduleName,
-            String instanceName) {
+    private static Map<String, String> createModuleMap(String moduleName,
+                                                       String instanceName) {
         Map<String, String> onParams = new HashMap<>();
         onParams.put(TYPE_KEY, TYPE_MODULE);
         onParams.put(MODULE_FACTORY_NAME_KEY, moduleName);
@@ -117,10 +178,12 @@ public class ObjectNameUtil {
     }
 
     public static String getFactoryName(ObjectName objectName) {
+        checkTypeOneOf(objectName, TYPE_MODULE, TYPE_RUNTIME_BEAN);
         return objectName.getKeyProperty(MODULE_FACTORY_NAME_KEY);
     }
 
     public static String getInstanceName(ObjectName objectName) {
+        checkTypeOneOf(objectName, TYPE_MODULE, TYPE_RUNTIME_BEAN);
         return objectName.getKeyProperty(INSTANCE_NAME_KEY);
     }
 
@@ -132,6 +195,7 @@ public class ObjectNameUtil {
      * Sanitize on: keep only mandatory attributes of module + metadata.
      */
     public static ObjectName withoutTransactionName(ObjectName inputON) {
+        checkTypeOneOf(inputON, TYPE_MODULE, TYPE_SERVICE_REFERENCE);
         if (getTransactionName(inputON) == null) {
             throw new IllegalArgumentException(
                     "Expected ObjectName with transaction:" + inputON);
@@ -140,14 +204,18 @@ public class ObjectNameUtil {
             throw new IllegalArgumentException("Expected different domain: "
                     + inputON);
         }
-        String moduleName = getFactoryName(inputON);
-        String instanceName = getInstanceName(inputON);
-
-
+        Map<String, String> outputProperties;
+        if (inputON.getKeyProperty(TYPE_KEY).equals(TYPE_MODULE)) {
+            String moduleName = getFactoryName(inputON);
+            String instanceName = getInstanceName(inputON);
+            outputProperties = new HashMap<>(createModuleMap(moduleName, instanceName));
+        } else {
+            String serviceQName = getServiceQName(inputON);
+            String refName = getReferenceName(inputON);
+            outputProperties = new HashMap<>(createServiceMap(serviceQName, refName));
+        }
         Map<String, String> allProperties = getAdditionalProperties(inputON);
-        Map<String, String> outputProperties = new HashMap<>(createModuleON(moduleName, instanceName));
-
-        for(Entry<String, String> entry: allProperties.entrySet()) {
+        for (Entry<String, String> entry : allProperties.entrySet()) {
             if (entry.getKey().startsWith("X-")) {
                 outputProperties.put(entry.getKey(), entry.getValue());
             }
@@ -155,6 +223,13 @@ public class ObjectNameUtil {
         return createON(ON_DOMAIN, outputProperties);
     }
 
+    public static ObjectName withTransactionName(ObjectName inputON, String transactionName) {
+        Map<String, String> additionalProperties = getAdditionalProperties(inputON);
+        additionalProperties.put(TRANSACTION_NAME_KEY, transactionName);
+        return createON(inputON.getDomain(), additionalProperties);
+
+    }
+
     private static void assertDoesNotContain(
             Map<String, String> additionalProperties, String key) {
         if (additionalProperties.containsKey(key)) {
@@ -165,7 +240,7 @@ public class ObjectNameUtil {
     }
 
     public static ObjectName createRuntimeBeanName(String moduleName,
-            String instanceName, Map<String, String> additionalProperties) {
+                                                   String instanceName, Map<String, String> additionalProperties) {
         // check that there is no overwriting of default attributes
         assertDoesNotContain(additionalProperties, MODULE_FACTORY_NAME_KEY);
         assertDoesNotContain(additionalProperties, INSTANCE_NAME_KEY);
@@ -217,8 +292,18 @@ public class ObjectNameUtil {
         }
     }
 
+    public static void checkTypeOneOf(ObjectName objectName, String ... types) {
+        for(String type: types) {
+            if (type.equals(objectName.getKeyProperty(TYPE_KEY))) {
+                return;
+            }
+        }
+        throw new IllegalArgumentException("Wrong type, expected one of " + Arrays.asList(types)
+                + ", got " + objectName);
+    }
+
     public static ObjectName createModulePattern(String moduleName,
-            String instanceName) {
+                                                 String instanceName) {
         if (moduleName == null)
             moduleName = "*";
         if (instanceName == null)
@@ -235,7 +320,7 @@ public class ObjectNameUtil {
     }
 
     public static ObjectName createModulePattern(String ifcName,
-            String instanceName, String transactionName) {
+                                                 String instanceName, String transactionName) {
         return ObjectNameUtil.createON(ObjectNameUtil.ON_DOMAIN
                 + ":type=Module," + ObjectNameUtil.MODULE_FACTORY_NAME_KEY
                 + "=" + ifcName + "," + ObjectNameUtil.INSTANCE_NAME_KEY + "="
@@ -244,7 +329,7 @@ public class ObjectNameUtil {
     }
 
     public static ObjectName createRuntimeBeanPattern(String moduleName,
-            String instanceName) {
+                                                      String instanceName) {
         return ObjectNameUtil.createON(ObjectNameUtil.ON_DOMAIN + ":"
                 + ObjectNameUtil.TYPE_KEY + "="
                 + ObjectNameUtil.TYPE_RUNTIME_BEAN + ","
@@ -255,7 +340,7 @@ public class ObjectNameUtil {
     }
 
     public static ModuleIdentifier fromON(ObjectName objectName,
-            String expectedType) {
+                                          String expectedType) {
         checkType(objectName, expectedType);
         String factoryName = getFactoryName(objectName);
         if (factoryName == null)
@@ -268,4 +353,7 @@ public class ObjectNameUtil {
         return new ModuleIdentifier(factoryName, instanceName);
     }
 
+    public static boolean isServiceReference(ObjectName objectName) {
+        return TYPE_SERVICE_REFERENCE.equals(objectName.getKeyProperty(TYPE_KEY));
+    }
 }
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/CloseableServiceReferenceReadableRegistry.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/CloseableServiceReferenceReadableRegistry.java
new file mode 100644 (file)
index 0000000..8c32507
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * 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;
+
+import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
+
+public interface CloseableServiceReferenceReadableRegistry  extends AutoCloseable, ServiceReferenceReadableRegistry {
+
+
+    void close();
+
+}
index e3311c747f872f601b0448e01d7e864163a15a75..19231705d1614f696e2e764260d971c59c513ecd 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.controller.config.manager.impl;
 import org.opendaylight.controller.config.api.ConflictingVersionException;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.config.api.RuntimeBeanRegistratorAwareModule;
-import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
 import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
 import org.opendaylight.controller.config.api.ValidationException;
 import org.opendaylight.controller.config.api.jmx.CommitStatus;
@@ -104,7 +103,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
     private List<ModuleFactory> lastListOfFactories = Collections.emptyList();
 
     @GuardedBy("this") // switched in every 2ndPC
-    private ServiceReferenceReadableRegistry readableSRRegistry = ServiceReferenceRegistryImpl.createInitialSRLookupRegistry();
+    private CloseableServiceReferenceReadableRegistry  readableSRRegistry = ServiceReferenceRegistryImpl.createInitialSRLookupRegistry();
 
     // constructor
     public ConfigRegistryImpl(ModuleFactoriesResolver resolver,
@@ -298,8 +297,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
             OsgiRegistration osgiRegistration = null;
             if (entry.hasOldModule()) {
                 ModuleInternalInfo oldInternalInfo = entry.getOldInternalInfo();
-                DynamicReadableWrapper oldReadableConfigBean = oldInternalInfo
-                        .getReadableModule();
+                DynamicReadableWrapper oldReadableConfigBean = oldInternalInfo.getReadableModule();
                 currentConfig.remove(entry.getIdentifier());
 
                 // test if old instance == new instance
@@ -368,7 +366,9 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
         version = configTransactionController.getVersion();
 
         // switch readable Service Reference Registry
-        this.readableSRRegistry = ServiceReferenceRegistryImpl.createSRReadableRegistry(configTransactionController.getWritableRegistry(), this);
+        this.readableSRRegistry.close();
+        this.readableSRRegistry = ServiceReferenceRegistryImpl.createSRReadableRegistry(
+                configTransactionController.getWritableRegistry(), this, baseJMXRegistrator);
 
         return new CommitStatus(newInstances, reusedInstances,
                 recreatedInstances);
@@ -525,8 +525,8 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
 
     // service reference functionality:
     @Override
-    public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
-        return readableSRRegistry.lookupConfigBeanByServiceInterfaceName(serviceInterfaceName, refName);
+    public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
+        return readableSRRegistry.lookupConfigBeanByServiceInterfaceName(serviceInterfaceQName, refName);
     }
 
     @Override
@@ -535,8 +535,8 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
     }
 
     @Override
-    public synchronized Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
-        return readableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName);
+    public synchronized Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
+        return readableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceQName);
     }
 
     @Override
@@ -549,11 +549,28 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
         return readableSRRegistry.getServiceInterfaceName(namespace, localName);
     }
 
+    @Override
+    public void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+        readableSRRegistry.checkServiceReferenceExists(objectName);
+    }
+
+    @Override
+    public ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+        return readableSRRegistry.getServiceReference(serviceInterfaceQName, refName);
+    }
+
     @Override
     public Set<String> getAvailableModuleFactoryQNames() {
         return ModuleQNameUtil.getQNames(resolver.getAllFactories());
     }
 
+    @Override
+    public String toString() {
+        return "ConfigRegistryImpl{" +
+                "versionCounter=" + versionCounter +
+                ", version=" + version +
+                '}';
+    }
 }
 
 /**
@@ -579,12 +596,12 @@ class ConfigHolder {
     }
 
     private void add(ModuleInternalInfo configInfo) {
-        ModuleInternalInfo oldValue = currentConfig.put(configInfo.getName(),
+        ModuleInternalInfo oldValue = currentConfig.put(configInfo.getIdentifier(),
                 configInfo);
         if (oldValue != null) {
             throw new IllegalStateException(
                     "Cannot overwrite module with same name:"
-                            + configInfo.getName() + ":" + configInfo);
+                            + configInfo.getIdentifier() + ":" + configInfo);
         }
     }
 
index 17ce0781546e231a5f81b2a8ca1b276f5a046d74..e0d1a42661362a0ef425526bec8e9abc5e4633b9 100644 (file)
@@ -95,7 +95,7 @@ class ConfigTransactionControllerImpl implements
         this.currentlyRegisteredFactories = currentlyRegisteredFactories;
         this.factoriesHolder = new HierarchicalConfigMBeanFactoriesHolder(currentlyRegisteredFactories);
         this.transactionStatus = new TransactionStatus();
-        this.dependencyResolverManager = new DependencyResolverManager(transactionName, transactionStatus);
+        this.dependencyResolverManager = new DependencyResolverManager(transactionName, transactionStatus, writableSRRegistry);
         this.transactionsMBeanServer = transactionsMBeanServer;
         this.configMBeanServer = configMBeanServer;
         this.blankTransaction = blankTransaction;
@@ -165,15 +165,14 @@ class ConfigTransactionControllerImpl implements
             throws InstanceAlreadyExistsException {
         transactionStatus.checkNotCommitStarted();
         transactionStatus.checkNotAborted();
-        ModuleIdentifier moduleIdentifier = oldConfigBeanInfo.getName();
+        ModuleIdentifier moduleIdentifier = oldConfigBeanInfo.getIdentifier();
         dependencyResolverManager.assertNotExists(moduleIdentifier);
 
         ModuleFactory moduleFactory = factoriesHolder
                 .findByModuleName(moduleIdentifier.getFactoryName());
 
         Module module;
-        DependencyResolver dependencyResolver = dependencyResolverManager
-                .getOrCreate(moduleIdentifier);
+        DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(moduleIdentifier);
         try {
             BundleContext bc = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
             module = moduleFactory.createModule(
@@ -412,7 +411,7 @@ class ConfigTransactionControllerImpl implements
         close();
     }
 
-    private void close() {
+    public void close() {
         //FIXME: should not close object that was retrieved in constructor, a wrapper object should do that perhaps
         txLookupRegistry.close();
     }
@@ -523,8 +522,8 @@ class ConfigTransactionControllerImpl implements
 
 
     @Override
-    public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
-        return writableSRRegistry.lookupConfigBeanByServiceInterfaceName(serviceInterfaceName, refName);
+    public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
+        return writableSRRegistry.lookupConfigBeanByServiceInterfaceName(serviceInterfaceQName, refName);
     }
 
     @Override
@@ -533,8 +532,8 @@ class ConfigTransactionControllerImpl implements
     }
 
     @Override
-    public synchronized Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
-        return writableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName);
+    public synchronized Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
+        return writableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceQName);
     }
 
     @Override
@@ -548,13 +547,13 @@ class ConfigTransactionControllerImpl implements
     }
 
     @Override
-    public synchronized void saveServiceReference(String serviceInterfaceName, String refName, ObjectName objectName) throws InstanceNotFoundException {
-        writableSRRegistry.saveServiceReference(serviceInterfaceName, refName, objectName);
+    public synchronized ObjectName saveServiceReference(String serviceInterfaceName, String refName, ObjectName moduleON) throws InstanceNotFoundException {
+        return writableSRRegistry.saveServiceReference(serviceInterfaceName, refName, moduleON);
     }
 
     @Override
-    public synchronized boolean removeServiceReference(String serviceInterfaceName, String refName) {
-        return writableSRRegistry.removeServiceReference(serviceInterfaceName, refName);
+    public synchronized void removeServiceReference(String serviceInterfaceName, String refName) throws InstanceNotFoundException {
+        writableSRRegistry.removeServiceReference(serviceInterfaceName, refName);
     }
 
     @Override
@@ -581,4 +580,13 @@ class ConfigTransactionControllerImpl implements
         return txLookupRegistry.getAvailableModuleFactoryQNames();
     }
 
+    @Override
+    public void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+        writableSRRegistry.checkServiceReferenceExists(objectName);
+    }
+
+    @Override
+    public ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+        return writableSRRegistry.getServiceReference(serviceInterfaceQName, refName);
+    }
 }
index 12db6c8f89e489114d0ad96b3e5e88ed1a97a4f3..a7d426ebdd78aa9d940b818f6f57ec8e58cd119c 100644 (file)
@@ -117,6 +117,13 @@ class ConfigTransactionLookupRegistry  implements LookupRegistry, Closeable {
         return ModuleQNameUtil.getQNames(allCurrentFactories);
     }
 
+
+    @Override
+    public String toString() {
+        return "ConfigTransactionLookupRegistry{" +
+                "transactionIdentifier=" + transactionIdentifier +
+                '}';
+    }
 }
 
 interface TransactionJMXRegistratorFactory {
index 14a706dd9b990e9251233aacef2db022502fb1dc..941aec10969fd90c700d257579b02c88520e40e9 100644 (file)
@@ -90,11 +90,6 @@ public class ModuleInternalInfo implements Comparable<ModuleInternalInfo>,
         return osgiRegistration;
     }
 
-    @Deprecated
-    public ModuleIdentifier getName() {
-        return name;
-    }
-
     /**
      * Get index representing dependency ordering within a transaction.
      */
@@ -111,7 +106,7 @@ public class ModuleInternalInfo implements Comparable<ModuleInternalInfo>,
     }
 
     public DestroyedModule toDestroyedModule() {
-        return new DestroyedModule(getName(),
+        return new DestroyedModule(getIdentifier(),
                 getReadableModule().getInstance(), getModuleJMXRegistrator(),
                 getOsgiRegistration(), getOrderingIdx());
     }
index 7fedcdf71ce7ce28974cc06a1e72c42720b04248..0faa32b7dc4e181962802d8d5e1345472d8378d9 100644 (file)
@@ -13,42 +13,52 @@ import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
 import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
 import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.manager.impl.jmx.BaseJMXRegistrator;
+import org.opendaylight.controller.config.manager.impl.jmx.ServiceReference;
+import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceMXBeanImpl;
+import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceRegistrator;
+import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceRegistrator.ServiceReferenceJMXRegistration;
+import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceRegistrator.ServiceReferenceTransactionRegistratorFactory;
+import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceRegistrator.ServiceReferenceTransactionRegistratorFactoryImpl;
 import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
 import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.management.InstanceAlreadyExistsException;
 import javax.management.InstanceNotFoundException;
 import javax.management.ObjectName;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
-public class ServiceReferenceRegistryImpl implements ServiceReferenceReadableRegistry, ServiceReferenceWritableRegistry {
+public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceReadableRegistry, ServiceReferenceWritableRegistry {
     private static final Logger logger = LoggerFactory.getLogger(ServiceReferenceRegistryImpl.class);
 
     private final Map<String, ModuleFactory> factories;
     private final Map<String, Set<String>> factoryNamesToQNames;
     // validator of incoming ObjectNames - throws InstanceNotFoundException if not found either in registry or transaction
     private final LookupRegistry lookupRegistry;
+    private final ServiceReferenceRegistrator serviceReferenceRegistrator;
     // helper method for getting QName of SI from namespace + local name
     private final Map<String /* namespace */, Map<String /* local name */, ServiceInterfaceAnnotation>> namespacesToAnnotations;
     // all Service Interface qNames for sanity checking
     private final Set<String /* qName */> allQNames;
 
     // actual reference database
-    private final Map<String /* qName */, Map<String /* refName */, ModuleIdentifier>> refNames;
+    private final Map<ServiceReference, ModuleIdentifier> refNames = new HashMap<>();
+    private final boolean writable;
+    private final Map<ServiceReference, Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration>> mBeans = new HashMap<>();
 
     /**
      * Static constructor for config registry. Since only transaction can write to this registry, it will
      * return blank state.
      */
-    public static ServiceReferenceReadableRegistry createInitialSRLookupRegistry() {
+    public static CloseableServiceReferenceReadableRegistry createInitialSRLookupRegistry() {
         // since this is initial state, just throw exception:
         LookupRegistry lookupRegistry = new LookupRegistry() {
             @Override
@@ -73,36 +83,99 @@ public class ServiceReferenceRegistryImpl implements ServiceReferenceReadableReg
 
             @Override
             public void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException {
-                throw new InstanceNotFoundException("Cannot find " + objectName);
+                throw new InstanceNotFoundException("Cannot find " + objectName + " - Tried to use mocking registry");
             }
 
             @Override
             public Set<String> getAvailableModuleFactoryQNames() {
                 throw new UnsupportedOperationException();
             }
+
+            @Override
+            public String toString() {
+                return "initial";
+            }
+        };
+        ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory = new ServiceReferenceTransactionRegistratorFactory(){
+            @Override
+            public ServiceReferenceRegistrator create() {
+                return new ServiceReferenceRegistrator() {
+                    @Override
+                    public String getNullableTransactionName() {
+                        throw new UnsupportedOperationException();
+                    }
+
+                    @Override
+                    public ServiceReferenceJMXRegistration registerMBean(ServiceReferenceMXBeanImpl object, ObjectName on) throws InstanceAlreadyExistsException {
+                        throw new UnsupportedOperationException();
+                    }
+
+                    @Override
+                    public void close() {
+
+                    }
+                };
+            }
         };
         return new ServiceReferenceRegistryImpl(Collections.<String, ModuleFactory>emptyMap(), lookupRegistry,
-                Collections.<String /* qName */, Map<String /* refName */, ModuleIdentifier>>emptyMap());
+                serviceReferenceRegistratorFactory, false);
     }
 
     /**
      * Static constructor for transaction controller. Take current state as seen by config registry, allow writing new data.
      */
     public static ServiceReferenceWritableRegistry createSRWritableRegistry(ServiceReferenceReadableRegistry oldReadableRegistry,
-            LookupRegistry lookupRegistry, Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories) {
+                                                    ConfigTransactionLookupRegistry txLookupRegistry,
+                                                    Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories) {
 
+        if (txLookupRegistry == null) {
+            throw new IllegalArgumentException("txLookupRegistry is null");
+        }
         ServiceReferenceRegistryImpl old = (ServiceReferenceRegistryImpl) oldReadableRegistry;
         Map<String, ModuleFactory> factories = extractFactoriesMap(currentlyRegisteredFactories);
-        return new ServiceReferenceRegistryImpl(factories, lookupRegistry, Collections.unmodifiableMap(old.refNames));
+        ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory = new ServiceReferenceTransactionRegistratorFactoryImpl(
+                txLookupRegistry.getTxModuleJMXRegistrator(), txLookupRegistry.getTxModuleJMXRegistrator().getTransactionName());
+        ServiceReferenceRegistryImpl newRegistry = new ServiceReferenceRegistryImpl(factories, txLookupRegistry,
+                serviceReferenceRegistratorFactory, true);
+        copy(old, newRegistry, txLookupRegistry.getTransactionIdentifier().getName());
+        return newRegistry;
     }
 
     /**
      * Copy back state to config registry after commit.
      */
-    public static ServiceReferenceReadableRegistry createSRReadableRegistry(ServiceReferenceWritableRegistry oldWritableRegistry, LookupRegistry lookupRegistry) {
+    public static CloseableServiceReferenceReadableRegistry createSRReadableRegistry(ServiceReferenceWritableRegistry oldWritableRegistry,
+                                                                            LookupRegistry lookupRegistry, BaseJMXRegistrator baseJMXRegistrator) {
         ServiceReferenceRegistryImpl old = (ServiceReferenceRegistryImpl) oldWritableRegistry;
+
         // even if factories do change, nothing in the mapping can change between transactions
-        return new ServiceReferenceRegistryImpl(old.factories, lookupRegistry, Collections.unmodifiableMap(old.refNames));
+        ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory = new ServiceReferenceTransactionRegistratorFactoryImpl(baseJMXRegistrator);
+        ServiceReferenceRegistryImpl newRegistry = new ServiceReferenceRegistryImpl(old.factories, lookupRegistry,
+                serviceReferenceRegistratorFactory, false);
+        copy(old, newRegistry, null);
+        return newRegistry;
+    }
+
+    /**
+     * Fill refNames and mBeans maps from old instance
+     */
+    private static void copy(ServiceReferenceRegistryImpl old, ServiceReferenceRegistryImpl newRegistry, String nullableDstTransactionName) {
+        for (Entry<ServiceReference, Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration>> refNameEntry : old.mBeans.entrySet()) {
+            ObjectName currentImplementation;
+            ObjectName currentImplementationSrc = refNameEntry.getValue().getKey().getCurrentImplementation();
+            if (nullableDstTransactionName != null) {
+                currentImplementation = ObjectNameUtil.withTransactionName(currentImplementationSrc, nullableDstTransactionName);
+            } else {
+                currentImplementation = ObjectNameUtil.withoutTransactionName(currentImplementationSrc);
+            }
+            try {
+                boolean skipChecks = true;
+                newRegistry.saveServiceReference(refNameEntry.getKey(), currentImplementation, skipChecks);
+            } catch (InstanceNotFoundException e) {
+                logger.error("Cannot save service reference({}, {})", refNameEntry.getKey(), currentImplementation);
+                throw new IllegalStateException("Possible code error", e);
+            }
+        }
     }
 
     private static Map<String, ModuleFactory> extractFactoriesMap(Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories) {
@@ -114,9 +187,14 @@ public class ServiceReferenceRegistryImpl implements ServiceReferenceReadableReg
     }
 
     private ServiceReferenceRegistryImpl(Map<String, ModuleFactory> factories, LookupRegistry lookupRegistry,
-                                         Map<String /* qName */, Map<String /* refName */, ModuleIdentifier>> refNamesToCopy) {
+                                         ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory,
+                                         boolean writable) {
         this.factories = factories;
+        this.writable = writable;
         this.lookupRegistry = lookupRegistry;
+
+        this.serviceReferenceRegistrator = serviceReferenceRegistratorFactory.create();
+
         Map<String, Set<String /* QName */>> factoryNamesToQNames = new HashMap<>();
         Set<ServiceInterfaceAnnotation> allAnnotations = new HashSet<>();
         Set<String /* qName */> allQNames = new HashSet<>();
@@ -154,22 +232,12 @@ public class ServiceReferenceRegistryImpl implements ServiceReferenceReadableReg
         }
         this.namespacesToAnnotations = Collections.unmodifiableMap(namespacesToAnnotations);
         // copy refNames
-        Map<String /* qName */, Map<String /* refName */, ModuleIdentifier>> deepCopy = new HashMap<>();
-        for (Entry<String, Map<String, ModuleIdentifier>> outerROEntry: refNamesToCopy.entrySet()) {
-            Map<String /* refName */, ModuleIdentifier> innerWritableMap = new HashMap<>();
-            deepCopy.put(outerROEntry.getKey(), innerWritableMap);
-            for (Entry<String, ModuleIdentifier> innerROEntry:  outerROEntry.getValue().entrySet()) {
-                innerWritableMap.put(innerROEntry.getKey(), innerROEntry.getValue());
-            }
-        }
-        this.refNames = deepCopy;
         logger.trace("factoryNamesToQNames:{}", this.factoryNamesToQNames);
-        logger.trace("refNames:{}", refNames);
     }
 
 
     @Override
-    public Set<String> lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException {
+    public synchronized Set<String> lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException {
         lookupRegistry.checkConfigBeanExists(objectName);
 
         String factoryName = ObjectNameUtil.getFactoryName(objectName);
@@ -183,7 +251,7 @@ public class ServiceReferenceRegistryImpl implements ServiceReferenceReadableReg
     }
 
     @Override
-    public String getServiceInterfaceName(String namespace, String localName) {
+    public synchronized String getServiceInterfaceName(String namespace, String localName) {
         Map<String /* localName */, ServiceInterfaceAnnotation> ofNamespace = namespacesToAnnotations.get(namespace);
         if (ofNamespace == null) {
             logger.error("Cannot find namespace {} in {}", namespace, namespacesToAnnotations);
@@ -197,23 +265,19 @@ public class ServiceReferenceRegistryImpl implements ServiceReferenceReadableReg
         return sia.value();
     }
 
-
-
     // reading:
 
     @Override
-    public Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> getServiceMapping() {
+    public synchronized Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> getServiceMapping() {
         Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> result = new HashMap<>();
-        for (Entry<String /* qName */, Map<String, ModuleIdentifier>> outerEntry: refNames.entrySet()) {
-            String qName = outerEntry.getKey();
-            Map<String /* refName */, ObjectName> innerMap = new HashMap<>();
-            result.put(qName, innerMap);
-            for (Entry<String /* refName */, ModuleIdentifier> innerEntry: outerEntry.getValue().entrySet()) {
-                ModuleIdentifier moduleIdentifier = innerEntry.getValue();
-                ObjectName on;
-                on = getObjectName(moduleIdentifier);
-                innerMap.put(innerEntry.getKey(), on);
+        for (Entry<ServiceReference, ModuleIdentifier> entry: refNames.entrySet()) {
+            String qName = entry.getKey().getServiceInterfaceName();
+            Map<String /* refName */, ObjectName> innerMap = result.get(qName);
+            if (innerMap == null) {
+                innerMap = new HashMap<>();
+                result.put(qName, innerMap);
             }
+            innerMap.put(entry.getKey().getRefName(), getObjectName(entry.getValue()));
         }
         return result;
     }
@@ -230,116 +294,227 @@ public class ServiceReferenceRegistryImpl implements ServiceReferenceReadableReg
     }
 
     @Override
-    public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
-        Map<String, ModuleIdentifier> innerMap = refNames.get(serviceInterfaceName);
-        if (innerMap == null) {
-            logger.error("Cannot find qname {} in {}", serviceInterfaceName, refName);
-            throw new IllegalArgumentException("Cannot find " + serviceInterfaceName);
-        }
-        ModuleIdentifier moduleIdentifier = innerMap.get(refName);
+    public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
+        ServiceReference serviceReference = new ServiceReference(serviceInterfaceQName, refName);
+        ModuleIdentifier moduleIdentifier = refNames.get(serviceReference);
         if (moduleIdentifier == null) {
-            logger.error("Cannot find refName {} in {}, using qname {}", refName, innerMap, serviceInterfaceName);
-            throw new IllegalArgumentException("Cannot find module based on service reference " + refName);
+            logger.error("Cannot find qname {} and refName {} in {}", serviceInterfaceQName, refName, refName);
+            throw new IllegalArgumentException("Cannot find " + serviceReference);
         }
         return getObjectName(moduleIdentifier);
     }
 
     @Override
-    public  Map<String /* refName */, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
-        Map<String, ModuleIdentifier> innerMap = refNames.get(serviceInterfaceName);
+    public synchronized Map<String /* refName */, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
+        Map<String, Map<String, ObjectName>> serviceMapping = getServiceMapping();
+        Map<String, ObjectName> innerMap = serviceMapping.get(serviceInterfaceQName);
         if (innerMap == null) {
-            logger.error("Cannot find qname {} in {}", serviceInterfaceName, refNames);
-            throw new IllegalArgumentException("Cannot find " + serviceInterfaceName);
+            logger.error("Cannot find qname {} in {}", serviceInterfaceQName, refNames);
+            throw new IllegalArgumentException("Cannot find " + serviceInterfaceQName);
         }
-        Map<String /* refName */, ObjectName> result = new HashMap<>();
-        for (Entry<String/* refName */, ModuleIdentifier> entry: innerMap.entrySet()) {
-            ObjectName on = getObjectName(entry.getValue());
-            result.put(entry.getKey(), on);
+        return innerMap;
+    }
+
+    @Override
+    public synchronized ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+        ServiceReference serviceReference = new ServiceReference(serviceInterfaceQName, refName);
+        if (mBeans.containsKey(serviceReference) == false) {
+            throw new InstanceNotFoundException("Cannot find " + serviceReference);
+        }
+        return getServiceON(serviceReference);
+    }
+
+    @Override
+    public synchronized void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+        String actualTransactionName = ObjectNameUtil.getTransactionName(objectName);
+        String expectedTransactionName = serviceReferenceRegistrator.getNullableTransactionName();
+        if (writable & actualTransactionName == null || (writable && actualTransactionName.equals(expectedTransactionName) == false)) {
+            throw new IllegalArgumentException("Mismatched transaction name in " + objectName);
+        }
+        String serviceQName = ObjectNameUtil.getServiceQName(objectName);
+        String referenceName = ObjectNameUtil.getReferenceName(objectName);
+        ServiceReference serviceReference = new ServiceReference(serviceQName, referenceName);
+        if (refNames.containsKey(serviceReference) == false) {
+            logger.warn("Cannot find {} in {}", serviceReference, refNames);
+            throw new InstanceNotFoundException("Service reference not found:" + objectName);
         }
-        return result;
     }
 
     // writing:
 
+    private void assertWritable() {
+        if (writable == false) {
+            throw new IllegalStateException("Cannot write to readable registry");
+        }
+    }
+
     @Override
-    public void saveServiceReference(String serviceInterfaceName, String refName, ObjectName objectName)  throws InstanceNotFoundException {
+    public synchronized ObjectName saveServiceReference(String serviceInterfaceName, String refName, ObjectName moduleON)  throws InstanceNotFoundException {
+        assertWritable();
+        ServiceReference serviceReference = new ServiceReference(serviceInterfaceName, refName);
+        return saveServiceReference(serviceReference, moduleON);
+    }
+
+    private synchronized ObjectName saveServiceReference(ServiceReference serviceReference, ObjectName moduleON)
+            throws InstanceNotFoundException{
+        return saveServiceReference(serviceReference, moduleON, false);
+    }
+
+    private synchronized ObjectName saveServiceReference(ServiceReference serviceReference, ObjectName moduleON,
+                                                         boolean skipChecks) throws InstanceNotFoundException {
+
         // make sure it is found
-        lookupRegistry.checkConfigBeanExists(objectName);
-        String factoryName = ObjectNameUtil.getFactoryName(objectName);
+        if (skipChecks == false) {
+            lookupRegistry.checkConfigBeanExists(moduleON);
+        }
+        String factoryName = ObjectNameUtil.getFactoryName(moduleON);
+        String instanceName = ObjectNameUtil.getInstanceName(moduleON);
+        ModuleIdentifier moduleIdentifier = new ModuleIdentifier(factoryName, instanceName);
+
         // check that service interface name exist
-        Set<String> serviceInterfaceQNames = factoryNamesToQNames.get(factoryName);
+        Set<String> serviceInterfaceQNames = factoryNamesToQNames.get(moduleIdentifier.getFactoryName());
         if (serviceInterfaceQNames == null) {
-            logger.error("Possible error in code: cannot find factoryName {} in {}, object name {}", factoryName, factoryNamesToQNames, objectName);
-            throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + factoryName);
+            logger.error("Possible error in code: cannot find factoryName {} in {}, {}", moduleIdentifier.getFactoryName(),
+                    factoryNamesToQNames, moduleIdentifier);
+            throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + moduleIdentifier.getFactoryName());
         }
         // supplied serviceInterfaceName must exist in this collection
-        if (serviceInterfaceQNames.contains(serviceInterfaceName) == false) {
-            logger.error("Cannot find qname {} with factory name {}, found {}", serviceInterfaceName, factoryName, serviceInterfaceQNames);
-            throw new IllegalArgumentException("Cannot find service interface " + serviceInterfaceName + " within factory " + factoryName );
+        if (serviceInterfaceQNames.contains(serviceReference.getServiceInterfaceName()) == false) {
+            logger.error("Cannot find qName {} with factory name {}, found {}", serviceReference.getServiceInterfaceName(), moduleIdentifier.getFactoryName(), serviceInterfaceQNames);
+            throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceName() + " within factory " + moduleIdentifier.getFactoryName());
         }
-        String instanceName = ObjectNameUtil.getInstanceName(objectName);
-        ModuleIdentifier moduleIdentifier = new ModuleIdentifier(factoryName, instanceName);
-        Map<String /* refName */, ModuleIdentifier> ofQName = refNames.get(serviceInterfaceName);
-        // might be null
-        if (ofQName == null) {
-            ofQName = new HashMap<>();
-            refNames.put(serviceInterfaceName, ofQName);
+
+
+        // create service reference object name, put to mBeans
+        ObjectName result = getServiceON(serviceReference);
+        Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration> mxBeanEntry = mBeans.get(serviceReference);
+        if (mxBeanEntry == null) {
+            // create dummy mx bean
+            ServiceReferenceMXBeanImpl dummyMXBean = new ServiceReferenceMXBeanImpl(moduleON);
+            ServiceReferenceJMXRegistration dummyMXBeanRegistration;
+            try {
+                dummyMXBeanRegistration = serviceReferenceRegistrator.registerMBean(dummyMXBean, result);
+            } catch (InstanceAlreadyExistsException e) {
+                throw new IllegalStateException("Possible error in code. Cannot register " + result, e);
+            }
+            mBeans.put(serviceReference, createMXBeanEntry(dummyMXBean, dummyMXBeanRegistration));
+        } else {
+            // update
+            mxBeanEntry.getKey().setCurrentImplementation(moduleON);
+        }
+        // save to refNames
+        refNames.put(serviceReference, moduleIdentifier);
+        return result;
+    }
+
+    private Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration> createMXBeanEntry(
+            final ServiceReferenceMXBeanImpl mxBean, final ServiceReferenceJMXRegistration registration) {
+        return new Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration>() {
+            @Override
+            public ServiceReferenceMXBeanImpl getKey() {
+                return mxBean;
+            }
+
+            @Override
+            public ServiceReferenceJMXRegistration getValue() {
+                return registration;
+            }
+
+            @Override
+            public ServiceReferenceJMXRegistration setValue(ServiceReferenceJMXRegistration value) {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+
+    private ObjectName getServiceON(ServiceReference serviceReference) {
+        if (writable) {
+            return ObjectNameUtil.createTransactionServiceON(serviceReferenceRegistrator.getNullableTransactionName(),
+                    serviceReference.getServiceInterfaceName(), serviceReference.getRefName());
+        } else {
+            return ObjectNameUtil.createReadOnlyServiceON(serviceReference.getServiceInterfaceName(), serviceReference.getRefName());
         }
-        ofQName.put(refName, moduleIdentifier);
     }
 
     @Override
-    public boolean removeServiceReference(String serviceInterfaceName, String refName) {
-        // is the qname known?
-        if (allQNames.contains(serviceInterfaceName) == false) {
-            logger.error("Cannot find qname {} in {}", serviceInterfaceName, allQNames);
-            throw new IllegalArgumentException("Cannot find service interface " + serviceInterfaceName);
+    public synchronized void removeServiceReference(String serviceInterfaceName, String refName) throws InstanceNotFoundException{
+        ServiceReference serviceReference = new ServiceReference(serviceInterfaceName, refName);
+        removeServiceReference(serviceReference);
+    }
+
+    private synchronized void removeServiceReference(ServiceReference serviceReference) throws InstanceNotFoundException {
+        logger.debug("Removing service reference {} from {}", serviceReference, this);
+        assertWritable();
+        // is the qName known?
+        if (allQNames.contains(serviceReference.getServiceInterfaceName()) == false) {
+            logger.error("Cannot find qname {} in {}", serviceReference.getServiceInterfaceName(), allQNames);
+            throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceName());
+        }
+        ModuleIdentifier removed = refNames.remove(serviceReference);
+        if (removed == null){
+            throw new InstanceNotFoundException("Cannot find " + serviceReference.getServiceInterfaceName());
         }
-        Map<String, ModuleIdentifier> ofQName = refNames.get(serviceInterfaceName);
-        if (ofQName == null) {
-            return false;
+        Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration> entry = mBeans.remove(serviceReference);
+        if (entry == null) {
+            throw new IllegalStateException("Possible code error: cannot remove from mBeans: " + serviceReference);
         }
-        return ofQName.remove(refName) != null;
+        entry.getValue().close();
     }
 
     @Override
-    public void removeAllServiceReferences() {
-        refNames.clear();
+    public synchronized void removeAllServiceReferences() {
+        assertWritable();
+        for (ServiceReference serviceReference: mBeans.keySet()) {
+            try {
+                removeServiceReference(serviceReference);
+            } catch (InstanceNotFoundException e) {
+                throw new IllegalStateException("Possible error in code", e);
+            }
+        }
     }
 
     @Override
-    public boolean removeServiceReferences(ObjectName objectName) throws InstanceNotFoundException {
-        lookupRegistry.checkConfigBeanExists(objectName);
-        String factoryName = ObjectNameUtil.getFactoryName(objectName);
+    public synchronized boolean removeServiceReferences(ObjectName moduleObjectName) throws InstanceNotFoundException {
+        assertWritable();
+        Set<ServiceReference> serviceReferencesLinkingTo = findServiceReferencesLinkingTo(moduleObjectName);
+        for (ServiceReference sr : serviceReferencesLinkingTo) {
+            removeServiceReference(sr);
+        }
+        return serviceReferencesLinkingTo.isEmpty() == false;
+    }
+
+    private synchronized Set<ServiceReference> findServiceReferencesLinkingTo(ObjectName moduleObjectName)  throws InstanceNotFoundException {
+        lookupRegistry.checkConfigBeanExists(moduleObjectName);
+        String factoryName = ObjectNameUtil.getFactoryName(moduleObjectName);
         // check that service interface name exist
         Set<String> serviceInterfaceQNames = factoryNamesToQNames.get(factoryName);
         if (serviceInterfaceQNames == null) {
-            logger.error("Possible error in code: cannot find factoryName {} in {}, object name {}", factoryName, factoryNamesToQNames, objectName);
+            logger.error("Possible error in code: cannot find factoryName {} in {}, object name {}", factoryName, factoryNamesToQNames, moduleObjectName);
             throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + factoryName);
         }
-        String instanceName = ObjectNameUtil.getInstanceName(objectName);
+        String instanceName = ObjectNameUtil.getInstanceName(moduleObjectName);
         ModuleIdentifier moduleIdentifier = new ModuleIdentifier(factoryName, instanceName);
-        boolean found = false;
-        for(String qName: serviceInterfaceQNames){
-            Map<String, ModuleIdentifier> ofQName = refNames.get(qName);
-            if (ofQName != null) {
-                for(Iterator<Entry<String, ModuleIdentifier>> it = ofQName.entrySet ().iterator(); it.hasNext();){
-                    Entry<String, ModuleIdentifier> next = it.next();
-                    if (next.getValue().equals(moduleIdentifier)) {
-                        found = true;
-                        it.remove();
-                    }
-                }
+        Set<ServiceReference> result = new HashSet<>();
+        for (Entry<ServiceReference, ModuleIdentifier> entry : refNames.entrySet()) {
+            if (entry.getValue().equals(moduleIdentifier)) {
+                result.add(entry.getKey());
             }
         }
-        return found;
+        return result;
     }
 
+
     @Override
     public String toString() {
         return "ServiceReferenceRegistryImpl{" +
+                "lookupRegistry=" + lookupRegistry +
                 "refNames=" + refNames +
                 ", factoryNamesToQNames=" + factoryNamesToQNames +
                 '}';
     }
+
+    @Override
+    public void close() {
+        serviceReferenceRegistrator.close();
+    }
 }
index 760fe50e28f533021684f1d1a0bb25685272fac8..925a57b044f44f87c31bf1aa9e8d60d7ebf210c9 100644 (file)
@@ -11,6 +11,7 @@ import org.opendaylight.controller.config.api.DependencyResolver;
 import org.opendaylight.controller.config.api.JmxAttribute;
 import org.opendaylight.controller.config.api.JmxAttributeValidationException;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
 import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.manager.impl.TransactionStatus;
@@ -37,12 +38,16 @@ final class DependencyResolverImpl implements DependencyResolver,
     private final TransactionStatus transactionStatus;
     @GuardedBy("this")
     private final Set<ModuleIdentifier> dependencies = new HashSet<>();
+    private final ServiceReferenceReadableRegistry readableRegistry;
 
     DependencyResolverImpl(ModuleIdentifier currentModule,
-            TransactionStatus transactionStatus, ModulesHolder modulesHolder) {
+            TransactionStatus transactionStatus, ModulesHolder modulesHolder,
+            ServiceReferenceReadableRegistry readableRegistry) {
+
         this.name = currentModule;
         this.transactionStatus = transactionStatus;
         this.modulesHolder = modulesHolder;
+        this.readableRegistry = readableRegistry;
     }
 
     /**
@@ -52,7 +57,7 @@ final class DependencyResolverImpl implements DependencyResolver,
     @Override
     public void validateDependency(
             Class<? extends AbstractServiceInterface> expectedServiceInterface,
-            ObjectName dependentModuleReadOnlyON, JmxAttribute jmxAttribute) {
+            ObjectName dependentReadOnlyON, JmxAttribute jmxAttribute) {
 
         transactionStatus.checkNotCommitted();
         if (expectedServiceInterface == null) {
@@ -62,22 +67,26 @@ final class DependencyResolverImpl implements DependencyResolver,
         if (jmxAttribute == null)
             throw new NullPointerException("Parameter 'jmxAttribute' is null");
 
-        JmxAttributeValidationException.checkNotNull(dependentModuleReadOnlyON,
+        JmxAttributeValidationException.checkNotNull(dependentReadOnlyON,
                 "is null, " + "expected dependency implementing "
                         + expectedServiceInterface, jmxAttribute);
 
+
+
         // check that objectName belongs to this transaction - this should be
         // stripped
         // in DynamicWritableWrapper
         boolean hasTransaction = ObjectNameUtil
-                .getTransactionName(dependentModuleReadOnlyON) != null;
+                .getTransactionName(dependentReadOnlyON) != null;
         JmxAttributeValidationException.checkCondition(
                 hasTransaction == false,
                 format("ObjectName should not contain "
                         + "transaction name. %s set to %s. ", jmxAttribute,
-                        dependentModuleReadOnlyON), jmxAttribute);
+                        dependentReadOnlyON), jmxAttribute);
+
+        dependentReadOnlyON = translateServiceRefIfPossible(dependentReadOnlyON);
 
-        ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(dependentModuleReadOnlyON, ObjectNameUtil
+        ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(dependentReadOnlyON, ObjectNameUtil
                 .TYPE_MODULE);
 
         ModuleFactory foundFactory = modulesHolder.findModuleFactory(moduleIdentifier, jmxAttribute);
@@ -90,7 +99,7 @@ final class DependencyResolverImpl implements DependencyResolver,
                             + "Module name is %s : %s, expected service interface %s, dependent module ON %s , "
                             + "attribute %s",
                     foundFactory.getImplementationName(), foundFactory,
-                    expectedServiceInterface, dependentModuleReadOnlyON,
+                    expectedServiceInterface, dependentReadOnlyON,
                     jmxAttribute);
             throw new JmxAttributeValidationException(message, jmxAttribute);
         }
@@ -99,24 +108,35 @@ final class DependencyResolverImpl implements DependencyResolver,
         }
     }
 
+    // transalate from serviceref to module ON
+    private ObjectName translateServiceRefIfPossible(ObjectName dependentReadOnlyON) {
+        if (ObjectNameUtil.isServiceReference(dependentReadOnlyON)) {
+            String serviceQName = ObjectNameUtil.getServiceQName(dependentReadOnlyON);
+            String refName = ObjectNameUtil.getReferenceName(dependentReadOnlyON);
+            dependentReadOnlyON = ObjectNameUtil.withoutTransactionName( // strip again of transaction name
+                    readableRegistry.lookupConfigBeanByServiceInterfaceName(serviceQName, refName));
+        }
+        return dependentReadOnlyON;
+    }
+
     /**
      * {@inheritDoc}
      */
     //TODO: check for cycles
     @Override
-    public <T> T resolveInstance(Class<T> expectedType, ObjectName dependentON,
+    public <T> T resolveInstance(Class<T> expectedType, ObjectName dependentReadOnlyON,
             JmxAttribute jmxAttribute) {
-        if (expectedType == null || dependentON == null || jmxAttribute == null) {
+        if (expectedType == null || dependentReadOnlyON == null || jmxAttribute == null) {
             throw new IllegalArgumentException(format(
                     "Null parameters not allowed, got {} {} {}", expectedType,
-                    dependentON, jmxAttribute));
+                    dependentReadOnlyON, jmxAttribute));
         }
-
+        dependentReadOnlyON = translateServiceRefIfPossible(dependentReadOnlyON);
         transactionStatus.checkCommitStarted();
         transactionStatus.checkNotCommitted();
 
         ModuleIdentifier dependentModuleIdentifier = ObjectNameUtil.fromON(
-                dependentON, ObjectNameUtil.TYPE_MODULE);
+                dependentReadOnlyON, ObjectNameUtil.TYPE_MODULE);
         Module module = modulesHolder.findModule(dependentModuleIdentifier,
                 jmxAttribute);
         synchronized (this) {
index 645aab37ff770cfc3cbe6399f139a7cf68a07470..afd865c4fc859a1de2e7ea9bbd6885f30be5d036 100644 (file)
@@ -11,6 +11,7 @@ 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.api.ServiceReferenceReadableRegistry;
 import org.opendaylight.controller.config.manager.impl.CommitInfo;
 import org.opendaylight.controller.config.manager.impl.ModuleInternalTransactionalInfo;
 import org.opendaylight.controller.config.manager.impl.TransactionStatus;
@@ -35,11 +36,13 @@ public class DependencyResolverManager implements TransactionHolder, DependencyR
     private final Map<ModuleIdentifier, DependencyResolverImpl> moduleIdentifiersToDependencyResolverMap = new HashMap<>();
     private final ModulesHolder modulesHolder;
     private final TransactionStatus transactionStatus;
+    private final ServiceReferenceReadableRegistry readableRegistry;
 
     public DependencyResolverManager(String transactionName,
-            TransactionStatus transactionStatus) {
+            TransactionStatus transactionStatus, ServiceReferenceReadableRegistry readableRegistry) {
         this.modulesHolder = new ModulesHolder(transactionName);
         this.transactionStatus = transactionStatus;
+        this.readableRegistry = readableRegistry;
     }
 
     @Override
@@ -48,14 +51,11 @@ public class DependencyResolverManager implements TransactionHolder, DependencyR
     }
 
     public synchronized DependencyResolverImpl getOrCreate(ModuleIdentifier name) {
-        DependencyResolverImpl dependencyResolver = moduleIdentifiersToDependencyResolverMap
-                .get(name);
+        DependencyResolverImpl dependencyResolver = moduleIdentifiersToDependencyResolverMap.get(name);
         if (dependencyResolver == null) {
             transactionStatus.checkNotCommitted();
-            dependencyResolver = new DependencyResolverImpl(name,
-                    transactionStatus, modulesHolder);
-            moduleIdentifiersToDependencyResolverMap.put(name,
-                    dependencyResolver);
+            dependencyResolver = new DependencyResolverImpl(name, transactionStatus, modulesHolder, readableRegistry);
+            moduleIdentifiersToDependencyResolverMap.put(name, dependencyResolver);
         }
         return dependencyResolver;
     }
index 09bc1f818fc563ae11e432cec37e148459a2e7dd..d09fc75d7374f4aef55d96a08ebb291322512d4b 100644 (file)
@@ -14,7 +14,7 @@ import javax.management.ObjectName;
 import javax.management.QueryExp;
 import java.util.Set;
 
-public class BaseJMXRegistrator implements AutoCloseable {
+public class BaseJMXRegistrator implements AutoCloseable, NestableJMXRegistrator {
 
     private final InternalJMXRegistrator internalJMXRegistrator;
 
@@ -50,6 +50,11 @@ public class BaseJMXRegistrator implements AutoCloseable {
         return internalJMXRegistrator.getRegisteredObjectNames();
     }
 
+    @Override
+    public InternalJMXRegistrator createChild() {
+        return internalJMXRegistrator.createChild();
+    }
+
     @Override
     public void close() {
         internalJMXRegistrator.close();
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/NestableJMXRegistrator.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/NestableJMXRegistrator.java
new file mode 100644 (file)
index 0000000..ff78e02
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * 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.jmx;
+
+public interface NestableJMXRegistrator {
+
+    InternalJMXRegistrator createChild();
+}
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReference.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReference.java
new file mode 100644 (file)
index 0000000..849f752
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.jmx;
+
+public class ServiceReference {
+    private final String serviceInterfaceName, refName;
+
+    public ServiceReference(String serviceInterfaceName, String refName) {
+        this.serviceInterfaceName = serviceInterfaceName;
+        this.refName = refName;
+    }
+
+    public String getServiceInterfaceName() {
+        return serviceInterfaceName;
+    }
+
+    public String getRefName() {
+        return refName;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ServiceReference that = (ServiceReference) o;
+
+        if (!refName.equals(that.refName)) return false;
+        if (!serviceInterfaceName.equals(that.serviceInterfaceName)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = serviceInterfaceName.hashCode();
+        result = 31 * result + refName.hashCode();
+        return result;
+    }
+}
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReferenceMXBean.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReferenceMXBean.java
new file mode 100644 (file)
index 0000000..759541d
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * 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.jmx;
+
+import javax.management.ObjectName;
+
+public interface ServiceReferenceMXBean {
+
+    ObjectName getCurrentImplementation();
+
+}
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReferenceMXBeanImpl.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReferenceMXBeanImpl.java
new file mode 100644 (file)
index 0000000..dedeeed
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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.jmx;
+
+import javax.management.ObjectName;
+
+public class ServiceReferenceMXBeanImpl implements ServiceReferenceMXBean {
+    private ObjectName currentImplementation;
+
+    public ServiceReferenceMXBeanImpl(ObjectName currentImplementation) {
+        this.currentImplementation = currentImplementation;
+    }
+
+    @Override
+    public ObjectName getCurrentImplementation() {
+        return currentImplementation;
+    }
+
+    public void setCurrentImplementation(ObjectName currentImplementation) {
+        this.currentImplementation = currentImplementation;
+    }
+}
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReferenceRegistrator.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReferenceRegistrator.java
new file mode 100644 (file)
index 0000000..160ee18
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * 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.jmx;
+
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.manager.impl.jmx.InternalJMXRegistrator.InternalJMXRegistration;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+
+public interface ServiceReferenceRegistrator extends AutoCloseable {
+
+    public String getNullableTransactionName();
+
+    ServiceReferenceJMXRegistration registerMBean(ServiceReferenceMXBeanImpl object,
+                                                          ObjectName on) throws InstanceAlreadyExistsException;
+
+    @Override
+    void close();
+
+    public static class ServiceReferenceJMXRegistration implements AutoCloseable {
+        private final InternalJMXRegistration registration;
+
+        ServiceReferenceJMXRegistration(InternalJMXRegistration registration) {
+            this.registration = registration;
+        }
+
+        @Override
+        public void close() {
+            registration.close();
+        }
+    }
+
+    public static interface ServiceReferenceTransactionRegistratorFactory {
+        public ServiceReferenceRegistrator create();
+    }
+
+    public static class ServiceReferenceRegistratorImpl implements ServiceReferenceRegistrator {
+        private final InternalJMXRegistrator currentJMXRegistrator;
+        private final String nullableTransactionName;
+
+        public ServiceReferenceRegistratorImpl(NestableJMXRegistrator parentRegistrator, String nullableTransactionName){
+            currentJMXRegistrator = parentRegistrator.createChild();
+            this.nullableTransactionName = nullableTransactionName;
+        }
+
+        public String getNullableTransactionName() {
+            return nullableTransactionName;
+        }
+
+
+        public ServiceReferenceJMXRegistration registerMBean(ServiceReferenceMXBeanImpl object,
+                                                             ObjectName on) throws InstanceAlreadyExistsException {
+            String actualTransactionName = ObjectNameUtil.getTransactionName(on);
+            boolean broken = false;
+            broken |= (nullableTransactionName == null) != (actualTransactionName == null);
+            broken |= (nullableTransactionName != null) && nullableTransactionName.equals(actualTransactionName) == false;
+            if (broken) {
+                throw new IllegalArgumentException("Transaction name mismatch between expected "
+                        + nullableTransactionName + ", got " + actualTransactionName + " in " + on);
+            }
+            if (ObjectNameUtil.isServiceReference(on) == false) {
+                throw new IllegalArgumentException("Invalid type of " + on);
+            }
+            return new ServiceReferenceJMXRegistration(currentJMXRegistrator.registerMBean(object, on));
+        }
+
+
+        @Override
+        public void close() {
+            currentJMXRegistrator.close();
+        }
+        public static interface ServiceReferenceTransactionRegistratorFactory {
+            public ServiceReferenceRegistrator create();
+        }
+    }
+
+
+    public static class ServiceReferenceTransactionRegistratorFactoryImpl implements ServiceReferenceTransactionRegistratorFactory {
+        private final NestableJMXRegistrator parentRegistrator;
+        private final String nullableTransactionName;
+
+        public ServiceReferenceTransactionRegistratorFactoryImpl(TransactionModuleJMXRegistrator parentRegistrator,
+                                                             String nullableTransactionName) {
+            this.parentRegistrator = parentRegistrator;
+            this.nullableTransactionName = nullableTransactionName;
+        }
+
+        public ServiceReferenceTransactionRegistratorFactoryImpl(BaseJMXRegistrator baseJMXRegistrator) {
+            this.parentRegistrator = baseJMXRegistrator;
+            this.nullableTransactionName = null;
+        }
+
+        public ServiceReferenceRegistrator create() {
+            return new ServiceReferenceRegistratorImpl(parentRegistrator, nullableTransactionName);
+        }
+    }
+}
index 546adb0d8900996e60957a8882bcdd6c79a2eb5c..238fd2447e894149b51246e04692dbe1b19bfaa4 100644 (file)
@@ -17,14 +17,14 @@ import javax.management.QueryExp;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.manager.impl.jmx.InternalJMXRegistrator.InternalJMXRegistration;
 
-public class TransactionModuleJMXRegistrator implements Closeable {
-    private final InternalJMXRegistrator childJMXRegistrator;
+public class TransactionModuleJMXRegistrator implements Closeable, NestableJMXRegistrator {
+    private final InternalJMXRegistrator currentJMXRegistrator;
     private final String transactionName;
 
     public TransactionModuleJMXRegistrator(
             InternalJMXRegistrator internalJMXRegistrator,
             String transactionName) {
-        this.childJMXRegistrator = internalJMXRegistrator.createChild();
+        this.currentJMXRegistrator = internalJMXRegistrator.createChild();
         this.transactionName = transactionName;
     }
 
@@ -44,21 +44,29 @@ public class TransactionModuleJMXRegistrator implements Closeable {
 
     public TransactionModuleJMXRegistration registerMBean(Object object,
             ObjectName on) throws InstanceAlreadyExistsException {
-        if (!transactionName.equals(ObjectNameUtil.getTransactionName(on)))
-            throw new IllegalArgumentException(
-                    "Transaction name mismatch between expected "
+        if (transactionName.equals(ObjectNameUtil.getTransactionName(on)) == false) {
+            throw new IllegalArgumentException("Transaction name mismatch between expected "
                             + transactionName + " " + "and " + on);
-        ObjectNameUtil.checkType(on, ObjectNameUtil.TYPE_MODULE);
+        }
+        ObjectNameUtil.checkTypeOneOf(on, ObjectNameUtil.TYPE_MODULE);
         return new TransactionModuleJMXRegistration(
-                childJMXRegistrator.registerMBean(object, on));
+                currentJMXRegistrator.registerMBean(object, on));
     }
 
     public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
-        return childJMXRegistrator.queryNames(name, query);
+        return currentJMXRegistrator.queryNames(name, query);
     }
 
     @Override
     public void close() {
-        childJMXRegistrator.close();
+        currentJMXRegistrator.close();
+    }
+
+    public String getTransactionName() {
+        return transactionName;
+    }
+
+    public InternalJMXRegistrator createChild() {
+        return currentJMXRegistrator.createChild();
     }
 }
index a7e3fa6c6fa29343f62bffb163fb35719aadae88..b0588a0903956cda35568bcd7b1eda94a528c67f 100644 (file)
@@ -14,6 +14,8 @@ import org.opendaylight.controller.config.manager.impl.factoriesresolver.ModuleF
 import org.opendaylight.controller.config.manager.impl.jmx.BaseJMXRegistrator;
 import org.opendaylight.controller.config.manager.impl.jmx.ConfigRegistryJMXRegistrator;
 import org.opendaylight.controller.config.manager.impl.jmx.InternalJMXRegistrator;
+import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.TestingScheduledThreadPoolImpl;
+import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPool;
 import org.opendaylight.controller.config.spi.Module;
 import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
@@ -84,6 +86,8 @@ public abstract class AbstractConfigTest extends
     public final void cleanUpConfigTransactionManagerImpl() {
         configRegistryJMXRegistrator.close();
         configRegistry.close();
+        TestingFixedThreadPool.cleanUp();
+        TestingScheduledThreadPoolImpl.cleanUp();
     }
 
     /**
diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImplTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImplTest.java
new file mode 100644 (file)
index 0000000..6d0b340
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * 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;
+
+import com.google.common.collect.ImmutableMap;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
+import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceMXBean;
+import org.opendaylight.controller.config.manager.testingservices.parallelapsp.TestingParallelAPSPModuleFactory;
+import org.opendaylight.controller.config.manager.testingservices.parallelapsp.test.AbstractParallelAPSPTest;
+import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.TestingScheduledThreadPoolModuleFactory;
+import org.opendaylight.controller.config.manager.testingservices.seviceinterface.TestingThreadPoolServiceInterface;
+import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPoolModuleFactory;
+import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
+
+import javax.management.Attribute;
+import javax.management.AttributeNotFoundException;
+import javax.management.InstanceNotFoundException;
+import javax.management.JMX;
+import javax.management.MBeanException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.opendaylight.controller.config.api.jmx.ObjectNameUtil.withoutTransactionName;
+
+public class ServiceReferenceRegistryImplTest extends AbstractParallelAPSPTest {
+
+
+    @Before
+    public void setUp() {
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+                new TestingFixedThreadPoolModuleFactory(),
+                new TestingParallelAPSPModuleFactory(),
+                new TestingScheduledThreadPoolModuleFactory()));
+    }
+
+    @Override
+    protected String getThreadPoolImplementationName() {
+        return TestingFixedThreadPoolModuleFactory.NAME;
+    }
+
+    @Test
+    public void test() throws Exception {
+        ConfigTransactionJMXClient transaction1 = configRegistryClient.createTransaction();
+        // create fixed1
+        int fixedNrOfThreads = 20, scheduledNrOfThreads = 30;
+
+        ObjectName fixedTPTransactionON = transaction1.createModule(getThreadPoolImplementationName(), fixed1);
+        platformMBeanServer.setAttribute(fixedTPTransactionON, new Attribute("ThreadCount", fixedNrOfThreads));
+
+        ObjectName scheduledTPTransactionON = transaction1.createModule(
+                TestingScheduledThreadPoolModuleFactory.NAME, "scheduled1");
+        platformMBeanServer.setAttribute(scheduledTPTransactionON, new Attribute("ThreadCount",
+                scheduledNrOfThreads));
+
+        String refName = "ref";
+        ObjectName serviceReference = transaction1.saveServiceReference(TestingThreadPoolServiceInterface.QNAME, refName,
+                fixedTPTransactionON);
+        // create apsp-parallel
+        createParallelAPSP(transaction1, serviceReference);
+        transaction1.commit();
+        // check fixed1 is used
+        ServiceReferenceMXBean serviceReferenceMXBean = JMX.newMXBeanProxy(platformMBeanServer,
+                withoutTransactionName(serviceReference), ServiceReferenceMXBean.class);
+        assertEquals(withoutTransactionName(fixedTPTransactionON), serviceReferenceMXBean.getCurrentImplementation());
+        checkApspThreadCount(fixedNrOfThreads);
+
+        // switch reference to scheduled
+        ConfigTransactionJMXClient transaction2 = configRegistryClient.createTransaction();
+        transaction2.saveServiceReference(TestingThreadPoolServiceInterface.QNAME, refName,
+                ObjectNameUtil.withTransactionName(scheduledTPTransactionON, transaction2.getTransactionName()));
+        transaction2.commit();
+        // check scheduled is used
+        checkApspThreadCount(scheduledNrOfThreads);
+        // check that dummy MXBean points to scheduled
+        assertEquals(withoutTransactionName(scheduledTPTransactionON), serviceReferenceMXBean.getCurrentImplementation());
+
+        // empty transaction
+        configRegistryClient.createTransaction().commit();
+
+        // get service mapping
+        Map<String,Map<String,ObjectName>> serviceMapping = configRegistryClient.getServiceMapping();
+        Map<String,Map<String,ObjectName>> expectedMapping = ImmutableMap.of(TestingThreadPoolServiceInterface.QNAME,
+                (Map<String, ObjectName>)ImmutableMap.of(refName, withoutTransactionName(scheduledTPTransactionON)));
+        assertEquals(expectedMapping, serviceMapping);
+
+        // destroy all
+        ConfigTransactionJMXClient transaction4 = configRegistryClient.createTransaction();
+        Set<ObjectName> objectNames = transaction4.lookupConfigBeans();
+        for(ObjectName on: objectNames) {
+            transaction4.destroyModule(on);
+        }
+        transaction4.commit();
+
+        serviceMapping = configRegistryClient.getServiceMapping();
+        assertTrue(serviceMapping.isEmpty());
+    }
+
+    private void checkApspThreadCount(int fixedNrOfThreads) throws MBeanException, AttributeNotFoundException,
+            InstanceNotFoundException, ReflectionException {
+        ObjectName apspON = ObjectNameUtil.createReadOnlyModuleON(TestingParallelAPSPModuleFactory.NAME, apsp1);
+        assertEquals(fixedNrOfThreads, platformMBeanServer.getAttribute(apspON, "MaxNumberOfThreads"));
+    }
+}
index 65b010532bfe342dd7db6b155ca8190d61e7b5b9..31e70bd84e66dee4bb1aa8b238d6551ac04c705e 100644 (file)
@@ -20,6 +20,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.config.api.JmxAttribute;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.manager.impl.ModuleInternalTransactionalInfo;
 import org.opendaylight.controller.config.manager.impl.TransactionStatus;
@@ -40,7 +41,8 @@ public class DependencyResolverManagerTest {
     @Before
     public void setUp() {
         transactionStatus = mock(TransactionStatus.class);
-        tested = new DependencyResolverManager("txName", transactionStatus);
+        ServiceReferenceReadableRegistry mockedRegistry = mock(ServiceReferenceReadableRegistry.class);
+        tested = new DependencyResolverManager("txName", transactionStatus, mockedRegistry);
         doNothing().when(transactionStatus).checkCommitStarted();
         doNothing().when(transactionStatus).checkNotCommitted();
     }
index 03380392e89c658e276c9af2f65ebbec1529a262..fe322895ab64fd15923680635c77fe765aa651af 100644 (file)
@@ -7,16 +7,19 @@
  */
 package org.opendaylight.controller.config.manager.impl.util;
 
-import java.util.Set;
-
-import javax.management.ObjectName;
-
+import com.google.common.base.Throwables;
+import com.google.common.collect.Sets;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.manager.impl.AbstractLockedPlatformMBeanServerTest;
 
-import com.google.common.base.Throwables;
-import com.google.common.collect.Sets;
+import javax.management.ObjectName;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 
 public class ObjectNameUtilTest extends AbstractLockedPlatformMBeanServerTest {
     private Set<ObjectName> unregisterONs;
@@ -37,7 +40,26 @@ public class ObjectNameUtilTest extends AbstractLockedPlatformMBeanServerTest {
             }
         }
         if (lastException != null) {
-            Throwables.propagate(lastException);
+            throw Throwables.propagate(lastException);
         }
     }
+
+    @Test
+    public void testQuotation() throws Exception {
+        String serviceQName = "(namespace?revision=r)qname";
+        String refName = "refName";
+        String transaction = "transaction";
+        ObjectName serviceReferenceON = ObjectNameUtil.createTransactionServiceON(transaction, serviceQName, refName);
+        assertFalse(serviceReferenceON.isPattern());
+        assertEquals(serviceQName, ObjectNameUtil.getServiceQName(serviceReferenceON));
+        assertEquals(refName, ObjectNameUtil.getReferenceName(serviceReferenceON));
+        assertEquals(transaction, ObjectNameUtil.getTransactionName(serviceReferenceON));
+
+        serviceReferenceON = ObjectNameUtil.createReadOnlyServiceON(serviceQName, refName);
+        assertFalse(serviceReferenceON.isPattern());
+        assertEquals(serviceQName, ObjectNameUtil.getServiceQName(serviceReferenceON));
+        assertEquals(refName, ObjectNameUtil.getReferenceName(serviceReferenceON));
+        assertEquals(null, ObjectNameUtil.getTransactionName(serviceReferenceON));
+
+    }
 }
index 3c55f4dcc05ffaead37a614904de3eed284de874..f4ba5ef887e359b9e5a6ab324ac58cc359ae565f 100644 (file)
@@ -114,8 +114,7 @@ public class TestingParallelAPSPModule implements Module,
 
             if (oldInstance != null) {
                 // changing thread pool is not supported
-                boolean reuse = threadPoolInstance.equals(oldInstance
-                        .getThreadPool());
+                boolean reuse = threadPoolInstance == oldInstance.getThreadPool();
                 if (reuse) {
                     logger.debug("Reusing old instance");
                     instance = oldInstance;
index 3d9d5245ef2886be3eaa937312c247541e50557e..f979a45dd15c8dffcc8297c80502a5287b77a991 100644 (file)
@@ -16,11 +16,11 @@ import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.ObjectName;
 
-abstract class AbstractParallelAPSPTest extends AbstractConfigTest {
+public abstract class AbstractParallelAPSPTest extends AbstractConfigTest {
     protected final String fixed1 = "fixed1";
     protected final String apsp1 = "apsp-parallel";
 
-    abstract String getThreadPoolImplementationName();
+    protected abstract String getThreadPoolImplementationName();
 
     protected ObjectName createParallelAPSP(
             ConfigTransactionJMXClient transaction, ObjectName threadPoolON)
@@ -36,6 +36,7 @@ abstract class AbstractParallelAPSPTest extends AbstractConfigTest {
 
     protected ObjectName createFixed1(ConfigTransactionJMXClient transaction,
             int numberOfThreads) throws InstanceAlreadyExistsException {
+
         ObjectName name = transaction.createModule(
                 getThreadPoolImplementationName(), fixed1);
 
index f9a11301e1aaf09b98d8af43bd965f1f8902e153..978d375cd24df6aff7cb508d4087c9cc1580b696 100644 (file)
@@ -48,7 +48,7 @@ public class DependentWiringTest extends AbstractParallelAPSPTest {
     }
 
     @Override
-    String getThreadPoolImplementationName() {
+    protected String getThreadPoolImplementationName() {
         return TestingFixedThreadPoolModuleFactory.NAME;
     }
 
index e385136abfbc1de0809a8eca94d9af77a5d35efc..642f526efd703730e7c19931496cfb803d0e91cb 100644 (file)
@@ -111,7 +111,7 @@ public class MockedDependenciesTest extends AbstractParallelAPSPTest {
     }
 
     @Override
-    String getThreadPoolImplementationName() {
+    protected String getThreadPoolImplementationName() {
         return threadPoolImplementationName;
     }
 
index 77d1f8bbdfedfca2402b9c310d54cf1413f94340..2b9760cfc4e922fe8663bfd653bc285fc3c1bc4b 100644 (file)
@@ -36,7 +36,7 @@ public class TestingScheduledThreadPoolModule implements Module,
     @Nullable
     private final TestingScheduledThreadPoolImpl oldInstance;
 
-    private final int threadCount = 10;
+    private int threadCount = 10;
     private TestingScheduledThreadPoolImpl instance;
     private RootRuntimeBeanRegistrator runtimeBeanRegistrator;
     private boolean recreate;
@@ -68,6 +68,11 @@ public class TestingScheduledThreadPoolModule implements Module,
         return threadCount;
     }
 
+    @Override
+    public void setThreadCount(int threadCount) {
+        this.threadCount = threadCount;
+    }
+
     @Override
     public Closeable getInstance() {
         assertNotNull(runtimeBeanRegistrator);
index 91a4cff415ac3200366deee7c4324a9755423a89..0a886e5fb0490a663df6429a045d9d23fb2690f0 100644 (file)
@@ -11,8 +11,9 @@ import org.opendaylight.controller.config.api.annotations.AbstractServiceInterfa
 import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
 import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingThreadPoolIfc;
 
-@ServiceInterfaceAnnotation(value = "testing-threadpool", osgiRegistrationType = TestingThreadPoolIfc.class,
-    namespace = "ns", revision = "foo", localName = "bar")
+@ServiceInterfaceAnnotation(value = TestingThreadPoolServiceInterface.QNAME, osgiRegistrationType = TestingThreadPoolIfc.class,
+    namespace = "ns", revision = "foo", localName = "testing-threadpool")
 public interface TestingThreadPoolServiceInterface extends
         AbstractServiceInterface {
+    public static final String QNAME = "(ns?revision=foo)testing-threadpool";
 }
index 8badb75f05c26f0082f00b627eedd91836bd28d5..549ff9ffcfdb9254a4115349d1cbd65520875809 100644 (file)
@@ -148,8 +148,8 @@ public class ConfigRegistryJMXClient implements ConfigRegistryClient {
     }
 
     @Override
-    public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
-        return configRegistryMXBeanProxy.lookupConfigBeanByServiceInterfaceName(serviceInterfaceName, refName);
+    public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
+        return configRegistryMXBeanProxy.lookupConfigBeanByServiceInterfaceName(serviceInterfaceQName, refName);
     }
 
     @Override
@@ -158,8 +158,8 @@ public class ConfigRegistryJMXClient implements ConfigRegistryClient {
     }
 
     @Override
-    public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
-        return configRegistryMXBeanProxy.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName);
+    public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
+        return configRegistryMXBeanProxy.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceQName);
     }
 
     @Override
@@ -201,4 +201,15 @@ public class ConfigRegistryJMXClient implements ConfigRegistryClient {
     public Set<String> getAvailableModuleFactoryQNames() {
         return configRegistryMXBeanProxy.getAvailableModuleFactoryQNames();
     }
+
+    @Override
+    public ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+        return configRegistryMXBeanProxy.getServiceReference(serviceInterfaceQName, refName);
+    }
+
+    @Override
+    public void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+        configRegistryMXBeanProxy.checkServiceReferenceExists(objectName);
+    }
+
 }
index 0db1e5b8224761bc8dbb091f22c1513cf6d5216a..e683d915baea604db86b891e81dc9192b203c4aa 100644 (file)
@@ -164,13 +164,13 @@ public class ConfigTransactionJMXClient implements ConfigTransactionClient {
     }
 
     @Override
-    public void saveServiceReference(String serviceInterfaceName, String refName, ObjectName objectName) throws InstanceNotFoundException {
-        configTransactionControllerMXBeanProxy.saveServiceReference(serviceInterfaceName,refName,objectName);
+    public ObjectName saveServiceReference(String serviceInterfaceName, String refName, ObjectName moduleON) throws InstanceNotFoundException {
+        return configTransactionControllerMXBeanProxy.saveServiceReference(serviceInterfaceName,refName, moduleON);
     }
 
     @Override
-    public boolean removeServiceReference(String serviceInterfaceName, String refName) {
-        return configTransactionControllerMXBeanProxy.removeServiceReference(serviceInterfaceName, refName);
+    public void removeServiceReference(String serviceInterfaceName, String refName) throws InstanceNotFoundException{
+        configTransactionControllerMXBeanProxy.removeServiceReference(serviceInterfaceName, refName);
     }
 
     @Override
@@ -179,8 +179,8 @@ public class ConfigTransactionJMXClient implements ConfigTransactionClient {
     }
 
     @Override
-    public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
-        return configTransactionControllerMXBeanProxy.lookupConfigBeanByServiceInterfaceName(serviceInterfaceName, refName);
+    public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
+        return configTransactionControllerMXBeanProxy.lookupConfigBeanByServiceInterfaceName(serviceInterfaceQName, refName);
     }
 
     @Override
@@ -189,8 +189,8 @@ public class ConfigTransactionJMXClient implements ConfigTransactionClient {
     }
 
     @Override
-    public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
-        return configTransactionControllerMXBeanProxy.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName);
+    public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
+        return configTransactionControllerMXBeanProxy.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceQName);
     }
 
     @Override
@@ -208,6 +208,16 @@ public class ConfigTransactionJMXClient implements ConfigTransactionClient {
         return configTransactionControllerMXBeanProxy.removeServiceReferences(objectName);
     }
 
+    @Override
+    public ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+        return configTransactionControllerMXBeanProxy.getServiceReference(serviceInterfaceQName, refName);
+    }
+
+    @Override
+    public void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+        configTransactionControllerMXBeanProxy.checkServiceReferenceExists(objectName);
+    }
+
     @Override
     public void validateBean(ObjectName configBeanON)
             throws ValidationException {
index 65341714df22e7e13315fbcbd6ca44120bf74664..e0d4c8594375c58739a46c1c27760c1a1c9860a1 100644 (file)
@@ -150,7 +150,7 @@ public class TestingConfigRegistry implements ConfigRegistryMXBean {
     }
 
     @Override
-    public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
+    public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
         throw new UnsupportedOperationException();
     }
 
@@ -160,7 +160,7 @@ public class TestingConfigRegistry implements ConfigRegistryMXBean {
     }
 
     @Override
-    public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
+    public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
         throw new UnsupportedOperationException();
     }
 
@@ -178,4 +178,14 @@ public class TestingConfigRegistry implements ConfigRegistryMXBean {
     public Set<String> getAvailableModuleFactoryQNames() {
         throw new UnsupportedOperationException();
     }
+
+    @Override
+    public ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+        throw new UnsupportedOperationException();
+    }
 }
index 44eb73af79e9c098b343ec7a4debb995e6e44337..4d16f51ae5e8e3068a32a0315dadc82ee16c6f42 100644 (file)
@@ -117,12 +117,12 @@ public class TestingConfigTransactionController implements
     }
 
     @Override
-    public void saveServiceReference(String serviceInterfaceName, String refName, ObjectName objectName) throws InstanceNotFoundException {
+    public ObjectName saveServiceReference(String serviceInterfaceName, String refName, ObjectName moduleON) throws InstanceNotFoundException {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public boolean removeServiceReference(String serviceInterfaceName, String refName) {
+    public void removeServiceReference(String serviceInterfaceName, String refName) {
         throw new UnsupportedOperationException();
     }
 
@@ -132,7 +132,7 @@ public class TestingConfigTransactionController implements
     }
 
     @Override
-    public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
+    public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
         throw new UnsupportedOperationException();
     }
 
@@ -142,7 +142,7 @@ public class TestingConfigTransactionController implements
     }
 
     @Override
-    public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
+    public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
         throw new UnsupportedOperationException();
     }
 
@@ -165,4 +165,14 @@ public class TestingConfigTransactionController implements
     public Set<String> getAvailableModuleFactoryQNames() {
         throw new UnsupportedOperationException();
     }
+
+    @Override
+    public ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+        throw new UnsupportedOperationException();
+    }
 }
index f7197d1582ca70193cb21591922f8c77529a31ed..b32e8bc130b991c5ff2a7ac78a6045b890148e04 100644 (file)
@@ -150,10 +150,7 @@ package ${packageName};
         }
         <#list moduleFields as field>
         <#if field.dependent==true>
-        if (${field.name}Dependency == null) {
-            if (other.${field.name}Dependency != null)
-                return false;
-        } else if (!${field.name}Dependency.equals(other.${field.name}Dependency)) {
+        if (${field.name}Dependency != other.${field.name}Dependency) { // reference to dependency must be same
             return false;
         }
         <#else>