Package com.sun.enterprise.management

Source Code of com.sun.enterprise.management.AMXTestBase

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. 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.html
* or glassfish/bootstrap/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 glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [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 com.sun.enterprise.management;

import java.io.IOException;

import java.util.Set;
import java.util.Map;
import java.util.Collection;
import java.util.HashSet;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.Arrays;


import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.Attribute;
import javax.management.JMException;
import javax.management.Notification;
import javax.management.NotificationListener;

import com.sun.appserv.management.base.AMX;
import com.sun.appserv.management.base.XTypes;
import com.sun.appserv.management.base.QueryMgr;
import com.sun.appserv.management.base.SystemInfo;
import com.sun.appserv.management.base.BulkAccess;
import com.sun.appserv.management.base.NotificationServiceMgr;
import com.sun.appserv.management.base.Util;
import com.sun.enterprise.management.support.XTypesMapper;
import com.sun.enterprise.management.support.J2EETypesMapper;


import com.sun.appserv.management.DomainRoot;

import com.sun.appserv.management.config.AMXConfig;
import com.sun.appserv.management.config.DomainConfig;
import com.sun.appserv.management.config.ConfigConfig;
import com.sun.appserv.management.config.ModuleMonitoringLevelsConfig;
import com.sun.appserv.management.config.ModuleMonitoringLevelValues;
import com.sun.appserv.management.config.NodeAgentConfig;

import com.sun.appserv.management.client.ProxyFactory;
import com.sun.appserv.management.client.ConnectionSource;
import com.sun.appserv.management.client.AppserverConnectionSource;

import com.sun.appserv.management.j2ee.J2EEDomain;

import com.sun.appserv.management.util.jmx.MBeanServerConnectionConnectionSource;
import com.sun.appserv.management.util.jmx.JMXUtil;

import com.sun.appserv.management.util.stringifier.SmartStringifier;
import com.sun.appserv.management.util.jmx.stringifier.AttributeStringifier;

import com.sun.appserv.management.util.misc.StringUtil;
import com.sun.appserv.management.util.misc.ClassUtil;
import com.sun.appserv.management.util.misc.GSetUtil;
import com.sun.appserv.management.util.misc.CollectionUtil;
import com.sun.appserv.management.util.misc.ExceptionUtil;
import com.sun.appserv.management.util.misc.TypeCast;

import com.sun.enterprise.management.PropertyKeys;
import com.sun.enterprise.management.util.jmx.JMXTestBase;
import com.sun.enterprise.management.support.AMXDebugStuff;
import com.sun.enterprise.management.support.AMXDebugSupportMBean;

/**
Base class for testing the AMX API
*/
public class AMXTestBase extends JMXTestBase
{
  private ConnectionSource    mConnectionSource;
  private final DomainRoot  mDomainRoot;
  private final ProxyFactory    mProxyFactory;
  private final Set<ObjectName>  mNotTested;
  private final TestUtil          mTestUtil;

    /** config name for PE (non-EE) configuration */
  protected static final String  PE_CONFIG_NAME  = "server-config";

  private final static boolean  WEB_MODULE_MONITOR_BROKEN  = true;
 
  private static boolean  MONITORING_ENABLED  = false;
 
  protected static final String NEWLINE = System.getProperty( "line.separator" );
 
 
    public
  AMXTestBase( )
  {
      checkConnection( getConnection() );
   
    mNotTested  = new HashSet<ObjectName>();
    try
    {
      mConnectionSource  =
          new MBeanServerConnectionConnectionSource( getConnection() );
     
      mProxyFactory    = ProxyFactory.getInstance( mConnectionSource, true );
      mDomainRoot    = mProxyFactory.getDomainRoot();
    }
    catch( Exception e )
    {
      throw new RuntimeException( e.toString(), e );
    }
   
    mTestUtil   = new TestUtil( getDomainRoot() );
  }
 
      protected Set<AMX>
  getAllAMX()
  {
      return getTestUtil().getAllAMX();
  }
 
    protected ModuleMonitoringLevelsConfig
  getModuleMonitoringLevelsConfig( final String configName )
  {
    final ConfigConfig  cc  = configName == null ? getConfigConfig() : getConfigConfig( configName );
    assert( cc != null );
   
    final ModuleMonitoringLevelsConfig  mon  =
      cc.getMonitoringServiceConfig().getModuleMonitoringLevelsConfig();
   
    return( mon );
  }
 
    protected ModuleMonitoringLevelsConfig
  getModuleMonitoringLevelsConfig(  )
  {
    return getModuleMonitoringLevelsConfig( null );
  }
 
  /**
    Ensure that monitoring is enabled so that unit tests don't miss anything
   */
    protected synchronized void
  turnOnMonitoring()
  {
    if ( ! MONITORING_ENABLED )
    {
      synchronized( AMXTestBase.class )
      {
        final String[]  configNames  = getConfigNames();
        for( int i = 0; i < configNames.length; ++i )
        {
          getModuleMonitoringLevelsConfig( configNames[ i ] ).changeAll( ModuleMonitoringLevelValues.HIGH );
        }
       
        MONITORING_ENABLED  = true;
      }
    }
  }
 
    protected synchronized void
  turnOffMonitoring()
  {
    synchronized( AMXTestBase.class )
    {
      getModuleMonitoringLevelsConfig().changeAll( ModuleMonitoringLevelValues.OFF );
      MONITORING_ENABLED  = false;
    }
  }
 
  private static final Set<String> EXPECTED_REMOTE_INCOMPLETE_TYPES   =
      GSetUtil.newUnmodifiableStringSet( XTypes.CALL_FLOW_MONITOR, XTypes.LOGGING );
     
      protected boolean
  isRemoteIncomplete( final ObjectName objectName )
  {
     final AMX amx    = getProxyFactory().getProxy( objectName, AMX.class );
     final String j2eeType    = amx.getJ2EEType();
    
     final boolean    isRemote    = ! amx.isDAS();
    
     if ( isRemote &&
       ! EXPECTED_REMOTE_INCOMPLETE_TYPES.contains( j2eeType ) )
     {
          warning( "isRemoteIncomplete: not expecting j2eeType=" + j2eeType +
              ", has the implementation changed?" );
     }
    
     return isRemote;
  }
 
 
    protected boolean
  shouldTest( final ObjectName objectName )
  {
    boolean  shouldTest  = ! isRemoteIncomplete( objectName );
   
    return( shouldTest );
  }

    protected void
  waitUnregistered( final ObjectName  objectName )
    throws IOException
  {
      final MBeanServerConnection  conn  = getConnection();
      if ( conn.isRegistered( objectName ) )
      {
        mySleep( 100 );
      }

      while ( conn.isRegistered( objectName ) )
      {
        trace( "waitUnregistered: " + objectName);
        mySleep( 100 );
      }     
  }


  /**
    Because proxies are cleaned up asynchronously, it's possible for one
    to remain in the factory until the factory processes the Notification
    that it's MBean has been unregistered.
   */
    protected void
  waitProxyGone(
    final ProxyFactory  factory,
    final ObjectName  objectName )
  {
    long  millis  = 1;
   
      while ( factory.getProxy( objectName, AMX.class, false ) != null )
      {
      mySleep( millis );
      millis  *= 2;
      trace( "waitProxyGone: waiting for proxy to disappear: " + objectName );
      }
  }

    protected final void
  notTested( final ObjectName objectName )
  {
      if ( isRemoteIncomplete( objectName ) )
      {
          trace( "remoteIncomplete (this is OK): " + objectName );
    }
    else
    {
        mNotTested.add( objectName );
    }
  }

    protected final Set<ObjectName>
  getNotTestedSet( )
  {
    return( mNotTested );
  }

    public static void
  mySleep( final long millis )
  {
    try
    {
      Thread.sleep( millis );
    }
    catch( InterruptedException e )
    {
    }
  }

    protected final void
  warnNotTested( )
  {
    final Set<ObjectName>  notTested  = getNotTestedSet();
   
    if ( notTested.size() != 0 )
    {
      final Set  j2eeTypes  =
        JMXUtil.getKeyPropertySet( AMX.J2EE_TYPE_KEY, notTested );
     
      trace( "WARNING: DID NOT TEST: " + notTested.size() + " MBeans of types {" +
        toString( j2eeTypes ) + "}" );
    }
  }
 


    protected void
  checkConnection( final MBeanServerConnection conn )
  {
      assert( getConnection() != null );
     
      try
      {
      conn.isRegistered( JMXUtil.getMBeanServerDelegateObjectName() );
       }
       catch( Exception e )
       {
         fail( "Connection failed:\n" +
           ExceptionUtil.getStackTrace( getRootCause( e ) ) );
       }
  }
 
    protected void
  checkConnection(  )
  {
    checkConnection( getConnection( ) );
  }
 
      protected TestUtil
  getTestUtil()
  {
      return mTestUtil;
  }


    protected final AMX
  getProxy( final ObjectName objectName )
  {
    final ProxyFactory  factory  = ProxyFactory.getInstance( getConnectionSource(), true);
   
    final AMX proxy   = factory.getProxy( objectName, AMX.class );
   
    return( proxy );
  }
 
  /**
       We don't have T extend AMX because not all mixin interfaces extend AMX.
   */
      protected final <T> T
  getProxy(
      final ObjectName objectName,
      final Class<T> theClass)
  {
    return( theClass.cast( getProxy(objectName) ) );
  }


    protected final DomainRoot
  getDomainRoot()
  {
    assert( mDomainRoot != null ) : "mDomainRoot is null";
    return( mDomainRoot );
  }

    protected final DomainConfig
  getDomainConfig()
  {
    return( getDomainRoot().getDomainConfig() );
  }
 
    protected final J2EEDomain
  getJ2EEDomain()
  {
    return( getDomainRoot().getJ2EEDomain() );
  }

    protected String[]
  getConfigNames()
  {
    final Map<String,ConfigConfig>  configMap  =
      getDomainConfig().getConfigConfigMap();
   
    return( GSetUtil.toStringArray( configMap.keySet() ) );
  }

    protected ConfigConfig
  getConfigConfig( final String name )
  {
    final Map<String,ConfigConfig>  configs  = getDomainConfig().getConfigConfigMap();

    return configs.get( name == null ? PE_CONFIG_NAME : name );
  }
 
    protected static ConfigConfig
  getConfigConfig( final AMXConfig any )
  {
        final ObjectName   objectName  = Util.getObjectName( any );
        final String       configName  = objectName.getKeyProperty( XTypes.CONFIG_CONFIG );
   
        return any.getDomainRoot().getDomainConfig().getConfigConfigMap().get( configName );
  }
 
    protected ConfigConfig
  getConfigConfig( )
  {
    return( getConfigConfig( PE_CONFIG_NAME ) );
  }


    protected QueryMgr
  getQueryMgr()
  {
    assert( mDomainRoot != null );
    final QueryMgr  proxy  = getDomainRoot().getQueryMgr();
    assert( proxy != null );
    return( proxy );
  }


    protected NotificationServiceMgr
  getNotificationServiceMgr()
  {
    return( getDomainRoot().getNotificationServiceMgr() );
  }

    protected BulkAccess
  getBulkAccess()
  {
    return( getDomainRoot().getBulkAccess() );
  }

    protected ConnectionSource
  getConnectionSource()
  {
    assert( mConnectionSource != null );
    return( mConnectionSource );
  }

    protected MBeanServerConnection
  getConnection()
  {
    return( getGlobalConnection() );
  }

    protected ProxyFactory
  getProxyFactory()
  {
    return( mProxyFactory );
  }


    protected Class
  getInterfaceClass( AMX proxy )
    throws ClassNotFoundException
  {
    final String  name  = Util.getExtra( proxy ).getInterfaceName();
    return( ClassUtil.getClassFromName( name ) );
  }
   
    protected <T extends AMX> boolean
  testOnProxies(
    final Collection<T>  proxies,
    final Method    method )
    throws Exception
  {
    final long  start  = now();
   
    boolean  failed  = false;
   
    int  testCount  = 0;
   
    final Object[]  args  = new Object[ 1 ];
    for( final T proxy : proxies )
    {
      final ObjectName  objectName  = Util.getExtra( proxy ).getObjectName();
     
      if ( ! shouldTest( objectName ) )
      {
        notTested( objectName );
        continue;
      }

      ++testCount;
      try
      {
        args[ 0 = proxy;
        method.invoke( this, args );
      }
      catch( Exception e )
      {
        trace( method.getName() + " failed for proxy: " +
            quote( JMXUtil.toString( objectName ) ) );
        failed  = true;
        trace( ExceptionUtil.toString( e ) );
      }
    }
   
   
    final long  elapsed  = now() - start;
    printVerbose( "Ran test method " + method.getName() + " on " + testCount +
      " candidates in " + elapsed + "ms");
    warnNotTested();
   
    warnNotTested();
   
    return( ! failed );
  }


    protected boolean
  testOnObjectNames(
    final Collection<ObjectName>  objectNames,
    final Method                method )
    throws Exception
  {
    boolean  failed  = false;
   
    final Object[]  args  = new Object[ 1 ];
   
    int  testCount  = 0;
    final long  start  = now();
   
    for( final ObjectName objectName : objectNames )
    {
      if ( ! shouldTest( objectName ) )
      {
        notTested( objectName );
        continue;
      }

      ++testCount;
      try
      {
        args[ 0 = objectName;
        method.invoke( this, args );
      }
      catch( Exception e )
      {
          final Throwable rootCause   = getRootCause( e );
        trace( method.getName() + " failed for: " +
            quote( JMXUtil.toString( objectName ) ) + " with Exception of type " +
                rootCause.getClass().getName() + ", msg = " + rootCause.getMessage() );
        failed  = true;
      }
    }
   
    final long  elapsed  = now() - start;
    printVerbose( "Ran test method " + method.getName() + " on " + testCount +
      " candidates in " + elapsed + "ms");
    warnNotTested();
   
    return( ! failed );
  }


   
  protected final static Class[]  OBJECTNAME_SIG  = new Class[] { ObjectName.class };
  protected final static Class[]  PROXY_SIG    = new Class[] { AMX.class };

    protected void
  testAll( final Collection<ObjectName> objectNames, final String methodName )
    throws Exception
  {
    final boolean success  = testOnObjectNames( objectNames,
          this.getClass().getMethod( methodName, OBJECTNAME_SIG ) );
   
    assert( success );
  }

    protected <T extends AMX> void
  testAllProxies( final Collection<T> proxies, final String methodName )
    throws Exception
  {
    final boolean success  = testOnProxies( proxies,
          this.getClass().getMethod( methodName, PROXY_SIG ) );
   
    assert( success );
  }

    protected void
  testAll( String methodName )
    throws Exception
  {
    final Set<ObjectName>  names  = getTestUtil().getAllObjectNames();
   
    testAll( names, methodName );
  }

    public void
  setUp() throws Exception
  {
    super.setUp();
         
    turnOnMonitoring();
  }
 
      public void
  testAssertsOn()
  {
      checkAssertsOn();
  }
 
  private static final String   DEFAULT_INSTANCE_NAME   = "test";
 
      protected static String
  getDefaultInstanceName( final String qualifier )
  {
      String  name    = null;
     
      if ( qualifier == null )
      {
          name    = DEFAULT_INSTANCE_NAME;
      }
      else
      {
          name    = qualifier + "." + DEFAULT_INSTANCE_NAME;
      }
      return name;
  }
 
      protected Throwable
  getRootCause( Throwable t )
  {
      return ExceptionUtil.getRootCause( t );
  }
 
        protected String
  getStackTrace( Throwable t )
  {
      return ExceptionUtil.getStackTrace( t );
  }
 
        protected String
  getRootCauseStackTrace( Throwable t )
  {
      return getStackTrace( getRootCause( t ) );
  }
 
      protected Map<String,AppserverConnectionSource>
    getNodeAgents()
    {
       final Map<?,?> m = Map.class.cast( getEnvValue( PropertyKeys.NODE_AGENTS_KEY ) );
       return TypeCast.checkedMap( m,
                String.class, AppserverConnectionSource.class);
    }
   
   
      protected String
    getDASNodeAgentName()
    {
        return getEnvString( PropertyKeys.DAS_NODE_AGENT_NAME, null);
    }
   
      protected NodeAgentConfig
    getDASNodeAgentConfig()
    {
       final String name    = getDASNodeAgentName();
      
       NodeAgentConfig  config  = null;
       if ( name != null )
       {
            config  = getDomainConfig().getNodeAgentConfigMap().get( name );
       }
      
       return config;
    }
   
        protected boolean
    getTestOffline()
    {
        return getEnvBoolean( PropertyKeys.TEST_OFFLINE_KEY, false );
    }
   
    /**
        Check if we're testing in Offline mode, which means that
        Config MBeans are loaded in-process. If so, issue a warning.
       
        @return true if test should be run, false if in offline mode
     */
        protected boolean
    checkNotOffline( final String testName )
    {
        boolean offline = getTestOffline();
       
        if ( offline )
        {
            //warning( "amxtest.testOffline=true, skipping test " + testName + "()" );
        }
       
        return ! offline;
    }
   
   
        public static Capabilities
  getDefaultCapabilities()
  {
      return getOfflineCapableCapabilities( true );
  }
 
        protected static Capabilities
  getOfflineCapableCapabilities( boolean offlineCapable )
  {
      final Capabilities    c   = new Capabilities( );
      c.setOfflineCapable( offlineCapable );
     
      return c;
  }
 
      AMXDebugSupportMBean
  getAMXDebugSupportMBean()
  {
      final ObjectName  objectName  = Util.newObjectName( AMXDebugSupportMBean.OBJECT_NAME );
     
      try
      {
      return (AMXDebugSupportMBean)newProxy( objectName, AMXDebugSupportMBean.class );
      }
      catch( Exception e )
      {
          assert false : "Can't get proxy to " + objectName;
      }
      return null;
  }
 
      protected boolean
  supportsMultipleServers()
  {
      return supportsMultipleServers( getDomainRoot() );
  }
   
        public static boolean
  supportsMultipleServers( final DomainRoot domainRoot )
  {
      return domainRoot.getSystemInfo().supportsFeature( SystemInfo.MULTIPLE_SERVERS_FEATURE );
  }

 
      protected boolean
  supportsClusters()
  {
      return getDomainRoot().getSystemInfo().supportsFeature( SystemInfo.CLUSTERS_FEATURE );
  }
}









TOP

Related Classes of com.sun.enterprise.management.AMXTestBase

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.