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;
12 import javax.annotation.concurrent.ThreadSafe;
13 import javax.management.Attribute;
14 import javax.management.AttributeList;
15 import javax.management.AttributeNotFoundException;
16 import javax.management.DynamicMBean;
17 import javax.management.InstanceNotFoundException;
18 import javax.management.InvalidAttributeValueException;
19 import javax.management.MBeanException;
20 import javax.management.MBeanOperationInfo;
21 import javax.management.MBeanServer;
22 import javax.management.ObjectName;
23 import javax.management.ReflectionException;
25 import org.opendaylight.controller.config.api.ModuleIdentifier;
26 import org.opendaylight.controller.config.api.ValidationException;
27 import org.opendaylight.controller.config.api.annotations.RequireInterface;
28 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
29 import org.opendaylight.controller.config.manager.impl.TransactionIdentifier;
30 import org.opendaylight.controller.config.spi.Module;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
35 * Wraps {@link org.opendaylight.controller.config.spi.Module} instance in a
36 * {@link DynamicMBean} interface. Inspects dependency attributes, identified by
37 * ObjectName getter/setter and {@link RequireInterface} annotation. Used to
38 * simplify client calls - to set a dependency, only instance name is needed.
39 * This class creates new writable String attribute for each dependency with
40 * 'Name' suffix backed by the actual ObjectName attribute.
42 * Thread safety - setting attributes is synchronized on 'this'. Synchronization
43 * of {@link org.opendaylight.controller.config.spi.Module#validate()} and
44 * {@link org.opendaylight.controller.config.spi.Module#getInstance()} is also
46 * {@link org.opendaylight.controller.config.manager.impl.ConfigTransactionControllerInternal}
47 * so the actual {@link org.opendaylight.controller.config.spi.Module} needs not
52 public class DynamicWritableWrapper extends AbstractDynamicWrapper {
53 private static final Logger logger = LoggerFactory
54 .getLogger(DynamicWritableWrapper.class);
56 private final ReadOnlyAtomicBoolean configBeanModificationDisabled;
58 public DynamicWritableWrapper(Module module,
59 ModuleIdentifier moduleIdentifier,
60 TransactionIdentifier transactionIdentifier,
61 ReadOnlyAtomicBoolean configBeanModificationDisabled,
62 MBeanServer internalServer, MBeanServer configMBeanServer) {
63 super(module, true, moduleIdentifier, ObjectNameUtil
64 .createTransactionModuleON(transactionIdentifier.getName(), moduleIdentifier), getOperations(moduleIdentifier),
65 internalServer, configMBeanServer);
66 this.configBeanModificationDisabled = configBeanModificationDisabled;
69 private static MBeanOperationInfo[] getOperations(
70 ModuleIdentifier moduleIdentifier) {
71 Method validationMethod;
73 validationMethod = DynamicWritableWrapper.class.getMethod(
74 "validate", new Class<?>[0]);
75 } catch (NoSuchMethodException e) {
76 throw new IllegalStateException("No such method exception on "
77 + moduleIdentifier, e);
79 return new MBeanOperationInfo[] { new MBeanOperationInfo("Validation",
84 public synchronized void setAttribute(Attribute attribute)
85 throws AttributeNotFoundException, InvalidAttributeValueException,
86 MBeanException, ReflectionException {
87 if (configBeanModificationDisabled.get() == true)
88 throw new IllegalStateException("Operation is not allowed now");
90 if (attribute.getName().equals("Attribute")) {
91 setAttribute((Attribute) attribute.getValue());
96 if (attribute.getValue() instanceof ObjectName) {
97 AttributeHolder attributeHolder = attributeHolderMap
98 .get(attribute.getName());
99 if (attributeHolder.getRequireInterfaceOrNull() != null) {
100 attribute = new Attribute(attribute.getName(),
101 fixObjectName((ObjectName) attribute.getValue()));
103 attribute = new Attribute(attribute.getName(),
104 attribute.getValue());
107 internalServer.setAttribute(objectNameInternal, attribute);
108 } catch (InstanceNotFoundException e) {
109 throw new MBeanException(e);
115 public AttributeList setAttributes(AttributeList attributes) {
116 AttributeList result = new AttributeList();
117 for (Object attributeObject : attributes) {
118 Attribute attribute = (Attribute) attributeObject;
120 setAttribute(attribute);
121 result.add(attribute);
122 } catch (Exception e) {
123 logger.warn("Setting attribute {} failed on {}",
124 attribute.getName(), moduleIdentifier, e);
125 throw new IllegalArgumentException(
126 "Setting attribute failed - " + attribute.getName()
127 + " on " + moduleIdentifier, e);
134 public Object invoke(String actionName, Object[] params, String[] signature)
135 throws MBeanException, ReflectionException {
136 if ("validate".equals(actionName)
137 && (params == null || params.length == 0)
138 && (signature == null || signature.length == 0)) {
141 } catch (Exception e) {
142 throw ValidationException.createForSingleException(
143 moduleIdentifier, e);
147 return super.invoke(actionName, params, signature);
150 public void validate() {