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.DynamicMBean;
16 import javax.management.InstanceNotFoundException;
17 import javax.management.InvalidAttributeValueException;
18 import javax.management.MBeanException;
19 import javax.management.MBeanOperationInfo;
20 import javax.management.MBeanServer;
21 import javax.management.ObjectName;
22 import javax.management.ReflectionException;
23 import org.opendaylight.controller.config.api.ModuleIdentifier;
24 import org.opendaylight.controller.config.api.ValidationException;
25 import org.opendaylight.controller.config.api.annotations.RequireInterface;
26 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
27 import org.opendaylight.controller.config.spi.Module;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
32 * Wraps {@link org.opendaylight.controller.config.spi.Module} instance in a
33 * {@link DynamicMBean} interface. Inspects dependency attributes, identified by
34 * ObjectName getter/setter and {@link RequireInterface} annotation. Used to
35 * simplify client calls - to set a dependency, only instance name is needed.
36 * This class creates new writable String attribute for each dependency with
37 * 'Name' suffix backed by the actual ObjectName attribute.
39 * Thread safety - setting attributes is synchronized on 'this'. Synchronization
40 * of {@link org.opendaylight.controller.config.spi.Module#validate()} and
41 * {@link org.opendaylight.controller.config.spi.Module#getInstance()} is also
43 * org.opendaylight.controller.config.manager.impl.ConfigTransactionControllerInternal
44 * so the actual {@link org.opendaylight.controller.config.spi.Module} needs not
49 public class DynamicWritableWrapper extends AbstractDynamicWrapper {
50 private static final Logger LOG = LoggerFactory
51 .getLogger(DynamicWritableWrapper.class);
53 private final ReadOnlyAtomicBoolean configBeanModificationDisabled;
55 public DynamicWritableWrapper(Module module,
56 ModuleIdentifier moduleIdentifier,
57 String transactionIdentifier,
58 ReadOnlyAtomicBoolean configBeanModificationDisabled,
59 MBeanServer internalServer, MBeanServer configMBeanServer) {
60 super(module, true, moduleIdentifier, ObjectNameUtil
61 .createTransactionModuleON(transactionIdentifier, moduleIdentifier), getOperations(moduleIdentifier),
62 internalServer, configMBeanServer);
63 this.configBeanModificationDisabled = configBeanModificationDisabled;
66 private static MBeanOperationInfo[] getOperations(
67 ModuleIdentifier moduleIdentifier) {
68 Method validationMethod;
70 validationMethod = DynamicWritableWrapper.class.getMethod("validate");
71 } catch (NoSuchMethodException e) {
72 throw new IllegalStateException("No such method exception on " + moduleIdentifier, e);
74 return new MBeanOperationInfo[]{new MBeanOperationInfo("Validation", validationMethod)};
78 public synchronized void setAttribute(Attribute attribute)
79 throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {
80 Attribute newAttribute = attribute;
81 if (configBeanModificationDisabled.get()) {
82 throw new IllegalStateException("Operation is not allowed now");
85 if ("Attribute".equals(newAttribute.getName())) {
86 setAttribute((Attribute) newAttribute.getValue());
91 if (newAttribute.getValue() instanceof ObjectName) {
92 newAttribute = fixDependencyAttribute(newAttribute);
93 } else if (newAttribute.getValue() instanceof ObjectName[]) {
94 newAttribute = fixDependencyListAttribute(newAttribute);
97 internalServer.setAttribute(objectNameInternal, newAttribute);
98 } catch (InstanceNotFoundException e) {
99 throw new MBeanException(e);
104 private Attribute fixDependencyListAttribute(Attribute attribute) {
105 Attribute newAttribute = attribute;
106 AttributeHolder attributeHolder = attributeHolderMap.get(newAttribute.getName());
107 if (attributeHolder.getRequireInterfaceOrNull() != null) {
108 newAttribute = new Attribute(newAttribute.getName(), fixObjectNames((ObjectName[]) newAttribute.getValue()));
113 private Attribute fixDependencyAttribute(Attribute attribute) {
114 Attribute newAttribute = attribute;
115 AttributeHolder attributeHolder = attributeHolderMap.get(newAttribute.getName());
116 if (attributeHolder.getRequireInterfaceOrNull() != null) {
117 newAttribute = new Attribute(newAttribute.getName(), fixObjectName((ObjectName) newAttribute.getValue()));
119 newAttribute = new Attribute(newAttribute.getName(), newAttribute.getValue());
124 private ObjectName[] fixObjectNames(ObjectName[] dependencies) {
127 for (ObjectName dependencyOn : dependencies) {
128 dependencies[i++] = fixObjectName(dependencyOn);
135 public AttributeList setAttributes(AttributeList attributes) {
136 AttributeList result = new AttributeList();
137 for (Object attributeObject : attributes) {
138 Attribute attribute = (Attribute) attributeObject;
140 setAttribute(attribute);
141 result.add(attribute);
142 } catch (Exception e) {
143 LOG.warn("Setting attribute {} failed on {}", attribute.getName(), moduleIdentifier, e);
144 throw new IllegalArgumentException(
145 "Setting attribute failed - " + attribute.getName()
146 + " on " + moduleIdentifier, e);
153 public Object invoke(String actionName, Object[] params, String[] signature)
154 throws MBeanException, ReflectionException {
155 if ("validate".equals(actionName)
156 && (params == null || params.length == 0)
157 && (signature == null || signature.length == 0)) {
160 } catch (Exception e) {
162 throw new MBeanException(ValidationException.createForSingleException(
163 moduleIdentifier, e));
167 return super.invoke(actionName, params, signature);
170 public void validate() {