Package com.sun.enterprise.management.base

Source Code of com.sun.enterprise.management.base.GenericTest

/*
* 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.
*/
/*
* $Header: /cvs/glassfish/admin/mbeanapi-impl/tests/com/sun/enterprise/management/base/GenericTest.java,v 1.8.6.1 2007/11/30 23:16:52 llc Exp $
* $Revision: 1.8.6.1 $
* $Date: 2007/11/30 23:16:52 $
*/
package com.sun.enterprise.management.base;

import java.util.Set;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.io.IOException;
import java.io.NotSerializableException;

import javax.management.ObjectName;
import javax.management.MBeanServerConnection;
import javax.management.MBeanOperationInfo;
import javax.management.InstanceNotFoundException;
import javax.management.JMException;
import javax.management.ReflectionException;
import javax.management.AttributeNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanAttributeInfo;
import javax.management.Attribute;
import javax.management.AttributeList;


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

import com.sun.appserv.management.client.ProxyFactory;
import com.sun.appserv.management.base.AMX;
import com.sun.appserv.management.config.ResourceRefConfig;
import com.sun.appserv.management.config.DeployedItemRefConfig;
import com.sun.appserv.management.config.ResourceConfig;

import com.sun.appserv.management.util.misc.ExceptionUtil;
import com.sun.appserv.management.util.misc.ArrayUtil;
import com.sun.appserv.management.util.misc.ArrayConversion;
import com.sun.appserv.management.util.misc.StringUtil;

import com.sun.appserv.management.util.misc.ClassUtil;
import com.sun.appserv.management.util.jmx.JMXUtil;
import com.sun.appserv.management.util.jmx.ReadWriteAttributeFilter;

import com.sun.appserv.management.util.stringifier.ArrayStringifier;



import com.sun.enterprise.management.AMXTestBase;
import com.sun.enterprise.management.Capabilities;

/**
*/
public final class GenericTest extends AMXTestBase
{
  final boolean    mDoInfo;
  final boolean    mDoAttributes;
  final boolean    mDoOperations;
  final boolean    mwarnings;

    public
  GenericTest()
    throws IOException
  {
    mDoInfo        = true;
    mDoAttributes    = true;
    mDoOperations    = true;
    mwarnings    = true;
  }
 
      public static Capabilities
  getCapabilities()
  {
      return getOfflineCapableCapabilities( true );
  }
    private Map<String,Throwable>
  validateAttributesSingly(
    final ObjectName    objectName,
    final String[]      attrNames,
    Map<String,Throwable>    failures,
    Map<String,Throwable>    warnings )
    throws Exception
  {
    MBeanServerConnection conn  = getConnection();
     
    for( int i = 0; i < attrNames.length; ++i )
    {
      final String  attrName  = attrNames[ i ];
     
      try
      {
        final Object  a  = conn.getAttribute( objectName, attrName );
       
        if ( a == null )
        {
          // null is legal, apparently
        }
      }
      catch( NotSerializableException e )
      {
        warnings.put( attrName, e );
      }
      catch( IOException e )
      {
        failures.put( attrName, e );
      }
      catch( Exception e )
      {
        failures.put( attrName, e );
      }
    }
   
    return( failures );
  }


    private String
  getExceptionMsg( final Throwable e )
  {
    String  msg  = null;
   
    if ( e instanceof IOException )
    {
      msg  = "received an exception of class " + e.getClass().getName();
     
      if ( shouldPrintStackTraces() )
      {
        msg  = msg + "Stack trace = \n" +
        ExceptionUtil.getStackTrace( ExceptionUtil.getRootCause( e ) );
      }
    }
    else
    {
      msg  = "threw an Exception of type " +
        e.getClass().getName() + ", message =  " + e.getMessage();
     
      if ( shouldPrintStackTraces() )
      {
        msg  = msg + "\n" + ExceptionUtil.getStackTrace( e );
      }
    }
   
    final Throwable rootCause  = ExceptionUtil.getRootCause( e );
   
    if ( rootCause != e )
    {
      msg  = msg + "...\nRoot cause was exception of type " + e.getClass().getName() + ", message = " +
        rootCause.getMessage();
       
     
      if ( shouldPrintStackTraces() )
      {
        msg  = msg + "\n" + ExceptionUtil.getStackTrace( rootCause );
      }
    }
   
    return( msg );
  }

    MBeanAttributeInfo
  findAttributeInfo(
    final MBeanAttributeInfo[]  infos,
    String             attrName )
  {
    MBeanAttributeInfo  info  = null;
   
    for( int i = 0; i < infos.length; ++i )
    {
      if ( infos[ i ] != null && infos[ i ].getName().equals( attrName ) )
      {
        info  = infos[ i ];
        break;
      }
    }
   
    assert( info != null );
    return( info );
  }
 
    private void
  displayAttributeFailuresOrWarnings(
    final boolean        failure,
    final ObjectName      objectName,
    final MBeanAttributeInfo[]  infos,
    final Map<String,Throwable>    problems )
    throws Exception
  {
    trace( "" );
    trace( problems.keySet().size() + (failure ? " Failures: " : " Warnings: ") + objectName  );
   
    int  i = 0;
    for( final String attrName : problems.keySet() )
    {
      final Throwable  t = problems.get( attrName );
     
      final MBeanAttributeInfo  info  = findAttributeInfo( infos, attrName );
     
      final String prefix  = "(" + (i+1) + ")" + " getting Attribute \"" + attrName + "\" of type " +
        info.getType() + " ";
       
      if ( t == null )
      {
        trace( prefix + "returned null" );
      }
      else
      {
        trace( prefix + getExceptionMsg( t ) );
      }
      ++i;
    }
  }
 
 
 
    private boolean
  validateMBeanInfo( final ObjectName objectName, final MBeanInfo info)
  {
    boolean  valid  = true;
   
    if ( ArrayUtil.arrayContainsNulls( info.getAttributes() ) )
    {
      warning( "MBean has nulls in its MBeanAttributeInfo[]: " + objectName );
      valid  = false;
    }
   
    if ( ArrayUtil.arrayContainsNulls( info.getConstructors() ) )
    {
      warning( "MBean has nulls in its MBeanConstructorInfo[]: " + objectName );
      valid  = false;
    }
   
    if ( ArrayUtil.arrayContainsNulls( info.getOperations() ) )
    {
      warning( "MBean has nulls in its MBeanOperationInfo[]: " + objectName );
      valid  = false;
    }
   
    if ( ArrayUtil.arrayContainsNulls( info.getNotifications() ) )
    {
      warning( "MBean has nulls in its MBeanNotificationInfo[]: " + objectName );
      valid  = false;
    }
   
    return( valid );
  }
 
  static final private String  SECTION_LINE  =
  "--------------------------------------------------------------------------------";
 
 
 
    private void
  printDuplicateAttributes( final ObjectName objectName, MBeanAttributeInfo[] attrInfos, String name)
  {
    String  msg  = "MBean " + quote( objectName ) + " has the same Attribute listed more than once:\n";
   
    for( int i = 0; i < attrInfos.length; ++i )
    {
      final MBeanAttributeInfo  a  = attrInfos[ i ];
       
      if ( a.getName().equals( name ) )
      {
        msg  = msg + quote(name) + ": " + a.getType() + ", " + quote( a.getDescription() )  + StringUtil.NEWLINE();
      }
    }
   
    warning( msg );
  }
 
    private boolean
  validateUniqueAttributeNames( final ObjectName objectName, MBeanAttributeInfo[] attrInfos )
  {
    boolean  valid  = true;
    final MBeanAttributeInfo[]  infos  =
      JMXUtil.filterAttributeInfos( attrInfos, ReadWriteAttributeFilter.READABLE_FILTER );
    final String[]  names  = JMXUtil.getAttributeNames( infos );
   
    if ( ArrayConversion.arrayToSet( names ).size() != attrInfos.length )
    {
      final Set<String>  set    = new HashSet<String>();
     
      for( int i = 0; i < names.length; ++i )
      {
        final String  name  = names[ i ];
     
        if ( set.contains( name ) )
        {
          valid  = false;
         
          printDuplicateAttributes( objectName, attrInfos, name );
        }
        else
        {
          set.add( name );
        }
      }
      set.clear();
    }
   
    return( valid );
  }
 
    private boolean
  validateMissingAndEmptyAttributeNames( final ObjectName objectName  )
  {
    boolean            valid  = true;
    final MBeanServerConnection  conn  = getConnection();
   
    AttributeList  attrs  = null;
    try
    {
      attrs  = conn.getAttributes( objectName, new String[0] );
      if ( attrs == null )
      {
        warning( "MBean " + quote( objectName ) +
          " returned NULL for an empty AttributeList" );
        valid  = false;
      }
      else if ( attrs.size() != 0 )
      {
        warning( "MBean " + quote( objectName ) +
          " returned attributes for an empty AttributeList" );
        valid  = false;
      }
    }
    catch( Exception e )
    {
      valid  = false;
     
      warning( "MBean " + quote( objectName ) +
        " threw an exception getting an empty attribute list" );
    }
   
    try
    {
      final String  notFoundName  = "bogus." + System.currentTimeMillis();
      attrs  = conn.getAttributes( objectName, new String[] { notFoundName });
      if ( attrs == null )
      {
        warning( "MBean " + quote( objectName ) +
          " returned NULL for a missing Attribute" );
        valid  = false;
      }
      else if ( attrs.size() != 0 )
      {
        warning( "MBean " + quote( objectName ) +
          " returned attributes for a non-existent name" );
        valid  = false;
      }
    }
    catch( Exception e )
    {
      valid  = false;
     
      warning( "MBean " + quote( objectName ) +
        " threw an exception when getAttributes() was called with a " +
        "non-existent Attribute, exception class = " +
        e.getClass().getName() );
    }
   
    return( valid );
  }
 
    private boolean
  validateAttributeTypes(
    final ObjectName      objectName,
    final AttributeList      attrs,
    final MBeanAttributeInfo[]  attrInfos)
    throws Exception
  {
    boolean  valid  = true;
   
    final Map<String,MBeanAttributeInfo>  attrInfosMap  = JMXUtil.attributeInfosToMap( attrInfos );
   
    final Iterator  iter  = attrs.iterator();
    while ( iter.hasNext() )
    {
      final Attribute  attr  = (Attribute)iter.next();
     
      final String  name  = attr.getName();
      final Object  value  = attr.getValue();
      final MBeanAttributeInfo  attrInfo = (MBeanAttributeInfo)attrInfosMap.get( name );
      if ( attrInfo == null )
      {
        valid  = false;
        warning( "MBean " + objectName + " returned an Attribute not " +
          "declared in its MBeanInfo: " + name );
      }
      else if ( value != null )
      {
        final String  typeName  = attrInfo.getType();
        final Class<?>    infoClass  = ClassUtil.getClassFromName( typeName );
        final Class<?>    valueClass  = value.getClass();
       
        if ( infoClass == null )
        {
          valid  = false;
          warning( "Can't find class for: " + typeName );
        }
        else if ( ! infoClass.isAssignableFrom( valueClass ) )
        {
          final Class<?> objectClass  = ClassUtil.PrimitiveClassToObjectClass( infoClass );
         
          if ( ! objectClass.isAssignableFrom( valueClass ) )
          {
            valid  = false;
            warning( "MBean " + objectName + " returned Attribute " +
              name + "=" + value +
              " of class " + value.getClass().getName() +
              " not matching its MBeanInfo: " + infoClass.getName() );
          }
        }
      }
    }
   
    return( valid );
  }
 
    private boolean
  validateAttributes(
    final ObjectName      objectName,
    final MBeanAttributeInfo[]  attrInfos)
    throws Exception
  {
    boolean  valid  = true;
   
    final MBeanAttributeInfo[]  readableInfos  = JMXUtil.filterAttributeInfos( attrInfos,
        ReadWriteAttributeFilter.READABLE_FILTER );
    final String[]  attrNames  = JMXUtil.getAttributeNames( readableInfos );
    Arrays.sort( attrNames  );
   
    if ( attrNames.length != 0 )
    {
      // if we can fetch all the attributes, then the MBean is OK;
      // try this first for efficiency
      try
      {
                //trace( objectName.getKeyProperty( "j2eeType" ) + ": " + attrNames.length );
        final AttributeList  attrs  = getConnection().getAttributes( objectName, attrNames );
       
        if ( attrs == null )
        {
          warning( "MBean " + quote( objectName ) + " returned NULL for its AttributeList" );
          valid  = false;
        }
        else if ( attrs.size() != readableInfos.length )
        {
          // mismatch between claimed number of attributes and actual
          final ArrayStringifier  as  = new ArrayStringifier( ", ", true );
          final String claimedString  = as.stringify( attrNames );
         
          final Set<String>  actualSet  = JMXUtil.attributeListToValueMap( attrs ).keySet();
          final Set<String>  missingSet  = ArrayConversion.arrayToSet( attrNames );
          missingSet.removeAll( actualSet );
         
          final String[]  missingNames  = (String[])ArrayConversion.setToArray( missingSet, true );
          Arrays.sort( missingNames  );
          final String  missingString  = as.stringify( missingNames );
         
          warning( "MBean " + quote( objectName ) +
            " did not supply the " +
            missingNames.length + " attributes " + missingString );
        }
       
        valid  = validateAttributeTypes( objectName, attrs, readableInfos  );
      }
      catch( Exception e )
      {
        trace( SECTION_LINE );
        final String  msg  = "getAttributes() failed on " + quote( objectName ) + ", exception =\n" + e;
       
        if ( e instanceof NotSerializableException )
        {
          warning( msg );
        }
        else
        {
          warning( msg );
          valid  = false;
        }
        // do them one-at-a time to see where failure occurs
        final Map<String,Throwable>  failures  = new HashMap<String,Throwable>();
        final Map<String,Throwable>  warnings  = new HashMap<String,Throwable>();
       
        validateAttributesSingly( objectName, attrNames, failures, warnings );
       
        trace( "Validating attributes one-at-a-time using getAttribute() for " + quote( objectName ));
        if ( failures.size() == 0 && warnings.size() == 0 )
        {
          warning( " during getAttributes(" +
            ArrayStringifier.stringify( attrNames, "," ) + ") for: " + objectName +
            " (but Attributes work when queried one-at-a-time).\nIt " +
            getExceptionMsg( e ) );
        }
       
        if ( failures.size() != 0 )
        {
          displayAttributeFailuresOrWarnings( true, objectName, readableInfos, failures );
        }
       
        if ( warnings.size() != 0 )
        {
          displayAttributeFailuresOrWarnings( false, objectName, readableInfos, warnings );
        }
       
        trace( SECTION_LINE );
      }
    }
    else
    {
      valid  = true;
    }
   
    if ( ! validateUniqueAttributeNames( objectName, attrInfos ) )
    {
      valid  = false;
    }
   
    if ( ! validateMissingAndEmptyAttributeNames( objectName ) )
    {
      valid  = false;
    }
   
    return( valid );
  }
 
    void
  checkObjectNameReturnValue(
    MBeanServerConnection  conn,
    ObjectName        callee,
    MBeanOperationInfo    operationInfo,
    ObjectName        resultOfCall )
    throws Exception
  {
    try
    {
      printVerbose( "checking MBean info for: " + resultOfCall );
      final MBeanInfo  mbeanInfo  = conn.getMBeanInfo( resultOfCall );
    }
    catch( InstanceNotFoundException e )
    {
      trace( "WARNING: MBean " + resultOfCall + " returned from " +
        operationInfo.getReturnType() + " " + operationInfo.getName() + "() does not exist" );
       
    }
    catch( Exception e )
    {
      trace( "WARNING: MBean " + resultOfCall + " returned from " +
        operationInfo.getReturnType() + " " + operationInfo.getName() +
        "() can't supply MBeanInfo: " + getExceptionMsg( e )
        );
     
      if ( e instanceof IOException )
      {
        throw (IOException)e;
      }
    }
  }
 
    void
  checkGetterResult(
    MBeanServerConnection  conn,
    ObjectName        callee,
    MBeanOperationInfo    operationInfo,
    Object          resultOfCall )
    throws Exception
  {
    if ( resultOfCall instanceof ObjectName )
    {
      final ObjectName  name  = (ObjectName)resultOfCall;
     
      checkObjectNameReturnValue( conn, callee, operationInfo, name );
    }
    else if ( resultOfCall instanceof ObjectName[] )
    {
      final ObjectName[]  names  = (ObjectName[])resultOfCall;
     
      for( int i = 0; i < names.length; ++i )
      {
        checkObjectNameReturnValue( conn, callee, operationInfo, names[ i ]);
      }
    }
  }
 
    private boolean
  validateGetters(
    final ObjectName      objectName,
    final MBeanOperationInfo[]  operationInfos )
    throws Exception
  {
    boolean  valid  = true;
    MBeanServerConnection conn  = getConnection();
   
    for( int i = 0; i < operationInfos.length; ++i )
    {
      final MBeanOperationInfo  info  = operationInfos[ i ];
     
      if ( JMXUtil.isGetter( info ) )
      {
        boolean  opValid  = false;
         
        try
        {
          printVerbose( "invoking getter: " + info.getName() + "()" );
          final Object  result  = conn.invoke( objectName, info.getName(), null, null );
         
          checkGetterResult( conn,
          objectName, info, result );
        }
        catch( Exception e )
        {
          warning( "Failure: calling " + info.getName() + "() on " + objectName +
            ": " + getExceptionMsg( e ) );
           
          if ( e instanceof IOException)
          {
            throw( (IOException)e );
          }
          valid  = false;
        }
      }
    }
   
    return( valid );
  }
 

 
    boolean
  shouldPrintStackTraces()
  {
    return( true );
  }
 
 
    private boolean
  validate( final ObjectName objectName )
    throws Exception
  {
    boolean  valid  = true;

    MBeanServerConnection conn  = getConnection();
   
    MBeanInfo  info  = null;
    try
    {
      info  = conn.getMBeanInfo( objectName );
    }
    catch( Exception e )
    {
      valid  = false;
      warning( " during getMBeanInfo() for: " + objectName + "\n" +
        " message = " + e.getMessage() );
      // abort--the connection has died
      throw e;
    }
   
    if ( mDoInfo && ! validateMBeanInfo( objectName, info ) )
    {
      trace( "validateMBeanInfo failed for: " + objectName );
      valid  = false;
    }
   
   
    if ( mDoAttributes &&
      ! validateAttributes( objectName, info.getAttributes() ) )
    {
      trace( "validateAttributes failed for: " + objectName );
      valid  = false;
    }
   
    if ( mDoOperations &&
      ! validateGetters( objectName, info.getOperations() ) )
    {
      trace( "validateGetters failed for: " + objectName );
      valid  = false;
    }
   
    return( valid );
  }
 
 
    private void
  validate( final ObjectName[] objectNames )
    throws Exception
  {
    int  failureCount  = 0;
   
    trace( "Validating: " );
    if ( mDoInfo )
    {
      trace( "- MBeanInfo" );
    }
    if ( mDoAttributes )
    {
      trace( "- Attributes" );
    }
    if ( mDoOperations )
    {
      trace( "- Operations (getters)" );
    }
   
    trace( "" );
   
    for( int i = 0; i < objectNames.length; ++i )
    {
      final ObjectName  objectName  = objectNames[ i ];
     
      printVerbose( "Validating: " + objectName );
     
      if ( ! shouldTest( objectName ) )
      {
        notTested( objectName );
        continue;
      }
     
      final boolean  valid  = validate( objectName );
      if ( ! valid )
      {
        ++failureCount;
      }
    }
   
    trace( "Total mbeans failing: " + failureCount );
  }
 
 
 
    public void
  testGenerically()
    throws Exception
  {
    final Set<ObjectName>  all  = getTestUtil().getAllObjectNames();
   
    final ObjectName[]  allObjectNames  = new ObjectName[ all.size() ];
    all.toArray( allObjectNames );
    validate( allObjectNames );
  }
 
}

TOP

Related Classes of com.sun.enterprise.management.base.GenericTest

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.