Dubbo 路由规则的过滤器实现

This commit is contained in:
YunaiV 2020-07-21 08:07:11 +08:00
parent e6201b00c1
commit 1dadf93449
24 changed files with 160 additions and 571 deletions

View File

@ -18,6 +18,13 @@
<artifactId>common-framework</artifactId> <artifactId>common-framework</artifactId>
</dependency> </dependency>
<!-- Web 相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<optional>true</optional>
</dependency>
<!-- RPC 相关 --> <!-- RPC 相关 -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>

View File

@ -0,0 +1,25 @@
package cn.iocoder.mall.dubbo.config;
import cn.iocoder.mall.dubbo.core.web.DubboRouterTagWebInterceptor;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
public class DubboWebAutoConfiguration implements WebMvcConfigurer {
// ========== 拦截器相关 ==========
@Override
public void addInterceptors(InterceptorRegistry registry) {
try {
registry.addInterceptor(new DubboRouterTagWebInterceptor()).order(-1000);
} catch (NoSuchBeanDefinitionException e) {
// logger.warn("[addInterceptors][无法获取 AccessLogInterceptor 拦截器,因此不启动 AccessLog 的记录]");
}
}
}

View File

@ -0,0 +1,62 @@
package cn.iocoder.mall.dubbo.core.filter;
import cn.iocoder.common.framework.util.StringUtils;
import cn.iocoder.mall.dubbo.core.router.DubboRouterTagContextHolder;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;
/**
* 基于 Dubbo 标签路由规则(http://dubbo.apache.org/zh-cn/docs/user/demos/routing-rule.html)实现如下功能
* 1. 本地开发调试时在带有 Dubbo Tag 的情况下优先调用指定 Tag 的服务提供者这样我们可以将本地启动的服务提供者打上相应的 Tag即可优先调用本地
* 2. TODO 优化点蓝绿发布灰度发布
*
* 实现逻辑为
* 1. 对于 Consumer 在调用 Provider 会将 {@link DubboRouterTagContextHolder} 中的 Tag 通过 Dubbo 隐式传参
* 同时Dubbo 自带 {@link org.apache.dubbo.rpc.cluster.router.tag.TagRouter}会根据该参数会选择符合该 Tag Provider
* 2. 对于 Provider 在通过 Dubbo 隐式传参获得到 Tag 会设置到 {@link DubboRouterTagContextHolder}
* 这样 Provider 作为 Consumer 角色时调用其它 Provider 可以继续实现标签路由的功能
*/
@Activate(group = {CommonConstants.PROVIDER, CommonConstants.CONSUMER}, order = -1000)
public class DubboRouterTagFilter implements Filter {
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
// 消费端
if (RpcContext.getContext().isConsumerSide()) {
// 设置 Dubbo Tag Dubbo 隐式传参
String dubboTag = DubboRouterTagContextHolder.getTag();
boolean hasDubboTag = StringUtils.hasText(dubboTag);
if (hasDubboTag) {
invocation.setAttachment(CommonConstants.TAG_KEY, dubboTag);
}
// 继续调用
try {
return invoker.invoke(invocation);
} finally {
// 解决极端情况下本地 injvm 调用时消费端会调用 DubboRouterTagContextHolder.clear() 上下文导致消费端也被清理了因为在同一个 JVM 进程内
if (hasDubboTag) {
DubboRouterTagContextHolder.setTag(dubboTag);
}
}
// 提供端
} else {
// Dubbo 隐式传参获得 Dubbo Tag
String dubboTag = invocation.getAttachment(CommonConstants.TAG_KEY);
boolean hasDubboTag = StringUtils.hasText(dubboTag);
if (hasDubboTag) {
invocation.setAttachment(CommonConstants.TAG_KEY, dubboTag);
}
// 继续调用
try {
return invoker.invoke(invocation);
} finally {
// 清理
if (hasDubboTag) {
DubboRouterTagContextHolder.clear();
}
}
}
}
}

View File

@ -1,4 +0,0 @@
/**
* 占坑
*/
package cn.iocoder.mall.dubbo.core;

View File

@ -0,0 +1,25 @@
package cn.iocoder.mall.dubbo.core.router;
/**
* Dubbo 路由 Tag 的上下文
*
* @see cn.iocoder.mall.dubbo.core.filter.DubboRouterTagFilter
* @see cn.iocoder.mall.dubbo.core.web.DubboRouterTagWebInterceptor
*/
public class DubboRouterTagContextHolder {
private static ThreadLocal<String> tagContext = new ThreadLocal<>();
public static void setTag(String tag) {
tagContext.set(tag);
}
public static String getTag() {
return tagContext.get();
}
public static void clear() {
tagContext.remove();
}
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.mall.dubbo.core.web;
import cn.iocoder.common.framework.util.StringUtils;
import cn.iocoder.mall.dubbo.core.router.DubboRouterTagContextHolder;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Dubbo 路由标签的 Web 拦截器将请求 Header 中的 {@link #HEADER_DUBBO_TAG} 设置到 {@link DubboRouterTagContextHolder}
*
* @see cn.iocoder.mall.dubbo.core.filter.DubboRouterTagFilter
*/
public class DubboRouterTagWebInterceptor implements HandlerInterceptor {
private static final String HEADER_DUBBO_TAG = "dubbo-tag";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String tag = request.getHeader(HEADER_DUBBO_TAG);
if (StringUtils.hasText(tag)) {
DubboRouterTagContextHolder.setTag(tag);
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
DubboRouterTagContextHolder.clear();
}
}

View File

@ -1 +1,2 @@
dubboExceptionFilter=cn.iocoder.mall.dubbo.core.filter.DubboProviderExceptionFilter dubboExceptionFilter=cn.iocoder.mall.dubbo.core.filter.DubboProviderExceptionFilter
dubboRouterTagFilter=cn.iocoder.mall.dubbo.core.filter.DubboRouterTagFilter

View File

@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.iocoder.mall.dubbo.config.DubboWebAutoConfiguration

View File

@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>onemall</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mall-cache</artifactId>
<dependencies>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.7.2</version>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.10.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -44,8 +44,8 @@
<!-- RPC 相关 --> <!-- RPC 相关 -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>cn.iocoder.mall</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId> <artifactId>mall-spring-boot-starter-dubbo</artifactId>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -2,6 +2,7 @@
POST {{baseUrl}}/department/create POST {{baseUrl}}/department/create
Content-Type: application/x-www-form-urlencoded Content-Type: application/x-www-form-urlencoded
Authorization: Bearer {{accessToken}} Authorization: Bearer {{accessToken}}
dubbo-tag: yunai
name=测试部门&pid=0&sort=0 name=测试部门&pid=0&sort=0

View File

@ -34,6 +34,7 @@ dubbo:
provider: provider:
filter: -exception filter: -exception
validation: true # 开启 Provider 参数校验 validation: true # 开启 Provider 参数校验
tag:
OAuth2Rpc: OAuth2Rpc:
version: 1.0.0 version: 1.0.0
AdminRpc: AdminRpc:

View File

@ -1,63 +0,0 @@
package cn.iocoder.mall.system.rest.controller.datadict;
import cn.iocoder.common.framework.enums.MallConstants;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(MallConstants.ROOT_PATH_ADMIN + "/data-dict")
@Api(tags = "管理员 - 数据字典 API")
public class AdminsDataDictController {
// @Reference(validation = "true", version = "${dubbo.provider.DataDictService.version}")
// private DataDictService dataDictService;
// @GetMapping("/list")
// @ApiOperation(value = "数据字典全列表")
// @RequiresPermissions("system.dataDict.list")
// public CommonResult<List<DataDictBO>> list() {
// return success( dataDictService.selectDataDictList());
// }
//
// @GetMapping("/tree")
// @RequiresPermissions // 因为是通用的接口所以无需权限标识
// @ApiOperation(value = "数据字典树结构", notes = "该接口返回的信息更为精简。一般用于前端缓存数据字典到本地。")
// public CommonResult<List<DataDictEnumVO>> tree() {
// // 查询数据字典全列表
// List<DataDictBO> dataDicts = dataDictService.selectDataDictList();
// // 构建基于 enumValue 聚合的 Multimap
// ImmutableListMultimap<String, DataDictBO> dataDictMap = Multimaps.index(dataDicts, DataDictBO::getEnumValue); // KEY enumValue VALUE DataDictBO 数组
// // 构建返回结果
// List<DataDictEnumVO> dataDictEnumVOs = new ArrayList<>(dataDictMap.size());
// dataDictMap.keys().forEach(enumValue -> {
// DataDictEnumVO dataDictEnumVO = new DataDictEnumVO().setEnumValue(enumValue)
// .setValues(DataDictConvert.INSTANCE.convert2(dataDictMap.get(enumValue)));
// dataDictEnumVOs.add(dataDictEnumVO);
// });
// return success(dataDictEnumVOs);
// }
//
// @PostMapping("/add")
// @RequiresPermissions("system.dataDict.add")
// @ApiOperation(value = "创建数据字典")
// public CommonResult<DataDictBO> add(DataDictAddDTO dataDictAddDTO) {
// return success(dataDictService.addDataDict(AdminSecurityContextHolder.getContext().getAdminId(), dataDictAddDTO));
// }
//
// @PostMapping("/update")
// @RequiresPermissions("system.dataDict.update")
// @ApiOperation(value = "更新数据字典")
// public CommonResult<Boolean> update(DataDictUpdateDTO dataDictUpdateDTO) {
// return success(dataDictService.updateDataDict(AdminSecurityContextHolder.getContext().getAdminId(), dataDictUpdateDTO));
// }
//
// @PostMapping("/delete")
// @RequiresPermissions("system.dataDict.delete")
// @ApiOperation(value = "删除数据字典")
// @ApiImplicitParam(name = "id", value = "编号", required = true, example = "100")
// public CommonResult<Boolean> delete(@RequestParam("id") Integer id) {
// return success(dataDictService.deleteDataDict(AdminSecurityContextHolder.getContext().getAdminId(), id));
// }
}

View File

@ -1,71 +0,0 @@
package cn.iocoder.mall.system.rest.controller.errorCode;
import cn.iocoder.common.framework.enums.MallConstants;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.security.core.annotation.RequiresPermissions;
import cn.iocoder.mall.system.biz.bo.errorcode.ErrorCodeBO;
import cn.iocoder.mall.system.biz.dto.errorcode.ErrorCodeAddDTO;
import cn.iocoder.mall.system.biz.dto.errorcode.ErrorCodeDeleteDTO;
import cn.iocoder.mall.system.biz.dto.errorcode.ErrorCodePageDTO;
import cn.iocoder.mall.system.biz.dto.errorcode.ErrorCodeUpdateDTO;
import cn.iocoder.mall.system.biz.service.errorcode.ErrorCodeService;
import cn.iocoder.mall.system.rest.convert.errorcode.ErrorCodeConvert;
import cn.iocoder.mall.system.rest.request.errorcode.ErrorCodeAddRequest;
import cn.iocoder.mall.system.rest.request.errorcode.ErrorCodePageRequest;
import cn.iocoder.mall.system.rest.response.errorcode.ErrorCodePageResponse;
import cn.iocoder.mall.system.rest.request.errorcode.ErrorCodeUpdateRequest;
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.web.bind.annotation.*;
/**
* 错误码
*
* @author youyusi
*/
@RestController
@RequestMapping(MallConstants.ROOT_PATH_ADMIN + "/errorcode") // TODO FROM 芋艿 to 鱿鱼须error-code
@Api("错误码")
public class SystemErrorCodeController { // TODO FROM 芋艿 to 鱿鱼须变量要空行
@Autowired
private ErrorCodeService errorCodeService;
@GetMapping("/page")
@ApiOperation(value = "错误码分页")
@RequiresPermissions("system:errorcode:page")
public CommonResult<PageResult<ErrorCodePageResponse>> page(ErrorCodePageRequest request) {
ErrorCodePageDTO pageDTO = ErrorCodeConvert.INSTANCE.convert(request);
PageResult<ErrorCodeBO> pageResult = errorCodeService.getErrorCodePage(pageDTO);
return CommonResult.success(ErrorCodeConvert.INSTANCE.convertPage(pageResult));
}
@PostMapping("/add")
@ApiOperation(value = "创建错误码")
@RequiresPermissions("system:errorcode:add")
public CommonResult<Integer> add(ErrorCodeAddRequest request) {
ErrorCodeAddDTO addDTO = ErrorCodeConvert.INSTANCE.convert(request);
return CommonResult.success(errorCodeService.addErrorCode(addDTO));
}
@PostMapping("/update")
@ApiOperation(value = "更新错误码")
@RequiresPermissions("system:errorcode:update")
public CommonResult<Boolean> update(ErrorCodeUpdateRequest request) {
ErrorCodeUpdateDTO updateDTO = ErrorCodeConvert.INSTANCE.convert(request);
errorCodeService.updateErrorCode(updateDTO);
return CommonResult.success(true);
}
@PostMapping("/delete")
@ApiOperation(value = "删除错误码")
@RequiresPermissions("system:errorcode:delete")
@ApiImplicitParam(name = "id", value = "错误码编号", required = true, example = "1")
public CommonResult<Boolean> delete(@RequestParam("id") Integer id) {
ErrorCodeDeleteDTO deleteDTO = new ErrorCodeDeleteDTO().setId(id);
errorCodeService.deleteErrorCode(deleteDTO);
return CommonResult.success(true);
}
}

View File

@ -1,56 +0,0 @@
package cn.iocoder.mall.system.rest.controller.systemlog;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.system.biz.bo.systemlog.AccessLogBO;
import cn.iocoder.mall.system.biz.dto.system.AccessLogPageDTO;
import cn.iocoder.mall.system.biz.service.systemlog.SystemLogService;
import cn.iocoder.mall.system.rest.convert.systemlog.AccessLogConvert;
import cn.iocoder.mall.system.rest.response.systemlog.AccessLogPageResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* @author:ycjx
* @descriptio
* @create:2019-06-23 16:42
*/
@RestController
@RequestMapping("admins/system/logs")
@Api("系统日志")
public class SystemLogController {
@Autowired
private SystemLogService systemLogService;
@GetMapping("/access/page")
@ApiOperation(value = "访问日志分页")
@ApiImplicitParams({
@ApiImplicitParam(name = "userId", value = "用户id", example = "1"),
@ApiImplicitParam(name = "pageNo", value = "页码,从 1 开始", example = "1"),
@ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, example = "10"),
})
public CommonResult<PageResult<AccessLogPageResponse>> page(@RequestParam(value = "accountId", required = false) Integer accountId,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
// TODO FROM 芋艿 to 2447007062不要留这么大的空行
// TODO FROM 芋艿 to 2447007062使用 Request 接收参数噢
AccessLogPageDTO accessLogPageDTO = new AccessLogPageDTO().setAccountId(accountId)
.setPageNo(pageNo).setPageSize(pageSize);
// 查询分页
PageResult<AccessLogBO> result = systemLogService.getAccessLogPage(accessLogPageDTO);
// 转换结果
return CommonResult.success(AccessLogConvert.INSTANCE.convert(result));
}
}

View File

@ -1,29 +0,0 @@
package cn.iocoder.mall.system.rest.convert.errorcode;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.system.biz.bo.errorcode.ErrorCodeBO;
import cn.iocoder.mall.system.biz.dto.errorcode.ErrorCodeAddDTO;
import cn.iocoder.mall.system.biz.dto.errorcode.ErrorCodePageDTO;
import cn.iocoder.mall.system.biz.dto.errorcode.ErrorCodeUpdateDTO;
import cn.iocoder.mall.system.rest.request.errorcode.ErrorCodeAddRequest;
import cn.iocoder.mall.system.rest.request.errorcode.ErrorCodePageRequest;
import cn.iocoder.mall.system.rest.response.errorcode.ErrorCodePageResponse;
import cn.iocoder.mall.system.rest.request.errorcode.ErrorCodeUpdateRequest;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
* @author ding
*/
@Mapper
public interface ErrorCodeConvert {
ErrorCodeConvert INSTANCE = Mappers.getMapper(ErrorCodeConvert.class);
ErrorCodeAddDTO convert(ErrorCodeAddRequest bean);
ErrorCodeUpdateDTO convert(ErrorCodeUpdateRequest bean);
ErrorCodePageDTO convert(ErrorCodePageRequest bean);
PageResult<ErrorCodePageResponse> convertPage(PageResult<ErrorCodeBO> bean);
}

View File

@ -1,26 +0,0 @@
package cn.iocoder.mall.system.rpc.api.errorcode;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.system.rpc.request.errorcode.ErrorCodeAddRequest;
import cn.iocoder.mall.system.rpc.request.systemlog.ExceptionLogAddRequest;
import cn.iocoder.mall.system.rpc.response.errorcode.ErrorCodeResponse;
import java.util.List;
/**
* ErrorCode RPC 接口
* 提供其他服务初始化加载错误码到db中同时提供读取该服务的错误码信息
* 同时提供删除接口
* @author ding
*/
public interface ErrorCodeRPC {
CommonResult<List<ErrorCodeResponse>> getErrorCodeByGroup(Integer group);
CommonResult<Boolean> addErrorCode(ErrorCodeAddRequest errorCodeAddRequest);
CommonResult<Boolean> addErrorCodeList(List<ErrorCodeAddRequest> list);
CommonResult<Boolean> deleteErrorCodeByGroup(Integer group, Integer type);
}

View File

@ -1,33 +0,0 @@
package cn.iocoder.mall.system.rpc.request.errorcode;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import java.io.Serializable;
/**
* 错误码模块枚举初始化错误码时使用
* @author ding
*/
@Data
@Accessors(chain = true)
public class ErrorCodeAddRequest implements Serializable {
@ApiModelProperty(value = "错误码信息", required = true)
@NotEmpty(message = "错误码信息不能为空")
private String message;
@ApiModelProperty(value = "错误码编码")
@NotEmpty(message = "错误码编码不能为空")
private Integer code;
@ApiModelProperty(value = "错误码分组,字典表获取")
@NotEmpty(message = "错误码分组不能为空")
private Integer group;
@ApiModelProperty(value = "错误码角色,系统内置(枚举)还是自定义")
@NotEmpty(message = "错误码角色不能空")
private Integer type;
}

View File

@ -1,33 +0,0 @@
package cn.iocoder.mall.system.rpc.response.errorcode;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 错误码模块
* @author ding
*/
@ApiModel("管理员 - 错误码模块 - 查询错误码")
@Data
@Accessors(chain = true)
public class ErrorCodeResponse {
/**
* 错误码编号
*/
private Integer id;
/**
* 错误码编码
*/
private Integer code;
/**
* 错误码错误信息
*/
private String message;
/**
* 添加时间
*/
private Date createTime;
}

View File

@ -1,23 +0,0 @@
package cn.iocoder.mall.system.rpc.convert.errorcode;
import cn.iocoder.mall.system.biz.bo.errorcode.ErrorCodeBO;
import cn.iocoder.mall.system.biz.dto.errorcode.ErrorCodeAddDTO;
import cn.iocoder.mall.system.rpc.request.errorcode.ErrorCodeAddRequest;
import cn.iocoder.mall.system.rpc.response.errorcode.ErrorCodeResponse;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface ErrorCodeConvert {
ErrorCodeConvert INSTANCE = Mappers.getMapper(ErrorCodeConvert.class);
List<ErrorCodeResponse> convert(List<ErrorCodeBO> bean);
ErrorCodeAddDTO convert(ErrorCodeAddRequest errorCodeAddRequest);
List<ErrorCodeAddDTO> convertList(List<ErrorCodeAddRequest> bean);
}

View File

@ -1,19 +0,0 @@
package cn.iocoder.mall.system.rpc.convert.systemlog;
import cn.iocoder.mall.system.biz.dto.system.AccessLogAddDTO;
import cn.iocoder.mall.system.biz.dto.system.ExceptionLogAddDTO;
import cn.iocoder.mall.system.rpc.request.systemlog.AccessLogAddRequest;
import cn.iocoder.mall.system.rpc.request.systemlog.ExceptionLogAddRequest;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper
public interface SystemLogConvert {
SystemLogConvert INSTANCE = Mappers.getMapper(SystemLogConvert.class);
AccessLogAddDTO convert(AccessLogAddRequest bean);
ExceptionLogAddDTO convert(ExceptionLogAddRequest bean);
}

View File

@ -1,69 +0,0 @@
package cn.iocoder.mall.system.rpc.rpc.errorcode;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.system.biz.bo.errorcode.ErrorCodeBO;
import cn.iocoder.mall.system.biz.service.errorcode.ErrorCodeService;
import cn.iocoder.mall.system.rpc.api.errorcode.ErrorCodeRPC;
import cn.iocoder.mall.system.rpc.convert.errorcode.ErrorCodeConvert;
import cn.iocoder.mall.system.rpc.convert.user.UserConvert;
import cn.iocoder.mall.system.rpc.request.errorcode.ErrorCodeAddRequest;
import cn.iocoder.mall.system.rpc.response.errorcode.ErrorCodeResponse;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/**
*
* @author ding
*/
@Service(version = "${dubbo.provider.ErrorCodeRPC.version}", validation = "true")
public class ErrorCodeRPCImpl implements ErrorCodeRPC {
@Autowired
private ErrorCodeService errorCodeService;
/**
* 根据分组获取错误码信息
* @param group 分组
* @return 错误码信息
*/
@Override
public CommonResult<List<ErrorCodeResponse>> getErrorCodeByGroup(Integer group) {
List<ErrorCodeBO> list = errorCodeService.getErrorCodeByGroup(group);
return CommonResult.success(ErrorCodeConvert.INSTANCE.convert(list));
}
/**
* 添加错误码信息如果是枚举错误码角色一定是系统内置
* @param errorCodeAddRequest 错误码
* @return 是否成功
*/
@Override
public CommonResult<Boolean> addErrorCode(ErrorCodeAddRequest errorCodeAddRequest) {
errorCodeService.addErrorCode(ErrorCodeConvert.INSTANCE.convert(errorCodeAddRequest));
return CommonResult.success(true);
}
/**
* 批量添加错误码信息
* @param list 错误码信息集合
* @return 是否成功
*/
@Override
public CommonResult<Boolean> addErrorCodeList(List<ErrorCodeAddRequest> list) {
errorCodeService.addErrorCodeList(ErrorCodeConvert.INSTANCE.convertList(list));
return CommonResult.success(true);
}
/**
* 根据分组和角色条件删除错误码信息只能删除db信息删除后会进行校验刷新utils
* @param group 分组
* @param type 角色
* @return 是否成功
*/
@Override
public CommonResult<Boolean> deleteErrorCodeByGroup(Integer group, Integer type) {
return null;
}
}

View File

@ -1,15 +0,0 @@
package cn.iocoder.mall.system.api;
import cn.iocoder.mall.system.api.bo.systemlog.AccessLogPageBO;
import cn.iocoder.mall.system.api.dto.systemlog.AccessLogPageDTO;
/**
* 系统日志 Service 接口
*
* 例如说访问日志错误日志操作日志等等
*/
public interface SystemLogService {
AccessLogPageBO getAccessLogPage(AccessLogPageDTO accessLogPageDTO);
}

View File

@ -1,94 +0,0 @@
package cn.iocoder.mall.admin.service;
import cn.iocoder.common.framework.util.StringUtil;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.system.api.SystemLogService;
import cn.iocoder.mall.system.api.bo.systemlog.AccessLogBO;
import cn.iocoder.mall.system.api.bo.systemlog.AccessLogPageBO;
import cn.iocoder.mall.system.api.dto.systemlog.AccessLogAddDTO;
import cn.iocoder.mall.system.api.dto.systemlog.AccessLogPageDTO;
import cn.iocoder.mall.system.api.dto.systemlog.ExceptionLogAddDTO;
import cn.iocoder.mall.admin.convert.AccessLogConvert;
import cn.iocoder.mall.admin.dao.AccessLogMapper;
import cn.iocoder.mall.admin.dao.ExceptionLogMapper;
import cn.iocoder.mall.admin.dataobject.AccessLogDO;
import cn.iocoder.mall.admin.dataobject.ExceptionLogDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
@Service
@org.apache.dubbo.config.annotation.Service(validation = "true", version = "${dubbo.provider.AdminAccessLogService.version}")
public class SystemLogServiceImpl implements SystemLogService {
/**
* 请求参数最大长度
*/
private static final Integer QUERY_STRING_MAX_LENGTH = 4096;
/**
* 请求地址最大长度
*/
private static final Integer URI_MAX_LENGTH = 4096;
/**
* User-Agent 最大长度
*/
private static final Integer USER_AGENT_MAX_LENGTH = 1024;
@Autowired
private AccessLogMapper accessLogMapper;
@Autowired
private ExceptionLogMapper exceptionLogMapper;
@Override
@SuppressWarnings("Duplicates")
public void addAccessLog(AccessLogAddDTO adminAccessLogAddDTO) {
// 创建 AdminAccessLogDO
AccessLogDO accessLog = AccessLogConvert.INSTANCE.convert(adminAccessLogAddDTO);
accessLog.setCreateTime(new Date());
// 截取最大长度
if (accessLog.getUri().length() > URI_MAX_LENGTH) {
accessLog.setUri(StringUtil.substring(accessLog.getUri(), URI_MAX_LENGTH));
}
if (accessLog.getQueryString().length() > QUERY_STRING_MAX_LENGTH) {
accessLog.setQueryString(StringUtil.substring(accessLog.getQueryString(), QUERY_STRING_MAX_LENGTH));
}
if (accessLog.getUserAgent().length() > USER_AGENT_MAX_LENGTH) {
accessLog.setUserAgent(StringUtil.substring(accessLog.getUserAgent(), USER_AGENT_MAX_LENGTH));
}
// 插入
accessLogMapper.insert(accessLog);
}
@Override
@SuppressWarnings("Duplicates")
public void addExceptionLog(ExceptionLogAddDTO exceptionLogAddDTO) {
// 创建 AdminAccessLogDO
ExceptionLogDO exceptionLog = AccessLogConvert.INSTANCE.convert(exceptionLogAddDTO);
exceptionLog.setCreateTime(new Date());
// 截取最大长度
if (exceptionLog.getUri().length() > URI_MAX_LENGTH) {
exceptionLog.setUri(StringUtil.substring(exceptionLog.getUri(), URI_MAX_LENGTH));
}
if (exceptionLog.getQueryString().length() > QUERY_STRING_MAX_LENGTH) {
exceptionLog.setQueryString(StringUtil.substring(exceptionLog.getQueryString(), QUERY_STRING_MAX_LENGTH));
}
if (exceptionLog.getUserAgent().length() > USER_AGENT_MAX_LENGTH) {
exceptionLog.setUserAgent(StringUtil.substring(exceptionLog.getUserAgent(), USER_AGENT_MAX_LENGTH));
}
// 插入
exceptionLogMapper.insert(exceptionLog);
}
@Override
@SuppressWarnings("Duplicates")
public AccessLogPageBO getAccessLogPage(AccessLogPageDTO accessLogPageDTO) {
AccessLogPageBO accessLogPageBO = new AccessLogPageBO();
PageResult<AccessLogBO> accessLogPageBOPageResult = AccessLogConvert.INSTANCE.convert(
accessLogMapper.selectPage(accessLogPageDTO));
accessLogPageBO.setList(accessLogPageBOPageResult.getList());
accessLogPageBO.setTotal(accessLogPageBOPageResult.getTotal());
return accessLogPageBO;
}
}