KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > hivemind > management > impl > PerformanceMonitorFactory


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 JavaDoc;
18 import java.lang.reflect.InvocationTargetException JavaDoc;
19 import java.lang.reflect.Method JavaDoc;
20 import java.lang.reflect.Proxy JavaDoc;
21 import java.util.HashSet JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.List JavaDoc;
24 import java.util.Set JavaDoc;
25
26 import javax.management.JMException JavaDoc;
27 import javax.management.ObjectName JavaDoc;
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 JavaDoc SERVICE_DECORATOR_TYPE = "PerformanceCollector";
56
57     private MBeanRegistry _mbeanRegistry;
58
59     private ObjectNameBuilder _objectNameBuilder;
60
61     private String JavaDoc _serviceId;
62
63     public PerformanceMonitorFactory(MBeanRegistry mbeanRegistry,
64             ObjectNameBuilder objectNameBuilder)
65     {
66         _mbeanRegistry = mbeanRegistry;
67         _objectNameBuilder = objectNameBuilder;
68     }
69
70     public void setServiceId(String JavaDoc string)
71     {
72         _serviceId = string;
73     }
74
75     /**
76      * Dynamic Proxy that counts method calls
77      */

78     private class PerformanceMonitorHandler implements InvocationHandler JavaDoc
79     {
80         private Object JavaDoc _inner;
81
82         private PerformanceCollector _counter;
83
84         private Set JavaDoc _interceptedMethods;
85
86         PerformanceMonitorHandler(Object JavaDoc inner, PerformanceCollector counter, Set JavaDoc interceptedMethods)
87         {
88             _inner = inner;
89             _counter = counter;
90             _interceptedMethods = interceptedMethods;
91         }
92
93         public Object JavaDoc invoke(Object JavaDoc proxy, Method JavaDoc method, Object JavaDoc[] args) throws Throwable JavaDoc
94         {
95             try
96             {
97                 // Filter the method
98
MethodSignature signature = new MethodSignature(method);
99                 if (_interceptedMethods.contains(signature))
100                 {
101                     // clock the execution time
102
long startTime = System.currentTimeMillis();
103                     Object JavaDoc result = method.invoke(_inner, args);
104                     long endTime = System.currentTimeMillis();
105
106                     _counter.addMeasurement(signature, endTime - startTime);
107                     return result;
108                 }
109
110                 return method.invoke(_inner, args);
111             }
112             catch (InvocationTargetException JavaDoc ex)
113             {
114                 throw ex.getTargetException();
115             }
116         }
117
118     }
119
120     public void createInterceptor(InterceptorStack stack, Module invokingModule, Object JavaDoc parameters)
121     {
122         ServicePoint servicePoint = invokingModule.getServicePoint(stack
123                 .getServiceExtensionPointId());
124         Set JavaDoc methods = getInterceptedMethods(stack, (List JavaDoc) parameters);
125         try
126         {
127             PerformanceCollector counter = createMBean(servicePoint, methods);
128             InvocationHandler JavaDoc countHandler = new PerformanceMonitorHandler(stack.peek(), counter,
129                     methods);
130
131             Object JavaDoc proxy = Proxy.newProxyInstance(invokingModule.getClassResolver()
132                     .getClassLoader(), new Class JavaDoc[]
133             { stack.getServiceInterface() }, countHandler);
134
135             stack.push(proxy);
136         }
137         catch (Exception JavaDoc ex)
138         {
139             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     public PerformanceCollector createMBean(ServicePoint servicePoint, Set JavaDoc methods)
148             throws JMException JavaDoc
149     {
150         PerformanceCollector counter = new PerformanceMonitorMBean(methods);
151         ObjectName JavaDoc objectName = _objectNameBuilder.createServiceDecoratorName(
152                 servicePoint,
153                 SERVICE_DECORATOR_TYPE);
154         _mbeanRegistry.registerMBean(counter, null, objectName);
155
156         return counter;
157     }
158
159     /**
160      * Creates a method matcher that helps finding the intercepted methods
161      */

162     private MethodMatcher buildMethodMatcher(List JavaDoc parameters)
163     {
164         MethodMatcher result = null;
165
166         Iterator JavaDoc i = parameters.iterator();
167         while (i.hasNext())
168         {
169             MethodContribution mc = (MethodContribution) i.next();
170
171             if (result == null)
172                 result = new MethodMatcher();
173
174             result.put(mc.getMethodPattern(), mc);
175         }
176
177         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     protected Set JavaDoc getInterceptedMethods(InterceptorStack stack, List JavaDoc parameters)
185     {
186         Set JavaDoc methods = new HashSet JavaDoc();
187         MethodMatcher matcher = buildMethodMatcher(parameters);
188
189         MethodIterator mi = new MethodIterator(stack.getServiceInterface());
190
191         while (mi.hasNext())
192         {
193             MethodSignature sig = mi.next();
194
195             if (includeMethod(matcher, sig))
196                 methods.add(sig);
197         }
198         return methods;
199     }
200
201     private boolean includeMethod(MethodMatcher matcher, MethodSignature sig)
202     {
203         if (matcher == null)
204             return true;
205
206         MethodContribution mc = (MethodContribution) matcher.get(sig);
207         return mc == null || mc.getInclude();
208     }
209
210 }
Popular Tags