/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package amxtest;
import java.util.Properties;
import java.util.Set;
import java.util.HashSet;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.net.MalformedURLException;
import java.io.IOException;
import javax.management.ObjectName;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.MBeanServerDelegateMBean;
import javax.management.MBeanServerNotification;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import org.glassfish.admin.amx.base.*;
import org.glassfish.admin.amx.core.*;
import org.glassfish.admin.amx.core.proxy.ProxyFactory;
import org.glassfish.admin.amx.config.AMXConfigProxy;
import org.glassfish.admin.amx.util.TimingDelta;
import org.glassfish.admin.amx.util.ListUtil;
import org.glassfish.admin.amx.util.ExceptionUtil;
import org.glassfish.admin.amx.util.jmx.JMXUtil;
import org.glassfish.external.amx.AMXGlassfish;
/** Demonstration AMX java client */
public final class Demo {
final String mAdminUser;
final String mAdminPassword;
final String mHost;
final int mPort;
final boolean mDebug;
private final MBeanServerConnection mMBeanServerConnection;
private final ProxyFactory mProxyFactory;
private final DomainRoot mDomainRoot;
private final MBeansListener mListener;
private final boolean mPrintln;
private final Query mQueryMgr;
/**
Get a connection to the server, and setup various high-level MBean proxies.
*/
Demo(
final boolean emitMessages,
final String host,
final String port,
final String user,
final String password ) throws Exception
{
mPrintln = emitMessages;
mDebug = true;
mHost = host;
mPort = Integer.parseInt(port);
mAdminUser = user;
mAdminPassword = password;
mMBeanServerConnection = _getMBeanServerConnection(mHost, mPort);
mProxyFactory = ProxyFactory.getInstance(mMBeanServerConnection);
mDomainRoot = mProxyFactory.getDomainRootProxy();
mQueryMgr = mDomainRoot.getQueryMgr();
mListener = new MBeansListener(mMBeanServerConnection, mDomainRoot.objectName().getDomain());
mListener.startListening();
println( "Demo: " + host + ":" + port + " as {" + user + "," + password + "}" );
}
private static String getArg(final String name, final String defaultValue, final String[] args )
{
String value = defaultValue;
for( final String arg : args )
{
if ( arg == null ) continue;
if ( arg.startsWith(name) || arg.startsWith("--" + name) )
{
final int idx = arg.indexOf("=");
value = arg.substring(idx+1);
break;
}
}
return value;
}
/**
Run the demo.
*/
public static void runDemo( final boolean emitMessages, final String[] args )
{
final String host = getArg("host", "localhost", args);
final String port = getArg("port", "8686", args);
final String user = getArg("user", "admin", args);
final String password = getArg("password", "changeit", args);
try
{
final Demo demo = new Demo(emitMessages, host, port, user, password);
demo.run();
}
catch( final Throwable t )
{
t.printStackTrace();
}
}
public static void main( final String[] args )
{
runDemo( true, args );
}
private void run()
{
final Set<AMXProxy> amxMBeans = mQueryMgr.queryAll();
println( "AMX MBeans: " + amxMBeans.size() );
println( "AMX config MBeans: " + getAllConfig().size() );
}
/** get all AMX MBeans that were found when the test started
Caller should use the QueryMgr if a fresh set is needed */
protected Set<AMXProxy> getAllAMX()
{
final Set<AMXProxy> allAMX = mQueryMgr.queryAll();
assert allAMX.size() >= 30;
return allAMX;
}
/** get all AMX MBeans with the specified interface */
protected <T> Set<T> getAll(final Class<T> intf)
{
return getAll(getAllAMX(), intf);
}
/** Filter all AMXProxy with the specified interface */
protected <T> Set<T> getAll(final Set<AMXProxy> all, final Class<T> intf)
{
final Set<T> result = new HashSet<T>();
for (final AMXProxy amx : all)
{
if (intf.isAssignableFrom(amx.getClass()))
{
result.add(intf.cast(amx));
}
}
return result;
}
private static MBeanServerConnection _getMBeanServerConnection(final String host, final int port)
throws MalformedURLException, IOException
{
final long start = System.currentTimeMillis();
final String urlStr = "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi";
final JMXServiceURL url = new JMXServiceURL(urlStr);
final JMXConnector jmxConn = JMXConnectorFactory.connect(url);
//debug( "Demo: connecting to: " + url );
final MBeanServerConnection conn = jmxConn.getMBeanServerConnection();
conn.getDomains(); // sanity check
try
{
final ObjectName domainRootObjectName = AMXGlassfish.DEFAULT.bootAMX(conn);
}
catch( final Exception e )
{
System.err.println( ExceptionUtil.toString(ExceptionUtil.getRootCause(e)) );
}
//debug( "Demo: got connection, verified connectivity: " + (System.currentTimeMillis() - start));
return conn;
}
/** Find all AMX MBeans of the specified type */
protected Set<AMXProxy> findAllContainingType( final String type )
{
final Set<AMXProxy> all = mQueryMgr.queryAll();
final Set<AMXProxy> parentsWith = new HashSet<AMXProxy>();
for( final AMXProxy amx : all )
{
if ( amx.type().equals(type) )
{
final AMXProxy parent = amx.parent();
parentsWith.add(parent);
}
}
return parentsWith;
}
/** Get all AMX MBeans that are descendendts of the specified MBean */
protected <T extends AMXProxy> List<T> getAllDescendents( final AMXProxy top, final Class<T> clazz)
{
final AMXProxy[] a = mQueryMgr.queryDescendants( top.objectName() );
final List<AMXProxy> list = ListUtil.newListFromArray(a);
return Util.asProxyList( list, clazz );
}
/** Get all config MBeans */
List<AMXConfigProxy> getAllConfig()
{
return getAllDescendents( mDomainRoot, AMXConfigProxy.class);
}
/** Get all monitoring MBeans */
List<AMXProxy> getAllMonitoring()
{
return getAllDescendents( mDomainRoot.getMonitoringRoot(), AMXProxy.class);
}
/**
Listen to MBeans for Notifications.
*/
final class MBeansListener implements NotificationListener
{
private final MBeanServerConnection mServer;
private final String mDomain;
private final List<ObjectName> mRegistered = Collections.synchronizedList(new ArrayList<ObjectName>());
private final List<ObjectName> mUnregistered = Collections.synchronizedList(new ArrayList<ObjectName>());
public MBeansListener(final MBeanServerConnection server, final String domain)
{
mServer = server;
mDomain = domain;
}
public void startListening()
{
final ObjectName delegate = JMXUtil.newObjectName( JMXUtil.MBEAN_SERVER_DELEGATE );
try
{
mServer.addNotificationListener( delegate, this, null, null);
}
catch( final Exception e )
{
throw new RuntimeException(e);
}
}
public void handleNotification(
final Notification notif,
final Object handback)
{
if ( ! (notif instanceof MBeanServerNotification) )
{
return;
}
final MBeanServerNotification mbs = (MBeanServerNotification)notif;
final ObjectName objectName = mbs.getMBeanName();
if ( "*".equals(mDomain) || mDomain.equals(objectName.getDomain()) )
{
if ( mbs.getType().equals(MBeanServerNotification.REGISTRATION_NOTIFICATION ) )
{
// debug( "Registered: " + objectName );
mRegistered.add( objectName );
}
else if ( mbs.getType().equals(MBeanServerNotification.UNREGISTRATION_NOTIFICATION ) )
{
// debug( "Unregistered: " + objectName );
mUnregistered.add( objectName );
}
}
}
}
protected void debug(final String s) {
System.out.println("" + s);
}
protected void println(final String s) {
if ( mPrintln ) {
System.out.println("" + s);
}
}
protected void warning(final String s) {
if ( mPrintln ) {
System.out.println("" + s);
}
}
}