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.jmx;
10 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory;
13 import javax.annotation.concurrent.GuardedBy;
14 import javax.management.InstanceAlreadyExistsException;
15 import javax.management.InstanceNotFoundException;
16 import javax.management.JMX;
17 import javax.management.MBeanRegistrationException;
18 import javax.management.MBeanServer;
19 import javax.management.NotCompliantMBeanException;
20 import javax.management.ObjectName;
21 import javax.management.QueryExp;
22 import java.io.Closeable;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.HashSet;
26 import java.util.List;
29 public class InternalJMXRegistrator implements Closeable {
30 private static final Logger logger = LoggerFactory
31 .getLogger(InternalJMXRegistrator.class);
32 private final MBeanServer configMBeanServer;
34 public InternalJMXRegistrator(MBeanServer configMBeanServer) {
35 this.configMBeanServer = configMBeanServer;
38 static class InternalJMXRegistration implements AutoCloseable {
39 private final InternalJMXRegistrator internalJMXRegistrator;
40 private final ObjectName on;
42 InternalJMXRegistration(InternalJMXRegistrator internalJMXRegistrator,
44 this.internalJMXRegistrator = internalJMXRegistrator;
50 internalJMXRegistrator.unregisterMBean(on);
55 private final Set<ObjectName> registeredObjectNames = new HashSet<>();
56 private final List<InternalJMXRegistrator> children = new ArrayList<>();
58 public synchronized InternalJMXRegistration registerMBean(Object object,
59 ObjectName on) throws InstanceAlreadyExistsException {
61 configMBeanServer.registerMBean(object, on);
62 } catch (MBeanRegistrationException | NotCompliantMBeanException e) {
63 throw new IllegalStateException(e);
65 registeredObjectNames.add(on);
66 return new InternalJMXRegistration(this, on);
69 private synchronized void unregisterMBean(ObjectName on) {
70 // first check that on was registered using this instance
71 boolean removed = registeredObjectNames.remove(on);
73 throw new IllegalStateException("Cannot unregister - ObjectName not found in 'registeredObjectNames': " + on);
76 configMBeanServer.unregisterMBean(on);
77 } catch (InstanceNotFoundException | MBeanRegistrationException e) {
78 throw new IllegalStateException(e);
82 public InternalJMXRegistrator createChild() {
83 InternalJMXRegistrator child = new InternalJMXRegistrator(
90 * Allow close to be called multiple times.
93 public synchronized void close() {
95 for (InternalJMXRegistrator child : children) {
98 // close registered ONs
99 for (ObjectName on : registeredObjectNames) {
101 configMBeanServer.unregisterMBean(on);
102 } catch (Exception e) {
103 logger.warn("Ignoring error while unregistering {}", on, e);
106 registeredObjectNames.clear();
109 public <T> T newMBeanProxy(ObjectName objectName, Class<T> interfaceClass) {
110 return JMX.newMBeanProxy(configMBeanServer, objectName, interfaceClass);
113 public <T> T newMBeanProxy(ObjectName objectName, Class<T> interfaceClass,
114 boolean notificationBroadcaster) {
115 return JMX.newMBeanProxy(configMBeanServer, objectName, interfaceClass,
116 notificationBroadcaster);
119 public <T> T newMXBeanProxy(ObjectName objectName, Class<T> interfaceClass) {
121 .newMXBeanProxy(configMBeanServer, objectName, interfaceClass);
124 public <T> T newMXBeanProxy(ObjectName objectName, Class<T> interfaceClass,
125 boolean notificationBroadcaster) {
126 return JMX.newMXBeanProxy(configMBeanServer, objectName,
127 interfaceClass, notificationBroadcaster);
130 public Set<ObjectName> getRegisteredObjectNames() {
131 return Collections.unmodifiableSet(registeredObjectNames);
134 public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
135 Set<ObjectName> result = configMBeanServer.queryNames(name, query);
136 // keep only those that were registered using this instance
137 return getSameNames(result);
140 private Set<ObjectName> getSameNames(Set<ObjectName> superSet) {
141 Set<ObjectName> result = new HashSet<>(superSet);
142 result.retainAll(registeredObjectNames);
143 for (InternalJMXRegistrator child : children) {
144 result.addAll(child.getSameNames(superSet));