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

263 lines
8.3 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 +
'}';
}
}
}