Kaynağa Gözat

中心服务改造完成

wuxw7 7 yıl önce
ebeveyn
işleme
38ac8ad64d

+ 1 - 1
Api/src/main/java/com/java110/api/listener/AbstractServiceApiDataFlowListener.java

@@ -64,7 +64,7 @@ public abstract class AbstractServiceApiDataFlowListener implements ServiceDataF
             } else {
                 responseEntity = tmpRestTemplate.exchange(service.getUrl(), HttpMethod.POST, httpEntity, String.class);
             }
-        }catch (HttpServerErrorException e){
+        }catch (HttpServerErrorException e){ //这里spring 框架 在4XX 或 5XX 时抛出 HttpServerErrorException 异常,需要重新封装一下
             responseEntity = new ResponseEntity<String>("请求下游系统异常异常,"+e.getResponseBodyAsString(),e.getStatusCode());
 
         }

+ 2 - 2
Api/src/main/java/com/java110/api/rest/RestApi.java

@@ -50,7 +50,7 @@ public class RestApi extends BaseController {
 
     @RequestMapping(path = "/{service:.+}",method = RequestMethod.POST )
     @ApiOperation(value="资源post请求", notes="test: 返回 2XX 表示服务正常")
-    @ApiImplicitParam(paramType="query", name = "method", value = "用户编号", required = true, dataType = "String")
+    @ApiImplicitParam(paramType="query", name = "service", value = "用户编号", required = true, dataType = "String")
     public ResponseEntity<String> servicePost(@PathVariable String service,
                                               @RequestBody String postInfo,
                                               HttpServletRequest request){
@@ -134,7 +134,7 @@ public class RestApi extends BaseController {
 
     @RequestMapping(path = "/{service:.+}",method = RequestMethod.DELETE )
     @ApiOperation(value="资源delete请求", notes="test: 返回 2XX 表示服务正常")
-    @ApiImplicitParam(paramType="query", name = "method", value = "用户编号", required = true, dataType = "String")
+    @ApiImplicitParam(paramType="query", name = "service", value = "用户编号", required = true, dataType = "String")
     public ResponseEntity<String> serviceDelete(@PathVariable String service,
                                              HttpServletRequest request){
         ResponseEntity<String> responseEntity = null;

+ 2 - 2
Api/src/main/java/com/java110/api/smo/impl/ApiServiceSMOImpl.java

@@ -245,8 +245,8 @@ public class ApiServiceSMOImpl extends LoggerEngine implements IApiServiceSMO {
         //判断 AppId 是否有权限操作相应的服务
         AppService appService = DataFlowFactory.getService(dataFlow, dataFlow.getRequestHeaders().get(CommonConstant.HTTP_SERVICE));
 
-                //这里调用缓存 查询缓存信息
-        if (appService == null) {
+        //这里调用缓存 查询缓存信息
+        if (appService == null || !CommonConstant.HTTP_SERVICE_API.equals(appService.getBusinessTypeCd())) {
             //添加耗时
             DataFlowFactory.addCostTime(dataFlow, "judgeAuthority", "鉴权耗时", startDate);
             throw new NoAuthorityException(ResponseConstant.RESULT_CODE_NO_AUTHORITY_ERROR, "AppId 没有权限访问 serviceCode = " + dataFlow.getRequestHeaders().get(CommonConstant.HTTP_SERVICE));

+ 141 - 0
CenterService/src/main/java/com/java110/center/api/CenterApi.java

@@ -0,0 +1,141 @@
+package com.java110.center.api;
+
+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.base.controller.BaseController;
+import com.java110.core.factory.DataTransactionFactory;
+import com.java110.event.center.DataFlowEventPublishing;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+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
+@Api(value = "中心服务接口服务规范")
+@RequestMapping(path = "/centerApi")
+public class CenterApi extends BaseController {
+
+    @Autowired
+    private ICenterServiceSMO centerServiceSMOImpl;
+
+    /**
+     *
+     * @param request HttpServletRequest对象
+     * @return
+     */
+    @RequestMapping(path = "/service",method= RequestMethod.GET)
+    @ApiOperation(value="中心服务get方式请求", notes="test: 返回 502 表示服务不支持GET 请求方式")
+    public ResponseEntity<String> serviceGet(HttpServletRequest request) {
+        return new ResponseEntity<String>("center服务 不支持GET 请求方式", HttpStatus.METHOD_NOT_ALLOWED);
+    }
+    /**
+     *
+     * @param request HttpServletRequest对象
+     * @return
+     */
+    @RequestMapping(path = "/service",method= RequestMethod.PUT)
+    @ApiOperation(value="中心服务put方式请求", notes="test: 返回 502 表示服务不支持PUT 请求方式")
+    public ResponseEntity<String> servicePut(HttpServletRequest request) {
+        return new ResponseEntity<String>("center服务 不支持GET 请求方式", HttpStatus.METHOD_NOT_ALLOWED);
+    }
+    /**
+     *
+     * @param request HttpServletRequest对象
+     * @return
+     */
+    @RequestMapping(path = "/service",method= RequestMethod.DELETE)
+    @ApiOperation(value="中心服务delete方式请求", notes="test: 返回 502 表示服务不支持DELETE 请求方式")
+    public ResponseEntity<String> serviceDelete(HttpServletRequest request) {
+        return new ResponseEntity<String>("center服务 不支持GET 请求方式", HttpStatus.METHOD_NOT_ALLOWED);
+    }
+
+
+    @RequestMapping(path = "/service",method= RequestMethod.POST)
+    @ApiOperation(value="中心服务订单受理", notes="test: 返回 200 表示服务受理成功,其他表示失败")
+    @ApiImplicitParam(paramType="query", name = "orderInfo", value = "订单受理信息", required = true, dataType = "String")
+    public ResponseEntity<String> servicePost(@RequestBody String orderInfo, HttpServletRequest request) {
+        try {
+            Map<String, String> headers = new HashMap<String, String>();
+            getRequestInfo(request, headers);
+            //接受请求事件
+            DataFlowEventPublishing.receiveRequest(orderInfo,headers);
+            //预校验
+            preValiateOrderInfo(orderInfo);
+            return centerServiceSMOImpl.serviceApi(orderInfo, headers);
+        }catch (Exception e){
+            logger.error("请求订单异常",e);
+            return new ResponseEntity<String>("请求中心服务发生异常,"+e.getMessage(),HttpStatus.INTERNAL_SERVER_ERROR);
+        }
+    }
+
+    /**
+     * 这里预校验,请求报文中不能有 dataFlowId
+     * @param orderInfo
+     */
+    private void preValiateOrderInfo(String orderInfo) {
+
+        Assert.jsonObjectHaveKey(orderInfo,"orders","请求报文中未包含orders节点,"+orderInfo);
+
+        Assert.jsonObjectHaveKey(orderInfo,"business","请求报文中未包含business节点,"+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 不能为空");
+    }
+
+    /**
+     * 获取请求信息
+     * @param request
+     * @param headers
+     * @throws RuntimeException
+     */
+    private void getRequestInfo(HttpServletRequest request,Map headers) throws Exception{
+        try{
+            super.initHeadParam(request,headers);
+            super.initUrlParam(request,headers);
+        }catch (Exception e){
+            logger.error("加载头信息失败",e);
+            throw e;
+        }
+    }
+
+
+    public ICenterServiceSMO getCenterServiceSMOImpl() {
+        return centerServiceSMOImpl;
+    }
+
+    public void setCenterServiceSMOImpl(ICenterServiceSMO centerServiceSMOImpl) {
+        this.centerServiceSMOImpl = centerServiceSMOImpl;
+    }
+}

+ 1 - 0
CenterService/src/main/java/com/java110/center/api/HttpApi.java

@@ -23,6 +23,7 @@ import java.util.Map;
  * Created by wuxw on 2018/4/13.
  */
 @RestController
+@Deprecated
 public class HttpApi extends BaseController {
 
     @Autowired

+ 9 - 0
CenterService/src/main/java/com/java110/center/smo/ICenterServiceSMO.java

@@ -1,6 +1,7 @@
 package com.java110.center.smo;
 
 import com.java110.common.exception.SMOException;
+import org.springframework.http.ResponseEntity;
 
 import javax.servlet.http.HttpServletRequest;
 import java.util.Map;
@@ -16,6 +17,7 @@ public interface ICenterServiceSMO {
      * @param reqJson 请求报文json
      * @return
      */
+    @Deprecated
     public String service(String reqJson, Map<String,String> headers) throws SMOException;
 
     /**
@@ -27,6 +29,13 @@ public interface ICenterServiceSMO {
      */
     public String serviceTransfer(String reqJson, Map<String,String> headers) throws SMOException;
 
+    /**
+     * 业务统一处理服务方法
+     * @param reqJson 请求报文json
+     * @return
+     */
+    public ResponseEntity<String> serviceApi(String reqJson, Map<String,String> headers) throws SMOException;
+
     /**
      * 接受业务系统通知消息
      * @param receiveJson 接受报文

+ 104 - 0
CenterService/src/main/java/com/java110/center/smo/impl/CenterServiceSMOImpl.java

@@ -30,6 +30,8 @@ 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.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
 import org.springframework.web.client.RestTemplate;
 
@@ -57,6 +59,7 @@ public class CenterServiceSMOImpl extends LoggerEngine implements ICenterService
     private IQueryServiceSMO queryServiceSMOImpl;
 
     @Override
+    @Deprecated
     public String service(String reqJson, Map<String, String> headers) throws SMOException{
 
         DataFlow dataFlow = null;
@@ -158,6 +161,102 @@ public class CenterServiceSMOImpl extends LoggerEngine implements ICenterService
 
     }
 
+    /**
+     * 业务统一处理服务方法
+     * @param reqJson 请求报文json
+     * @return
+     */
+    public ResponseEntity<String> serviceApi(String reqJson, Map<String,String> headers) throws SMOException{
+        DataFlow dataFlow = null;
+
+        JSONObject responseJson = null;
+
+        ResponseEntity<String> responseEntity = null;
+
+        try {
+            DataFlowEventPublishing.preValidateData(reqJson,headers);
+            //1.0 创建数据流
+            dataFlow = DataFlowFactory.newInstance(DataFlow.class).builder(reqJson, headers);
+            DataFlowEventPublishing.initDataFlowComplete(dataFlow);
+
+            //2.0 加载配置信息
+            initConfigData(dataFlow);
+            DataFlowEventPublishing.loadConfigDataComplete(dataFlow);
+
+            //3.0 校验 APPID是否有权限操作serviceCode
+            judgeAuthority(dataFlow);
+            //4.0 调用规则校验
+            ruleValidate(dataFlow);
+            DataFlowEventPublishing.ruleValidateComplete(dataFlow);
+
+            //5.0 保存订单和业务项 c_orders c_order_attrs c_business c_business_attrs
+            saveOrdersAndBusiness(dataFlow);
+
+            //6.0 调用下游系统
+            DataFlowEventPublishing.invokeBusinessSystem(dataFlow);
+            invokeBusinessSystem(dataFlow);
+
+            responseJson = DataTransactionFactory.createCommonResponseJson(dataFlow);
+
+        } catch (DecryptException e){ //解密异常
+            responseEntity = new ResponseEntity<String>(e.getMessage() , HttpStatus.PROXY_AUTHENTICATION_REQUIRED);
+        }catch (BusinessException e) {
+            try {
+                //7.0 作废订单和业务项
+                invalidOrderAndBusiness(dataFlow);
+                //8.0 广播作废业务系统订单信息
+                //想法:这里可以直接不广播,只有在业务返回时才广播,
+                // 疑问:在这里部分消息发出去了,如果在receiveBusinessSystemNotifyMessage这个方法中依然没有收到,我们认为是下游系统也是失败了不用处理,
+                //目前看逻辑也是对的
+                //invalidBusinessSystem(dataFlow);
+            } catch (Exception e1) {
+                LoggerEngine.error("作废订单失败", e);
+                //9.0 将订单状态改为失败,人工处理。
+                updateOrderAndBusinessError(dataFlow);
+            } finally {
+                responseEntity = new ResponseEntity<String>(e.getMessage() , HttpStatus.INTERNAL_SERVER_ERROR);
+            }
+
+        } catch (OrdersException e) {
+            responseEntity = new ResponseEntity<String>(e.getMessage() , HttpStatus.INTERNAL_SERVER_ERROR);
+        } catch (RuleException e) {
+            responseEntity = new ResponseEntity<String>(e.getMessage(), HttpStatus.NETWORK_AUTHENTICATION_REQUIRED);
+        } catch (NoAuthorityException e) {
+            responseEntity = new ResponseEntity<String>(e.getMessage(), HttpStatus.UNAUTHORIZED);
+        } catch (InitConfigDataException e){
+            responseEntity = new ResponseEntity<String>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
+        }catch (Exception e) {
+            logger.error("内部异常了:",e);
+            responseEntity = new ResponseEntity<String>("内部异常了:"+e.getMessage() + e.getLocalizedMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
+        } finally {
+            if(dataFlow != null) {
+                //这里记录日志
+                Date endDate = DateUtil.getCurrentDate();
+
+                dataFlow.setEndDate(endDate);
+                if(responseJson != null ) {
+                    dataFlow.setResJson(responseJson);
+                    //处理返回报文鉴权
+                    AuthenticationFactory.putSign(dataFlow, responseJson);
+                }
+                //添加耗时
+                //DataFlowFactory.addCostTime(dataFlow, "service", "业务处理总耗时", dataFlow.getStartDate(), dataFlow.getEndDate());
+                //保存耗时
+                //saveCostTimeLogMessage(dataFlow);
+                saveLogMessage(dataFlow,LogAgent.createLogMessage(dataFlow.getRequestHeaders(),dataFlow.getReqJson().toJSONString()),
+                        LogAgent.createLogMessage(dataFlow.getResponseHeaders(),dataFlow.getResJson().toJSONString()),endDate.getTime()-dataFlow.getStartDate().getTime());
+                DataFlowEventPublishing.dataResponse(dataFlow,reqJson,headers);
+            }
+            if(responseEntity == null){
+                String resJson = encrypt(responseJson.toJSONString(),headers);
+                responseEntity = new ResponseEntity<String>(resJson,HttpStatus.OK);
+            }
+            //这里保存耗时,以及日志
+            return responseEntity ;
+
+        }
+    }
+
     /**
      * 透传处理
      * @param reqJson
@@ -375,6 +474,11 @@ public class CenterServiceSMOImpl extends LoggerEngine implements ICenterService
                     DataFlowFactory.addCostTime(dataFlow, "judgeAuthority", "鉴权耗时", startDate);
                     throw new NoAuthorityException(ResponseConstant.RESULT_CODE_NO_AUTHORITY_ERROR, "AppId 没有权限访问 serviceCod = " + business.getServiceCode());
                 }
+
+                if(CommonConstant.HTTP_SERVICE_API.equals(appService.getBusinessTypeCd())){
+                    DataFlowFactory.addCostTime(dataFlow, "judgeAuthority", "鉴权耗时", startDate);
+                    throw new NoAuthorityException(ResponseConstant.RESULT_CODE_NO_AUTHORITY_ERROR, "当前服务配置为API 该AppId 没有权限访问 serviceCod = " + business.getServiceCode());
+                }
             }
         }
 

+ 2 - 0
java110-common/src/main/java/com/java110/common/constant/CommonConstant.java

@@ -126,6 +126,8 @@ public class CommonConstant {
     public final static String INSTANCE_N = "N";
 
 
+
+    public final static String HTTP_SERVICE_API = "API";
     public final static String HTTP_SERVICE = "SERVICE";
     public final static String HTTP_METHOD = "METHOD";
     public final static String HTTP_APP_ID = "app_id";

+ 21 - 1
java110-core/src/main/java/com/java110/core/context/DataFlow.java

@@ -2,6 +2,7 @@ package com.java110.core.context;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.java110.common.constant.CommonConstant;
 import com.java110.common.util.DateUtil;
 import com.java110.core.factory.GenerateCodeFactory;
 import com.java110.common.util.StringUtil;
@@ -218,7 +219,7 @@ public class DataFlow extends AbstractDataFlowContext {
         try{
             Business business = null;
             JSONObject reqInfoObj = JSONObject.parseObject(reqInfo);
-            JSONObject orderObj = reqInfoObj.getJSONObject("orders");
+            JSONObject orderObj = refreshOrderObj(reqInfoObj,headerAll);
             Object businessObj = reqInfoObj.get("business");
             JSONArray businessArray = null;
             if(businessObj instanceof JSONObject){
@@ -311,4 +312,23 @@ public class DataFlow extends AbstractDataFlowContext {
         return this;
     }
 
+    private JSONObject refreshOrderObj(JSONObject reqInfoObj,Map<String,String> headerAll){
+
+        JSONObject reqInfoOrder = reqInfoObj.getJSONObject("orders");
+
+        if(!reqInfoOrder.containsKey("appId")) {
+            reqInfoOrder.put("appId", headerAll.get(CommonConstant.HTTP_APP_ID));
+        }
+        if(!reqInfoOrder.containsKey("transactionId")) {
+            reqInfoOrder.put("transactionId", headerAll.get(CommonConstant.HTTP_TRANSACTION_ID));
+        }
+        if(!reqInfoOrder.containsKey("sign")) {
+            reqInfoOrder.put("sign", headerAll.get(CommonConstant.HTTP_SIGN));
+        }
+
+        if(!reqInfoOrder.containsKey("requestTime")) {
+            reqInfoOrder.put("requestTime", headerAll.get(CommonConstant.HTTP_REQ_TIME));
+        }
+        return reqInfoOrder;
+    }
 }