/** * 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(); } }