2009/04/15 - Apache HiveMind has been retired.

For more information, please explore the Attic.

Clover coverage report - Code Coverage for hivemind-jmx release 1.2.1
Coverage timestamp: Fri Feb 10 2006 16:34:17 PST
file stats: LOC: 210   Methods: 9
NCLOC: 136   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
PerformanceMonitorFactory.java 83.3% 93.8% 100% 92.8%
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.impl;
 16   
 17    import java.lang.reflect.InvocationHandler;
 18    import java.lang.reflect.InvocationTargetException;
 19    import java.lang.reflect.Method;
 20    import java.lang.reflect.Proxy;
 21    import java.util.HashSet;
 22    import java.util.Iterator;
 23    import java.util.List;
 24    import java.util.Set;
 25   
 26    import javax.management.JMException;
 27    import javax.management.ObjectName;
 28   
 29    import org.apache.hivemind.ApplicationRuntimeException;
 30    import org.apache.hivemind.InterceptorStack;
 31    import org.apache.hivemind.ServiceInterceptorFactory;
 32    import org.apache.hivemind.internal.Module;
 33    import org.apache.hivemind.internal.ServicePoint;
 34    import org.apache.hivemind.management.MBeanRegistry;
 35    import org.apache.hivemind.management.ManagementMessages;
 36    import org.apache.hivemind.management.ObjectNameBuilder;
 37    import org.apache.hivemind.management.mbeans.PerformanceMonitorMBean;
 38    import org.apache.hivemind.methodmatch.MethodMatcher;
 39    import org.apache.hivemind.service.MethodContribution;
 40    import org.apache.hivemind.service.MethodIterator;
 41    import org.apache.hivemind.service.MethodSignature;
 42   
 43    /**
 44    * Interceptor factory that adds a MBean based performance monitor to a service. The interceptor
 45    * collects the number of calls, and the duration for each intercepted method. The results are
 46    * delegated to an {@link org.apache.hivemind.management.mbeans.PerformanceMonitorMBean MBean} that
 47    * is created and registered in the MBeanServer. Which methods are intercepted can be defined like
 48    * in the logging interceptor
 49    *
 50    * @author Achim Huegen
 51    * @since 1.1
 52    */
 53    public class PerformanceMonitorFactory implements ServiceInterceptorFactory
 54    {
 55    private static final String SERVICE_DECORATOR_TYPE = "PerformanceCollector";
 56   
 57    private MBeanRegistry _mbeanRegistry;
 58   
 59    private ObjectNameBuilder _objectNameBuilder;
 60   
 61    private String _serviceId;
 62   
 63  1 public PerformanceMonitorFactory(MBeanRegistry mbeanRegistry,
 64    ObjectNameBuilder objectNameBuilder)
 65    {
 66  1 _mbeanRegistry = mbeanRegistry;
 67  1 _objectNameBuilder = objectNameBuilder;
 68    }
 69   
 70  1 public void setServiceId(String string)
 71    {
 72  1 _serviceId = string;
 73    }
 74   
 75    /**
 76    * Dynamic Proxy that counts method calls
 77    */
 78    private class PerformanceMonitorHandler implements InvocationHandler
 79    {
 80    private Object _inner;
 81   
 82    private PerformanceCollector _counter;
 83   
 84    private Set _interceptedMethods;
 85   
 86  1 PerformanceMonitorHandler(Object inner, PerformanceCollector counter, Set interceptedMethods)
 87    {
 88  1 _inner = inner;
 89  1 _counter = counter;
 90  1 _interceptedMethods = interceptedMethods;
 91    }
 92   
 93  2 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
 94    {
 95  2 try
 96    {
 97    // Filter the method
 98  2 MethodSignature signature = new MethodSignature(method);
 99  2 if (_interceptedMethods.contains(signature))
 100    {
 101    // clock the execution time
 102  1 long startTime = System.currentTimeMillis();
 103  1 Object result = method.invoke(_inner, args);
 104  1 long endTime = System.currentTimeMillis();
 105   
 106  1 _counter.addMeasurement(signature, endTime - startTime);
 107  1 return result;
 108    }
 109   
 110  1 return method.invoke(_inner, args);
 111    }
 112    catch (InvocationTargetException ex)
 113    {
 114  0 throw ex.getTargetException();
 115    }
 116    }
 117   
 118    }
 119   
 120  1 public void createInterceptor(InterceptorStack stack, Module invokingModule, List parameters)
 121    {
 122  1 ServicePoint servicePoint = invokingModule.getServicePoint(stack
 123    .getServiceExtensionPointId());
 124  1 Set methods = getInterceptedMethods(stack, parameters);
 125  1 try
 126    {
 127  1 PerformanceCollector counter = createMBean(servicePoint, methods);
 128  1 InvocationHandler countHandler = new PerformanceMonitorHandler(stack.peek(), counter,
 129    methods);
 130   
 131  1 Object proxy = Proxy.newProxyInstance(invokingModule.getClassResolver()
 132    .getClassLoader(), new Class[]
 133    { stack.getServiceInterface() }, countHandler);
 134   
 135  1 stack.push(proxy);
 136    }
 137    catch (Exception ex)
 138    {
 139  0 throw new ApplicationRuntimeException(ManagementMessages
 140    .errorInstantiatingPerformanceInterceptor(_serviceId, stack, ex), ex);
 141    }
 142    }
 143   
 144    /**
 145    * Creates and registers the MBean that holds the performance data.
 146    */
 147  1 public PerformanceCollector createMBean(ServicePoint servicePoint, Set methods)
 148    throws JMException
 149    {
 150  1 PerformanceCollector counter = new PerformanceMonitorMBean(methods);
 151  1 ObjectName objectName = _objectNameBuilder.createServiceDecoratorName(
 152    servicePoint,
 153    SERVICE_DECORATOR_TYPE);
 154  1 _mbeanRegistry.registerMBean(counter, null, objectName);
 155   
 156  1 return counter;
 157    }
 158   
 159    /**
 160    * Creates a method matcher that helps finding the intercepted methods
 161    */
 162  1 private MethodMatcher buildMethodMatcher(List parameters)
 163    {
 164  1 MethodMatcher result = null;
 165   
 166  1 Iterator i = parameters.iterator();
 167  1 while (i.hasNext())
 168    {
 169  1 MethodContribution mc = (MethodContribution) i.next();
 170   
 171  1 if (result == null)
 172  1 result = new MethodMatcher();
 173   
 174  1 result.put(mc.getMethodPattern(), mc);
 175    }
 176   
 177  1 return result;
 178    }
 179   
 180    /**
 181    * Returns the methods that must be intercepted. Which methods are intercepted is controled by
 182    * the interceptor parameters via include and exclude mechanism
 183    */
 184  1 protected Set getInterceptedMethods(InterceptorStack stack, List parameters)
 185    {
 186  1 Set methods = new HashSet();
 187  1 MethodMatcher matcher = buildMethodMatcher(parameters);
 188   
 189  1 MethodIterator mi = new MethodIterator(stack.getServiceInterface());
 190   
 191  1 while (mi.hasNext())
 192    {
 193  5 MethodSignature sig = mi.next();
 194   
 195  5 if (includeMethod(matcher, sig))
 196  4 methods.add(sig);
 197    }
 198  1 return methods;
 199    }
 200   
 201  5 private boolean includeMethod(MethodMatcher matcher, MethodSignature sig)
 202    {
 203  5 if (matcher == null)
 204  0 return true;
 205   
 206  5 MethodContribution mc = (MethodContribution) matcher.get(sig);
 207  5 return mc == null || mc.getInclude();
 208    }
 209   
 210    }