mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-11 21:57:56 +08:00
1.1.0
This commit is contained in:
@@ -1,8 +1,14 @@
|
||||
package com.gitee.sop.gateway.config;
|
||||
|
||||
import com.gitee.sop.gateway.entity.IsvInfo;
|
||||
import com.gitee.sop.gateway.manager.ManagerInitializer;
|
||||
import com.gitee.sop.gatewaycommon.bean.ApiConfig;
|
||||
import com.gitee.sop.gatewaycommon.bean.ApiContext;
|
||||
import com.gitee.sop.gatewaycommon.gateway.configuration.AlipayGatewayConfiguration;
|
||||
import com.gitee.sop.gatewaycommon.manager.IsvRoutePermissionManager;
|
||||
import com.gitee.sop.gatewaycommon.secret.IsvManager;
|
||||
import com.gitee.sop.gatewaycommon.zuul.configuration.AlipayZuulConfiguration;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -30,6 +36,14 @@ public class GatewayConfig extends AlipayGatewayConfiguration {
|
||||
appSecretStore.put("2019032617262200001", "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlyb9aUBaljQP/vjmBFe1mF8HsWSvyfC2NTlpT/V9E+sBxTr8TSkbzJCeeeOEm4LCaVXL0Qz63MZoT24v7AIXTuMdj4jyiM/WJ4tjrWAgnmohNOegfntTto16C3l234vXz4ryWZMR/7W+MXy5B92wPGQEJ0LKFwNEoLspDEWZ7RdE53VH7w6y6sIZUfK+YkXWSwehfKPKlx+lDw3zRJ3/yvMF+U+BAdW/MfECe1GuBnCFKnlMRh3UKczWyXWkL6ItOpYHHJi/jx85op5BWDje2pY9QowzfN94+0DB3T7UvZeweu3zlP6diwAJDzLaFQX8ULfWhY+wfKxIRgs9NoiSAQIDAQAB");
|
||||
ApiContext.getApiConfig().addAppSecret(appSecretStore);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
ManagerInitializer managerInitializer;
|
||||
|
||||
@Override
|
||||
protected void doAfter() {
|
||||
managerInitializer.init();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,9 +1,15 @@
|
||||
package com.gitee.sop.gateway.config;
|
||||
|
||||
import com.gitee.sop.gateway.entity.IsvInfo;
|
||||
import com.gitee.sop.gateway.manager.ManagerInitializer;
|
||||
import com.gitee.sop.gatewaycommon.bean.ApiConfig;
|
||||
import com.gitee.sop.gatewaycommon.bean.ApiContext;
|
||||
import com.gitee.sop.gatewaycommon.easyopen.EasyopenZuulConfiguration;
|
||||
import com.gitee.sop.gatewaycommon.manager.IsvRoutePermissionManager;
|
||||
import com.gitee.sop.gatewaycommon.secret.IsvManager;
|
||||
import com.gitee.sop.gatewaycommon.zuul.configuration.AlipayZuulConfiguration;
|
||||
import com.gitee.sop.gatewaycommon.zuul.configuration.TaobaoZuulConfiguration;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -30,6 +36,14 @@ public class ZuulConfig extends AlipayZuulConfiguration {
|
||||
appSecretStore.put("2019032617262200001", "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlyb9aUBaljQP/vjmBFe1mF8HsWSvyfC2NTlpT/V9E+sBxTr8TSkbzJCeeeOEm4LCaVXL0Qz63MZoT24v7AIXTuMdj4jyiM/WJ4tjrWAgnmohNOegfntTto16C3l234vXz4ryWZMR/7W+MXy5B92wPGQEJ0LKFwNEoLspDEWZ7RdE53VH7w6y6sIZUfK+YkXWSwehfKPKlx+lDw3zRJ3/yvMF+U+BAdW/MfECe1GuBnCFKnlMRh3UKczWyXWkL6ItOpYHHJi/jx85op5BWDje2pY9QowzfN94+0DB3T7UvZeweu3zlP6diwAJDzLaFQX8ULfWhY+wfKxIRgs9NoiSAQIDAQAB");
|
||||
ApiContext.getApiConfig().addAppSecret(appSecretStore);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
ManagerInitializer managerInitializer;
|
||||
|
||||
@Override
|
||||
protected void doAfter() {
|
||||
managerInitializer.init();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -0,0 +1,48 @@
|
||||
package com.gitee.sop.gateway.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;
|
||||
|
||||
|
||||
/**
|
||||
* 表名:isv_info
|
||||
* 备注:isv信息表
|
||||
*
|
||||
* @author tanghc
|
||||
*/
|
||||
@Table(name = "isv_info")
|
||||
@Data
|
||||
public class IsvInfo {
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
/** 数据库字段:id */
|
||||
private Long id;
|
||||
|
||||
/** appKey, 数据库字段:app_key */
|
||||
private String appKey;
|
||||
|
||||
/** secret, 数据库字段:secret */
|
||||
private String secret;
|
||||
|
||||
/** 公钥, 数据库字段:pub_key */
|
||||
private String pubKey;
|
||||
|
||||
/** 私钥, 数据库字段:pri_key */
|
||||
private String priKey;
|
||||
|
||||
/** 0启用,1禁用, 数据库字段:status */
|
||||
private Byte status;
|
||||
|
||||
/** 数据库字段:gmt_create */
|
||||
private Date gmtCreate;
|
||||
|
||||
/** 数据库字段:gmt_modified */
|
||||
private Date gmtModified;
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
package com.gitee.sop.gateway.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;
|
||||
|
||||
|
||||
/**
|
||||
* 表名:perm_isv_role
|
||||
* 备注:isv角色
|
||||
*
|
||||
* @author tanghc
|
||||
*/
|
||||
@Table(name = "perm_isv_role")
|
||||
@Data
|
||||
public class PermIsvRole {
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
/** 数据库字段:id */
|
||||
private Long id;
|
||||
|
||||
/** isv_info表id, 数据库字段:isv_id */
|
||||
private Long isvId;
|
||||
|
||||
/** 角色code, 数据库字段:role_code */
|
||||
private String roleCode;
|
||||
|
||||
/** 数据库字段:gmt_create */
|
||||
private Date gmtCreate;
|
||||
|
||||
/** 数据库字段:gmt_modified */
|
||||
private Date gmtModified;
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
package com.gitee.sop.gateway.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;
|
||||
|
||||
|
||||
/**
|
||||
* 表名:perm_role_permission
|
||||
* 备注:角色权限表
|
||||
*
|
||||
* @author tanghc
|
||||
*/
|
||||
@Table(name = "perm_role_permission")
|
||||
@Data
|
||||
public class PermRolePermission {
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
/** 数据库字段:id */
|
||||
private Long id;
|
||||
|
||||
/** 角色表code, 数据库字段:role_code */
|
||||
private String roleCode;
|
||||
|
||||
/** api_id, 数据库字段:route_id */
|
||||
private String routeId;
|
||||
|
||||
/** 数据库字段:gmt_create */
|
||||
private Date gmtCreate;
|
||||
|
||||
/** 数据库字段:gmt_modified */
|
||||
private Date gmtModified;
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
package com.gitee.sop.gateway.manager;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.gitee.fastmybatis.core.query.Query;
|
||||
import com.gitee.sop.gateway.entity.IsvInfo;
|
||||
import com.gitee.sop.gateway.mapper.IsvInfoMapper;
|
||||
import com.gitee.sop.gatewaycommon.bean.ChannelMsg;
|
||||
import com.gitee.sop.gatewaycommon.bean.IsvDefinition;
|
||||
import com.gitee.sop.gatewaycommon.manager.ZookeeperContext;
|
||||
import com.gitee.sop.gatewaycommon.secret.CacheIsvManager;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class DbIsvManager extends CacheIsvManager {
|
||||
|
||||
@Autowired
|
||||
IsvInfoMapper isvInfoMapper;
|
||||
|
||||
@Autowired
|
||||
Environment environment;
|
||||
|
||||
@Override
|
||||
public void load(Function<Object, String> secretGetter) {
|
||||
log.info("从数据库读取ISV信息,保存到本地");
|
||||
List<IsvInfo> isvInfoList = isvInfoMapper.list(new Query());
|
||||
isvInfoList.stream()
|
||||
.forEach(isvInfo -> {
|
||||
IsvDefinition isvDefinition = new IsvDefinition();
|
||||
BeanUtils.copyProperties(isvInfo, isvDefinition);
|
||||
String secret = secretGetter.apply(isvInfo);
|
||||
isvDefinition.setSecret(secret);
|
||||
this.getIsvCache().put(isvDefinition.getAppKey(), isvDefinition);
|
||||
});
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
protected void after() throws Exception {
|
||||
ZookeeperContext.setEnvironment(environment);
|
||||
String isvChannelPath = ZookeeperContext.getIsvInfoChannelPath();
|
||||
ZookeeperContext.listenPath(isvChannelPath, nodeCache -> {
|
||||
String nodeData = new String(nodeCache.getCurrentData().getData());
|
||||
ChannelMsg channelMsg = JSON.parseObject(nodeData, ChannelMsg.class);
|
||||
final IsvDefinition isvDefinition = JSON.parseObject(channelMsg.getData(), IsvDefinition.class);
|
||||
switch (channelMsg.getOperation()) {
|
||||
case "update":
|
||||
log.info("更新ISV信息,isvDefinition:{}", isvDefinition);
|
||||
update(isvDefinition);
|
||||
break;
|
||||
case "remove":
|
||||
log.info("删除ISV,isvDefinition:{}", isvDefinition);
|
||||
remove(isvDefinition.getAppKey());
|
||||
break;
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,146 @@
|
||||
package com.gitee.sop.gateway.manager;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.gitee.fastmybatis.core.query.Query;
|
||||
import com.gitee.sop.gateway.entity.IsvInfo;
|
||||
import com.gitee.sop.gateway.entity.PermIsvRole;
|
||||
import com.gitee.sop.gateway.entity.PermRolePermission;
|
||||
import com.gitee.sop.gateway.mapper.IsvInfoMapper;
|
||||
import com.gitee.sop.gateway.mapper.PermIsvRoleMapper;
|
||||
import com.gitee.sop.gateway.mapper.PermRolePermissionMapper;
|
||||
import com.gitee.sop.gatewaycommon.bean.ChannelMsg;
|
||||
import com.gitee.sop.gatewaycommon.bean.IsvRoutePermission;
|
||||
import com.gitee.sop.gatewaycommon.manager.DefaultIsvRoutePermissionManager;
|
||||
import com.gitee.sop.gatewaycommon.manager.ZookeeperContext;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.stream.Collectors.mapping;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
/**
|
||||
* 从数据库中读取路由权限信息
|
||||
*
|
||||
* @author tanghc
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class DbIsvRoutePermissionManager extends DefaultIsvRoutePermissionManager {
|
||||
|
||||
@Autowired
|
||||
Environment environment;
|
||||
|
||||
@Autowired
|
||||
PermIsvRoleMapper permIsvRoleMapper;
|
||||
|
||||
@Autowired
|
||||
PermRolePermissionMapper permRolePermissionMapper;
|
||||
|
||||
@Autowired
|
||||
IsvInfoMapper isvInfoMapper;
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
// key: appKey, value: roleCodeList
|
||||
Map<String, List<String>> appKeyRoleCodeMap = this.getIsvRoleCode();
|
||||
|
||||
for (Map.Entry<String, List<String>> entry : appKeyRoleCodeMap.entrySet()) {
|
||||
this.loadIsvRoutePermission(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public void loadIsvRoutePermission(String appKey, List<String> roleCodeList) {
|
||||
Collections.sort(roleCodeList);
|
||||
List<String> routeIdList = this.getRouteIdList(roleCodeList);
|
||||
String roleCodeListMd5 = DigestUtils.md5Hex(JSON.toJSONString(routeIdList));
|
||||
IsvRoutePermission isvRoutePermission = new IsvRoutePermission();
|
||||
isvRoutePermission.setAppKey(appKey);
|
||||
isvRoutePermission.setRouteIdList(routeIdList);
|
||||
isvRoutePermission.setRouteIdListMd5(roleCodeListMd5);
|
||||
this.update(isvRoutePermission);
|
||||
}
|
||||
|
||||
// 获取ISV对应的角色
|
||||
public Map<String, List<String>> getIsvRoleCode() {
|
||||
Query query = new Query();
|
||||
List<PermIsvRole> permIsvRoles = permIsvRoleMapper.list(query);
|
||||
Map<String, List<String>> appKeyRoleCodeMap = permIsvRoles.stream()
|
||||
.map(permIsvRole -> {
|
||||
IsvInfo isvInfo = isvInfoMapper.getById(permIsvRole.getIsvId());
|
||||
if (isvInfo == null) {
|
||||
return null;
|
||||
}
|
||||
IsvRole isvRole = new IsvRole();
|
||||
isvRole.appKey = isvInfo.getAppKey();
|
||||
isvRole.roleCode = permIsvRole.getRoleCode();
|
||||
return isvRole;
|
||||
})
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.groupingBy(IsvRole::getAppKey,
|
||||
mapping(IsvRole::getRoleCode, toList()))
|
||||
);
|
||||
return appKeyRoleCodeMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色对应的路由
|
||||
*
|
||||
* @param roleCodeList
|
||||
* @return
|
||||
*/
|
||||
public List<String> getRouteIdList(List<String> roleCodeList) {
|
||||
if (CollectionUtils.isEmpty(roleCodeList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Query query = new Query();
|
||||
query.in("role_code", roleCodeList);
|
||||
List<PermRolePermission> rolePermissionList = permRolePermissionMapper.list(query);
|
||||
return rolePermissionList.stream()
|
||||
.map(PermRolePermission::getRouteId)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Data
|
||||
static class IsvRole {
|
||||
private String appKey;
|
||||
private String roleCode;
|
||||
}
|
||||
|
||||
|
||||
@PostConstruct
|
||||
protected void after() throws Exception {
|
||||
ZookeeperContext.setEnvironment(environment);
|
||||
String isvChannelPath = ZookeeperContext.getIsvRoutePermissionChannelPath();
|
||||
ZookeeperContext.listenPath(isvChannelPath, nodeCache -> {
|
||||
String nodeData = new String(nodeCache.getCurrentData().getData());
|
||||
ChannelMsg channelMsg = JSON.parseObject(nodeData, ChannelMsg.class);
|
||||
final IsvRoutePermission isvRoutePermission = JSON.parseObject(channelMsg.getData(), IsvRoutePermission.class);
|
||||
switch (channelMsg.getOperation()) {
|
||||
case "reload":
|
||||
log.info("重新加载路由权限信息,isvRoutePermission:{}", isvRoutePermission);
|
||||
load();
|
||||
break;
|
||||
case "update":
|
||||
log.info("更新ISV路由权限信息,isvRoutePermission:{}", isvRoutePermission);
|
||||
update(isvRoutePermission);
|
||||
break;
|
||||
case "remove":
|
||||
log.info("删除ISV路由权限信息,isvRoutePermission:{}", isvRoutePermission);
|
||||
remove(isvRoutePermission.getAppKey());
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
package com.gitee.sop.gateway.manager;
|
||||
|
||||
import com.gitee.sop.gateway.entity.IsvInfo;
|
||||
import com.gitee.sop.gatewaycommon.bean.ApiConfig;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ManagerInitializer {
|
||||
@Autowired
|
||||
private DbIsvManager dbIsvManager;
|
||||
|
||||
@Autowired
|
||||
private DbIsvRoutePermissionManager dbIsvRoutePermissionManager;
|
||||
|
||||
public void init() {
|
||||
ApiConfig apiConfig = ApiConfig.getInstance();
|
||||
apiConfig.setIsvManager(dbIsvManager);
|
||||
apiConfig.setIsvRoutePermissionManager(dbIsvRoutePermissionManager);
|
||||
|
||||
// 从数据库加载isv信息
|
||||
log.debug("从数据库加载isv信息");
|
||||
dbIsvManager.load((isvInfoObj) -> {
|
||||
IsvInfo isvInfo = (IsvInfo)isvInfoObj;
|
||||
return isvInfo.getPubKey();
|
||||
});
|
||||
|
||||
log.debug("从数据库加载路由权限信息");
|
||||
dbIsvRoutePermissionManager.load();
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
package com.gitee.sop.gateway.mapper;
|
||||
|
||||
import com.gitee.fastmybatis.core.mapper.CrudMapper;
|
||||
import com.gitee.sop.gateway.entity.IsvInfo;
|
||||
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
public interface IsvInfoMapper extends CrudMapper<IsvInfo, Long> {
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
package com.gitee.sop.gateway.mapper;
|
||||
|
||||
import com.gitee.fastmybatis.core.mapper.CrudMapper;
|
||||
import com.gitee.sop.gateway.entity.PermIsvRole;
|
||||
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
public interface PermIsvRoleMapper extends CrudMapper<PermIsvRole, Long> {
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
package com.gitee.sop.gateway.mapper;
|
||||
|
||||
import com.gitee.fastmybatis.core.mapper.CrudMapper;
|
||||
import com.gitee.sop.gateway.entity.PermRolePermission;
|
||||
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
public interface PermRolePermissionMapper extends CrudMapper<PermRolePermission, Long> {
|
||||
}
|
@@ -16,3 +16,9 @@ spring:
|
||||
lower-case-service-id: true
|
||||
enabled: true
|
||||
|
||||
# 数据源
|
||||
datasource:
|
||||
driver-class-name: com.mysql.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3306/sop?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
|
||||
username: root
|
||||
password: root
|
@@ -11,7 +11,6 @@ import org.apache.curator.retry.ExponentialBackoffRetry;
|
||||
*/
|
||||
public class CuratorTest extends TestCase {
|
||||
|
||||
|
||||
private String zookeeperServerAddr = "127.0.0.1:2181";
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user