import com.alibaba.fastjson.JSON;
import com.flinkRisk.cache.GroupCache;
import com.flinkRisk.config.FlinkConfig;
import com.flinkRisk.constant.GeneralRuleType;
import com.flinkRisk.handler.impl.speedLimit.LimitSpeedData;
import com.flinkRisk.manager.HandlerManager;
import com.flinkRisk.model.*;
import com.flinkRisk.rule.*;
import com.flinkRisk.sink.mysql.MysqlOutPutDataDispatcher;
import com.flinkRisk.sink.redis.RedisOperationHandler;
import com.flinkRisk.sink.rocketmq.RocketMqOutPutDataDispatcher;
import com.flinkRisk.utils.HttpAsyncUtil;
import com.flinkRisk.utils.IdGenUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.flink.api.common.state.*;
import org.apache.flink.api.common.time.Time;
import org.apache.flink.api.common.typeinfo.Types;
import org.apache.flink.api.java.utils.ParameterTool;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.streaming.api.functions.co.KeyedBroadcastProcessFunction;
import org.apache.flink.util.Collector;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* 自定义BroadcastProcessFunction
* 当事件流中的车辆ID在规则配置中出现时,获取规则处理数据
* Tuple4<String, String, String, Integer>: 第一个流(事件流)的数据类型
* HashMap<String, Tuple2<String, Integer>>: 第二个流(配置流)的数据类型
* Tuple6<String, String, String, Integer,String, Integer>: 返回的数据类型
*/
@Slf4j
public class BaseBroadcastProcessFunction extends KeyedBroadcastProcessFunction<Long, VehiclePosInfo, BaseRule, AlarmEvent> {
/**
* 上一次车辆状态
*/
private transient ValueState<VehicleState> lastVehicleState;
/**
* 车辆的报警状态:key:报警英文 value:报警事件
*/
private transient MapState<String, AlarmEvent> alarmState;
/**
* 车辆规则
*/
private Map<Long, Set<BaseRule>> vehicleRule = new ConcurrentHashMap<>();
/**
* 车组规则
*/
private Map<Long, Set<BaseRule>> groupRule = new ConcurrentHashMap<Long, Set<BaseRule>>();
/**
* 车辆规则
*/
private Map<Long, Set<BaseRule>> vehicleRuleTemp =null;
/**
* 车组规则
*/
private Map<Long, Set<BaseRule>> groupRuleTemp = null;
/**
* key:行政编号 value:行政区域经纬度
*/
public static Map<String, List<List<PointInfo>>> areaCodePointsMap=new ConcurrentHashMap<>();
/**
* 放道路分段限速信息 key:车牌 value:调用地图接口获取的道路限速信息
*/
private final Map<Long, LimitSpeedData> limitSpeedDataMap=new ConcurrentHashMap<>();
/**
* 第三方监管疲劳驾驶规则
*/
private ThirdPartyFatigueRule thirdPartyFatigueRule;
/**
* 第三方监管超速规则
*/
private ThirdPartyOverSpeedRule thirdPartyOverSpeedRule;
/**
* 第三方监管夜间禁行规则
*/
private ThirdPartyNotTrafficAtNightRule notTrafficAtNightRule;
/**
* 第三方平台长时间不定报警规则
*/
private ThirdPartyLongTimeNoPosRule thirdPartyLongTimeNoPosRule;
/**
* 第三方平台离线位移
*
*/
private ThirdPartyOfflineDisplacementRule thirdPartyOfflineDisplacementRule ;
/**
* 第三那方推送报警等级规则
*/
private ThirdPartyAlarmPushRule thirdPartyAlarmPushRule = new ThirdPartyAlarmPushRule();
/**
* 粤标普通规则
*/
public static Map<String,GeneralRule> cacheGeneralRuleMap = null;
/**
* 存报警等级配置的数据,从这张表上获取alarm_level_conf
*/
public static Map<String, Integer> alarmLevelMap=new ConcurrentHashMap<>();
@Override
public void open(Configuration conf) {
//初始化
ParameterTool parameterTool = (ParameterTool) getRuntimeContext().getExecutionConfig().getGlobalJobParameters();
//线上模式时,算子的配置不共享,需要重新获取配置
FlinkConfig.init(parameterTool);
FlinkConfig.initRule(parameterTool, vehicleRule, groupRule);
// 第三方规则
FlinkConfig.initThirdPartyRule(true, parameterTool, null, thirdPartyOverSpeedRule, null, null,null, null, null);
//http异步请求工具初始化
HttpAsyncUtil.init();
//初始化mysql数据处理
MysqlOutPutDataDispatcher.init(parameterTool);
//初始化mq数据处理
RocketMqOutPutDataDispatcher.init(parameterTool);
//redis操作
RedisOperationHandler.init(parameterTool);
long indexTask= getRuntimeContext().getIndexOfThisSubtask()+1L;
if(indexTask<30){
IdGenUtil.init(3L,getRuntimeContext().getIndexOfThisSubtask()+1L);
}
if(indexTask>=30&&indexTask<60){
IdGenUtil.init(11L,indexTask-30);
}
if(indexTask>=60&&indexTask<90){
IdGenUtil.init(12L,indexTask-60);
}
// 上次车辆状态
StateTtlConfig ttlConfig = StateTtlConfig
//超过15天没有数据清除状态
.newBuilder(Time.days(30))
.setUpdateType(StateTtlConfig.UpdateType.OnCreateAndWrite)
.setStateVisibility(StateTtlConfig.StateVisibility.NeverReturnExpired)
.build();
ValueStateDescriptor<VehicleState> lastAction = new ValueStateDescriptor<>("lastVehicleState", Types.POJO(VehicleState.class));
lastAction.enableTimeToLive(ttlConfig);
lastVehicleState = getRuntimeContext().getState(lastAction);
//车辆当前报警状态
StateTtlConfig ttlAlarmState = StateTtlConfig
//超过15天没有数据清除状态
.newBuilder(Time.days(30))
.setUpdateType(StateTtlConfig.UpdateType.OnCreateAndWrite)
.setStateVisibility(StateTtlConfig.StateVisibility.NeverReturnExpired)
.build();
MapStateDescriptor<String, AlarmEvent> mapStateDescriptor = new MapStateDescriptor<>("alarmState", Types.STRING, Types.POJO(AlarmEvent.class));
mapStateDescriptor.enableTimeToLive(ttlAlarmState);
alarmState = getRuntimeContext().getMapState(mapStateDescriptor);
}
@Override
public void close() throws Exception {
super.close();
HttpAsyncUtil.close();
MysqlOutPutDataDispatcher.close();
RocketMqOutPutDataDispatcher.close();
RedisOperationHandler.close();
// 将疲劳连续三个点超过阈值的标志清掉
lastVehicleState.value().setFatigueSpeedSign(0);
}
/**
* 读取状态,并基于状态,处理事件流中的数据
* 在这里,从上下文中获取状态,基于获取的状态,对事件流中的数据进行处理
*
* @param posInfo 事件流中的数据
* @param ctx 上下文
* @param out 输出零条或多条数据
* @throws Exception
*/
@Override
public void processElement(VehiclePosInfo posInfo, ReadOnlyContext ctx, Collector<AlarmEvent> out) throws Exception {
Set<BaseRule> vehicleRules = vehicleRule.get(posInfo.getVehicleId());
Set<BaseRule> groupRules = groupRule.get((long) posInfo.getGroupId());
RuleParam ruleParam = getVehicleRuleParam(vehicleRules, groupRules);
ruleParam.setThirdPartyFatigueRule(thirdPartyFatigueRule);
ruleParam.setThirdPartyOverSpeedRule(thirdPartyOverSpeedRule);
ruleParam.setNotTrafficAtNightRule(notTrafficAtNightRule);
ruleParam.setThirdPartyLongTimeNoPosRule(thirdPartyLongTimeNoPosRule);
ruleParam.setThirdPartyOfflineDisplacementRule(thirdPartyOfflineDisplacementRule);
ruleParam.setThirdPartyAlarmPushRule(thirdPartyAlarmPushRule);
HandlerManager.handler(posInfo, ruleParam, ctx, lastVehicleState, alarmState, out, limitSpeedDataMap);
}
/**
* 车辆,车组规则合并
*
* @param vehicleRules
* @param groupRules
* @return
*/
private RuleParam getVehicleRuleParam(Set<BaseRule> vehicleRules, Set<BaseRule> groupRules) {
RuleParam param = new RuleParam();
//车辆规则优先于车组规则
if (groupRules != null && groupRules.size() > 0) {
for (BaseRule rule : groupRules) {
addRule(rule, param);
}
}
if (vehicleRules != null && vehicleRules.size() > 0) {
for (BaseRule rule : vehicleRules) {
addRule(rule, param);
}
}
return param;
}
private void addRule(BaseRule rule, RuleParam param) {
if (rule.getRuleTheme() == 1) {
switch (rule.getRuleType()) {
case 1:
param.getGeneralRuleMap().put(GeneralRuleType.OFFLINE_RULE, (GeneralRule) rule);
break;
case 2:
param.getGeneralRuleMap().put(GeneralRuleType.LONG_TIME_NO_POS_RULE, (GeneralRule) rule);
break;
case 3:
param.getGeneralRuleMap().put(GeneralRuleType.NO_TRAFFIC_AT_NIGHT_RULE, (GeneralRule) rule);
break;
case 4:
param.getGeneralRuleMap().put(GeneralRuleType.TEMPERATURE_ALARM_RULE, (GeneralRule) rule);
break;
case 6:
param.getGeneralRuleMap().put(GeneralRuleType.NO_LEVEL_SETTING_ALARM_RULE, (GeneralRule) rule);
break;
case 7:
param.getGeneralRuleMap().put(GeneralRuleType.ALARM_AUTO_HANDLE_RULE, (GeneralRule) rule);
break;
case 8:
param.getGeneralRuleMap().put(GeneralRuleType.OVER_FLOW_RULE, (GeneralRule) rule);
break;
case 11:
param.getGeneralRuleMap().put(GeneralRuleType.ABNORMAL_STOP_RULE, (GeneralRule) rule);
break;
case 12:
param.getGeneralRuleMap().put(GeneralRuleType.OFFLINE_DISPLACEMENT_RULE, (GeneralRule) rule);
break;
case 15:
param.getGeneralRuleMap().put(GeneralRuleType.FATIGUE_RULE, (GeneralRule) rule);
break;
case 19:
param.getGeneralRuleMap().put(GeneralRuleType.OIL_PRE_FULL_RULE, (GeneralRule) rule);
break;
case 20:
param.getGeneralRuleMap().put(GeneralRuleType.REVERSAL_RULE, (GeneralRule) rule);
break;
case 25:
param.getGeneralRuleMap().put(GeneralRuleType.OVER_SPEED_PLATFORM, (GeneralRule) rule);
break;
case 22:
param.getGeneralRuleMap().put(GeneralRuleType.IS_START_RISK_RULE, (GeneralRule) rule);
break;
default:
break;
}
}
if (rule.getRuleTheme() == 2) {
param.getPathRules().add((PathRule)rule);
}
if (rule.getRuleTheme() == 3) {
param.getAreaRules().add((AreaRule)rule);
}
if (rule.getRuleTheme() == 5) {
param.getRoadRules().add((RoadSpeedLimitRule)rule);
}
if (rule.getRuleTheme() == 6) {
param.setSedimentCarWayBillRule((SedimentCarWayBillRule)rule);
}
}
/**
* 处理广播流中的每一条数据,并更新状态
*
* @param rule 广播流中的数据
* @param ctx 上下文
* @param out 输出零条或多条数据
* @throws Exception
*/
@Override
public void processBroadcastElement(BaseRule rule, Context ctx, Collector<AlarmEvent> out) {
if(rule==null){
return;
}
//开始更新
if(rule.getRuleTheme()==555){
vehicleRuleTemp=new ConcurrentHashMap<>();
groupRuleTemp=new ConcurrentHashMap<>();
cacheGeneralRuleMap = new ConcurrentHashMap<>();
}
//结束更新
if(rule.getRuleTheme()==666){
vehicleRule=mapCopy(vehicleRuleTemp);
groupRule=mapCopy(groupRuleTemp);
FlinkConfig.generalRuleMap=mapCopy(cacheGeneralRuleMap);
vehicleRuleTemp.clear();
groupRuleTemp.clear();
cacheGeneralRuleMap.clear();
}
FlinkConfig.addRuleMap(rule, vehicleRuleTemp, groupRuleTemp);
if(rule.getRuleTheme()==333){
AreaCode areaCode = (AreaCode) rule;
areaCodePointsMap.put(areaCode.getAreaCode(),areaCode.getPointInfo());
}
//更新车组缓存
if (rule.getRuleTheme() == 888) {
VehicleGroup group = (VehicleGroup) rule;
GroupCache.addGroupMap(group.getGroupId(), group);
if (group.getUpdateFlag() == 1) {
GroupCache.buildCompanyGroupMap();
}
}
if (rule.getRuleTheme()!=null&&rule.getRuleTheme() == 301) {
thirdPartyOverSpeedRule = (ThirdPartyOverSpeedRule) rule;
log.info("规则thirdPartyOverSpeedRule:{}", JSON.toJSONString(thirdPartyOverSpeedRule));
}
if (rule.getRuleTheme()!=null&&rule.getRuleTheme() == 302) {
thirdPartyFatigueRule = (ThirdPartyFatigueRule) rule;
log.info("规则thirdPartyFatigueRule:{}",JSON.toJSONString(thirdPartyFatigueRule));
}
if (rule.getRuleTheme()!=null&&rule.getRuleTheme() == 303) {
notTrafficAtNightRule = (ThirdPartyNotTrafficAtNightRule) rule;
log.info("规则notTrafficAtNightRule:{}",JSON.toJSONString(notTrafficAtNightRule));
}
if (rule.getRuleTheme()!=null&&rule.getRuleTheme() == 305){
thirdPartyLongTimeNoPosRule = (ThirdPartyLongTimeNoPosRule) rule;
log.info("规则thirdParthLongTimeNoPosRule:{}",JSON.toJSONString(thirdPartyLongTimeNoPosRule));
}
if (rule.getRuleTheme()!=null&&rule.getRuleTheme() == 306){
thirdPartyOfflineDisplacementRule = (ThirdPartyOfflineDisplacementRule) rule;
log.info("规则thirdPartyOfflineDisplacementRule:{}",JSON.toJSONString(thirdPartyOfflineDisplacementRule));
}
if (rule.getRuleTheme()!=null&&rule.getRuleTheme() == 307){
thirdPartyAlarmPushRule = (ThirdPartyAlarmPushRule) rule;
log.info("规则thirdPartyAlarmPushRule:{}",JSON.toJSONString(thirdPartyAlarmPushRule));
}
if (rule.getRuleTheme()!=null && rule.getRuleTheme()==308){
AlarmLevel alarmLevel = (AlarmLevel) rule;
alarmLevelMap.put(alarmLevel.getAlarmType(),alarmLevel.getAlarmLevel());
}
if (rule.getRuleTheme()==111){
GeneralRule generalRule = (GeneralRule) rule;
if (rule.getParam()!=null){
// 超速规则
if (generalRule.getRuleType()==26){
OverSpeedRule overSpeedRule = JSON.parseObject(generalRule.getParam(), OverSpeedRule.class);
String vehicleShapes = overSpeedRule.getVehicleShape();
if (vehicleShapes !=null){
String[] split = vehicleShapes.split(",");
// 车辆类型加 规则类型
for (String vehicleShape : split) {
cacheGeneralRuleMap.put(vehicleShape+FlinkConfig.ovType,generalRule);
}
}
}
// 夜间禁行规则
if (generalRule.getRuleType()==3){
String params = generalRule.getParam();
String[] split = params.split(";");
if (split.length==5) {
String vehicleShapes = split[1];
if (vehicleShapes !=null) {
String[] split1 = vehicleShapes.split(",");
for (String vehicleShape : split1) {
cacheGeneralRuleMap.put(vehicleShape+FlinkConfig.niType,generalRule);
}
}
}
}
// 疲劳报警规则
if (generalRule.getRuleType()==15){
FatigueDrivingRuleParam fatigueDrivingRuleParam = JSON.parseObject(generalRule.getParam(), FatigueDrivingRuleParam.class);
String vehicleShapes = fatigueDrivingRuleParam.getVehicleShape();
if (vehicleShapes!=null) {
String[] split = vehicleShapes.split(",");
for (String vehicleShape : split) {
cacheGeneralRuleMap.put(vehicleShape+FlinkConfig.faType,generalRule);
}
}
}
// 是否启用风险规则
if (generalRule.getRuleType()==22){
RiskRule riskRule = JSON.parseObject(rule.getParam(),RiskRule.class);
if (riskRule !=null){
cacheGeneralRuleMap.put(FlinkConfig.isStarRisk, generalRule);
}
}
}
}
}
/**
* 复制map对象
* @explain 将paramsMap中的键值对全部拷贝到resultMap中;
* paramsMap中的内容不会影响到resultMap(深拷贝)
* @param paramsMap
* 被拷贝对象
* 拷贝后的对象
*/
public static Map mapCopy(Map paramsMap) {
Map resultMap = new HashMap();
Iterator it = paramsMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
Object key = entry.getKey();
resultMap.put(key, paramsMap.get(key) != null ? paramsMap.get(key) : "");
}
return resultMap;
}
}
BaseBroadcastProcessFunction自定义的
于 2022-09-30 12:09:35 首次发布