X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fconfig%2Fconfig-manager%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fconfig%2Fmanager%2Fimpl%2Fdynamicmbean%2FAbstractDynamicWrapper.java;h=4a148669b16eaabaf076d41f7f89e56e6169786c;hp=ba2c1089c2bef93bbcacbbc98019c6ab5045043d;hb=0a16f37f1baa4a2616e9b7289a445649b4f3132d;hpb=76b8b1fc0196ec1a2516ae1a682b0b83ef5ca880 diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dynamicmbean/AbstractDynamicWrapper.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dynamicmbean/AbstractDynamicWrapper.java index ba2c1089c2..4a148669b1 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dynamicmbean/AbstractDynamicWrapper.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dynamicmbean/AbstractDynamicWrapper.java @@ -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,25 +38,26 @@ 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 + private static final Logger LOGGER = LoggerFactory .getLogger(AbstractDynamicWrapper.class); protected final boolean writable; @@ -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,10 +97,10 @@ 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); @@ -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 attributeHolderMap, - MBeanOperationInfo[] dOperations, Set> jmxInterfaces) { + Map attributeHolderMap, + MBeanOperationInfo[] dOperations, Set> 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 buildMBeanInfo(Module module, - boolean writable, ModuleIdentifier moduleIdentifier, - Set> jmxInterfaces, MBeanServer internalServer, - ObjectName internalObjectName) { + boolean writable, ModuleIdentifier moduleIdentifier, + Set> jmxInterfaces, MBeanServer internalServer, + ObjectName internalObjectName) { // internal variables for describing MBean elements Set 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); } } @@ -235,7 +234,7 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper { public Object getAttribute(String attributeName) throws AttributeNotFoundException, MBeanException, ReflectionException { - if (attributeName.equals("MBeanInfo")) { + if ("MBeanInfo".equals(attributeName)) { return getMBeanInfo(); } @@ -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 @@ -279,7 +318,7 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper { result.add(new Attribute(attributeName, value)); } catch (Exception e) { - logger.debug("Getting attribute {} failed", attributeName, e); + LOGGER.debug("Getting attribute {} failed", attributeName, e); } } return result; @@ -303,7 +342,7 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper { && signature[0].equals(AttributeList.class.getName())) { return setAttributes((AttributeList) params[0]); } else { - logger.debug("Operation not found {} ", actionName); + LOGGER.debug("Operation not found {} ", actionName); throw new UnsupportedOperationException( format("Operation not found on %s. Method invoke is only supported for getInstance and getAttribute(s) " + "method, got actionName %s, params %s, signature %s ",