Merge "Fixed for bug 1168 : Issue while update subnet"
[controller.git] / opendaylight / config / config-manager / src / main / java / org / opendaylight / controller / config / manager / impl / dynamicmbean / AbstractDynamicWrapper.java
index b7c15706c5293a367739ba8d57a0836d936e728f..7e48af1caae9adc31cb0c76b64a86d0fb7bca428 100644 (file)
@@ -7,16 +7,14 @@
  */
 package org.opendaylight.controller.config.manager.impl.dynamicmbean;
 
-import static java.lang.String.format;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.annotations.Description;
+import org.opendaylight.controller.config.api.annotations.RequireInterface;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
+import org.opendaylight.controller.config.spi.Module;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.management.Attribute;
 import javax.management.AttributeList;
@@ -40,22 +38,23 @@ import javax.management.Notification;
 import javax.management.NotificationListener;
 import javax.management.ObjectName;
 import javax.management.ReflectionException;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
-import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.config.api.annotations.Description;
-import org.opendaylight.controller.config.api.annotations.RequireInterface;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
-import org.opendaylight.controller.config.spi.Module;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import static java.lang.String.format;
 
 /**
  * Contains common code for readable/rw dynamic mbean wrappers. Routes all
  * requests (getAttribute, setAttribute, invoke) into the actual instance, but
  * provides additional functionality - namely it disallows setting attribute on
  * a read only wrapper.
- *
  */
 abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
     private static final Logger logger = LoggerFactory
@@ -71,9 +70,9 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
     protected final MBeanServer internalServer;
 
     public AbstractDynamicWrapper(Module module, boolean writable,
-            ModuleIdentifier moduleIdentifier,
-            ObjectName thisWrapperObjectName, MBeanOperationInfo[] dOperations,
-            MBeanServer internalServer, MBeanServer configMBeanServer) {
+                                  ModuleIdentifier moduleIdentifier,
+                                  ObjectName thisWrapperObjectName, MBeanOperationInfo[] dOperations,
+                                  MBeanServer internalServer, MBeanServer configMBeanServer) {
 
         this.writable = writable;
         this.module = module;
@@ -98,17 +97,17 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
      * case unregister the module and remove listener.
      */
     private final NotificationListener registerActualModule(Module module,
-            final ObjectName thisWrapperObjectName,
-            final ObjectName objectNameInternal,
-            final MBeanServer internalServer,
-            final MBeanServer configMBeanServer) {
+                                                            final ObjectName thisWrapperObjectName,
+                                                            final ObjectName objectNameInternal,
+                                                            final MBeanServer internalServer,
+                                                            final MBeanServer configMBeanServer) {
 
         try {
             internalServer.registerMBean(module, objectNameInternal);
         } catch (InstanceAlreadyExistsException | MBeanRegistrationException
                 | NotCompliantMBeanException | IllegalStateException e) {
             throw new IllegalStateException(
-                    "Error occured during mbean registration ", e);
+                    "Error occured during mbean registration with name " + objectNameInternal, e);
         }
 
         NotificationListener listener = new NotificationListener() {
@@ -116,7 +115,7 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
             public void handleNotification(Notification n, Object handback) {
                 if (n instanceof MBeanServerNotification
                         && n.getType()
-                                .equals(MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) {
+                        .equals(MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) {
                     if (((MBeanServerNotification) n).getMBeanName().equals(
                             thisWrapperObjectName)) {
                         try {
@@ -142,8 +141,8 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
     }
 
     private static MBeanInfo generateMBeanInfo(String className, Module module,
-            Map<String, AttributeHolder> attributeHolderMap,
-            MBeanOperationInfo[] dOperations, Set<Class<?>> jmxInterfaces) {
+                                               Map<String, AttributeHolder> attributeHolderMap,
+                                               MBeanOperationInfo[] dOperations, Set<Class<?>> jmxInterfaces) {
 
         String dDescription = findDescription(module.getClass(), jmxInterfaces);
         MBeanConstructorInfo[] dConstructors = new MBeanConstructorInfo[0];
@@ -170,9 +169,9 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
     // inspect all exported interfaces ending with MXBean, extract getters &
     // setters into attribute holder
     private static Map<String, AttributeHolder> buildMBeanInfo(Module module,
-            boolean writable, ModuleIdentifier moduleIdentifier,
-            Set<Class<?>> jmxInterfaces, MBeanServer internalServer,
-            ObjectName internalObjectName) {
+                                                               boolean writable, ModuleIdentifier moduleIdentifier,
+                                                               Set<Class<?>> jmxInterfaces, MBeanServer internalServer,
+                                                               ObjectName internalObjectName) {
 
         // internal variables for describing MBean elements
         Set<Method> methods = new HashSet<>();
@@ -217,7 +216,7 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
                 }
                 AttributeHolder attributeHolder = new AttributeHolder(
                         attribName, module, attributeMap.get(attribName)
-                                .getType(), writable, ifc, description);
+                        .getType(), writable, ifc, description);
                 attributeHolderMap.put(attribName, attributeHolder);
             }
         }
@@ -246,6 +245,7 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
         } catch (InstanceNotFoundException e) {
             new MBeanException(e);
         }
+
         if (obj instanceof ObjectName) {
             AttributeHolder attributeHolder = attributeHolderMap
                     .get(attributeName);
@@ -254,20 +254,59 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
             }
             return obj;
         }
+
+
+        if (isDependencyListAttr(attributeName, obj)) {
+            obj = fixDependencyListAttribute(obj);
+        }
+
         return obj;
+    }
+
+    private Object fixDependencyListAttribute(Object attribute) {
+        if (attribute.getClass().isArray() == false) {
+            throw new IllegalArgumentException("Unexpected attribute type, should be an array, but was " + attribute.getClass());
+        }
+
+        for (int i = 0; i < Array.getLength(attribute); i++) {
+
+            Object on = Array.get(attribute, i);
+            if (on instanceof ObjectName == false) {
+                throw new IllegalArgumentException("Unexpected attribute type, should be an ObjectName, but was " + on.getClass());
+            }
+            on = fixObjectName((ObjectName) on);
+
+            Array.set(attribute, i, on);
+        }
+
+        return attribute;
+    }
+
+    private boolean isDependencyListAttr(String attributeName, Object attribute) {
+        if (attributeHolderMap.containsKey(attributeName) == false) {
+            return false;
+        }
+
+        AttributeHolder attributeHolder = attributeHolderMap.get(attributeName);
 
+        boolean isDepList = true;
+        isDepList &= attributeHolder.getRequireInterfaceOrNull() != null;
+        isDepList &= attribute instanceof ObjectName[];
+        return isDepList;
     }
 
     protected ObjectName fixObjectName(ObjectName on) {
-        if (!ObjectNameUtil.ON_DOMAIN.equals(on.getDomain()))
+        if (!ObjectNameUtil.ON_DOMAIN.equals(on.getDomain())) {
             throw new IllegalArgumentException("Wrong domain, expected "
                     + ObjectNameUtil.ON_DOMAIN + " setter on " + on);
+        }
         // if on contains transaction name, remove it
         String transactionName = ObjectNameUtil.getTransactionName(on);
-        if (transactionName != null)
+        if (transactionName != null) {
             return ObjectNameUtil.withoutTransactionName(on);
-        else
+        } else {
             return on;
+        }
     }
 
     @Override