thingsboard-client-demo/src/main/java/com/tuoheng/status/statemachine/manager/StateMachineManager.java

263 lines
8.3 KiB
Java
Raw Normal View History

2025-12-15 16:27:55 +08:00
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;
// 存储状态机实例的Mapkey为状态机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 +
'}';
}
}
}