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 java.io.Closeable;
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.HashSet;
14 import java.util.List;
17 import javax.annotation.concurrent.GuardedBy;
18 import javax.management.InstanceAlreadyExistsException;
19 import javax.management.JMX;
20 import javax.management.MBeanServer;
21 import javax.management.ObjectName;
22 import javax.management.QueryExp;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
27 public class InternalJMXRegistrator implements Closeable {
28 private static final Logger logger = LoggerFactory
29 .getLogger(InternalJMXRegistrator.class);
30 private final MBeanServer configMBeanServer;
32 public InternalJMXRegistrator(MBeanServer configMBeanServer) {
33 this.configMBeanServer = configMBeanServer;
36 static class InternalJMXRegistration implements AutoCloseable {
37 private final InternalJMXRegistrator internalJMXRegistrator;
38 private final ObjectName on;
40 InternalJMXRegistration(InternalJMXRegistrator internalJMXRegistrator,
42 this.internalJMXRegistrator = internalJMXRegistrator;
48 internalJMXRegistrator.unregisterMBean(on);
53 private final Set<ObjectName> registeredObjectNames = new HashSet<>();
54 private final List<InternalJMXRegistrator> children = new ArrayList<>();
56 public synchronized InternalJMXRegistration registerMBean(Object object,
57 ObjectName on) throws InstanceAlreadyExistsException {
59 configMBeanServer.registerMBean(object, on);
60 } catch (InstanceAlreadyExistsException e) {
62 } catch (Exception e) {
63 throw new RuntimeException(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(
74 "Cannot unregister - ObjectName not found in 'registeredObjectNames': "
77 configMBeanServer.unregisterMBean(on);
78 } catch (Exception e) {
79 throw new RuntimeException(e);
83 public InternalJMXRegistrator createChild() {
84 InternalJMXRegistrator child = new InternalJMXRegistrator(
91 * Allow close to be called multiple times.
94 public synchronized void close() {
96 for (InternalJMXRegistrator child : children) {
99 // close registered ONs
100 for (ObjectName on : registeredObjectNames) {
102 configMBeanServer.unregisterMBean(on);
103 } catch (Exception e) {
104 logger.warn("Ignoring error while unregistering {}", on, e);
107 registeredObjectNames.clear();
110 public <T> T newMBeanProxy(ObjectName objectName, Class<T> interfaceClass) {
111 return JMX.newMBeanProxy(configMBeanServer, objectName, interfaceClass);
114 public <T> T newMBeanProxy(ObjectName objectName, Class<T> interfaceClass,
115 boolean notificationBroadcaster) {
116 return JMX.newMBeanProxy(configMBeanServer, objectName, interfaceClass,
117 notificationBroadcaster);
120 public <T> T newMXBeanProxy(ObjectName objectName, Class<T> interfaceClass) {
122 .newMXBeanProxy(configMBeanServer, objectName, interfaceClass);
125 public <T> T newMXBeanProxy(ObjectName objectName, Class<T> interfaceClass,
126 boolean notificationBroadcaster) {
127 return JMX.newMXBeanProxy(configMBeanServer, objectName,
128 interfaceClass, notificationBroadcaster);
131 public Set<ObjectName> getRegisteredObjectNames() {
132 return Collections.unmodifiableSet(registeredObjectNames);
135 public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
136 Set<ObjectName> result = configMBeanServer.queryNames(name, query);
137 // keep only those that were registered using this instance
138 return getSameNames(result);
141 private Set<ObjectName> getSameNames(Set<ObjectName> superSet) {
142 Set<ObjectName> result = new HashSet<>(superSet);
143 result.retainAll(registeredObjectNames);
144 for (InternalJMXRegistrator child : children) {
145 result.addAll(child.getSameNames(superSet));