diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/LimitNewApi.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/LimitNewApi.java new file mode 100644 index 00000000..e665bbb6 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/LimitNewApi.java @@ -0,0 +1,111 @@ +package com.gitee.sop.adminserver.api.service; + +import com.gitee.easyopen.annotation.Api; +import com.gitee.easyopen.annotation.ApiService; +import com.gitee.easyopen.doc.annotation.ApiDoc; +import com.gitee.easyopen.doc.annotation.ApiDocMethod; +import com.gitee.easyopen.exception.ApiException; +import com.gitee.easyopen.util.CopyUtil; +import com.gitee.fastmybatis.core.PageInfo; +import com.gitee.fastmybatis.core.query.Query; +import com.gitee.fastmybatis.core.query.Sort; +import com.gitee.fastmybatis.core.query.expression.ValueExpression; +import com.gitee.fastmybatis.core.util.MapperUtil; +import com.gitee.fastmybatis.core.util.MyBeanUtil; +import com.gitee.sop.adminserver.api.service.param.LimitNewAddParam; +import com.gitee.sop.adminserver.api.service.param.LimitNewParam; +import com.gitee.sop.adminserver.api.service.param.LimitNewUpdateParam; +import com.gitee.sop.adminserver.api.service.param.RouteSearchParam; +import com.gitee.sop.adminserver.api.service.result.LimitNewVO; +import com.gitee.sop.adminserver.bean.ConfigLimitDto; +import com.gitee.sop.adminserver.bean.GatewayRouteDefinition; +import com.gitee.sop.adminserver.common.LimitEnum; +import com.gitee.sop.adminserver.entity.ConfigLimit; +import com.gitee.sop.adminserver.mapper.ConfigLimitMapper; +import com.gitee.sop.adminserver.service.RouteConfigService; +import com.gitee.sop.adminserver.service.RouteService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.BooleanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 限流 + * + * @author tanghc + */ +@ApiService +@ApiDoc("服务管理") +@Slf4j +public class LimitNewApi { + + @Autowired + RouteService routeService; + + @Autowired + RouteConfigService routeConfigService; + + @Autowired + ConfigLimitMapper configLimitMapper; + + @Api(name = "config.limit.list") + @ApiDocMethod(description = "限流列表(新)", elementClass = LimitNewVO.class) + PageInfo listLimit(LimitNewParam param) throws Exception { + Query query = Query.build(param); + query.orderby("route_id", Sort.ASC) + .orderby("app_key", Sort.ASC) + .orderby("order_index", Sort.ASC); + PageInfo pageInfo = MapperUtil.query(configLimitMapper, query); + return pageInfo; + } + + @Api(name = "config.limit.add") + @ApiDocMethod(description = "新增限流(新)") + @Transactional(rollbackFor = Exception.class) + public void createLimtit(LimitNewAddParam param) { + ConfigLimit configLimit = new ConfigLimit(); + CopyUtil.copyPropertiesIgnoreNull(param, configLimit); + configLimitMapper.save(configLimit); + ConfigLimitDto configLimitDto = buildConfigLimitDto(configLimit); + try { + routeConfigService.sendLimitConfigMsg(configLimitDto); + } catch (Exception e) { + log.error("推送限流消息错误, param:{}", param, e); + throw new ApiException("新增失败,请查看日志"); + } + } + + @Api(name = "config.limit.update") + @ApiDocMethod(description = "修改限流(新)") + @Transactional(rollbackFor = Exception.class) + public void updateLimtit(LimitNewUpdateParam param) { + ConfigLimit configLimit = configLimitMapper.getById(param.getId()); + if (configLimit == null) { + configLimit = new ConfigLimit(); + CopyUtil.copyPropertiesIgnoreNull(param, configLimit); + configLimitMapper.save(configLimit); + } else { + CopyUtil.copyPropertiesIgnoreNull(param, configLimit); + configLimitMapper.update(configLimit); + } + ConfigLimitDto configLimitDto = buildConfigLimitDto(configLimit); + try { + routeConfigService.sendLimitConfigMsg(configLimitDto); + } catch (Exception e) { + log.error("推送限流消息错误, param:{}", param, e); + throw new ApiException("修改失败,请查看日志"); + } + } + + private ConfigLimitDto buildConfigLimitDto(ConfigLimit configLimit) { + ConfigLimitDto configLimitDto = new ConfigLimitDto(); + CopyUtil.copyPropertiesIgnoreNull(configLimit, configLimitDto); + return configLimitDto; + } +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/RouteApi.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/RouteApi.java index bd0b4ef4..d0dab1d1 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/RouteApi.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/RouteApi.java @@ -81,6 +81,21 @@ public class RouteApi { return routeDefinitionList; } + @Api(name = "route.list", version = "1.2") + @ApiDocMethod(description = "路由列表1.2") + List listRoute2(RouteSearchParam param) throws Exception { + List routeDefinitionList = routeService.getRouteDefinitionList(param) + .stream() + .map(gatewayRouteDefinition -> { + RouteVO vo = new RouteVO(); + BeanUtils.copyProperties(gatewayRouteDefinition, vo); + return vo; + }) + .collect(Collectors.toList()); + + return routeDefinitionList; + } + @Api(name = "route.update") @ApiDocMethod(description = "修改路由") void updateRoute(RouteParam param) throws Exception { diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/LimitNewAddParam.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/LimitNewAddParam.java new file mode 100644 index 00000000..9d9b85ba --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/LimitNewAddParam.java @@ -0,0 +1,62 @@ +package com.gitee.sop.adminserver.api.service.param; + +import com.gitee.easyopen.doc.annotation.ApiDocField; +import lombok.Data; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 限流 + * @author tanghc + */ +@Data +public class LimitNewAddParam { + /** 路由id, 数据库字段:route_id */ + @ApiDocField(description = "routeId") + private String routeId; + + /** 数据库字段:app_key */ + @ApiDocField(description = "appKey") + private String appKey; + + /** 限流ip,多个用英文逗号隔开, 数据库字段:limit_ip */ + @ApiDocField(description = "limitIp") + private String limitIp; + + @ApiDocField(description = "serviceId") + @NotBlank(message = "serviceId can not null") + private String serviceId; + + /** 限流策略,1:漏桶策略,2:令牌桶策略, 数据库字段:limit_type */ + @ApiDocField(description = "限流策略,1:漏桶策略,2:令牌桶策略") + @NotNull(message = "limitType不能为空") + private Byte limitType; + + /** 每秒可处理请求数, 数据库字段:exec_count_per_second */ + @ApiDocField(description = "每秒可处理请求数") + private Integer execCountPerSecond; + + /** 返回的错误码, 数据库字段:limit_code */ + @ApiDocField(description = "返回的错误码") + private String limitCode; + + /** 返回的错误信息, 数据库字段:limit_msg */ + @ApiDocField(description = "返回的错误信息") + private String limitMsg; + + /** 令牌桶容量, 数据库字段:token_bucket_count */ + @ApiDocField(description = "令牌桶容量") + private Integer tokenBucketCount; + + /** 1:开启,0关闭, 数据库字段:limit_status */ + @ApiDocField(description = "1:开启,0关闭") + @NotNull(message = "limitStatus不能为空") + private Byte limitStatus; + + @ApiDocField(description = "排序字段") + @NotNull(message = "orderIndex不能为空") + @Min(value = 0, message = "orderIndex必须大于等于0") + private Integer orderIndex; +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/LimitNewParam.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/LimitNewParam.java new file mode 100644 index 00000000..b25636e4 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/LimitNewParam.java @@ -0,0 +1,28 @@ +package com.gitee.sop.adminserver.api.service.param; + +import com.gitee.easyopen.doc.annotation.ApiDocField; +import com.gitee.fastmybatis.core.query.Operator; +import com.gitee.fastmybatis.core.query.annotation.Condition; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author tanghc + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class LimitNewParam extends ServiceSearchParam { + @ApiDocField(description = "路由id") + @Condition(operator = Operator.like) + private String routeId; + + /** 数据库字段:app_key */ + @ApiDocField(description = "appKey") + @Condition(operator = Operator.like) + private String appKey; + + /** 限流ip,多个用英文逗号隔开, 数据库字段:limit_ip */ + @ApiDocField(description = "限流ip,多个用英文逗号隔开") + @Condition(operator = Operator.like) + private String limitIp; +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/LimitNewUpdateParam.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/LimitNewUpdateParam.java new file mode 100644 index 00000000..efdb628d --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/LimitNewUpdateParam.java @@ -0,0 +1,67 @@ +package com.gitee.sop.adminserver.api.service.param; + +import com.gitee.easyopen.doc.annotation.ApiDocField; +import lombok.Data; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 限流 + * @author tanghc + */ +@Data +public class LimitNewUpdateParam { + @ApiDocField(description = "id") + @NotNull(message = "id can not null") + @Min(value = 1, message = "id不正确") + private Long id; + + /** 路由id, 数据库字段:route_id */ + @ApiDocField(description = "routeId") + private String routeId; + + /** 数据库字段:app_key */ + @ApiDocField(description = "appKey") + private String appKey; + + /** 限流ip,多个用英文逗号隔开, 数据库字段:limit_ip */ + @ApiDocField(description = "limitIp") + private String limitIp; + + @ApiDocField(description = "serviceId") + @NotBlank(message = "serviceId can not null") + private String serviceId; + + /** 限流策略,1:漏桶策略,2:令牌桶策略, 数据库字段:limit_type */ + @ApiDocField(description = "限流策略,1:漏桶策略,2:令牌桶策略") + @NotNull(message = "limitType不能为空") + private Byte limitType; + + /** 每秒可处理请求数, 数据库字段:exec_count_per_second */ + @ApiDocField(description = "每秒可处理请求数") + private Integer execCountPerSecond; + + /** 返回的错误码, 数据库字段:limit_code */ + @ApiDocField(description = "返回的错误码") + private String limitCode; + + /** 返回的错误信息, 数据库字段:limit_msg */ + @ApiDocField(description = "返回的错误信息") + private String limitMsg; + + /** 令牌桶容量, 数据库字段:token_bucket_count */ + @ApiDocField(description = "令牌桶容量") + private Integer tokenBucketCount; + + /** 1:开启,0关闭, 数据库字段:limit_status */ + @ApiDocField(description = "1:开启,0关闭") + @NotNull(message = "limitStatus不能为空") + private Byte limitStatus; + + @ApiDocField(description = "排序字段") + @NotNull(message = "orderIndex不能为空") + @Min(value = 0, message = "orderIndex必须大于等于0") + private Integer orderIndex; +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/result/LimitNewVO.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/result/LimitNewVO.java new file mode 100644 index 00000000..1ec2c6b9 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/result/LimitNewVO.java @@ -0,0 +1,82 @@ +package com.gitee.sop.adminserver.api.service.result; + +import com.gitee.easyopen.doc.annotation.ApiDocField; +import lombok.Data; + +/** + * 限流 + * + * @author tanghc + */ +@Data +public class LimitNewVO { + /** 路由id, 数据库字段:route_id */ + @ApiDocField(description = "路由id") + private String routeId; + + /** 数据库字段:app_key */ + @ApiDocField(description = "appKey") + private String appKey; + + /** 限流ip,多个用英文逗号隔开, 数据库字段:limit_ip */ + @ApiDocField(description = "限流ip,多个用英文逗号隔开") + private String limitIp; + + @ApiDocField(description = "限流key") + private String limitKey; + + /** + * 接口名 + */ + @ApiDocField(description = "接口名") + private String name; + + /** + * 版本号 + */ + @ApiDocField(description = "版本号") + private String version; + + @ApiDocField(description = "serviceId") + private String serviceId; + + /** + * 限流策略,1:漏桶策略,2:令牌桶策略, 数据库字段:limit_type + */ + @ApiDocField(description = "限流策略,1:漏桶策略,2:令牌桶策略") + private Byte limitType; + + /** + * 每秒可处理请求数, 数据库字段:exec_count_per_second + */ + @ApiDocField(description = "每秒可处理请求数") + private Integer execCountPerSecond; + + /** + * 返回的错误码, 数据库字段:limit_code + */ + @ApiDocField(description = "返回的错误码") + private String limitCode; + + /** + * 返回的错误信息, 数据库字段:limit_msg + */ + @ApiDocField(description = "返回的错误信息") + private String limitMsg; + + /** + * 令牌桶容量, 数据库字段:token_bucket_count + */ + @ApiDocField(description = "令牌桶容量") + private Integer tokenBucketCount; + + /** + * 1:开启,0关闭, 数据库字段:limit_status + */ + @ApiDocField(description = "1:开启,0关闭") + private Byte limitStatus; + + /** 顺序,值小的优先执行, 数据库字段:order_index */ + @ApiDocField(description = "排序字段") + private Integer orderIndex; +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/ConfigLimitDto.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/ConfigLimitDto.java new file mode 100644 index 00000000..ef6af953 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/ConfigLimitDto.java @@ -0,0 +1,50 @@ +package com.gitee.sop.adminserver.bean; + +import lombok.Data; + +import java.util.Date; + +@Data +public class ConfigLimitDto { + /** 数据库字段:id */ + private Long id; + + /** 路由id, 数据库字段:route_id */ + private String routeId; + + /** 数据库字段:app_key */ + private String appKey; + + /** 限流ip,多个用英文逗号隔开, 数据库字段:limit_ip */ + private String limitIp; + + /** 服务id, 数据库字段:service_id */ + private String serviceId; + + /** 限流策略,1:漏桶策略,2:令牌桶策略, 数据库字段:limit_type */ + private Byte limitType; + + /** 每秒可处理请求数, 数据库字段:exec_count_per_second */ + private Integer execCountPerSecond; + + /** 返回的错误码, 数据库字段:limit_code */ + private String limitCode; + + /** 返回的错误信息, 数据库字段:limit_msg */ + private String limitMsg; + + /** 令牌桶容量, 数据库字段:token_bucket_count */ + private Integer tokenBucketCount; + + /** 限流开启状态,1:开启,0关闭, 数据库字段:limit_status */ + private Byte limitStatus; + + /** 顺序,值小的优先执行, 数据库字段:order_index */ + private Integer orderIndex; + + /** 数据库字段:gmt_create */ + private Date gmtCreate; + + /** 数据库字段:gmt_modified */ + private Date gmtModified; +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/ZookeeperContext.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/ZookeeperContext.java index a2122c75..8f8d8487 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/ZookeeperContext.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/ZookeeperContext.java @@ -71,6 +71,10 @@ public class ZookeeperContext { return SOP_MSG_CHANNEL_PATH + "/route-conf"; } + public static String getLimitConfigChannelPath() { + return SOP_MSG_CHANNEL_PATH + "/limit-conf"; + } + public static CuratorFramework getClient() { return client; } diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/entity/ConfigLimit.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/entity/ConfigLimit.java new file mode 100644 index 00000000..a0d8c7ea --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/entity/ConfigLimit.java @@ -0,0 +1,66 @@ +package com.gitee.sop.adminserver.entity; + +import lombok.Data; + +import javax.persistence.Column; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import java.util.Date; + + +/** + * 表名:config_limit + * 备注:限流配置 + * + * @author tanghc + */ +@Table(name = "config_limit") +@Data +public class ConfigLimit { + @Id + @Column(name = "id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + /** 数据库字段:id */ + private Long id; + + /** 路由id, 数据库字段:route_id */ + private String routeId; + + /** 数据库字段:app_key */ + private String appKey; + + /** 限流ip,多个用英文逗号隔开, 数据库字段:limit_ip */ + private String limitIp; + + /** 服务id, 数据库字段:service_id */ + private String serviceId; + + /** 限流策略,1:漏桶策略,2:令牌桶策略, 数据库字段:limit_type */ + private Byte limitType; + + /** 每秒可处理请求数, 数据库字段:exec_count_per_second */ + private Integer execCountPerSecond; + + /** 返回的错误码, 数据库字段:limit_code */ + private String limitCode; + + /** 返回的错误信息, 数据库字段:limit_msg */ + private String limitMsg; + + /** 令牌桶容量, 数据库字段:token_bucket_count */ + private Integer tokenBucketCount; + + /** 限流开启状态,1:开启,0关闭, 数据库字段:limit_status */ + private Byte limitStatus; + + /** 顺序,值小的优先执行, 数据库字段:order_index */ + private Integer orderIndex; + + /** 数据库字段:gmt_create */ + private Date gmtCreate; + + /** 数据库字段:gmt_modified */ + private Date gmtModified; +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/mapper/ConfigLimitMapper.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/mapper/ConfigLimitMapper.java new file mode 100644 index 00000000..fc3a8296 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/mapper/ConfigLimitMapper.java @@ -0,0 +1,12 @@ +package com.gitee.sop.adminserver.mapper; + +import com.gitee.fastmybatis.core.mapper.CrudMapper; + +import com.gitee.sop.adminserver.entity.ConfigLimit; + + +/** + * @author tanghc + */ +public interface ConfigLimitMapper extends CrudMapper { +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/RouteConfigService.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/RouteConfigService.java index 8719938d..ac02f8db 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/RouteConfigService.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/RouteConfigService.java @@ -2,6 +2,7 @@ package com.gitee.sop.adminserver.service; import com.alibaba.fastjson.JSON; import com.gitee.sop.adminserver.bean.ChannelMsg; +import com.gitee.sop.adminserver.bean.ConfigLimitDto; import com.gitee.sop.adminserver.bean.RouteConfigDto; import com.gitee.sop.adminserver.bean.ZookeeperContext; import lombok.extern.slf4j.Slf4j; @@ -27,4 +28,18 @@ public class RouteConfigService { log.info("消息推送--路由配置(update), path:{}, data:{}", path, jsonData); ZookeeperContext.createOrUpdateData(path, jsonData); } + + /** + * 推送路由配置 + * @param routeConfigDto + * @throws Exception + */ + public void sendLimitConfigMsg(ConfigLimitDto routeConfigDto) throws Exception { + String configData = JSON.toJSONString(routeConfigDto); + ChannelMsg channelMsg = new ChannelMsg("update", configData); + String jsonData = JSON.toJSONString(channelMsg); + String path = ZookeeperContext.getLimitConfigChannelPath(); + log.info("消息推送--限流配置(update), path:{}, data:{}", path, jsonData); + ZookeeperContext.createOrUpdateData(path, jsonData); + } } diff --git a/sop-admin/sop-admin-vue/src/router/index.js b/sop-admin/sop-admin-vue/src/router/index.js index 3085492e..c7556d55 100644 --- a/sop-admin/sop-admin-vue/src/router/index.js +++ b/sop-admin/sop-admin-vue/src/router/index.js @@ -76,7 +76,7 @@ export const constantRoutes = [ { path: 'limit', name: 'Limit', - component: () => import('@/views/service/limit/index'), + component: () => import('@/views/service/limit/index2'), meta: { title: '限流管理' } } ] diff --git a/sop-admin/sop-admin-vue/src/views/isv/index.vue b/sop-admin/sop-admin-vue/src/views/isv/index.vue index 9d90f2b4..2ee651ce 100644 --- a/sop-admin/sop-admin-vue/src/views/isv/index.vue +++ b/sop-admin/sop-admin-vue/src/views/isv/index.vue @@ -1,20 +1,19 @@