aoqi@0: /* aoqi@0: * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: aoqi@0: package com.sun.org.glassfish.external.amx; aoqi@0: aoqi@0: import javax.management.ObjectName; aoqi@0: import javax.management.MBeanServer; aoqi@0: import javax.management.MBeanServerConnection; aoqi@0: aoqi@0: import java.io.IOException; aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * AMX behavior specific to Glassfish V3. aoqi@0: */ aoqi@0: public final class AMXGlassfish aoqi@0: { aoqi@0: public static final String DEFAULT_JMX_DOMAIN = "amx"; aoqi@0: aoqi@0: /** Default domain support */ aoqi@0: public static final AMXGlassfish DEFAULT = new AMXGlassfish(DEFAULT_JMX_DOMAIN); aoqi@0: aoqi@0: private final String mJMXDomain; aoqi@0: private final ObjectName mDomainRoot; aoqi@0: aoqi@0: /** Anything other than {@link #DEFAULT} is not supported in Glassfish V3 */ aoqi@0: public AMXGlassfish(final String jmxDomain) aoqi@0: { aoqi@0: mJMXDomain = jmxDomain; aoqi@0: mDomainRoot = newObjectName("", "domain-root", null); aoqi@0: } aoqi@0: aoqi@0: /** Return a version string, or null if not running in Glassfish */ aoqi@0: public static String getGlassfishVersion() aoqi@0: { aoqi@0: // must all exist as a check to verify that it's Glassfish V3 aoqi@0: final String version = System.getProperty( "glassfish.version" ); aoqi@0: return version; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** JMX domain used by AMX MBeans. aoqi@0: *
aoqi@0: * All MBeans in this domain must be AMX-compliant, see http://tinyurl.com/nryoqp =
aoqi@0: https://glassfish.dev.java.net/nonav/v3/admin/planning/V3Changes/V3_AMX_SPI.html
aoqi@0: */
aoqi@0: public String amxJMXDomain()
aoqi@0: {
aoqi@0: return mJMXDomain;
aoqi@0: }
aoqi@0:
aoqi@0: /** JMX domain used by AMX support MBeans. Private use only */
aoqi@0: public String amxSupportDomain()
aoqi@0: {
aoqi@0: return amxJMXDomain() + "-support";
aoqi@0: }
aoqi@0:
aoqi@0: /** name of the Domain Admin Server (DAS) as found in an ObjectName */
aoqi@0: public String dasName()
aoqi@0: {
aoqi@0: return "server";
aoqi@0: }
aoqi@0:
aoqi@0: /** name of the Domain Admin Server (DAS) <config> */
aoqi@0: public String dasConfig()
aoqi@0: {
aoqi@0: return dasName() + "-config";
aoqi@0: }
aoqi@0:
aoqi@0: /** return the ObjectName of the AMX DomainRoot MBean */
aoqi@0: public ObjectName domainRoot()
aoqi@0: {
aoqi@0: return mDomainRoot;
aoqi@0: }
aoqi@0:
aoqi@0: /** ObjectName for top-level monitoring MBean (parent of those for each server) */
aoqi@0: public ObjectName monitoringRoot()
aoqi@0: {
aoqi@0: return newObjectName("/", "mon", null);
aoqi@0: }
aoqi@0:
aoqi@0: /** ObjectName for top-level monitoring MBean for specified server */
aoqi@0: public ObjectName serverMon(final String serverName)
aoqi@0: {
aoqi@0: return newObjectName("/mon", "server-mon", serverName);
aoqi@0: }
aoqi@0:
aoqi@0: /** ObjectName for top-level monitoring MBean for the DAS. */
aoqi@0: public ObjectName serverMonForDAS() {
aoqi@0: return serverMon( "server" ) ;
aoqi@0: }
aoqi@0:
aoqi@0: /** Make a new AMX ObjectName with unchecked exception.
aoqi@0: * name must be null to create a singleton ObjectName.
aoqi@0: * Note that the arguments must not contain the characters
aoqi@0: * @param pp The parent part
aoqi@0: * @param type The ObjectName type
aoqi@0: * @param name The ObjectName name
aoqi@0: * @return The objectname with pp, type, and (optionally) name.
aoqi@0: */
aoqi@0: public ObjectName newObjectName(
aoqi@0: final String pp,
aoqi@0: final String type,
aoqi@0: final String name)
aoqi@0: {
aoqi@0: String props = prop(AMX.PARENT_PATH_KEY, pp) + "," + prop(AMX.TYPE_KEY, type);
aoqi@0: if (name != null) {
aoqi@0: props = props + "," + prop(AMX.NAME_KEY, name);
aoqi@0: }
aoqi@0:
aoqi@0: return newObjectName( props);
aoqi@0: }
aoqi@0:
aoqi@0: /** Make a new ObjectName for AMX domain with unchecked exception */
aoqi@0: public ObjectName newObjectName(final String s)
aoqi@0: {
aoqi@0: String name = s;
aoqi@0: if ( ! name.startsWith( amxJMXDomain() ) ) {
aoqi@0: name = amxJMXDomain() + ":" + name;
aoqi@0: }
aoqi@0:
aoqi@0: return AMXUtil.newObjectName( name );
aoqi@0: }
aoqi@0:
aoqi@0: private static String prop(final String key, final String value)
aoqi@0: {
aoqi@0: return key + "=" + value;
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: ObjectName for {@link BootAMXMBean}
aoqi@0: */
aoqi@0: public ObjectName getBootAMXMBeanObjectName()
aoqi@0: {
aoqi@0: return AMXUtil.newObjectName( amxSupportDomain() + ":type=boot-amx" );
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: Invoke the bootAMX() method on {@link BootAMXMBean}. Upon return,
aoqi@0: AMX continues to load.
aoqi@0: A cilent should call {@link invokeWaitAMXReady} prior to use.
aoqi@0: */
aoqi@0: public void invokeBootAMX(final MBeanServerConnection conn)
aoqi@0: {
aoqi@0: // start AMX and wait for it to be ready
aoqi@0: try
aoqi@0: {
aoqi@0: conn.invoke( getBootAMXMBeanObjectName(), BootAMXMBean.BOOT_AMX_OPERATION_NAME, null, null);
aoqi@0: }
aoqi@0: catch (final Exception e)
aoqi@0: {
aoqi@0: e.printStackTrace();
aoqi@0: throw new RuntimeException(e);
aoqi@0: }
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: Invoke the waitAMXReady() method on the DomainRoot MBean, which must already be loaded.
aoqi@0: */
aoqi@0: private static void invokeWaitAMXReady(final MBeanServerConnection conn, final ObjectName objectName)
aoqi@0: {
aoqi@0: try
aoqi@0: {
aoqi@0: conn.invoke( objectName, "waitAMXReady", null, null );
aoqi@0: }
aoqi@0: catch( final Exception e )
aoqi@0: {
aoqi@0: throw new RuntimeException(e);
aoqi@0: }
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: Listen for the registration of AMX DomainRoot
aoqi@0: Listening starts automatically.
aoqi@0: */
aoqi@0: public
aoqi@0: This will not cause AMX to load; it will block forever until AMX is ready. In other words,
aoqi@0: don't call this method unless it's a convenient thread that can wait forever.
aoqi@0: */
aoqi@0: public ObjectName waitAMXReady( final MBeanServerConnection server)
aoqi@0: {
aoqi@0: final WaitForDomainRootListenerCallback callback = new WaitForDomainRootListenerCallback(server);
aoqi@0: listenForDomainRoot( server, callback );
aoqi@0: callback.await();
aoqi@0: return callback.getRegistered();
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: Listen for the registration of the {@link BootAMXMBean}.
aoqi@0: Listening starts automatically. See {@link AMXBooter#BootAMXCallback}.
aoqi@0: */
aoqi@0: public