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=54f7946db5dbf9fa5e88a554adc3598bc1a47420;hp=6f0d1b2682a00e17b8935cca72c86599cd2b2b63;hb=2d60632f7cf63712e8357a3cf3fc40d83366e5e6;hpb=9212fed678702583f4a555641208cf1c7b45b829 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 6f0d1b2682..54f7946db5 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2013, 2017 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, @@ -7,15 +7,15 @@ */ package org.opendaylight.controller.config.manager.impl.dynamicmbean; -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 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 javax.management.Attribute; import javax.management.AttributeList; import javax.management.AttributeNotFoundException; @@ -38,58 +38,71 @@ 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 static java.lang.String.format; +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; /** * 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 - .getLogger(AbstractDynamicWrapper.class); +public abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper { - protected final boolean writable; protected final Module module; - private final MBeanInfo mbeanInfo; protected final ObjectName objectNameInternal; protected final Map attributeHolderMap; protected final ModuleIdentifier moduleIdentifier; protected final MBeanServer internalServer; - public AbstractDynamicWrapper(Module module, boolean writable, - ModuleIdentifier moduleIdentifier, - ObjectName thisWrapperObjectName, MBeanOperationInfo[] dOperations, - MBeanServer internalServer, MBeanServer configMBeanServer) { + private static final Logger LOG = LoggerFactory.getLogger(AbstractDynamicWrapper.class); - this.writable = writable; + public AbstractDynamicWrapper(final Module module, final boolean writable, final ModuleIdentifier moduleIdentifier, + final ObjectName thisWrapperObjectName, final MBeanOperationInfo[] operations, + final MBeanServer internalServer, final MBeanServer configMBeanServer) { this.module = module; this.moduleIdentifier = moduleIdentifier; this.internalServer = internalServer; this.objectNameInternal = thisWrapperObjectName; // register the actual instance into an mbean server. - registerActualModule(module, thisWrapperObjectName, objectNameInternal, - internalServer, configMBeanServer); - Set> jmxInterfaces = InterfacesHelper.getMXInterfaces(module - .getClass()); - this.attributeHolderMap = buildMBeanInfo(module, writable, - moduleIdentifier, jmxInterfaces, internalServer, - objectNameInternal); - this.mbeanInfo = generateMBeanInfo(module.getClass().getName(), module, - attributeHolderMap, dOperations, jmxInterfaces); + registerActualModule(objectNameInternal, configMBeanServer); + Set> jmxInterfaces = InterfacesHelper.getMXInterfaces(module.getClass()); + this.attributeHolderMap = buildMBeanInfo(writable, moduleIdentifier, jmxInterfaces, objectNameInternal); + this.mbeanInfo = generateMBeanInfo(module, attributeHolderMap, operations, jmxInterfaces); + } + + private static final class ModuleNotificationListener implements NotificationListener { + private final ObjectName objectNameInternal; + private final MBeanServer internalServer; + private final MBeanServer configMBeanServer; + + private ModuleNotificationListener(final ObjectName objectNameInternal, final MBeanServer internalServer, + final MBeanServer configMBeanServer) { + this.objectNameInternal = objectNameInternal; + this.internalServer = internalServer; + this.configMBeanServer = configMBeanServer; + } + + @Override + public void handleNotification(final Notification notification, final Object handback) { + if (notification instanceof MBeanServerNotification + && notification.getType().equals(MBeanServerNotification.UNREGISTRATION_NOTIFICATION) + && ((MBeanServerNotification) notification).getMBeanName().equals(objectNameInternal)) { + try { + internalServer.unregisterMBean(objectNameInternal); + configMBeanServer.removeNotificationListener(MBeanServerDelegate.DELEGATE_NAME, this); + } catch (MBeanRegistrationException | ListenerNotFoundException | InstanceNotFoundException e) { + throw new IllegalStateException(e); + } + } + } } /** @@ -97,69 +110,43 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper { * platform mbean server. Wait until this wrapper gets unregistered, in that * case unregister the module and remove listener. */ - private final NotificationListener registerActualModule(Module module, - final ObjectName thisWrapperObjectName, - final ObjectName objectNameInternal, - final MBeanServer internalServer, + private NotificationListener registerActualModule(final ObjectName internalObjectName, final MBeanServer configMBeanServer) { - try { - internalServer.registerMBean(module, objectNameInternal); - } catch (InstanceAlreadyExistsException | MBeanRegistrationException - | NotCompliantMBeanException | IllegalStateException e) { - throw new IllegalStateException( - "Error occured during mbean registration with name " + objectNameInternal, e); + internalServer.registerMBean(module, internalObjectName); + } catch (InstanceAlreadyExistsException | MBeanRegistrationException | NotCompliantMBeanException + | IllegalStateException e) { + throw new IllegalStateException("Error occured during mbean registration with name " + internalObjectName, + e); } - NotificationListener listener = new NotificationListener() { - @Override - public void handleNotification(Notification n, Object handback) { - if (n instanceof MBeanServerNotification - && n.getType() - .equals(MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) { - if (((MBeanServerNotification) n).getMBeanName().equals( - thisWrapperObjectName)) { - try { - internalServer.unregisterMBean(objectNameInternal); - configMBeanServer.removeNotificationListener( - MBeanServerDelegate.DELEGATE_NAME, this); - } catch (MBeanRegistrationException - | ListenerNotFoundException - | InstanceNotFoundException e) { - throw new IllegalStateException(e); - } - } - } - } - }; + NotificationListener listener = new ModuleNotificationListener(internalObjectName, internalServer, + configMBeanServer); try { - configMBeanServer.addNotificationListener( - MBeanServerDelegate.DELEGATE_NAME, listener, null, null); - } catch (InstanceNotFoundException e) { + configMBeanServer.addNotificationListener(MBeanServerDelegate.DELEGATE_NAME, listener, null, null); + } catch (final InstanceNotFoundException e) { throw new RuntimeException("Could not add notification listener", e); } return listener; } - private static MBeanInfo generateMBeanInfo(String className, Module module, - Map attributeHolderMap, - MBeanOperationInfo[] dOperations, Set> jmxInterfaces) { + private static MBeanInfo generateMBeanInfo(final Module module, + final Map attributeHolderMap, final MBeanOperationInfo[] operations, + final Set> jmxInterfaces) { - String dDescription = findDescription(module.getClass(), jmxInterfaces); - MBeanConstructorInfo[] dConstructors = new MBeanConstructorInfo[0]; - List attributes = new ArrayList<>( - attributeHolderMap.size()); + String description = findDescription(module.getClass(), jmxInterfaces); + MBeanConstructorInfo[] constructors = new MBeanConstructorInfo[0]; + List attributes = new ArrayList<>(attributeHolderMap.size()); for (AttributeHolder attributeHolder : attributeHolderMap.values()) { attributes.add(attributeHolder.toMBeanAttributeInfo()); } - return new MBeanInfo(className, dDescription, - attributes.toArray(new MBeanAttributeInfo[0]), dConstructors, - dOperations, new MBeanNotificationInfo[0]); + return new MBeanInfo(module.getClass().getName(), description, attributes.toArray(new MBeanAttributeInfo[0]), + constructors, operations, new MBeanNotificationInfo[0]); } - static String findDescription(Class clazz, Set> jmxInterfaces) { - List descriptions = AnnotationsHelper - .findClassAnnotationInSuperClassesAndIfcs(clazz, Description.class, jmxInterfaces); + static String findDescription(final Class clazz, final Set> jmxInterfaces) { + List descriptions = AnnotationsHelper.findClassAnnotationInSuperClassesAndIfcs(clazz, + Description.class, jmxInterfaces); return AnnotationsHelper.aggregateDescriptions(descriptions); } @@ -169,10 +156,8 @@ 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) { + private Map buildMBeanInfo(final boolean writable, final ModuleIdentifier modId, + final Set> jmxInterfaces, final ObjectName internalObjectName) { // internal variables for describing MBean elements Set methods = new HashSet<>(); @@ -185,8 +170,7 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper { MBeanInfo internalInfo; try { internalInfo = internalServer.getMBeanInfo(internalObjectName); - } catch (InstanceNotFoundException | ReflectionException - | IntrospectionException e) { + } catch (InstanceNotFoundException | ReflectionException | IntrospectionException e) { throw new RuntimeException("MBean info not found", e); } @@ -194,34 +178,28 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper { for (MBeanAttributeInfo a : internalInfo.getAttributes()) { attributeMap.put(a.getName(), a); } - Map attributeHolderMap = new HashMap<>(); + Map attributeHolderMapLocal = new HashMap<>(); for (Method method : methods) { - if (method.getParameterTypes().length == 1 - && method.getName().startsWith("set")) { + if (method.getParameterTypes().length == 1 && method.getName().startsWith("set")) { Method setter; String attribName = method.getName().substring(3); try { - setter = module.getClass().getMethod(method.getName(), - method.getParameterTypes()); - } catch (NoSuchMethodException e) { - throw new RuntimeException("No such method on " - + moduleIdentifier, e); + setter = module.getClass().getMethod(method.getName(), method.getParameterTypes()); + } catch (final NoSuchMethodException e) { + throw new RuntimeException("No such method on " + modId, e); } - RequireInterface ifc = AttributeHolder - .findRequireInterfaceAnnotation(setter, jmxInterfaces); + RequireInterface ifc = AttributeHolder.findRequireInterfaceAnnotation(setter, jmxInterfaces); String description = null; if (ifc != null) { - description = AttributeHolder.findDescription(setter, - jmxInterfaces); + description = AttributeHolder.findDescription(setter, jmxInterfaces); } - AttributeHolder attributeHolder = new AttributeHolder( - attribName, module, attributeMap.get(attribName) - .getType(), writable, ifc, description); - attributeHolderMap.put(attribName, attributeHolder); + AttributeHolder attributeHolder = new AttributeHolder(attribName, module, + attributeMap.get(attribName).getType(), writable, ifc, description); + attributeHolderMapLocal.put(attribName, attributeHolder); } } - return attributeHolderMap; + return attributeHolderMapLocal; } // DynamicMBean methods @@ -232,47 +210,47 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper { } @Override - public Object getAttribute(String attributeName) - throws AttributeNotFoundException, MBeanException, - ReflectionException { - if (attributeName.equals("MBeanInfo")) { + public Object getAttribute(final String attributeName) + throws AttributeNotFoundException, MBeanException, ReflectionException { + if ("MBeanInfo".equals(attributeName)) { return getMBeanInfo(); } Object obj = null; try { - obj = internalServer - .getAttribute(objectNameInternal, attributeName); - } catch (InstanceNotFoundException e) { - new MBeanException(e); + obj = internalServer.getAttribute(objectNameInternal, attributeName); + } catch (final InstanceNotFoundException e) { + throw new MBeanException(e); } if (obj instanceof ObjectName) { - AttributeHolder attributeHolder = attributeHolderMap - .get(attributeName); + AttributeHolder attributeHolder = attributeHolderMap.get(attributeName); if (attributeHolder.getRequireInterfaceOrNull() != null) { obj = fixObjectName((ObjectName) obj); } return obj; } - - if(isDependencyListAttr(attributeName, 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()); + private Object fixDependencyListAttribute(final Object attribute) { + if (!attribute.getClass().isArray()) { + 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()); + if (!(on instanceof ObjectName)) { + throw new IllegalArgumentException( + "Unexpected attribute type, should be an ObjectName, but was " + on.getClass()); + } on = fixObjectName((ObjectName) on); Array.set(attribute, i, on); @@ -281,9 +259,10 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper { return attribute; } - private boolean isDependencyListAttr(String attributeName, Object attribute) { - if (attributeHolderMap.containsKey(attributeName) == false) + private boolean isDependencyListAttr(final String attributeName, final Object attribute) { + if (!attributeHolderMap.containsKey(attributeName)) { return false; + } AttributeHolder attributeHolder = attributeHolderMap.get(attributeName); @@ -293,43 +272,43 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper { return isDepList; } - protected ObjectName fixObjectName(ObjectName on) { - if (!ObjectNameUtil.ON_DOMAIN.equals(on.getDomain())) - throw new IllegalArgumentException("Wrong domain, expected " - + ObjectNameUtil.ON_DOMAIN + " setter on " + on); + protected ObjectName fixObjectName(final ObjectName on) { + 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 - return on; + } + + return on; } @Override - public AttributeList getAttributes(String[] attributes) { + public AttributeList getAttributes(final String[] attributes) { AttributeList result = new AttributeList(); for (String attributeName : attributes) { + Object value; try { - Object value = getAttribute(attributeName); + value = getAttribute(attributeName); result.add(new Attribute(attributeName, value)); - - } catch (Exception e) { - logger.debug("Getting attribute {} failed", attributeName, e); + } catch (AttributeNotFoundException | MBeanException | ReflectionException e) { + LOG.debug("Getting attribute {} failed", attributeName, e); } } return result; } @Override - public Object invoke(String actionName, Object[] params, String[] signature) + public Object invoke(final String actionName, final Object[] params, final String[] signature) throws MBeanException, ReflectionException { - if ("getAttribute".equals(actionName) && params.length == 1 - && signature[0].equals(String.class.getName())) { + if ("getAttribute".equals(actionName) && params.length == 1 && signature[0].equals(String.class.getName())) { try { return getAttribute((String) params[0]); - } catch (AttributeNotFoundException e) { - throw new MBeanException(e, "Attribute not found on " - + moduleIdentifier); + } catch (final AttributeNotFoundException e) { + throw new MBeanException(e, "Attribute not found on " + moduleIdentifier); } } else if ("getAttributes".equals(actionName) && params.length == 1 && signature[0].equals(String[].class.getName())) { @@ -338,11 +317,11 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper { && signature[0].equals(AttributeList.class.getName())) { return setAttributes((AttributeList) params[0]); } else { - 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) " + LOG.debug("Operation not found {} ", actionName); + throw new UnsupportedOperationException(String.format( + "Operation not found on %s. Method invoke is only supported for getInstance and getAttribute(s) " + "method, got actionName %s, params %s, signature %s ", - moduleIdentifier, actionName, params, signature)); + moduleIdentifier, actionName, params, signature)); } } @@ -352,7 +331,7 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper { } @Override - public final boolean equals(Object other) { + public final boolean equals(final Object other) { return module.equals(other); }