*/
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;
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;
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;
* 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);
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 {
}
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];
// 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<>();
}
AttributeHolder attributeHolder = new AttributeHolder(
attribName, module, attributeMap.get(attribName)
- .getType(), writable, ifc, description);
+ .getType(), writable, ifc, description);
attributeHolderMap.put(attribName, attributeHolder);
}
}
public Object getAttribute(String attributeName)
throws AttributeNotFoundException, MBeanException,
ReflectionException {
- if (attributeName.equals("MBeanInfo")) {
+ if ("MBeanInfo".equals(attributeName)) {
return getMBeanInfo();
}
} catch (InstanceNotFoundException e) {
new MBeanException(e);
}
+
if (obj instanceof ObjectName) {
AttributeHolder attributeHolder = attributeHolderMap
.get(attributeName);
}
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
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;
&& 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 ",