/**
* Dianping.com Inc.
* Copyright (c) 2003-2013 All Rights Reserved.
*/
package com.dianping.pigeon.remoting.provider.process;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import com.dianping.pigeon.remoting.provider.process.filter.*;
import com.dianping.pigeon.log.Logger;
import com.dianping.pigeon.log.LoggerLoader;
import com.dianping.pigeon.remoting.common.domain.Disposable;
import com.dianping.pigeon.remoting.common.domain.InvocationContext;
import com.dianping.pigeon.remoting.common.domain.InvocationResponse;
import com.dianping.pigeon.remoting.common.process.ServiceInvocationFilter;
import com.dianping.pigeon.remoting.common.process.ServiceInvocationHandler;
import com.dianping.pigeon.remoting.common.util.Constants;
import com.dianping.pigeon.remoting.provider.domain.ProviderContext;
import com.dianping.pigeon.remoting.provider.process.filter.SecurityFilter;
import com.dianping.pigeon.remoting.provider.process.filter.TraceFilter;
public final class ProviderProcessHandlerFactory {
private static final Logger logger = LoggerLoader.getLogger(ProviderProcessHandlerFactory.class);
private static List<ServiceInvocationFilter<ProviderContext>> bizProcessFilters = new LinkedList<ServiceInvocationFilter<ProviderContext>>();
private static List<ServiceInvocationFilter<ProviderContext>> heartBeatProcessFilters = new LinkedList<ServiceInvocationFilter<ProviderContext>>();
private static List<ServiceInvocationFilter<ProviderContext>> healthCheckProcessFilters = new LinkedList<ServiceInvocationFilter<ProviderContext>>();
private static List<ServiceInvocationFilter<ProviderContext>> scannerHeartBeatProcessFilters = new LinkedList<ServiceInvocationFilter<ProviderContext>>();
private static ServiceInvocationHandler bizInvocationHandler = null;
private static ServiceInvocationHandler heartBeatInvocationHandler = null;
private static ServiceInvocationHandler healthCheckInvocationHandler = null;
private static ServiceInvocationHandler scannerHeartBeatInvocationHandler = null;
public static ServiceInvocationHandler selectInvocationHandler(int messageType) {
if (Constants.MESSAGE_TYPE_HEART == messageType) {
return heartBeatInvocationHandler;
} else if (Constants.MESSAGE_TYPE_HEALTHCHECK == messageType) {
return healthCheckInvocationHandler;
} else if (Constants.MESSAGE_TYPE_SCANNER_HEART == messageType) {
return scannerHeartBeatInvocationHandler;
} else {
return bizInvocationHandler;
}
}
public static void init() {
registerBizProcessFilter(new TraceFilter());
if (Constants.MONITOR_ENABLE) {
registerBizProcessFilter(new MonitorProcessFilter());
}
registerBizProcessFilter(new WriteResponseProcessFilter());
registerBizProcessFilter(new ContextTransferProcessFilter());
registerBizProcessFilter(new ExceptionProcessFilter());
registerBizProcessFilter(new SecurityFilter());
registerBizProcessFilter(new GatewayProcessFilter());
registerBizProcessFilter(new BusinessProcessFilter());
bizInvocationHandler = createInvocationHandler(bizProcessFilters);
registerHeartBeatProcessFilter(new WriteResponseProcessFilter());
registerHeartBeatProcessFilter(new HeartbeatProcessFilter());
heartBeatInvocationHandler = createInvocationHandler(heartBeatProcessFilters);
registerHealthCheckProcessFilter(new WriteResponseProcessFilter());
registerHealthCheckProcessFilter(new HealthCheckProcessFilter());
healthCheckInvocationHandler = createInvocationHandler(healthCheckProcessFilters);
registerScannerHeartBeatProcessFilter(new WriteResponseProcessFilter());
registerScannerHeartBeatProcessFilter(new ScannerHeartBeatProcessFilter());
scannerHeartBeatInvocationHandler = createInvocationHandler(scannerHeartBeatProcessFilters);
}
@SuppressWarnings({ "rawtypes" })
private static <K, V extends ServiceInvocationFilter> ServiceInvocationHandler createInvocationHandler(
List<V> internalFilters) {
ServiceInvocationHandler last = null;
List<V> filterList = new ArrayList<V>();
filterList.addAll(internalFilters);
for (int i = filterList.size() - 1; i >= 0; i--) {
final V filter = filterList.get(i);
final ServiceInvocationHandler next = last;
last = new ServiceInvocationHandler() {
@SuppressWarnings("unchecked")
@Override
public InvocationResponse handle(InvocationContext invocationContext) throws Throwable {
return filter.invoke(next, invocationContext);
}
};
}
return last;
}
private static void registerBizProcessFilter(ServiceInvocationFilter<ProviderContext> filter) {
bizProcessFilters.add(filter);
}
private static void registerHeartBeatProcessFilter(ServiceInvocationFilter<ProviderContext> filter) {
heartBeatProcessFilters.add(filter);
}
private static void registerHealthCheckProcessFilter(ServiceInvocationFilter<ProviderContext> filter) {
healthCheckProcessFilters.add(filter);
}
private static void registerScannerHeartBeatProcessFilter(ServiceInvocationFilter<ProviderContext> filter) {
scannerHeartBeatProcessFilters.add(filter);
}
public static void destroy() {
for (ServiceInvocationFilter<ProviderContext> filter : bizProcessFilters) {
if (filter instanceof Disposable) {
try {
((Disposable) filter).destroy();
} catch (Exception e) {
}
}
}
for (ServiceInvocationFilter<ProviderContext> filter : heartBeatProcessFilters) {
if (filter instanceof Disposable) {
try {
((Disposable) filter).destroy();
} catch (Exception e) {
}
}
}
bizProcessFilters.clear();
heartBeatProcessFilters.clear();
}
}