package com.alipay.bluewhale.core.daemon; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import backtype.storm.generated.NotAliveException; import com.alipay.bluewhale.core.callback.Callback; import com.alipay.bluewhale.core.callback.impl.ActiveTransitionCallback; import com.alipay.bluewhale.core.callback.impl.DelayRebalanceTransitionCallback; import com.alipay.bluewhale.core.callback.impl.DelayRemoveTransitionCallback; import com.alipay.bluewhale.core.callback.impl.InactiveTransitionCallback; import com.alipay.bluewhale.core.callback.impl.KillTransitionCallback; import com.alipay.bluewhale.core.callback.impl.ReassignTransitionCallback; import com.alipay.bluewhale.core.callback.impl.RebalanceTransitionCallback; import com.alipay.bluewhale.core.callback.impl.DoRebalanceTransitionCallback; import com.alipay.bluewhale.core.callback.impl.RemoveTransitionCallback; import com.alipay.bluewhale.core.cluster.Common; import com.alipay.bluewhale.core.cluster.StormBase; import com.alipay.bluewhale.core.cluster.StormClusterState; import com.alipay.bluewhale.core.cluster.StormStatus; /** * ״̬ת���� * * @author lixin 2012-3-21 ����4:17:10 * */ public class StatusTransition { private final static Logger LOG = Logger.getLogger(StatusTransition.class); //����״̬ת������ //FIXME ����Ų����transition�������棬û��ҪŪһ����̬�ij�Ա���� private static Map<StatusType, Map<StatusType, Callback>> rtn; //ϵͳ�¼�---:startup��:monitor���� private static List<String>system_events; /** * ״̬ת��������Ӧ�¼� * * @param data * nimbus���ݶ��� * @param topologyId * topologyid * @param errorOnNTransition * @param eventtype * Ҫת���¼����� * @param args * �¼����� */ public static <T> void transition(NimbusData data, String topologyid, boolean errorOnNoTransition, StatusType transition_status, T... args) { synchronized (data.getSubmitLock()) { // ��������ֹclean��submittopology�Ȳ��� if(system_events==null){ //ϵͳ�¼�---:startup��:monitor���� system_events=new ArrayList<String>(); system_events.add(StatusType.startup.getStatus()); system_events.add(StatusType.monitor.getStatus()); } //��ȡָ��topology��Ӧ��״̬���� StormBase stormbase = data.getStormClusterState().storm_base(topologyid, null); StormStatus topologyStatus=null; if (stormbase != null){ topologyStatus = stormbase.getStatus(); } if (topologyStatus != null) { //if(rtn==null){ //����ÿ�λ�ȡ����״̬ת������ rtn=stateTransitions(data,topologyid, topologyStatus); //} //��ȡ��ǰtopology״̬��ת����״̬���� Map<StatusType, Callback> transition_map=rtn.get(topologyStatus.getStatusType()); if(transition_map.containsKey(transition_status)){ //��ȡת���¶���ִ�з�����ִ�С� Callback callback=transition_map.get(transition_status); //�����µ�״̬����StormStatus if(callback!=null){ Object obj=callback.execute(args); if (obj != null && obj instanceof StormStatus) { StormStatus newStatus=(StormStatus)obj; //����״̬ data.getStormClusterState().update_storm(topologyid, newStatus); LOG.info("Updated " + topologyid + " with status " + newStatus); } } }else{ String msg = "No transition for event: " + transition_status.getStatus() + ", status: " + topologyStatus + " topology-id: " + topologyid; if (errorOnNoTransition) { throw new RuntimeException(msg); }else if (system_events.contains(transition_status.getStatus())) { LOG.info(msg); } } }else{ LOG.info("Cannot apply event " + transition_status.getStatus() + " to " + topologyid + " because topology no longer exists"); } } } public static <T> void transitionName(NimbusData data, String topologyName, boolean errorOnNoTransition, StatusType transition_status, T... args) throws NotAliveException { StormClusterState stormClusterState = data.getStormClusterState(); String topologyId = Common.get_storm_id(stormClusterState, topologyName); if (topologyId == null){ throw new NotAliveException(topologyName); } transition(data, topologyId, errorOnNoTransition, transition_status, args); } /** * ��ʼ��״̬���ͼ���Ӧ�����߼� * * @param data * @param topologyid * @param status * @return */ private static Map<StatusType, Map<StatusType, Callback>> stateTransitions(NimbusData data, String topologyid, StormStatus status) { rtn = new HashMap<StatusType, Map<StatusType, Callback>>(); Map<StatusType, Callback> activeMap = new HashMap<StatusType, Callback>(); activeMap.put(StatusType.monitor, new ReassignTransitionCallback(data,topologyid)); activeMap.put(StatusType.inactive, new InactiveTransitionCallback()); activeMap.put(StatusType.activate, null); activeMap.put(StatusType.rebalance, new RebalanceTransitionCallback(data,topologyid, status)); activeMap.put(StatusType.kill, new KillTransitionCallback(data, topologyid,status)); rtn.put(StatusType.active, activeMap); Map<StatusType, Callback> inactiveMap = new HashMap<StatusType, Callback>(); inactiveMap.put(StatusType.monitor, new ReassignTransitionCallback(data,topologyid)); inactiveMap.put(StatusType.activate, new ActiveTransitionCallback()); inactiveMap.put(StatusType.inactivate, null); inactiveMap.put(StatusType.rebalance, new RebalanceTransitionCallback(data,topologyid, status)); inactiveMap.put(StatusType.kill, new KillTransitionCallback(data, topologyid,status)); rtn.put(StatusType.inactive, inactiveMap); Map<StatusType, Callback> killedMap = new HashMap<StatusType, Callback>(); killedMap.put(StatusType.startup, new DelayRemoveTransitionCallback(data, topologyid, status)); killedMap.put(StatusType.kill, new KillTransitionCallback(data, topologyid,status)); killedMap.put(StatusType.remove, new RemoveTransitionCallback(data, topologyid)); rtn.put(StatusType.killed, killedMap); Map<StatusType, Callback> rebalancingMap = new HashMap<StatusType, Callback>(); rebalancingMap.put(StatusType.startup, new DelayRebalanceTransitionCallback(data, topologyid, status)); rebalancingMap.put(StatusType.kill, new KillTransitionCallback(data, topologyid,status)); rebalancingMap.put(StatusType.do_rebalance, new DoRebalanceTransitionCallback(data, topologyid, status)); rtn.put(StatusType.rebalancing, rebalancingMap); return rtn; } }