java110 лет назад: 2
Родитель
Сommit
e050a2ab2f

+ 11 - 4
java110-core/src/main/java/com/java110/core/event/cmd/ServiceCmdEventPublishing.java

@@ -110,6 +110,7 @@ public class ServiceCmdEventPublishing {
      */
     public static void multicastEvent(ICmdDataFlowContext cmdDataFlowContext) throws Exception {
         Assert.notNull(cmdDataFlowContext.getServiceCode(), "当前没有可处理的业务信息!");
+        //todo 根据cmd serviceCode 发布事件
         multicastEvent(cmdDataFlowContext.getServiceCode(), cmdDataFlowContext, null);
     }
 
@@ -132,8 +133,10 @@ public class ServiceCmdEventPublishing {
      */
     public static void multicastEvent(String serviceCode, ICmdDataFlowContext dataFlowContext, String asyn) throws Exception {
         try {
+            //todo 组装事件
             CmdEvent targetDataFlowEvent = new CmdEvent(serviceCode, dataFlowContext);
 
+            //todo 发布事件
             multicastEvent(serviceCode, targetDataFlowEvent, asyn);
         } catch (Exception e) {
             logger.error("发布侦听失败,失败原因为:", e);
@@ -151,6 +154,7 @@ public class ServiceCmdEventPublishing {
      * @param asyn  A 表示异步处理
      */
     public static void multicastEvent(String serviceCode, final CmdEvent event, String asyn) throws Exception {
+        //todo 根据serviceCode 去寻找 处理的Cmd处理类 如果java类中 @Java110Cmd(serviceCode = "xx.xx") 写了该注解就会被寻找到
         List<ServiceCmdListener> listeners = getListeners(serviceCode);
         //这里判断 serviceCode + httpMethod 的侦听,如果没有注册直接报错。
         if (listeners == null || listeners.size() == 0) {
@@ -159,7 +163,7 @@ public class ServiceCmdEventPublishing {
         }
         for (final ServiceCmdListener listener : listeners) {
 
-            if (CommonConstant.PROCESS_ORDER_ASYNCHRONOUS.equals(asyn)) { //异步处理
+            if (CommonConstant.PROCESS_ORDER_ASYNCHRONOUS.equals(asyn)) { //todo 异步处理,一般很少用
 
                 Executor executor = getTaskExecutor();
                 executor.execute(new Runnable() {
@@ -174,6 +178,7 @@ public class ServiceCmdEventPublishing {
                 });
                 break;
             } else {
+                // todo 通过同步的方式调用CMDjava类
                 invokeListener(listener, event);
                 break;
             }
@@ -192,7 +197,7 @@ public class ServiceCmdEventPublishing {
     }
 
     /**
-     * Invoke the given listener with the given event.
+     * 执行 根据serviceCode 找到的cmd 类
      *
      * @param listener the ApplicationListener to invoke
      * @param event    the current event to propagate
@@ -201,15 +206,17 @@ public class ServiceCmdEventPublishing {
     @SuppressWarnings({"unchecked", "rawtypes"})
     protected static void invokeListener(ServiceCmdListener listener, CmdEvent event) throws Exception {
         try {
-            //        //这里处理业务逻辑数据
+            //todo 获取 cmd 上下文对象
             ICmdDataFlowContext dataFlowContext = event.getCmdDataFlowContext();
-            //获取请求数据
+            //todo 获取请求数据
             JSONObject reqJson = dataFlowContext.getReqJson();
 
             logger.debug("API服务 --- 请求参数为:{}", reqJson.toJSONString());
 
+            //todo 调用 cmd的校验方法
             listener.validate(event, dataFlowContext, reqJson);
 
+            //todo 调用 cmd的业务处理方法
             listener.doCmd(event, dataFlowContext, reqJson);
 
             //logger.debug("API服务 --- 返回报文信息:{}", dataFlowContext.getResponseEntity());

+ 13 - 1
java110-service/src/main/java/com/java110/service/api/CmdApi.java

@@ -41,6 +41,13 @@ public class CmdApi extends BaseController {
     ISaveSystemErrorSMO saveSystemErrorSMOImpl;
 
 
+    /**
+     * 微服务 /cmd/xx.xx 接受类
+     * @param service
+     * @param postInfo
+     * @param request
+     * @return
+     */
     @RequestMapping(path = "/{service:.+}", method = RequestMethod.POST)
     public ResponseEntity<String> service(@PathVariable String service,
                                           @RequestBody String postInfo,
@@ -48,17 +55,22 @@ public class CmdApi extends BaseController {
         ResponseEntity<String> responseEntity = null;
         Map<String, String> headers = new HashMap<String, String>();
         try {
-
+            //todo 头信息封装
             this.getRequestInfo(request, headers);
+            //todo 将serviceCode 写入到头信息
             headers.put(CommonConstant.HTTP_SERVICE, service);
+            //todo 将请求方式 写入到头信息
             headers.put(CommonConstant.HTTP_METHOD, CommonConstant.HTTP_METHOD_POST);
             logger.debug("api:{} 请求报文为:{},header信息为:{}", service, postInfo, headers);
+            //todo 开始调用 cmd 类
             responseEntity = cmdServiceSMOImpl.cmd(postInfo, headers);
         } catch (Throwable e) {
+            //todo 异常信息进行记录
             LogSystemErrorPo logSystemErrorPo = new LogSystemErrorPo();
             logSystemErrorPo.setErrId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_errId));
             logSystemErrorPo.setErrType(LogSystemErrorDto.ERR_TYPE_CMD);
             logSystemErrorPo.setMsg(ExceptionUtil.getStackTrace(e));
+            //todo 日志
             saveSystemErrorSMOImpl.saveLog(logSystemErrorPo);
             logger.error("请求post 方法[" + service + "]失败:" + postInfo, e);
             responseEntity = new ResponseEntity<String>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);

+ 1 - 1
java110-service/src/main/java/com/java110/service/smo/ICmdServiceSMO.java

@@ -15,7 +15,7 @@ import java.util.Map;
 public interface ICmdServiceSMO {
 
     /**
-     * 业务统一处理服务方法
+     * cmd 调用 处理类
      * @param reqJson 请求报文json
      * @return
      */

+ 5 - 4
java110-service/src/main/java/com/java110/service/smo/impl/CmdServiceSMOImpl.java

@@ -53,7 +53,7 @@ public class CmdServiceSMOImpl extends LoggerEngine implements ICmdServiceSMO {
 
 
     /**
-     * 服务调度
+     * cmd 服务调度
      *
      * @param reqJson 请求报文json
      * @param headers
@@ -70,11 +70,11 @@ public class CmdServiceSMOImpl extends LoggerEngine implements ICmdServiceSMO {
 
         ResponseEntity<String> responseEntity = null;
 
-        //1.0 创建数据流 appId serviceCode
+        //todo 1.0 创建数据流 appId serviceCode
         cmdDataFlowContext = DataFlowFactory.newInstance(CmdDataFlow.class).builder(reqJson, headers);
 
 
-        //6.0 调用下游系统
+        //todo 2.0 调用下游系统
         invokeBusinessSystem(cmdDataFlowContext);
 
         responseEntity = cmdDataFlowContext.getResponseEntity();
@@ -89,12 +89,13 @@ public class CmdServiceSMOImpl extends LoggerEngine implements ICmdServiceSMO {
 
 
     /**
-     * 6.0 调用下游系统
+     * 2.0 调用下游系统
      *
      * @param cmdDataFlowContext
      * @throws BusinessException
      */
     private void invokeBusinessSystem(ICmdDataFlowContext cmdDataFlowContext) throws Exception {
+        //todo 发布 cmd 事件
         ServiceCmdEventPublishing.multicastEvent(cmdDataFlowContext);
     }
 

+ 14 - 2
springboot/src/main/java/com/java110/boot/controller/app/AppController.java

@@ -63,7 +63,7 @@ public class AppController extends BaseController {
     private IPrivilegeSMO privilegeSMOImpl;
 
     /**
-     * 资源请求 post方式
+     * 资源请求 post方式 统一入口类
      * <p>
      * /app/user.listUser
      * <p>
@@ -86,12 +86,18 @@ public class AppController extends BaseController {
         ResponseEntity<String> responseEntity = null;
         try {
             Map<String, String> headers = new HashMap<String, String>();
+            //todo 封装请求中的 头信息
             this.getRequestInfo(request, headers);
+            //todo 将接口编码(服务编码) 放入头信息 通过头信息的方式 传递到后端
             headers.put(CommonConstant.HTTP_SERVICE, service);
+            // todo 请求方式 放入到头信息
             headers.put(CommonConstant.HTTP_METHOD, CommonConstant.HTTP_METHOD_POST);
             logger.debug("api:{} 请求报文为:{},header信息为:{}", service, postInfo, headers);
+            //todo 获取由 PageProcessAspect aop 拦截封装的 pd 页面数据对象
             IPageData pd = (IPageData) request.getAttribute(CommonConstant.CONTEXT_PAGE_DATA);
+            //todo 根据登录用户 的权限 校验 用户是否有权限访问该接口,此时的"/app/" + service 为 开发这账户 菜单权限下的资源地址
             privilegeSMOImpl.hasPrivilege(restTemplate, pd, "/app/" + service);
+            //todo 进入 接口相关 业务处理
             responseEntity = apiSMOImpl.doApi(postInfo, headers,request);
             //todo 写入 token
             wirteToken(request,pd,service,responseEntity);
@@ -105,7 +111,7 @@ public class AppController extends BaseController {
     }
 
     /**
-     * 资源请求 get方式
+     * 资源请求 get方式 统一入口类
      *
      * @param service 请求接口方式
      * @param request 请求对象 查询头信息 url等信息
@@ -121,12 +127,18 @@ public class AppController extends BaseController {
         ResponseEntity<String> responseEntity = null;
         try {
             Map<String, String> headers = new HashMap<String, String>();
+            //todo 封装请求中的 头信息
             this.getRequestInfo(request, headers);
+            //todo 将接口编码(服务编码) 放入头信息 通过头信息的方式 传递到后端
             headers.put(CommonConstant.HTTP_SERVICE, service);
+            // todo 请求方式 放入到头信息
             headers.put(CommonConstant.HTTP_METHOD, CommonConstant.HTTP_METHOD_GET);
             logger.debug("api:{} 请求报文为:{},header信息为:{}", "", headers);
+            //todo 获取由 PageProcessAspect aop 拦截封装的 pd 页面数据对象
             IPageData pd = (IPageData) request.getAttribute(CommonConstant.CONTEXT_PAGE_DATA);
+            //todo 根据登录用户 的权限 校验 用户是否有权限访问该接口,此时的"/app/" + service 为 开发这账户 菜单权限下的资源地址
             privilegeSMOImpl.hasPrivilege(restTemplate, pd, "/app/" + service);
+            //todo 进入 接口相关 业务处理
             responseEntity = apiSMOImpl.doApi(JSONObject.toJSONString(getParameterStringMap(request)), headers, request);
 
         } catch (Throwable e) {

+ 16 - 0
springboot/src/main/java/com/java110/boot/controller/package-info.java

@@ -0,0 +1,16 @@
+/**
+ * 入口控制类
+ *
+ * // 1.0 系统基本入口类为 ./app/AppController 通过 servicePost  或者 serviceGet 拦截 请求
+ * 请求地址为 /app/xxx.xxx  其中xxx.xxx 统称为 serviceCode  服务编码或者接口编码
+ *
+ * 数据流转流程: AppController.java下的servicePost 接受请求--->ApiSMOImpl.java下的doApi---> ApiServiceSMOImpl下的service方法 --> ApiServiceSMOImpl下的dealCmd方法
+ * --->java110-service 模块下的 CmdApi 类 --->CmdServiceSMOImpl.java 的 cmd方法 ---> ServiceCmdListener.java 下的cmd 类 ---> 到具体的serviceCode 对应的cmd文件
+ *
+ * //2.0 支付 三方支付系统通知 统一有 ./app/payment 下的类来处理
+ *
+ * // 3.0 智能电表通知 通过 ./app/smartWeter 下的类来处理
+ *
+ * // 4.0 智能充电桩 通过./app/charge 下的类来处理
+ */
+package com.java110.boot.controller;

+ 1 - 1
springboot/src/main/java/com/java110/boot/smo/IApiServiceSMO.java

@@ -12,7 +12,7 @@ import java.util.Map;
 public interface IApiServiceSMO {
 
     /**
-     * 业务统一处理服务方法
+     * 业务统一处理服务方法 应用是否有接口权限校验
      * @param reqJson 请求报文json
      * @return
      */

+ 9 - 1
springboot/src/main/java/com/java110/boot/smo/api/IApiSMO.java

@@ -8,5 +8,13 @@ import java.util.Map;
 
 public interface IApiSMO {
 
-    public ResponseEntity<String> doApi(String body, Map<String, String> headers, HttpServletRequest request) throws UnsupportedEncodingException;
+    /**
+     *  主要完成员工是否有访问小区的权限校验
+     * @param body
+     * @param headers
+     * @param request
+     * @return
+     * @throws UnsupportedEncodingException
+     */
+     ResponseEntity<String> doApi(String body, Map<String, String> headers, HttpServletRequest request) throws UnsupportedEncodingException;
 }

+ 4 - 5
springboot/src/main/java/com/java110/boot/smo/api/impl/ApiSMOImpl.java

@@ -88,19 +88,17 @@ public class ApiSMOImpl extends DefaultAbstractComponentSMO implements IApiSMO {
 
         IPageData pd = (IPageData) request.getAttribute(CommonConstant.CONTEXT_PAGE_DATA);
 
-
+        //todo 校验员工时 是否有访问小区的权限
         ComponentValidateResult result = this.validateStoreStaffCommunityRelationship(pd, restTemplate);
+        //todo 如果 登录用户不为空 则将 前段传递的user-id 重写
         if (!StringUtil.isEmpty(result.getLoginUserId())) {
             headers.remove("user-id");
             headers.remove("user_id");
             headers.put("user-id", result.getUserId());
             headers.put("user_id", result.getUserId());
             headers.put("login-user-id",result.getLoginUserId());
-//            if (!StringUtil.isEmpty(result.getUserName())) {
-//                headers.put("user-name", URLEncoder.encode(result.getUserName(), "UTF-8"));
-//            }
         }
-
+        // todo 如果 商户不为空则 商户ID写入只头信息中 这里的商户ID 可以是物业ID 或者商家ID
         if (!StringUtil.isEmpty(result.getStoreId())) {
             headers.remove("store-id");
             headers.put("store-id", result.getStoreId());
@@ -113,6 +111,7 @@ public class ApiSMOImpl extends DefaultAbstractComponentSMO implements IApiSMO {
             headers.put("user-id", "-1");
         }
         headers.put("store-id", result.getStoreId());
+        // todo 应用是否有接口权限校验
         ResponseEntity<String> responseEntity = apiServiceSMOImpl.service(body, headers);
         return responseEntity;
     }

+ 31 - 19
springboot/src/main/java/com/java110/boot/smo/impl/ApiServiceSMOImpl.java

@@ -85,21 +85,21 @@ public class ApiServiceSMOImpl extends LoggerEngine implements IApiServiceSMO {
         String resJson = "";
 
         try {
-            //在post和 put 时才存在报文加密的情况
+            //todo 在post和 put 时才存在报文加密的情况
             if ("POST,PUT".contains(headers.get(CommonConstant.HTTP_METHOD))) {
                 reqJson = decrypt(reqJson, headers);
             }
 
-            //1.0 创建数据流 appId serviceCode
+            //todo 1.0 创建数据流 appId serviceCode
             dataFlow = DataFlowFactory.newInstance(ApiDataFlow.class).builder(reqJson, headers);
 
-            //2.0 加载配置信息
+            //todo 2.0 加载配置信息
             initConfigData(dataFlow);
 
-            //3.0 校验 APPID是否有权限操作serviceCode
+            //todo 3.0 校验 APPID是否有权限操作serviceCode
             judgeAuthority(dataFlow);
 
-            //6.0 调用下游系统
+            //todo 6.0 调用下游系统
             invokeBusinessSystem(dataFlow);
 
             responseEntity = dataFlow.getResponseEntity();
@@ -328,13 +328,13 @@ public class ApiServiceSMOImpl extends LoggerEngine implements IApiServiceSMO {
             DataFlowFactory.addCostTime(dataFlow, "judgeAuthority", "鉴权耗时", startDate);
             throw new NoAuthorityException(ResponseConstant.RESULT_CODE_NO_AUTHORITY_ERROR, "requestTime 格式不对,遵循yyyyMMddHHmmss格式");
         }
-        //用户ID校验
+        //todo 用户ID校验
         if (StringUtil.isNullOrNone(dataFlow.getUserId())) {
             throw new NoAuthorityException(ResponseConstant.RESULT_CODE_NO_AUTHORITY_ERROR, "USER_ID 不能为空");
         }
 
 
-        //判断 AppId 是否有权限操作相应的服务
+        //todo 判断 AppId 是否有权限操作相应的服务
         AppService appService = DataFlowFactory.getService(dataFlow, dataFlow.getRequestHeaders().get(CommonConstant.HTTP_SERVICE));
 
         //这里调用缓存 查询缓存信息
@@ -373,9 +373,9 @@ public class ApiServiceSMOImpl extends LoggerEngine implements IApiServiceSMO {
      */
     private void invokeBusinessSystem(ApiDataFlow dataFlow) throws BusinessException {
         Date startDate = DateUtil.getCurrentDate();
-        //拿到当前服务
+        //todo 拿到当前服务
         AppService appService = DataFlowFactory.getService(dataFlow, dataFlow.getRequestHeaders().get(CommonConstant.HTTP_SERVICE));
-        //这里对透传类处理
+        //todo 这里对透传类处理,目前很少用到,可以不用关注
         if ("NT".equals(appService.getIsInstance())) {
             //如果是透传类 请求方式必须与接口提供方调用方式一致
             String httpMethod = dataFlow.getRequestCurrentHeaders().get(CommonConstant.HTTP_METHOD);
@@ -386,8 +386,8 @@ public class ApiServiceSMOImpl extends LoggerEngine implements IApiServiceSMO {
             //dataFlow.setApiCurrentService(ServiceCodeConstant.SERVICE_CODE_DO_SERVICE_TRANSFER);
             doNT(appService, dataFlow, dataFlow.getReqJson());
             return;
-        } else if ("T".equals(appService.getIsInstance())) {
-            //如果是透传类 请求方式必须与接口提供方调用方式一致
+        } else if ("T".equals(appService.getIsInstance())) { // todo 通过透传方式 调用 目前很少用到,可以不用关注
+            //todo 如果是透传类 请求方式必须与接口提供方调用方式一致
             String httpMethod = dataFlow.getRequestCurrentHeaders().get(CommonConstant.HTTP_METHOD);
             if (!appService.getMethod().equals(httpMethod)) {
                 throw new ListenerExecuteException(ResponseConstant.RESULT_CODE_ERROR,
@@ -395,13 +395,14 @@ public class ApiServiceSMOImpl extends LoggerEngine implements IApiServiceSMO {
             }
             doTransfer(appService, dataFlow, dataFlow.getReqJson());
             return;
-        } else if ("CMD".equals(appService.getIsInstance())) {
+        } else if ("CMD".equals(appService.getIsInstance())) { // todo 微服务调用方式,目前主要用这种方式调度分发 到不同的微服务,这里是通过c_service 中配置 调用到不同的微服务
             //如果是透传类 请求方式必须与接口提供方调用方式一致
             String httpMethod = dataFlow.getRequestCurrentHeaders().get(CommonConstant.HTTP_METHOD);
             if (!appService.getMethod().equals(httpMethod)) {
                 throw new ListenerExecuteException(ResponseConstant.RESULT_CODE_ERROR,
                         "服务【" + appService.getServiceCode() + "】调用方式不对请检查,当前请求方式为:" + httpMethod);
             }
+            // todo 根据接口编码找到 appService 也就是c_service 表中的内容
             dealCmd(appService, dataFlow, dataFlow.getReqJson());
             return;
         } else {
@@ -503,11 +504,11 @@ public class ApiServiceSMOImpl extends LoggerEngine implements IApiServiceSMO {
                 oId = headers.get(OrderDto.O_ID).get(0);
             }
 
-            //进入databus
-            if (!CommonConstant.HTTP_METHOD_GET.equals(appService.getMethod())) {
-
-                // dealDatabus(serviceCode, reqJson, oId);
-            }
+//            //进入databus
+//            if (!CommonConstant.HTTP_METHOD_GET.equals(appService.getMethod())) {
+//
+//                // dealDatabus(serviceCode, reqJson, oId);
+//            }
 
 
         } catch (HttpStatusCodeException e) { //这里spring 框架 在4XX 或 5XX 时抛出 HttpServerErrorException 异常,需要重新封装一下
@@ -545,12 +546,20 @@ public class ApiServiceSMOImpl extends LoggerEngine implements IApiServiceSMO {
         dataFlow.setResponseEntity(responseEntity);
     }
 
+    /**
+     * 开始调度微服务
+     * @param appService
+     * @param dataFlow
+     * @param reqJson
+     */
     private void dealCmd(AppService appService, ApiDataFlow dataFlow, JSONObject reqJson) {
         Map<String, String> reqHeader = dataFlow.getRequestCurrentHeaders();
         HttpHeaders header = new HttpHeaders();
+        //todo 对头信息重新包装
         for (String key : dataFlow.getRequestCurrentHeaders().keySet()) {
             header.add(key, reqHeader.get(key));
         }
+        //todo 用户信息再次包装
         if (reqHeader.containsKey(CommonConstant.USER_ID)
                 && (!reqJson.containsKey("userId") || StringUtil.isEmpty(reqJson.getString("userId")))) {
             reqJson.put("userId", reqHeader.get(CommonConstant.USER_ID));
@@ -570,14 +579,18 @@ public class ApiServiceSMOImpl extends LoggerEngine implements IApiServiceSMO {
 
         serviceCode = serviceCode.startsWith("/") ? serviceCode : ("/" + serviceCode);
 
+        //todo 组装调用微服务的地址
         String requestUrl = "http://127.0.0.1:8008/cmd" + serviceCode;
         //
         ResponseEntity responseEntity = null;
+        //todo url 带了地址这里 拼接
         if (!StringUtil.isNullOrNone(orgRequestUrl)) {
             String param = orgRequestUrl.contains("?") ? orgRequestUrl.substring(orgRequestUrl.indexOf("?") + 1, orgRequestUrl.length()) : "";
             requestUrl += ("?" + param);
         }
         try {
+            //todo http的方式调用微服务,相应的java类可以到相应微服务下的cmd下根据serviceCode 的寻找
+            //todo 这里会调用到 java110-service 模块下的 CmdApi 类,这个类各个微服务都会集成
             responseEntity = outRestTemplate.exchange(requestUrl, HttpMethod.POST, httpEntity, String.class);
             HttpHeaders headers = responseEntity.getHeaders();
             String oId = "-1";
@@ -585,7 +598,7 @@ public class ApiServiceSMOImpl extends LoggerEngine implements IApiServiceSMO {
                 oId = headers.get(OrderDto.O_ID).get(0);
             }
 
-        } catch (HttpStatusCodeException e) { //这里spring 框架 在4XX 或 5XX 时抛出 HttpServerErrorException 异常,需要重新封装一下
+        } catch (HttpStatusCodeException e) { //todo 这里spring 框架 在4XX 或 5XX 时抛出 HttpServerErrorException 异常,需要重新封装一下
             logger.error("请求下游服务【" + requestUrl + "】异常,参数为" + httpEntity + e.getResponseBodyAsString(), e);
             String body = e.getResponseBodyAsString();
 
@@ -603,7 +616,6 @@ public class ApiServiceSMOImpl extends LoggerEngine implements IApiServiceSMO {
         if (responseEntity.getStatusCode() != HttpStatus.OK) {
             responseEntity = ResultVo.createResponseEntity(ResultVo.CODE_ERROR, String.valueOf(responseEntity.getBody()));
             dataFlow.setResponseEntity(responseEntity);
-
             return;
         }
         if (StringUtils.isEmpty(responseEntity.getBody() + "")) {