src/share/jaxws_classes/com/sun/org/glassfish/external/amx/AMXGlassfish.java

changeset 0
373ffda63c9a
child 637
9c07ef4934dd
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/jaxws_classes/com/sun/org/glassfish/external/amx/AMXGlassfish.java	Wed Apr 27 01:27:09 2016 +0800
     1.3 @@ -0,0 +1,318 @@
     1.4 +/*
     1.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.  Oracle designates this
    1.11 + * particular file as subject to the "Classpath" exception as provided
    1.12 + * by Oracle in the LICENSE file that accompanied this code.
    1.13 + *
    1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.17 + * version 2 for more details (a copy is included in the LICENSE file that
    1.18 + * accompanied this code).
    1.19 + *
    1.20 + * You should have received a copy of the GNU General Public License version
    1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.23 + *
    1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.25 + * or visit www.oracle.com if you need additional information or have any
    1.26 + * questions.
    1.27 + */
    1.28 +
    1.29 +
    1.30 +package com.sun.org.glassfish.external.amx;
    1.31 +
    1.32 +import javax.management.ObjectName;
    1.33 +import javax.management.MBeanServer;
    1.34 +import javax.management.MBeanServerConnection;
    1.35 +
    1.36 +import java.io.IOException;
    1.37 +
    1.38 +
    1.39 +/**
    1.40 + * AMX behavior specific to Glassfish V3.
    1.41 + */
    1.42 +public final class AMXGlassfish
    1.43 +{
    1.44 +    public static final String DEFAULT_JMX_DOMAIN = "amx";
    1.45 +
    1.46 +    /** Default domain support */
    1.47 +    public static final AMXGlassfish DEFAULT = new AMXGlassfish(DEFAULT_JMX_DOMAIN);
    1.48 +
    1.49 +    private final String     mJMXDomain;
    1.50 +    private final ObjectName mDomainRoot;
    1.51 +
    1.52 +    /** Anything other than {@link #DEFAULT} is not supported in Glassfish V3 */
    1.53 +    public AMXGlassfish(final String jmxDomain)
    1.54 +    {
    1.55 +        mJMXDomain = jmxDomain;
    1.56 +        mDomainRoot = newObjectName("", "domain-root", null);
    1.57 +    }
    1.58 +
    1.59 +    /** Return a version string, or null if not running in Glassfish */
    1.60 +    public static String getGlassfishVersion()
    1.61 +    {
    1.62 +        // must all exist as a check to verify that it's Glassfish V3
    1.63 +        final String version = System.getProperty( "glassfish.version" );
    1.64 +        return version;
    1.65 +    }
    1.66 +
    1.67 +
    1.68 +    /** JMX domain used by AMX MBeans.
    1.69 +     * <p>
    1.70 +     * All MBeans in this domain must be AMX-compliant, see http://tinyurl.com/nryoqp =
    1.71 +    https://glassfish.dev.java.net/nonav/v3/admin/planning/V3Changes/V3_AMX_SPI.html
    1.72 +    */
    1.73 +    public String amxJMXDomain()
    1.74 +    {
    1.75 +        return mJMXDomain;
    1.76 +    }
    1.77 +
    1.78 +    /** JMX domain used by AMX support MBeans.  Private use only */
    1.79 +    public String amxSupportDomain()
    1.80 +    {
    1.81 +        return amxJMXDomain() + "-support";
    1.82 +    }
    1.83 +
    1.84 +    /** name of the Domain Admin Server (DAS) as found in an ObjectName */
    1.85 +    public String dasName()
    1.86 +    {
    1.87 +        return "server";
    1.88 +    }
    1.89 +
    1.90 +    /** name of the Domain Admin Server (DAS) &lt;config> */
    1.91 +    public String dasConfig()
    1.92 +    {
    1.93 +        return dasName() + "-config";
    1.94 +    }
    1.95 +
    1.96 +    /** return the ObjectName of the AMX DomainRoot MBean */
    1.97 +    public ObjectName domainRoot()
    1.98 +    {
    1.99 +        return mDomainRoot;
   1.100 +    }
   1.101 +
   1.102 +    /** ObjectName for top-level monitoring MBean (parent of those for each server) */
   1.103 +    public ObjectName monitoringRoot()
   1.104 +    {
   1.105 +        return newObjectName("/", "mon", null);
   1.106 +    }
   1.107 +
   1.108 +    /** ObjectName for top-level monitoring MBean for specified server */
   1.109 +    public ObjectName serverMon(final String serverName)
   1.110 +    {
   1.111 +        return newObjectName("/mon", "server-mon", serverName);
   1.112 +    }
   1.113 +
   1.114 +    /** ObjectName for top-level monitoring MBean for the DAS. */
   1.115 +    public ObjectName serverMonForDAS() {
   1.116 +        return serverMon( "server" ) ;
   1.117 +    }
   1.118 +
   1.119 +    /** Make a new AMX ObjectName with unchecked exception.
   1.120 +     *  name must be null to create a singleton ObjectName.
   1.121 +     *  Note that the arguments must not contain the characters
   1.122 +     * @param pp The parent part
   1.123 +     * @param type The ObjectName type
   1.124 +     * @param name The ObjectName name
   1.125 +     * @return The objectname with pp, type, and (optionally) name.
   1.126 +     */
   1.127 +    public ObjectName newObjectName(
   1.128 +            final String pp,
   1.129 +            final String type,
   1.130 +            final String name)
   1.131 +    {
   1.132 +        String props = prop(AMX.PARENT_PATH_KEY, pp) + "," + prop(AMX.TYPE_KEY, type);
   1.133 +        if (name != null) {
   1.134 +            props = props + "," + prop(AMX.NAME_KEY, name);
   1.135 +        }
   1.136 +
   1.137 +        return newObjectName( props);
   1.138 +    }
   1.139 +
   1.140 +    /** Make a new ObjectName for AMX domain with unchecked exception */
   1.141 +    public ObjectName newObjectName(final String s)
   1.142 +    {
   1.143 +        String name = s;
   1.144 +        if ( ! name.startsWith( amxJMXDomain() ) ) {
   1.145 +            name = amxJMXDomain() + ":" + name;
   1.146 +        }
   1.147 +
   1.148 +        return AMXUtil.newObjectName( name );
   1.149 +    }
   1.150 +
   1.151 +    private static String prop(final String key, final String value)
   1.152 +    {
   1.153 +        return key + "=" + value;
   1.154 +    }
   1.155 +
   1.156 +    /**
   1.157 +        ObjectName for {@link BootAMXMBean}
   1.158 +     */
   1.159 +    public ObjectName getBootAMXMBeanObjectName()
   1.160 +    {
   1.161 +        return AMXUtil.newObjectName( amxSupportDomain() + ":type=boot-amx" );
   1.162 +    }
   1.163 +
   1.164 +    /**
   1.165 +    Invoke the bootAMX() method on {@link BootAMXMBean}.  Upon return,
   1.166 +    AMX continues to load.
   1.167 +    A cilent should call {@link invokeWaitAMXReady} prior to use.
   1.168 +    */
   1.169 +    public void invokeBootAMX(final MBeanServerConnection conn)
   1.170 +    {
   1.171 +        // start AMX and wait for it to be ready
   1.172 +        try
   1.173 +        {
   1.174 +            conn.invoke( getBootAMXMBeanObjectName(), BootAMXMBean.BOOT_AMX_OPERATION_NAME, null, null);
   1.175 +        }
   1.176 +        catch (final Exception e)
   1.177 +        {
   1.178 +            e.printStackTrace();
   1.179 +            throw new RuntimeException(e);
   1.180 +        }
   1.181 +    }
   1.182 +
   1.183 +    /**
   1.184 +        Invoke the waitAMXReady() method on the DomainRoot MBean, which must already be loaded.
   1.185 +     */
   1.186 +    private static void invokeWaitAMXReady(final MBeanServerConnection conn, final ObjectName objectName)
   1.187 +    {
   1.188 +        try
   1.189 +        {
   1.190 +            conn.invoke( objectName, "waitAMXReady", null, null );
   1.191 +        }
   1.192 +        catch( final Exception e )
   1.193 +        {
   1.194 +            throw new RuntimeException(e);
   1.195 +        }
   1.196 +    }
   1.197 +
   1.198 +      /**
   1.199 +        Listen for the registration of AMX DomainRoot
   1.200 +        Listening starts automatically.
   1.201 +     */
   1.202 +    public <T extends MBeanListener.Callback> MBeanListener<T> listenForDomainRoot(
   1.203 +        final MBeanServerConnection server,
   1.204 +        final T callback)
   1.205 +    {
   1.206 +        final MBeanListener<T> listener = new MBeanListener<T>( server, domainRoot(), callback);
   1.207 +        listener.startListening();
   1.208 +        return listener;
   1.209 +    }
   1.210 +
   1.211 +    private static final class WaitForDomainRootListenerCallback extends MBeanListener.CallbackImpl {
   1.212 +        private final MBeanServerConnection mConn;
   1.213 +
   1.214 +        public WaitForDomainRootListenerCallback( final MBeanServerConnection conn ) {
   1.215 +            mConn = conn;
   1.216 +        }
   1.217 +
   1.218 +        @Override
   1.219 +        public void mbeanRegistered(final ObjectName objectName, final MBeanListener listener) {
   1.220 +            super.mbeanRegistered(objectName,listener);
   1.221 +            invokeWaitAMXReady(mConn, objectName);
   1.222 +            mLatch.countDown();
   1.223 +        }
   1.224 +    }
   1.225 +
   1.226 +    /**
   1.227 +        Wait until AMX has loaded and is ready for use.
   1.228 +        <p>
   1.229 +        This will <em>not</em> cause AMX to load; it will block forever until AMX is ready. In other words,
   1.230 +        don't call this method unless it's a convenient thread that can wait forever.
   1.231 +     */
   1.232 +    public ObjectName waitAMXReady( final MBeanServerConnection server)
   1.233 +    {
   1.234 +        final WaitForDomainRootListenerCallback callback = new WaitForDomainRootListenerCallback(server);
   1.235 +        listenForDomainRoot( server, callback );
   1.236 +        callback.await();
   1.237 +        return callback.getRegistered();
   1.238 +    }
   1.239 +
   1.240 +    /**
   1.241 +        Listen for the registration of the {@link BootAMXMBean}.
   1.242 +        Listening starts automatically.  See {@link AMXBooter#BootAMXCallback}.
   1.243 +     */
   1.244 +    public <T extends MBeanListener.Callback> MBeanListener<T> listenForBootAMX(
   1.245 +        final MBeanServerConnection server,
   1.246 +        final T callback)
   1.247 +    {
   1.248 +        final MBeanListener<T> listener = new MBeanListener<T>( server, getBootAMXMBeanObjectName(), callback);
   1.249 +        listener.startListening();
   1.250 +        return listener;
   1.251 +    }
   1.252 +
   1.253 +    /**
   1.254 +        Callback for {@link MBeanListener} that waits for the BootAMXMBean to appear;
   1.255 +        it always will load early in server startup. Once it has loaded, AMX can be booted
   1.256 +        via {@link #bootAMX}.  A client should normally just call {@link #bootAMX}, but
   1.257 +        this callback may be suclassed if desired, and used as a trigger to
   1.258 +        boot AMX and then take other dependent actions.
   1.259 +     */
   1.260 +    public static class BootAMXCallback extends MBeanListener.CallbackImpl
   1.261 +    {
   1.262 +        private final MBeanServerConnection mConn;
   1.263 +        public BootAMXCallback(final MBeanServerConnection conn)
   1.264 +        {
   1.265 +            mConn = conn;
   1.266 +        }
   1.267 +
   1.268 +        @Override
   1.269 +        public void mbeanRegistered(final ObjectName objectName, final MBeanListener listener)
   1.270 +        {
   1.271 +            super.mbeanRegistered(objectName, listener);
   1.272 +            mLatch.countDown();
   1.273 +        }
   1.274 +    }
   1.275 +
   1.276 +    /**
   1.277 +    Ensure that AMX is loaded and ready to use.  This method returns only when all
   1.278 +    AMX subsystems have been loaded.
   1.279 +    It can be called more than once without ill effect, subsequent calls are ignored.
   1.280 +    @param conn connection to the MBeanServer
   1.281 +    @return the ObjectName of the domain-root MBean
   1.282 +     */
   1.283 +    public ObjectName bootAMX(final MBeanServerConnection conn)
   1.284 +        throws IOException
   1.285 +    {
   1.286 +        final ObjectName domainRoot = domainRoot();
   1.287 +
   1.288 +        if ( !conn.isRegistered( domainRoot ) )
   1.289 +        {
   1.290 +            // wait for the BootAMXMBean to be available (loads at startup)
   1.291 +            final BootAMXCallback callback = new BootAMXCallback(conn);
   1.292 +            listenForBootAMX(conn, callback);
   1.293 +            callback.await(); // block until the MBean appears
   1.294 +
   1.295 +            invokeBootAMX(conn);
   1.296 +
   1.297 +            final WaitForDomainRootListenerCallback drCallback = new WaitForDomainRootListenerCallback(conn);
   1.298 +            listenForDomainRoot(conn, drCallback);
   1.299 +            drCallback.await();
   1.300 +
   1.301 +            invokeWaitAMXReady(conn, domainRoot);
   1.302 +        }
   1.303 +        else
   1.304 +        {
   1.305 +            invokeWaitAMXReady(conn, domainRoot );
   1.306 +        }
   1.307 +        return domainRoot;
   1.308 +    }
   1.309 +
   1.310 +    public ObjectName bootAMX(final MBeanServer server)
   1.311 +    {
   1.312 +        try
   1.313 +        {
   1.314 +            return bootAMX( (MBeanServerConnection)server);
   1.315 +        }
   1.316 +        catch( final IOException e )
   1.317 +        {
   1.318 +            throw new RuntimeException(e);
   1.319 +        }
   1.320 +    }
   1.321 +}

mercurial