/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.monitor.ows;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.geoserver.monitor.Monitor;
import org.geoserver.monitor.RequestData;
import org.geoserver.monitor.RequestData.Status;
import org.geoserver.ows.DispatcherCallback;
import org.geoserver.ows.util.OwsUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class ControlFlowCallbackProxy implements InvocationHandler, BeanPostProcessor {
Object target;
Monitor monitor;
public ControlFlowCallbackProxy(Monitor monitor) {
this.monitor = monitor;
}
public ControlFlowCallbackProxy(Monitor monitor, Object target) {
this.monitor = monitor;
this.target = target;
}
/**
* Returns the number of running requests from the underlying control flow callback.
*/
public long getRunningRequests() {
return (Long) OwsUtils.get(target, "runningRequests");
}
/**
* Returns the number of blocked requests from the underlying control flow callback.
*/
public long getBlockedRequests() {
return (Long) OwsUtils.get(target, "blockedRequests");
}
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if ("ControlFlowCallback".equals(bean.getClass().getSimpleName())) {
//wrap the control flow in a proxy
bean = Proxy.newProxyInstance(bean.getClass().getClassLoader(),
new Class[]{DispatcherCallback.class}, new ControlFlowCallbackProxy(monitor, bean));
}
return bean;
}
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("operationDispatched".equals(method.getName()) && monitor.current() != null) {
RequestData data = monitor.current();
if (data == null) {
// means monitor is configured but inactive
return method.invoke(target, args);
}
data.setStatus(Status.WAITING);
monitor.update();
Object result = method.invoke(target, args);
data.setStatus(Status.RUNNING);
monitor.update();
return result;
}
else {
return method.invoke(target, args);
}
}
}