263 lines
8.3 KiB
Java
263 lines
8.3 KiB
Java
|
|
package com.tuoheng.status.statemachine.manager;
|
|||
|
|
|
|||
|
|
import com.tuoheng.status.statemachine.events.Event;
|
|||
|
|
import com.tuoheng.status.statemachine.status.Status;
|
|||
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|||
|
|
import org.springframework.statemachine.StateMachine;
|
|||
|
|
import org.springframework.statemachine.config.StateMachineFactory;
|
|||
|
|
import org.springframework.statemachine.state.State;
|
|||
|
|
import org.springframework.stereotype.Component;
|
|||
|
|
|
|||
|
|
import java.util.Map;
|
|||
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|||
|
|
import java.util.logging.Logger;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 状态机管理器
|
|||
|
|
* 用于管理多个状态机实例,通过ID获取和查询状态机
|
|||
|
|
*/
|
|||
|
|
@Component
|
|||
|
|
public class StateMachineManager {
|
|||
|
|
|
|||
|
|
private static final Logger logger = Logger.getLogger(StateMachineManager.class.getName());
|
|||
|
|
|
|||
|
|
@Autowired
|
|||
|
|
private StateMachineFactory<Status, Event> stateMachineFactory;
|
|||
|
|
|
|||
|
|
// 存储状态机实例的Map,key为状态机ID
|
|||
|
|
private final Map<String, StateMachine<Status, Event>> stateMachineMap = new ConcurrentHashMap<>();
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 创建或获取状态机实例
|
|||
|
|
* 如果ID对应的状态机不存在,则创建新实例;如果存在,则返回现有实例
|
|||
|
|
*
|
|||
|
|
* @param machineId 状态机ID
|
|||
|
|
* @return 状态机实例
|
|||
|
|
*/
|
|||
|
|
public StateMachine<Status, Event> getOrCreateStateMachine(String machineId) {
|
|||
|
|
return stateMachineMap.computeIfAbsent(machineId, id -> {
|
|||
|
|
logger.info("创建新状态机实例,ID: " + id);
|
|||
|
|
StateMachine<Status, Event> stateMachine = stateMachineFactory.getStateMachine(id);
|
|||
|
|
// 将machineId存储到扩展状态中
|
|||
|
|
stateMachine.getExtendedState().getVariables().put("machineId", id);
|
|||
|
|
// 启动状态机
|
|||
|
|
stateMachine.start();
|
|||
|
|
return stateMachine;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取状态机实例(如果不存在则返回null)
|
|||
|
|
*
|
|||
|
|
* @param machineId 状态机ID
|
|||
|
|
* @return 状态机实例,如果不存在则返回null
|
|||
|
|
*/
|
|||
|
|
public StateMachine<Status, Event> getStateMachine(String machineId) {
|
|||
|
|
return stateMachineMap.get(machineId);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 创建新的状态机实例(如果已存在则先停止并移除旧的)
|
|||
|
|
*
|
|||
|
|
* @param machineId 状态机ID
|
|||
|
|
* @return 新创建的状态机实例
|
|||
|
|
*/
|
|||
|
|
public StateMachine<Status, Event> createStateMachine(String machineId) {
|
|||
|
|
// 如果已存在,先停止并移除
|
|||
|
|
StateMachine<Status, Event> existing = stateMachineMap.remove(machineId);
|
|||
|
|
if (existing != null) {
|
|||
|
|
logger.info("停止并移除已存在的状态机,ID: " + machineId);
|
|||
|
|
try {
|
|||
|
|
existing.stop();
|
|||
|
|
} catch (Exception e) {
|
|||
|
|
logger.warning("停止状态机时发生错误: " + e.getMessage());
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 创建新实例
|
|||
|
|
logger.info("创建新状态机实例,ID: " + machineId);
|
|||
|
|
StateMachine<Status, Event> stateMachine = stateMachineFactory.getStateMachine(machineId);
|
|||
|
|
stateMachine.getExtendedState().getVariables().put("machineId", machineId);
|
|||
|
|
stateMachine.start();
|
|||
|
|
stateMachineMap.put(machineId, stateMachine);
|
|||
|
|
return stateMachine;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取状态机的当前状态
|
|||
|
|
*
|
|||
|
|
* @param machineId 状态机ID
|
|||
|
|
* @return 当前状态,如果状态机不存在则返回null
|
|||
|
|
*/
|
|||
|
|
public Status getCurrentStatus(String machineId) {
|
|||
|
|
StateMachine<Status, Event> stateMachine = stateMachineMap.get(machineId);
|
|||
|
|
if (stateMachine == null) {
|
|||
|
|
logger.warning("状态机不存在,ID: " + machineId);
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
State<Status, Event> state = stateMachine.getState();
|
|||
|
|
if (state == null) {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return state.getId();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取状态机的详细信息(包括当前状态和扩展状态)
|
|||
|
|
*
|
|||
|
|
* @param machineId 状态机ID
|
|||
|
|
* @return 状态机信息,如果状态机不存在则返回null
|
|||
|
|
*/
|
|||
|
|
public StateMachineInfo getStateMachineInfo(String machineId) {
|
|||
|
|
StateMachine<Status, Event> stateMachine = stateMachineMap.get(machineId);
|
|||
|
|
if (stateMachine == null) {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
StateMachineInfo info = new StateMachineInfo();
|
|||
|
|
info.setMachineId(machineId);
|
|||
|
|
|
|||
|
|
State<Status, Event> state = stateMachine.getState();
|
|||
|
|
if (state != null) {
|
|||
|
|
info.setCurrentStatus(state.getId());
|
|||
|
|
info.setIsSubState(state.isSubmachineState());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
info.setExtendedState(stateMachine.getExtendedState().getVariables());
|
|||
|
|
// 通过检查状态机是否有状态来判断是否在运行
|
|||
|
|
// Spring StateMachine 3.2.0 没有 isRunning() 方法,使用状态判断
|
|||
|
|
info.setIsRunning(state != null);
|
|||
|
|
|
|||
|
|
return info;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 移除状态机实例
|
|||
|
|
*
|
|||
|
|
* @param machineId 状态机ID
|
|||
|
|
* @return 是否成功移除
|
|||
|
|
*/
|
|||
|
|
public boolean removeStateMachine(String machineId) {
|
|||
|
|
StateMachine<Status, Event> stateMachine = stateMachineMap.remove(machineId);
|
|||
|
|
if (stateMachine != null) {
|
|||
|
|
logger.info("移除状态机实例,ID: " + machineId);
|
|||
|
|
try {
|
|||
|
|
stateMachine.stop();
|
|||
|
|
return true;
|
|||
|
|
} catch (Exception e) {
|
|||
|
|
logger.warning("停止状态机时发生错误: " + e.getMessage());
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 检查状态机是否存在
|
|||
|
|
*
|
|||
|
|
* @param machineId 状态机ID
|
|||
|
|
* @return 是否存在
|
|||
|
|
*/
|
|||
|
|
public boolean exists(String machineId) {
|
|||
|
|
return stateMachineMap.containsKey(machineId);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取所有状态机的ID列表
|
|||
|
|
*
|
|||
|
|
* @return 状态机ID集合
|
|||
|
|
*/
|
|||
|
|
public java.util.Set<String> getAllMachineIds() {
|
|||
|
|
return stateMachineMap.keySet();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取当前管理的状态机数量
|
|||
|
|
*
|
|||
|
|
* @return 状态机数量
|
|||
|
|
*/
|
|||
|
|
public int getStateMachineCount() {
|
|||
|
|
return stateMachineMap.size();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 清空所有状态机实例
|
|||
|
|
*/
|
|||
|
|
public void clearAll() {
|
|||
|
|
logger.info("清空所有状态机实例,数量: " + stateMachineMap.size());
|
|||
|
|
for (Map.Entry<String, StateMachine<Status, Event>> entry : stateMachineMap.entrySet()) {
|
|||
|
|
try {
|
|||
|
|
entry.getValue().stop();
|
|||
|
|
} catch (Exception e) {
|
|||
|
|
logger.warning("停止状态机时发生错误,ID: " + entry.getKey() + ", 错误: " + e.getMessage());
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
stateMachineMap.clear();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 状态机信息类
|
|||
|
|
*/
|
|||
|
|
public static class StateMachineInfo {
|
|||
|
|
private String machineId;
|
|||
|
|
private Status currentStatus;
|
|||
|
|
private boolean isSubState;
|
|||
|
|
private boolean isRunning;
|
|||
|
|
private Map<Object, Object> extendedState;
|
|||
|
|
|
|||
|
|
// Getters and Setters
|
|||
|
|
public String getMachineId() {
|
|||
|
|
return machineId;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void setMachineId(String machineId) {
|
|||
|
|
this.machineId = machineId;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public Status getCurrentStatus() {
|
|||
|
|
return currentStatus;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void setCurrentStatus(Status currentStatus) {
|
|||
|
|
this.currentStatus = currentStatus;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public boolean isSubState() {
|
|||
|
|
return isSubState;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void setIsSubState(boolean subState) {
|
|||
|
|
isSubState = subState;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public boolean isRunning() {
|
|||
|
|
return isRunning;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void setIsRunning(boolean running) {
|
|||
|
|
isRunning = running;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public Map<Object, Object> getExtendedState() {
|
|||
|
|
return extendedState;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void setExtendedState(Map<Object, Object> extendedState) {
|
|||
|
|
this.extendedState = extendedState;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@Override
|
|||
|
|
public String toString() {
|
|||
|
|
return "StateMachineInfo{" +
|
|||
|
|
"machineId='" + machineId + '\'' +
|
|||
|
|
", currentStatus=" + currentStatus +
|
|||
|
|
", isSubState=" + isSubState +
|
|||
|
|
", isRunning=" + isRunning +
|
|||
|
|
", extendedState=" + extendedState +
|
|||
|
|
'}';
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|