Merge "Added sun.misc to jre.properties"
[controller.git] / opendaylight / config / config-manager / src / main / java / org / opendaylight / controller / config / manager / impl / dependencyresolver / DependencyResolverImpl.java
index 4f60a673f5f711ce17815061318f2641bbda0091..024518ca98f43a544ec2f3f87673033914de3113 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.controller.config.manager.impl.dependencyresolver;
 
 import static java.lang.String.format;
 
+import com.google.common.base.Preconditions;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.Set;
@@ -45,7 +46,7 @@ import org.slf4j.LoggerFactory;
  */
 final class DependencyResolverImpl implements DependencyResolver,
         Comparable<DependencyResolverImpl> {
-    private static final Logger logger = LoggerFactory.getLogger(DependencyResolverImpl.class);
+    private static final Logger LOG = LoggerFactory.getLogger(DependencyResolverImpl.class);
 
     private final ModulesHolder modulesHolder;
     private final ModuleIdentifier name;
@@ -104,12 +105,12 @@ final class DependencyResolverImpl implements DependencyResolver,
                 format("ObjectName should not contain "
                                 + "transaction name. %s set to %s. ", jmxAttribute,
                         dependentReadOnlyON
-                ), jmxAttribute
+            ), jmxAttribute
         );
 
-        dependentReadOnlyON = translateServiceRefIfPossible(dependentReadOnlyON);
+        ObjectName newDependentReadOnlyON = translateServiceRefIfPossible(dependentReadOnlyON);
 
-        ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(dependentReadOnlyON, ObjectNameUtil
+        ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(newDependentReadOnlyON, ObjectNameUtil
                 .TYPE_MODULE);
 
         ModuleFactory foundFactory = modulesHolder.findModuleFactory(moduleIdentifier, jmxAttribute);
@@ -122,7 +123,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, dependentReadOnlyON,
+                    expectedServiceInterface, newDependentReadOnlyON,
                     jmxAttribute
             );
             throw new JmxAttributeValidationException(message, jmxAttribute);
@@ -134,13 +135,14 @@ final class DependencyResolverImpl implements DependencyResolver,
 
     // translate 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
+        ObjectName translatedDependentReadOnlyON = dependentReadOnlyON;
+        if (ObjectNameUtil.isServiceReference(translatedDependentReadOnlyON)) {
+            String serviceQName = ObjectNameUtil.getServiceQName(translatedDependentReadOnlyON);
+            String refName = ObjectNameUtil.getReferenceName(translatedDependentReadOnlyON);
+            translatedDependentReadOnlyON = ObjectNameUtil.withoutTransactionName( // strip again of transaction name
                     readableRegistry.lookupConfigBeanByServiceInterfaceName(serviceQName, refName));
         }
-        return dependentReadOnlyON;
+        return translatedDependentReadOnlyON;
     }
 
     /**
@@ -150,28 +152,17 @@ final class DependencyResolverImpl implements DependencyResolver,
     @Override
     public <T> T resolveInstance(Class<T> expectedType, ObjectName dependentReadOnlyON,
                                  JmxAttribute jmxAttribute) {
-        if (expectedType == null || dependentReadOnlyON == null || jmxAttribute == null) {
-            throw new IllegalArgumentException(format(
-                    "Null parameters not allowed, got %s %s %s", expectedType,
-                    dependentReadOnlyON, jmxAttribute));
-        }
-        dependentReadOnlyON = translateServiceRefIfPossible(dependentReadOnlyON);
-        transactionStatus.checkCommitStarted();
-        transactionStatus.checkNotCommitted();
+        Module module = resolveModuleInstance(dependentReadOnlyON, jmxAttribute);
 
-        ModuleIdentifier dependentModuleIdentifier = ObjectNameUtil.fromON(
-                dependentReadOnlyON, ObjectNameUtil.TYPE_MODULE);
-        Module module = modulesHolder.findModule(dependentModuleIdentifier,
-                jmxAttribute);
         synchronized (this) {
-            dependencies.add(dependentModuleIdentifier);
+            dependencies.add(module.getIdentifier());
         }
         AutoCloseable instance = module.getInstance();
         if (instance == null) {
             String message = format(
                     "Error while %s resolving instance %s. getInstance() returned null. "
                             + "Expected type %s , attribute %s", name,
-                    dependentModuleIdentifier, expectedType, jmxAttribute
+                    module.getIdentifier(), expectedType, jmxAttribute
             );
             throw new JmxAttributeValidationException(message, jmxAttribute);
         }
@@ -187,6 +178,36 @@ final class DependencyResolverImpl implements DependencyResolver,
         }
     }
 
+    private Module resolveModuleInstance(ObjectName dependentReadOnlyON,
+                                 JmxAttribute jmxAttribute) {
+        Preconditions.checkArgument(dependentReadOnlyON != null ,"dependentReadOnlyON");
+        Preconditions.checkArgument(jmxAttribute != null, "jmxAttribute");
+        ObjectName translatedDependentReadOnlyON = translateServiceRefIfPossible(dependentReadOnlyON);
+        transactionStatus.checkCommitStarted();
+        transactionStatus.checkNotCommitted();
+
+        ModuleIdentifier dependentModuleIdentifier = ObjectNameUtil.fromON(
+                translatedDependentReadOnlyON, ObjectNameUtil.TYPE_MODULE);
+
+        return Preconditions.checkNotNull(modulesHolder.findModule(dependentModuleIdentifier, jmxAttribute));
+    }
+
+    @Override
+    public boolean canReuseDependency(ObjectName objectName, JmxAttribute jmxAttribute) {
+        Preconditions.checkNotNull(objectName);
+        Preconditions.checkNotNull(jmxAttribute);
+
+        Module currentModule = resolveModuleInstance(objectName, jmxAttribute);
+        ModuleIdentifier identifier = currentModule.getIdentifier();
+        ModuleInternalTransactionalInfo moduleInternalTransactionalInfo = modulesHolder.findModuleInternalTransactionalInfo(identifier);
+
+        if(moduleInternalTransactionalInfo.hasOldModule()) {
+            Module oldModule = moduleInternalTransactionalInfo.getOldInternalInfo().getReadableModule().getModule();
+            return currentModule.canReuse(oldModule);
+        }
+        return false;
+    }
+
     @Override
     public <T extends BaseIdentity> Class<? extends T> resolveIdentity(IdentityAttributeRef identityRef, Class<T> expectedBaseClass) {
         final QName qName = QName.create(identityRef.getqNameOfIdentity());
@@ -199,7 +220,7 @@ final class DependencyResolverImpl implements DependencyResolver,
         if (expectedBaseClass.isAssignableFrom(deserialized)) {
             return (Class<T>) deserialized;
         } else {
-            logger.error("Cannot resolve class of identity {} : deserialized class {} is not a subclass of {}.",
+            LOG.error("Cannot resolve class of identity {} : deserialized class {} is not a subclass of {}.",
                     identityRef, deserialized, expectedBaseClass);
             throw new IllegalArgumentException("Deserialized identity " + deserialized + " cannot be cast to " + expectedBaseClass);
         }
@@ -216,7 +237,7 @@ final class DependencyResolverImpl implements DependencyResolver,
 
     @Override
     public int compareTo(DependencyResolverImpl o) {
-        transactionStatus.checkCommitted();
+        transactionStatus.checkCommitStarted();
         return Integer.compare(getMaxDependencyDepth(),
                 o.getMaxDependencyDepth());
     }
@@ -231,7 +252,11 @@ final class DependencyResolverImpl implements DependencyResolver,
     }
 
     void countMaxDependencyDepth(DependencyResolverManager manager) {
-        transactionStatus.checkCommitted();
+        // We can calculate the dependency after second phase commit was started
+        // Second phase commit starts after validation and validation adds the dependencies into the dependency resolver, which are necessary for the calculation
+        // FIXME generated code for abstract module declares validate method as non-final
+        // Overriding the validate would cause recreate every time instead of reuse + also possibly wrong close order if there is another module depending
+        transactionStatus.checkCommitStarted();
         if (maxDependencyDepth == null) {
             maxDependencyDepth = getMaxDepth(this, manager,
                     new LinkedHashSet<ModuleIdentifier>());
@@ -277,17 +302,17 @@ final class DependencyResolverImpl implements DependencyResolver,
     @Override
     public Object getAttribute(ObjectName name, String attribute)
             throws MBeanException, AttributeNotFoundException, InstanceNotFoundException, ReflectionException {
-        name = translateServiceRefIfPossible(name);
+        ObjectName newName = translateServiceRefIfPossible(name);
         // add transaction name
-        name = ObjectNameUtil.withTransactionName(name, transactionName);
-        return mBeanServer.getAttribute(name, attribute);
+        newName = ObjectNameUtil.withTransactionName(newName, transactionName);
+        return mBeanServer.getAttribute(newName, attribute);
     }
 
     @Override
     public <T> T newMXBeanProxy(ObjectName name, Class<T> interfaceClass) {
-        name = translateServiceRefIfPossible(name);
+        ObjectName newName = translateServiceRefIfPossible(name);
         // add transaction name
-        name = ObjectNameUtil.withTransactionName(name, transactionName);
-        return JMX.newMXBeanProxy(mBeanServer, name, interfaceClass);
+        newName = ObjectNameUtil.withTransactionName(newName, transactionName);
+        return JMX.newMXBeanProxy(mBeanServer, newName, interfaceClass);
     }
 }