package com.dy.rtuMw.server.upgrade;
|
|
import com.dy.common.softUpgrade.state.UpgradeInfo;
|
import com.dy.common.softUpgrade.state.UpgradeRtu;
|
import com.dy.common.softUpgrade.state.UpgradeState;
|
import com.dy.common.softUpgrade.state.UpgradeTaskVo;
|
import com.dy.common.springUtil.SpringContextUtil;
|
import com.dy.common.util.Callback;
|
import com.dy.common.util.DateTime;
|
import com.dy.common.util.TimerTaskJob;
|
import com.dy.rtuMw.web.webRequest.WebRequestDeal;
|
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.Logger;
|
import java.util.List;
|
|
/**
|
* 升级管理类
|
* @Author liurunyu
|
* @Date 2024/11/4 16:03
|
* @Description
|
*/
|
public class UpgradeManager extends TimerTaskJob implements Callback {
|
|
private static final Logger log = LogManager.getLogger(UpgradeManager.class.getName());
|
|
private static final UpgradeManager INSTANCE = new UpgradeManager();
|
|
private Integer failTryTimes ;//升级失败后,重新偿试升级次数,0表示不重新偿试升级
|
private Integer ugMaxRtuSameTime ;//同时升级RTU最大个数
|
|
private UpgradeTask task ;//升级任务
|
private boolean monitorFirst = true ;//是否是第一次监视
|
|
private UpgradeManager(){
|
monitorFirst = true ;
|
}
|
|
public static UpgradeManager getInstance() {
|
return UpgradeManager.INSTANCE;
|
}
|
|
/**
|
* 初始化配置信息
|
*/
|
public void initOption(UpgradeUnitConfigVo configVo) {
|
this.failTryTimes = configVo.failTryTimes;
|
this.ugMaxRtuSameTime = configVo.ugMaxRtuAtOnce;
|
}
|
|
/**
|
* 设置升级任务
|
* @param vo UpgradeTaskVo 升级任务对象
|
* @throws Exception 异常
|
*/
|
public void setUpgradeTask(UpgradeTaskVo vo) throws Exception {
|
if(this.task != null && !this.task.taskIsOver){
|
throw new Exception("当前存在升级任务,请等待当前任务执行完或强制结束当前任务");
|
}else {
|
Exception ex = null ;
|
try{
|
if(this.task != null){
|
this.task.forceOver();
|
}
|
this.task = new UpgradeTask();
|
this.task.initOption(this.failTryTimes, this.ugMaxRtuSameTime);
|
this.task.setTask(vo);
|
log.info("======================================================") ;
|
log.info("= =") ;
|
log.info("=设置了升级任务,涉及RTU" + vo.rtuAddrList.size() + "台 =") ;
|
log.info("= =") ;
|
log.info("======================================================") ;
|
}catch (Exception e){
|
ex = e ;
|
}finally {
|
if(ex != null){
|
this.task = null ;
|
throw ex ;
|
}else{
|
this.start(1000L, (long) UpgradeUnit.confVo.notifyStateInterval, this);
|
}
|
}
|
}
|
}
|
|
/**
|
* 强制结束当前升级任务,
|
* 此功能可能不会开放出去,
|
* 因为强制结束升级任务,对一个未升级完成的RTU就会卡死,
|
* 所以当强制结束升级任务,代码逻辑并没有强制结果RTU升级过程,如果升级过程也强制停止,那么RTU真会卡死
|
*/
|
public String forceOverUpgradeTask() {
|
if(this.task != null){
|
this.task.countRunningRtuCount();
|
if(this.task.curUgRunningRtuTotal > 0){
|
return "当前存在升级中的设备,不能结束升级任务" ;
|
}else{
|
this.stop();
|
this.task.forceOver();
|
return null ;
|
}
|
}else{
|
return "当前没有升级任务" ;
|
}
|
}
|
|
/**
|
* RTU有上行数据了,触发下发升级数据
|
* @param rtuAddr 控制器RTU地址
|
* @param code 上行数据功能码
|
* @param protocolName 上行数据对应的协议名称
|
* @param protocolVersion 上行数据对应的协议版本号
|
* @param callbackCom 回调函数,处理下行命令
|
*/
|
public void trigger(String rtuAddr, String code, String protocolName, Short protocolVersion, Callback callbackCom){
|
if(task != null && !task.taskIsOver){
|
this.task.trigger(rtuAddr, code, protocolName, protocolVersion, callbackCom);
|
}
|
}
|
|
////////////////////////////////////////////////////
|
//
|
// 查询升级状态信息
|
//
|
////////////////////////////////////////////////////
|
/**
|
* 当前升级状态
|
* @return 当前升级状态
|
*/
|
public UpgradeState currentUpgradeState() {
|
if(task != null){
|
return task.currentUpgradeState() ;
|
}else{
|
return null ;
|
}
|
}
|
|
/**
|
* Rtu升级信息
|
* @param rtuAddr 控制器RTU地址
|
* @return 控制器RTU升级状态
|
*/
|
@SuppressWarnings("unused")
|
public UpgradeRtu upgradeRtuInfo(String rtuAddr){
|
if(task != null){
|
return task.upgradeInfos(rtuAddr) ;
|
}else{
|
return null ;
|
}
|
}
|
|
/**
|
* Rtu升级信息
|
* @param rtuAddrList 控制器地址列表
|
* @return 指定列表中的控制器RTU升级状态
|
*/
|
@SuppressWarnings("unused")
|
public List<UpgradeRtu> upgradeRtuInfos(List<String> rtuAddrList){
|
if(task != null){
|
return task.upgradeInfos(rtuAddrList) ;
|
}else{
|
return null ;
|
}
|
}
|
|
|
/**
|
* 所有Rtu升级信息
|
* @return 所有Rtu升级信息
|
*/
|
public List<UpgradeRtu> upgradeRtuInfoAll(){
|
if(task != null){
|
return task.upgradeInfoAll() ;
|
}else{
|
return null ;
|
}
|
}
|
|
|
////////////////////////////////////////////////////
|
//
|
// 升级服务工作线程执行的方法
|
// 统计状态 + 状态通知
|
//
|
////////////////////////////////////////////////////
|
public Object execute() {
|
if(this.task == null
|
|| this.task.taskVo == null
|
|| this.task.taskVo.rtuAddrList == null
|
|| this.task.taskVo.rtuAddrList.size() == 0){
|
//任务为空
|
this.stop() ;
|
}else{
|
if(!this.task.taskIsOver){
|
//升级任务未完成
|
//工作1:判断是否无任何一个RTU进行过升级,并且达到时限,则认为当前升级任务完成
|
//-1:无一RTU升级且超时,0:无RTU升级但未超时等待,1有RTU升级正常执行
|
//int temp = 1 ;
|
int temp = this.task.countNoOneRtuUpgradeInDuration() ;
|
if(temp == -1){
|
//当前没有RTU进行过升级,而且超时了,认为任务已经完成
|
this.task.taskIsOver = true ;
|
this.stop();
|
log.info("===========================================================") ;
|
log.info("= =") ;
|
log.info("=无RTU升级超时,因无一台RTU进行升级,并且等待超时,强制设置升级完成 =") ;
|
log.info("= =") ;
|
log.info("===========================================================") ;
|
}else if(temp == 1){
|
//当前有RTU进行过升级
|
//工作2:统计当前正在升级的RTU数量,为同时升级数量限制做准备
|
this.task.countRunningRtuCount() ;
|
|
//工作3:统计需要升级但当前离线RTU的情况,超过时限的设置为升级完成
|
int tmp = this.task.countOffRtuAndSetIfOver() ;
|
if(tmp >= 1){
|
//超时,强制设置一些RTU升级失败并且升级完成)
|
log.info("======================================================") ;
|
log.info("= =") ;
|
log.info("=因离线超时,强制设置" + tmp + "台RTU升级失败并且升级完成 =") ;
|
log.info("= =") ;
|
log.info("======================================================") ;
|
}else if(tmp == 0){
|
log.info("======================================================") ;
|
log.info("= =") ;
|
log.info("=离线超时,但无一台RTU因离线而被设置成升级失败并且升级完成 =") ;
|
log.info("= =") ;
|
log.info("======================================================") ;
|
}else{//tmp = -1
|
//无任务逻辑
|
}
|
//工作4:统计是否全部升级完成
|
this.task.taskIsOver = this.task.countIsAllOver() ;
|
if(this.task.taskIsOver){
|
log.info("==================================================") ;
|
log.info("= =") ;
|
log.info("= 升级全部结束,设置升级任务完成,涉及RTU" + this.task.taskVo.rtuAddrList.size() + "台 =") ;
|
log.info("= =") ;
|
log.info("==================================================") ;
|
}
|
}else if(temp == 0){
|
//当前没有一个RTU进行过升级,也没有超时,不作为
|
}
|
if(this.task.taskIsOver){
|
if(!this.task.taskOverType.equals(UpgradeTask.TaskOverType_Force)){
|
//任务不是强制结束的
|
this.task.taskOverType = UpgradeTask.TaskOverType_Natural ;//任务完成方式(自然,强制)
|
this.task.taskOverDt = DateTime.yyyy_MM_dd_HH_mm_ss() ;//任务完成时间(yyyy-mm-dd HH:MM:SS)
|
}
|
//任务完成,执行最后一次升级状态通知
|
//工作5:升级状态通知
|
//if(!first){
|
// this.notifyUpgradeStatus() ;
|
//}
|
}else{
|
//任务未完成,继续执行升级状态通知
|
//工作5: 升级状态通知
|
//if(!first){
|
// this.notifyUpgradeStatus() ;
|
//}
|
}
|
//工作5:升级状态通知
|
if(!this.monitorFirst){
|
this.notifyUpgradeStatus() ;
|
}
|
}else{
|
//任务已经完成
|
this.stop();
|
}
|
}
|
if(this.monitorFirst){
|
this.monitorFirst = false ;
|
}
|
return true ;
|
}
|
|
/**
|
* 升级状态通知
|
*/
|
private void notifyUpgradeStatus(){
|
if(this.task.taskVo.callbackWebUrl != null && this.task.taskVo.callbackWebUrl.length() > 0){
|
UpgradeInfo info = new UpgradeInfo() ;
|
info.ugTaskId = this.task.taskVo.id ;//任务ID
|
info.ugOverallState = this.currentUpgradeState() ;
|
info.ugRtuStateList = this.upgradeRtuInfoAll() ;
|
WebRequestDeal deal = SpringContextUtil.getBean(WebRequestDeal.class) ;
|
deal.deal(this.task.taskVo.callbackWebUrl, info);
|
}
|
}
|
|
////////////////////////////////////////////////////
|
//
|
// 升级状态通知工作线程执行完成后回调的方法,
|
// 也就是上面execute方法执行完成返回或抛出异常后,执行下面三个方法
|
//
|
////////////////////////////////////////////////////
|
@Override
|
public void call(Object obj) {
|
//线程工作执行完了,obj = Boolean(true)
|
}
|
@Override
|
public void call(Object... objs) {
|
}
|
@Override
|
public void exception(Exception e) {
|
log.error("远程升级伺服线程发生异常", e);
|
}
|
|
}
|