001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.monitoring.statistics.service;
016    
017    import com.liferay.portal.kernel.monitoring.RequestStatus;
018    import com.liferay.portal.kernel.monitoring.statistics.DataSampleThreadLocal;
019    import com.liferay.portal.kernel.util.AutoResetThreadLocal;
020    import com.liferay.portal.monitoring.jmx.MethodSignature;
021    import com.liferay.portal.spring.aop.ChainableMethodAdvice;
022    
023    import java.lang.reflect.Method;
024    
025    import java.util.HashSet;
026    import java.util.Set;
027    
028    import org.aopalliance.intercept.MethodInvocation;
029    
030    /**
031     * @author Michael C. Han
032     */
033    public class ServiceMonitorAdvice extends ChainableMethodAdvice {
034    
035            /**
036             * @deprecated As of 6.1.0
037             */
038            @Deprecated
039            public static ServiceMonitorAdvice getInstance() {
040                    return new ServiceMonitorAdvice();
041            }
042    
043            public static boolean isActive() {
044                    return _active;
045            }
046    
047            public void addMonitoredClass(String className) {
048                    _monitoredClasses.add(className);
049            }
050    
051            public void addMonitoredMethod(
052                    String className, String methodName, String[] parameterTypes) {
053    
054                    MethodSignature methodSignature = new MethodSignature(
055                            className, methodName, parameterTypes);
056    
057                    _monitoredMethods.add(methodSignature);
058            }
059    
060            @Override
061            public void afterReturning(MethodInvocation methodInvocation, Object result)
062                    throws Throwable {
063    
064                    ServiceRequestDataSample serviceRequestDataSample =
065                            _serviceRequestDataSampleThreadLocal.get();
066    
067                    if (serviceRequestDataSample != null) {
068                            serviceRequestDataSample.capture(RequestStatus.SUCCESS);
069                    }
070            }
071    
072            @Override
073            public void afterThrowing(
074                            MethodInvocation methodInvocation, Throwable throwable)
075                    throws Throwable {
076    
077                    ServiceRequestDataSample serviceRequestDataSample =
078                            _serviceRequestDataSampleThreadLocal.get();
079    
080                    if (serviceRequestDataSample != null) {
081                            serviceRequestDataSample.capture(RequestStatus.ERROR);
082                    }
083            }
084    
085            @Override
086            public Object before(MethodInvocation methodInvocation) throws Throwable {
087                    if (!_active) {
088                            serviceBeanAopCacheManager.removeMethodInterceptor(
089                                    methodInvocation, this);
090    
091                            return null;
092                    }
093    
094                    if (!_permissiveMode && !isMonitored(methodInvocation)) {
095                            return null;
096                    }
097    
098                    ServiceRequestDataSample serviceRequestDataSample =
099                            new ServiceRequestDataSample(methodInvocation);
100    
101                    serviceRequestDataSample.prepare();
102    
103                    _serviceRequestDataSampleThreadLocal.set(serviceRequestDataSample);
104    
105                    DataSampleThreadLocal.initialize();
106    
107                    return null;
108            }
109    
110            @Override
111            public void duringFinally(MethodInvocation methodInvocation) {
112                    ServiceRequestDataSample serviceRequestDataSample =
113                            _serviceRequestDataSampleThreadLocal.get();
114    
115                    if (serviceRequestDataSample != null) {
116                            _serviceRequestDataSampleThreadLocal.remove();
117    
118                            DataSampleThreadLocal.addDataSample(serviceRequestDataSample);
119                    }
120            }
121    
122            public Set<String> getMonitoredClasses() {
123                    return _monitoredClasses;
124            }
125    
126            public Set<MethodSignature> getMonitoredMethods() {
127                    return _monitoredMethods;
128            }
129    
130            public boolean isPermissiveMode() {
131                    return _permissiveMode;
132            }
133    
134            public void setActive(boolean active) {
135                    if (active && !_active) {
136                            serviceBeanAopCacheManager.reset();
137                    }
138    
139                    _active = active;
140            }
141    
142            public void setMonitoredClasses(Set<String> monitoredClasses) {
143                    _monitoredClasses = monitoredClasses;
144            }
145    
146            public void setMonitoredMethods(Set<MethodSignature> monitoredMethods) {
147                    _monitoredMethods = monitoredMethods;
148            }
149    
150            /**
151             * @deprecated As of 6.2.0
152             */
153            @Deprecated
154            public void setMonitoringDestinationName(String monitoringDestinationName) {
155            }
156    
157            public void setPermissiveMode(boolean permissiveMode) {
158                    _permissiveMode = permissiveMode;
159            }
160    
161            protected boolean isMonitored(MethodInvocation methodInvocation) {
162                    Method method = methodInvocation.getMethod();
163    
164                    Class<?> declaringClass = method.getDeclaringClass();
165    
166                    String className = declaringClass.getName();
167    
168                    if (_monitoredClasses.contains(className)) {
169                            return true;
170                    }
171    
172                    MethodSignature methodSignature = new MethodSignature(method);
173    
174                    if (_monitoredMethods.contains(methodSignature)) {
175                            return true;
176                    }
177    
178                    return false;
179            }
180    
181            private static boolean _active;
182            private static Set<String> _monitoredClasses = new HashSet<String>();
183            private static Set<MethodSignature> _monitoredMethods =
184                    new HashSet<MethodSignature>();
185            private static boolean _permissiveMode;
186            private static final ThreadLocal<ServiceRequestDataSample>
187                    _serviceRequestDataSampleThreadLocal =
188                            new AutoResetThreadLocal<ServiceRequestDataSample>(
189                                    ServiceRequestDataSample.class +
190                                            "._serviceRequestDataSampleThreadLocal");
191    
192    }