mrzcc
2020-02-17 e64197421cf28099935f71f193989a3394d47fe0
OrderService/src/main/java/com/java110/order/smo/impl/OrderServiceSMOImpl.java
@@ -2,32 +2,32 @@
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.java110.common.cache.MappingCache;
import com.java110.common.constant.CommonConstant;
import com.java110.common.constant.KafkaConstant;
import com.java110.common.constant.MappingConstant;
import com.java110.common.constant.ResponseConstant;
import com.java110.common.constant.ServiceBusinessConstant;
import com.java110.common.constant.StatusConstant;
import com.java110.common.exception.BusinessException;
import com.java110.common.exception.BusinessStatusException;
import com.java110.common.exception.ConfigDataException;
import com.java110.common.exception.DAOException;
import com.java110.common.exception.DecryptException;
import com.java110.common.exception.InitConfigDataException;
import com.java110.common.exception.NoAuthorityException;
import com.java110.common.exception.NoSupportException;
import com.java110.common.exception.OrdersException;
import com.java110.common.exception.RuleException;
import com.java110.common.exception.SMOException;
import com.java110.common.factory.ApplicationContextFactory;
import com.java110.common.kafka.KafkaFactory;
import com.java110.common.log.LoggerEngine;
import com.java110.common.util.Assert;
import com.java110.common.util.DateUtil;
import com.java110.common.util.ServiceBusinessUtil;
import com.java110.common.util.StringUtil;
import com.java110.common.util.WebServiceAxisClient;
import com.java110.utils.cache.MappingCache;
import com.java110.utils.constant.CommonConstant;
import com.java110.utils.constant.KafkaConstant;
import com.java110.utils.constant.MappingConstant;
import com.java110.utils.constant.ResponseConstant;
import com.java110.utils.constant.ServiceBusinessConstant;
import com.java110.utils.constant.StatusConstant;
import com.java110.utils.exception.BusinessException;
import com.java110.utils.exception.BusinessStatusException;
import com.java110.utils.exception.ConfigDataException;
import com.java110.utils.exception.DAOException;
import com.java110.utils.exception.DecryptException;
import com.java110.utils.exception.InitConfigDataException;
import com.java110.utils.exception.NoAuthorityException;
import com.java110.utils.exception.NoSupportException;
import com.java110.utils.exception.OrdersException;
import com.java110.utils.exception.RuleException;
import com.java110.utils.exception.SMOException;
import com.java110.utils.factory.ApplicationContextFactory;
import com.java110.utils.kafka.KafkaFactory;
import com.java110.utils.log.LoggerEngine;
import com.java110.utils.util.Assert;
import com.java110.utils.util.DateUtil;
import com.java110.utils.util.ServiceBusinessUtil;
import com.java110.utils.util.StringUtil;
import com.java110.utils.util.WebServiceAxisClient;
import com.java110.core.client.RestTemplate;
import com.java110.core.context.DataFlow;
import com.java110.core.context.IOrderDataFlowContext;
@@ -70,19 +70,12 @@
 */
@Service("orderServiceSMOImpl")
//@Transactional
public class OrderServiceSMOImpl implements IOrderServiceSMO {
public class OrderServiceSMOImpl extends AbstractOrderServiceSMOImpl implements IOrderServiceSMO {
    private static Logger logger = LoggerFactory.getLogger(OrderServiceSMOImpl.class);
    @Autowired
    ICenterServiceDAO centerServiceDaoImpl;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private RestTemplate restTemplateNoLoadBalanced;
    @Autowired
    private IQueryServiceSMO queryServiceSMOImpl;
@@ -156,20 +149,6 @@
        }
    }
    /**
     * 刷返回值
     *
     * @param dataFlow
     */
    private void refreshOrderDataFlowResJson(IOrderDataFlowContext dataFlow) {
//        if(dataFlow.getResJson() == null || dataFlow.getResJson().isEmpty()){
//            JSONObject resJson = new JSONObject();
//            resJson.put("msg","成功");
//            dataFlow.setResJson(resJson);
//        }
    }
    /**
     * 抒写返回头信息
@@ -233,87 +212,6 @@
     */
    private void initConfigData(IOrderDataFlowContext dataFlow) {
    }
    /**
     * 4.0规则校验
     *
     * @param dataFlow
     * @throws RuleException
     */
    private void ruleValidate(IOrderDataFlowContext dataFlow) throws RuleException {
        Date startDate = DateUtil.getCurrentDate();
        try {
            if (MappingConstant.VALUE_OFF.equals(MappingCache.getValue(MappingConstant.KEY_RULE_ON_OFF))
                    || (MappingCache.getValue(MappingConstant.KEY_NO_NEED_RULE_VALDATE_ORDER) != null
                    && MappingCache.getValue(MappingConstant.KEY_NO_NEED_RULE_VALDATE_ORDER).contains(dataFlow.getOrders().getOrderTypeCd()))) {
                //不做校验
                //添加耗时
                OrderDataFlowContextFactory.addCostTime(dataFlow, "ruleValidate", "规则校验耗时", startDate);
                return;
            }
            //调用规则
        } catch (Exception e) {
            //添加耗时
            OrderDataFlowContextFactory.addCostTime(dataFlow, "ruleValidate", "规则校验耗时", startDate);
            throw new RuleException(ResponseConstant.RESULT_CODE_RULE_ERROR, "规则校验异常失败:" + e.getMessage());
        }
        OrderDataFlowContextFactory.addCostTime(dataFlow, "ruleValidate", "规则校验耗时", startDate);
    }
    /**
     * 5.0 保存订单和业务项 c_orders c_order_attrs c_business c_business_attrs
     *
     * @param dataFlow
     * @throws OrdersException
     */
    private void saveOrdersAndBusiness(IOrderDataFlowContext dataFlow) throws OrdersException {
        Date startDate = DateUtil.getCurrentDate();
        if (MappingCache.getValue(MappingConstant.KEY_NO_SAVE_ORDER) != null
                && MappingCache.getValue(MappingConstant.KEY_NO_SAVE_ORDER).contains(dataFlow.getOrders().getOrderTypeCd())) {
            //不保存订单信息
            OrderDataFlowContextFactory.addCostTime(dataFlow, "saveOrdersAndBusiness", "保存订单和业务项耗时", startDate);
            return;
        }
        //1.0 保存 orders信息
        centerServiceDaoImpl.saveOrder(OrderDataFlowContextFactory.getOrder(dataFlow.getOrders()));
        centerServiceDaoImpl.saveOrderAttrs(OrderDataFlowContextFactory.getOrderAttrs(dataFlow.getOrders()));
        //2.0 保存 business信息
        centerServiceDaoImpl.saveBusiness(OrderDataFlowContextFactory.getBusiness(dataFlow));
        centerServiceDaoImpl.saveBusinessAttrs(OrderDataFlowContextFactory.getBusinessAttrs(dataFlow));
        OrderDataFlowContextFactory.addCostTime(dataFlow, "saveOrdersAndBusiness", "保存订单和业务项耗时", startDate);
    }
    /**
     * 6.0 调用下游系统
     *
     * @param dataFlow
     * @throws BusinessException
     */
    private void invokeBusinessSystem(IOrderDataFlowContext dataFlow) throws BusinessException {
        Date startDate = DateUtil.getCurrentDate();
        //6.1 先处理同步方式的服务,每一同步后发布事件广播
        doSynchronousBusinesses(dataFlow);
        //6.2 处理异步服务
        doAsynchronousBusinesses(dataFlow);
        OrderDataFlowContextFactory.addCostTime(dataFlow, "invokeBusinessSystem", "调用下游系统耗时", startDate);
    }
@@ -427,28 +325,7 @@
    }
    /**
     * 将订单状态改为作废状态。
     *
     * @param dataFlow
     */
    private void updateOrderAndBusinessDelete(IOrderDataFlowContext dataFlow) {
        Date startDate = DateUtil.getCurrentDate();
        //作废 订单
        centerServiceDaoImpl.updateOrder(OrderDataFlowContextFactory.getNeedInvalidOrder(dataFlow));
        //作废订单项
        centerServiceDaoImpl.updateBusiness(OrderDataFlowContextFactory.getNeedDeleteBusiness(dataFlow));
        //加入撤单记录
        //doAddDeleteOrderBusinessData(dataFlow);
        OrderDataFlowContextFactory.addCostTime(dataFlow, "updateOrderAndBusinessError", "订单状态改为失败耗时", startDate);
    }
    /**
     * 加入撤单记录
@@ -754,212 +631,6 @@
                DateUtil.getCurrentDate().getTime() - startTime);*/
    }
    /**
     * 处理同步业务
     *
     * @param dataFlow
     */
    private void doSynchronousBusinesses(IOrderDataFlowContext dataFlow) throws BusinessException {
        Date startDate = DateUtil.getCurrentDate();
        List<Business> synchronousBusinesses = OrderDataFlowContextFactory.getSynchronousBusinesses(dataFlow);
        List<Business> deleteBusinesses = new ArrayList<Business>();
        if (synchronousBusinesses == null || synchronousBusinesses.size() == 0) {
            return;
        }
        JSONArray responseBusinesses = new JSONArray();
        //6.1处理同步服务 发起Business
        doSaveDataInfoToBusinessTable(dataFlow, synchronousBusinesses, responseBusinesses);
        try {
            //6.2发起Instance
            doBusinessTableDataInfoToInstanceTable(dataFlow, synchronousBusinesses, deleteBusinesses);
        } catch (Exception e) {
            try {
                //这里发起撤单逻辑
                doDeleteOrderAndInstanceData(dataFlow, deleteBusinesses);
            } catch (Exception e1) {
                logger.error("撤单失败", e1);
                //这里记录撤单失败的信息
            }
            throw new BusinessException(ResponseConstant.RESULT_PARAM_ERROR, e.getMessage());
        }
        //6.3 c_business 数据修改为完成
        /*List<Business> asynchronousBusinesses = OrderDataFlowContextFactory.getAsynchronousBusinesses(dataFlow);
        if(asynchronousBusinesses == null || asynchronousBusinesses.size() == 0){
            doComplateOrderAndBusiness(dataFlow,synchronousBusinesses);
        }*/
        OrderDataFlowContextFactory.addCostTime(dataFlow, "doSynchronousBusinesses", "同步调用业务系统总耗时", startDate);
    }
    /**
     * 发起撤单业务
     *
     * @param dataFlow
     * @param deleteBusinesses
     */
    private void doDeleteOrderAndInstanceData(IOrderDataFlowContext dataFlow, List<Business> deleteBusinesses) {
        if (deleteBusinesses == null || deleteBusinesses.size() == 0) {
            return;
        }
        //1.0 在c_business 表中加入 撤单记录
        centerServiceDaoImpl.saveBusiness(OrderDataFlowContextFactory.getDeleteOrderBusiness(dataFlow, "业务系统实例失败,发起撤单"));
        //2.0 作废 c_orders 和 c_business 数据
        updateOrderAndBusinessDelete(dataFlow);
        //3.0 发起 撤单业务
        doDeleteBusinessSystemInstanceData(dataFlow, deleteBusinesses);
    }
    /**
     * 完成订单状态
     * @param synchronousBusinesses
     */
    /*private void doComplateOrderAndBusiness(DataFlow dataFlow,List<Business> synchronousBusinesses) {
        //Complete Order and business
        Map order = new HashMap();
        order.put("oId",dataFlow.getoId());
        order.put("statusCd", StatusConstant.STATUS_CD_COMPLETE);
        order.put("finishTime",DateUtil.getCurrentDate());
        centerServiceDaoImpl.updateOrder(order);
        centerServiceDaoImpl.updateBusiness(order);
        Date businessStartDate;
        AppService service;
        JSONObject requestBusinessJson;
        for(Business business : synchronousBusinesses){
            businessStartDate = DateUtil.getCurrentDate();
            service = OrderDataFlowContextFactory.getService(dataFlow,business.getServiceCode());
            if(!CommonConstant.INSTANCE_Y.equals(service.getIsInstance())){
                continue;
            }
            requestBusinessJson = OrderDataFlowContextFactory.getCompleteInstanceDataJson(dataFlow,business);
            JSONObject responseJson = doRequestBusinessSystem(dataFlow, service, requestBusinessJson);
            OrderDataFlowContextFactory.addCostTime(dataFlow, business.getServiceCode(), "调用"+business.getServiceName()+"-doComplete耗时", businessStartDate);
            saveLogMessage(dataFlow,LogAgent.createLogMessage(dataFlow.getRequestCurrentHeaders(),requestBusinessJson.toJSONString()),
                    LogAgent.createLogMessage(dataFlow.getResponseCurrentHeaders(),responseJson.toJSONString()),
                    DateUtil.getCurrentDate().getTime() - businessStartDate.getTime());
        }
    }*/
    /**
     * 将BusinessTable 中的数据保存到 InstanceTable
     *
     * @param dataFlow
     * @param synchronousBusinesses
     */
    private void doBusinessTableDataInfoToInstanceTable(IOrderDataFlowContext dataFlow, List<Business> synchronousBusinesses, List<Business> deleteBusinesses) {
        Date businessStartDate;
        ServiceBusiness serviceBusiness;
        JSONObject requestBusinessJson;
        for (Business business : synchronousBusinesses) {
            businessStartDate = DateUtil.getCurrentDate();
            serviceBusiness = ServiceBusinessUtil.getServiceBusiness(business.getBusinessTypeCd());
            //添加需要撤单的业务信息
            deleteBusinesses.add(business);
            requestBusinessJson = OrderDataFlowContextFactory.getBusinessTableDataInfoToInstanceTableJson(dataFlow, business);
            JSONObject responseJson = doRequestBusinessSystem(dataFlow, serviceBusiness, requestBusinessJson);
            //发布事件
            DataFlowEventPublishing.invokeBusinessISuccess(dataFlow, business);
            updateBusinessStatusCdByBId(business.getbId(), StatusConstant.STATUS_CD_COMPLETE);
            OrderDataFlowContextFactory.addCostTime(dataFlow, business.getBusinessTypeCd(), "调用" + business.getBusinessTypeCd() + "耗时", businessStartDate);
          /*  saveLogMessage(dataFlow,LogAgent.createLogMessage(dataFlow.getRequestCurrentHeaders(),requestBusinessJson.toJSONString()),
                    LogAgent.createLogMessage(dataFlow.getResponseCurrentHeaders(),responseJson.toJSONString()),
                    DateUtil.getCurrentDate().getTime() - businessStartDate.getTime());*/
        }
      /*  if(dataFlow.getCurrentBusiness() == null){
            return ;
        }*/
        //判断业务动作是否都竣工,主要考虑 请求报文中 有异步也有同步的情况
        //如果业务都完成,则将 订单改为完成状态
        centerServiceDaoImpl.completeOrderByOId(dataFlow.getOrders().getoId());
    }
    /**
     * 业务系统撤单
     *
     * @param dataFlow
     * @param deleteBusinesses
     */
    private void doDeleteBusinessSystemInstanceData(IOrderDataFlowContext dataFlow, List<Business> deleteBusinesses) {
        Date businessStartDate;
        JSONObject requestBusinessJson;
        ServiceBusiness serviceBusiness;
        for (Business business : deleteBusinesses) {
            businessStartDate = DateUtil.getCurrentDate();
            requestBusinessJson = OrderDataFlowContextFactory.getDeleteInstanceTableJson(dataFlow, business);
            serviceBusiness = ServiceBusinessUtil.getServiceBusiness(business.getBusinessTypeCd());
            JSONObject responseJson = doRequestBusinessSystem(dataFlow, serviceBusiness, requestBusinessJson);
            OrderDataFlowContextFactory.addCostTime(dataFlow, business.getBusinessTypeCd(), "调用" + business.getBusinessTypeCd() + "-撤单 耗时", businessStartDate);
//            saveLogMessage(dataFlow,LogAgent.createLogMessage(dataFlow.getRequestCurrentHeaders(),requestBusinessJson.toJSONString()),
//                    LogAgent.createLogMessage(dataFlow.getResponseCurrentHeaders(),responseJson.toJSONString()),
//                    DateUtil.getCurrentDate().getTime() - businessStartDate.getTime());
        }
    }
    /**
     * 调用下游系统
     *
     * @param dataFlow
     * @param serviceBusiness
     * @param requestBusinessJson 请求报文
     * @return
     */
    private JSONObject doRequestBusinessSystem(IOrderDataFlowContext dataFlow, ServiceBusiness serviceBusiness, JSONObject requestBusinessJson) {
        String responseMessage;
        Assert.hasLength(serviceBusiness.getInvokeType(), "c_service_business表配置出错,invoke_type 不能为空" + serviceBusiness.getBusinessTypeCd());
        String httpUrl = "";
        if (ServiceBusinessConstant.INVOKE_TYPE_WEBSERVICE.equals(serviceBusiness.getInvokeType())) {//webservice方式
            String url = serviceBusiness.getUrl();
            String[] urls = url.split("#");
            if (urls.length != 2) {
                throw new ConfigDataException(ResponseConstant.RESULT_CODE_CONFIG_ERROR, "配置错误:c_service_business配置url字段错误" + serviceBusiness.getBusinessTypeCd());
            }
            httpUrl = MappingCache.getValue(urls[0]);
            String method = MappingCache.getValue(urls[1]);
            responseMessage = (String) WebServiceAxisClient.callWebService(httpUrl, method,
                    new Object[]{requestBusinessJson.toJSONString()},
                    serviceBusiness.getTimeout());
        } else if (ServiceBusinessConstant.INVOKE_TYPE_HTTP_POST.equals(serviceBusiness.getInvokeType())) {
            //http://user-service/test/sayHello
            httpUrl = MappingCache.getValue(serviceBusiness.getUrl());
            responseMessage = restTemplate.postForObject(httpUrl, requestBusinessJson.toJSONString(), String.class);
        } else if (ServiceBusinessConstant.INVOKE_TYPE_OUT_HTTP_POST.equals(serviceBusiness.getInvokeType())) {
            httpUrl = MappingCache.getValue(serviceBusiness.getUrl());
            responseMessage = restTemplateNoLoadBalanced.postForObject(httpUrl, requestBusinessJson.toJSONString(), String.class);
        } else {//post方式
            throw new ConfigDataException(ResponseConstant.RESULT_CODE_CONFIG_ERROR, "配置错误:c_service_business配置url字段错误,当前无法识别" + serviceBusiness.getBusinessTypeCd());
        }
        logger.debug("调用地址:{}, 订单服务调用下游服务请求报文:{},返回报文:{}", httpUrl, requestBusinessJson, responseMessage);
        if (StringUtil.isNullOrNone(responseMessage) || !Assert.isJsonObject(responseMessage)) {
            throw new BusinessException(ResponseConstant.RESULT_CODE_INNER_ERROR, "下游系统返回格式不正确,请按协议规范处理");
        }
        JSONObject responseJson = JSONObject.parseObject(responseMessage);
        Assert.jsonObjectHaveKey(responseJson, "response", "下游返回报文格式错误,没有包含responseJson节点【" + serviceBusiness.getBusinessTypeCd() + "】");
        JSONObject responseInfo = responseJson.getJSONObject("response");
        Assert.jsonObjectHaveKey(responseInfo, "code", "下游返回报文格式错误,response 节点中没有包含code节点【" + serviceBusiness.getBusinessTypeCd() + "】");
        if (!ResponseConstant.RESULT_CODE_SUCCESS.equals(responseInfo.getString("code"))) {
            throw new BusinessException(ResponseConstant.RESULT_PARAM_ERROR, "业务系统处理失败," + responseInfo.getString("message"));
        }
        return responseJson;
    }
    private String doTransferRequestBusinessSystem(DataFlow dataFlow, AppService service, String reqData) {
        String responseMessage;
@@ -979,45 +650,15 @@
        return responseMessage;
    }
    /**
     * 数据保存到BusinessTable 中
     *
     * @param dataFlow
     * @param synchronousBusinesses
     * @param responseBusinesses
     */
    private void doSaveDataInfoToBusinessTable(IOrderDataFlowContext dataFlow, List<Business> synchronousBusinesses, JSONArray responseBusinesses) {
        Date businessStartDate;
        ServiceBusiness serviceBusiness;
        JSONObject requestBusinessJson;
        for (Business business : synchronousBusinesses) {
            businessStartDate = DateUtil.getCurrentDate();
            //发起Business过程
            updateBusinessStatusCdByBId(business.getbId(), StatusConstant.STATUS_CD_BUSINESS);
            serviceBusiness = ServiceBusinessUtil.getServiceBusiness(business.getBusinessTypeCd());
            requestBusinessJson = OrderDataFlowContextFactory.getRequestBusinessJson(dataFlow, business);
            JSONObject responseJson = doRequestBusinessSystem(dataFlow, serviceBusiness, requestBusinessJson);
            //发布事件
            DataFlowEventPublishing.invokeBusinessBSuccess(dataFlow, business, responseJson);
            responseBusinesses.add(responseJson);
            OrderDataFlowContextFactory.addCostTime(dataFlow, business.getBusinessTypeCd(), "调用" + business.getBusinessTypeCd() + "耗时", businessStartDate);
   /*         saveLogMessage(null,LogAgent.createLogMessage(dataFlow.getRequestCurrentHeaders(),requestBusinessJson.toJSONString()),
                    LogAgent.createLogMessage(dataFlow.getResponseCurrentHeaders(),responseJson.toJSONString()),
                    DateUtil.getCurrentDate().getTime()-businessStartDate.getTime());*/
        }
    }
    /**
     * 处理异步业务
     *
     * @param
     */
    private void doAsynchronousBusinesses(IOrderDataFlowContext dataFlow) throws BusinessException {
    @Override
    protected void doAsynchronousBusinesses(IOrderDataFlowContext dataFlow) throws BusinessException {
        Date startDate = DateUtil.getCurrentDate();
        //6.3 处理异步,按消息队里处理
        List<Business> asynchronousBusinesses = OrderDataFlowContextFactory.getAsynchronousBusinesses(dataFlow);
@@ -1106,19 +747,7 @@
        }
    }
    /**
     * 修改c_business状态
     *
     * @param bId
     * @param statusCd
     */
    private void updateBusinessStatusCdByBId(String bId, String statusCd) {
        Map business = new HashMap();
        business.put("bId", bId);
        business.put("statusCd", statusCd);
        business.put("finishTime", DateUtil.getCurrentDate());
        centerServiceDaoImpl.updateBusinessByBId(business);
    }
    public ICenterServiceDAO getCenterServiceDaoImpl() {
        return centerServiceDaoImpl;