feats: 增加 Rest 请求数据插件。

Signed-off-by: feihu.wang <wfh45678@163.com>
This commit is contained in:
feihu.wang
2019-11-14 18:52:52 +08:00
parent e12b9d3831
commit c5ea622de4
12 changed files with 140 additions and 49 deletions

View File

@@ -2,6 +2,7 @@ package com.pgmmers.radar.controller;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.pgmmers.radar.dal.bean.AbstractionQuery;
import com.pgmmers.radar.enums.PluginType;
import com.pgmmers.radar.service.common.CommonResult;
@@ -19,6 +20,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@RestController
@RequestMapping("/services/v1/abstraction")
@@ -70,21 +72,20 @@ public class AbstractionApiController {
// 2、PREPARE
ds = new DataColumnInfo(DataType.PREITEMS.getDesc(), DataType.PREITEMS.getName());
List<PreItemVO> listPreItem = preItemService.listPreItem(modelId);
if(listPreItem!=null&&listPreItem.size()!=0){
if(listPreItem != null && listPreItem.size()!= 0){
for (PreItemVO preItem : listPreItem) {
PluginType pt = PluginType.get(preItem.getPlugin());
if (StringUtils.isNoneBlank(pt.getType())) {
if (StringUtils.isNotEmpty(pt.getType()) && pt.getType().equals("JSON")) {
//load http request data
JsonNode json = preItem.getConfigJson();
List<DataColumnInfo> children = new ArrayList<>();
extractMetaColumn(ds, preItem, json.toString(), children);
} else if (StringUtils.isNotEmpty(pt.getType())) {
ds.addChildren(preItem.getLabel(), preItem.getDestField(), pt.getType());
} else {
List<DataColumnInfo> children = new ArrayList<>();
JSONArray array = JSONArray.parseArray(pt.getMeta());
for (int i = 0; i < array.size(); i++) {
JSONObject obj = array.getJSONObject(i);
children.add(new DataColumnInfo(obj.getString("title"), obj.getString("column"), obj
.getString("type")));
}
ds.addChildren(preItem.getLabel(), preItem.getDestField(), children);
}
extractMetaColumn(ds, preItem, pt.getMeta(), children);
}
}
list.add(ds);
}
@@ -95,7 +96,17 @@ public class AbstractionApiController {
return result;
}
@PutMapping
private void extractMetaColumn(DataColumnInfo ds, PreItemVO preItem, String jsonStr, List<DataColumnInfo> children) {
JSONArray array = JSONArray.parseArray(jsonStr);
for (int i = 0; i < array.size(); i++) {
JSONObject obj = array.getJSONObject(i);
children.add(new DataColumnInfo(obj.getString("title"), obj.getString("column"), obj
.getString("type")));
}
ds.addChildren(preItem.getLabel(), preItem.getDestField(), children);
}
@PutMapping
public CommonResult save(@RequestBody AbstractionVO abstraction) {
return abstractionService.save(abstraction);
}

View File

@@ -3,6 +3,7 @@ package com.pgmmers.radar.controller;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.pgmmers.radar.dal.bean.ActivationQuery;
import com.pgmmers.radar.enums.FieldType;
import com.pgmmers.radar.enums.PluginType;
@@ -67,17 +68,16 @@ public class ActivationApiController {
List<PreItemVO> listPreItem = preItemService.listPreItem(modelId);
for (PreItemVO preItem : listPreItem) {
PluginType pt = PluginType.get(preItem.getPlugin());
if (StringUtils.isNoneBlank(pt.getType())) {
if (StringUtils.isNotEmpty(pt.getType()) && pt.getType().equals("JSON")) {
//load http request data
JsonNode json = preItem.getConfigJson();
List<DataColumnInfo> children = new ArrayList<>();
extractMetaColumn(ds, preItem, json.toString(), children);
} else if (StringUtils.isNotEmpty(pt.getType())) {
ds.addChildren(preItem.getLabel(), preItem.getDestField(), pt.getType());
} else {
List<DataColumnInfo> children = new ArrayList<>();
JSONArray array = JSONArray.parseArray(pt.getMeta());
for (int i = 0; i < array.size(); i++) {
JSONObject obj = array.getJSONObject(i);
children.add(new DataColumnInfo(obj.getString("title"), obj.getString("column"), obj
.getString("type")));
}
ds.addChildren(preItem.getLabel(), preItem.getDestField(), children);
extractMetaColumn(ds, preItem, pt.getMeta(), children);
}
}
list.add(ds);
@@ -133,5 +133,15 @@ public class ActivationApiController {
@PostMapping("/updateOrder")
public CommonResult updateOrder(@RequestParam Long activationId, @RequestParam String ruleOrder) {
return activationService.updateOrder(activationId,ruleOrder);
}
}
private void extractMetaColumn(DataColumnInfo ds, PreItemVO preItem, String jsonStr, List<DataColumnInfo> children) {
JSONArray array = JSONArray.parseArray(jsonStr);
for (int i = 0; i < array.size(); i++) {
JSONObject obj = array.getJSONObject(i);
children.add(new DataColumnInfo(obj.getString("title"), obj.getString("column"), obj
.getString("type")));
}
ds.addChildren(preItem.getLabel(), preItem.getDestField(), children);
}
}

View File

@@ -233,7 +233,7 @@ public class ModelDalImpl implements ModelDal {
PreItemVO vo = null;
for (PreItemPO po : itemPOList) {
vo = new PreItemVO();
BeanUtils.copyProperties(po, vo);
vo = POVOUtils.copyFromPreItemPO(po);
itemList.add(vo);
}
return itemList;

View File

@@ -16,13 +16,13 @@ public enum PluginType {
"ip2location",
"IP转换成地址",
null,
"[{\"column\":\"country\", \"title\":\"国家\", \"type\":\"STRING\"},{\"column\":\"provice\", \"title\":\"省份\", \"type\":\"STRING\"},{\"column\":\"city\", \"title\":\"城市\", \"type\":\"STRING\"}]"), //
"[{\"column\":\"country\", \"title\":\"国家\", \"type\":\"STRING\"},{\"column\":\"province\", \"title\":\"省份\", \"type\":\"STRING\"},{\"column\":\"city\", \"title\":\"城市\", \"type\":\"STRING\"}]"), //
GPS2LOCATION(
2,
"gps2location",
"GPS转换成地址",
null,
"[{\"column\":\"country\", \"title\":\"国家\", \"type\":\"STRING\"},{\"column\":\"provice\", \"title\":\"省份\", \"type\":\"STRING\"},{\"column\":\"city\", \"title\":\"城市\", \"type\":\"STRING\"}]"), //
"[{\"column\":\"country\", \"title\":\"国家\", \"type\":\"STRING\"},{\"column\":\"province\", \"title\":\"省份\", \"type\":\"STRING\"},{\"column\":\"city\", \"title\":\"城市\", \"type\":\"STRING\"}]"), //
ALLINONE(3, "allInOne", "字段合并", "STRING", null), //
SUBSTRING(4, "subString", "字符串截短", "STRING", null), //
MOBILE2LOCATION(
@@ -30,10 +30,10 @@ public enum PluginType {
"mobile2location",
"手机号码归属地",
null,
"[{\"column\":\"country\", \"title\":\"国家\", \"type\":\"STRING\"},{\"column\":\"provice\", \"title\":\"省份\", \"type\":\"STRING\"},{\"column\":\"city\", \"title\":\"城市\", \"type\":\"STRING\"}]"), //
"[{\"column\":\"country\", \"title\":\"国家\", \"type\":\"STRING\"},{\"column\":\"province\", \"title\":\"省份\", \"type\":\"STRING\"},{\"column\":\"city\", \"title\":\"城市\", \"type\":\"STRING\"}]"), //
SENSITIVE_TIME(6, "getSensitiveTime", "敏感时间段(小时)", "STRING", null),
DATEFORMAT(7, "formatDate", "日期时间格式化", "STRING", null),
RESTUTIL(8, "doRest", "RestUtil", "STRING", null),
HTTP_UTIL(8, "httpRequest", "HttpUtil", "JSON", null),
;
private Integer key;

View File

@@ -0,0 +1,25 @@
package com.pgmmers.radar.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory){
return new RestTemplate(factory);
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
//ms
factory.setReadTimeout(5000);
factory.setConnectTimeout(5000);
return factory;
}
}

View File

@@ -61,5 +61,10 @@
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@@ -120,7 +120,7 @@ public class AntiFraudServiceImpl implements AntiFraudService {
jsonInfo.get(sourceField[1]).toString());
break;
case ALLINONE:
List<Object> values = new ArrayList<Object>();
List<Object> values = new ArrayList<>();
for (String field : sourceField) {
values.add(jsonInfo.get(field));
}
@@ -142,11 +142,16 @@ public class AntiFraudServiceImpl implements AntiFraudService {
millis = Long.parseLong(jsonInfo.get(sourceField[0]).toString());
transfer = pluginService.formatDate(millis, formatStr);
break;
case HTTP_UTIL:
String url = item.getArgs();
String reqType = item.getReqType();
String arg = jsonInfo.get(sourceField[0]).toString();
transfer = pluginService.httpRequest(url, reqType, arg);
break;
default:
}
result.put(item.getDestField(), transfer);
//result.put(plugin.getFieldName(), transfer);
}
return result;
}

View File

@@ -1,6 +1,7 @@
package com.pgmmers.radar.service.impl.engine;
import com.alibaba.fastjson.JSONObject;
import com.pgmmers.radar.enums.CombineType;
import com.pgmmers.radar.service.data.MobileInfoService;
import com.pgmmers.radar.service.engine.PluginService;
@@ -17,7 +18,9 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import javax.annotation.PostConstruct;
import java.util.Calendar;
@@ -37,6 +40,9 @@ public class PluginServiceImpl implements PluginService {
@Autowired
private MobileInfoService mobileInfoService;
@Autowired
private RestTemplate restTemplate;
@PostConstruct
public void init() {
try {
@@ -53,14 +59,13 @@ public class PluginServiceImpl implements PluginService {
if (!Util.isIpAddress(ip)) {
return null;
}
;
try {
DataBlock block = ipSearcher.memorySearch(ip);
String[] detail = block.getRegion().split("\\|");
location = new Location();
location.setCountry(detail[0]);
location.setRegion(detail[1]);
location.setProvice(detail[2]);
location.setProvince(detail[2]);
location.setCity(detail[3]);
location.setAddress(detail[4]);
} catch (Exception e) {
@@ -111,7 +116,7 @@ public class PluginServiceImpl implements PluginService {
MobileInfoVO vo = mobileInfoService.getMobileInfoByMobile(mobile);
Location location = new Location();
if (vo != null) {
location.setProvice(vo.getProvince());
location.setProvince(vo.getProvince());
location.setCity(vo.getCity());
location.setCountry("中国");
}
@@ -131,4 +136,15 @@ public class PluginServiceImpl implements PluginService {
return dateStr;
}
@Override
public JSONObject httpRequest(String url, String reqType, String... args) {
HttpHeaders headers = new HttpHeaders();
HttpEntity<String> entity = new HttpEntity<>(headers);
ResponseEntity<JSONObject> responseEntity = restTemplate.exchange(url, HttpMethod.valueOf(reqType), entity, JSONObject.class, args);
if (responseEntity.getStatusCode() == HttpStatus.OK) {
return responseEntity.getBody();
}
return null;
}
}

View File

@@ -1,5 +1,6 @@
package com.pgmmers.radar.service.engine;
import com.alibaba.fastjson.JSONObject;
import com.pgmmers.radar.service.engine.vo.Location;
import java.util.List;
@@ -51,5 +52,22 @@ public interface PluginService {
String getSensitiveTime(Long timeMills);
/**
* date format by format str, like yyyyMMdd.
* @param timeMills
* @param format
* @return
* @author feihu.wang
*/
String formatDate(Long timeMills, String format);
/**
* http util.
* @param url
* @param reqType
* @param args
* @return
* @author feihu.wang
*/
JSONObject httpRequest(String url, String reqType, String ...args);
}

View File

@@ -6,7 +6,7 @@ public class Location {
private String region = "";
private String provice = "";
private String province = "";
private String city = "";
@@ -28,12 +28,12 @@ public class Location {
this.region = region;
}
public String getProvice() {
return provice;
public String getProvince() {
return province;
}
public void setProvice(String provice) {
this.provice = provice;
public void setProvince(String province) {
this.province = province;
}
public String getCity() {

View File

@@ -23,6 +23,7 @@ export default class AddPreItem extends React.Component{
plugin:'',
status:1,
args:'',
reqType:'GET',
configJson:''
}
}
@@ -80,7 +81,7 @@ export default class AddPreItem extends React.Component{
plugin:'',
status:1,
args:'',
reqType:1,
reqType:'GET',
visible:true,
configJson:''
})
@@ -287,12 +288,12 @@ export default class AddPreItem extends React.Component{
</Col>
</Row>
</FormItem>
<FormItem required={true} {...formItemLayout} label="请求信息" style={plugin=='RESTUTIL'?{}:{display:"none"}} help={validate.args.help} validateStatus={validate.args.status}>
<FormItem required={true} {...formItemLayout} label="请求信息" style={plugin=='HTTP_UTIL'?{}:{display:"none"}} help={validate.args.help} validateStatus={validate.args.status}>
<Row>
<Col span={20}>
<Radio.Group name="reqType" onChange={this.handleChange} value={this.state.reqType}>
<Radio value={1}>GET</Radio>
<Radio value={2}>POST</Radio>
<Radio value={'GET'}>GET</Radio>
<Radio disabled={true} value={'POST'}>POST</Radio>
</Radio.Group>
</Col>
<Col span={2} offset={1}>
@@ -307,17 +308,17 @@ export default class AddPreItem extends React.Component{
<Input type="text" name="args" value={this.state.args} onChange={this.handleChange}/>
</Col>
<Col span={2} offset={1}>
<Tooltip placement="right" title={'Rest url, like http://xxx/getSth'}>
<Tooltip placement="right" title={'Rest url, like http://xxx/getSth?id={1}'}>
<Icon style={{fontSize:16}} type="question-circle-o" />
</Tooltip>
</Col>
</Row>
<Row>
<Col span={20}>
<Input.TextArea name="configJson" value={this.state.configJson} onChange={(e)=>this.handleChange(e)} rows={4} placeholder="请输入响应结果字段描叙信息" />
<Input.TextArea name="configJson" value={this.state.configJson} onChange={(e)=>this.handleChange(e)} rows={4} placeholder="请输入响应结果字段描叙信息json数组" />
</Col>
<Col span={2} offset={1}>
<Tooltip placement="right" title={'响应字段元信息'}>
<Tooltip placement="right" title={'响应字段元信息, like:[{"column":"country","title":"国家","type":"STRING"},{"column":"province","title":"省份","type":"STRING"}]'}>
<Icon style={{fontSize:16}} type="question-circle-o" />
</Tooltip>
</Col>

View File

@@ -23,7 +23,7 @@ export default class EditPreItem extends React.Component{
plugin:'',
status:1,
args:'',
reqType:1,
reqType:'GET',
configJson:'',
preItem:null
}
@@ -283,12 +283,12 @@ export default class EditPreItem extends React.Component{
</FormItem>
<FormItem required={true} {...formItemLayout} label="请求信息" style={plugin=='RESTUTIL'?{}:{display:"none"}} help={validate.args.help} validateStatus={validate.args.status}>
<FormItem required={true} {...formItemLayout} label="请求信息" style={plugin=='HTTP_UTIL'?{}:{display:"none"}} help={validate.args.help} validateStatus={validate.args.status}>
<Row>
<Col span={20}>
<Radio.Group name="reqType" onChange={this.handleChange} value={this.state.reqType}>
<Radio value={1}>GET</Radio>
<Radio value={2}>POST</Radio>
<Radio value={'GET'}>GET</Radio>
<Radio disabled={true} value={'POST'}>POST</Radio>
</Radio.Group>
</Col>
<Col span={2} offset={1}>
@@ -303,17 +303,17 @@ export default class EditPreItem extends React.Component{
<Input type="text" name="args" value={this.state.args} onChange={this.handleChange}/>
</Col>
<Col span={2} offset={1}>
<Tooltip placement="right" title={'Rest url, like http://xxx/getSth'}>
<Tooltip placement="right" title={'Rest url, like http://xxx/getSth?id={1}'}>
<Icon style={{fontSize:16}} type="question-circle-o" />
</Tooltip>
</Col>
</Row>
<Row>
<Col span={20}>
<Input.TextArea name="configJson" value={this.state.configJson} onChange={(e)=>this.handleChange(e)} rows={4} placeholder="请输入响应结果字段描叙信息" />
<Input.TextArea name="configJson" value={this.state.configJson} onChange={(e)=>this.handleChange(e)} rows={4} placeholder="请输入响应结果字段描叙信息json数组" />
</Col>
<Col span={2} offset={1}>
<Tooltip placement="right" title={'响应字段元信息'}>
<Tooltip placement="right" title={'响应字段元信息like:[{"column":"country","title":"国家","type":"STRING"},{"column":"province","title":"省份","type":"STRING"}]'}>
<Icon style={{fontSize:16}} type="question-circle-o" />
</Tooltip>
</Col>