版本2.0更新

This commit is contained in:
yunian
2022-06-23 16:27:20 +08:00
parent 5a9e9a03f5
commit db6b7991af
899 changed files with 72581 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ddp-enginex</artifactId>
<groupId>com.fibo.ddp</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ddp-enginex-dataflow-engine</artifactId>
</project>

View File

@@ -0,0 +1,82 @@
package com.fibo.ddp.enginex.dataflow.controller;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.common.enums.ErrorCodeEnum;
import com.fibo.ddp.common.model.common.requestParam.QueryListParam;
import com.fibo.ddp.common.model.common.requestParam.UpdateStatusParam;
import com.fibo.ddp.common.model.enginex.risk.Engine;
import com.fibo.ddp.common.service.enginex.dataflow.EngineServiceV3;
import com.fibo.ddp.common.service.monitor.logger.ArchivesLog;
import com.fibo.ddp.common.utils.constant.OpTypeConst;
import com.fibo.ddp.common.utils.util.SnowFlakUtil;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* (Engine)表控制层
*
* @author jgp
* @since 2021-12-22 13:28:09
*/
@RestController
@RequestMapping("/v3/engine")
@Slf4j
public class DataFlowEngineController {
/**
* 服务对象
*/
@Resource
private EngineServiceV3 engineServiceV3;
@PostMapping(value = "/getEngineList")
public ResponseEntityDto getList(@RequestBody QueryListParam<Engine> param) {
PageInfo pageInfo = engineServiceV3.queryList(param);
return ResponseEntityBuilder.buildNormalResponse(pageInfo);
}
/**
* 生成一个雪花id作为引擎的code
*
* @return
*/
@PostMapping(value = "/getEngineCode")
public ResponseEntityDto getEngineCode() {
return ResponseEntityBuilder.buildNormalResponse(SnowFlakUtil.snowflakeIdStr());
}
@PostMapping(value = "/addEngine")
@ArchivesLog(operationType = OpTypeConst.SAVE_ENGINE)
@ResponseBody
public ResponseEntityDto addEngine(@RequestBody Engine engine) {
Engine result = engineServiceV3.addEngine(engine);
if (result==null){
return ResponseEntityBuilder.buildErrorResponse(ErrorCodeEnum.PARAMS_EXCEPTION.getCode(),"新增引擎失败");
}
return ResponseEntityBuilder.buildNormalResponse(result);
}
@PostMapping(value = "/updateEngine")
@ArchivesLog(operationType = OpTypeConst.UPDATE_ENGINE)
@ResponseBody
public ResponseEntityDto updateEngine(@RequestBody Engine engine) {
Engine result = engineServiceV3.updateEngine(engine);
if (result==null){
return ResponseEntityBuilder.buildErrorResponse(ErrorCodeEnum.PARAMS_EXCEPTION.getCode(),"修改引擎失败");
}
return ResponseEntityBuilder.buildNormalResponse(result);
}
@PostMapping(value = "/updateStatus")
public ResponseEntityDto updateStatus(@RequestBody UpdateStatusParam param) {
UpdateStatusParam.checkParam(param);
boolean result = engineServiceV3.updateStatus(param.getList(), param.getStatus());
if (!result) {
return ResponseEntityBuilder.buildErrorResponse(ErrorCodeEnum.PARAMS_EXCEPTION.getCode(), "修改状态失败");
}
return ResponseEntityBuilder.buildNormalResponse(result);
}
}

View File

@@ -0,0 +1,35 @@
package com.fibo.ddp.enginex.dataflow.controller;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.common.enums.ErrorCodeEnum;
import com.fibo.ddp.common.model.enginex.dataflow.EngineVersionContent;
import com.fibo.ddp.common.model.enginex.dataflow.vo.EngineVersionContentVo;
import com.fibo.ddp.common.service.enginex.dataflow.EngineVersionContentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/v3/engineVersionContent")
public class DataFlowEngineVersionContentController {
@Autowired
private EngineVersionContentService engineVersionContentService;
@PostMapping("/getEngineVersionContentInfo")
public ResponseEntityDto getEngineVersionContentInfo(@RequestBody EngineVersionContentVo param ){
EngineVersionContent result = engineVersionContentService.queryById(param.getEngineVersionId());
return ResponseEntityBuilder.buildNormalResponse(result);
}
@PostMapping("/updateEngineVersionContentInfo")
public ResponseEntityDto updateEngineVersionContentInfo(@RequestBody EngineVersionContentVo param){
boolean result = engineVersionContentService.updateVersionContent(param);
if (result){
return ResponseEntityBuilder.buildNormalResponse(result);
}
return ResponseEntityBuilder.buildErrorResponse(ErrorCodeEnum.PARAMS_EXCEPTION.getCode(),"修改引擎内容失败");
}
}

View File

@@ -0,0 +1,53 @@
package com.fibo.ddp.enginex.dataflow.controller;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.common.enums.ErrorCodeEnum;
import com.fibo.ddp.common.model.common.requestParam.QueryListParam;
import com.fibo.ddp.common.model.enginex.risk.EngineVersion;
import com.fibo.ddp.common.service.enginex.dataflow.EngineVersionServiceV3;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/v3/engineVersion")
@Slf4j
public class DataFlowEngineVersionController {
@Autowired
private EngineVersionServiceV3 engineVersionServiceV3;
@PostMapping("/getEngineVersionPage")
public ResponseEntityDto getEngineVersionPage(@RequestBody QueryListParam<EngineVersion> param){
PageInfo pageInfo = engineVersionServiceV3.queryList(param);
return ResponseEntityBuilder.buildNormalResponse(pageInfo);
}
@PostMapping("/getEngineVersionList")
public ResponseEntityDto getEngineVersionList(@RequestBody EngineVersion param){
List<EngineVersion> result = engineVersionServiceV3.queryByEngineId(param.getEngineId());
return ResponseEntityBuilder.buildNormalResponse(result);
}
@PostMapping("/addEngineVersion")
public ResponseEntityDto addEngineVersion(@RequestBody EngineVersion param){
boolean result = engineVersionServiceV3.addEngineVersion(param);
if (result){
return ResponseEntityBuilder.buildNormalResponse(result);
}
return ResponseEntityBuilder.buildErrorResponse(ErrorCodeEnum.PARAMS_EXCEPTION.getCode(),"新增版本失败");
}
@PostMapping("/copyEngineVersion")
public ResponseEntityDto copyEngineVersion(@RequestBody EngineVersion param){
boolean result = engineVersionServiceV3.copyEngineVersion(param.getVersionId());
if (result){
return ResponseEntityBuilder.buildNormalResponse(result);
}
return ResponseEntityBuilder.buildErrorResponse(ErrorCodeEnum.PARAMS_EXCEPTION.getCode(),"新增版本失败");
}
}

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ddp-enginex</artifactId>
<groupId>com.fibo.ddp</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ddp-enginex-marketing-engine</artifactId>
</project>

View File

@@ -0,0 +1,75 @@
package com.fibo.ddp.enginex.marketing.controller;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.common.enums.ErrorCodeEnum;
import com.fibo.ddp.common.model.common.requestParam.QueryListParam;
import com.fibo.ddp.common.model.common.requestParam.UpdateStatusParam;
import com.fibo.ddp.common.model.enginex.risk.Engine;
import com.fibo.ddp.common.service.enginex.dataflow.EngineServiceV3;
import com.fibo.ddp.common.service.monitor.logger.ArchivesLog;
import com.fibo.ddp.common.utils.constant.OpTypeConst;
import com.fibo.ddp.common.utils.util.SnowFlakUtil;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@RestController
@RequestMapping("/engine/marketing")
@Slf4j
public class MarketingEngineController {
@Resource
private EngineServiceV3 engineServiceV3;
@PostMapping(value = "/getEngineList")
public ResponseEntityDto getList(@RequestBody QueryListParam<Engine> param) {
PageInfo pageInfo = engineServiceV3.queryList(param);
return ResponseEntityBuilder.buildNormalResponse(pageInfo);
}
/**
* 生成一个雪花id作为引擎的code
*
* @return
*/
@PostMapping(value = "/getEngineCode")
public ResponseEntityDto getEngineCode() {
return ResponseEntityBuilder.buildNormalResponse(SnowFlakUtil.snowflakeIdStr());
}
@PostMapping(value = "/addEngine")
@ArchivesLog(operationType = OpTypeConst.SAVE_ENGINE)
@ResponseBody
public ResponseEntityDto addEngine(@RequestBody Engine engine) {
Engine result = engineServiceV3.addEngine(engine);
if (result == null) {
return ResponseEntityBuilder.buildErrorResponse(ErrorCodeEnum.PARAMS_EXCEPTION.getCode(), "新增引擎失败");
}
return ResponseEntityBuilder.buildNormalResponse(result);
}
@PostMapping(value = "/updateEngine")
@ArchivesLog(operationType = OpTypeConst.UPDATE_ENGINE)
@ResponseBody
public ResponseEntityDto updateEngine(@RequestBody Engine engine) {
Engine result = engineServiceV3.updateEngine(engine);
if (result == null) {
return ResponseEntityBuilder.buildErrorResponse(ErrorCodeEnum.PARAMS_EXCEPTION.getCode(), "修改引擎失败");
}
return ResponseEntityBuilder.buildNormalResponse(result);
}
@PostMapping(value = "/updateStatus")
public ResponseEntityDto updateStatus(@RequestBody UpdateStatusParam param) {
UpdateStatusParam.checkParam(param);
boolean result = engineServiceV3.updateStatus(param.getList(), param.getStatus());
if (!result) {
return ResponseEntityBuilder.buildErrorResponse(ErrorCodeEnum.PARAMS_EXCEPTION.getCode(), "修改状态失败");
}
return ResponseEntityBuilder.buildNormalResponse(result);
}
}

View File

@@ -0,0 +1,53 @@
package com.fibo.ddp.enginex.marketing.controller;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.enginex.marketing.entity.MarketingEngineResult;
import com.fibo.ddp.common.model.enginex.marketing.vo.MarketingDataResultReqVo;
import com.fibo.ddp.common.model.enginex.marketing.vo.MarketingDataResultRspVo;
import com.fibo.ddp.common.model.enginex.marketing.vo.MarketingListResultReqVo;
import com.fibo.ddp.common.service.enginex.marketing.MarketingEngineResultService;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* 营销引擎结果表(MarketingEngineResult)表控制层
*
* @author andy.wang
* @since 2022-01-07 18:13:24
*/
@RestController
@RequestMapping("/engineResult/marketing")
public class MarketingEngineResultController {
@Autowired
private MarketingEngineResultService marketingEngineResultService;
/**
* 获取营销引擎结果列表页
*
* @param param
* @return
*/
@RequestMapping(value = "queryListByPage", method = RequestMethod.POST)
public ResponseEntityDto<PageInfo<MarketingEngineResult>> queryListByPage(@RequestBody MarketingListResultReqVo param) {
PageInfo<MarketingEngineResult> pageInfo = marketingEngineResultService.getListByPage(param);
return ResponseEntityBuilder.buildNormalResponse(pageInfo);
}
/**
* 获取营销引擎数据详情
*
* @param param
* @return
*/
@RequestMapping(value = "queryEngineDataByDate", method = RequestMethod.POST)
public ResponseEntityDto<MarketingDataResultRspVo> queryEngineDataByDate(@RequestBody MarketingDataResultReqVo param) {
MarketingDataResultRspVo marketingDataResultRspVo = marketingEngineResultService.getEngineDataByDate(param);
return ResponseEntityBuilder.buildNormalResponse(marketingDataResultRspVo);
}
}

View File

@@ -0,0 +1,38 @@
package com.fibo.ddp.enginex.marketing.controller;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.common.enums.ErrorCodeEnum;
import com.fibo.ddp.common.model.enginex.dataflow.EngineVersionContent;
import com.fibo.ddp.common.model.enginex.dataflow.vo.EngineVersionContentVo;
import com.fibo.ddp.common.service.enginex.dataflow.EngineVersionContentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/engineVersionContent/marketing")
@Slf4j
public class MarketingEngineVersionContentController {
@Autowired
private EngineVersionContentService engineVersionContentService;
@PostMapping("/getEngineVersionContentInfo")
public ResponseEntityDto getEngineVersionContentInfo(@RequestBody EngineVersionContent param ){
EngineVersionContentVo result = engineVersionContentService.queryById(param.getEngineVersionId());
return ResponseEntityBuilder.buildNormalResponse(result);
}
@PostMapping("/updateEngineVersionContentInfo")
public ResponseEntityDto updateEngineVersionContentInfo(@RequestBody EngineVersionContentVo param){
boolean result = engineVersionContentService.updateVersionContent(param);
if (result){
return ResponseEntityBuilder.buildNormalResponse(result);
}
return ResponseEntityBuilder.buildErrorResponse(ErrorCodeEnum.PARAMS_EXCEPTION.getCode(),"修改引擎内容失败");
}
}

View File

@@ -0,0 +1,29 @@
package com.fibo.ddp.enginex.marketing.controller;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.enginex.risk.EngineVersion;
import com.fibo.ddp.common.service.enginex.dataflow.EngineVersionServiceV3;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/engineVersion/marketing")
@Slf4j
public class MarketingEngineVersionController {
@Autowired
private EngineVersionServiceV3 engineVersionServiceV3;
@PostMapping("/getEngineVersionList")
public ResponseEntityDto getEngineVersionList(@RequestBody EngineVersion param){
List<EngineVersion> result = engineVersionServiceV3.queryByEngineId(param.getEngineId());
return ResponseEntityBuilder.buildNormalResponse(result);
}
}

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ddp-enginex</artifactId>
<groupId>com.fibo.ddp</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ddp-enginex-personas-engine</artifactId>
</project>

View File

@@ -0,0 +1,84 @@
package com.fibo.ddp.enginex.persons.controller;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.common.enums.ErrorCodeEnum;
import com.fibo.ddp.common.model.common.requestParam.QueryListParam;
import com.fibo.ddp.common.model.common.requestParam.UpdateStatusParam;
import com.fibo.ddp.common.model.enginex.risk.Engine;
import com.fibo.ddp.common.service.enginex.dataflow.EngineServiceV3;
import com.fibo.ddp.common.service.monitor.logger.ArchivesLog;
import com.fibo.ddp.common.utils.constant.OpTypeConst;
import com.fibo.ddp.common.utils.util.SnowFlakUtil;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* (Engine)表控制层
*
* @author jgp
* @since 2021-12-22 13:28:09
*/
@RestController
@RequestMapping("/v3/engine/personas")
@Slf4j
public class PersonasEngineController {
/**
* 服务对象
*/
@Resource
private EngineServiceV3 engineServiceV3;
@PostMapping(value = "/getEngineList")
public ResponseEntityDto getList(@RequestBody QueryListParam<Engine> param) {
PageInfo pageInfo = engineServiceV3.queryList(param);
return ResponseEntityBuilder.buildNormalResponse(pageInfo);
}
/**
* 生成一个雪花id作为引擎的code
*
* @return
*/
@PostMapping(value = "/getEngineCode")
public ResponseEntityDto getEngineCode() {
return ResponseEntityBuilder.buildNormalResponse(SnowFlakUtil.snowflakeIdStr());
}
@PostMapping(value = "/addEngine")
@ArchivesLog(operationType = OpTypeConst.SAVE_ENGINE)
@ResponseBody
public ResponseEntityDto addEngine(@RequestBody Engine engine) {
Engine result = engineServiceV3.addEngine(engine);
if (result == null) {
return ResponseEntityBuilder.buildErrorResponse(ErrorCodeEnum.PARAMS_EXCEPTION.getCode(), "新增引擎失败");
}
return ResponseEntityBuilder.buildNormalResponse(result);
}
@PostMapping(value = "/updateEngine")
@ArchivesLog(operationType = OpTypeConst.UPDATE_ENGINE)
@ResponseBody
public ResponseEntityDto updateEngine(@RequestBody Engine engine) {
Engine result = engineServiceV3.updateEngine(engine);
if (result == null) {
return ResponseEntityBuilder.buildErrorResponse(ErrorCodeEnum.PARAMS_EXCEPTION.getCode(), "修改引擎失败");
}
return ResponseEntityBuilder.buildNormalResponse(result);
}
@PostMapping(value = "/updateStatus")
public ResponseEntityDto updateStatus(@RequestBody UpdateStatusParam param) {
UpdateStatusParam.checkParam(param);
boolean result = engineServiceV3.updateStatus(param.getList(), param.getStatus());
if (!result) {
return ResponseEntityBuilder.buildErrorResponse(ErrorCodeEnum.PARAMS_EXCEPTION.getCode(), "修改状态失败");
}
return ResponseEntityBuilder.buildNormalResponse(result);
}
}

View File

@@ -0,0 +1,47 @@
package com.fibo.ddp.enginex.persons.controller;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.common.requestParam.QueryListParam;
import com.fibo.ddp.common.model.enginex.personas.PersonasEngineResult;
import com.fibo.ddp.common.model.enginex.personas.PersonasEngineResultDetail;
import com.fibo.ddp.common.model.enginex.personas.vo.PersonasReport;
import com.fibo.ddp.common.model.enginex.personas.vo.PersonasReportParam;
import com.fibo.ddp.common.service.enginex.personas.PersonasEngineResultDetailService;
import com.fibo.ddp.common.service.enginex.personas.PersonasEngineResultService;
import com.fibo.ddp.common.utils.util.ResponseUtil;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/v3/engineResult/personas")
public class PersonasEngineResultController {
@Autowired
private PersonasEngineResultService personasEngineResultService;
@Autowired
private PersonasEngineResultDetailService personasEngineResultDetailService;
@PostMapping("/getResultList")
public ResponseEntityDto getResultList(QueryListParam<PersonasEngineResult> param){
PageInfo<PersonasEngineResult> resultPageInfo = personasEngineResultService.queryByEntity(param);
Map<String, Object> responseMap = ResponseUtil.getResponseMap(resultPageInfo);
return ResponseEntityBuilder.buildNormalResponse(responseMap);
}
@PostMapping("/getResultDetailList")
public ResponseEntityDto getResultDetailList(QueryListParam<PersonasEngineResultDetail> param){
PageInfo<PersonasEngineResultDetail> resultPageInfo = personasEngineResultDetailService.queryByEntity(param);
Map<String, Object> responseMap = ResponseUtil.getResponseMap(resultPageInfo);
return ResponseEntityBuilder.buildNormalResponse(responseMap);
}
@PostMapping("/getReportList")
public ResponseEntityDto getReportList(QueryListParam<PersonasReportParam> param){
Map map = personasEngineResultDetailService.queryReportList(param);
return ResponseEntityBuilder.buildNormalResponse(map);
}
}

View File

@@ -0,0 +1,35 @@
package com.fibo.ddp.enginex.persons.controller;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.common.enums.ErrorCodeEnum;
import com.fibo.ddp.common.model.enginex.dataflow.EngineVersionContent;
import com.fibo.ddp.common.model.enginex.dataflow.vo.EngineVersionContentVo;
import com.fibo.ddp.common.service.enginex.dataflow.EngineVersionContentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/v3/engineVersionContent/personas")
public class PersonasEngineVersionContentController {
@Autowired
private EngineVersionContentService engineVersionContentService;
@PostMapping("/getEngineVersionContentInfo")
public ResponseEntityDto getEngineVersionContentInfo(@RequestBody EngineVersionContent param ){
EngineVersionContent result = engineVersionContentService.queryById(param.getEngineVersionId());
return ResponseEntityBuilder.buildNormalResponse(result);
}
@PostMapping("/updateEngineVersionContentInfo")
public ResponseEntityDto updateEngineVersionContentInfo(@RequestBody EngineVersionContentVo param){
boolean result = engineVersionContentService.updateVersionContent(param);
if (result){
return ResponseEntityBuilder.buildNormalResponse(result);
}
return ResponseEntityBuilder.buildErrorResponse(ErrorCodeEnum.PARAMS_EXCEPTION.getCode(),"修改引擎内容失败");
}
}

View File

@@ -0,0 +1,53 @@
package com.fibo.ddp.enginex.persons.controller;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.common.enums.ErrorCodeEnum;
import com.fibo.ddp.common.model.common.requestParam.QueryListParam;
import com.fibo.ddp.common.model.enginex.risk.EngineVersion;
import com.fibo.ddp.common.service.enginex.dataflow.EngineVersionServiceV3;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/v3/engineVersion/personas")
@Slf4j
public class PersonasEngineVersionController {
@Autowired
private EngineVersionServiceV3 engineVersionServiceV3;
@PostMapping("/getEngineVersionPage")
public ResponseEntityDto getEngineVersionPage(@RequestBody QueryListParam<EngineVersion> param){
PageInfo pageInfo = engineVersionServiceV3.queryList(param);
return ResponseEntityBuilder.buildNormalResponse(pageInfo);
}
@PostMapping("/getEngineVersionList")
public ResponseEntityDto getEngineVersionList(@RequestBody EngineVersion param){
List<EngineVersion> result = engineVersionServiceV3.queryByEngineId(param.getEngineId());
return ResponseEntityBuilder.buildNormalResponse(result);
}
@PostMapping("/addEngineVersion")
public ResponseEntityDto addEngineVersion(@RequestBody EngineVersion param){
boolean result = engineVersionServiceV3.addEngineVersion(param);
if (result){
return ResponseEntityBuilder.buildNormalResponse(result);
}
return ResponseEntityBuilder.buildErrorResponse(ErrorCodeEnum.PARAMS_EXCEPTION.getCode(),"新增版本失败");
}
@PostMapping("/copyEngineVersion")
public ResponseEntityDto copyEngineVersion(@RequestBody EngineVersion param){
boolean result = engineVersionServiceV3.copyEngineVersion(param.getVersionId());
if (result){
return ResponseEntityBuilder.buildNormalResponse(result);
}
return ResponseEntityBuilder.buildErrorResponse(ErrorCodeEnum.PARAMS_EXCEPTION.getCode(),"新增版本失败");
}
}

31
ddp-enginex/pom.xml Normal file
View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ddp</artifactId>
<groupId>com.fibo.ddp</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ddp-enginex</artifactId>
<packaging>pom</packaging>
<modules>
<module>risk-engine</module>
<module>rule-engine</module>
<module>dataflow-engine</module>
<module>personas-engine</module>
<module>marketing-engine</module>
<module>runner-node</module>
</modules>
<dependencies>
<dependency>
<groupId>com.fibo.ddp</groupId>
<artifactId>ddp-common-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ddp-enginex</artifactId>
<groupId>com.fibo.ddp</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ddp-enginex-risk-engine</artifactId>
<dependencies>
<dependency>
<groupId>com.fibo.ddp</groupId>
<artifactId>ddp-enginex-runner-node</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,81 @@
package com.fibo.ddp.enginex.riskengine.controller;
import com.fibo.ddp.common.model.authx.system.SysUser;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.enginex.risk.Engine;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.model.enginex.risk.request.EngineListParam;
import com.fibo.ddp.common.service.common.SessionManager;
import com.fibo.ddp.common.service.enginex.risk.EngineNodeService;
import com.fibo.ddp.common.service.enginex.risk.EngineService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* 子引擎节点接口
*/
@RestController
@RequestMapping("childEngineNode")
public class ChildEngineNodeController {
@Autowired
private EngineService engineService;
@Autowired
private EngineNodeService engineNodeService;
/**
* @api {POST} /childEngineNode/getEngineList 7.81. 子引擎节点 获取引擎列表
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Integer} pageNo 页数
* @apiParam {Integer} pageSize 每页的条数
* @apiParam {Long} nodeId 节点id
* @apiParam {Long} engineId 引擎id
* @apiParam {String} [searchString] 搜索关键字
* @apiSuccess {String} status 状态: 1成功, 0失败
* @apiParamExample {json} 请求示例:
* {"pageNo":1,"pageSize":5,"nodeId":0,"engineId":220,"searchString":"信用卡"}
* @apiSuccessExample {json} 成功返回数据示例:
* {"status":"1","error":"00000000","msg":null,"data":{"pager":{"pageNum":1,"pageSize":5,"size":2,"startRow":1,"endRow":2,"total":2,"pages":1,"list":null,"prePage":0,"nextPage":0,"isFirstPage":true,"isLastPage":true,"hasPreviousPage":false,"hasNextPage":false,"navigatePages":8,"navigatepageNums":[1],"navigateFirstPage":1,"navigateLastPage":1,"lastPage":1,"firstPage":1},"engineList":[{"userId":220,"versionCode":"7eb07302-cbf3-4f6e-95b5-075e89b59f4c","name":"信用卡引擎2","description":"信用卡引擎2","status":1,"createDatetime":1610505340000,"updateDatetime":1610505340000,"creator":142,"userId":null,"organId":46,"searchString":null,"engineVersionList":null,"runState":0,"checked":false,"callbackType":1,"callbackUrl":null},{"userId":219,"versionCode":"5bc79716-8c62-4248-bf91-de07f654668a","name":"信用卡引擎1","description":"信用卡引擎1","status":1,"createDatetime":1610505333000,"updateDatetime":1610505333000,"creator":142,"userId":null,"organId":46,"searchString":null,"engineVersionList":null,"runState":0,"checked":false,"callbackType":1,"callbackUrl":null}]}}
*/
@RequestMapping(value = "getEngineList", method = RequestMethod.POST)
public ResponseEntityDto getEngineList(@RequestBody EngineListParam param) {
String searchString = param.getSearchString();
Long nodeId = param.getNodeId();
List<Integer> list = new ArrayList<Integer>();
SysUser user = SessionManager.getLoginAccount();
Long organId = user.getOrganId();
PageHelper.startPage(param.getPageNo(), param.getPageSize());
//查询对应的引擎
List<Engine> engineList = engineService.getEngineList(organId, searchString, list);
EngineNode engineNode = engineNodeService.findById(nodeId);
if (engineNode != null) {
for (Engine engine : engineList) {
if (engine.getId().toString().equals(engineNode.getNodeJson())) {
engine.setChecked(true);
break;
}
}
}
PageInfo<Engine> pageInfo = new PageInfo<Engine>(engineList);
pageInfo.setList(null);
HashMap<String, Object> resultMap = new HashMap();
resultMap.put("pager", pageInfo);
resultMap.put("engineList", engineList);
return ResponseEntityBuilder.buildNormalResponse(resultMap);
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,358 @@
package com.fibo.ddp.enginex.riskengine.controller;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.common.enums.ErrorCodeEnum;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.model.enginex.risk.EngineVersion;
import com.fibo.ddp.common.service.common.SessionManager;
import com.fibo.ddp.common.service.enginex.risk.EngineNodeService;
import com.fibo.ddp.common.service.enginex.risk.EngineVersionService;
import com.fibo.ddp.common.service.monitor.logger.ArchivesLog;
import com.fibo.ddp.common.utils.constant.OpTypeConst;
import com.fibo.ddp.common.utils.constant.enginex.EngineConst;
import com.fibo.ddp.common.utils.constant.enginex.EngineMsg;
import com.fibo.ddp.common.utils.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.*;
@Controller("EngineVersionControllerV2")
@RequestMapping("/v2/engineVersion")
@ResponseBody
public class EngineVersionController {
@Autowired
private EngineVersionService engineVersionService;
@Autowired
private EngineNodeService engineNodeService;
/**
* @api {POST} /v2/engineVersion/add/{engineId}/{version} 7.56. 新增版本
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Number} engineId 路径参数engineId
* @apiParam {Number} version 路径参数version
* @apiSuccess {String} status 状态1成功0失败
* @apiParamExample {json} 请求示例:
* {无请求体}
* @apiSuccessExample {json} 成功返回数据示例:
* {待完善}
*/
@RequestMapping(value = "/add/{engineId}/{version}", method = RequestMethod.POST)
@ArchivesLog(operationType = OpTypeConst.SAVE_VERSION)
public ResponseEntityDto<Object> addEngineVersion(@PathVariable Long engineId, @PathVariable Integer version) {
Map<String, Object> map = new HashMap<>();
// 获取当前系统登录用户,即引擎的创建者
Long userId = SessionManager.getLoginAccount().getUserId();
//获取当前选中的版本的最大子版本
EngineVersion engineVer = new EngineVersion();
engineVer.setEngineId(engineId);
engineVer.setVersion(version);
EngineVersion engineVersion = engineVersionService.getLatestEngineSubVersion(engineVer);
if (engineVersion != null) {
//无论引擎是否正在运行,皆在此版本下创建子版本
EngineVersion newEngineVersion = new EngineVersion();
newEngineVersion.setBootState(0);
newEngineVersion.setCreateTime(new Date().toString());
newEngineVersion.setEngineId(engineVersion.getEngineId());
newEngineVersion.setLatestTime(new Date().toString());
newEngineVersion.setLatestUser(userId);
newEngineVersion.setLayout(0);
newEngineVersion.setStatus(1);
newEngineVersion.setSubVersion(engineVersion.getSubVersion() + 1); // 子版本 +1
newEngineVersion.setUserId(userId);
newEngineVersion.setVersion(engineVersion.getVersion());
//新增版本
Long versionId = saveEngineVersion(newEngineVersion);
map.put("result", 1);
map.put("versionId", versionId);
} else {
map.put("result", -1);
map.put("versionId", 0);
}
return ResponseEntityBuilder.buildNormalResponse(map);
}
/**
* @api {POST} /v2/engineVersion/clear/{versionId} 7.57. 清空引擎节点根据versionId清空
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Number} versionId 路径参数versionId
* @apiSuccess {String} status 状态1成功0失败
* @apiParamExample {json} 请求示例:
* {无请求体}
* @apiSuccessExample {json} 成功返回数据示例:
* {待完善}
*/
@RequestMapping(value = "/clear/{versionId}", method = RequestMethod.POST)
@ArchivesLog(operationType = OpTypeConst.CLEAR_NODE)
public ResponseEntityDto<Object> clear(@PathVariable Long versionId) {
Map<String, Object> map = new HashMap<>();
// 正在部署的不能清除
EngineVersion engineVersion = engineVersionService.selectByPrimaryKey(versionId);
if (engineVersion != null) {
if (engineVersion.getBootState() == 1) {
map.put("result", "-1");
map.put("msg", "版本正在运行,请先停止部署!");
} else {
boolean flag = engineVersionService.clear(versionId);
if (flag) {
map.put("result", "1");
map.put("msg", "清除成功!");
} else {
map.put("result", "-1");
map.put("msg", "清除失败,请联系管理员!");
}
}
} else {
map.put("result", "-1");
map.put("msg", "数据错误,目标版本不存在!");
}
return ResponseEntityBuilder.buildNormalResponse(map);
}
/**
* @api {POST} /v2/engineVersion/deploy/{versionId} 7.50.1. 根据versionId部署引擎
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Number} versionId 路径参数versionId
* @apiSuccess {String} status 状态1成功0失败
* @apiSuccess {Object} data
* @apiSuccess {Number} data.status 部署结果1成功0失败
* @apiSuccess {String} data.msg 部署结果提示信息
* @apiParamExample {json} 请求示例:
* {无请求体}
* @apiSuccessExample {json} 成功返回数据示例:
* {待完善}
*/
@RequestMapping(value = "/deploy/{versionId}", method = RequestMethod.POST)
@ArchivesLog(operationType = OpTypeConst.ENGINDE_DEPLOY)
public ResponseEntityDto<Object> deployEngineVersion(@PathVariable Long versionId) {
int count = engineVersionService.deployEngine(versionId);
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("versionId", versionId);
if (count == 1) {
resultMap.put("status", EngineMsg.STATUS_SUCCESS);
resultMap.put("msg", EngineMsg.DEPLOY_SUCCESS);
} else {
resultMap.put("status", EngineMsg.STATUS_FAILED);
resultMap.put("msg", EngineMsg.DEPLOY_FAILED);
}
return ResponseEntityBuilder.buildNormalResponse(resultMap);
}
@RequestMapping(value = "/applyDeploy/{versionId}", method = RequestMethod.POST)
@ArchivesLog(operationType = OpTypeConst.ENGINDE_DEPLOY)
public ResponseEntityDto<Object> applyDeployEngineVersion(@PathVariable Long versionId) {
Map<String,Object> map = engineVersionService.applyDeployEngine(versionId);
if (map!=null&&!map.isEmpty()){
return ResponseEntityBuilder.buildNormalResponse(map);
}else {
return ResponseEntityBuilder.buildErrorResponse(ErrorCodeEnum.PARAMS_EXCEPTION);
}
}
/**
* @api {POST} /v2/engineVersion/undeploy/{versionId} 7.50.2. 根据versionId停用部署的引擎
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Number} versionId 路径参数versionId
* @apiSuccess {String} status 状态1成功0失败
* @apiSuccess {Object} data
* @apiSuccess {Number} data.status 停用部署结果1已停用0停用失败
* @apiSuccess {String} data.msg 停用部署结果提示信息
* @apiParamExample {json} 请求示例:
* {无请求体}
* @apiSuccessExample {json} 成功返回数据示例:
* {待完善}
*/
@RequestMapping(value = "/undeploy/{versionId}", method = RequestMethod.POST)
@ArchivesLog(operationType = OpTypeConst.ENGINDE_UNDEPLOY)
public ResponseEntityDto<Object> undeployEngineVersion(@PathVariable Long versionId) {
int count = engineVersionService.undeployEngine(versionId);
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("versionId", versionId);
if (count == 1) {
resultMap.put("status", EngineMsg.STATUS_SUCCESS);
resultMap.put("msg", EngineMsg.UNDEPLOY_SUCCESS);
} else {
resultMap.put("status", EngineMsg.STATUS_FAILED);
resultMap.put("msg", EngineMsg.UNDEPLOY_FAILED);
}
return ResponseEntityBuilder.buildNormalResponse(resultMap);
}
/**
* @api {POST} /v2/engineVersion/nodeList/{versionId} 7.66.20. 根据版本编号获取节点列表(这个接口没什么用)
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Number} versionId 路径参数versionId
* @apiSuccess {String} status 状态1成功0失败
* @apiParamExample {json} 请求示例:
* {无请求体}
* @apiSuccessExample {json} 成功返回数据示例:
* {待完善}
*/
@RequestMapping(value = "/nodeList/{versionId}", method = RequestMethod.POST)
public ResponseEntityDto<Object> getEngineNodeListByVerionId(@PathVariable Long versionId) {
List<EngineNode> nodeList = engineNodeService.getEngineNodeListByEngineVersionId(versionId);
// if (CollectionUtil.isNotNullOrEmpty(nodeList)) {
// return ResponseEntityBuilder.buildNormalResponse(nodeList);
// }
// return ResponseEntityBuilder.buildNormalResponse(null);
return ResponseEntityBuilder.buildNormalResponse(nodeList);
}
/**
* @api {POST} /v2/engineVersion/getTypedNodes/{versionId} 7.58. 根据类型获取节点
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Number} versionId 路径参数versionId
* @apiParam {JSONArray} types 节点类型
* @apiSuccess {String} status 状态1成功0失败
* @apiParamExample {json} 请求示例:
* [3,7]
* @apiSuccessExample {json} 成功返回数据示例:
* {待完善}
*/
@RequestMapping(value = "/getTypedNodes/{versionId}", method = RequestMethod.POST)
public ResponseEntityDto<Object> getEngineNodesByType(@PathVariable Long versionId, @RequestBody List<Integer> types) {
// @RequestParam Map<String, Object> paramMap,
// @RequestParam("types[]") List<Integer> types
// Long versionId = Long.parseLong(paramMap.get("versionId").toString());
HashMap<String, Object> paramMap = new HashMap<>();
List<EngineNode> nodeList = engineNodeService.getEngineTypedNodeListByEngineVersionId(versionId, types);
boolean flag = true;
boolean flag1 = true;
if (nodeList != null && nodeList.size() > 0) {
for (EngineNode engineNode : nodeList) {
if ((int) engineNode.getNodeType() == 7 && flag) {
if (!StringUtil.isBlank(engineNode.getNodeJson())) {
JSONArray json = JSONArray.parseArray(engineNode.getNodeJson());
if (!StringUtil.isBlank(engineNode.getNextNodes())) {
String[] nextNodes = engineNode.getNextNodes().split(",");
paramMap.put("sanBoxNode", engineNode);
if (json.size() == nextNodes.length) {
paramMap.put("sanbox", "1");
} else {
paramMap.put("sanbox", "0");
flag = false;
}
} else {
paramMap.put("sanbox", "0");
flag = false;
}
}
}
if ((int) engineNode.getNodeType() == 3 && flag1) {
if (!StringUtil.isBlank(engineNode.getNodeJson())) {
JSONObject jsonObj = JSONObject.parseObject(engineNode.getNodeJson());
JSONArray json = jsonObj.getJSONArray("conditions");
if (!StringUtil.isBlank(engineNode.getNextNodes())) {
String[] nextNodes = engineNode.getNextNodes().split(",");
paramMap.put("groupNode", engineNode);
if (json.size() == nextNodes.length) {
paramMap.put("group", "1");
} else {
paramMap.put("group", "0");
flag1 = false;
}
} else {
paramMap.put("group", "0");
flag1 = false;
}
}
}
}
} else {
paramMap.put("sanbox", "-1");
paramMap.put("group", "-1");
}
return ResponseEntityBuilder.buildNormalResponse(paramMap);
}
/**
* @api {POST} /v2/engineVersion/delete/{versionId} 7.66.21. 删除当前版本
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Number} versionId 路径参数versionId
* @apiSuccess {String} status 状态1成功0失败
* @apiParamExample {json} 请求示例:
* {无请求体}
* @apiSuccessExample {json} 成功返回数据示例:
* {待完善}
*/
@RequestMapping(value = "/delete/{versionId}", method = RequestMethod.POST)
@ArchivesLog(operationType = OpTypeConst.DELETE_VERSION)
public ResponseEntityDto<Object> deleteEngineVersion(@PathVariable Long versionId) {
EngineVersion engineVersion = engineVersionService.selectByPrimaryKey(versionId);
Map<String, Object> map = new HashMap<>();
// 当前版本是否正在运行
int bootState = engineVersion.getBootState();
if (EngineConst.BOOT_STATE_DEPLOY == bootState) {
// 如果正在运行,则提示用户不能删除
map.put("status", EngineMsg.STATUS_FAILED);
map.put("msg", EngineMsg.DELETE_RUNNING_FAILED);
} else {
// 假删除,是否删除 (0:在回收站中,可恢复,1:正常,2彻底删除)
engineVersion.setStatus(0); // 状态改为0
int count = engineVersionService.update(engineVersion);
if (count == 1) {
map.put("status", EngineMsg.STATUS_SUCCESS);
map.put("msg", EngineMsg.DELETE_VERSION_SUCCESS);
} else {
map.put("status", EngineMsg.STATUS_FAILED);
map.put("msg", EngineMsg.DELETE_VERSION_FAILED);
}
}
return ResponseEntityBuilder.buildNormalResponse(map);
}
/**
* 新增版本
* 新增分为两种情况,一种是自然地新增,
* 一种是当前版本正在运行修改的新增
*
* @param engineVersion
* @return
*/
@RequestMapping("save")
@ArchivesLog(operationType = OpTypeConst.SAVE_VERSION)
public Long saveEngineVersion(EngineVersion engineVersion) {
List<EngineNode> nodeList = new ArrayList<>();
EngineNode engineNode = new EngineNode();
engineNode.setNodeX(200d);
engineNode.setNodeY(200d);
engineNode.setNodeName("开始");
engineNode.setNodeType(1);
engineNode.setNodeOrder(1);
engineNode.setNodeCode("ND_START");
engineNode.setParams("{\"arr_linkId\":\"\",\"dataId\":\"-1\",\"url\":\"/Riskmanage/resource/images/decision/start.png\",\"type\":\"1\"}");
nodeList.add(engineNode);
Long versionId = engineVersionService.saveEngineVersion(engineVersion, nodeList);
return versionId;
}
}

View File

@@ -0,0 +1,105 @@
package com.fibo.ddp.enginex.riskengine.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.enginex.risk.EngineVersion;
import com.fibo.ddp.common.service.common.SessionManager;
import com.fibo.ddp.common.service.datax.datamanage.FieldService;
import com.fibo.ddp.common.service.enginex.risk.EngineNodeService;
import com.fibo.ddp.common.service.enginex.risk.EngineVersionService;
import com.fibo.ddp.common.service.monitor.logger.ArchivesLog;
import com.fibo.ddp.common.service.strategyx.listlibrary.ListDbService;
import com.fibo.ddp.common.utils.constant.OpTypeConst;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* 黑白名单节点接口
*/
@Controller("listDbNodeControllerV2")
@RequestMapping("v2/bwListNode")
@ResponseBody
public class ListDbNodeController {
@Autowired
private ListDbService listDbService;
@Autowired
private EngineNodeService engineNodeService;
@Autowired
private EngineVersionService engineVersionService;
@Autowired
private FieldService fieldService;
/**
* @api {POST} /v2/bwListNode/update 7.73. 黑白名单节点 修改节点信息
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Number} nodeId 节点编号
* @apiParam {Number} versionId 版本编号
* @apiParam {Number} nodeType 节点类型5黑名单6白名单
* @apiParam {Number} nodeOrder 节点顺序
* @apiParam {String} nodeName 节点名称
* @apiParam {String} nodeCode 节点code
* @apiParam {Number} nodeX 节点X轴
* @apiParam {Number} nodeY 节点Y轴
* @apiParam {String} innerListdbs 内部黑名单id逗号分隔
* @apiParam {String} outerListdbs 外部黑名单id逗号分隔
* @apiParam {String} [nodeJson] 节点json
* @apiParam {String} [nodeScript] 节点脚本
* @apiParam {String} [params] 节点类型,图标等信息
* @apiSuccess {String} status 状态1成功0失败
* @apiParamExample {json} 请求示例:
* {"nodeId":3361,"versionId":454,"nodeType":5,"nodeOrder":13,"nodeName":"黑名单66","nodeCode":"ND_13","nodeX":666.66,"nodeY":666.77,"innerListdbs":"112,115","outerListdbs":""}
* @apiSuccessExample {json} 成功返回数据示例:
* {"status":"1","error":"00000000","msg":null,"data":true}
*/
@RequestMapping(value = "update", method = RequestMethod.POST)
@ArchivesLog(operationType = OpTypeConst.UPDATE_NODE)
public ResponseEntityDto update(@RequestBody HashMap<String, Object> paramMap) {
//增加黑白名单库用到的字段绑定传递engineId和字段id
Long userId = SessionManager.getLoginAccount().getUserId();
paramMap.put("userId", userId); //listDbIds
String innerListdbs = String.valueOf(paramMap.get("innerListdbs"));
String outerListdbs = String.valueOf(paramMap.get("outerListdbs"));
Object nodeJson = paramMap.get("nodeJson");
List<Long> listDbIds = new ArrayList<>();
if (nodeJson!=null){
JSONObject jsonObject = JSON.parseObject(nodeJson.toString());
JSONArray listDbList = jsonObject.getJSONArray("listDbList");
if (listDbList!=null&&listDbList.size()>0){
for (Object o : listDbList) {
JSONObject listDbJson = JSON.parseObject(JSON.toJSONString(o));
Long listDbId = listDbJson.getLong("listDbId");
if (listDbId!=null){
listDbIds.add(listDbId);
}
}
}
}
String snapshot = String.valueOf(paramMap.get("snapshot"));
paramMap.put("listDbIds", listDbIds);
String strFieldIds = listDbService.findFieldsByListDbIds(paramMap);
Long versionId = Long.valueOf(String.valueOf(paramMap.get("versionId")));
EngineVersion engineVesion = engineVersionService.selectByPrimaryKey(versionId);
Long engineId = engineVesion.getEngineId();
paramMap.put("engineId", engineId);
paramMap.put("fieldIds", strFieldIds);
fieldService.bindEngineField(paramMap);
paramMap.put("snapshot",snapshot);
engineNodeService.updateNodeSnapshot(paramMap);
return ResponseEntityBuilder.buildNormalResponse();
}
}

View File

@@ -0,0 +1,77 @@
package com.fibo.ddp.enginex.riskengine.controller;
import com.fibo.ddp.common.model.authx.system.SysUser;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.model.enginex.risk.request.ModelListParam;
import com.fibo.ddp.common.model.strategyx.aimodel.MachineLearningModels;
import com.fibo.ddp.common.service.common.SessionManager;
import com.fibo.ddp.common.service.enginex.risk.EngineNodeService;
import com.fibo.ddp.common.service.strategyx.aimodel.ModelsService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
/**
* 模型节点接口
*/
@RestController
@RequestMapping("modelNode")
public class ModelNodeController {
@Autowired
private ModelsService modelsService;
@Autowired
private EngineNodeService engineNodeService;
/**
* @api {POST} /modelNode/getModelList 7.91. 模型节点 获取模型列表
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Integer} pageNo 页数
* @apiParam {Integer} pageSize 每页的条数
* @apiParam {Long} nodeId 节点id
* @apiParam {Long} engineId 引擎id
* @apiParam {String} [searchString] 搜索关键字
* @apiSuccess {String} status 状态: 1成功, 0失败
* @apiParamExample {json} 请求示例:
* {"pageNo":1,"pageSize":5,"nodeId":3247,"engineId":214,"searchString":"模型"}
* @apiSuccessExample {json} 成功返回数据示例:
* {"status":"1","error":"00000000","msg":null,"data":{"pager":{"pageNum":1,"pageSize":5,"size":1,"startRow":1,"endRow":1,"total":1,"pages":1,"list":null,"prePage":0,"nextPage":0,"isFirstPage":true,"isLastPage":true,"hasPreviousPage":false,"hasNextPage":false,"navigatePages":8,"navigatepageNums":[1],"navigateFirstPage":1,"navigateLastPage":1,"lastPage":1,"firstPage":1},"modelsList":[{"userId":1,"modelName":"老户模型","description":"老户模型描述","modelType":"pmml","fileName":"1614578067937_model_RF.pmml","filePath":"/usr/local/tomcat_riskmanage/webapps/Riskmanage/upload/models/fieldUpload/1614578067937_model_RF.pmml","modelField":"x16,x17,x8,x19,x6,x10,x5,x1,x13,x2,x3,x15,x21,x18,x11,x7,x14,x12,x20","mappingField":"588,590,591,592,593,594,605,606,611,613,610,612,614,615,616,609,617,620,589","status":1,"creator":135,"modifier":135,"organId":46,"createTime":1614578104000,"updateTime":1614578104000,"modelFieldArr":null,"mappingFieldArr":null,"checked":true}]}}
*/
@RequestMapping(value = "getModelList", method = RequestMethod.POST)
public ResponseEntityDto<Object> getModelList(@RequestBody ModelListParam param) {
String searchString = param.getSearchString();
Long nodeId = param.getNodeId();
SysUser sysUser = SessionManager.getLoginAccount();
Integer organId = Integer.valueOf(sysUser.getOrganId().toString());
PageHelper.startPage(param.getPageNo(), param.getPageSize());
List<MachineLearningModels> modelsList = modelsService.getModelsListByOrganId(organId, searchString);
EngineNode engineNode = engineNodeService.findById(nodeId);
if (engineNode != null) {
for (MachineLearningModels models : modelsList) {
if (models.getId().toString().equals(engineNode.getNodeJson())) {
models.setChecked(true);
break;
}
}
}
PageInfo<MachineLearningModels> pageInfo = new PageInfo<MachineLearningModels>(modelsList);
pageInfo.setList(null);
HashMap<String, Object> modelMap = new HashMap<>();
modelMap.put("pager", pageInfo);
modelMap.put("modelsList", modelsList);
return ResponseEntityBuilder.buildNormalResponse(modelMap);
}
}

View File

@@ -0,0 +1,152 @@
package com.fibo.ddp.enginex.riskengine.controller;
import com.fibo.ddp.common.model.authx.system.SysUser;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.enginex.risk.request.KnowledgeTreeListParam;
import com.fibo.ddp.common.model.strategyx.guiderule.RuleInfo;
import com.fibo.ddp.common.model.strategyx.guiderule.request.RuleListParamV2;
import com.fibo.ddp.common.model.strategyx.knowledge.KnowledgeTree;
import com.fibo.ddp.common.service.common.SessionManager;
import com.fibo.ddp.common.service.strategyx.guiderule.RuleService;
import com.fibo.ddp.common.service.strategyx.guiderule.RuleVersionService;
import com.fibo.ddp.common.service.strategyx.knowledge.KnowledgeTreeService;
import com.fibo.ddp.common.service.strategyx.scriptrule.RuleScriptVersionService;
import com.fibo.ddp.common.utils.util.StringUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Controller("RuleNodeController")
@RequestMapping("/v2/ruleNode")
@ResponseBody
public class RuleNodeController {
@Autowired
private RuleService ruleService;
@Autowired
private RuleVersionService versionService;
@Autowired
private RuleScriptVersionService ruleScriptVersionService;
@Autowired
private KnowledgeTreeService knowledgeTreeService;
/**
* @api {POST} /v2/ruleNode/getTreeDataForEngine 7.61. 获取树形节点集合
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Integer} status 值为1
* @apiParam {Integer} type 1规则集2
* @apiParam {Integer} [pageNo=1] 第几页
* @apiParam {Integer} [pageSize=5] 每页的条数
* @apiParam {Integer} [engineId] 引擎id
* @apiSuccess {String} status 状态1成功0失败
* @apiParamExample {json} 请求示例:
* {"status":1,"type":1,"pageNo":1,"pageSize":5,"engineId":211}
* @apiSuccessExample {json} 成功返回数据示例:
* {待完善}
*/
@RequestMapping(value = "/getTreeDataForEngine", method = RequestMethod.POST)
public ResponseEntityDto<Object> getTreeDataForEngine(@RequestBody Map<String, Object> param) {
// @RequestParam Map<String,Object> inputParam,
// @RequestParam(defaultValue = "1") Integer pageNo,
// @RequestParam(defaultValue = "5") Integer pageSize
Integer pageNo = param.get("pageNo") == null ? 1 : Integer.valueOf(param.get("pageNo").toString());
Integer pageSize = param.get("pageSize") == null ? 5 : Integer.valueOf(param.get("pageSize").toString());
param.putAll(getParam(param));
param.put("sort", false);
param.put("tree_type", StringUtil.toLongList("0"));
param.put("status", StringUtil.toLongList(param.get("status").toString()));
PageHelper.startPage(pageNo, pageSize);
List<KnowledgeTree> klist = knowledgeTreeService.getTreeDataForEngine(param);
PageInfo<KnowledgeTree> pageInfo = new PageInfo<>(klist);
param.put("klist", klist);
param.put("pager", pageInfo);
return ResponseEntityBuilder.buildNormalResponse(param);
}
/**
* @api {POST} /v2/ruleNode/getRuleDataForEngine 7.62. 获取规则数据为引擎节点
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Integer} status 值为1
* @apiParam {Integer} parentIds XXXXX
* @apiParam {Integer} [is_select] 值为1
* @apiParam {Integer} [dictKey] 值为ruleName
* @apiParam {Integer} [dictValue] 搜索关键字
* @apiParam {Integer} [engineId] 引擎id
* @apiSuccess {String} status 状态1成功0失败
* @apiParamExample {json} 请求示例1
* {"status":1,"parentIds":1038,"engineId":211}
* @apiParamExample {json} 请求示例2
* {"status":1,"is_select":1,"dictKey":"ruleName","dictValue":"欺诈","engineId":211}
* @apiSuccessExample {json} 成功返回数据示例:
* {待完善}
*/
@RequestMapping(value = "/getRuleDataForEngine", method = RequestMethod.POST)
public ResponseEntityDto<Object> getRuleDataForEngine(@RequestBody Map<String, Object> param) {
param.putAll(getParam(param));
param.put("status", StringUtil.toLongList(param.get("status").toString()));
RuleInfo rule = new RuleInfo();
rule.setStatus(1);
rule.setOrganId(SessionManager.getLoginAccount().getOrganId());
if (param.containsKey("parentIds")) {
List<Long> parentIds = StringUtil.toLongList(param.get("parentIds").toString());
param.put("parentIds",parentIds );
rule.setParentIds(parentIds);
}
// List<Rule> rlist = s.ruleService.getRuleList(inputParam);
RuleListParamV2 ruleListParam = new RuleListParamV2();
ruleListParam.setPageNum(0);
ruleListParam.setPageSize(0);
ruleListParam.setRuleInfo(rule);
List<RuleInfo> list = ruleService.queryByEntity(ruleListParam).getList();
if (list != null && list.size() > 0) {
for (RuleInfo info : list) {
if (info.getDifficulty() == 2) {
info.setRuleVersionList(versionService.queryVersionListByRuleId(info.getId()));
}else
if (info.getDifficulty() == 3){
info.setRuleScriptVersionList(ruleScriptVersionService.queryVersionListByRuleId(info.getId()));
}
}
}
param.put("rlist", list);
return ResponseEntityBuilder.buildNormalResponse(param);
}
// 已选规则预览(待完善)(待讨论)
@RequestMapping(value = "/previewRule", method = RequestMethod.POST)
public ModelAndView previewRule(@RequestParam Map<String, Object> paramMap) {
ModelAndView mav = new ModelAndView("decision/rulesDetails");
mav.addAllObjects(paramMap);
return mav;
}
// 根据用户角色或权限,获取所需参数集合
private Map<String, Object> getParam(Map<String, Object> paramMap) {
SysUser sysUser = SessionManager.getLoginAccount();
paramMap.put("userId", sysUser.getUserId());
paramMap.put("organId", sysUser.getOrganId());
return paramMap;
}
@RequestMapping(value = "/getFolderList", method = RequestMethod.POST)
public ResponseEntityDto<Object> getFolderList(@RequestBody KnowledgeTreeListParam param) {
List<KnowledgeTree> list = knowledgeTreeService.getFolderList(param);
Map<String, Object> map = new HashMap<>();
map.put("klist", list);
return ResponseEntityBuilder.buildNormalResponse(map);
}
}

View File

@@ -0,0 +1,144 @@
package com.fibo.ddp.enginex.riskengine.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.model.strategyx.scorecard.Scorecard;
import com.fibo.ddp.common.model.strategyx.scorecard.vo.ScorecardVersionVo;
import com.fibo.ddp.common.model.strategyx.scorecard.vo.ScorecardVo;
import com.fibo.ddp.common.service.enginex.risk.EngineNodeService;
import com.fibo.ddp.common.service.strategyx.scorecard.ScorecardService;
import com.fibo.ddp.common.service.strategyx.scorecard.ScorecardVersionService;
import com.fibo.ddp.common.utils.util.StringUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Controller("ScorecardNodeControllerV2")
@RequestMapping("/v2/cardNode")
@ResponseBody
public class ScorecardNodeController {
@Autowired
private ScorecardVersionService scorecardVersionService;
@Autowired
private ScorecardService scorecardService;
@Autowired
private EngineNodeService engineNodeService;
// 决策流
@RequestMapping("toCardNode")
public ModelAndView toCardNode() {
ModelAndView mav = new ModelAndView("decision/decisions");
return mav;
}
/**
* @api {POST} /v2/cardNode/cardList 7.60. 返回评分卡列表
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Number} nodeId 节点id0表示新建的
* @apiParam {Number} status 1
* @apiParam {String} [dictKey] 值为"scorecardName"
* @apiParam {String} [dictValue] 搜索关键字
* @apiParam {Number} [pageNo=1] 第几页
* @apiParam {Number} [pageSize=10] 每页的条数
* @apiParam {Number} [engineId] 引擎id
* @apiSuccess {String} status 状态1成功0失败
* @apiParamExample {json} 请求示例1
* {"nodeId":3223,"status":1}
* @apiParamExample {json} 请求示例2
* {"nodeId":3223,"status":1,"dictKey":"scorecardName","dictValue":"客户","pageNo":1,"pageSize":10,"engineId":211}
* @apiSuccessExample {json} 成功返回数据示例:
* {"status":"1","error":"00000000","msg":null,"data":{"pager":{"pageNum":1,"pageSize":1,"size":1,"startRow":1,"endRow":1,"total":9,"pages":9,"list":[{"userId":99,"name":"客户评分卡-有盾","versionCode":"SC_test_card2","description":"客户评分卡-有盾值","version":null,"parentId":1076,"userId":135,"author":135,"authorName":"管理员","engineId":211,"type":1,"status":1,"sFieldList":[],"sContentList":[],"created":1520236208000,"updated":1615889385000,"checked":false,"score":"{\"output\":{\"field_id\":0,\"field_code\":\"score\",\"field_name\":\"信用得分\",\"field_type\":1},\"formula\":\"300+#{f_yd_realNameScore}\",\"formula_show\":\"300+@有盾实名认证分值@\",\"fields\":[{\"field_id\":642,\"field_code\":\"f_yd_realNameScore\",\"field_type\":1,\"field_name\":\"有盾实名认证分值\",\"segments\":[{\"segment\":\"(,29]\",\"dictValue\":0},{\"segment\":\"(29,69]\",\"dictValue\":50},{\"segment\":\"(69,)\",\"dictValue\":100}]}]}","pd":null,"odds":null,"engineName":null,"organId":46,"sRuleContentList":[]}],"prePage":0,"nextPage":2,"isFirstPage":true,"isLastPage":false,"hasPreviousPage":false,"hasNextPage":true,"navigatePages":8,"navigatepageNums":[1,2,3,4,5,6,7,8],"navigateFirstPage":1,"navigateLastPage":8,"firstPage":1,"lastPage":8},"keySearch":"客户","list":[{"userId":99,"name":"客户评分卡-有盾","versionCode":"SC_test_card2","description":"客户评分卡-有盾值","version":null,"parentId":1076,"userId":135,"author":135,"authorName":"管理员","engineId":211,"type":1,"status":1,"sFieldList":[],"sContentList":[],"created":1520236208000,"updated":1615889385000,"checked":false,"score":"{\"output\":{\"field_id\":0,\"field_code\":\"score\",\"field_name\":\"信用得分\",\"field_type\":1},\"formula\":\"300+#{f_yd_realNameScore}\",\"formula_show\":\"300+@有盾实名认证分值@\",\"fields\":[{\"field_id\":642,\"field_code\":\"f_yd_realNameScore\",\"field_type\":1,\"field_name\":\"有盾实名认证分值\",\"segments\":[{\"segment\":\"(,29]\",\"dictValue\":0},{\"segment\":\"(29,69]\",\"dictValue\":50},{\"segment\":\"(69,)\",\"dictValue\":100}]}]}","pd":null,"odds":null,"engineName":null,"organId":46,"sRuleContentList":[]}]}}
*/
@RequestMapping(value = "/cardList", method = RequestMethod.POST)
public ResponseEntityDto<Object> getCardNode(@RequestBody Map<String, Object> param) {
Long nodeId = Long.parseLong(param.get("nodeId").toString());
Integer pageNo = param.get("pageNo") == null ? 1 : Integer.parseInt(param.get("pageNo").toString());
Integer pageSize = param.get("pageSize") == null ? 10 : Integer.parseInt(param.get("pageSize").toString());
String keySearch = "1";
param.put("status", StringUtil.toLongList(param.get("status").toString()));
PageHelper.startPage(pageNo, pageSize);
List<Scorecard> list = scorecardService.getScorecardList(param);
// 回显
if (nodeId != null && nodeId != 0) {
EngineNode byId = engineNodeService.findById(nodeId);
if (byId != null) {
//获取评分卡id
//long knowledgeId = nodeKnowledge.getKnowledgeId();//
if (StringUtils.isNotBlank(byId.getNodeJson())) {
// && !"".equals(byId.getNodeJson())
// long knowledgeId = Long.valueOf(byId.getNodeJson());
long knowledgeId = 0;
if(byId.getNodeJson()!=null&&!byId.getNodeJson().contains("{")){
knowledgeId = StringUtil.getStrToLong(byId.getNodeJson());
}
//原来存储id现在被转换为存储的是json
Map<Long,Long> scorecardIdMap = new HashMap();
if (knowledgeId == 0) {
try {
JSONObject jsonObject = JSON.parseObject(byId.getNodeJson());
JSONArray scorecardList = jsonObject.getJSONArray("scorecardList");
if (scorecardList!=null&&!scorecardList.isEmpty()){
for (int i = 0; i < scorecardList.size(); i++) {
JSONObject scorecard = scorecardList.getJSONObject(i);
scorecardIdMap.put(scorecard.getLong("scorecardId"),scorecard.getLong("versionId"));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}else {
ScorecardVersionVo version = scorecardVersionService.queryById(knowledgeId);
if (version!=null){
scorecardIdMap.put(version.getScorecardId(),version.getId());
}
}
//判断并回显
if (scorecardIdMap != null&& !scorecardIdMap.isEmpty() && list != null && list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
Long cardId = list.get(i).getId();
if (scorecardIdMap.containsKey(cardId)) {
ScorecardVo scorecardInfo = scorecardService.getScorecardInfo(cardId);
scorecardInfo.setChecked(true);
scorecardInfo.setCheckedId(scorecardIdMap.get(cardId));
list.set(i, scorecardInfo);
}
}
}
}
}
}
PageInfo<Scorecard> pageInfo = new PageInfo<>(list);
if (param.containsKey("dictValue")) {
keySearch = param.get("dictValue").toString();
}
HashMap<String, Object> modelMap = new HashMap<>();
modelMap.put("list", list);
modelMap.put("pager", pageInfo);
modelMap.put("keySearch", keySearch);
return ResponseEntityBuilder.buildNormalResponse(modelMap);
}
}

View File

@@ -0,0 +1,67 @@
package com.fibo.ddp.enginex.riskengine.runner.api;
import com.fibo.ddp.common.service.common.runner.RunnerSessionManager;
import com.fibo.ddp.common.service.common.runner.SessionData;
import com.fibo.ddp.enginex.riskengine.runner.business.DecisionApiBizData;
import com.fibo.ddp.enginex.riskengine.runner.business.DecisionApiRequest;
import com.fibo.ddp.enginex.riskengine.runner.business.RiskEngineBusiness;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("runner")
public class RiskEngineApi {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
public RiskEngineBusiness riskEngineBusiness;
@RequestMapping(value = "/decision", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
public String decision(@RequestBody DecisionApiRequest apiRequest) {
long start = System.currentTimeMillis();
DecisionApiBizData bizData = apiRequest.getBiz_data();
Map<String, Object> map = new HashMap<>();
map.put("pid", bizData.getBusinessId());
map.put("uid", "");
map.put("reqType", 1);
map.put("engineId", bizData.getEngineId());
map.put("organId", bizData.getOrganId());
SessionData sessionData = new SessionData();
sessionData.setOrganId(bizData.getOrganId());
sessionData.setEngineId(bizData.getEngineId());
sessionData.setReqType(1);
RunnerSessionManager.setSession(sessionData);
if(bizData.getFields() != null){
map.put("fields", bizData.getFields());
} else {
map.put("fields", new HashMap<>());
}
String result = riskEngineBusiness.engineApi(map);
long end = System.currentTimeMillis();
logger.info("============ 接口调用耗时:{}ms ============", (end -start));
return result;
}
@RequestMapping(value = "/batchExecute", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
public List batchExecute(@RequestBody List<DecisionApiRequest> requestList){
List<String> list = new ArrayList<>();
for (DecisionApiRequest apiRequest : requestList) {
String decision = this.decision(apiRequest);
list.add(decision);
}
return list;
}
}

View File

@@ -0,0 +1,18 @@
package com.fibo.ddp.enginex.riskengine.runner.business;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Map;
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
public class DecisionApiBizData {
private String businessId; // 业务id
private Long organId; // 组织id
private Long engineId; // 引擎id
private Map<String, Object> fields; // 指标字段键值对
}

View File

@@ -0,0 +1,17 @@
package com.fibo.ddp.enginex.riskengine.runner.business;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
public class DecisionApiRequest {
private String tp_code; // 调用方编码
private String timestamp; // 精确到毫秒
private String sign; // 签名
private String biz_enc; // biz_data加密方式0不加密1加密
private DecisionApiBizData biz_data; // 请求的业务数据json格式的字符串
}

View File

@@ -0,0 +1,8 @@
package com.fibo.ddp.enginex.riskengine.runner.business;
import java.util.Map;
public interface RiskEngineBusiness {
String engineApi(Map<String, Object> paramJson);
}

View File

@@ -0,0 +1,606 @@
package com.fibo.ddp.enginex.riskengine.runner.business.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.dao.enginex.risk.EngineResultSetMapper;
import com.fibo.ddp.common.model.enginex.risk.Engine;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.model.enginex.risk.EngineResultSet;
import com.fibo.ddp.common.model.enginex.risk.EngineVersion;
import com.fibo.ddp.common.model.monitor.decisionflow.MonitorNode;
import com.fibo.ddp.common.service.enginex.risk.EngineNodeService;
import com.fibo.ddp.common.service.enginex.risk.EngineService;
import com.fibo.ddp.common.service.enginex.risk.EngineVersionService;
import com.fibo.ddp.common.service.monitor.runner.MonitorCenterFactoryRunner;
import com.fibo.ddp.common.service.monitor.runner.MonitorCommonService;
import com.fibo.ddp.common.service.monitor.runner.hbase.IFeatureRecordService;
import com.fibo.ddp.common.utils.constant.enginex.NodeTypeEnum;
import com.fibo.ddp.common.utils.constant.monitor.MonitorStorageType;
import com.fibo.ddp.enginex.riskengine.runner.business.RiskEngineBusiness;
import com.fibo.ddp.enginex.runner.node.impl.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;
import org.springframework.web.client.AsyncRestTemplate;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
@Service
public class RiskEngineBusinessImpl implements RiskEngineBusiness {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
public EngineService engineService;
@Resource
public EngineVersionService engineVersionService;
@Resource
public EngineNodeService engineNodeService;
@Resource
public EngineResultSetMapper resultSetMapper;
@Resource
private DecisionTablesNode decisionTablesNode;
@Resource
private DecisionTreeNode decisionTreeNode;
@Autowired
private DecisionOptionsNode decisionOptionsNode;
@Autowired
private ScorecardNode scorecardNode;
@Autowired
private RuleSetNode ruleSetNode;
@Autowired
private GroupNode groupNode;
@Autowired
private ModelNode modelNode;
@Autowired
private ChildEngineNode childEngineNode;
@Autowired
private BlackOrWhiteNode blackOrWhiteNode;
@Autowired
private AggregationNode aggregationNode;
@Autowired
private ParallelNode parallelNode;
@Autowired
private ChampionChallengeNode championChallengeNode;
@Autowired
private RpcNode rpcNode;
@Autowired
private SandboxProportionNode sandboxProportionNode;
@Autowired
private MonitorCommonService monitorCommonService;
@Autowired
private IFeatureRecordService featureRecordService;
@Autowired
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Value("${monitor.data.storage.type}")
private String storageType;
@Autowired(required = false)
private AsyncRestTemplate asyncRestTemplate;
@Override
public String engineApi(Map<String, Object> paramJson) {
logger.info("请求参数paramJson: {}", JSONObject.toJSONString(paramJson));
JSONObject jsonObject = new JSONObject();
JSONArray resultJson = new JSONArray();
Map<String, Map<String,Object>> featureMaps = new ConcurrentHashMap<>();
//时间差小于等于30分钟并且鉴权成功
if (true){
Long organId = Long.valueOf(paramJson.get("organId").toString());
Long engineId = Long.valueOf(paramJson.get("engineId").toString());
//获取引擎信息
Engine engine = engineService.getEngineById(engineId);
if(engine != null && !engine.getOrganId().equals(organId)){
// todo 校验引擎是否为该组织所属
}
//获取引擎正在运行中的版本
EngineVersion engineVersion = engineVersionService.getRunningVersion(engineId);
if (engineVersion != null) {
//返回引擎下的所有节点集合
List<EngineNode> engineNodeList = engineNodeService.getEngineNodeListByVersionId(engineVersion.getVersionId());
Map<String, EngineNode> engineNodeMap = getEngineNodeListByMap(engineNodeList);
try {
//变量池
Map<String, Object> inputParam = new ConcurrentHashMap<>();
inputParam.putAll(JSONObject.parseObject(JSONObject.toJSONString(paramJson.get("fields")), Map.class));
EngineNode engineNode = engineNodeMap.get("ND_START");
if (null != engineNode && null != engineNode.getNextNodes()) {
//返回输出结果
Map<String, Object> outMap = new ConcurrentHashMap<>();
// 记录执行前全量指标
featureMaps.put("before",inputParam);
//节点执行方法
recursionEngineNode(inputParam, engineNodeMap.get(engineNode.getNextNodes()), engineNodeMap, outMap);
jsonObject.put("status", "0x0000");
jsonObject.put("msg", "执行成功");
if (outMap.containsKey("centens") && outMap.get("centens").equals("true")) {
jsonObject.put("status", "0x0006");
jsonObject.put("msg", "获取数据失败");
jsonObject.put("data", "");
return jsonObject.toString();
}
//记录执行后的全量指标
featureMaps.put("after",inputParam);
paramJson.put("versionId",engineNode.getVersionId());
// todo 压测暂时去掉
// featureRecordService.recordAllFeature(featureMaps,engine,paramJson);
String json = JSONObject.toJSONString(inputParam);
jsonObject.put("input", JSONObject.parseObject(json));
EngineResultSet resultSet = new EngineResultSet();
resultSet.setEngineCode(engine.getCode());
resultSet.setInput(json);
resultSet.setEngineId(engine.getId());
resultSet.setEngineName(engine.getName());
resultSet.setType(2);
resultSet.setSubVersion(engineVersion.getSubVersion());
resultSet.setUid(String.valueOf(paramJson.get("uid")));
resultSet.setPid(String.valueOf(paramJson.get("pid")));
//决策表最终结果
if (outMap.containsKey("decisionTables")){
jsonObject.put("decisionTablesResult", outMap.get("decisionTables").toString());
resultSet.setDecisionTablesResult(outMap.get("decisionTables").toString());
}
//决策树最终结果
if (outMap.containsKey("decisionTree")){
jsonObject.put("decisionTreeResult", outMap.get("decisionTree").toString());
resultSet.setDecisionTreeResult(outMap.get("decisionTree").toString());
}
// 节点终止输出
if (outMap.containsKey("result")) {
resultSet.setResult(outMap.get("result").toString());
//决策选项最终结果
jsonObject.put("result", outMap.get("result").toString());
}
if (outMap.containsKey("blackJson")) {
resultJson.add(new JSONObject().parse(outMap.get("blackJson").toString()));
}
if (outMap.containsKey("whiteJson")) {
resultJson.add(new JSONObject().parse(outMap.get("whiteJson").toString()));
}
if (outMap.containsKey("ruleJson")) {
//规则集节点输出
JSONObject ruleJson = new JSONObject();
ruleJson.put("resultType", 2);
ruleJson.put("resultJson", outMap.get("ruleJson"));
resultJson.add(ruleJson);
}
if (outMap.containsKey("scoreJson")) {
//评分卡输出
JSONObject ruleJson = new JSONObject();
ruleJson.put("resultType", 4);
ruleJson.put("resultJson", outMap.get("scoreJson"));
resultJson.add(ruleJson);
}
if (outMap.containsKey("decisionJson")) {
//决策选项输出
JSONObject ruleJson = new JSONObject();
ruleJson.put("resultType", 9);
ruleJson.put("resultJson", outMap.get("decisionJson"));
resultJson.add(ruleJson);
}
if (outMap.containsKey("childEngineJson")) {
//子引擎节点输出
JSONObject ruleJson = new JSONObject();
ruleJson.put("resultType", 14);
ruleJson.put("resultJson", outMap.get("childEngineJson"));
resultJson.add(ruleJson);
}
if (outMap.containsKey("modelJson")) {
//模型节点输出
JSONObject ruleJson = new JSONObject();
ruleJson.put("resultType", 15);
ruleJson.put("resultJson", outMap.get("modelJson"));
resultJson.add(ruleJson);
}
if (outMap.containsKey("decisionTablesJson")) {
//决策表输出
JSONObject ruleJson = new JSONObject();
ruleJson.put("resultType", 16);
ruleJson.put("resultJson", outMap.get("decisionTablesJson"));
resultJson.add(ruleJson);
}
if (outMap.containsKey("decisionTreeJson")) {
//决策树输出
JSONObject ruleJson = new JSONObject();
ruleJson.put("resultType", 17);
ruleJson.put("resultJson", outMap.get("decisionTreeJson"));
resultJson.add(ruleJson);
}
jsonObject.put("data", resultJson);
String result = JSONObject.toJSONString(jsonObject);
JSONObject tmpJsonObject = JSONObject.parseObject(result);
tmpJsonObject.remove("input");
resultSet.setOutput(JSONObject.toJSONString(tmpJsonObject));
// todo 压测暂时去掉
// resultSetMapper.insertResultSet(resultSet);
Integer resultId = resultSet.getId();
// todo 压测暂时去掉
// this.monitorDecisionFlow(inputParam,engine,engineVersion,engineNodeList,outMap,paramJson,resultId);
// 正常返回结果回调
decisionCallback(engine.getCallbackUrl(), paramJson, result);
}
} catch (Exception e) {
logger.error("接口请求异常", e);
jsonObject.put("status", "0x0005");
jsonObject.put("msg", "执行失败");
jsonObject.put("data", "");
// 异常回调
decisionCallback(engine.getCallbackUrl(), paramJson, "执行失败");
}
} else {
jsonObject.put("status", "0x0004");
jsonObject.put("msg", "请求引擎不存在或尚未部署运行");
jsonObject.put("data", "");
}
} else {
jsonObject.put("status", "0x0001");
jsonObject.put("msg", "鉴权失败,非法调用");
jsonObject.put("data", "");
}
return jsonObject.toString();
}
/**
* 决策流监控
* @param inputParam
* @param engine
* @param engineVersion
* @param engineNodeList
* @param outMap
* @param paramJson
* @param resultId
*/
private void monitorDecisionFlow(Map<String, Object> inputParam, Engine engine, EngineVersion engineVersion, List<EngineNode> engineNodeList, Map<String, Object> outMap, Map<String, Object> paramJson, Integer resultId) {
switch (storageType){
case MonitorStorageType.Mysql:
MonitorCenterFactoryRunner.getMonitorCenterServiceImp(MonitorStorageType.Mysql).monitorDecisionFlow(inputParam,engine,engineVersion,engineNodeList,outMap,paramJson,resultId);
break;
case MonitorStorageType.HBase:
MonitorCenterFactoryRunner.getMonitorCenterServiceImp(MonitorStorageType.HBase).monitorDecisionFlow(inputParam,engine,engineVersion,engineNodeList,outMap,paramJson,resultId);
break;
default:
logger.info("检查监控存储类型配置是否正确");
break;
}
}
/**
* 递归执行节点
* @param inputParam
* @param engineNode
* @param engineNodeMap
* @param outMap
*/
private EngineNode recursionEngineNode(Map<String, Object> inputParam, EngineNode engineNode, Map<String, EngineNode> engineNodeMap, Map<String, Object> outMap) {
logger.info("请求参数--" + "inputParam:" + JSONObject.toJSONString(inputParam));
EngineNode resultNode = null; // 结束时返回节点: 串行流程返回null、并行流程返回聚合节点
if(engineNode == null){
return null;
}
// 获取节点所需的指标
getNodeField(engineNode, inputParam);
// 执行节点逻辑
runNode(engineNode, inputParam, outMap);
//用于存储执行过的节点
List<String> executedNodeList = new ArrayList<>();
//用于存储执行过的节点以及其对应的配置信息(节点id,对应的配置信息,以及结果)
List<MonitorNode> monitorNodeInfoList = new ArrayList<>();
if(outMap.containsKey("monitorNodes")){
monitorNodeInfoList = (List<MonitorNode>)outMap.get("monitorNodes");
}
if(outMap.containsKey("executedNodes")){
executedNodeList =(List<String>) outMap.get("executedNodes");
}
executedNodeList.add(engineNode.getNodeId()+"");
// 更新执行过节点数组
outMap.put("executedNodes",executedNodeList);
monitorCommonService.buildMonitorNode(inputParam,engineNode,outMap,monitorNodeInfoList);
// 所有节点监控信息数组放入 输出变量池中
outMap.put("monitorNodes",monitorNodeInfoList);
// 递归执行下一个节点
if (StringUtils.isNotBlank(engineNode.getNextNodes())) {
if(engineNode.getNodeType() == NodeTypeEnum.PARALLEL.getValue()){
// 并行节点执行
EngineNode aggregationNode = parallelNode(inputParam, engineNode, engineNodeMap, outMap);
recursionEngineNode(inputParam, aggregationNode, engineNodeMap, outMap);
} else {
// 串行节点执行
EngineNode nextEngineNode = engineNodeMap.get(engineNode.getNextNodes());
//如果输出的map里面有nextNode则说明有分组需要走分组下面的节点
if (outMap.containsKey("nextNode")) {
nextEngineNode = engineNodeMap.get(outMap.get("nextNode"));
outMap.remove("nextNode");
}
if(nextEngineNode!=null&&nextEngineNode.getNodeType() == NodeTypeEnum.AGGREGATION.getValue()){
// 并行节点后面的分支为多线程执行,执行到聚合节点则结束
resultNode = nextEngineNode;
} else {
resultNode = recursionEngineNode(inputParam, nextEngineNode, engineNodeMap, outMap);
}
}
}
return resultNode;
}
/**
* 并行节点处理(并行执行后面的分支,并返回最后的聚合节点)
* @param inputParam
* @param engineNode
* @param engineNodeMap
* @param outMap
* @return
*/
private EngineNode parallelNode(Map<String, Object> inputParam, EngineNode engineNode, Map<String, EngineNode> engineNodeMap, Map<String, Object> outMap){
EngineNode aggregationNode = null; // 聚合节点code
String[] nextNodeArr = engineNode.getNextNodes().split(",");
List<CompletableFuture<EngineNode>> futureList = new ArrayList<>();
for (String nextNodeCode : nextNodeArr) {
CompletableFuture<EngineNode> future = CompletableFuture.supplyAsync(() -> {
EngineNode nextEngineNode = engineNodeMap.get(nextNodeCode);
EngineNode resultNode = recursionEngineNode(inputParam, nextEngineNode, engineNodeMap, outMap);
return resultNode;
}, threadPoolTaskExecutor);
futureList.add(future);
}
for(CompletableFuture<EngineNode> future : futureList){
try {
EngineNode result = future.get();
aggregationNode = result;
} catch (Exception e) {
e.printStackTrace();
}
}
return aggregationNode;
}
/**
* 获取节点所需的指标
* @param engineNode
* @param inputParam
*/
private void getNodeField(EngineNode engineNode, Map<String, Object> inputParam) {
switch (engineNode.getNodeType()) {
case 2:
//规则
ruleSetNode.getNodeField(engineNode, inputParam);
break;
case 3:
//分组
groupNode.getNodeField(engineNode, inputParam);
break;
case 4:
//评分卡
scorecardNode.getNodeField(engineNode, inputParam);
break;
case 5:
//黑名单
blackOrWhiteNode.getNodeField(engineNode, inputParam);
break;
case 6:
//白名单
blackOrWhiteNode.getNodeField(engineNode, inputParam);
break;
case 9:
//决策选项
decisionOptionsNode.getNodeField(engineNode, inputParam);
break;
case 14:
//子引擎
childEngineNode.getNodeField(engineNode, inputParam);
break;
case 15:
//模型
modelNode.getNodeField(engineNode, inputParam);
break;
case 16:
//决策表
decisionTablesNode.getNodeField(engineNode, inputParam);
break;
case 17:
//决策树
decisionTreeNode.getNodeField(engineNode, inputParam);
break;
case 18:
//远程调用节点
rpcNode.getNodeField(engineNode, inputParam);
break;
case 19:
//并行节点
parallelNode.getNodeField(engineNode, inputParam);
break;
case 20:
//聚合节点
aggregationNode.getNodeField(engineNode, inputParam);
break;
case 21:
//冠军挑战节点
championChallengeNode.getNodeField(engineNode, inputParam);
break;
default:
break;
}
}
/**
* 执行节点逻辑
* @param engineNode
* @param inputParam
* @param outMap
*/
private void runNode(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap) {
switch (engineNode.getNodeType()) {
case 2:
//规则
ruleSetNode.runNode(engineNode, inputParam, outMap);
break;
case 3:
//分组
groupNode.runNode(engineNode, inputParam, outMap);
break;
case 4:
//评分卡
scorecardNode.runNode(engineNode, inputParam, outMap);
break;
case 5:
//黑名单
blackOrWhiteNode.runNode(engineNode, inputParam, outMap);
break;
case 6:
//白名单
blackOrWhiteNode.runNode(engineNode, inputParam, outMap);
break;
case 7:
//沙盒比例
sandboxProportionNode.runNode(engineNode, inputParam, outMap);
break;
case 9:
//决策选项
decisionOptionsNode.runNode(engineNode, inputParam, outMap);
break;
case 14:
//子引擎
childEngineNode.runNode(engineNode, inputParam, outMap);
break;
case 15:
//模型
modelNode.runNode(engineNode, inputParam, outMap);
break;
case 16:
//决策表
decisionTablesNode.runNode(engineNode,inputParam,outMap);
break;
case 17:
//决策树
decisionTreeNode.runNode(engineNode,inputParam,outMap);
break;
case 18:
//远程调用节点
rpcNode.runNode(engineNode,inputParam,outMap);
break;
case 19:
//并行节点
parallelNode.runNode(engineNode,inputParam,outMap);
break;
case 20:
//聚合节点
aggregationNode.runNode(engineNode,inputParam,outMap);
break;
case 21:
//冠军挑战节点
championChallengeNode.runNode(engineNode,inputParam,outMap);
break;
default:
break;
}
}
/**
* 把引擎节点以序号为key放入map
*
* @param nodelist 引擎节点
* @return map
* @see
*/
private Map<String, EngineNode> getEngineNodeListByMap(List<EngineNode> nodelist) {
Map<String, EngineNode> map = new HashMap<>();
for (int i = 0; i < nodelist.size(); i++) {
map.put(nodelist.get(i).getNodeCode(), nodelist.get(i));
}
return map;
}
/**
* 决策流执行完回调(包括决策流正常返回结果回调、以及异常回调)
* @param url
* @param paramJson
* @param result
*/
private void decisionCallback(String url, Map<String, Object> paramJson, String result){
if(StringUtils.isBlank(url)){
return;
}
Map<String, String> paramMap = new HashMap<>();
paramMap.put("paramJson", JSONObject.toJSONString(paramJson));
paramMap.put("result", result);
// 设置请求头
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
// 封装请求体
JSONObject body = JSONObject.parseObject(JSONObject.toJSONString(paramMap));
// 封装参数和头信息
HttpEntity<JSONObject> httpEntity = new HttpEntity(body, httpHeaders);
ListenableFuture<ResponseEntity<String>> future = asyncRestTemplate.postForEntity(url, httpEntity, String.class);
if(future != null){
future.addCallback(new ListenableFutureCallback<ResponseEntity<String>>() {
@Override
public void onFailure(Throwable throwable) {
logger.info("引擎回调异步调用失败", throwable);
}
@Override
public void onSuccess(ResponseEntity<String> stringResponseEntity) {
String result = stringResponseEntity.getBody();
logger.info("引擎回调异步调用成功result:{}", result);
}
});
}
}
}

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ddp-enginex</artifactId>
<groupId>com.fibo.ddp</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ddp-enginex-rule-engine</artifactId>
</project>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ddp-enginex</artifactId>
<groupId>com.fibo.ddp</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ddp-enginex-runner-node</artifactId>
</project>

View File

@@ -0,0 +1,120 @@
package com.fibo.ddp.enginex.runner.canal;
import com.fibo.ddp.common.dao.canal.TableEnum;
import com.fibo.ddp.common.dao.datax.datasource.SimpleMapper;
import com.fibo.ddp.common.service.redis.RedisManager;
import com.fibo.ddp.common.service.redis.RedisUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/cache")
public class CacheController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Resource
private SimpleMapper simpleMapper;
@Autowired
private RedisManager redisManager;
@RequestMapping(value = "initCache", method = RequestMethod.GET)
public void initCache() {
logger.info("===================== 缓存初始化开始 =====================");
long start = System.currentTimeMillis();
// 遍历表
for (TableEnum tableEnum : TableEnum.values()) {
String tableName = tableEnum.getTableName();
logger.info("===================== 开始初始化缓存表[{}] =====================", tableName);
String sqlStr = "select * from " + tableName;
Map<String, Object> parameterMap = new HashMap<>();
parameterMap.put("sqlStr", sqlStr);
List<LinkedHashMap<String, Object>> result = simpleMapper.customSelect(parameterMap);
// 遍历行
for (LinkedHashMap<String, Object> map : result) {
row(tableEnum, map);
}
logger.info("===================== 结束初始化缓存表[{}],共[{}]条数据 =====================", tableName, result.size());
}
long end = System.currentTimeMillis();
logger.info("===================== 缓存初始化成功!!耗时:{}ms =====================", (end - start));
}
private void row(TableEnum tableEnum, LinkedHashMap<String, Object> map) {
String tableName = tableEnum.getTableName();
String primaryKey = null;
String foreignKey = null;
if (StringUtils.isNotBlank(tableEnum.getPrimaryId())) {
String primaryId = map.get(tableEnum.getPrimaryId()).toString();
primaryKey = RedisUtils.getPrimaryKey(tableName, primaryId);
}
if (StringUtils.isNotBlank(tableEnum.getForeignId())) {
Object obj = map.get(tableEnum.getForeignId());
if (obj != null && !"".equals(obj.toString())) {
String foreignId = obj.toString();
foreignKey = RedisUtils.getForeignKey(tableName, foreignId);
}
}
if (StringUtils.isNotBlank(primaryKey)) {
// 遍历列
for (String field : map.keySet()) {
String value = map.get(field) == null ? null : map.get(field).toString();
setColumnCache(primaryKey, field, value);
}
}
if (StringUtils.isNotBlank(foreignKey)) {
setForeignKeyCache(primaryKey, foreignKey);
}
// 指标表特殊处理
dealSpecialTable(tableName, map);
}
private void setColumnCache(String primaryKey, String field, String value) {
logger.info("开始主键缓存设置, primaryKey:{}, field:{}, value:{}", primaryKey, field, value);
redisManager.hset(primaryKey, field, value);
logger.info("结束主键缓存设置, primaryKey:{}, field:{}, value:{}", primaryKey, field, value);
}
private void setForeignKeyCache(String primaryKey, String foreignKey) {
logger.info("开始外键缓存设置, primaryKey:{}, foreignKey:{}", primaryKey, foreignKey);
redisManager.sadd(foreignKey, primaryKey);
logger.info("结束外键缓存设置, primaryKey:{}, foreignKey:{}", primaryKey, foreignKey);
}
private void dealSpecialTable(String tableName, LinkedHashMap<String, Object> map) {
if(tableName.equals(TableEnum.T_FIELD.getTableName())){
String fieldEn = "field_en:" + map.get("organ_id") + ":" + map.get("field_en");
String fieldEnKey = RedisUtils.getPrimaryKey(tableName, fieldEn);
String fieldCn = "field_cn:" + map.get("organ_id") + ":" + map.get("field_cn");
String fieldCnKey = RedisUtils.getPrimaryKey(tableName, fieldCn);
for (String field : map.keySet()) {
String value = map.get(field) == null ? null : map.get(field).toString();
setColumnCache(fieldEnKey, field, value);
setColumnCache(fieldCnKey, field, value);
}
}
}
}

View File

@@ -0,0 +1,254 @@
package com.fibo.ddp.enginex.runner.canal;
import com.alibaba.otter.canal.client.CanalConnector;
import com.alibaba.otter.canal.client.CanalConnectors;
import com.alibaba.otter.canal.protocol.CanalEntry;
import com.alibaba.otter.canal.protocol.Message;
import com.fibo.ddp.common.dao.canal.TableEnum;
import com.fibo.ddp.common.service.redis.RedisManager;
import com.fibo.ddp.common.service.redis.RedisUtils;
import com.fibo.ddp.common.utils.constant.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.net.InetSocketAddress;
import java.util.List;
import java.util.Optional;
/**
* Canal数据同步
* 实现ApplicationRunner接口springboot启动成功后会执行run方法
*/
@Component
public class CanalClient implements ApplicationRunner {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final static int BATCH_SIZE = 1000;
@Autowired
private RedisManager redisManager;
// canal缓存同步是否开启
@Value("${switch.canal.cache}")
private String canalCacheSwitch;
// canal主机地址
@Value("${canal.hostname}")
private String canalHostName;
// canal端口
@Value("${canal.port}")
private int canalPort;
@Override
public void run(ApplicationArguments args) throws Exception {
if(Constants.switchFlag.OFF.equals(canalCacheSwitch)){
return;
}
// 创建链接
CanalConnector connector = CanalConnectors.newSingleConnector(
new InetSocketAddress(canalHostName, canalPort),
"example", "", "");
try {
//打开连接
connector.connect();
//订阅数据库表,全部表
connector.subscribe(".*\\..*");
//回滚到未进行ack的地方下次fetch的时候可以从最后一个没有ack的地方开始拿
connector.rollback();
while (true) {
logger.info("canal数据同步监听中...");
// 获取指定数量的数据
Message message = connector.getWithoutAck(BATCH_SIZE);
//获取批量ID
long batchId = message.getId();
//获取批量的数量
int size = message.getEntries().size();
//如果没有数据
if (batchId == -1 || size == 0) {
try {
//线程休眠2秒
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
//如果有数据,处理数据
printEntry(message.getEntries());
}
//进行 batch id 的确认。确认之后,小于等于此 batchId 的 Message 都会被确认。
connector.ack(batchId);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
connector.disconnect();
}
}
/**
* 解析binlog获得的实体类信息
*/
private void printEntry(List<CanalEntry.Entry> entrys) {
for (CanalEntry.Entry entry : entrys) {
if (entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONBEGIN || entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONEND) {
//开启/关闭事务的实体类型,跳过
continue;
}
String tableName = entry.getHeader().getTableName();
TableEnum tableEnum = TableEnum.getByTableName(tableName);
if(tableEnum == null){
// 没有在枚举中定义的表,跳过
continue;
}
//RowChange对象包含了一行数据变化的所有特征
//比如isDdl 是否是ddl变更操作 sql 具体的ddl sql beforeColumns afterColumns 变更前后的数据字段等等
CanalEntry.RowChange rowChage;
try {
rowChage = CanalEntry.RowChange.parseFrom(entry.getStoreValue());
} catch (Exception e) {
throw new RuntimeException("ERROR ## parser of eromanga-event has an error , data:" + entry.toString(), e);
}
//获取操作类型insert/update/delete类型
CanalEntry.EventType eventType = rowChage.getEventType();
//打印Header信息
logger.info(String.format("============= binlog[%s:%s] , name[%s,%s] , eventType : %s =============",
entry.getHeader().getLogfileName(), entry.getHeader().getLogfileOffset(),
entry.getHeader().getSchemaName(), entry.getHeader().getTableName(),
eventType));
//判断是否是DDL语句
if (rowChage.getIsDdl()) {
logger.info("============= isDdl: true,sql:" + rowChage.getSql());
}
//获取RowChange对象里的每一行数据
for (CanalEntry.RowData rowData : rowChage.getRowDatasList()) {
//如果是删除语句
if (eventType == CanalEntry.EventType.DELETE) {
row(rowData.getBeforeColumnsList(), tableName);
//如果是新增语句
} else if (eventType == CanalEntry.EventType.INSERT) {
row(rowData.getAfterColumnsList(), tableName);
//如果是更新的语句
} else {
//变更前的数据
// printColumn(rowData.getBeforeColumnsList(), tableName);
//变更后的数据
row(rowData.getAfterColumnsList(), tableName);
}
}
}
}
private void row(List<CanalEntry.Column> columns, String tableName) {
Optional<CanalEntry.Column> keyColumn = columns.stream().filter(item -> item.getIsKey()).findFirst();
if(keyColumn.isPresent()){
// 获取主键id
String id = keyColumn.get().getValue();
// 拼接主键key
String key = RedisUtils.getPrimaryKey(tableName, id);
// 拼接外键key
String foreignKey = null;
// 子表的redis key需要拼接上主表的id
TableEnum tableEnum = TableEnum.getByTableName(tableName);
if(tableEnum != null){
Optional<CanalEntry.Column> foreignKeyColumn = columns.stream().filter(item -> item.getName().equals(tableEnum.getForeignId())).findFirst();
if(foreignKeyColumn.isPresent()){
String foreignKeyValue = foreignKeyColumn.get().getValue();
foreignKey = RedisUtils.getForeignKey(tableName, foreignKeyValue);
}
}
for (CanalEntry.Column column : columns) {
// 更新发生改变的字段缓存
setUpdatedColumnCache(column, key, foreignKey);
}
// 指标表特殊处理
dealSpecialTable(columns, tableName);
}
}
private void setUpdatedColumnCache(CanalEntry.Column column, String key, String foreignKey){
if(column.getUpdated()) {
logger.info("开始主键缓存更新, {}, {}, {}", key, column.getName(), column.getValue());
redisManager.hset(key, column.getName(), column.getValue());
logger.info("结束主键缓存更新, {}, {}, {}", key, column.getName(), column.getValue());
if(foreignKey != null){
logger.info("开始外键缓存更新, {}, {}", key, foreignKey);
redisManager.sadd(foreignKey, key);
logger.info("结束外键缓存更新, {}, {}", key, foreignKey);
}
}
}
private void setAllColumnCache(CanalEntry.Column column, String key){
logger.info("开始主键缓存更新, {}, {}, {}", key, column.getName(), column.getValue());
redisManager.hset(key, column.getName(), column.getValue());
logger.info("结束主键缓存更新, {}, {}, {}", key, column.getName(), column.getValue());
}
private void dealSpecialTable(List<CanalEntry.Column> columns, String tableName){
if(tableName.equals(TableEnum.T_FIELD.getTableName())){
String organ_id = null;
String field_en = null;
String field_cn = null;
for (CanalEntry.Column column : columns) {
String name = column.getName();
switch (name) {
case "organ_id":
organ_id = column.getValue();
break;
case "field_en":
field_en = column.getValue();
break;
case "field_cn":
field_cn = column.getValue();
break;
default:
break;
}
}
String fieldEn = "field_en:" + organ_id + ":" + field_en;
String fieldEnKey = RedisUtils.getPrimaryKey(tableName, fieldEn);
String fieldCn = "field_cn:" + organ_id + ":" + field_cn;
String fieldCnKey = RedisUtils.getPrimaryKey(tableName, fieldCn);
// 如果field_en或field_cn发生变化则对应的key为新生成的需要保存所有字段缓存
Optional<CanalEntry.Column> fieldEnOptional = columns.stream().filter(item -> item.getName().equals("field_en") && item.getUpdated()).findFirst();
Optional<CanalEntry.Column> fieldCnOptional = columns.stream().filter(item -> item.getName().equals("field_cn") && item.getUpdated()).findFirst();
for (CanalEntry.Column column : columns) {
if(fieldEnOptional.isPresent()){
// 更新所有字段缓存
setAllColumnCache(column, fieldEnKey);
} else {
// 更新发生改变的字段缓存
setUpdatedColumnCache(column, fieldEnKey, null);
}
if(fieldCnOptional.isPresent()){
setAllColumnCache(column, fieldCnKey);
} else {
setUpdatedColumnCache(column, fieldCnKey, null);
}
}
}
}
}

View File

@@ -0,0 +1,60 @@
package com.fibo.ddp.enginex.runner.ksession;
import com.fibo.ddp.common.service.redis.RedisManager;
import org.apache.commons.pool2.BaseKeyedPooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.*;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* kSession工厂类
*/
@Component
public class KSessionFactory extends BaseKeyedPooledObjectFactory<String, StatefulKnowledgeSession> {
@Autowired
private RedisManager redisManager;
@Override
public StatefulKnowledgeSession create(String key) throws Exception {
StatefulKnowledgeSession kSession = null;
try {
String ruleString = redisManager.get(key);
if(ruleString == null){
throw new Exception("create kSession fail, key is "+ key + ", ruleString is null");
}
long start = System.currentTimeMillis();
KnowledgeBuilder kb = KnowledgeBuilderFactory.newKnowledgeBuilder();
kb.add(ResourceFactory.newByteArrayResource(ruleString.getBytes("utf-8")), ResourceType.DRL);
KnowledgeBuilderErrors errors = kb.getErrors();
for (KnowledgeBuilderError error : errors) {
System.out.println(error);
}
KnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase();
kBase.addKnowledgePackages(kb.getKnowledgePackages());
kSession = kBase.newStatefulKnowledgeSession();
long end = System.currentTimeMillis();
System.out.println("------------------drools kSession创建耗时" + (end - start) + " ----------------------");
} catch (Exception e) {
throw e;
}
return kSession;
}
@Override
public PooledObject<StatefulKnowledgeSession> wrap(StatefulKnowledgeSession kSession) {
return new DefaultPooledObject<StatefulKnowledgeSession>(kSession);
}
public void setRedisManager(RedisManager redisManager) {
this.redisManager = redisManager;
}
}

View File

@@ -0,0 +1,67 @@
package com.fibo.ddp.enginex.runner.ksession;
import org.apache.commons.pool2.impl.GenericKeyedObjectPool;
import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig;
import org.drools.runtime.StatefulKnowledgeSession;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* kSession连接池
*/
@Component
public class KSessionPool implements InitializingBean {
private GenericKeyedObjectPool<String, StatefulKnowledgeSession> pool;
@Autowired
private KSessionFactory kSessionFactory;
/**
* 初始化方法
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
initPool();
}
/**
* 初始化连接池
* @return
* @throws Exception
*/
public void initPool() throws Exception {
GenericKeyedObjectPoolConfig poolConfig = new GenericKeyedObjectPoolConfig();
poolConfig.setMaxTotalPerKey(200);
poolConfig.setMaxIdlePerKey(50);
poolConfig.setMinIdlePerKey(5);
poolConfig.setMaxTotal(2000);
this.pool = new GenericKeyedObjectPool(kSessionFactory, poolConfig);
}
/**
* 获取一个连接对象
* @return
* @throws Exception
*/
public StatefulKnowledgeSession borrowObject(String key) throws Exception {
return pool.borrowObject(key);
}
/**
* 归还一个连接对象
* @param ftpClient
*/
public void returnObject(String key, StatefulKnowledgeSession kSession) {
if(kSession != null){
pool.returnObject(key, kSession);
}
}
public void setkSessionFactory(KSessionFactory kSessionFactory) {
this.kSessionFactory = kSessionFactory;
}
}

View File

@@ -0,0 +1,26 @@
package com.fibo.ddp.enginex.runner.node;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import java.util.Map;
/**
* 引擎节点执行
*/
public interface EngineRunnerNode {
/**
* 获取节点所需的指标
* @param engineNode
* @param inputParam
*/
void getNodeField(EngineNode engineNode, Map<String, Object> inputParam);
/**
* 执行节点逻辑
* @param engineNode
* @param inputParam
* @param outMap
*/
void runNode(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap);
}

View File

@@ -0,0 +1,36 @@
package com.fibo.ddp.enginex.runner.node.impl;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.enginex.runner.node.EngineRunnerNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.Map;
/**
* 聚合节点
*/
@Service
public class AggregationNode implements EngineRunnerNode {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void getNodeField(EngineNode engineNode, Map<String, Object> inputParam) {
}
@Override
public void runNode(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap) {
logger.info("start【执行聚合节点】AggregationNode.runNode engineNode:{},inputParam:{},outMap:{}"
, JSONObject.toJSONString(engineNode), JSONObject.toJSONString(inputParam), JSONObject.toJSONString(outMap));
// 直接返回下一个节点
outMap.put("nextNode", engineNode.getNextNodes());
if (engineNode != null && engineNode.getSnapshot() != null) {
outMap.put("nodeSnapshot", engineNode.getSnapshot());
}
}
}

View File

@@ -0,0 +1,286 @@
package com.fibo.ddp.enginex.runner.node.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.dao.datax.datamanage.CustListMapper;
import com.fibo.ddp.common.dao.datax.datamanage.FieldMapper;
import com.fibo.ddp.common.dao.strategyx.listlibrary.TblColumnMapper;
import com.fibo.ddp.common.model.datax.datamanage.Field;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.model.strategyx.listlibrary.ListDb;
import com.fibo.ddp.common.model.strategyx.listlibrary.TblColumn;
import com.fibo.ddp.common.model.strategyx.strategyout.StrategyOutput;
import com.fibo.ddp.common.service.common.runner.RunnerSessionManager;
import com.fibo.ddp.common.service.common.runner.SessionData;
import com.fibo.ddp.common.service.datax.runner.CommonService;
import com.fibo.ddp.common.service.datax.runner.ExecuteUtils;
import com.fibo.ddp.common.service.strategyx.listlibrary.ListDbService;
import com.fibo.ddp.common.service.strategyx.strategyout.StrategyOutputService;
import com.fibo.ddp.common.utils.constant.strategyx.StrategyType;
import com.fibo.ddp.enginex.runner.node.EngineRunnerNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
@Service
public class BlackOrWhiteNode implements EngineRunnerNode {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private CommonService commonService;
@Autowired
private TblColumnMapper tblColumnMapper;
@Resource
private ListDbService listDbService;
@Resource
public FieldMapper fieldMapper;
@Resource
public CustListMapper custListMapper;
@Resource
private StrategyOutputService outputService;
private List<Long> getExecuteVersionIdList(EngineNode engineNode) {
return ExecuteUtils.getExecuteIdList(engineNode, "listDbId");
}
@Override
public void getNodeField(EngineNode engineNode, Map<String, Object> inputParam) {
List<Long> list = getExecuteVersionIdList(engineNode);
List<Long> fieldIds = new ArrayList<>();
for (Long l : list) {
fieldIds.addAll(listDbService.getNodeFieldIds(l));
}
commonService.getFieldByIds(fieldIds, inputParam);
}
@Override
public void runNode(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap) {
//监控中心-节点信息快照记录
if(engineNode!=null && engineNode.getNodeJson()!=null){
outMap.put("nodeSnapshot",engineNode.getNodeJson());
}
inputParam.put("nodeId", engineNode.getNodeId());
inputParam.put("nodeName", engineNode.getNodeName());
JSONObject nodeInfo = new JSONObject();
nodeInfo.put("engineNode", engineNode);
nodeInfo.put("nodeId", engineNode.getNodeId());
nodeInfo.put("nodeName", engineNode.getNodeName());
nodeInfo.put("nodeType", engineNode.getNodeType());
outMap.put("nodeInfo", nodeInfo);
//新代码
String hitKey = "" + engineNode.getNodeType() + "_" + engineNode.getNodeId() + "_size";
List<Long> list = getExecuteVersionIdList(engineNode);
List<ListDb> hitListDb = new ArrayList<>();
//创建内部多选的名单库结果数组
JSONArray resultJsonArray = new JSONArray();
JSONArray strategySnapshot = new JSONArray();
for (Long id : list) {
ListDb listDb = listDbService.queryById(id);
//监控中心 == 策略层面快照信息
if (listDb != null && listDb.getSnapshot() != null) {
strategySnapshot.add(listDb.getSnapshot());
}
boolean isfalg = this.executeListDb(listDb, inputParam, outMap,resultJsonArray);
if (isfalg) {
hitListDb.add(listDb);
}
}
//监控中心==》策略层面快照信息记录
outMap.put("strategySnapshot",strategySnapshot);
//构造节点信息
JSONObject jsonObject = new JSONObject();
jsonObject.put("nodeId", engineNode.getNodeId());
jsonObject.put("nodeName", engineNode.getNodeName());
jsonObject.put("resultList", resultJsonArray);
//判断是否出现过同类型的,如果出现过则获取并且增加内容,如果没有则需要构建名单库类型的节点信息
if (outMap.containsKey("blackJson")) {
//如果出现过黑名单则从黑名单接送中获取
JSONObject blackJson = (JSONObject) outMap.get("blackJson");
JSONArray resultJson = blackJson.getJSONArray("resultJson");
resultJson.add(jsonObject);
} else {
JSONObject nodeResult = new JSONObject();
nodeResult.put("resultType", 5);
JSONArray resultJson = new JSONArray();
resultJson.add(jsonObject);
nodeResult.put("resultJson",resultJson);
outMap.put("blackJson", nodeResult);
}
// nodeResult.put("resultJson", resultJsonArray);
// outMap.put("blackJson", nodeResult);
// outMap.put("nodeResult", nodeResult);
inputParam.put(hitKey, hitListDb.size());
//处理终止条件判断中选择的名单库
long count = handlerResultCount(engineNode, hitListDb);
this.terminalCondition(engineNode, inputParam, outMap, count);
}
private boolean executeListDb(ListDb listDb, Map<String, Object> inputParam, Map<String, Object> outMap,JSONArray resultJsonArray) {
SessionData sessionData = RunnerSessionManager.getSession();
Long organId = sessionData.getOrganId();
JSONObject resultJson = new JSONObject();
Integer matchs = 0;
Integer revMatchs = 0; //模糊查询时反向匹配
// JSONArray strategySnopshot = new JSONArray();
Long listDbId = listDb.getId();
// if (listDb.getSnapshot() != null) {
//
// strategySnopshot.add(listDb.getSnapshot());
// }
inputParam.put("listDb", listDb);
ListDb version = listDb;
String queryKeyArray[] = listDb.getQueryField().split(",");
if (queryKeyArray.length > 0) {
Integer queryType = version.getQueryType();//and1or0
Integer matchType = version.getMatchType();//精确匹配1模糊匹配0
String queryKey = ""; // t1 like '%t1%'
String revQueryKey = ""; // 反向模糊匹配 instr('高档洗浴消费',t1) t1行业字段 eg.'洗浴'
String tableName = "organ" + "_" + organId + "_" + listDb.getListType() + "_" + listDbId;
inputParam.put("tableName", tableName);
inputParam.put("schemaName", getDbName());
//获取名单库的匿名字段与注释的关系
List<TblColumn> columnList = tblColumnMapper.getColumnList(inputParam);
//字段id转匿名字段名准备待查字段条件
Integer loc = 0;
List<String> tableColumn = Arrays.asList(version.getTableColumn().split(","));
int k = 0;
for (int j = 0; j < queryKeyArray.length; j++) {
k = tableColumn.indexOf(queryKeyArray[j]);
if (k < 0) {
continue;
}
Field field = fieldMapper.selectById(queryKeyArray[j]);
String fieldEn = field.getFieldEn(); //age
String columnKey = "t" + k;
for (TblColumn tblColumn : columnList) {
String colName = tblColumn.getColName(); //t5
String paramValue = inputParam.get(fieldEn).toString();
if (columnKey.equals(colName)) {
if (paramValue == null || paramValue.equals("")) {
continue ; //数据项缺失导致无法命中,默认返回没命中
} else {
loc += 1;
if (matchType == 1) {
if (loc > 1 && queryType == 1) {
queryKey += " and ";
} else if (loc > 1 && queryType == 0) {
queryKey += " or ";
}
queryKey += colName + " = '" + paramValue + "'";
} else if (matchType == 0) { //模糊匹配
if (loc > 1 && queryType == 1) {
queryKey += " and ";
} else if (loc > 1 && queryType == 0) {
queryKey += " or ";
revQueryKey += " + ";
}
//正向模糊搜索
queryKey += colName + " like " + "'%" + paramValue + "%'"; // t5 like '%36岁%'
//反向模糊搜索
revQueryKey += "max(instr('" + paramValue + "'," + colName + "))";
}
}
}
}
}
inputParam.put("queryKey", queryKey);
inputParam.put("revQueryKey", revQueryKey);
}
matchs += custListMapper.findByQueryKey(inputParam);
if (!"".equals(inputParam.get("revQueryKey"))) {
revMatchs = custListMapper.revFindByQueryKey(inputParam);
}
if (revMatchs == null){
revMatchs = 0;
}
inputParam.put(listDb.getResultFieldEn(), "未命中");
List<JSONObject> fieldList = new ArrayList<>();
JSONObject hitResult = new JSONObject();
hitResult.put(listDb.getResultFieldEn(), "未命中");
// resultJson.put("nodeId", inputParam.get("nodeId").toString());
// resultJson.put("nodeName", inputParam.get("nodeName").toString());
resultJson.put("listDbId", listDb.getId());
resultJson.put("listDbName", listDb.getListName());
resultJson.put("listDbType", listDb.getListType());
if (null != listDb.getListDesc()) {
resultJson.put("desc", listDb.getListDesc());
}
resultJson.put("fieldList", fieldList);
resultJsonArray.add(resultJson);
if (matchs + revMatchs > 0) {
inputParam.put(listDb.getResultFieldEn(), "命中");
hitResult.put(listDb.getResultFieldEn(), "命中");
List<JSONObject> jsonObjects = outputService.setOutput(new StrategyOutput(Long.valueOf(listDbId.toString()), StrategyType.LIST_DB), inputParam);
fieldList.add(hitResult);
fieldList.addAll(jsonObjects);
// outMap.put("black", listDb);
return true;
} else {
fieldList.add(hitResult);
}
//监控中心==》策略层面记录策略的快照信息
// JSONObject strategyObject = new JSONObject();
// strategyObject.put("strategySnopshot", strategySnopshot);
// outMap.put("strategySnopshot", strategyObject);
return false;
}
/**
* 根据传入数据监测是否命中黑名单
*
* @param paramMap
* @return
* @see
*/
public boolean findByQueryKey(Map<String, Object> paramMap, Map<String, Object> outmap, Integer type, EngineNode engineNode) {
return false;
}
private String getDbName() {
return "riskmanage";
}
private long handlerResultCount(EngineNode engineNode,List<ListDb> hitListDb){
JSONObject jsonObject = JSON.parseObject(engineNode.getNodeJson());
JSONArray selectedRule = jsonObject.getJSONObject("terminationInfo").getJSONArray("selectedRule");
List<Long> selectedListDbIds = new ArrayList<>();
if (selectedRule!=null&&selectedRule.size()>0){
for (Object o : selectedRule) {
if (o==null){
continue;
}
Long id = JSON.parseObject(JSON.toJSONString(o)).getLong("id");
if (id==null){
continue;
}
selectedListDbIds.add(id);
}
}
long count = hitListDb.stream().filter(item -> selectedListDbIds.contains(item.getId())).count();
return count;
}
private void terminalCondition(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap, Object executeResult) {
String sizeKey = engineNode.getNodeType() + "_" + engineNode.getNodeId() + "_terminal_size";
Map<String, Object> map = new HashMap<>();
map.put(sizeKey, executeResult);
ExecuteUtils.terminalCondition(engineNode, inputParam, outMap, map);
}
}

View File

@@ -0,0 +1,44 @@
package com.fibo.ddp.enginex.runner.node.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.enginex.runner.node.EngineRunnerNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.Map;
/**
* 冠军挑战节点
*/
@Service
public class ChampionChallengeNode implements EngineRunnerNode {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void getNodeField(EngineNode engineNode, Map<String, Object> inputParam) {
}
@Override
public void runNode(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap) {
logger.info("start【执行冠军挑战节点】ChampionChallengeNode.runNode engineNode:{},inputParam:{},outMap:{}"
, JSONObject.toJSONString(engineNode), JSONObject.toJSONString(inputParam), JSONObject.toJSONString(outMap));
if (engineNode != null && engineNode.getSnapshot() != null) {
outMap.put("nodeSnapshot", engineNode.getSnapshot());
}
JSONArray jsonArray = JSONArray.parseArray(engineNode.getNodeJson());
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
int champion = jsonObject.getIntValue("champion");
// 返回冠军分支对应的下一个节点
if(champion == 1){
outMap.put("nextNode", jsonObject.getString("nextNode"));
break;
}
}
}
}

View File

@@ -0,0 +1,82 @@
package com.fibo.ddp.enginex.runner.node.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.model.enginex.risk.Engine;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.service.common.runner.RunnerSessionManager;
import com.fibo.ddp.common.service.common.runner.SessionData;
import com.fibo.ddp.common.service.enginex.risk.EngineService;
import com.fibo.ddp.enginex.runner.node.EngineRunnerNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class ChildEngineNode implements EngineRunnerNode {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
// @Autowired
// private EngineApiService engineApiService;
@Autowired
public EngineService engineService;
@Override
public void getNodeField(EngineNode engineNode, Map<String, Object> inputParam) {
}
@Override
public void runNode(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap) {
SessionData sessionData = RunnerSessionManager.getSession();
Long organId = sessionData.getOrganId();
Integer reqType = sessionData.getReqType();
Long childEngineId = Long.valueOf(engineNode.getNodeJson());
Map<String, Object> map = new HashMap<>();
map.put("fields",inputParam);
map.put("engineId", childEngineId);
map.put("organId",organId);
map.put("reqType",reqType);
// String result = engineApiService.engineApi(map);
String result = null;
String engineResult = "";
JSONObject jsonObject = JSONObject.parseObject(result);
if (jsonObject.getString("status").equals("0x0000")&&jsonObject.getString("result")!=null) {
engineResult = jsonObject.getString("result");
} else {
logger.error("子引擎执行失败, childEngineId:{},result:{}", childEngineId, result);
}
Engine engineVo = engineService.getEngineById(childEngineId);
//监控中心--节点信息记录(不需要监控策略层面的监控)
outMap.put("nodeSnapshot",engineVo);
JSONObject nodeInfo = new JSONObject();
nodeInfo.put("engineNode",engineNode);
nodeInfo.put("nodeId",engineNode.getNodeId());
nodeInfo.put("nodeName",engineNode.getNodeName());
nodeInfo.put("nodeType",engineNode.getNodeType());
outMap.put("nodeInfo",nodeInfo);
jsonObject.put("nodeId", engineNode.getNodeId());
jsonObject.put("nodeName", engineNode.getNodeName());
jsonObject.put("engineId", engineVo.getId());
jsonObject.put("engineName", engineVo.getName());
//监控中心====》输出结果写入Hbase
outMap.put("nodeResult",jsonObject);
if (outMap.containsKey("childEngineJson")) {
JSONArray resultJson = (JSONArray) outMap.get("childEngineJson");
resultJson.add(jsonObject);
} else {
JSONArray resultJson = new JSONArray();
resultJson.add(jsonObject);
outMap.put("childEngineJson", resultJson);
}
String key = engineNode.getNodeType() + "_" + engineNode.getNodeId() + "_" + engineNode.getNodeJson() + "_result";
inputParam.put(key, engineResult);
}
}

View File

@@ -0,0 +1,144 @@
package com.fibo.ddp.enginex.runner.node.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.service.datax.runner.CommonService;
import com.fibo.ddp.common.utils.util.runner.JevalUtil;
import com.fibo.ddp.common.utils.util.runner.jeval.EvaluationException;
import com.fibo.ddp.enginex.runner.node.EngineRunnerNode;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 决策选项节点
*/
@Service
public class DecisionOptionsNode implements EngineRunnerNode {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private CommonService commonService;
@Override
public void getNodeField(EngineNode engineNode, Map<String, Object> inputParam) {
logger.info("start【获取决策选项节点指标】DecisionOptionsNode.getNodeField engineNode:{},inputParam:{}", JSONObject.toJSONString(engineNode), JSONObject.toJSONString(inputParam));
JSONObject jsonObject = JSONObject.parseObject(engineNode.getNodeScript());
JSONArray array = jsonObject.getJSONArray("input");
List<Long> ids = new ArrayList<>();
for (int i = 0; i < array.size(); i++) {
JSONObject input = array.getJSONObject(i);
Object fieldId = input.get("field_id");
if(fieldId != null && !"".equals(fieldId.toString())){
ids.add(Long.valueOf(fieldId.toString()));
}
}
commonService.getFieldByIds(ids, inputParam);
}
@Override
public void runNode(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap) {
//监控信息--节点信息记录(不需要策略层面的监控)
outMap.put("nodeSnapshot",JSON.parseObject(engineNode.getNodeJson()));
JSONObject nodeInfo = new JSONObject();
nodeInfo.put("engineNode",engineNode);
nodeInfo.put("nodeId",engineNode.getNodeId());
nodeInfo.put("nodeName",engineNode.getNodeName());
nodeInfo.put("nodeType",engineNode.getNodeType());
outMap.put("nodeInfo",nodeInfo);
JSONObject jsonObject = JSONObject.parseObject(engineNode.getNodeScript());
JSONArray inputArray = jsonObject.getJSONArray("input");
List<JSONObject> inputList = JSONObject.parseArray(JSONObject.toJSONString(jsonObject.getJSONArray("input")), JSONObject.class);
JSONArray conditionArray = jsonObject.getJSONArray("conditions");
JSONObject outputJson = jsonObject.getJSONObject("output");
// 变量值转义
Map<String, Object> variablesMap = new HashMap<>();
for (int i = 0; i < inputArray.size(); i++) {
String input = inputArray.get(i).toString();
JSONObject inputField = JSONObject.parseObject(input);
String field_code = inputField.getString("field_code");
Map<String, Integer> fieldsMap = new HashMap<>();
fieldsMap.put(field_code, inputField.getInteger("valueType"));
variablesMap.put(field_code, inputParam.get(field_code));
variablesMap = JevalUtil.convertVariables(fieldsMap, variablesMap);
}
// 默认值处理
String dicisionResult ="";
String defaultValue = outputJson.getString("defaultValue");
if (StringUtils.isNotBlank(defaultValue)){
dicisionResult = defaultValue;
}
// 决策条件判断
if(conditionArray != null && conditionArray.size() > 0){
for (int i = 0; i < conditionArray.size(); i++) {
JSONObject formulaJson = JSONObject.parseObject(conditionArray.getString(i));
try {
boolean outfieldvalue = JevalUtil.evaluateBoolean(formulaJson.getString("formula"), variablesMap);
if (outfieldvalue) {
dicisionResult = formulaJson.getString("result");
// 输出结果计算
String result = formulaJson.getString("result");
if(result.contains("{") && result.contains("}")){
String expression = result;
Pattern pattern = Pattern.compile("\\{[a-zA-Z0-9_\u4e00-\u9fa5()-]+\\}");
Matcher matcher = pattern.matcher(expression);
while (matcher.find()) {
String asName = matcher.group(0).replace("{", "").replace("}", "");
Optional<JSONObject> inputObj = inputList.stream().filter(item -> asName.equals(item.getString("asName"))).findFirst();
if(inputObj.isPresent()){
String field_code = inputObj.get().getString("field_code");
expression = expression.replaceAll(asName, field_code);
}
}
expression = expression.replaceAll("\\{", "#{");
Double calResult = JevalUtil.evaluateNumric(expression, variablesMap);
dicisionResult = calResult.toString();
}
break;
}
} catch (EvaluationException e) {
e.printStackTrace();
logger.error("请求异常", e);
}
}
}
Map<String, Object> outFields = new HashMap<>();
String outputFieldCode = outputJson.getString("field_code");
outFields.put("fieldId", outputJson.getIntValue("field_id"));
outFields.put("fieldName", outputJson.getString("field_name"));
outFields.put("fieldCode", outputFieldCode);
outFields.put("outValue", dicisionResult);
outMap.put("result", dicisionResult);
String key = engineNode.getNodeType() + "_" + engineNode.getNodeId() + "_result";
inputParam.put(key, dicisionResult);
inputParam.put(outputFieldCode, dicisionResult);
JSONObject json = new JSONObject();
json.put("nodeId", engineNode.getNodeId());
json.put("nodeName", engineNode.getNodeName());
json.put("outFields", JSONObject.parseObject(JSON.toJSONString(outFields)));
//监控中心===》hbase中写入结果信息
outMap.put("nodeResult",json);
if (outMap.containsKey("decisionJson")) {
JSONArray resultJson = (JSONArray) outMap.get("decisionJson");
resultJson.add(json);
} else {
JSONArray resultJson = new JSONArray();
resultJson.add(json);
outMap.put("decisionJson", resultJson);
}
}
}

View File

@@ -0,0 +1,385 @@
package com.fibo.ddp.enginex.runner.node.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.model.enginex.risk.InputParam;
import com.fibo.ddp.common.model.enginex.risk.Result;
import com.fibo.ddp.common.model.enginex.runner.ExpressionParam;
import com.fibo.ddp.common.model.strategyx.decisiontable.DecisionTablesDetailCondition;
import com.fibo.ddp.common.model.strategyx.decisiontable.vo.DecisionTablesDetailVo;
import com.fibo.ddp.common.model.strategyx.decisiontable.vo.DecisionTablesResultVo;
import com.fibo.ddp.common.model.strategyx.decisiontable.vo.DecisionTablesVersionVo;
import com.fibo.ddp.common.model.strategyx.decisiontable.vo.DecisionTablesVo;
import com.fibo.ddp.common.service.datax.runner.CommonService;
import com.fibo.ddp.common.service.datax.runner.ExecuteUtils;
import com.fibo.ddp.common.service.redis.RedisManager;
import com.fibo.ddp.common.service.strategyx.decisiontable.DecisionTablesDetailService;
import com.fibo.ddp.common.service.strategyx.decisiontable.DecisionTablesService;
import com.fibo.ddp.common.service.strategyx.decisiontable.impl.DecisionTablesServiceImpl;
import com.fibo.ddp.common.utils.common.MD5;
import com.fibo.ddp.common.utils.constant.CommonConst;
import com.fibo.ddp.enginex.runner.ksession.KSessionPool;
import com.fibo.ddp.enginex.runner.node.EngineRunnerNode;
import org.apache.commons.lang3.StringUtils;
import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.rule.FactHandle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@Service
public class DecisionTablesNode implements EngineRunnerNode {
private static final Logger logger = LoggerFactory.getLogger(DecisionTablesServiceImpl.class);
@Resource
private RedisManager redisManager;
@Autowired
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Autowired
private KSessionPool kSessionPool;
@Resource
private DecisionTablesService decisionTablesService;
@Autowired
private DecisionTablesDetailService detailService;
@Autowired
private CommonService commonService;
private List<Long> getExecuteVersionIdList(EngineNode engineNode) {
return ExecuteUtils.getExecuteIdList(engineNode, "versionId");
}
@Override
public void getNodeField(EngineNode engineNode, Map<String, Object> inputParam) {
try {
List<Long> versionIdList = getExecuteVersionIdList(engineNode);
//获取决策表节点的字段id
List<Long> ids = new ArrayList<>();
for (Long versionId : versionIdList) {
ids.addAll(detailService.queryFieldIdByDecisionTablesVersionId(versionId));
}
commonService.getFieldByIds(ids, inputParam);
} catch (Exception e) {
logger.error("【DecisionTablesNode】,getNodeField:获取决策表指标异常");
}
}
@Override
public void runNode(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap) {
//监控中心-节点信息快照记录
if (engineNode != null && engineNode.getNodeJson() != null) {
outMap.put("nodeSnapshot", engineNode.getNodeJson());
}
List<Long> versionIdList = getExecuteVersionIdList(engineNode);
JSONObject nodeInfo = new JSONObject();
nodeInfo.put("engineNode", engineNode);
nodeInfo.put("nodeId", engineNode.getNodeId());
nodeInfo.put("nodeName", engineNode.getNodeName());
nodeInfo.put("nodeType", engineNode.getNodeType());
outMap.put("nodeInfo", nodeInfo);
JSONArray strategySnapshot = new JSONArray();
for (Long versionId : versionIdList) {
//获取决策表decisionTablesVo
DecisionTablesVo decisionTablesVo = decisionTablesService.queryByVersionId(versionId);
//监控中心==策略层面快照信息记录
if (decisionTablesVo.getExecuteVersion().getSnapshot() != null) {
strategySnapshot.add(decisionTablesVo.getExecuteVersion().getSnapshot());
}
DecisionTablesVersionVo version = decisionTablesVo.getExecuteVersion();
//获取存放决策表执行结果的变量
String resultFieldEn = version.getResultFieldEn();
//执行决策表
Object executeResult = this.executeDecisionTables(version, inputParam);
//处理结果
JSONObject jsonObject = new JSONObject();
jsonObject.put("nodeId", engineNode.getNodeId());
jsonObject.put("nodeName", engineNode.getNodeName());
jsonObject.put("decisionTablesId", decisionTablesVo.getId());
jsonObject.put("decisionTablesName", decisionTablesVo.getName());
jsonObject.put("desc", version.getDescription());
jsonObject.put("versionId", version.getId());
jsonObject.put("versionCode", version.getVersionCode());
if (executeResult != null) {
jsonObject.put("result", executeResult);
JSONObject resultField = new JSONObject();
resultField.put(resultFieldEn, executeResult);
//将执行结果按照固定格式存入参数map以供后续节点使用.
// inputParam.put("decisionTable_"+decisionTablesId+"_"+engineNode.getNodeId(),executeResult);
inputParam.put(resultFieldEn, executeResult);
List<JSONObject> fieldList = new ArrayList<>();
fieldList.add(resultField);
//处理自定义输出
List<JSONObject> jsonObjects = decisionTablesService.setOutput(versionId, inputParam);
fieldList.addAll(jsonObjects);
jsonObject.put("fieldList", fieldList);
} else {
jsonObject.put("result", "");
// inputParam.put("decisionTable_"+decisionTablesId+"_"+engineNode.getNodeId(),"");
inputParam.put(resultFieldEn, "");
}
//将执行结果存入最终返回值
if (outMap.containsKey("decisionTablesJson")) {
JSONArray resultJson = (JSONArray) outMap.get("decisionTablesJson");
resultJson.add(jsonObject);
//监控中心==》将执行结果写入Hbase
JSONObject nodeResult = new JSONObject();
nodeResult.put("result", resultJson);
outMap.put("nodeResult", nodeResult);
} else {
JSONArray resultJson = new JSONArray();
resultJson.add(jsonObject);
outMap.put("decisionTablesJson", resultJson);
//监控中心==》将执行结果写入Hbase
JSONObject nodeResult = new JSONObject();
nodeResult.put("result", resultJson);
outMap.put("nodeResult", nodeResult);
}
terminalCondition(engineNode, inputParam, outMap, executeResult);
}
//监控中心==》策略层面快照信息记录
JSONObject jsonObject = new JSONObject();
jsonObject.put("snapshot", strategySnapshot);
outMap.put("decisionTableStrategy", jsonObject);
}
//执行整个决策表返回决策结果数据
public Object executeDecisionTables(DecisionTablesVersionVo versionVo, Map<String, Object> inputParam) {
Future<Integer> top = null;
Future<Integer> left = null;
//取出行列索引
Integer row = -1;
Integer column = -1;
List<DecisionTablesDetailVo> leftDetailVo = versionVo.getLeftDetailVo();
if (CollectionUtils.isEmpty(leftDetailVo)
|| (leftDetailVo.size() == 1
&& StringUtils.isBlank(leftDetailVo.get(0).getFieldEn())
&& CollectionUtils.isEmpty(leftDetailVo.get(0).getChildren()))) {
row = 0;
} else {
//左侧执行
left = threadPoolTaskExecutor.submit(new Callable<Integer>() {
@Override
public Integer call() {
return executeDecisionTablesDetail(versionVo.getLeftDetailVo(), inputParam);
}
});
}
//右侧执行
List<DecisionTablesDetailVo> topDetailVo = versionVo.getTopDetailVo();
if (CollectionUtils.isEmpty(topDetailVo)
|| (topDetailVo.size() == 1
&& StringUtils.isBlank(topDetailVo.get(0).getFieldEn())
&& CollectionUtils.isEmpty(topDetailVo.get(0).getChildren()))) {
column = 0;
} else {
top = threadPoolTaskExecutor.submit(new Callable<Integer>() {
@Override
public Integer call() {
return executeDecisionTablesDetail(versionVo.getTopDetailVo(), inputParam);
}
});
}
try {
if (row == -1) {
row = left.get();
}
if (column == -1) {
column = top.get();
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
//行列值均取到的进行处理
if (row >= 0 && column >= 0) {
//根据行列去结果集中找结果返回
DecisionTablesResultVo resultSet = versionVo.getResultSet();
if (row < resultSet.getRows() && column < resultSet.getColumns()) {
String resultValue = resultSet.getResultValue();
JSONArray array = JSON.parseArray(resultValue);
JSONArray rowArray = JSON.parseArray(JSON.toJSONString(array.get(row)));
return rowArray.get(column);
}
}
return null;
}
//执行决策表的条件获取
public Integer executeDecisionTablesDetail(List<DecisionTablesDetailVo> decisionTablesDetailList, Map<String, Object> paramMap) {
for (DecisionTablesDetailVo decisionTablesDetailVo : decisionTablesDetailList) {
//调用drools执行
// int result = recursionExecuteDecisionTablesDetail(decisionTablesDetailVo, paramMap);
//调用不使用drools执行
int result = executeDecisionTablesDetail(decisionTablesDetailVo, paramMap);
if (result >= 0) {
return result;
}
}
return -1;
}
//执行决策表详情得出位置坐标:drools执行
public int recursionExecuteDecisionTablesDetail(DecisionTablesDetailVo decisionTablesDetailVo, Map<String, Object> paramMap) {
StatefulKnowledgeSession kSession = null;
String keyMd5 = null;
try {
//解析content
String ruleString = decisionTablesDetailVo.getContent().replace("\\r\\n", "\r\n");
ruleString = ruleString.replace("\\t", "\t");
keyMd5 = CommonConst.DROOLS_KSESSION_KEY_PREFIX + MD5.GetMD5Code(ruleString);
redisManager.set(keyMd5, ruleString, 120);
//drools执行
kSession = kSessionPool.borrowObject(keyMd5);
List<Result> resultList = new ArrayList<>();
InputParam inputParam = new InputParam();
inputParam.setInputParam(paramMap);
inputParam.setResult(resultList);
FactHandle fact = kSession.insert(inputParam);
kSession.fireAllRules();
kSession.retract(fact);
//获取执行结果对结果进行分析。
List<Result> results = inputParam.getResult();
Map<String, Object> resultMap = new HashMap<>();
if (results != null && results.size() > 0 && results.get(0) != null && results.get(0).getMap() != null) {
resultMap = inputParam.getResult().get(0).getMap();
}
//本节点命中后处理
if (resultMap.containsKey("result")) {
Integer type = decisionTablesDetailVo.getType();
List<DecisionTablesDetailVo> children = decisionTablesDetailVo.getChildren();
if (type != null) {
switch (type) {
//普通节点符合,让子节点继续执行。
case 1:
if (children != null && children.size() > 0) {
for (DecisionTablesDetailVo child : children) {
int result = this.recursionExecuteDecisionTablesDetail(child, paramMap);
if (result >= 0) {
return result;
}
}
}
break;
//叶子节点符合,返回叶子节点的值。
case 2:
return decisionTablesDetailVo.getIndexValue();
default:
break;
}
}
}
} catch (Exception e) {
e.printStackTrace();
logger.error("请求异常", e);
} finally {
if (keyMd5 != null && kSession != null) {
kSessionPool.returnObject(keyMd5, kSession);
}
}
//执行至此则不命中。
return -1;
}
//不使用drools的执行
private int executeDecisionTablesDetail(DecisionTablesDetailVo decisionTablesDetailVo, Map<String, Object> paramMap) {
//获取需要执行的条件列表
List<DecisionTablesDetailCondition> conditionList = decisionTablesDetailVo.getConditionList();
String fieldEn = decisionTablesDetailVo.getFieldEn();
String logical = decisionTablesDetailVo.getLogical();
boolean result = false;
//根据不通关系进行处理
switch (logical) {
case "||":
result = false;
for (DecisionTablesDetailCondition condition : conditionList) {
ExpressionParam expressionParam = new ExpressionParam();
BeanUtils.copyProperties(condition, expressionParam);
expressionParam.setFieldEn(fieldEn);
try {
boolean expressionResult = ExecuteUtils.getExpressionResult(expressionParam, paramMap);
if (expressionResult) {
result = true;
break;
}
}catch (Throwable e){
logger.error("【DecisionTablesNode】runNode执行异常expressionParam{}",expressionParam);
result = false;
break;
}
}
break;
case "&&":
result = true;
for (DecisionTablesDetailCondition condition : conditionList) {
ExpressionParam expressionParam = new ExpressionParam();
BeanUtils.copyProperties(condition, expressionParam);
expressionParam.setFieldEn(fieldEn);
try {
boolean expressionResult = ExecuteUtils.getExpressionResult(expressionParam, paramMap);
if (!expressionResult) {
result = false;
break;
}
}catch (Throwable e){
logger.error("【DecisionTablesNode】runNode执行异常expressionParam{}",expressionParam);
result = false;
break;
}
}
break;
}
//如果本节点符合则执行后续节点
if (result) {
Integer type = decisionTablesDetailVo.getType();
List<DecisionTablesDetailVo> children = decisionTablesDetailVo.getChildren();
if (type != null) {
switch (type) {
//普通节点符合,让子节点继续执行。
case 1:
if (children != null && children.size() > 0) {
for (DecisionTablesDetailVo child : children) {
int executeResult = this.executeDecisionTablesDetail(child, paramMap);
if (executeResult >= 0) {
return executeResult;
}
}
}
break;
//叶子节点符合,返回叶子节点的值。
case 2:
return decisionTablesDetailVo.getIndexValue();
default:
break;
}
}
}
return -1;
}
private void terminalCondition(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap, Object executeResult) {
String resultKey = engineNode.getNodeType() + "_" + engineNode.getNodeId() + "_terminal_result";
Map<String, Object> map = new HashMap<>();
map.put(resultKey, executeResult);
ExecuteUtils.terminalCondition(engineNode, inputParam, outMap, map);
}
}

View File

@@ -0,0 +1,215 @@
package com.fibo.ddp.enginex.runner.node.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.model.enginex.runner.ExpressionParam;
import com.fibo.ddp.common.model.strategyx.decisiontree.DecisionTreeDetail;
import com.fibo.ddp.common.model.strategyx.decisiontree.DecisionTreeDetailCondition;
import com.fibo.ddp.common.model.strategyx.decisiontree.vo.DecisionTreeVersionVo;
import com.fibo.ddp.common.model.strategyx.decisiontree.vo.DecisionTreeVo;
import com.fibo.ddp.common.service.datax.runner.CommonService;
import com.fibo.ddp.common.service.datax.runner.ExecuteUtils;
import com.fibo.ddp.common.service.strategyx.decisiontree.DecisionTreeService;
import com.fibo.ddp.enginex.runner.node.EngineRunnerNode;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class DecisionTreeNode implements EngineRunnerNode {
@Autowired
private DecisionTreeService decisionTreeService;
@Autowired
private CommonService commonService;
private List<Long> getExecuteVersionIdList(EngineNode engineNode){
return ExecuteUtils.getExecuteIdList(engineNode,"versionId");
}
@Override
public void getNodeField(EngineNode engineNode, Map<String, Object> inputParam) {
List<Long> list = getExecuteVersionIdList(engineNode);
List<Long> fieldIds = new ArrayList<>();
for (Long l : list) {
fieldIds.addAll(decisionTreeService.getNodeFieldIds(l));
}
commonService.getFieldByIds(fieldIds,inputParam);
}
@Override
public void runNode(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap) {
//监控中心--记录节点快照信息
if (engineNode != null && engineNode.getSnapshot() != null) {
outMap.put("nodeSnapshot", engineNode.getSnapshot());
}
List<Long> list = getExecuteVersionIdList(engineNode);
JSONObject nodeInfo = new JSONObject();
nodeInfo.put("engineNode", engineNode);
nodeInfo.put("nodeId", engineNode.getNodeId());
nodeInfo.put("nodeName", engineNode.getNodeName());
nodeInfo.put("nodeType", engineNode.getNodeType());
outMap.put("nodeInfo", nodeInfo);
JSONArray strategySnapshot = new JSONArray();
for (Long versionId : list) {
DecisionTreeVo decisionTreeVo = decisionTreeService.queryExecuteDecisionTree(null, versionId);
if (decisionTreeVo == null) {
continue;
}
//监控中心==策略层面快照信息记录
if(decisionTreeVo.getExecuteVersion().getSnapshot()!=null){
strategySnapshot.add(decisionTreeVo.getExecuteVersion().getSnapshot());
}
DecisionTreeVersionVo version = decisionTreeVo.getExecuteVersion();
String resultFieldEn = version.getResultFieldEn();
//执行决策表
Object executeResult = this.executeDecisionTree(version, inputParam);
//处理结果
JSONObject jsonObject = new JSONObject();
jsonObject.put("nodeId", engineNode.getNodeId());
jsonObject.put("nodeName", engineNode.getNodeName());
jsonObject.put("decisionTreeId", decisionTreeVo.getId());
jsonObject.put("decisionTreeName", decisionTreeVo.getName());
jsonObject.put("desc", version.getDescription());
jsonObject.put("versionId", version.getId());
jsonObject.put("versionCode", version.getVersionCode());
if (executeResult != null) {
jsonObject.put("result", executeResult);
JSONObject resultField = new JSONObject();
resultField.put(resultFieldEn, executeResult);
inputParam.put(resultFieldEn, executeResult);
List<JSONObject> fieldList = new ArrayList<>();
fieldList.add(resultField);
//处理自定义输出
List<JSONObject> jsonObjects = decisionTreeService.setOutput(versionId, inputParam);
fieldList.addAll(jsonObjects);
jsonObject.put("fieldList", fieldList);
} else {
jsonObject.put("result", "");
inputParam.put(resultFieldEn, "");
}
//将执行结果存入最终返回值
if (outMap.containsKey("decisionTreeJson")) {
JSONArray resultJson = (JSONArray) outMap.get("decisionTreeJson");
resultJson.add(jsonObject);
//监控中心==》将执行结果写入Hbase
JSONObject nodeResult = new JSONObject();
nodeResult.put("result", resultJson);
outMap.put("nodeResult", nodeResult);
} else {
JSONArray resultJson = new JSONArray();
resultJson.add(jsonObject);
outMap.put("decisionTreeJson", resultJson);
//监控中心==》将执行结果写入Hbase
JSONObject nodeResult = new JSONObject();
nodeResult.put("result", resultJson);
outMap.put("nodeResult", nodeResult);
}
terminalCondition(engineNode,inputParam,outMap,executeResult);
}
//监控中心==》策略层面快照信息记录
JSONObject jsonObject = new JSONObject();
jsonObject.put("snapshot",strategySnapshot);
outMap.put("decisionTreeStrategy",jsonObject);
}
private Object executeDecisionTree(DecisionTreeVersionVo version, Map<String, Object> inputParam) {
List<DecisionTreeDetail> detailList = version.getDetailList();
for (DecisionTreeDetail decisionTreeDetail : detailList) {
Object o = executeDecisionTreeDetail(decisionTreeDetail, inputParam);
if (o != null) {
return o;
}
}
return null;
}
private Object executeDecisionTreeDetail(DecisionTreeDetail detail, Map<String, Object> paramMap) {
//获取需要执行的条件列表
List<DecisionTreeDetailCondition> conditionList = detail.getConditionList();
String fieldEn = detail.getFieldEn();
String logical = detail.getLogical();
boolean result = false;
//根据不通关系进行处理
switch (logical) {
case "||":
result = false;
for (DecisionTreeDetailCondition condition : conditionList) {
ExpressionParam expressionParam = new ExpressionParam();
BeanUtils.copyProperties(condition, expressionParam);
expressionParam.setFieldEn(fieldEn);
boolean expressionResult = ExecuteUtils.getExpressionResult(expressionParam, paramMap);
if (expressionResult) {
result = true;
break;
}
}
break;
case "&&":
result = true;
for (DecisionTreeDetailCondition condition : conditionList) {
ExpressionParam expressionParam = new ExpressionParam();
BeanUtils.copyProperties(condition, expressionParam);
expressionParam.setFieldEn(fieldEn);
boolean expressionResult = ExecuteUtils.getExpressionResult(expressionParam, paramMap);
if (!expressionResult) {
result = false;
break;
}
}
break;
}
//如果本节点符合则执行后续节点
if (result) {
Integer type = detail.getNodeType();
List<DecisionTreeDetail> children = detail.getChildren();
if (type == null) {
if (children == null || children.isEmpty()) {
type = 2;
} else {
type = 1;
}
}
if (type != null) {
switch (type) {
//普通节点符合,让子节点继续执行。
case 1:
if (children != null && children.size() > 0) {
for (DecisionTreeDetail child : children) {
Object executeResult = this.executeDecisionTreeDetail(child, paramMap);
if (executeResult != null) {
return executeResult;
}
}
}
break;
//叶子节点符合,返回叶子节点的值。
case 2:
String resultStr = detail.getResultValue();
Object resultValue = resultStr;
Integer variableType = detail.getVariableType();
if (variableType == 2) {
resultValue = ExecuteUtils.getObjFromMap(paramMap, resultStr);
} else if (variableType == 3) {
resultValue = ExecuteUtils.getObjFromScript(paramMap, resultStr);
}
return resultValue;
default:
break;
}
}
}
return null;
}
private void terminalCondition(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap,Object executeResult) {
String resultKey = engineNode.getNodeType() + "_" + engineNode.getNodeId() + "_terminal_result";
Map<String,Object> map = new HashMap<>();
map.put(resultKey,executeResult);
ExecuteUtils.terminalCondition(engineNode,inputParam,outMap, map);
}
}

View File

@@ -0,0 +1,107 @@
package com.fibo.ddp.enginex.runner.node.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.service.datax.runner.CommonService;
import com.fibo.ddp.common.utils.constant.CommonConst;
import com.fibo.ddp.common.utils.util.runner.JevalUtil;
import com.fibo.ddp.common.utils.util.runner.jeval.EvaluationException;
import com.fibo.ddp.enginex.runner.node.EngineRunnerNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class GroupNode implements EngineRunnerNode {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private CommonService commonService;
@Override
public void getNodeField(EngineNode engineNode, Map<String, Object> inputParam) {
logger.info("start【获取分组节点指标】GroupNode.getNodeField engineNode:{},inputParam:{}", JSONObject.toJSONString(engineNode), JSONObject.toJSONString(inputParam));
JSONObject jsonObject = JSONObject.parseObject(engineNode.getNodeScript());
JSONArray array = jsonObject.getJSONArray("fields");
List<Long> ids = new ArrayList<>();
for (int i = 0; i < array.size(); i++) {
JSONObject input = array.getJSONObject(i);
Object fieldId = input.get("fieldId");
if(fieldId != null && !"".equals(fieldId.toString())){
ids.add(Long.valueOf(fieldId.toString()));
}
}
commonService.getFieldByIds(ids, inputParam);
}
@Override
public void runNode(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap) {
JSONObject jsonScript = JSONObject.parseObject(engineNode.getNodeScript());
//监控中心--节点信息记录(不需要策略层面的监控)
outMap.put("nodeSnapshot",JSONObject.parse(engineNode.getNodeJson()));
JSONObject nodeInfo = new JSONObject();
nodeInfo.put("engineNode",engineNode);
nodeInfo.put("nodeId",engineNode.getNodeId());
nodeInfo.put("nodeName",engineNode.getNodeName());
nodeInfo.put("nodeType",engineNode.getNodeType());
outMap.put("nodeInfo",nodeInfo);
try {
String nextNode = handleClassify(jsonScript, inputParam);
outMap.put("nextNode", nextNode);
JSONObject result = new JSONObject();
result.put("nodeResult",nextNode);
outMap.put("nodeResult",result);
} catch (EvaluationException e) {
e.printStackTrace();
logger.error("请求异常", e);
}
}
private static String handleClassify(JSONObject jsonScript, Map<String, Object> inputParam) throws EvaluationException {
JSONArray conditions = jsonScript.getJSONArray("conditions");
JSONArray fields = jsonScript.getJSONArray("fields");
Map<String, Object> variablesMap = new HashMap<>();
variablesMap.putAll(inputParam);
Map<String, Integer> fieldsMap = new HashMap<>();
for(int i = 0; i < fields.size(); i++){
JSONObject jsonObject = fields.getJSONObject(i);
fieldsMap.put(jsonObject.getString("fieldCode"), jsonObject.getIntValue("valueType"));
}
JevalUtil.convertVariables(fieldsMap, variablesMap);
String nextNode = "";
if (conditions == null || conditions.isEmpty()) {
//TODO 如果为空,如何处理
return nextNode;
} else {
int size = conditions.size();
boolean flag = false;
JSONObject formula = null;
for (int i = 0; i < size; i++) {
formula = conditions.getJSONObject(i);
//公式为空则为else条件分支
if (CommonConst.STRING_EMPTY.equals(formula.getString("formula"))) {
//else条件
if (nextNode.equals(CommonConst.STRING_EMPTY)) {
nextNode = formula.getString("nextNode");
}
} else {
//正常条件分支
flag = JevalUtil.evaluateBoolean(formula.getString("formula"), variablesMap);
if (flag) {
nextNode = formula.getString("nextNode");
break;
}
}
}
return nextNode;
}
}
}

View File

@@ -0,0 +1,284 @@
package com.fibo.ddp.enginex.runner.node.impl;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.service.datax.runner.CommonService;
import com.fibo.ddp.common.service.datax.runner.ExecuteUtils;
import com.fibo.ddp.common.service.strategyx.listlibrary.ListDbService;
import com.fibo.ddp.common.utils.constant.enginex.NodeTypeEnum;
import com.fibo.ddp.enginex.runner.node.EngineRunnerNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ListDbNode implements EngineRunnerNode {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private CommonService commonService;
@Resource
private ListDbService listDbService;
private List<Long> getExecuteVersionIdList(EngineNode engineNode){
return ExecuteUtils.getExecuteIdList(engineNode,"versionId");
}
@Override
public void getNodeField(EngineNode engineNode, Map<String, Object> inputParam) {
List<Long> list = getExecuteVersionIdList(engineNode);
List<Long> fieldIds = new ArrayList<>();
for (Long l : list) {
fieldIds.addAll(listDbService.getNodeFieldIds(l));
}
commonService.getFieldByIds(fieldIds,inputParam);
}
@Override
public void runNode(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap) {
//监控中心--节点信息快照记录,主要用于监控中心节点信息配置页面显示
JSONObject snapshot = new JSONObject();
snapshot.put("snapshot",engineNode.getSnapshot());
outMap.put("nodeSnapshot",snapshot);
inputParam.put("nodeId", engineNode.getNodeId());
inputParam.put("nodeName", engineNode.getNodeName());
JSONObject nodeInfo = new JSONObject();
nodeInfo.put("engineNode",engineNode);
nodeInfo.put("nodeId",engineNode.getNodeId());
nodeInfo.put("nodeName",engineNode.getNodeName());
nodeInfo.put("nodeType",engineNode.getNodeType());
outMap.put("nodeInfo",nodeInfo);
int type = 0;
if(engineNode.getNodeType() == NodeTypeEnum.BLACKLIST.getValue()){
type = 1;
} else if(engineNode.getNodeType() == NodeTypeEnum.WHITELIST.getValue()){
type = 2;
}
boolean isfalg = this.findByQueryKey(inputParam, outMap, type,engineNode);
if (isfalg) {
if (type == 1) {
outMap.put("isBlack", "true");
outMap.put("enginefalg", "true");
// engineNode.setNextNodes(null);
} else {
outMap.put("isWhite", "true");
outMap.put("engineWhite", "true");
// engineNode.setNextNodes(null);
}
}
}
/**
* 根据传入数据监测是否命中黑名单
*
* @param paramMap
* @return
* @see
*/
public boolean findByQueryKey(Map<String, Object> paramMap, Map<String, Object> outmap, Integer type,EngineNode engineNode) {
// SessionData sessionData = SessionManager.getSession();
// Long organId = sessionData.getOrganId();
// JSONObject blackandWhite = new JSONObject();
// JSONObject resultJson = new JSONObject();
// //传递nodeId
// String strlistDbIds = null;
// if (!paramMap.get("nodeId").equals("0")) {
// NodeListDb nodeListDb = nodeListDbMapper.findByNodeId(paramMap);
// strlistDbIds = nodeListDb.getInnerListdbs();
// //节点配置信息快照hbase入库用
//// JSONObject bwNodeSnopshot = new JSONObject();
//// String strListDbIdsOut = nodeListDb.getOuterListdbs();
//// if(strListDbIdsOut!=null && strListDbIdsOut.length()>0){
//// bwNodeSnopshot.put("outerIdList",strListDbIdsOut.split(","));
//// }
// //循环处理所有内部黑/白名单库
// String[] arraylistDBIds = null;
// Integer matchs = 0;
// Integer revMatchs = 0; //模糊查询时反向匹配
// if (strlistDbIds.length() > 0) {
// arraylistDBIds = strlistDbIds.split(",");
//// bwNodeSnopshot.put("innerIdList",arraylistDBIds);
//// outmap.put("nodeSnapshot",bwNodeSnopshot);
// String hitKey = ""+engineNode.getNodeType()+"_"+engineNode.getNodeId()+"_size";
// int hitSize = 0;
// JSONArray strategySnopshot = new JSONArray();
// for (int i = 0; i < arraylistDBIds.length; i++) {
// HashMap<String, Object> param1 = new HashMap<String, Object>();
// param1.put("organId", organId);
// Integer listDbId = Integer.valueOf(arraylistDBIds[i]).intValue();
// param1.put("listDbId", listDbId);
// ListDb listDb = new ListDb();
//// listDb = listDbService.findListDbByIdandByorganId(param1);
// //监控中心--策略层面记录名单库快照信息
// if(listDb.getSnapshot()!=null){
// strategySnopshot.add(listDb.getSnapshot());
// }
// paramMap.put("listDb", listDb);
// String listType = listDb.getListType();
// String queryKeyArray[] = listDb.getQueryField().split(",");
// if (queryKeyArray.length > 0) {
// Integer queryType = listDb.getQueryType();//and1or0
// Integer matchType = listDb.getMatchType();//精确匹配1模糊匹配0
//
// String queryKey = ""; // t1 like '%t1%'
// String revQueryKey = ""; // 反向模糊匹配 instr('高档洗浴消费',t1) t1行业字段 eg.'洗浴'
// String tableName = "organ" + "_" + organId + "_" + listType + "_" + listDbId;
// paramMap.put("tableName", tableName);
// paramMap.put("schemaName", getDbName());
//
// //获取名单库的匿名字段与注释的关系
// List<TblColumn> columnList = tblColumnMapper.getColumnList(paramMap);
//
// //字段id转匿名字段名准备待查字段条件
// Integer loc = 0;
//
// for (int j = 0; j < queryKeyArray.length; j++) {
//
// HashMap<String, Object> inputParam = new HashMap<String, Object>();
// inputParam.put("id", queryKeyArray[j]);
// inputParam.put("organId", organId);
// inputParam.put("engineId", null);
// //id(3)-field(age)
// Field field = fieldMapper.findByFieldIdbyorganId(inputParam);
// String fieldEn = field.getFieldEn(); //age
//
// for (TblColumn tblColumn : columnList) {
//
// String colComment = tblColumn.getColComment(); //age
// String colName = tblColumn.getColName(); //t5
// String paramValue =paramMap.get(fieldEn).toString();
//
// if (colName.startsWith("t") && queryKeyArray[j].equals(colComment)) {
//
// if (paramValue == null || paramValue.equals("")) {
// return false; //数据项缺失导致无法命中,默认返回没命中
// } else {
// loc += 1;
// if (matchType == 1) {
// if (loc > 1 && queryType == 1) {
// queryKey += " and ";
// } else if (loc > 1 && queryType == 0) {
// queryKey += " or ";
// }
// queryKey += colName + " = '" + paramValue + "'";
// } else if (matchType == 0) { //模糊匹配
// if (loc > 1 && queryType == 1) {
// queryKey += " and ";
// } else if (loc > 1 && queryType == 0) {
// queryKey += " or ";
// revQueryKey += " + ";
// }
// //正向模糊搜索
// queryKey += colName + " like " + "'%" + paramValue + "%'"; // t5 like '%36岁%'
// //反向模糊搜索
// revQueryKey += "max(instr('" + paramValue + "'," + colName + "))";
// }
// }
// }
// }
// }
// paramMap.put("queryKey", queryKey);
// paramMap.put("revQueryKey", revQueryKey);
// }
// matchs += custListMapper.findByQueryKey(paramMap);
// if (!paramMap.get("revQueryKey").equals("")) {
// revMatchs = custListMapper.revFindByQueryKey(paramMap);
// }
// if (revMatchs == null)
// revMatchs = 0;
//
// paramMap.put(listDb.getResultFieldEn(),"未命中");
// List<JSONObject> fieldList = new ArrayList<>();
//
// JSONObject hitResult = new JSONObject();
// hitResult.put(listDb.getResultFieldEn(),"未命中");
// if (matchs + revMatchs > 0) {
// resultJson.put("nodeId", paramMap.get("nodeId").toString());
// resultJson.put("nodeName", paramMap.get("nodeName").toString());
// resultJson.put("status", "0x0000");
// paramMap.put(listDb.getResultFieldEn(),"命中");
// hitResult.put(listDb.getResultFieldEn(),"命中");
// hitSize++;
// List<JSONObject> jsonObjects = outputService.setOutput(new StrategyOutput(Long.valueOf(listDbId.toString()), StrategyType.LIST_DB), paramMap);
// fieldList.add(hitResult);
// fieldList.addAll(jsonObjects);
// resultJson.put("fieldList",fieldList);
// if (type == 1) {
// blackandWhite.put("resultType", 5);
// outmap.put("black", listDb);
// resultJson.put("blackId", listDb.getId());
// resultJson.put("blackName", listDb.getListName());
// resultJson.put("blackType", listDb.getListType());
// if (null != listDb.getListDesc()) {
// resultJson.put("desc", listDb.getListDesc());
// }
//
// blackandWhite.put("resultJson", resultJson);
// //黑名单api返回
// outmap.put("blackJson", blackandWhite);
// } else {
// blackandWhite.put("resultType", 6);
// resultJson.put("status", "0x0000");
// resultJson.put("whiteId", listDb.getId());
// resultJson.put("whiteName", listDb.getListName());
// resultJson.put("whiteType", listDb.getListType());
// if (null != listDb.getListDesc()) {
// resultJson.put("desc", listDb.getListDesc());
// }
// blackandWhite.put("resultJson", resultJson);
// //白名单api返回
// outmap.put("whiteJson", blackandWhite);
// outmap.put("white", listDb);
// }
// paramMap.put(hitKey,hitSize);
// return true;
// }else {
// //未命中
// blackandWhite.put("resultJson","未命中");
// fieldList.add( hitResult);
// }
// //监控中心==》将评分卡的执行结果得分明细放入 输出变量池 用于存入hbase
// outmap.put("nodeResult",blackandWhite);
// }
// paramMap.put(hitKey,hitSize);
// //监控中心==》策略层面记录策略的快照信息
// JSONObject strategyObject = new JSONObject();
// strategyObject.put("strategySnopshot",strategySnopshot);
// outmap.put("strategySnopshot",strategyObject);
// } else
// return false;
// }
return false;
}
/**
* Description: 获取jdbc.properties里配置的数据库名
*
* @return
* @see
*/
private String getDbName() {
// ResourceBundle resource = ResourceBundle.getBundle("conf/jdbc");
// String mysqlUrl = resource.getString("mysql.url");
//
// String aArray[] = mysqlUrl.split("/");
// String bArray[] = aArray[3].split("\\?");
// String dbName = bArray[0];
//
// return dbName;
return "riskmanage";
}
private void terminalCondition(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap,Object executeResult) {
String sizeKey = engineNode.getNodeType() + "_" + engineNode.getNodeId() + "_terminal_size";
Map<String,Object> map = new HashMap<>();
map.put(sizeKey,executeResult);
ExecuteUtils.terminalCondition(engineNode,inputParam,outMap, map);
}
}

View File

@@ -0,0 +1,128 @@
package com.fibo.ddp.enginex.runner.node.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.model.strategyx.aimodel.MachineLearningModels;
import com.fibo.ddp.common.model.strategyx.strategyout.StrategyOutput;
import com.fibo.ddp.common.service.datax.runner.CommonService;
import com.fibo.ddp.common.service.datax.runner.ExecuteUtils;
import com.fibo.ddp.common.service.strategyx.aimodel.ModelsService;
import com.fibo.ddp.common.service.strategyx.aimodel.PMMLExecutor.PMMLExecutor;
import com.fibo.ddp.common.service.strategyx.strategyout.StrategyOutputService;
import com.fibo.ddp.common.utils.constant.strategyx.StrategyType;
import com.fibo.ddp.common.utils.util.StringUtil;
import com.fibo.ddp.enginex.runner.node.EngineRunnerNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class ModelNode implements EngineRunnerNode {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private CommonService commonService;
@Resource
public ModelsService modelsService;
@Resource(name = "PMMLExecutorRFImpl")
private PMMLExecutor pmmlExecutor;
@Resource
private StrategyOutputService outputService;
private List<Long> getExecuteVersionIdList(EngineNode engineNode) {
return ExecuteUtils.getExecuteIdList(engineNode, "modelId");
}
@Override
public void getNodeField(EngineNode engineNode, Map<String, Object> inputParam) {
logger.info("start【获取模型节点指标】ModelNode.getNodeField engineNode:{},inputParam:{}", JSONObject.toJSONString(engineNode), JSONObject.toJSONString(inputParam));
// Long modelId = Long.valueOf(engineNode.getNodeJson());
List<Long> modelIds = getExecuteVersionIdList(engineNode);
List<Long> ids = new ArrayList<>();
for (Long modelId : modelIds) {
MachineLearningModels models = modelsService.selectById(Integer.valueOf(modelId.toString()));
ids.addAll(StringUtil.toLongList(models.getMappingField()));
}
try {
commonService.getFieldByIds(ids, inputParam);
}catch (Exception e){
logger.error("模型中字段未完全找到");
e.printStackTrace();
}
}
@Override
public void runNode(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap) {
List<Long> modelIds = getExecuteVersionIdList(engineNode);
if (modelIds == null || modelIds.isEmpty()){
logger.error("模型节点内容为空node{}",engineNode);
return;
}
Long modelId = modelIds.get(0);
MachineLearningModels models = modelsService.selectById(Integer.valueOf(modelId.toString()));
//监控中心--节点信息记录
outMap.put("nodeSnapshot", models);
JSONObject nodeInfo = new JSONObject();
nodeInfo.put("engineNode", engineNode);
nodeInfo.put("nodeId", engineNode.getNodeId());
nodeInfo.put("nodeName", engineNode.getNodeName());
nodeInfo.put("nodeType", engineNode.getNodeType());
outMap.put("nodeInfo", nodeInfo);
// 加载模型文件
org.jpmml.evaluator.Evaluator evaluator = pmmlExecutor.loadPmml(models.getFilePath());
Map<String, Object> input = new HashMap<>();
String[] modelFieldArr = models.getModelField().split(",");
String[] mappingFieldArr = models.getMappingField().split(",");
for (int i = 0; i < modelFieldArr.length; i++) {
input.put(modelFieldArr[i], inputParam.get(mappingFieldArr[i]));
}
// 调用模型
double modelResult = 0d;
try {
modelResult =pmmlExecutor.predict(evaluator, input);
}catch (Exception e){
logger.error("模型节点执行异常,node{}",engineNode);
}
JSONObject jsonObject = new JSONObject();
jsonObject.put("nodeId", engineNode.getNodeId());
jsonObject.put("nodeName", engineNode.getNodeName());
jsonObject.put("modelId", models.getId());
jsonObject.put("modelName", models.getModelName());
List<JSONObject> fieldList = new ArrayList<>();
JSONObject result = new JSONObject();
result.put(models.getResultFieldEn(), modelResult);
fieldList.add(result);
fieldList.addAll(outputService.setOutput(new StrategyOutput(modelId, StrategyType.MODELS), input));
jsonObject.put("fieldList", fieldList);
outMap.put("nodeResult", jsonObject);
if (outMap.containsKey("modelJson")) {
JSONArray resultJson = (JSONArray) outMap.get("modelJson");
resultJson.add(jsonObject);
} else {
JSONArray resultJson = new JSONArray();
resultJson.add(jsonObject);
outMap.put("modelJson", resultJson);
}
inputParam.put("model_" + modelId, modelResult);
inputParam.put(models.getResultFieldEn(), modelResult);
outMap.put("model_" + modelId, modelResult);
terminalCondition(engineNode, inputParam, outMap, modelResult);
}
private void terminalCondition(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap, Object executeResult) {
String resultKey = engineNode.getNodeType() + "_" + engineNode.getNodeId() + "_terminal_result";
Map<String, Object> map = new HashMap<>();
map.put(resultKey, executeResult);
ExecuteUtils.terminalCondition(engineNode, inputParam, outMap, map);
}
}

View File

@@ -0,0 +1,33 @@
package com.fibo.ddp.enginex.runner.node.impl;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.enginex.runner.node.EngineRunnerNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.Map;
/**
* 并行节点
*/
@Service
public class ParallelNode implements EngineRunnerNode {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void getNodeField(EngineNode engineNode, Map<String, Object> inputParam) {
}
@Override
public void runNode(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap) {
logger.info("start【执行并行节点】ParallelNode.runNode engineNode:{},inputParam:{},outMap:{}"
, JSONObject.toJSONString(engineNode), JSONObject.toJSONString(inputParam), JSONObject.toJSONString(outMap));
if (engineNode != null && engineNode.getSnapshot() != null) {
outMap.put("nodeSnapshot", engineNode.getSnapshot());
}
}
}

View File

@@ -0,0 +1,59 @@
package com.fibo.ddp.enginex.runner.node.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.model.datax.datainterface.InterfaceInfo;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.service.datax.datainterface.InterfaceService;
import com.fibo.ddp.enginex.runner.node.EngineRunnerNode;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
/**
* 远程调用节点
*/
@Service
public class RpcNode implements EngineRunnerNode {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private InterfaceService interfaceService;
@Override
public void getNodeField(EngineNode engineNode, Map<String, Object> inputParam) {
}
@Override
public void runNode(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap) {
logger.info("start【执行RPC节点】RpcNode.runNode engineNode:{},inputParam:{},outMap:{}"
, JSONObject.toJSONString(engineNode), JSONObject.toJSONString(inputParam), JSONObject.toJSONString(outMap));
if (engineNode != null && engineNode.getSnapshot() != null) {
outMap.put("nodeSnapshot", engineNode.getSnapshot());
}
JSONObject nodeJson = JSONObject.parseObject(engineNode.getNodeJson());
JSONObject callConfig = nodeJson.getJSONObject("callConfig");
int callType = callConfig.getInteger("callType");
JSONArray resultConfig = nodeJson.getJSONArray("resultConfig");
InterfaceInfo interfaceInfo = interfaceService.getInterfaceById(callConfig.getInteger("interfaceId"));
// 发送http请求
String result = interfaceService.getHttpResponse(interfaceInfo, inputParam, callType);
// 解析指标
parseField(result, resultConfig, inputParam);
}
private void parseField(String result, JSONArray resultConfig, Map<String, Object> inputParam){
if(resultConfig != null && !resultConfig.isEmpty() && StringUtils.isNotBlank(result)){
JSONObject configJson = resultConfig.getJSONObject(0);
String fieldEn = configJson.getString("fieldEn");
String parseField = configJson.getString("parseField");
String fieldValue = interfaceService.interfaceParseField(parseField, result);
inputParam.put(fieldEn, fieldValue);
}
}
}

View File

@@ -0,0 +1,769 @@
package com.fibo.ddp.enginex.runner.node.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.model.datax.datamanage.Field;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.model.enginex.runner.ExpressionParam;
import com.fibo.ddp.common.model.strategyx.guiderule.RuleInfo;
import com.fibo.ddp.common.model.strategyx.guiderule.RuleLoopGroupAction;
import com.fibo.ddp.common.model.strategyx.guiderule.vo.RuleConditionVo;
import com.fibo.ddp.common.model.strategyx.guiderule.vo.RuleVersionVo;
import com.fibo.ddp.common.model.strategyx.scriptrule.RuleScriptVersion;
import com.fibo.ddp.common.service.datax.datamanage.FieldService;
import com.fibo.ddp.common.service.datax.runner.CommonService;
import com.fibo.ddp.common.service.datax.runner.ExecuteUtils;
import com.fibo.ddp.common.service.strategyx.guiderule.RuleConditionService;
import com.fibo.ddp.common.service.strategyx.guiderule.RuleService;
import com.fibo.ddp.common.service.strategyx.guiderule.RuleVersionService;
import com.fibo.ddp.common.service.strategyx.scriptrule.RuleScriptVersionService;
import com.fibo.ddp.common.utils.constant.Constants;
import com.fibo.ddp.common.utils.constant.strategyx.RuleConst;
import com.fibo.ddp.common.utils.constant.strategyx.StrategyType;
import com.fibo.ddp.enginex.runner.node.EngineRunnerNode;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
@Service
public class RuleSetNode implements EngineRunnerNode {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private CommonService commonService;
@Resource
private RuleService ruleService;
@Autowired
private RuleConditionService conditionService;
@Resource
private RuleScriptVersionService ruleScriptVersionService;
@Resource
private FieldService fieldService;
@Autowired
private RuleVersionService versionService;
@Autowired
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Override
public void getNodeField(EngineNode engineNode, Map<String, Object> inputParam) {
logger.info("start【获取规则集节点指标】RuleSetNode.getNodeField engineNode:{},inputParam:{}", JSONObject.toJSONString(engineNode), JSONObject.toJSONString(inputParam));
JSONObject nodeJson = JSONObject.parseObject(engineNode.getNodeJson());
List<Long> ids = new ArrayList<>();
List<Long> versionIds = new ArrayList<>(); // 复杂规则集
List<Long> scriptVersionIds = new ArrayList<>(); // 脚本规则集
JSONArray jsonArray = null;
int groupType = nodeJson.getInteger("groupType");
if (groupType == Constants.ruleNode.MUTEXGROUP) {
jsonArray = nodeJson.getJSONObject("mutexGroup").getJSONArray("rules");
} else {
jsonArray = nodeJson.getJSONObject("executeGroup").getJSONArray("rules");
}
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject ruleObj = jsonArray.getJSONObject(i);
Long versionId = ruleObj.getLong("ruleVersionId");
Long difficulty = ruleObj.getLong("difficulty");
if (difficulty != null && difficulty == 3) {
scriptVersionIds.add(versionId); // 脚本式规则
} else if (versionId != null) {
versionIds.add(versionId); // 复杂规则
}
}
//获取字段en
List<String> fieldEnList = new ArrayList<>();
if (!versionIds.isEmpty()) {
fieldEnList.addAll(conditionService.queryFieldEnByVersionIds(versionIds));
}
if (!scriptVersionIds.isEmpty()) {
fieldEnList.addAll(ruleScriptVersionService.queryFieldEnByVersionIds(scriptVersionIds));
}
//筛选调那些循环或者嵌套中的字段
fieldEnList = fieldEnList.stream().distinct().filter(f -> f != null && !f.contains(".") && !f.contains("%")).collect(Collectors.toList());
if (fieldEnList != null && !fieldEnList.isEmpty()) {
List<Field> fieldList = fieldService.selectFieldListByEns(fieldEnList);
for (Field field : fieldList) {
ids.add(field.getId());
}
}
if (!ids.isEmpty()) {
commonService.getFieldByIds(ids, inputParam);
}
}
@Override
public void runNode(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap) {
JSONObject nodeJson = JSONObject.parseObject(engineNode.getNodeJson());
//监控中心--记录节点快照信息
if (engineNode != null && engineNode.getSnapshot() != null) {
outMap.put("nodeSnapshot", engineNode.getSnapshot());
}
JSONObject nodeInfo = new JSONObject();
nodeInfo.put("engineNode", engineNode);
nodeInfo.put("nodeId", engineNode.getNodeId());
nodeInfo.put("nodeName", engineNode.getNodeName());
nodeInfo.put("nodeType", engineNode.getNodeType());
outMap.put("nodeInfo", nodeInfo);
int groupType = nodeJson.getInteger("groupType") == null ? Constants.ruleNode.EXECUTEGROUP : nodeJson.getInteger("groupType");
CopyOnWriteArrayList<Map> ruleResultList = new CopyOnWriteArrayList<>();// 规则执行结果集合
List<RuleInfo> ruleHitList = new ArrayList<>(); // 命中的规则集合
// 互斥组(串行)
if (groupType == Constants.ruleNode.MUTEXGROUP) {
JSONArray jsonArray = nodeJson.getJSONObject("mutexGroup").getJSONArray("rules");
List<RuleInfo> ruleInfoList = getRuleFromJsonArray(jsonArray);
//监控中心--循环获取策略层面的快照信息
recordStrategySnopshot(ruleInfoList, outMap);
ruleHitList = serialRule(inputParam, outMap, ruleInfoList, ruleResultList);
}
// 执行组(并行)
else if (groupType == Constants.ruleNode.EXECUTEGROUP) {
JSONArray jsonArray = nodeJson.getJSONObject("executeGroup").getJSONArray("rules");
List<RuleInfo> ruleInfoList = getRuleFromJsonArray(jsonArray);
//监控中心--循环获取策略层面的快照信息
recordStrategySnopshot(ruleInfoList, outMap);
ruleHitList = parallelRule(inputParam, outMap, ruleInfoList, ruleResultList);
}
// 终止条件处理
terminalCondition(engineNode, nodeJson, outMap, ruleHitList);
JSONObject jsonObject = new JSONObject();
jsonObject.put("nodeId", engineNode.getNodeId());
jsonObject.put("nodeName", engineNode.getNodeName());
jsonObject.put("ruleResultList", ruleResultList);
if (outMap.containsKey("ruleJson")) {
JSONArray resultJson = (JSONArray) outMap.get("ruleJson");
resultJson.add(jsonObject);
} else {
JSONArray resultJson = new JSONArray();
resultJson.add(jsonObject);
outMap.put("ruleJson", resultJson);
}
int hitSize = 0;
double scoreSum = 0d;
for (Map map : ruleResultList) {
Object ruleScore = map.get("ruleScore");
Object ruleResult = map.get("ruleResult");
if (null != ruleResult && "命中".equals(ruleResult)) {
hitSize++;
if (null != ruleScore) {
try {
scoreSum += Double.valueOf(ruleScore.toString());
} catch (Exception e) {
continue;
}
}
}
}
String hitKey = "" + engineNode.getNodeType() + "_" + engineNode.getNodeId() + "_size";
String scoreKey = "" + engineNode.getNodeType() + "_" + engineNode.getNodeId() + "_score";
inputParam.put(hitKey, hitSize);
inputParam.put(scoreKey, scoreSum);
//监控中心==》记录节点输出结果
//记录整个规则集中的所有规则的命中情况,以及总的统计次数 放到输出变量池
JSONObject nodeResult = new JSONObject();
nodeResult.put("ruleResultList", ruleResultList);
nodeResult.put("hitNum", hitSize);
nodeResult.put("scoreTotal", scoreSum);
outMap.put("nodeResult", nodeResult);
}
/**
* 监控中心--获取策略层面快照信息
*
* @param ruleInfoList
* @param outMap
*/
private void recordStrategySnopshot(List<RuleInfo> ruleInfoList, Map<String, Object> outMap) {
JSONArray jsonObject = new JSONArray();
ruleInfoList.stream().forEach(ruleInfo -> {
logger.info("===========================监控添加策略信息快照情况==============版本id:{}=====:{}",ruleInfo.getVersion().getId(),ruleInfo.getVersion().getSnapshot());
if (ruleInfo.getVersion().getSnapshot() != null) {
jsonObject.add(ruleInfo.getVersion().getSnapshot());
}
});
JSONObject jsonObject1 = new JSONObject();
jsonObject1.put("snopshot", jsonObject);
logger.info("===========================监控添加策略信息快照情况:{}",jsonObject1);
outMap.put("strategySnopshot", jsonObject1);
}
/**
* 串行执行规则
*
* @param inputParam
* @param outMap
* @param ruleInfoList
* @param ruleResultList
* @return
*/
private List<RuleInfo> serialRule(Map<String, Object> inputParam, Map<String, Object> outMap, List<RuleInfo> ruleInfoList, CopyOnWriteArrayList<Map> ruleResultList) {
logger.info("请求参数--串行执行规则" + "map:" + JSONObject.toJSONString(inputParam));
List<RuleInfo> resultList = new ArrayList<>();
for (int i = 0; i < ruleInfoList.size(); i++) {
RuleInfo rule = ruleInfoList.get(i);
boolean hitFlag = executeByDifficulty(inputParam, outMap, rule, ruleResultList);
if (hitFlag) {
resultList.add(rule);
break;
}
}
return resultList;
}
/**
* 并行执行规则
*
* @param inputParam
* @param outMap
* @param ruleInfoList
* @param ruleResultList
* @return
*/
private List<RuleInfo> parallelRule(Map<String, Object> inputParam, Map<String, Object> outMap, List<RuleInfo> ruleInfoList, CopyOnWriteArrayList<Map> ruleResultList) {
logger.info("请求参数--并行执行规则" + "map:" + JSONObject.toJSONString(inputParam));
List<RuleInfo> resultList = new ArrayList<>();
List<CompletableFuture<RuleInfo>> futureList = new ArrayList<>();
for (int i = 0; i < ruleInfoList.size(); i++) {
final int index = i;
CompletableFuture<RuleInfo> future = CompletableFuture.supplyAsync(() -> {
RuleInfo rule = ruleInfoList.get(index);
boolean hitFlag = executeByDifficulty(inputParam, outMap, rule, ruleResultList);
if (hitFlag) {
return rule;
} else {
return null;
}
}, threadPoolTaskExecutor);
futureList.add(future);
}
for (CompletableFuture<RuleInfo> future : futureList) {
try {
RuleInfo rule = future.get();
if (rule != null) {
resultList.add(rule);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
return resultList;
}
/**
* 根究规则类型选择执行
*
* @param inputParam
* @param outMap
* @param rule
* @param ruleResultList
* @return
*/
private boolean executeByDifficulty(Map<String, Object> inputParam, Map<String, Object> outMap, RuleInfo rule, CopyOnWriteArrayList<Map> ruleResultList) {
boolean hitFlag = false;
if (rule.getDifficulty() == 2) {
hitFlag = executeComplexRule(inputParam, outMap, rule, ruleResultList);
} else if (rule.getDifficulty() == 3) {
hitFlag = executeScriptRule(inputParam, outMap, rule, ruleResultList);
}
return hitFlag;
}
/**
* 执行复杂规则
*
* @param input
* @param output
* @param rule
* @param ruleResultList
* @return
*/
public boolean executeComplexRule(Map<String, Object> input, Map<String, Object> output, RuleInfo rule, CopyOnWriteArrayList<Map> ruleResultList) {
boolean hitFlag = false;
//获取需要执行的整个规则。
// RuleVo rule = ruleService.queryByVersionId(ruleId);
// Long versionId = rule.getVersionId();
// if (versionId==null){
// return false;
// }
// RuleVersionVo ruleVersion = versionService.queryByVersionId(versionId);
RuleVersionVo ruleVersion = rule.getVersion();
if (ruleVersion == null) {
return false;
}
//取出本规则的条件列表
Map<String, Object> ruleMap = new HashMap<>();
ruleMap.put("ruleId", rule.getId());
ruleMap.put("ruleVersionId",ruleVersion.getId());
ruleMap.put("ruleCode", rule.getCode());
ruleMap.put("ruleName", rule.getName());
ruleMap.put("versionCode", ruleVersion.getVersionCode());
ruleMap.put("versionDesc", ruleVersion.getDescription());
ruleMap.put("desc", rule.getDescription());
ruleMap.put("ruleResult", "未命中");
//获取规则需要执行的condition逻辑。
RuleConditionVo ruleCondition = ruleVersion.getRuleConditionVo();
//传入输入参数、中间变量、输出参数和需要执行的condition逻辑获取执行结果
Map<String, Object> temp = JSON.parseObject(JSON.toJSONString(input), Map.class);
boolean result = this.executeRuleCondition(temp, output, ruleCondition);
String resultFieldEn = ruleVersion.getResultFieldEn();
if (resultFieldEn == null || "".equals(resultFieldEn)) {
resultFieldEn = "rule_2_"+rule.getId()+"_"+ruleVersion.getId()+"_hitResult";
}
String scoreFieldEn = ruleVersion.getScoreFieldEn();
if (StringUtils.isBlank(scoreFieldEn)){
scoreFieldEn = "rule_2_"+rule.getId()+"_"+ruleVersion.getId()+"_score";
}
input.put(resultFieldEn, "未命中");
//根据执行的最终结果处理此规则输出内容
List<JSONObject> fieldList = new ArrayList<>();
JSONObject resultJson = new JSONObject();
if (result) {
ruleMap.put("ruleResult", "命中");
ruleMap.put("ruleScore", rule.getScore());
JSONObject scoreJson = new JSONObject();
resultJson.put(resultFieldEn, "命中");
fieldList.add(resultJson);
// if (StringUtils.isNotBlank(ruleVersion.getScoreFieldEn())) {
scoreJson.put(scoreFieldEn, ruleVersion.getScore());
fieldList.add(scoreJson);
input.put(scoreFieldEn, ruleVersion.getScore());
// }
input.put(resultFieldEn, "命中");
//处理此规则需要输出的内容
fieldList.addAll(ruleService.setComplexRuleOutput(ruleVersion.getId(), temp, input, StrategyType.OutType.SUCCESS_OUT));
ruleMap.put("fieldList", fieldList);
hitFlag = true;
} else {
resultJson.put(resultFieldEn, "未命中");
ruleMap.put("ruleScore", 0);
input.put(scoreFieldEn,0);
fieldList.add(resultJson);
fieldList.addAll(ruleService.setComplexRuleOutput(ruleVersion.getId(), temp, input, StrategyType.OutType.FAIL_OUT));
ruleMap.put("fieldList", fieldList);
}
ruleResultList.add(ruleMap);
return hitFlag;
}
//执行规则的条件
private boolean executeRuleCondition(Map<String, Object> input, Map<String, Object> output, RuleConditionVo ruleCondition) {
Integer conditionType = ruleCondition.getConditionType();
boolean result = false;
switch (conditionType) {
//关系条件节点 &&和||
case RuleConst.RELATION_CONDITION:
//循环结果的条件
case RuleConst.LOOP_RESULT_CONDITION:
case RuleConst.CONDITION_RESULT_CONDITION:
result = executeRelation(input, output, ruleCondition);
break;
//表达式条件节点
case RuleConst.EXPRESSION_CONDITION:
result = executeExpression(input, output, ruleCondition);
break;
//循环条件根节点
case RuleConst.LOOP_CONDITION:
result = executeLoop(input, output, ruleCondition);
break;
//条件组根节点
case RuleConst.CONDITION_GROUP_CONDITION:
result = executeCondGroup(input, output, ruleCondition);
break;
}
return result;
}
//执行条件组
private boolean executeCondGroup(Map<String, Object> input, Map<String, Object> output, RuleConditionVo ruleCondition) {
//取出子条件
List<RuleConditionVo> children = ruleCondition.getChildren();
//存储命中条数
int hitNum = 0;
if (children == null) {
return false;
}
//执行条件组中条件列表,命中则添加命中条数
for (RuleConditionVo child : children) {
boolean childResult = executeRuleCondition(input, output, child);
if (childResult) {
hitNum++;
}
}
//获取条件组命中条件为null直接不命中
RuleConditionVo condGroup = ruleCondition.getCondGroupResultCondition();
if (condGroup == null) {
return false;
}
//传入命中条件和组内命中条数执行并返回
Map<String, Object> map = new HashMap<>();
//将命中条数存入map然后判断执行结果
map.put("hitNum", hitNum);
return executeRuleCondition(map, output, condGroup);
}
//关系条件节点 &&和||
private boolean executeRelation(Map<String, Object> input, Map<String, Object> output, RuleConditionVo ruleCondition) {
//获取关系逻辑
String logical = ruleCondition.getLogical();
//处理子逻辑
List<RuleConditionVo> children = ruleCondition.getChildren();
boolean result = false;
switch (logical) {
case "||":
result = false;
for (RuleConditionVo child : children) {
boolean childResult = executeRuleCondition(input, output, child);
if (childResult) {
return true;
}
}
break;
case "&&":
result = true;
for (RuleConditionVo child : children) {
boolean childResult = executeRuleCondition(input, output, child);
if (!childResult) {
return false;
}
}
break;
}
return result;
}
//表达式条件节点
private boolean executeExpression(Map<String, Object> input, Map<String, Object> output, RuleConditionVo ruleCondition) {
String executionLogic = ruleCondition.getExecutionLogic();
boolean result = false;
ExpressionParam expressionParam = new ExpressionParam();
//复制执行的关键参数到统一入参
BeanUtils.copyProperties(ruleCondition, expressionParam);
result = ExecuteUtils.getExpressionResult(expressionParam, input);
return result;
}
//循环条件根节点
private boolean executeLoop(Map<String, Object> input, Map<String, Object> output, RuleConditionVo ruleCondition) {
List<RuleConditionVo> children = ruleCondition.getChildren();
String fieldEn = ruleCondition.getFieldEn();
//对循环中每个条件进行处理
String[] split = fieldEn.split("\\.");
//从map中取元素返回最终取到的对象
Object obj = ExecuteUtils.getObjFromMap(input, fieldEn);
List arrayList = new ArrayList();
if (obj != null) {
arrayList.addAll(JSON.parseObject(JSON.toJSONString(obj), ArrayList.class));
}
//取不到这个数组
if (arrayList.isEmpty()) {
return false;
}
//拼接当前对象的key
String currentKey = "%" + split[split.length - 1] + "%";
for (RuleConditionVo child : children) {
List<RuleLoopGroupAction> loopGroupActions = child.getLoopGroupActions();
// 调用for循环条件下的操作,并且将其存入input中
for (RuleLoopGroupAction loopGroupAction : loopGroupActions) {
this.initLoopGroupAction(loopGroupAction, input);
}
}
for (Object currentObj : arrayList) {
//将循环时的当前对象存入input
input.put(currentKey, currentObj);
//循环执行当前for中的每个判断单元
for (RuleConditionVo child : children) {
if (executeRuleCondition(input, output, child)) {
List<RuleLoopGroupAction> loopGroupActions = child.getLoopGroupActions();
// 调用for循环条件下的操作,并且将其存入input中
for (RuleLoopGroupAction loopGroupAction : loopGroupActions) {
this.saveLoopGroupAction(loopGroupAction, input);
}
}
}
}
//计算for的返回结果
RuleConditionVo loopResultCondition = ruleCondition.getLoopResultCondition();
boolean result = executeRuleCondition(input, output, loopResultCondition);
return result;
}
//保存循环规则的动作
private void saveLoopGroupAction(RuleLoopGroupAction loopGroupAction, Map<String, Object> input) {
Integer actionType = loopGroupAction.getActionType();
String actionKey = loopGroupAction.getActionKey();
String actionValue = loopGroupAction.getActionValue();
if (actionType == null) {
return;
}
switch (actionType) {
case RuleConst.LOOP_GROUP_ACTION_TYPE_SUM:
Integer count = 1;
if (input.containsKey(actionKey) && StringUtils.isNumeric(ExecuteUtils.getObjFromMap(input, actionKey).toString())) {
count = count + Integer.parseInt(ExecuteUtils.getObjFromMap(input, actionKey).toString());
}
input.put(actionKey, count);
break;
case RuleConst.LOOP_GROUP_ACTION_TYPE_ASSIGNMENT:
//赋值待添加
break;
case RuleConst.LOOP_GROUP_ACTION_TYPE_OUT_CONST:
input.put(actionKey, actionValue);
break;
case RuleConst.LOOP_GROUP_ACTION_TYPE_OUT_VARIABLE:
input.put(actionKey, ExecuteUtils.getObjFromMap(input, actionValue));
break;
}
}
private void initLoopGroupAction(RuleLoopGroupAction loopGroupAction, Map<String, Object> input){
Integer actionType = loopGroupAction.getActionType();
String actionKey = loopGroupAction.getActionKey();
String actionValue = loopGroupAction.getActionValue();
if (actionType == null) {
return;
}
switch (actionType) {
case RuleConst.LOOP_GROUP_ACTION_TYPE_SUM:
input.put(actionKey, 0);
break;
case RuleConst.LOOP_GROUP_ACTION_TYPE_ASSIGNMENT:
//赋值待添加
break;
case RuleConst.LOOP_GROUP_ACTION_TYPE_OUT_CONST:
input.put(actionKey, "");
break;
case RuleConst.LOOP_GROUP_ACTION_TYPE_OUT_VARIABLE:
input.put(actionKey,new HashSet<>());
break;
}
}
/**
* 终止条件判断
*
* @param engineNode
* @param inputParam
* @param outMap
* @param ruleHitList
*/
private void terminalCondition(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap, List<RuleInfo> ruleHitList) {
if (StringUtils.isBlank(engineNode.getNodeScript())) {
return;
}
JSONObject nodeScript = JSONObject.parseObject(engineNode.getNodeScript());
JSONObject terminationInfo = nodeScript.getJSONObject("terminationInfo");
JSONArray selectedRule = terminationInfo.getJSONArray("selectedRule");
String conditions = terminationInfo.getString("conditions");
if (!selectedRule.isEmpty()) {
if (!selectedRule.isEmpty()) {
List<JSONObject> selectedRuleList = JSONObject.parseArray(JSONObject.toJSONString(selectedRule), JSONObject.class);
// 查找已选规则中命名的规则集合
List<RuleInfo> selectedHitRules = new ArrayList<>();
for (JSONObject jsonObject : selectedRuleList) {
Optional<RuleInfo> rule = ruleHitList.stream().filter(item -> item.getId().equals(jsonObject.getLong("id"))).findFirst();
if (rule.isPresent()) {
selectedHitRules.add(rule.get());
}
}
int totalSize = selectedHitRules.size(); // 规则命名个数
double totalScore = selectedHitRules.stream().mapToDouble(RuleInfo::getScore).sum(); // 规则总得分
String sizeKey = engineNode.getNodeType() + "_" + engineNode.getNodeId() + "_terminal_size";
String scoreKey = engineNode.getNodeType() + "_" + engineNode.getNodeId() + "_terminal_score";
Map<String, Object> variablesMap = new HashMap<>();
variablesMap.put(sizeKey, totalSize);
variablesMap.put(scoreKey, totalScore);
ExecuteUtils.terminalCondition(engineNode,inputParam,outMap,variablesMap);
}
}
}
private List<RuleInfo> getRuleFromJsonArray(JSONArray jsonArray) {
List<Long> ruleIds = new ArrayList<>();
Map<Long, Long> map = new HashMap<>();
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject ruleObj = jsonArray.getJSONObject(i);
Long versionId = ruleObj.getLong("ruleVersionId");
Long ruleId = ruleObj.getLong("id");
if (ruleId != null) {
ruleIds.add(ruleId);
if (versionId != null) {
map.put(ruleId, versionId);
}
}
}
List<RuleInfo> ruleInfoList = ruleService.getRuleList(ruleIds);
for (RuleInfo ruleInfo : ruleInfoList) {
if (ruleInfo.getDifficulty() == 2 || ruleInfo.getDifficulty() == 3) {
Long versionId = map.get(ruleInfo.getId());
ruleInfo.setVersionId(versionId);
if (versionId != null) {
switch (ruleInfo.getDifficulty()) {
case 2:
RuleVersionVo ruleVersionVo = versionService.queryById(versionId);
ruleInfo.setVersion(ruleVersionVo);
ruleInfo.setScore(ruleVersionVo.getScore());
break;
case 3:
RuleScriptVersion ruleScriptVersion = ruleScriptVersionService.queryById(versionId);
ruleInfo.setScriptVersion(ruleScriptVersion);
ruleInfo.setVersion(JSON.parseObject(JSON.toJSONString(ruleScriptVersion), RuleVersionVo.class));
ruleInfo.setScore(0);
break;
}
} else {
ruleInfo.setScore(0);
}
}
}
return ruleInfoList;
}
/**
* 执行脚本规则
*
* @param inputParam
* @param outMap
* @param rule
* @param ruleResultList
* @return
*/
private boolean executeScriptRule(Map<String, Object> inputParam, Map<String, Object> outMap, RuleInfo rule, CopyOnWriteArrayList<Map> ruleResultList) {
boolean hitFlag = false;
RuleScriptVersion scriptVersion = rule.getScriptVersion();
if (RuleConst.ScriptType.GROOVY.equals(rule.getScriptType())&&RuleConst.ScriptType.GROOVY.equals( scriptVersion.getScriptType())) {
//groovy脚本执行
//取出需要执行的版本
if (scriptVersion == null || StringUtils.isBlank(scriptVersion.getScriptContent())) {
return false;
}
//取出脚本内容
String scriptContent = scriptVersion.getScriptContent();
//取出本规则集的规则列表
Map<String, Object> ruleMap = new HashMap<>();
ruleMap.put("ruleId", rule.getId());
ruleMap.put("ruleVersionId",scriptVersion.getId());
ruleMap.put("ruleCode", rule.getCode());
ruleMap.put("ruleName", rule.getName());
ruleMap.put("versionCode", scriptVersion.getVersionCode());
ruleMap.put("versionDesc", scriptVersion.getDescription());
ruleMap.put("desc", rule.getDescription());
ruleMap.put("ruleResult", "未命中");
String resultFieldEn = "hitResult";
String resultEn = "rule_"+rule.getDifficulty()+"_"+rule.getId()+"_"+scriptVersion.getId()+"_hitResult";
String scoreEn = "rule_"+rule.getDifficulty()+"_"+rule.getId()+"_"+scriptVersion.getId()+"_score";
inputParam.put(resultEn, "未命中");
inputParam.put(scoreEn,0);
//根据执行的最终结果处理此规则输出内容
List fieldList = new ArrayList<>();
JSONObject resultJson = new JSONObject();
try {
Object resp = ExecuteUtils.getObjFromScript(inputParam, scriptContent);
String result = "未命中";
JSONObject executeResult = null;
int ruleScore = 0;
if (resp instanceof HashMap) {
Map resultMap = (HashMap) resp;
executeResult = JSON.parseObject(JSON.toJSONString(resultMap));
ruleScore = executeResult.getIntValue("ruleScore");
result = executeResult.getString(resultFieldEn);
JSONArray fieldListJson = executeResult.getJSONArray("fieldList");
JSONObject updateInputMap = executeResult.getJSONObject("updateInputMap");
if (fieldListJson != null) {
fieldList = fieldListJson.toJavaList(Object.class);
List list = new ArrayList();
for (Object o : fieldList) {
if (o!=null&& o instanceof Map){
Map map = ExecuteUtils.handleGroovyResult((Map) o);
list.add(map);
}
}
fieldList = list;
}
if (executeResult != null) {
ruleMap.put("ruleResult", result);
ruleMap.put("ruleScore", ruleScore);
resultJson.put(resultFieldEn, result);
fieldList.add(resultJson);
inputParam.put(resultFieldEn, result);
//处理此规则需要输出的内容
ruleMap.put("fieldList", fieldList);
}
if ("命中".equals(result)) {
hitFlag = true;
inputParam.put(resultEn,"命中");
inputParam.put(scoreEn,ruleScore);
}
//更新入参
if (updateInputMap!=null&&!updateInputMap.isEmpty()){
Set<Map.Entry<String, Object>> entries = ExecuteUtils.handleGroovyResult(updateInputMap).entrySet();
for (Map.Entry<String, Object> entry : entries) {
inputParam.put(entry.getKey(),entry.getValue());
}
}
}
} catch (Exception e) {
e.printStackTrace();
logger.error("脚本规则集执行错误:{}" + e);
}
ruleResultList.add(ruleMap);
}
return hitFlag;
}
// public static void main(String[] args) {
//// HashMap<String, Object> result = new HashMap<>(); //规则执行的返回值
//// int ruleScore = 0; //规则命中时得分
//// String hitResult = "未命中"; //命中结果,可选类型为:命中、未命中
//// HashMap<String, Object> updateInputMap = new HashMap<>(); //用于更新入参的map此map中的所有内容将被更新到入参中,key重复的将被覆盖。
//// ArrayList<HashMap<String, Object>> fieldList = new ArrayList<>(); //用于存放输出字段的值
//// //自定义代码区域,根据需要书写逻辑代码
////
////
////
//// //返回固定格式的结果用于后续执行
//// result.put("hitResult",hitResult);
//// result.put("ruleScore",ruleScore);
//// result.put("fieldList",fieldList);
//// result.put("updateInputMap",updateInputMap);
//// return result;
// }
}

View File

@@ -0,0 +1,114 @@
package com.fibo.ddp.enginex.runner.node.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.model.enginex.runner.Sandbox;
import com.fibo.ddp.enginex.runner.node.EngineRunnerNode;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
@Service
public class SandboxProportionNode implements EngineRunnerNode {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void getNodeField(EngineNode engineNode, Map<String, Object> inputParam) {
}
@Override
public void runNode(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap) {
if (null != engineNode.getNodeScript()) {
List<Sandbox> list = JSON.parseArray(engineNode.getNodeScript(), Sandbox.class);
//监控中心-- 节点配置信息记录(不需要策略层面的监控)
JSONObject nodeSnapshot = new JSONObject();
nodeSnapshot.put("nodeSnapshot",JSON.parseArray(engineNode.getNodeJson()));
outMap.put("nodeSnapshot",nodeSnapshot);
JSONObject nodeInfo = new JSONObject();
nodeInfo.put("engineNode",engineNode);
nodeInfo.put("nodeId",engineNode.getNodeId());
nodeInfo.put("nodeName",engineNode.getNodeName());
nodeInfo.put("nodeType",engineNode.getNodeType());
outMap.put("nodeInfo",nodeInfo);
int num = 0;//随机生成的数
int startNum = 0;
int endNum = 0;
for (int i = 0; i < list.size(); i++) {
Sandbox sandbox = list.get(i);
endNum = startNum + sandbox.getProportion();
if (num == 0)
num = getRandoms(0, sandbox.getSum(), 1)[0];
int[] range = getRandoms(startNum, endNum, sandbox.getProportion());
for (int j = 0; j < range.length; j++) {
if (range[j] == num) {
if (StringUtils.isBlank(sandbox.getNextNode())) {
List<Sandbox> sblist = JSON.parseArray(engineNode.getNodeJson(), Sandbox.class);
for (Sandbox sb : sblist) {
if (sb.getSandbox() == sandbox.getSandbox()) {
sandbox.setNextNode(sb.getNextNode());
break;
}
}
}
outMap.put("nextNode", sandbox.getNextNode());
JSONObject nodeResult = new JSONObject();
nodeResult.put("nodeResult",sandbox.getNextNode());
outMap.put("nodeResult",nodeResult);
break;
}
}
startNum = endNum;
}
}
}
/**
* 根据min和max随机生成count个不重复的随机数组
*
* @param min
* @param max
* @param count
* @return int[]
*/
public int[] getRandoms(int min, int max, int count) {
int[] randoms = new int[count];
List<Integer> listRandom = new ArrayList<Integer>();
if (count > (max - min + 1)) {
return null;
}
// 将所有的可能出现的数字放进候选list
for (int i = min; i < max; i++) {
listRandom.add(i);
}
// 从候选list中取出放入数组已经被选中的就从这个list中移除
for (int i = 0; i < count; i++) {
int index = getRandom(0, listRandom.size() - 1);
randoms[i] = listRandom.get(index);
listRandom.remove(index);
}
return randoms;
}
/**
* 根据min和max随机生成一个范围在[min,max]的随机数包括min和max
*
* @param min
* @param max
* @return int
*/
public int getRandom(int min, int max) {
Random random = new Random();
return random.nextInt(max - min + 1) + min;
}
}

View File

@@ -0,0 +1,264 @@
package com.fibo.ddp.enginex.runner.node.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.model.datax.datamanage.Field;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.model.strategyx.scorecard.ScorecardDetail;
import com.fibo.ddp.common.model.strategyx.scorecard.ScorecardDimension;
import com.fibo.ddp.common.model.strategyx.scorecard.vo.ScorecardDetailVo;
import com.fibo.ddp.common.model.strategyx.scorecard.vo.ScorecardDimensionVo;
import com.fibo.ddp.common.model.strategyx.scorecard.vo.ScorecardVersionVo;
import com.fibo.ddp.common.model.strategyx.scorecard.vo.ScorecardVo;
import com.fibo.ddp.common.service.datax.datamanage.FieldService;
import com.fibo.ddp.common.service.datax.runner.CommonService;
import com.fibo.ddp.common.service.datax.runner.ExecuteUtils;
import com.fibo.ddp.common.service.strategyx.scorecard.ScorecardDetailService;
import com.fibo.ddp.common.service.strategyx.scorecard.ScorecardDimensionService;
import com.fibo.ddp.common.service.strategyx.scorecard.ScorecardService;
import com.fibo.ddp.common.utils.util.runner.JevalUtil;
import com.fibo.ddp.common.utils.util.runner.StrUtils;
import com.fibo.ddp.common.utils.util.runner.jeval.EvaluationException;
import com.fibo.ddp.enginex.runner.node.EngineRunnerNode;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class ScorecardNode implements EngineRunnerNode {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private CommonService commonService;
@Resource
public FieldService fieldService;
@Resource
public ScorecardService scorecardService;
@Autowired
private ScorecardDimensionService scorecardDimensionService; // 维度
@Autowired
private ScorecardDetailService scorecardDetailService; // 明细
private List<Long> getExecuteVersionIdList(EngineNode engineNode) {
return ExecuteUtils.getExecuteIdList(engineNode,"versionId");
}
@Override
public void getNodeField(EngineNode engineNode, Map<String, Object> inputParam) {
List<Long> versionIdList = getExecuteVersionIdList(engineNode);
Set<Long> fieldIdSet = new HashSet<>();
for (Long versionId : versionIdList) {
List<ScorecardDimension> scorecardDimensions = scorecardDimensionService.getDimensionListByVersionId(versionId);
List<Integer> dimensionIds = scorecardDimensions.stream().map(item -> item.getId()).collect(Collectors.toList());
List<ScorecardDetail> scorecardDetails = scorecardDetailService.getDetailListByDimensionIds(dimensionIds);
fieldIdSet.addAll(scorecardDetails.stream().map(item -> Long.valueOf(item.getFieldId().toString())).collect(Collectors.toSet()));
}
List<Long> ids = new ArrayList<>(fieldIdSet);
commonService.getFieldByIds(ids, inputParam);
}
@Override
public void runNode(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap) {
//监控中心--节点快照信息
if (engineNode != null && engineNode.getSnapshot() != null) {
outMap.put("nodeSnapshot", engineNode.getSnapshot());
}
List<Long> versionIdList = getExecuteVersionIdList(engineNode);
for (Long versionId : versionIdList) {
ScorecardVo scorecard = scorecardService.queryExecuteScorecard(versionId);
JSONObject nodeInfo = new JSONObject();
nodeInfo.put("engineNode", engineNode);
nodeInfo.put("nodeId", engineNode.getNodeId());
nodeInfo.put("nodeName", engineNode.getNodeName());
nodeInfo.put("nodeType", engineNode.getNodeType());
outMap.put("nodeInfo", nodeInfo);
List<ScorecardDetail> hitDetailList = new ArrayList<>(); // 命中的评分字段列表
ScorecardVersionVo versionVo = scorecard.getExecuteVersion();
List<ScorecardDimensionVo> scorecardDimensions = new ArrayList<>();
if (versionVo != null) {
//监控中心 == 策略层面快照信息
if (versionVo != null && versionVo.getSnapshot() != null) {
outMap.put("scorecardStrategy", versionVo.getSnapshot());
}
scorecardDimensions = versionVo.getScorecardDimension();
for (ScorecardDimensionVo scorecardDimensionVo : scorecardDimensions) {
List<ScorecardDetailVo> scorecardDetailVoList = scorecardDimensionVo.getChildren();
scorecardHit(hitDetailList, 0, scorecardDetailVoList, inputParam);
}
}
Double totalScore = 0d;
List<JSONObject> scoreDetail = new ArrayList<>();
for (ScorecardDimension scorecardDimension : scorecardDimensions) {
Double dimensionScore = 0d;
JSONObject jsonObject = new JSONObject();
jsonObject.put("dimensionName", scorecardDimension.getDimensionName());
jsonObject.put("dimensionId", scorecardDimension.getId());
for (ScorecardDetail scorecardDetail : hitDetailList) {
if (!scorecardDetail.getDimensionId().equals(scorecardDimension.getId())) {
continue;
}
String fieldEn = scorecardDetail.getFieldEn();
Integer scoreCalculateType = scorecard.getScoreCalculateType();
Integer calculateType = scorecardDetail.getCalculateType();
// 计算方式为 得分
if (calculateType == 1) {
if (scoreCalculateType == 1) { // 评分计算方式为 求和
Double value = scorecardDetail.getScore();
totalScore += value;
dimensionScore += value;
} else if (scoreCalculateType == 2) { // 评分计算方式为 加权求和
Double value = scorecardDetail.getScore() * scorecardDimension.getWeight();
totalScore += value;
dimensionScore += value;
}
}
// 计算方式为 系数
else if (calculateType == 2) {
if (scoreCalculateType == 1) { // 评分计算方式为 求和
Double value = Double.valueOf(inputParam.get(fieldEn).toString()) * scorecardDetail.getCoefficient();
totalScore += value;
dimensionScore += value;
} else if (scoreCalculateType == 2) { // 评分计算方式为 加权求和
Double value = Double.valueOf(inputParam.get(fieldEn).toString()) * scorecardDetail.getCoefficient() * scorecardDimension.getWeight();
totalScore += value;
dimensionScore += value;
}
}
// 计算方式为 自定义
else if (calculateType == 3) {
double value = 0d;
String custom = scorecardDetail.getCustom();
if (custom != null && !"".equals(custom)) {
Double result = StrUtils.strToDouble(ExecuteUtils.getObjFromScript(inputParam, custom).toString());
if (result != null) {
value = result;
}
}
totalScore += value;
dimensionScore += value;
}
}
jsonObject.put("score", dimensionScore);
scoreDetail.add(jsonObject);
}
JSONObject jsonObject = new JSONObject();
jsonObject.put("nodeId", engineNode.getNodeId());
jsonObject.put("nodeName", engineNode.getNodeName());
jsonObject.put("cardId", scorecard.getId());
jsonObject.put("cardName", scorecard.getName());
jsonObject.put("cardCode", scorecard.getCode());
String versionCode = "";
Long cardVersionId = null;
if (versionVo != null) {
versionCode = versionVo.getVersionCode();
cardVersionId = versionVo.getId();
}
jsonObject.put("cardVersion", versionCode);
jsonObject.put("cardVersionId",cardVersionId);
jsonObject.put("desc", scorecard.getDescription());
jsonObject.put("score", totalScore);
jsonObject.put("scoreDetail", scoreDetail);
//给入参中放入评分卡执行结果
String resultFieldEn = versionVo.getResultFieldEn();
if (StringUtils.isBlank(resultFieldEn)) {
resultFieldEn = engineNode.getNodeType() + "_" + engineNode.getNodeId() + "_" + versionVo.getId() + "_score";
}
inputParam.put(resultFieldEn, totalScore);
inputParam.put(scorecard.getCode(), totalScore);
List<JSONObject> fieldList = new ArrayList<>();
JSONObject scoreResult = new JSONObject();
scoreResult.put(resultFieldEn, totalScore);
fieldList.add(scoreResult);
if (totalScore != 0) {
List<JSONObject> jsonObjects = scorecardService.setOutput(scorecard.getId(), inputParam);
fieldList.addAll(jsonObjects);
}
jsonObject.put("fieldList", fieldList);
//监控中心==》将评分卡的执行结果得分明细放入 输出变量池 用于存入hbase
outMap.put("nodeResult", jsonObject);
if (outMap.containsKey("scoreJson")) {
JSONArray resultJson = (JSONArray) outMap.get("scoreJson");
resultJson.add(jsonObject);
} else {
JSONArray resultJson = new JSONArray();
resultJson.add(jsonObject);
outMap.put("scoreJson", resultJson);
}
terminalCondition(engineNode,inputParam,outMap,totalScore);
}
}
/**
* 评分卡命中判断
*
* @param hitDetailList
* @param detailId
* @param scorecardDetailVoList
* @param inputParam
*/
private void scorecardHit(List<ScorecardDetail> hitDetailList, Integer detailId, List<ScorecardDetailVo> scorecardDetailVoList, Map<String, Object> inputParam) {
List<ScorecardDetailVo> scorecardDetailVos = scorecardDetailVoList.stream().filter(item -> item.getParentId().equals(detailId)).collect(Collectors.toList());
for (ScorecardDetailVo scorecardDetailVo : scorecardDetailVos) {
Field field = fieldService.queryById(Long.valueOf(scorecardDetailVo.getFieldId()));
String fieldEn = field.getFieldEn();
scorecardDetailVo.setFieldEn(fieldEn);
String condition = scorecardDetailVo.getCondition();
Boolean isHit = isScoreFieldValue(inputParam, fieldEn, condition);
if (isHit) {
if (scorecardDetailVo.getType() == 1) {
hitDetailList.add(scorecardDetailVo);
} else {
this.scorecardHit(hitDetailList, scorecardDetailVo.getId(), scorecardDetailVoList, inputParam);
}
}
}
}
/**
* 评分卡字段是否在区间内
*
* @param map
* @param fieldCode
* @param condition
* @return
*/
private Boolean isScoreFieldValue(Map<String, Object> map, String fieldCode, String condition) {
if ("(,)".equals(condition)) {
return true;
}
String exp = JevalUtil.getNumericInterval(condition, fieldCode);
try {
if (JevalUtil.evaluateBoolean(exp, map)) {
return true;
}
} catch (EvaluationException e) {
e.printStackTrace();
logger.error("请求异常", e);
}
return false;
}
private void terminalCondition(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap,Object executeResult) {
String resultKey = engineNode.getNodeType() + "_" + engineNode.getNodeId() + "_terminal_score";
Map<String,Object> map = new HashMap<>();
map.put(resultKey,executeResult);
ExecuteUtils.terminalCondition(engineNode,inputParam,outMap, map);
}
}