Clover coverage report - Code Coverage for hivemind-jmx release 1.1-beta-1
Coverage timestamp: Thu Apr 28 2005 19:55:29 EDT
file stats: LOC: 241   Methods: 10
NCLOC: 148   Classes: 2
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
PerformanceMonitorMBean.java 88.9% 95.8% 90% 93.4%
coverage coverage
 1   
 // Copyright 2005 The Apache Software Foundation
 2   
 //
 3   
 // Licensed under the Apache License, Version 2.0 (the "License");
 4   
 // you may not use this file except in compliance with the License.
 5   
 // You may obtain a copy of the License at
 6   
 //
 7   
 //     http://www.apache.org/licenses/LICENSE-2.0
 8   
 //
 9   
 // Unless required by applicable law or agreed to in writing, software
 10   
 // distributed under the License is distributed on an "AS IS" BASIS,
 11   
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12   
 // See the License for the specific language governing permissions and
 13   
 // limitations under the License.
 14   
 
 15   
 package org.apache.hivemind.management.mbeans;
 16   
 
 17   
 import java.util.ArrayList;
 18   
 import java.util.HashMap;
 19   
 import java.util.Iterator;
 20   
 import java.util.List;
 21   
 import java.util.Map;
 22   
 import java.util.Set;
 23   
 
 24   
 import javax.management.AttributeNotFoundException;
 25   
 import javax.management.MBeanAttributeInfo;
 26   
 import javax.management.MBeanException;
 27   
 import javax.management.ReflectionException;
 28   
 
 29   
 import org.apache.hivemind.management.impl.PerformanceCollector;
 30   
 import org.apache.hivemind.management.impl.PerformanceMonitorFactory;
 31   
 import org.apache.hivemind.service.MethodSignature;
 32   
 
 33   
 import mx4j.AbstractDynamicMBean;
 34   
 
 35   
 /**
 36   
  * MBean that holds and calculates the performance data for service method calls intercepted by the
 37   
  * {@link PerformanceMonitorFactory performanceMonitor}interceptor. Creates for each intercepted
 38   
  * method 5 MBean attributes: Number of Calls, Minimum, maximum, average and last execution time
 39   
  * 
 40   
  * @author Achim Huegen
 41   
  * @since 1.1
 42   
  */
 43   
 public class PerformanceMonitorMBean extends AbstractDynamicMBean implements PerformanceCollector
 44   
 {
 45   
     protected static final String DATA_TYPE_MAXIMUM_TIME = "Maximum time";
 46   
 
 47   
     protected static final String DATA_TYPE_MINIMUM_TIME = "Minimum time";
 48   
 
 49   
     protected static final String DATA_TYPE_LAST_TIME = "Last time";
 50   
 
 51   
     protected static final String DATA_TYPE_AVERAGE_TIME = "Average time";
 52   
 
 53   
     protected static final String DATA_TYPE_COUNT = "Count";
 54   
 
 55   
     private static final String DATA_TYPE_SEPARATOR = " : ";
 56   
 
 57   
     private Set _methods;
 58   
 
 59   
     private Map _countersByMethodSignature = new HashMap();
 60   
 
 61   
     private Map _countersByMethodId = new HashMap();
 62   
 
 63   
     private MBeanAttributeInfo[] mBeanAttributeInfos;
 64   
 
 65   
     /**
 66   
      * Creates a new instance
 67   
      * 
 68   
      * @param methods
 69   
      *            Set with instances of {@link org.apache.hivemind.service.MethodSignature}Contains
 70   
      *            the methods for that calls can be counted by this MBean
 71   
      */
 72  2
     public PerformanceMonitorMBean(Set methods)
 73   
     {
 74  2
         _methods = methods;
 75  2
         initCounters();
 76  2
         initAttributes();
 77   
     }
 78   
 
 79   
     /**
 80   
      * Builds two maps for accessing the counters by method signature and method id
 81   
      */
 82  2
     protected void initCounters()
 83   
     {
 84  2
         for (Iterator methodIterator = _methods.iterator(); methodIterator.hasNext();)
 85   
         {
 86  6
             MethodSignature method = (MethodSignature) methodIterator.next();
 87  6
             Counter counter = new Counter();
 88  6
             _countersByMethodSignature.put(method, counter);
 89  6
             _countersByMethodId.put(method.getUniqueId(), counter);
 90   
         }
 91   
     }
 92   
 
 93   
     /**
 94   
      * Creates for each intercepted method 5 MBean attributes: Number of Calls, Minimum, maximum,
 95   
      * average and last execution time
 96   
      */
 97  2
     protected void initAttributes()
 98   
     {
 99  2
         List mBeanAttributeInfoList = new ArrayList();
 100  2
         for (Iterator methodIterator = _methods.iterator(); methodIterator.hasNext();)
 101   
         {
 102  6
             MethodSignature method = (MethodSignature) methodIterator.next();
 103   
 
 104  6
             addAttribute(
 105   
                     mBeanAttributeInfoList,
 106   
                     method,
 107   
                     Long.class,
 108   
                     DATA_TYPE_COUNT,
 109   
                     "Number of method calls for method " + method);
 110  6
             addAttribute(
 111   
                     mBeanAttributeInfoList,
 112   
                     method,
 113   
                     Long.class,
 114   
                     DATA_TYPE_AVERAGE_TIME,
 115   
                     "Average execution time in ms of method " + method);
 116  6
             addAttribute(
 117   
                     mBeanAttributeInfoList,
 118   
                     method,
 119   
                     Long.class,
 120   
                     DATA_TYPE_LAST_TIME,
 121   
                     "Last execution time in ms of method " + method);
 122  6
             addAttribute(
 123   
                     mBeanAttributeInfoList,
 124   
                     method,
 125   
                     Long.class,
 126   
                     DATA_TYPE_MINIMUM_TIME,
 127   
                     "Minimum execution time in ms of method " + method);
 128  6
             addAttribute(
 129   
                     mBeanAttributeInfoList,
 130   
                     method,
 131   
                     Long.class,
 132   
                     DATA_TYPE_MAXIMUM_TIME,
 133   
                     "Maximum execution time in ms of method " + method);
 134   
 
 135   
         }
 136  2
         mBeanAttributeInfos = (MBeanAttributeInfo[]) mBeanAttributeInfoList
 137   
                 .toArray(new MBeanAttributeInfo[mBeanAttributeInfoList.size()]);
 138   
     }
 139   
 
 140   
     /**
 141   
      * Creates a new MBean Attribute for a performance counter
 142   
      */
 143  30
     private void addAttribute(List mBeanAttributeInfoList, MethodSignature method,
 144   
             Class attributeType, String performanceDataType, String description)
 145   
     {
 146  30
         String attributeName = buildAttributeName(method, performanceDataType);
 147  30
         MBeanAttributeInfo infoCount = new MBeanAttributeInfo(attributeName, attributeType
 148   
                 .getName(), description, true, false, false);
 149  30
         mBeanAttributeInfoList.add(infoCount);
 150   
     }
 151   
 
 152   
     /**
 153   
      * Builds the attribute name that holds the measurement data of type
 154   
      * <code>performanceDataType</code> for the method
 155   
      */
 156  35
     protected String buildAttributeName(MethodSignature method, String performanceDataType)
 157   
     {
 158  35
         String attributeName = method.getUniqueId() + DATA_TYPE_SEPARATOR + performanceDataType;
 159  35
         return attributeName;
 160   
     }
 161   
 
 162   
     /**
 163   
      * @see PerformanceCollector#addMeasurement(MethodSignature, long)
 164   
      */
 165  4
     public void addMeasurement(MethodSignature method, long executionTime)
 166   
     {
 167  4
         Counter counter = (Counter) _countersByMethodSignature.get(method);
 168  4
         counter.addMeasurement(executionTime);
 169   
     }
 170   
 
 171  1
     protected MBeanAttributeInfo[] createMBeanAttributeInfo()
 172   
     {
 173  1
         return mBeanAttributeInfos;
 174   
     }
 175   
 
 176   
     /**
 177   
      * @see AbstractDynamicMBean#getAttribute(java.lang.String)
 178   
      */
 179  5
     public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException,
 180   
             ReflectionException
 181   
     {
 182   
         // Split the attribute to get method id and performance data type separately
 183  5
         int posSep = attribute.indexOf(DATA_TYPE_SEPARATOR);
 184  5
         String methodId = attribute.substring(0, posSep);
 185  5
         String type = attribute
 186   
                 .substring(posSep + DATA_TYPE_SEPARATOR.length(), attribute.length());
 187  5
         Counter counter = (Counter) _countersByMethodId.get(methodId);
 188  5
         if (type.equals(DATA_TYPE_COUNT))
 189  1
             return new Long(counter.count);
 190  4
         else if (type.equals(DATA_TYPE_AVERAGE_TIME))
 191  1
             return new Long(counter.average);
 192  3
         else if (type.equals(DATA_TYPE_LAST_TIME))
 193  1
             return new Long(counter.last);
 194  2
         else if (type.equals(DATA_TYPE_MINIMUM_TIME))
 195  1
             return new Long(counter.min);
 196  1
         else if (type.equals(DATA_TYPE_MAXIMUM_TIME))
 197  1
             return new Long(counter.max);
 198   
         else
 199  0
             throw new IllegalArgumentException("Unknown performance data type");
 200   
     }
 201   
 
 202   
 }
 203   
 
 204   
 /**
 205   
  * Class that holds and calculates the performance data for a single method
 206   
  */
 207   
 
 208   
 class Counter
 209   
 {
 210   
     long count = 0;
 211   
 
 212   
     long last = 0;
 213   
 
 214   
     long average = 0;
 215   
 
 216   
     long max = 0;
 217   
 
 218   
     long min = 0;
 219   
 
 220  0
     public String toString()
 221   
     {
 222  0
         return "" + count;
 223   
     }
 224   
 
 225   
     /**
 226   
      * Should be synchronized, but this could slow things really down
 227   
      * 
 228   
      * @param executionTime
 229   
      */
 230  4
     public void addMeasurement(long executionTime)
 231   
     {
 232  4
         count++;
 233  4
         last = executionTime;
 234   
         // not an exact value without a complete history and stored as long
 235  4
         average = (average * (count - 1) + executionTime) / count;
 236  4
         if (executionTime < min || min == 0)
 237  4
             min = executionTime;
 238  4
         if (executionTime > max || max == 0)
 239  2
             max = executionTime;
 240   
     }
 241   
 }