1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
13   */
14  
15  package com.liferay.portal.monitoring.statistics.service;
16  
17  import com.liferay.portal.SystemException;
18  import com.liferay.portal.kernel.messaging.MessageBusUtil;
19  import com.liferay.portal.kernel.util.AutoResetThreadLocal;
20  import com.liferay.portal.kernel.util.MethodKey;
21  import com.liferay.portal.monitoring.MonitoringProcessor;
22  import com.liferay.portal.monitoring.RequestStatus;
23  import com.liferay.portal.monitoring.statistics.DataSampleThreadLocal;
24  import com.liferay.portal.spring.aop.ChainableMethodAdvice;
25  
26  import java.lang.reflect.Method;
27  
28  import java.util.HashSet;
29  import java.util.Set;
30  
31  import org.aopalliance.intercept.MethodInvocation;
32  
33  /**
34   * <a href="ServiceMonitorAdvice.java.html"><b><i>View Source</i></b></a>
35   *
36   * @author Michael C. Han
37   */
38  public class ServiceMonitorAdvice extends ChainableMethodAdvice {
39  
40      /**
41       * @deprecated
42       */
43      public static ServiceMonitorAdvice getInstance() {
44          return new ServiceMonitorAdvice();
45      }
46  
47      public void addMonitoredClass(String className) {
48          _monitoredClasses.add(className);
49      }
50  
51      public void addMonitoredMethod(
52              String className, String methodName, String[] parameterTypes)
53          throws SystemException {
54  
55          try {
56              MethodKey methodKey = new MethodKey(
57                  className, methodName, parameterTypes);
58  
59              _monitoredMethods.add(methodKey);
60          }
61          catch (ClassNotFoundException cnfe) {
62              throw new SystemException("Unable to add method", cnfe);
63          }
64      }
65  
66      public void afterReturning(MethodInvocation methodInvocation, Object result)
67          throws Throwable {
68  
69          ServiceRequestDataSample serviceRequestDataSample =
70              _serviceRequestDataSampleThreadLocal.get();
71  
72          if (serviceRequestDataSample != null) {
73              serviceRequestDataSample.capture(RequestStatus.SUCCESS);
74          }
75      }
76  
77      public void afterThrowing(
78              MethodInvocation methodInvocation, Throwable throwable)
79          throws Throwable {
80  
81          ServiceRequestDataSample serviceRequestDataSample =
82              _serviceRequestDataSampleThreadLocal.get();
83  
84          if (serviceRequestDataSample != null) {
85              serviceRequestDataSample.capture(RequestStatus.ERROR);
86          }
87      }
88  
89      public Object before(MethodInvocation methodInvocation) throws Throwable {
90          if (!_active) {
91              return null;
92          }
93  
94          Class<?> classObj = methodInvocation.getThis().getClass();
95  
96          Class<?>[] interfaces = classObj.getInterfaces();
97  
98          for (int i = 0; i < interfaces.length; i++) {
99              if (interfaces[i].isAssignableFrom(MonitoringProcessor.class)) {
100                 return null;
101             }
102         }
103 
104         if (!_permissiveMode && !isMonitored(methodInvocation)) {
105             return null;
106         }
107 
108         ServiceRequestDataSample serviceRequestDataSample =
109             new ServiceRequestDataSample(methodInvocation);
110 
111         serviceRequestDataSample.prepare();
112 
113         _serviceRequestDataSampleThreadLocal.set(serviceRequestDataSample);
114 
115         return null;
116     }
117 
118     public void duringFinally(MethodInvocation methodInvocation) {
119         ServiceRequestDataSample serviceRequestDataSample =
120             _serviceRequestDataSampleThreadLocal.get();
121 
122         if (serviceRequestDataSample != null) {
123             _serviceRequestDataSampleThreadLocal.remove();
124 
125             DataSampleThreadLocal.addDataSample(serviceRequestDataSample);
126 
127             MessageBusUtil.sendMessage(
128                 _monitoringDestinationName, serviceRequestDataSample);
129         }
130     }
131 
132     public Set<String> getMonitoredClasses() {
133         return _monitoredClasses;
134     }
135 
136     public Set<MethodKey> getMonitoredMethods() {
137         return _monitoredMethods;
138     }
139 
140     public String getMonitoringDestinationName() {
141         return _monitoringDestinationName;
142     }
143 
144     public boolean isActive() {
145         return _active;
146     }
147 
148     public boolean isPermissiveMode() {
149         return _permissiveMode;
150     }
151 
152     public void setActive(boolean active) {
153         _active = active;
154     }
155 
156     public void setMonitoredClasses(Set<String> monitoredClasses) {
157         _monitoredClasses = monitoredClasses;
158     }
159 
160     public void setMonitoredMethods(Set<MethodKey> monitoredMethods) {
161         _monitoredMethods = monitoredMethods;
162     }
163 
164     public void setMonitoringDestinationName(String monitoringDestinationName) {
165         _monitoringDestinationName = monitoringDestinationName;
166     }
167 
168     public void setPermissiveMode(boolean permissiveMode) {
169         _permissiveMode = permissiveMode;
170     }
171 
172     protected boolean isMonitored(MethodInvocation methodInvocation) {
173         Method method = methodInvocation.getMethod();
174 
175         Class<?> declaringClass = method.getDeclaringClass();
176 
177         String className = declaringClass.getName();
178 
179         if (_monitoredClasses.contains(className)) {
180             return true;
181         }
182 
183         String methodName = method.getName();
184         Class<?>[] parameterTypes = method.getParameterTypes();
185 
186         MethodKey methodKey = new MethodKey(
187             className, methodName, parameterTypes);
188 
189         if (_monitoredMethods.contains(methodKey)) {
190             return true;
191         }
192 
193         return false;
194     }
195 
196     private static ThreadLocal<ServiceRequestDataSample>
197         _serviceRequestDataSampleThreadLocal =
198             new AutoResetThreadLocal<ServiceRequestDataSample>();
199 
200     private static boolean _active;
201     private static Set<String> _monitoredClasses = new HashSet<String>();
202     private static Set<MethodKey> _monitoredMethods = new HashSet<MethodKey>();
203     private static String _monitoringDestinationName;
204     private static boolean _permissiveMode;
205 
206 }