|
|
@@ -1,7 +1,244 @@
|
|
|
package com.shkpr.service.warncore.bizhandler;
|
|
|
|
|
|
+import com.shkpr.service.warncore.commtools.CommTool;
|
|
|
+import com.shkpr.service.warncore.commtools.TimeTool;
|
|
|
+import com.shkpr.service.warncore.constants.CommFieldStatus;
|
|
|
+import com.shkpr.service.warncore.dbdao.DBMgrProxy;
|
|
|
+import com.shkpr.service.warncore.dbdao.services.intef.OrdWarnPlanInfoDBService;
|
|
|
+import com.shkpr.service.warncore.dbdao.services.intef.OrdWarnPlanRulesDBService;
|
|
|
+import com.shkpr.service.warncore.dbdao.tables.OrdWarnPlanInfoTable;
|
|
|
+import com.shkpr.service.warncore.dto.*;
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
+
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
/**
|
|
|
* 分区分析统计数据处理
|
|
|
*/
|
|
|
public class ZoneDataWarnHandler {
|
|
|
+ private static OrdWarnPlanInfoDBService getWarnPlanInfoDBService(){
|
|
|
+ return DBMgrProxy.getInstance().applyXXXApi(OrdWarnPlanInfoDBService.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static OrdWarnPlanRulesDBService getWarnPlanRuleDBService(){
|
|
|
+ return DBMgrProxy.getInstance().applyXXXApi(OrdWarnPlanRulesDBService.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static ResponseCode handlerDataByDay(OrdWarnPlanDetail planDetail, List<OrdWarnPlanRules> rules){
|
|
|
+ ResponseCode code = ResponseCode.RESULT_NORMAL;
|
|
|
+ String step = "Start to pre analysis.";
|
|
|
+ if (getWarnPlanInfoDBService().existsLineEx(OrdWarnPlanInfoTable.R_INFO.TABLE
|
|
|
+ , new HashMap<String, Object>(){{put(OrdWarnPlanInfoTable.R_INFO.STATUS, CommFieldStatus.ENABLE);
|
|
|
+ put(OrdWarnPlanInfoTable.R_INFO.UNIQUE_ID, planDetail.getUid());
|
|
|
+ put(OrdWarnPlanInfoTable.R_INFO.VERSION, planDetail.getVersion());
|
|
|
+ }}, null, "") <= 0){
|
|
|
+ step = "Plan is changed,do analysis next time";
|
|
|
+ code = ResponseCode.RESULT_BAD;
|
|
|
+ }
|
|
|
+
|
|
|
+ final long curUTCTm = TimeTool.getCurMsUTC();
|
|
|
+ final int preDayInYear = TimeTool.getYearIndex(curUTCTm-TimeTool.MS_ONE_DAY);//日分析时,分析前一日所在的年份
|
|
|
+ final int preDayInMonth = TimeTool.getMonthIndex(curUTCTm-TimeTool.MS_ONE_DAY);//日分析时,分析前一日所在的月份
|
|
|
+
|
|
|
+ long queryBeginUTC = 0L, conditionMinUTC = 0L;
|
|
|
+ long queryEndUTC = TimeTool.getTodayBeginUTC();
|
|
|
+ OrdWarnPlanTempStep thisStepTempRes = new OrdWarnPlanTempStep(planDetail);
|
|
|
+ do {
|
|
|
+ int findStartRange = -1;
|
|
|
+ for (int i=rules.size()-1;i>=0;i--){
|
|
|
+ if (preDayInMonth >= rules.get(i).getStart() && preDayInMonth <= rules.get(i).getEnd()){
|
|
|
+ findStartRange = rules.get(i).getStart();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (findStartRange < 0){
|
|
|
+ step = "Not in time range,do analysis next time";
|
|
|
+ code = ResponseCode.RESULT_BAD;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ findStartRange = findStartRange-1;
|
|
|
+ for (int i=rules.size()-1;i>=0;i--){
|
|
|
+ if (findStartRange <= 0)
|
|
|
+ break;
|
|
|
+ if (findStartRange == rules.get(i).getEnd())
|
|
|
+ findStartRange = rules.get(i).getStart()-1;
|
|
|
+ }
|
|
|
+
|
|
|
+ queryBeginUTC = TimeTool.convertDateStr2BeginUTC(String.format("%d-%2d-01 00:00:00", preDayInYear, findStartRange+1));
|
|
|
+ conditionMinUTC = queryBeginUTC;
|
|
|
+ long before3Day = queryEndUTC-TimeTool.MS_ONE_DAY*3;//最多只往前分析3天
|
|
|
+ if (before3Day > queryBeginUTC)
|
|
|
+ queryBeginUTC = before3Day;
|
|
|
+
|
|
|
+ if (thisStepTempRes.getLastCompareSampleTime() <= 0L
|
|
|
+ || thisStepTempRes.getLastCompareSampleTime() < queryBeginUTC) {//从未分析过则重新计数)
|
|
|
+ thisStepTempRes.resetData();
|
|
|
+ }else if (thisStepTempRes.getLastCompareSampleTime() >= queryBeginUTC) {
|
|
|
+ queryBeginUTC = thisStepTempRes.getLastCompareSampleTime() + TimeTool.MS_ONE_DAY;
|
|
|
+ }
|
|
|
+ if (queryBeginUTC >= queryEndUTC){
|
|
|
+ step = "Time is invalid,do analysis next time";
|
|
|
+ code = ResponseCode.RESULT_BAD;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ thisStepTempRes.setDoForTodayBefore(true);
|
|
|
+ thisStepTempRes.setQueryBeginUTC(queryBeginUTC);
|
|
|
+ thisStepTempRes.setQueryEndUTC(queryEndUTC);
|
|
|
+ thisStepTempRes.setConditionMinUTC(conditionMinUTC);
|
|
|
+
|
|
|
+ if (!StringUtils.isEmpty(planDetail.getLastEventId())){
|
|
|
+ //向数据库中快速查询事件最近处理阶段action的值
|
|
|
+ //并赋值给thisTempStep
|
|
|
+ }
|
|
|
+
|
|
|
+ return analysisDataByDay(planDetail, rules, thisStepTempRes);
|
|
|
+ }while (false);
|
|
|
+ return code;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static ResponseCode analysisDataByDay(OrdWarnPlanDetail planDetail, List<OrdWarnPlanRules> rules, OrdWarnPlanTempStep thisTempStep){
|
|
|
+ ResponseCode code = ResponseCode.RESULT_NORMAL;
|
|
|
+ String step = "Start to deep analysis";
|
|
|
+ long curTime = TimeTool.getCurMsUTC();
|
|
|
+ final String zoneId = rules.get(0).getObjId();
|
|
|
+ List<DateKeyValue> zoneStatsData = null;//要求数据按date升序
|
|
|
+ Map<String, Long> eventId2NewEndUTC = new HashMap<>();//需要更新预警事件的样本截止时间
|
|
|
+
|
|
|
+ do {
|
|
|
+ String[] storeTagAndBackTag = rules.get(0).getConditions().get(0).getFormat().split("@");
|
|
|
+ if (storeTagAndBackTag == null || storeTagAndBackTag.length < 2){
|
|
|
+ step = String.format("Format param valid in rules");
|
|
|
+ code = ResponseCode.RESULT_BAD;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ //数据库获取数据
|
|
|
+
|
|
|
+ if (zoneStatsData == null){
|
|
|
+ step = String.format("Get zone stats data failed");
|
|
|
+ code = ResponseCode.RESULT_BAD;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (CommTool.listSize(zoneStatsData) <= 0){//数据条目缺失可认为,还在等待录入则跳过
|
|
|
+ step = String.format("Get zone stats data empty");
|
|
|
+ code = ResponseCode.RESULT_BAD;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (DateKeyValue sampleItem:zoneStatsData){
|
|
|
+ long sampleRecordTm = TimeTool.convertDateStr2UTC(sampleItem.getDate());
|
|
|
+ if (sampleRecordTm <= 0L)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ boolean matched = false;
|
|
|
+ OrdWarnPlanRules findRule = null;
|
|
|
+ int sampleTmInMonth = TimeTool.getMonthIndex(sampleRecordTm);
|
|
|
+ for (OrdWarnPlanRules ruleItem:rules){
|
|
|
+ if (sampleTmInMonth <= ruleItem.getEnd() && sampleTmInMonth >= ruleItem.getStart()){
|
|
|
+ findRule = ruleItem;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (findRule == null)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ for (OrdWarnRuleCondition condition:findRule.getConditions()){
|
|
|
+ String originValue = "";
|
|
|
+ String backTag = storeTagAndBackTag[1];
|
|
|
+ if (backTag.equals(sampleItem.getKey()))
|
|
|
+ originValue = sampleItem.getValue();
|
|
|
+
|
|
|
+ int pkRes = CommToolHandler.matchedToRuleItem(originValue, condition);
|
|
|
+ if (pkRes == -1){
|
|
|
+ step = String.format("Compare value exception error");
|
|
|
+ code = ResponseCode.RESULT_BAD;
|
|
|
+ break;
|
|
|
+ }else {
|
|
|
+ matched = matched || (pkRes==1?true:false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (code != ResponseCode.RESULT_NORMAL)
|
|
|
+ break;
|
|
|
+
|
|
|
+ if (!matched){//本次没有匹配成功
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
+ thisTempStep.setLastCompareSampleResult(0);
|
|
|
+ thisTempStep.setFirstMatchSampleTime(0L);
|
|
|
+ thisTempStep.setLastEventId("");
|
|
|
+ thisTempStep.setLastEventTime(0L);
|
|
|
+ continue;
|
|
|
+ }//本次匹配成功进入下一步
|
|
|
+
|
|
|
+ long triggerEventPeriodSwitch = planDetail.getFrequency()*planDetail.getThreshold();//触发预警事件的最小时长(单位:天)
|
|
|
+ if (thisTempStep.getLastCompareSampleResult() <= 0){//上一次没有匹配成功
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
+ thisTempStep.setLastCompareSampleResult(1);
|
|
|
+ thisTempStep.setFirstMatchSampleTime(sampleRecordTm);
|
|
|
+ if (triggerEventPeriodSwitch <= 1){//触发事件
|
|
|
+ thisTempStep.setLastEventId("新事件ID");
|
|
|
+ thisTempStep.setLastEventTime(curTime);
|
|
|
+ thisTempStep.setLastEventAction(1);
|
|
|
+ }
|
|
|
+ continue;
|
|
|
+ }//上一次匹配成功了进入下一步
|
|
|
+
|
|
|
+ long diffMatch = (sampleRecordTm-thisTempStep.getLastCompareSampleTime())/TimeTool.MS_ONE_DAY;//两个最近匹配样本之间的采集时间差(单位:天)
|
|
|
+ if (diffMatch > triggerEventPeriodSwitch){//两个最近匹配样本间缺失的数据太多、或跨了天、或跨了时段,可认为重新计数
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
+ thisTempStep.setLastCompareSampleResult(1);
|
|
|
+ thisTempStep.setFirstMatchSampleTime(sampleRecordTm);
|
|
|
+ if (triggerEventPeriodSwitch <= 1){//触发事件
|
|
|
+ thisTempStep.setLastEventId("新事件ID");
|
|
|
+ thisTempStep.setLastEventTime(curTime);
|
|
|
+ thisTempStep.setLastEventAction(1);
|
|
|
+ }else {
|
|
|
+ thisTempStep.setLastEventId("");
|
|
|
+ thisTempStep.setLastEventTime(0L);
|
|
|
+ }
|
|
|
+ continue;
|
|
|
+ }//两个最近匹配样本间隔很近,可认为是持续匹配,则进入下一步
|
|
|
+
|
|
|
+ long matchLen = (thisTempStep.getFirstMatchSampleTime()<=0)?0:((sampleRecordTm-thisTempStep.getFirstMatchSampleTime())/TimeTool.MS_ONE_DAY);//样本匹配的持续时长(单位:天)
|
|
|
+ if (StringUtils.isEmpty(thisTempStep.getLastEventId())){//之前无预警事件
|
|
|
+ if (matchLen < triggerEventPeriodSwitch){//还得持续等待,达不到触发事件的累计时长
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
+ thisTempStep.setLastCompareSampleResult(1);
|
|
|
+ if (thisTempStep.getFirstMatchSampleTime() <= 0){
|
|
|
+ thisTempStep.setFirstMatchSampleTime(sampleRecordTm);
|
|
|
+ if (triggerEventPeriodSwitch <= 1){//补充触发事件
|
|
|
+ thisTempStep.setLastEventId("新事件ID");
|
|
|
+ thisTempStep.setLastEventTime(curTime);
|
|
|
+ thisTempStep.setLastEventAction(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else {//触发一个新的事件
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
+ thisTempStep.setLastCompareSampleResult(1);
|
|
|
+ thisTempStep.setLastEventId("新事件ID");
|
|
|
+ thisTempStep.setLastEventTime(curTime);
|
|
|
+ thisTempStep.setLastEventAction(1);
|
|
|
+ //[!!!]do not change the FirstMatchSampleTime[!!!]
|
|
|
+ }
|
|
|
+ }else {//之前有预警事件
|
|
|
+ if (planDetail.getMergeToEvent() == 0 || thisTempStep.getLastEventAction() >= 2){//之前的预警事件已处理,则可认为进行重新计数
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
+ thisTempStep.setLastCompareSampleResult(1);
|
|
|
+ thisTempStep.setFirstMatchSampleTime(sampleRecordTm);
|
|
|
+ if (triggerEventPeriodSwitch <= 1){//触发事件
|
|
|
+ thisTempStep.setLastEventId("新事件ID");
|
|
|
+ thisTempStep.setLastEventTime(curTime);
|
|
|
+ thisTempStep.setLastEventAction(1);
|
|
|
+ }else {
|
|
|
+ thisTempStep.setLastEventId("");
|
|
|
+ thisTempStep.setLastEventTime(0L);
|
|
|
+ }
|
|
|
+ }else {//之前的预警事件未处理,则更新预警事件的样本截止时刻
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
+ thisTempStep.setLastCompareSampleResult(1);
|
|
|
+ eventId2NewEndUTC.put(thisTempStep.getLastEventId(), sampleRecordTm);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }while (false);
|
|
|
+ return code;
|
|
|
+ }
|
|
|
}
|