2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.config.manager.impl.dynamicmbean;
10 import java.lang.reflect.Method;
11 import javax.annotation.concurrent.ThreadSafe;
12 import javax.management.Attribute;
13 import javax.management.AttributeList;
14 import javax.management.AttributeNotFoundException;
15 import javax.management.InstanceNotFoundException;
16 import javax.management.InvalidAttributeValueException;
17 import javax.management.MBeanException;
18 import javax.management.MBeanOperationInfo;
19 import javax.management.MBeanServer;
20 import javax.management.ObjectName;
21 import javax.management.ReflectionException;
22 import org.opendaylight.controller.config.api.ModuleIdentifier;
23 import org.opendaylight.controller.config.api.ValidationException;
24 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
25 import org.opendaylight.controller.config.manager.impl.TransactionIdentifier;
26 import org.opendaylight.controller.config.spi.Module;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
31 * Wraps {@link org.opendaylight.controller.config.spi.Module} instance in a
32 * {@link DynamicMBean} interface. Inspects dependency attributes, identified by
33 * ObjectName getter/setter and {@link RequireInterface} annotation. Used to
34 * simplify client calls - to set a dependency, only instance name is needed.
35 * This class creates new writable String attribute for each dependency with
36 * 'Name' suffix backed by the actual ObjectName attribute.
38 * Thread safety - setting attributes is synchronized on 'this'. Synchronization
39 * of {@link org.opendaylight.controller.config.spi.Module#validate()} and
40 * {@link org.opendaylight.controller.config.spi.Module#getInstance()} is also
42 * {@link org.opendaylight.controller.config.manager.impl.ConfigTransactionControllerInternal}
43 * so the actual {@link org.opendaylight.controller.config.spi.Module} needs not
48 public class DynamicWritableWrapper extends AbstractDynamicWrapper {
49 private static final Logger LOG = LoggerFactory
50 .getLogger(DynamicWritableWrapper.class);
52 private final ReadOnlyAtomicBoolean configBeanModificationDisabled;
54 public DynamicWritableWrapper(Module module,
55 ModuleIdentifier moduleIdentifier,
56 TransactionIdentifier transactionIdentifier,
57 ReadOnlyAtomicBoolean configBeanModificationDisabled,
58 MBeanServer internalServer, MBeanServer configMBeanServer) {
59 super(module, true, moduleIdentifier, ObjectNameUtil
60 .createTransactionModuleON(transactionIdentifier.getName(), moduleIdentifier), getOperations(moduleIdentifier),
61 internalServer, configMBeanServer);
62 this.configBeanModificationDisabled = configBeanModificationDisabled;
65 private static MBeanOperationInfo[] getOperations(
66 ModuleIdentifier moduleIdentifier) {
67 Method validationMethod;
69 validationMethod = DynamicWritableWrapper.class.getMethod("validate");
70 } catch (NoSuchMethodException e) {
71 throw new IllegalStateException("No such method exception on " + moduleIdentifier, e);
73 return new MBeanOperationInfo[]{new MBeanOperationInfo("Validation", validationMethod)};
77 public synchronized void setAttribute(Attribute attribute)
78 throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {
79 Attribute newAttribute = attribute;
80 if (configBeanModificationDisabled.get() == true) {
81 throw new IllegalStateException("Operation is not allowed now");
84 if ("Attribute".equals(newAttribute.getName())) {
85 setAttribute((Attribute) newAttribute.getValue());
90 if (newAttribute.getValue() instanceof ObjectName) {
91 newAttribute = fixDependencyAttribute(newAttribute);
92 } else if (newAttribute.getValue() instanceof ObjectName[]) {
93 newAttribute = fixDependencyListAttribute(newAttribute);
96 internalServer.setAttribute(objectNameInternal, newAttribute);
97 } catch (InstanceNotFoundException e) {
98 throw new MBeanException(e);
103 private Attribute fixDependencyListAttribute(Attribute attribute) {
104 Attribute newAttribute = attribute;
105 AttributeHolder attributeHolder = attributeHolderMap.get(newAttribute.getName());
106 if (attributeHolder.getRequireInterfaceOrNull() != null) {
107 newAttribute = new Attribute(newAttribute.getName(), fixObjectNames((ObjectName[]) newAttribute.getValue()));
112 private Attribute fixDependencyAttribute(Attribute attribute) {
113 Attribute newAttribute = attribute;
114 AttributeHolder attributeHolder = attributeHolderMap.get(newAttribute.getName());
115 if (attributeHolder.getRequireInterfaceOrNull() != null) {
116 newAttribute = new Attribute(newAttribute.getName(), fixObjectName((ObjectName) newAttribute.getValue()));
118 newAttribute = new Attribute(newAttribute.getName(), newAttribute.getValue());
123 private ObjectName[] fixObjectNames(ObjectName[] dependencies) {
126 for (ObjectName dependencyOn : dependencies) {
127 dependencies[i++] = fixObjectName(dependencyOn);
134 public AttributeList setAttributes(AttributeList attributes) {
135 AttributeList result = new AttributeList();
136 for (Object attributeObject : attributes) {
137 Attribute attribute = (Attribute) attributeObject;
139 setAttribute(attribute);
140 result.add(attribute);
141 } catch (Exception e) {
142 LOG.warn("Setting attribute {} failed on {}", attribute.getName(), moduleIdentifier, e);
143 throw new IllegalArgumentException(
144 "Setting attribute failed - " + attribute.getName()
145 + " on " + moduleIdentifier, e);
152 public Object invoke(String actionName, Object[] params, String[] signature)
153 throws MBeanException, ReflectionException {
154 if ("validate".equals(actionName)
155 && (params == null || params.length == 0)
156 && (signature == null || signature.length == 0)) {
159 } catch (Exception e) {
161 throw new MBeanException(ValidationException.createForSingleException(
162 moduleIdentifier, e));
166 return super.invoke(actionName, params, signature);
169 public void validate() {