Commit 6bfbbc62 authored by wuxw7's avatar wuxw7
Browse files

加入 接口透传功能

parent ee9aff69
Showing with 377 additions and 19 deletions
+377 -19
......@@ -43,6 +43,17 @@ public class CenterServiceApplicationStart {
return restTemplate;
}
/**
* 实例化RestTemplate
* @return restTemplate
*/
@Bean
public RestTemplate restTemplateNoLoadBalanced() {
StringHttpMessageConverter m = new StringHttpMessageConverter(Charset.forName("UTF-8"));
RestTemplate restTemplate = new RestTemplateBuilder().additionalMessageConverters(m).build();
return restTemplate;
}
public static void main(String[] args) throws Exception{
ApplicationContext context = SpringApplication.run(CenterServiceApplicationStart.class, args);
......
......@@ -4,21 +4,21 @@ import com.alibaba.fastjson.JSONObject;
import com.java110.center.smo.ICenterServiceSMO;
import com.java110.common.constant.ResponseConstant;
import com.java110.common.exception.BusinessException;
import com.java110.common.util.Assert;
import com.java110.core.factory.DataTransactionFactory;
import com.java110.core.base.controller.BaseController;
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 org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
/**
* 中心http服务 统一服务类
* 1、只提供service方法
* 2、提供 透传机制
* Created by wuxw on 2018/4/13.
*/
@RestController
......@@ -48,15 +48,59 @@ public class HttpApi extends BaseController {
}
}
/**
* 对协议不遵循的 接口进行透传
* @param orderInfo
* @param request
* @return
*/
@RequestMapping(path = "/httpApi/service/{serviceCode}",method= RequestMethod.POST)
public String servicePostTransfer(@PathVariable String serviceCode, @RequestBody String orderInfo, HttpServletRequest request,
HttpServletResponse response) {
String resData = "";
Map<String, String> headers = new HashMap<String, String>();
try {
headers.put("serviceCode",serviceCode);
getRequestInfo(request, headers);
//预校验
preValiateOrderInfo(orderInfo,headers);
resData = centerServiceSMOImpl.serviceTransfer(orderInfo, headers);
}catch (Exception e){
logger.error("请求订单异常",e);
resData = DataTransactionFactory.createOrderResponseJson(ResponseConstant.NO_TRANSACTION_ID,
ResponseConstant.RESULT_CODE_ERROR,e.getMessage()+e).toJSONString();
}finally {
for(String key : headers.keySet()) {
response.addHeader(key,headers.get(key));
}
return resData;
}
}
/**
* 这里预校验,请求报文中不能有 dataFlowId
* @param orderInfo
*/
private void preValiateOrderInfo(String orderInfo) {
if(JSONObject.parseObject(orderInfo).getJSONObject("orders").containsKey("dataFlowId")){
throw new BusinessException(ResponseConstant.RESULT_CODE_ERROR,"报文中不能存在dataFlowId节点");
}
}
/**
* 这里预校验,请求报文中不能有 dataFlowId
* @param orderInfo
*/
private void preValiateOrderInfo(String orderInfo,Map<String, String> headers) {
Assert.hasKey(headers,"serviceCode","没有包含serviceCode");
Assert.hasLength(headers.get("serviceCode"),"serviceCode 不能为空");
Assert.hasKey(headers,"appId","没有包含appId");
Assert.hasLength(headers.get("appId"),"appId 不能为空");
}
/**
* 获取请求信息
......
......@@ -18,6 +18,15 @@ public interface ICenterServiceSMO {
*/
public String service(String reqJson, Map<String,String> headers) throws SMOException;
/**
* 透传业务
* @param reqJson
* @param headers
* @return
* @throws SMOException
*/
public String serviceTransfer(String reqJson, Map<String,String> headers) throws SMOException;
/**
* 接受业务系统通知消息
* @param receiveJson 接受报文
......
......@@ -21,6 +21,8 @@ import com.java110.event.center.DataFlowEventPublishing;
import com.java110.service.smo.IQueryServiceSMO;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
......@@ -42,6 +44,9 @@ public class CenterServiceSMOImpl extends LoggerEngine implements ICenterService
@Autowired
private RestTemplate restTemplate;
@Autowired
private RestTemplate restTemplateNoLoadBalanced;
@Autowired
private IQueryServiceSMO queryServiceSMOImpl;
......@@ -135,6 +140,93 @@ public class CenterServiceSMOImpl extends LoggerEngine implements ICenterService
}
/**
* 透传处理
* @param reqJson
* @param headers
* @return
* @throws SMOException
*/
@Override
public String serviceTransfer(String reqJson, Map<String, String> headers) throws SMOException {
DataFlow dataFlow = null;
String responseData = null;
String resJson = "";
try {
reqJson = decrypt(reqJson,headers);
//1.0 创建数据流
dataFlow = DataFlowFactory.newInstance(DataFlow.class).builderTransfer(reqJson, headers);
//2.0 加载配置信息
initConfigData(dataFlow);
//3.0 校验 APPID是否有权限操作serviceCode
judgeAuthority(dataFlow);
//4.0 调用规则校验
ruleValidate(dataFlow);
//5.0 保存订单和业务项 c_orders c_order_attrs c_business c_business_attrs
//saveOrdersAndBusiness(dataFlow);
//6.0 调用下游系统
transferInvokeBusinessSystem(dataFlow);
responseData = DataTransactionFactory.createCommonResData(dataFlow);
} catch (DecryptException e){ //解密异常
responseData = DataTransactionFactory.createOrderResponseJson(ResponseConstant.NO_TRANSACTION_ID,
e.getResult().getCode(), e.getMessage()).toJSONString();
} catch (RuleException e) {
responseData = DataTransactionFactory.createOrderResponseJson(dataFlow.getTransactionId(),
e.getResult().getCode(), e.getMessage()).toJSONString();
} catch (NoAuthorityException e) {
responseData = DataTransactionFactory.createOrderResponseJson(dataFlow.getTransactionId(),
e.getResult().getCode(), e.getMessage()).toJSONString();
} catch (InitConfigDataException e){
responseData = DataTransactionFactory.createOrderResponseJson(dataFlow.getTransactionId(),
e.getResult().getCode(), e.getMessage()).toJSONString();
}catch (Exception e) {
logger.error("内部异常了:",e);
responseData = DataTransactionFactory.createOrderResponseJson(dataFlow == null
? ResponseConstant.NO_TRANSACTION_ID
: dataFlow.getTransactionId(),
ResponseConstant.RESULT_CODE_INNER_ERROR, "内部异常了:" + e.getMessage() + e.getLocalizedMessage()).toJSONString();
} finally {
if(dataFlow != null) {
//这里记录日志
Date endDate = DateUtil.getCurrentDate();
dataFlow.setEndDate(endDate);
dataFlow.setResData(responseData);
//添加耗时
DataFlowFactory.addCostTime(dataFlow, "service", "业务处理总耗时", dataFlow.getStartDate(), dataFlow.getEndDate());
//这里保存耗时,以及日志
saveLogMessage(dataFlow.getReqJson(), dataFlow.getResJson());
//保存耗时
saveCostTimeLogMessage(dataFlow);
//组装返回头信息
putResponseHeader(dataFlow,headers);
//处理返回报文鉴权
AuthenticationFactory.putSign(dataFlow, headers);
}
resJson = encrypt(responseData,headers);
return resJson;
}
}
/**
* 抒写返回头信息
* @param dataFlow
*/
private void putResponseHeader(DataFlow dataFlow,Map<String,String> headers) {
headers.put("responseTime", DateUtil.getDefaultFormateTimeString(new Date()));
headers.put("transactionId",dataFlow.getTransactionId());
}
/**
* 解密
* @param reqJson
......@@ -377,6 +469,40 @@ public class CenterServiceSMOImpl extends LoggerEngine implements ICenterService
}
/**
* 6.0 调用下游系统
*
* @param dataFlow
* @throws BusinessException
*/
private void transferInvokeBusinessSystem(DataFlow dataFlow) throws BusinessException {
Date startDate = DateUtil.getCurrentDate();
/* if(MappingCache.getValue(MappingConstant.KEY_NO_INVOKE_BUSINESS_SYSTEM) != null
&&MappingCache.getValue(MappingConstant.KEY_NO_INVOKE_BUSINESS_SYSTEM).contains(dataFlow.getOrderTypeCd())){
//不用调用 下游系统的配置(一般不存在这种情况,这里主要是在没有下游系统的情况下测试中心服务用)
DataFlowFactory.addCostTime(dataFlow, "invokeBusinessSystem", "调用下游系统耗时", startDate);
dataFlow.setResponseBusinessJson(DataTransactionFactory.createCommonResponseJson(dataFlow.getTransactionId(),
ResponseConstant.RESULT_CODE_SUCCESS, "成功",null));
return ;
}*/
//6.1 先处理同步方式的服务,每一同步后发布事件广播
AppService service = DataFlowFactory.getService(dataFlow,dataFlow.getCurrentBusiness().getServiceCode());
String responseJson = doTransferRequestBusinessSystem(dataFlow, service, dataFlow.getCurrentBusiness().getTransferData());
dataFlow.setResData(responseJson);
DataFlowFactory.addCostTime(dataFlow,dataFlow.getCurrentBusiness().getServiceCode(), "调用"+dataFlow.getCurrentBusiness().getServiceCode()+"耗时", startDate);
saveLogMessage(dataFlow.getCurrentBusiness().getTransferData(),dataFlow.getResData());
DataFlowFactory.addCostTime(dataFlow, "invokeBusinessSystem", "调用下游系统耗时", startDate);
}
/**
* 7.0 作废订单和业务项 插入撤单记录 等待撤单
......@@ -925,6 +1051,24 @@ public class CenterServiceSMOImpl extends LoggerEngine implements ICenterService
return responseJson;
}
private String doTransferRequestBusinessSystem(DataFlow dataFlow, AppService service, String reqData) {
String responseMessage;
if(service.getMethod() == null || "".equals(service.getMethod())) {//post方式
//http://user-service/test/sayHello
HttpHeaders header = new HttpHeaders();
for(String key : dataFlow.getHeaders().keySet()){
header.add(key,dataFlow.getHeaders().get(key));
}
HttpEntity<String> httpEntity = new HttpEntity<String>(reqData, header);
responseMessage = restTemplateNoLoadBalanced.postForObject(service.getUrl(),httpEntity,String.class);
}else{//webservice方式
responseMessage = (String) WebServiceAxisClient.callWebService(service.getUrl(),service.getMethod(),
new Object[]{dataFlow.getRequestBusinessJson().toJSONString()},
service.getTimeOut());
}
return responseMessage;
}
/**
* 数据保存到BusinessTable 中
* @param dataFlow
......@@ -1009,6 +1153,24 @@ public class CenterServiceSMOImpl extends LoggerEngine implements ICenterService
}
}
/**
* 保存日志信息
* @param requestJson
*/
private void saveLogMessage(String requestJson,String responseJson){
try{
if(MappingConstant.VALUE_ON.equals(MappingCache.getValue(MappingConstant.KEY_LOG_ON_OFF))){
JSONObject log = new JSONObject();
log.put("request",requestJson);
log.put("response",responseJson);
KafkaFactory.sendKafkaMessage(KafkaConstant.TOPIC_LOG_NAME,"",log.toJSONString());
}
}catch (Exception e){
logger.error("报错日志出错了,",e);
}
}
/**
* 保存耗时信息
* @param dataFlow
......@@ -1071,4 +1233,12 @@ public class CenterServiceSMOImpl extends LoggerEngine implements ICenterService
public void setQueryServiceSMOImpl(IQueryServiceSMO queryServiceSMOImpl) {
this.queryServiceSMOImpl = queryServiceSMOImpl;
}
public RestTemplate getRestTemplateNoLoadBalanced() {
return restTemplateNoLoadBalanced;
}
public void setRestTemplateNoLoadBalanced(RestTemplate restTemplateNoLoadBalanced) {
this.restTemplateNoLoadBalanced = restTemplateNoLoadBalanced;
}
}
......@@ -22,6 +22,9 @@ public class Business implements Comparable{
private JSONObject datas;
//透传
private String transferData;
private JSONArray attrs;
//返回 编码
private String code;
......@@ -111,6 +114,14 @@ public class Business implements Comparable{
this.isInstance = isInstance;
}
public String getTransferData() {
return transferData;
}
public void setTransferData(String transferData) {
this.transferData = transferData;
}
/**
* 构建成对象
* @return
......@@ -121,7 +132,7 @@ public class Business implements Comparable{
try{
this.setbId(businessObj.getString("bId"));
this.setServiceCode(businessObj.getString("serviceCode"));
if(businessObj.containsKey("serviceCode")) {
if(businessObj.containsKey("serviceName")) {
this.setServiceName(businessObj.getString("serviceName"));
}
if(businessObj.containsKey("remark")) {
......@@ -138,6 +149,11 @@ public class Business implements Comparable{
if(businessObj.containsKey("attrs")){
this.setAttrs(businessObj.getJSONArray("attrs"));
}
if(businessObj.containsKey("transferData")){
this.setTransferData(businessObj.getString("transferData"));
}
if(businessObj.containsKey("response")){
this.setCode(businessObj.getJSONObject("response").getString("code"));
this.setMessage(businessObj.getJSONObject("response").getString("message"));
......
......@@ -19,7 +19,7 @@ public class Assert extends org.springframework.util.Assert{
* @param key
* @param message
*/
public static void isNotNull(JSONObject jsonObject,String key,String message){
public static void isNotNull(Map jsonObject,String key,String message){
Assert.notEmpty(jsonObject,message);
if(!jsonObject.containsKey(key)){
......@@ -37,6 +37,16 @@ public class Assert extends org.springframework.util.Assert{
isNotNull(jsonObject,key,message);
}
/**
* 判断 jsonObject 是否为空
* @param info
* @param key
* @param message
*/
public static void hasKey(Map info,String key,String message){
isNotNull(info,key,message);
}
/**
* 判断json是否为空
* @param jsonArray
......
......@@ -160,7 +160,7 @@ INSERT c_mapping(domain,`name`,`key`,`value`,remark) VALUES('DOMAIN.COMMON','日
INSERT c_mapping(domain,`name`,`key`,`value`,remark) VALUES('DOMAIN.COMMON','耗时开关','COST_TIME_ON_OFF','ON','耗时开关');
INSERT c_mapping(domain,`name`,`key`,`value`,remark) VALUES('DOMAIN.COMMON','规则开关','RULE_ON_OFF','OFF','规则开关');
INSERT c_mapping(domain,`name`,`key`,`value`,remark) VALUES('DOMAIN.COMMON','不调规则服务的订单类型','NO_NEED_RULE_VALDATE_ORDER','Q','不调规则服务的订单类型');
INSERT c_mapping(domain,`name`,`key`,`value`,remark) VALUES('DOMAIN.COMMON','不保存订单信息','NO_SAVE_ORDER','Q','不保存订单信息');
INSERT c_mapping(domain,`name`,`key`,`value`,remark) VALUES('DOMAIN.COMMON','不保存订单信息','NO_SAVE_ORDER','Q,T','不保存订单信息');
INSERT c_mapping(domain,`name`,`key`,`value`,remark) VALUES('DOMAIN.COMMON','不用调用 下游系统的配置','NO_INVOKE_BUSINESS_SYSTEM','Q','不用调用 下游系统的配置(一般不存在这种情况,这里主要是在没有下游系统的情况下测试中心服务用)');
INSERT c_mapping(domain,`name`,`key`,`value`,remark) VALUES('DOMAIN.COMMON','不用调用 作废下游系统的配置','NO_INVALID_BUSINESS_SYSTEM','Q','不用调用 作废下游系统的配置 (一般不存在这种情况,这里主要是在没有下游系统的情况下测试中心服务用)');
INSERT c_mapping(domain,`name`,`key`,`value`,remark) VALUES('DOMAIN.COMMON','需要调用服务生成各个ID','NEED_INVOKE_SERVICE_GENERATE_ID','OFF','需要调用服务生成各个ID');
......@@ -269,6 +269,10 @@ VALUES('update.center.mapping','Q','修改映射信息',1,'http://center-service
INSERT INTO c_service(service_code,business_type_cd,`name`,seq,url,provide_app_id)
VALUES('save.user.userInfo','D','保存用户信息',1,'http://user-service/userApi/service','8000418003');
INSERT INTO c_service(service_code,business_type_cd,`name`,seq,url,provide_app_id)
VALUES('transfer.console.menu','T','透传菜单查询',1,'http://192.168.31.199:8001/userApi/service','8000418001');
insert into c_route(app_id,service_id,invoke_model,order_type_cd,status_cd) values(
'8000418001','1','S','Q','0'
);
......
......@@ -35,10 +35,14 @@ public abstract class AbstractDataFlowContext implements DataFlowContext,Orders{
private String message;
private String reqData;
private JSONObject reqJson;
private JSONObject resJson;
private String resData;
protected List<Business> businesses;
private Business currentBusiness;
......@@ -152,15 +156,14 @@ public abstract class AbstractDataFlowContext implements DataFlowContext,Orders{
return headers;
}
public JSONObject getReqJson() {
return reqJson;
public String getReqData() {
return reqData;
}
public void setReqJson(JSONObject reqJson) {
this.reqJson = reqJson;
public void setReqData(String reqData) {
this.reqData = reqData;
}
public JSONObject getResJson() {
return resJson;
}
......@@ -233,7 +236,23 @@ public abstract class AbstractDataFlowContext implements DataFlowContext,Orders{
return null;
}
public void addParamOut(String key,Object value) {
public String getResData() {
return resData;
}
public void setResData(String resData) {
this.resData = resData;
}
public JSONObject getReqJson() {
return reqJson;
}
public void setReqJson(JSONObject reqJson) {
this.reqJson = reqJson;
}
public void addParamOut(String key, Object value) {
}
......
......@@ -2,6 +2,9 @@ package com.java110.core.context;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.java110.common.util.DateUtil;
import com.java110.common.util.SequenceUtil;
import com.java110.common.util.StringUtil;
import com.java110.entity.center.AppRoute;
import com.java110.entity.center.Business;
......@@ -181,6 +184,7 @@ public class DataFlow extends AbstractDataFlowContext {
Business business = null;
JSONObject reqInfoObj = JSONObject.parseObject(businessInfo);
this.setReqJson(reqInfoObj);
this.setReqData(businessInfo);
this.setDataFlowId(reqInfoObj.containsKey("dataFlowId")?reqInfoObj.getString("dataFlowId"):"-1");
//this.setAppId(orderObj.getString("appId"));
this.setTransactionId(reqInfoObj.getString("transactionId"));
......@@ -216,6 +220,7 @@ public class DataFlow extends AbstractDataFlowContext {
JSONObject reqInfoObj = JSONObject.parseObject(reqInfo);
JSONObject orderObj = reqInfoObj.getJSONObject("orders");
JSONArray businessArray = reqInfoObj.getJSONArray("business");
this.setReqData(reqInfo);
this.setReqJson(reqInfoObj);
this.setDataFlowId(orderObj.containsKey("dataFlowId")?orderObj.getString("dataFlowId"):"-1");
this.setAppId(orderObj.getString("appId"));
......@@ -249,4 +254,49 @@ public class DataFlow extends AbstractDataFlowContext {
return this;
}
/**
* 透传时构建对象
* @param reqInfo
* @param headerAll
* @return
* @throws Exception
*/
public DataFlow builderTransfer(String reqInfo, Map<String,String> headerAll) throws Exception{
try{
Business business = null;
this.setReqData(reqInfo);
this.setDataFlowId("-1");
this.setAppId(headerAll.get("appId"));
this.setTransactionId(StringUtil.isNullOrNone(headerAll.get("transactionId"))? SequenceUtil.getTransactionId():headerAll.get("transactionId"));
this.setUserId(StringUtil.isNullOrNone(headerAll.get("userId"))? "-1":headerAll.get("userId"));
this.setOrderTypeCd("T");
this.setRemark(StringUtil.isNullOrNone(headerAll.get("remark"))? "":headerAll.get("remark"));
this.setReqSign(StringUtil.isNullOrNone(headerAll.get("sign"))? "":headerAll.get("sign"));
this.setRequestTime(StringUtil.isNullOrNone(headerAll.get("requestTime"))? DateUtil.getyyyyMMddhhmmssDateString():headerAll.get("requestTime"));
String serviceCode = headerAll.get("serviceCode");
this.businesses = new ArrayList<Business>();
if(!StringUtil.isNullOrNone(serviceCode)){
JSONObject bInfo = new JSONObject();
bInfo.put("serviceCode",serviceCode);
bInfo.put("transferData",reqInfo);
business = new Business().builder(bInfo);
businesses.add(business);
this.setCurrentBusiness(business);
}
if (headerAll != null){
this.headers.putAll(headerAll);
this.setRequestURL(headers.get("REQUEST_URL"));
this.setIp(headers.get("IP"));
}
}catch (Exception e){
throw e;
}
return this;
}
}
......@@ -18,8 +18,9 @@ public interface DataFlowContext {
* 请求报文
* @return
*/
public JSONObject getReqJson();
public String getReqData();
public JSONObject getReqJson();
/**
* 返回报文
* @return
......
......@@ -15,6 +15,7 @@ import com.java110.common.constant.CommonConstant;
import com.java110.common.constant.MappingConstant;
import com.java110.common.constant.ResponseConstant;
import com.java110.common.exception.NoAuthorityException;
import com.java110.common.util.DateUtil;
import com.java110.common.util.StringUtil;
import com.java110.core.context.DataFlow;
......@@ -27,10 +28,7 @@ import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.*;
/**
*
......@@ -61,7 +59,10 @@ public class AuthenticationFactory {
if(dataFlow == null){
throw new NoAuthorityException(ResponseConstant.RESULT_CODE_NO_AUTHORITY_ERROR,"MD5签名过程中出现错误");
}
String reqInfo = dataFlow.getTransactionId() + dataFlow.getAppId() + dataFlow.getReqBusiness().toJSONString()+dataFlow.getAppRoutes().get(0).getSecurityCode();
String reqInfo = dataFlow.getTransactionId() +dataFlow.getAppId();
reqInfo += ((dataFlow.getReqBusiness() == null || dataFlow.getReqBusiness().size() == 0)
?dataFlow.getReqData() :dataFlow.getReqBusiness().toJSONString());
reqInfo += dataFlow.getAppRoutes().get(0).getSecurityCode();
return md5(reqInfo);
}
......@@ -94,6 +95,20 @@ public class AuthenticationFactory {
}
}
/**
* 添加 sign
* @param dataFlow
* @param headers
*/
public static void putSign(DataFlow dataFlow,Map<String,String> headers){
if(dataFlow == null || dataFlow.getAppRoutes() == null || dataFlow.getAppRoutes().size() == 0 || StringUtil.isNullOrNone(dataFlow.getAppRoutes().get(0).getSecurityCode())) {
headers.put("resSign","");
}else {
headers.put("resSign", AuthenticationFactory.md5(dataFlow.getTransactionId(), headers.get("responseTime"),
dataFlow.getResData(), dataFlow.getAppRoutes().get(0).getSecurityCode()));
}
}
/**
* 加密
......
......@@ -70,6 +70,15 @@ public class DataTransactionFactory {
return dataFlow.getResponseBusinessJson();
}
/**
* 组装返回报文
* @param dataFlow 数据流
* @return
*/
public static String createCommonResData(DataFlow dataFlow){
return dataFlow.getResData();
}
/**
* 业务系统返回报文模板
* @param code
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment