/* * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ import com.sun.jmx.namespace.ObjectNameRouter; import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR; import java.io.IOException; import java.util.Arrays; import java.util.Map; import java.util.Set; import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.JMX; import javax.management.ListenerNotFoundException; import javax.management.MBeanException; import javax.management.MBeanNotificationInfo; import javax.management.MBeanRegistration; import javax.management.MBeanRegistrationException; import javax.management.MBeanServer; import javax.management.MBeanServerConnection; import javax.management.MalformedObjectNameException; import javax.management.NotCompliantMBeanException; import javax.management.Notification; import javax.management.NotificationBroadcasterSupport; import javax.management.NotificationEmitter; import javax.management.NotificationFilter; import javax.management.NotificationListener; import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.management.ReflectionException; import javax.management.namespace.JMXNamespace; import javax.management.namespace.JMXNamespaces; import javax.management.namespace.JMXRemoteNamespaceMBean; import javax.management.remote.JMXServiceURL; /** * The {@code NamespaceController} MBean makes it possible to easily * create mount points ({@linkplain JMXNamespace JMXNamespaces}) in an * {@code MBeanServer}. * There is at most one instance of NamespaceController in an * MBeanServer - which can be created using the {@link #createInstance * createInstance} method. The {@code NamespaceController} MBean will * make it possible to remotely create name spaces by mounting remote * MBeanServers into the MBeanServer in which it was registered. */ // This API was originally in the draft of javax/management/namespaces // but we decided to retire it. Rather than removing all the associated // tests I have moved the API to the test hierarchy - so it is now used as // an additional (though somewhat complex) test case... // public class NamespaceController implements NamespaceControllerMBean, NotificationEmitter, MBeanRegistration { /** * A logger for this class. **/ private static final Logger LOG = Logger.getLogger(NamespaceController.class.getName()); private static long seqNumber=0; private final NotificationBroadcasterSupport broadcaster = new NotificationBroadcasterSupport(); private volatile MBeanServer mbeanServer = null; private volatile ObjectName objectName = null; //was: NamespaceController.class.getPackage().getName() public static final String NAMESPACE_CONTROLLER_DOMAIN = "jmx.ns"; /** * Creates a new NamespaceController. * Using {@link #createInstance} should be preferred. **/ public NamespaceController() { this(null); } public NamespaceController(MBeanServer mbeanServer) { this.mbeanServer = mbeanServer; } /* * MBeanNotification support * You shouldn't update these methods */ public final void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) { broadcaster.addNotificationListener(listener, filter, handback); } public MBeanNotificationInfo[] getNotificationInfo() { return new MBeanNotificationInfo[] { }; } public final void removeNotificationListener(NotificationListener listener) throws ListenerNotFoundException { broadcaster.removeNotificationListener(listener); } public final void removeNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws ListenerNotFoundException { broadcaster.removeNotificationListener(listener, filter, handback); } public static synchronized long getNextSeqNumber() { return seqNumber++; } protected final void sendNotification(Notification n) { if (n.getSequenceNumber()<=0) n.setSequenceNumber(getNextSeqNumber()); if (n.getSource()==null) n.setSource(objectName); broadcaster.sendNotification(n); } /** * The ObjectName with which this MBean was registered. *
Unless changed by subclasses, this is
* {@code
* "javax.management.namespace:type="+this.getClass().getSimpleName()}.
* @return this MBean's ObjectName, or null if this MBean was never
* registered.
**/
public final ObjectName getObjectName() {
return objectName;
}
/**
* The MBeanServer served by this NamespaceController.
* @return the MBeanServer served by this NamespaceController.
**/
public final MBeanServer getMBeanServer() {
return mbeanServer;
}
/**
* Allows the MBean to perform any operations it needs before being
* registered in the MBean server. If the name of the MBean is not
* specified, the MBean can provide a name for its registration. If
* any exception is raised, the MBean will not be registered in the
* MBean server. Subclasses which override {@code preRegister}
* must call {@code super.preRegister(name,server)};
* @param server The MBean server in which the MBean will be registered.
* @param name The object name of the MBean.
* The name must be either {@code null} - or equal to that
* described by {@link #getObjectName}.
* @return The name under which the MBean is to be registered.
* This will be the name described by {@link #getObjectName}.
* @throws MalformedObjectNameException if the supplied name does not
* meet expected requirements.
*/
public ObjectName preRegister(MBeanServer server, ObjectName name)
throws MalformedObjectNameException {
objectName = name;
final ObjectName single =
ObjectName.getInstance(NAMESPACE_CONTROLLER_DOMAIN+
":type="+this.getClass().getSimpleName());
if (name!=null && !single.equals(name))
throw new MalformedObjectNameException(name.toString());
if (mbeanServer == null) mbeanServer = server;
return single;
}
/**
* Allows the MBean to perform any operations needed after having
* been registered in the MBean server or after the registration has
* failed.
* @param registrationDone Indicates whether or not the MBean has been
* successfully registered in the MBean server. The value false means
* that the registration has failed.
*/
public void postRegister(Boolean registrationDone) {
//TODO postRegister implementation;
}
/**
* Allows the MBean to perform any operations it needs before being
* unregistered by the MBean server.
* @throws Exception This exception will be caught by the MBean server and
* re-thrown as an MBeanRegistrationException.
*/
public void preDeregister() throws Exception {
//TODO preDeregister implementation;
}
/**
* Allows the MBean to perform any operations needed after having been
* unregistered in the MBean server.
*/
public void postDeregister() {
//TODO postDeregister implementation;
}
public String mount(JMXServiceURL url,
String targetPath,
Map The name of the MBean is that returned by {@link #preRegister}
* as described by {@link #getObjectName}.
* @throws IOException if an {@code IOException} is raised when invoking
* the provided connection.
* @throws InstanceAlreadyExistsException if an MBean was already
* registered with the NamespaceController's name.
* @throws MBeanRegistrationException if thrown by {@link
* MBeanServerConnection#createMBean(java.lang.String,javax.management.ObjectName)
* server.createMBean}
* @throws MBeanException if thrown by {@link
* MBeanServerConnection#createMBean(java.lang.String,javax.management.ObjectName)
* server.createMBean}
* @return the {@link ObjectInstance}, as returned by {@link
* MBeanServerConnection#createMBean(java.lang.String,javax.management.ObjectName)
* server.createMBean}
**/
public static ObjectInstance createInstance(MBeanServerConnection server)
throws IOException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException {
try {
final ObjectInstance instance =
server.createMBean(NamespaceController.class.getName(), null);
return instance;
} catch (NotCompliantMBeanException ex) {
throw new RuntimeException("unexpected exception: " + ex, ex);
} catch (ReflectionException ex) {
throw new RuntimeException("unexpected exception: " + ex, ex);
}
}
private final static String ALL_NAMESPACES=
"*"+NAMESPACE_SEPARATOR+":"+
JMXNamespace.TYPE_ASSIGNMENT;
}