适配eureka

This commit is contained in:
tanghc
2019-09-26 20:01:35 +08:00
parent 51ca5ba319
commit be0adc0a8e
37 changed files with 1120 additions and 219 deletions

View File

@@ -86,7 +86,7 @@ public class IPBlacklistApi {
}
}
public void sendIpBlacklistMsg(ConfigIpBlacklist configIpBlacklist, ChannelOperation channelOperation) throws Exception {
public void sendIpBlacklistMsg(ConfigIpBlacklist configIpBlacklist, ChannelOperation channelOperation) {
ChannelMsg channelMsg = new ChannelMsg(channelOperation, configIpBlacklist);
configPushService.publishConfig(NacosConfigs.DATA_ID_IP_BLACKLIST, NacosConfigs.GROUP_CHANNEL, channelMsg);
}

View File

@@ -18,7 +18,6 @@ import com.gitee.sop.adminserver.common.BizException;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
@@ -33,9 +32,6 @@ import org.springframework.transaction.annotation.Transactional;
@Slf4j
public class LimitNewApi {
@Autowired
RouteService routeService;
@Autowired
RouteConfigService routeConfigService;
@@ -44,7 +40,7 @@ public class LimitNewApi {
@Api(name = "config.limit.list")
@ApiDocMethod(description = "限流列表(新)", elementClass = LimitNewVO.class)
PageInfo<ConfigLimit> listLimit(LimitNewParam param) throws Exception {
PageInfo<ConfigLimit> listLimit(LimitNewParam param) {
Query query = Query.build(param);
query.orderby("route_id", Sort.ASC)
.orderby("app_key", Sort.ASC)

View File

@@ -4,6 +4,10 @@ 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.fastmybatis.core.query.Query;
import com.gitee.fastmybatis.core.query.Sort;
import com.gitee.fastmybatis.core.support.PageEasyui;
import com.gitee.fastmybatis.core.util.MapperUtil;
import com.gitee.sop.adminserver.api.isv.result.RoleVO;
import com.gitee.sop.adminserver.api.service.param.RouteAddParam;
import com.gitee.sop.adminserver.api.service.param.RouteDeleteParam;
@@ -14,19 +18,24 @@ import com.gitee.sop.adminserver.api.service.result.RouteVO;
import com.gitee.sop.adminserver.bean.RouteConfigDto;
import com.gitee.sop.adminserver.common.BizException;
import com.gitee.sop.adminserver.entity.ConfigRouteBase;
import com.gitee.sop.adminserver.entity.ConfigServiceRoute;
import com.gitee.sop.adminserver.entity.PermRole;
import com.gitee.sop.adminserver.entity.PermRolePermission;
import com.gitee.sop.adminserver.entity.RouteRoleDTO;
import com.gitee.sop.adminserver.mapper.ConfigRouteBaseMapper;
import com.gitee.sop.adminserver.mapper.ConfigServiceRouteMapper;
import com.gitee.sop.adminserver.mapper.PermRoleMapper;
import com.gitee.sop.adminserver.mapper.PermRolePermissionMapper;
import com.gitee.sop.adminserver.service.RouteConfigService;
import com.gitee.sop.adminserver.service.RoutePermissionService;
import com.gitee.sop.adminserver.service.RouteService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
@@ -46,48 +55,56 @@ public class RouteApi {
@Autowired
ConfigRouteBaseMapper configRouteBaseMapper;
@Autowired
private ConfigServiceRouteMapper configServiceRouteMapper;
@Autowired
RoutePermissionService routePermissionService;
@Autowired
RouteConfigService routeConfigService;
@Autowired
RouteService routeService;
@Api(name = "route.list")
@ApiDocMethod(description = "路由列表")
List<RouteVO> listRoute(RouteSearchParam param) throws Exception {
List<RouteVO> routeDefinitionList = routeService.getRouteDefinitionList(param)
.stream()
.map(gatewayRouteDefinition -> {
RouteVO vo = new RouteVO();
BeanUtils.copyProperties(gatewayRouteDefinition, vo);
vo.setRoles(this.getRouteRole(gatewayRouteDefinition.getId()));
ConfigRouteBase configRouteBase = configRouteBaseMapper.getByColumn("route_id", gatewayRouteDefinition.getId());
if (configRouteBase != null) {
vo.setStatus(configRouteBase.getStatus());
}
return vo;
})
@ApiDocMethod(description = "路由列表,分页")
@Api(name = "route.page")
PageEasyui<RouteVO> page(RouteSearchParam form) {
Query query = Query.build(form);
query.orderby("id", Sort.ASC);
PageEasyui<RouteVO> datagrid = MapperUtil.queryForEasyuiDatagrid(configServiceRouteMapper, query, RouteVO.class);
List<String> routeIdList = datagrid.getRows()
.parallelStream()
.map(RouteVO::getId)
.collect(Collectors.toList());
return routeDefinitionList;
Map<String, Byte> routeIdStatusMap = configRouteBaseMapper
.list(new Query().in("route_id", routeIdList))
.stream()
.collect(Collectors.toMap(ConfigRouteBase::getRouteId, ConfigRouteBase::getStatus));
Map<String, List<RouteRoleDTO>> routeIdRoleMap = permRolePermissionMapper.listRouteRole(routeIdList)
.parallelStream()
.collect(Collectors.groupingBy(RouteRoleDTO::getRouteId));
datagrid.getRows().forEach(vo -> {
String routeId = vo.getId();
List<RouteRoleDTO> routeRoleDTOS = routeIdRoleMap.getOrDefault(routeId, Collections.emptyList());
vo.setRoles(routeRoleDTOS);
Byte status = routeIdStatusMap.getOrDefault(routeId, vo.getStatus());
vo.setStatus(status);
});
return datagrid;
}
@Api(name = "route.list", version = "1.2")
@ApiDocMethod(description = "路由列表1.2")
List<RouteVO> listRoute2(RouteSearchParam param) throws Exception {
List<RouteVO> routeDefinitionList = routeService.getRouteDefinitionList(param)
.stream()
.map(gatewayRouteDefinition -> {
RouteVO vo = new RouteVO();
BeanUtils.copyProperties(gatewayRouteDefinition, vo);
return vo;
})
.collect(Collectors.toList());
return routeDefinitionList;
List<ConfigServiceRoute> listRoute2(RouteSearchParam param) {
String serviceId = param.getServiceId();
if (StringUtils.isBlank(serviceId)) {
return Collections.emptyList();
}
Query query = Query.build(param);
return configServiceRouteMapper.list(query);
}
@Api(name = "route.add")
@@ -149,6 +166,34 @@ public class RouteApi {
/**
* 获取路由对应的角色
*
* @param routeIdList routeIdList
* @return
*/
private List<RoleVO> getRouteRole(List<String> routeIdList) {
// key:routeId, value: roleCode
Map<String, List<String>> routeIdRoleCodeMap = permRolePermissionMapper.list(new Query().in("route_id", routeIdList))
.stream()
.collect(Collectors.groupingBy(PermRolePermission::getRouteId,
Collectors.mapping(PermRolePermission::getRoleCode, Collectors.toList())));
return permRolePermissionMapper.list(new Query().in("route_id", routeIdList))
.stream()
.map(permRolePermission -> {
RoleVO vo = new RoleVO();
String roleCode = permRolePermission.getRoleCode();
PermRole permRole = permRoleMapper.getByColumn("role_code", roleCode);
BeanUtils.copyProperties(permRole, vo);
return vo;
})
.collect(Collectors.toList());
}
/**
* 获取路由对应的角色
*
* @param id routeId
* @return
*/

View File

@@ -1,6 +1,9 @@
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 com.gitee.fastmybatis.core.query.param.PageParam;
import lombok.Getter;
import lombok.Setter;
@@ -11,11 +14,16 @@ import javax.validation.constraints.NotBlank;
*/
@Getter
@Setter
public class RouteSearchParam {
public class RouteSearchParam extends PageParam {
@ApiDocField(description = "服务名serviceId")
@NotBlank(message = "serviceId不能为空")
private String serviceId;
@ApiDocField(description = "路由id")
@Condition(column = "id", operator = Operator.like)
private String id;
@ApiDocField(description = "是否授权接口1")
@Condition(ignoreValue = "0")
private Integer permission;
}

View File

@@ -1,7 +1,6 @@
package com.gitee.sop.adminserver.api.service.result;
import com.gitee.sop.adminserver.api.isv.result.RoleVO;
import com.gitee.sop.adminserver.bean.RouteDefinition;
import com.gitee.sop.adminserver.entity.RouteRoleDTO;
import lombok.Getter;
import lombok.Setter;
@@ -12,6 +11,46 @@ import java.util.List;
*/
@Getter
@Setter
public class RouteVO extends RouteDefinition {
private List<RoleVO> roles;
public class RouteVO {
/** 数据库字段id */
private String id;
/** 数据库字段service_id */
private String serviceId;
/** 接口名, 数据库字段name */
private String name;
/** 版本号, 数据库字段version */
private String version;
/** 路由断言SpringCloudGateway专用, 数据库字段predicates */
private String predicates;
/** 路由过滤器SpringCloudGateway专用, 数据库字段filters */
private String filters;
/** 路由规则转发的目标uri, 数据库字段uri */
private String uri;
/** uri后面跟的path, 数据库字段path */
private String path;
/** 路由执行的顺序, 数据库字段order */
private Integer order;
/** 是否忽略验证,业务参数验证除外, 数据库字段ignore_validate */
private Byte ignoreValidate;
/** 状态0待审核1启用2禁用, 数据库字段status */
private Byte status;
/** 是否合并结果, 数据库字段merge_result */
private Byte mergeResult;
/** 是否需要授权才能访问, 数据库字段permission */
private Byte permission;
private List<RouteRoleDTO> roles;
}

View File

@@ -0,0 +1,22 @@
package com.gitee.sop.adminserver.bean;
import lombok.Data;
/**
* @author tanghc
*/
@Data
public class GatewayPushDTO {
private String dataId;
private String groupId;
private ChannelMsg channelMsg;
public GatewayPushDTO() {
}
public GatewayPushDTO(String dataId, String groupId, ChannelMsg channelMsg) {
this.dataId = dataId;
this.groupId = groupId;
this.channelMsg = channelMsg;
}
}

View File

@@ -0,0 +1,69 @@
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_service_route
* 备注:路由配置
*
* @author tanghc
*/
@Table(name = "config_service_route")
@Data
public class ConfigServiceRoute {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.AUTO)
/** 数据库字段id */
private String id;
/** 数据库字段service_id */
private String serviceId;
/** 接口名, 数据库字段name */
private String name;
/** 版本号, 数据库字段version */
private String version;
/** 路由断言SpringCloudGateway专用, 数据库字段predicates */
private String predicates;
/** 路由过滤器SpringCloudGateway专用, 数据库字段filters */
private String filters;
/** 路由规则转发的目标uri, 数据库字段uri */
private String uri;
/** uri后面跟的path, 数据库字段path */
private String path;
/** 路由执行的顺序, 数据库字段order */
private Integer order;
/** 是否忽略验证,业务参数验证除外, 数据库字段ignore_validate */
private Byte ignoreValidate;
/** 状态0待审核1启用2禁用, 数据库字段status */
private Byte status;
/** 是否合并结果, 数据库字段merge_result */
private Byte mergeResult;
/** 是否需要授权才能访问, 数据库字段permission */
private Byte permission;
/** 数据库字段gmt_create */
private Date gmtCreate;
/** 数据库字段gmt_modified */
private Date gmtModified;
}

View File

@@ -0,0 +1,18 @@
package com.gitee.sop.adminserver.entity;
import lombok.Data;
/**
* @author tanghc
*/
@Data
public class RouteRoleDTO {
/** routeId, 数据库字段route_id */
private String routeId;
/** 角色代码, 数据库字段role_code */
private String roleCode;
/** 角色描述, 数据库字段description */
private String description;
}

View File

@@ -0,0 +1,11 @@
package com.gitee.sop.adminserver.mapper;
import com.gitee.fastmybatis.core.mapper.CrudMapper;
import com.gitee.sop.adminserver.entity.ConfigServiceRoute;
/**
* @author tanghc
*/
public interface ConfigServiceRouteMapper extends CrudMapper<ConfigServiceRoute, Long> {
}

View File

@@ -3,10 +3,15 @@ package com.gitee.sop.adminserver.mapper;
import com.gitee.fastmybatis.core.mapper.CrudMapper;
import com.gitee.sop.adminserver.entity.PermRolePermission;
import com.gitee.sop.adminserver.entity.RouteRoleDTO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author tanghc
*/
public interface PermRolePermissionMapper extends CrudMapper<PermRolePermission, Long> {
List<RouteRoleDTO> listRouteRole(@Param("routeIdList") List<String> routeIdList);
}

View File

@@ -5,10 +5,20 @@ import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;
import com.gitee.sop.adminserver.bean.ChannelMsg;
import com.gitee.sop.adminserver.bean.GatewayPushDTO;
import com.gitee.sop.adminserver.bean.HttpTool;
import com.gitee.sop.adminserver.common.BizException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* @author tanghc
*/
@@ -16,17 +26,53 @@ import org.springframework.stereotype.Service;
@Service
public class ConfigPushService {
private static final String GATEWAY_PUSH_URL = "http://%s/configChannelMsg";
private static HttpTool httpTool = new HttpTool();
@NacosInjected
private ConfigService configService;
@Value("${gateway.host:}")
private String gatewayHost;
@Value("${zuul.secret}")
private String secret;
public void publishConfig(String dataId, String groupId, ChannelMsg channelMsg) {
try {
log.info("nacos配置, dataId={}, groupId={}, operation={}", dataId, groupId, channelMsg.getOperation());
configService.publishConfig(dataId, groupId, JSON.toJSONString(channelMsg));
} catch (NacosException e) {
log.error("nacos配置失败, dataId={}, groupId={}, operation={}", dataId, groupId, channelMsg.getOperation(), e);
throw new BizException("nacos配置失败");
if (StringUtils.isNotBlank(gatewayHost)) {
String[] hosts = gatewayHost.split(",");
for (String host : hosts) {
GatewayPushDTO gatewayPushDTO = new GatewayPushDTO(dataId, groupId, channelMsg);
String url = String.format(GATEWAY_PUSH_URL, host);
try {
String requestBody = JSON.toJSONString(gatewayPushDTO);
Map<String, String> header = new HashMap<>(8);
header.put("sign", buildRequestBodySign(requestBody, secret));
String resp = httpTool.requestJson(url, requestBody, header);
if (!"ok".equals(resp)) {
throw new IOException(resp);
}
} catch (IOException e) {
log.error("nacos配置失败, dataId={}, groupId={}, operation={} url={}", dataId, groupId, channelMsg.getOperation(), url, e);
throw new BizException("推送配置失败");
}
}
} else {
try {
log.info("nacos配置, dataId={}, groupId={}, operation={}", dataId, groupId, channelMsg.getOperation());
configService.publishConfig(dataId, groupId, JSON.toJSONString(channelMsg));
} catch (NacosException e) {
log.error("nacos配置失败, dataId={}, groupId={}, operation={}", dataId, groupId, channelMsg.getOperation(), e);
throw new BizException("nacos配置失败");
}
}
}
public static String buildRequestBodySign(String requestBody, String secret) {
String signContent = secret + requestBody + secret;
return DigestUtils.md5Hex(signContent);
}
}

View File

@@ -1,52 +0,0 @@
package com.gitee.sop.adminserver.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService;
import com.gitee.sop.adminserver.api.service.param.RouteSearchParam;
import com.gitee.sop.adminserver.bean.RouteDefinition;
import com.gitee.sop.adminserver.bean.NacosConfigs;
import com.gitee.sop.adminserver.bean.ServiceRouteInfo;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
import static java.util.stream.Collectors.toList;
/**
* @author tanghc
*/
@Service
public class RouteService {
@NacosInjected
private ConfigService configService;
public List<RouteDefinition> getRouteDefinitionList(RouteSearchParam param) throws Exception {
String serviceId = param.getServiceId();
if (StringUtils.isBlank(serviceId)) {
return Collections.emptyList();
}
String configData = configService.getConfig(NacosConfigs.getRouteDataId(serviceId), NacosConfigs.GROUP_ROUTE, 3000);
if (StringUtils.isBlank(configData)) {
return Collections.emptyList();
}
ServiceRouteInfo serviceRouteInfo = JSON.parseObject(configData, ServiceRouteInfo.class);
return serviceRouteInfo.getRouteDefinitionList()
.stream()
.filter(gatewayRouteDefinition -> {
boolean isRoute = gatewayRouteDefinition.getOrder() != Integer.MIN_VALUE;
String id = param.getId();
if (StringUtils.isBlank(id)) {
return isRoute;
} else {
return isRoute && gatewayRouteDefinition.getId().contains(id);
}
})
.collect(toList());
}
}

View File

@@ -9,6 +9,10 @@ mysql.password=root
# nacos注册中心地址
nacos.url=127.0.0.1:8848
# 网关地址,多个用逗号隔开
# 此配置仅在使用eureka时有用不用的话注释掉
gateway.host=127.0.0.1:8081
# ------- 需要改的配置end -------
# token过期时间分钟
@@ -27,6 +31,7 @@ spring.datasource.username=${mysql.username}
spring.datasource.password=${mysql.password}
# 固定不用改
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
easyopen.show-doc=false
easyopen.ignore-validate=true

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 注意文件名必须跟Dao类名字一致因为是根据文件名做关联。 -->
<mapper namespace="com.gitee.sop.adminserver.mapper.PermRolePermissionMapper">
<select id="listRouteRole" resultType="com.gitee.sop.adminserver.entity.RouteRoleDTO">
SELECT
t.route_id as routeId,
t.role_code as roleCode,
t2.description
FROM perm_role_permission t
INNER JOIN perm_role t2 ON t.role_code=t2.role_code
WHERE t.route_id in
<foreach collection="routeIdList" item="routeId" open="(" separator="," close=")">
#{routeId}
</foreach>
</select>
</mapper>