mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-11 21:57:56 +08:00
5.0
This commit is contained in:
@@ -11,6 +11,8 @@ import java.io.Serializable;
|
||||
public class ApiInfoDTO implements Serializable {
|
||||
private static final long serialVersionUID = 2183251167679411550L;
|
||||
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 所属应用
|
||||
*/
|
||||
|
@@ -0,0 +1,11 @@
|
||||
package com.gitee.sop.gateway.common;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
public class CacheKey {
|
||||
public static final String KEY_API = "sop:api";
|
||||
public static final String KEY_ISV = "sop:isv";
|
||||
public static final String KEY_SEC = "sop:sec";
|
||||
public static final String KEY_ISV_PERM = "sop:isv-perm";
|
||||
}
|
@@ -12,5 +12,6 @@ public class SopConstants {
|
||||
|
||||
public static final Charset CHARSET_UTF8 = StandardCharsets.UTF_8;
|
||||
public static final String UTF8 = "UTF-8";
|
||||
public static final String NULL = "null";
|
||||
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
package com.gitee.sop.gateway.common;
|
||||
package com.gitee.sop.gateway.common.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
@@ -0,0 +1,26 @@
|
||||
package com.gitee.sop.gateway.common.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum YesOrNoEnum {
|
||||
YES(1),
|
||||
NO(0);
|
||||
|
||||
private final int value;
|
||||
|
||||
public static YesOrNoEnum of(Integer value) {
|
||||
return Objects.equals(value, YES.value) ? YES : NO;
|
||||
}
|
||||
|
||||
public static YesOrNoEnum of(Boolean value) {
|
||||
return Objects.equals(value, true) ? YES : NO;
|
||||
}
|
||||
}
|
@@ -7,12 +7,15 @@ import com.gitee.sop.gateway.service.RouteService;
|
||||
import com.gitee.sop.gateway.service.RouteServiceImpl;
|
||||
import com.gitee.sop.gateway.service.interceptor.internal.ResultRouteInterceptor;
|
||||
import com.gitee.sop.gateway.service.manager.ApiManager;
|
||||
import com.gitee.sop.gateway.service.manager.IsvApiPermissionManager;
|
||||
import com.gitee.sop.gateway.service.manager.IsvManager;
|
||||
import com.gitee.sop.gateway.service.manager.SecretManager;
|
||||
import com.gitee.sop.gateway.service.manager.impl.LocalApiManagerImpl;
|
||||
import com.gitee.sop.gateway.service.manager.impl.LocalIsvApiPermissionManagerImpl;
|
||||
import com.gitee.sop.gateway.service.manager.impl.LocalIsvManagerImpl;
|
||||
import com.gitee.sop.gateway.service.manager.impl.LocalSecretManagerImpl;
|
||||
import com.gitee.sop.gateway.service.manager.impl.RedisApiManagerImpl;
|
||||
import com.gitee.sop.gateway.service.manager.impl.RedisIsvApiPermissionManagerImpl;
|
||||
import com.gitee.sop.gateway.service.manager.impl.RedisIsvManagerImpl;
|
||||
import com.gitee.sop.gateway.service.manager.impl.RedisSecretManager;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -66,6 +69,18 @@ public class IndexConfig {
|
||||
return new RedisSecretManager();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(value = "gateway.manager.isv-api-perm", havingValue = "local", matchIfMissing = true)
|
||||
public IsvApiPermissionManager localIsvApiPermissionManager() {
|
||||
return new LocalIsvApiPermissionManagerImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(value = "gateway.manager.isv-api-perm", havingValue = "redis")
|
||||
public IsvApiPermissionManager redisIsvApiPermissionManager() {
|
||||
return new RedisIsvApiPermissionManagerImpl();
|
||||
}
|
||||
|
||||
|
||||
// DEFAULT ROUTE INTERCEPTOR
|
||||
@Bean
|
||||
|
@@ -9,7 +9,7 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
@@ -22,10 +22,10 @@ import java.io.IOException;
|
||||
@Controller
|
||||
public class IndexController {
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
private RouteService routeService;
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
private ParamExecutor<HttpServletRequest, HttpServletResponse> paramExecutor;
|
||||
|
||||
@GetMapping("/")
|
||||
|
@@ -1,7 +1,6 @@
|
||||
package com.gitee.sop.gateway.dao.entity;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
import com.gitee.fastmybatis.annotation.Pk;
|
||||
import com.gitee.fastmybatis.annotation.PkStrategy;
|
||||
@@ -20,9 +19,15 @@ import lombok.Data;
|
||||
@Data
|
||||
public class IsvKeys {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
private String appId;
|
||||
/**
|
||||
* isv_info.id
|
||||
*/
|
||||
private Long isvId;
|
||||
|
||||
/**
|
||||
* 秘钥格式,1:PKCS8(JAVA适用),2:PKCS1(非JAVA适用)
|
||||
@@ -49,8 +54,14 @@ public class IsvKeys {
|
||||
*/
|
||||
private String privateKeyPlatform;
|
||||
|
||||
/**
|
||||
* 添加时间
|
||||
*/
|
||||
private LocalDateTime addTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
|
||||
|
@@ -0,0 +1,48 @@
|
||||
package com.gitee.sop.gateway.dao.entity;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import com.gitee.fastmybatis.annotation.Pk;
|
||||
import com.gitee.fastmybatis.annotation.PkStrategy;
|
||||
import com.gitee.fastmybatis.annotation.Table;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
/**
|
||||
* 表名:perm_group_permission
|
||||
* 备注:组权限表
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@Table(name = "perm_group_permission", pk = @Pk(name = "id", strategy = PkStrategy.INCREMENT))
|
||||
@Data
|
||||
public class PermGroupPermission {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 组id
|
||||
*/
|
||||
private Long groupId;
|
||||
|
||||
/**
|
||||
* api_info.id
|
||||
*/
|
||||
private Long apiId;
|
||||
|
||||
/**
|
||||
* 添加时间
|
||||
*/
|
||||
private LocalDateTime addTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
package com.gitee.sop.gateway.dao.entity;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import com.gitee.fastmybatis.annotation.Pk;
|
||||
import com.gitee.fastmybatis.annotation.PkStrategy;
|
||||
import com.gitee.fastmybatis.annotation.Table;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
/**
|
||||
* 表名:perm_isv_group
|
||||
* 备注:isv分组
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@Table(name = "perm_isv_group", pk = @Pk(name = "id", strategy = PkStrategy.INCREMENT))
|
||||
@Data
|
||||
public class PermIsvGroup {
|
||||
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* isv_info表id
|
||||
*/
|
||||
private Long isvId;
|
||||
|
||||
/**
|
||||
* 组id
|
||||
*/
|
||||
private Long groupId;
|
||||
|
||||
private LocalDateTime addTime;
|
||||
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
|
||||
}
|
@@ -3,10 +3,12 @@ package com.gitee.sop.gateway.dao.mapper;
|
||||
|
||||
import com.gitee.fastmybatis.core.mapper.BaseMapper;
|
||||
import com.gitee.sop.gateway.dao.entity.ApiInfo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Mapper
|
||||
public interface ApiInfoMapper extends BaseMapper<ApiInfo> {
|
||||
|
||||
default ApiInfo getByNameVersion(String apiName, String apiVersion) {
|
||||
|
@@ -2,10 +2,12 @@ package com.gitee.sop.gateway.dao.mapper;
|
||||
|
||||
import com.gitee.fastmybatis.core.mapper.BaseMapper;
|
||||
import com.gitee.sop.gateway.dao.entity.IsvInfo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Mapper
|
||||
public interface IsvInfoMapper extends BaseMapper<IsvInfo> {
|
||||
|
||||
default IsvInfo getByAppId(String appId) {
|
||||
|
@@ -2,14 +2,16 @@ package com.gitee.sop.gateway.dao.mapper;
|
||||
|
||||
import com.gitee.fastmybatis.core.mapper.BaseMapper;
|
||||
import com.gitee.sop.gateway.dao.entity.IsvKeys;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Mapper
|
||||
public interface IsvKeysMapper extends BaseMapper<IsvKeys> {
|
||||
|
||||
default IsvKeys getByAppId(String appId) {
|
||||
return this.get(IsvKeys::getAppId, appId);
|
||||
default IsvKeys getByIsvId(Long isvId) {
|
||||
return this.get(IsvKeys::getIsvId, isvId);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,13 @@
|
||||
package com.gitee.sop.gateway.dao.mapper;
|
||||
|
||||
import com.gitee.fastmybatis.core.mapper.BaseMapper;
|
||||
import com.gitee.sop.gateway.dao.entity.PermGroupPermission;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Mapper
|
||||
public interface PermGroupPermissionMapper extends BaseMapper<PermGroupPermission> {
|
||||
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
package com.gitee.sop.gateway.dao.mapper;
|
||||
|
||||
import com.gitee.fastmybatis.core.mapper.BaseMapper;
|
||||
import com.gitee.sop.gateway.dao.entity.PermIsvGroup;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Mapper
|
||||
public interface PermIsvGroupMapper extends BaseMapper<PermIsvGroup> {
|
||||
|
||||
}
|
@@ -15,7 +15,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
@@ -36,7 +36,7 @@ public class ParamExecutorImpl implements ParamExecutor<HttpServletRequest, Http
|
||||
private static final String MULTIPART = "multipart";
|
||||
private static final String FORM = "form";
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
private ApiConfig apiConfig;
|
||||
|
||||
@Override
|
||||
|
@@ -26,7 +26,7 @@ import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -44,13 +44,13 @@ import java.util.Optional;
|
||||
@Slf4j
|
||||
public class RouteServiceImpl implements RouteService {
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
protected Validator validator;
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
protected GenericServiceInvoker genericServiceInvoker;
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
protected ExceptionExecutor exceptionExecutor;
|
||||
|
||||
@Autowired(required = false)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
package com.gitee.sop.gateway.service.dubbo;
|
||||
|
||||
import com.gitee.sop.gateway.common.ApiInfoDTO;
|
||||
import com.gitee.sop.gateway.common.StatusEnum;
|
||||
import com.gitee.sop.gateway.common.enums.StatusEnum;
|
||||
import com.gitee.sop.gateway.dao.entity.ApiInfo;
|
||||
import com.gitee.sop.gateway.dao.mapper.ApiInfoMapper;
|
||||
import com.gitee.sop.gateway.service.manager.ApiManager;
|
||||
@@ -11,7 +11,7 @@ import com.gitee.sop.support.service.dto.RegisterDTO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dubbo.config.annotation.DubboService;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
@@ -20,10 +20,12 @@ import javax.annotation.Resource;
|
||||
@DubboService
|
||||
public class ApiRegisterServiceImpl implements ApiRegisterService {
|
||||
|
||||
@Resource
|
||||
private static final int REG_SOURCE_SYS = 1;
|
||||
|
||||
@Autowired
|
||||
private ApiManager apiCacheManager;
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
private ApiInfoMapper apiInfoMapper;
|
||||
|
||||
@Override
|
||||
@@ -37,7 +39,7 @@ public class ApiRegisterServiceImpl implements ApiRegisterService {
|
||||
apiInfo = new ApiInfo();
|
||||
}
|
||||
CopyUtil.copyPropertiesIgnoreNull(apiInfoDTO, apiInfo);
|
||||
apiInfo.setRegSource(1);
|
||||
apiInfo.setRegSource(REG_SOURCE_SYS);
|
||||
// 保存到数据库
|
||||
apiInfoMapper.saveOrUpdate(apiInfo);
|
||||
// 保存到缓存
|
||||
|
@@ -1,26 +0,0 @@
|
||||
package com.gitee.sop.gateway.service.dubbo;
|
||||
|
||||
import com.gitee.sop.gateway.service.manager.IsvManager;
|
||||
import com.gitee.sop.support.service.IsvService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dubbo.config.annotation.DubboService;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@DubboService
|
||||
@Slf4j
|
||||
public class IsvServiceImpl implements IsvService {
|
||||
|
||||
@Resource
|
||||
private IsvManager isvManager;
|
||||
|
||||
@Override
|
||||
public void refresh(String appId) {
|
||||
log.info("refresh Isv, appId={}", appId);
|
||||
// 刷新isv信息
|
||||
isvManager.reload(appId);
|
||||
}
|
||||
}
|
@@ -0,0 +1,50 @@
|
||||
package com.gitee.sop.gateway.service.dubbo;
|
||||
|
||||
import com.gitee.sop.gateway.service.manager.ApiManager;
|
||||
import com.gitee.sop.gateway.service.manager.IsvApiPermissionManager;
|
||||
import com.gitee.sop.gateway.service.manager.IsvManager;
|
||||
import com.gitee.sop.gateway.service.manager.SecretManager;
|
||||
import com.gitee.sop.support.service.RefreshService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dubbo.config.annotation.DubboService;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@DubboService
|
||||
@Slf4j
|
||||
public class RefreshServiceImpl implements RefreshService {
|
||||
|
||||
@Autowired
|
||||
private IsvManager isvManager;
|
||||
@Autowired
|
||||
private SecretManager secretManager;
|
||||
@Autowired
|
||||
private IsvApiPermissionManager isvApiPermissionManager;
|
||||
@Autowired
|
||||
private ApiManager apiManager;
|
||||
|
||||
@Override
|
||||
public void refreshApi(Collection<Long> apiIds) {
|
||||
apiManager.refresh(apiIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshIsv(Collection<String> appIds) {
|
||||
isvManager.refresh(appIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshIsvPerm(Collection<Long> isvIds) {
|
||||
isvApiPermissionManager.refresh(isvIds);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void refreshSecret(Collection<Long> isvIds) {
|
||||
secretManager.refresh(isvIds);
|
||||
}
|
||||
}
|
@@ -2,12 +2,14 @@ package com.gitee.sop.gateway.service.manager;
|
||||
|
||||
import com.gitee.sop.gateway.common.ApiInfoDTO;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
public interface ApiManager {
|
||||
public interface ApiManager extends Manager<Collection<Long>, Map<Long, ApiInfoDTO>> {
|
||||
|
||||
void save(ApiInfoDTO apiInfoDTO);
|
||||
|
||||
|
@@ -0,0 +1,9 @@
|
||||
package com.gitee.sop.gateway.service.manager;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
public interface CacheManager {
|
||||
|
||||
|
||||
}
|
@@ -1,12 +1,24 @@
|
||||
package com.gitee.sop.gateway.service.manager;
|
||||
|
||||
import com.gitee.sop.gateway.common.ApiInfoDTO;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* isv接口授权管理
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
public interface IsvApiPermissionManager {
|
||||
|
||||
boolean hasPermission(String appId, String apiNameVersion);
|
||||
public interface IsvApiPermissionManager extends Manager<Collection<Long>, Map<Long, List<Long>>> {
|
||||
|
||||
/**
|
||||
* isv是否可以访问接口
|
||||
* @param isvId isvId
|
||||
* @param apiInfoDTO apiInfoDTO
|
||||
* @return true:能访问
|
||||
*/
|
||||
boolean hasPermission(Long isvId, ApiInfoDTO apiInfoDTO);
|
||||
}
|
||||
|
@@ -2,10 +2,13 @@ package com.gitee.sop.gateway.service.manager;
|
||||
|
||||
import com.gitee.sop.gateway.service.manager.dto.IsvDTO;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
public interface IsvManager {
|
||||
public interface IsvManager extends Manager<Collection<String>, Map<String, IsvDTO>> {
|
||||
|
||||
/**
|
||||
* 获取isv信息
|
||||
@@ -14,11 +17,4 @@ public interface IsvManager {
|
||||
* @return 返回isv信息, 没有返回null
|
||||
*/
|
||||
IsvDTO getIsv(String appId);
|
||||
|
||||
/**
|
||||
* 重新加载isv信息到内存中
|
||||
*
|
||||
* @param appId appId
|
||||
*/
|
||||
void reload(String appId);
|
||||
}
|
||||
|
@@ -0,0 +1,16 @@
|
||||
package com.gitee.sop.gateway.service.manager;
|
||||
|
||||
/**
|
||||
* @param <T> 入参
|
||||
* @param <R> 出参
|
||||
* @author 六如
|
||||
*/
|
||||
public interface Manager<T, R> {
|
||||
|
||||
R refresh(T id);
|
||||
|
||||
default void init() {
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -1,19 +1,20 @@
|
||||
package com.gitee.sop.gateway.service.manager;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 秘钥管理
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
public interface SecretManager {
|
||||
public interface SecretManager extends Manager<Collection<Long>, Map<Long, String>> {
|
||||
|
||||
/**
|
||||
* 获取用户上传的公钥
|
||||
*
|
||||
* @param appId appId
|
||||
* @param isvId isvId
|
||||
* @return 返回公钥内容
|
||||
*/
|
||||
String getIsvPublicKey(String appId);
|
||||
|
||||
String reload(String appId);
|
||||
String getIsvPublicKey(Long isvId);
|
||||
}
|
||||
|
@@ -8,6 +8,8 @@ import lombok.Data;
|
||||
@Data
|
||||
public class IsvDTO {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String appId;
|
||||
|
||||
private Integer status;
|
||||
|
@@ -1,16 +0,0 @@
|
||||
package com.gitee.sop.gateway.service.manager.impl;
|
||||
|
||||
import com.gitee.sop.gateway.service.manager.IsvApiPermissionManager;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Service
|
||||
public class IsvApiPermissionManagerImpl implements IsvApiPermissionManager {
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String appId, String apiNameVersion) {
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -6,20 +6,26 @@ import com.gitee.sop.gateway.dao.mapper.ApiInfoMapper;
|
||||
import com.gitee.sop.gateway.service.manager.ApiManager;
|
||||
import com.gitee.sop.gateway.util.CopyUtil;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* 本地存储接口信息.
|
||||
* @author 六如
|
||||
*/
|
||||
@Slf4j
|
||||
public class LocalApiManagerImpl implements ApiManager {
|
||||
|
||||
private static final Map<String, Optional<ApiInfoDTO>> CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
protected ApiInfoMapper apiInfoMapper;
|
||||
|
||||
@Override
|
||||
@@ -28,6 +34,7 @@ public class LocalApiManagerImpl implements ApiManager {
|
||||
CACHE.put(key, Optional.of(apiInfoDTO));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ApiInfoDTO get(String apiName, String apiVersion) {
|
||||
String key = apiName + apiVersion;
|
||||
@@ -36,4 +43,24 @@ public class LocalApiManagerImpl implements ApiManager {
|
||||
return Optional.ofNullable(CopyUtil.copyBean(apiInfo, ApiInfoDTO::new));
|
||||
}).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, ApiInfoDTO> refresh(Collection<Long> id) {
|
||||
log.info("刷新api信息, id={}", id);
|
||||
Map<Long, ApiInfo> apiIdMap = apiInfoMapper.query()
|
||||
.in(ApiInfo::getId, id)
|
||||
.map(ApiInfo::getId, Function.identity());
|
||||
|
||||
apiIdMap.values().forEach(this::cache);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
protected ApiInfoDTO cache(ApiInfo apiInfo) {
|
||||
ApiInfoDTO apiInfoDTO = CopyUtil.copyBean(apiInfo, ApiInfoDTO::new);
|
||||
String key = apiInfoDTO.buildApiNameVersion();
|
||||
CACHE.put(key, Optional.of(apiInfoDTO));
|
||||
log.info("更新接口本地缓存, apiInfoDTO={}", apiInfoDTO);
|
||||
return apiInfoDTO;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,99 @@
|
||||
package com.gitee.sop.gateway.service.manager.impl;
|
||||
|
||||
import com.gitee.sop.gateway.common.ApiInfoDTO;
|
||||
import com.gitee.sop.gateway.common.enums.YesOrNoEnum;
|
||||
import com.gitee.sop.gateway.dao.entity.ApiInfo;
|
||||
import com.gitee.sop.gateway.dao.entity.PermGroupPermission;
|
||||
import com.gitee.sop.gateway.dao.entity.PermIsvGroup;
|
||||
import com.gitee.sop.gateway.dao.mapper.ApiInfoMapper;
|
||||
import com.gitee.sop.gateway.dao.mapper.PermGroupPermissionMapper;
|
||||
import com.gitee.sop.gateway.dao.mapper.PermIsvGroupMapper;
|
||||
import com.gitee.sop.gateway.service.manager.IsvApiPermissionManager;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 缓存ISV接口权限
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@Slf4j
|
||||
public class LocalIsvApiPermissionManagerImpl implements IsvApiPermissionManager {
|
||||
|
||||
// key:isvId, value: List<apiName+apiVersion>
|
||||
private static final Map<Long, List<Long>> CACHE = new HashMap<>();
|
||||
|
||||
@Autowired
|
||||
private PermGroupPermissionMapper permGroupPermissionMapper;
|
||||
@Autowired
|
||||
private PermIsvGroupMapper permIsvGroupMapper;
|
||||
@Autowired
|
||||
private ApiInfoMapper apiInfoMapper;
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(Long isvId, ApiInfoDTO apiInfoDTO) {
|
||||
// 通用接口都可以访问
|
||||
if (Objects.equals(apiInfoDTO.getIsPermission(), YesOrNoEnum.NO.getValue())) {
|
||||
return true;
|
||||
}
|
||||
return doCheck(isvId, apiInfoDTO);
|
||||
}
|
||||
|
||||
public boolean doCheck(Long isvId, ApiInfoDTO apiInfoDTO) {
|
||||
List<Long> apiNameVerionList = CACHE.computeIfAbsent(isvId, k -> this.listApiId(isvId));
|
||||
if (CollectionUtils.isEmpty(apiNameVerionList)) {
|
||||
return false;
|
||||
}
|
||||
return apiNameVerionList.contains(apiInfoDTO.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, List<Long>> refresh(Collection<Long> isvIds) {
|
||||
log.info("刷新isv接口权限, isvIds={}", isvIds);
|
||||
if (CollectionUtils.isEmpty(isvIds)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Map<Long, List<Long>> map = new HashMap<>(isvIds.size() * 2);
|
||||
for (Long isvId : isvIds) {
|
||||
List<Long> apiIdList = this.listApiId(isvId);
|
||||
map.put(isvId, apiIdList);
|
||||
// 缓存
|
||||
cache(isvId, apiIdList);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
protected void cache(Long isvId, List<Long> apiIdList) {
|
||||
CACHE.put(isvId, apiIdList);
|
||||
log.info("更新isv接口id本地缓存, isvId={}, apiIdList={}", isvId, apiIdList);
|
||||
}
|
||||
|
||||
protected List<Long> listApiId(Long isvId) {
|
||||
List<Long> groupIds = permIsvGroupMapper.query()
|
||||
.eq(PermIsvGroup::getIsvId, isvId)
|
||||
.listUniqueValue(PermIsvGroup::getGroupId);
|
||||
if (groupIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<Long> apiIdList = permGroupPermissionMapper.query()
|
||||
.in(PermGroupPermission::getGroupId, groupIds)
|
||||
.listUniqueValue(PermGroupPermission::getApiId);
|
||||
if (apiIdList.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return apiInfoMapper.query()
|
||||
.select(ApiInfo::getApiName, ApiInfo::getApiVersion)
|
||||
.in(ApiInfo::getId, apiIdList)
|
||||
.listUniqueValue(ApiInfo::getId);
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -5,8 +5,13 @@ import com.gitee.sop.gateway.dao.mapper.IsvInfoMapper;
|
||||
import com.gitee.sop.gateway.service.manager.IsvManager;
|
||||
import com.gitee.sop.gateway.service.manager.dto.IsvDTO;
|
||||
import com.gitee.sop.gateway.util.CopyUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -14,12 +19,12 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Slf4j
|
||||
public class LocalIsvManagerImpl implements IsvManager {
|
||||
|
||||
private static final Map<String, Optional<IsvDTO>> CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
protected IsvInfoMapper isvInfoMapper;
|
||||
|
||||
@Override
|
||||
@@ -31,10 +36,25 @@ public class LocalIsvManagerImpl implements IsvManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload(String appId) {
|
||||
IsvInfo isvInfo = isvInfoMapper.getByAppId(appId);
|
||||
IsvDTO isvDTO = CopyUtil.copyBean(isvInfo, IsvDTO::new);
|
||||
public Map<String, IsvDTO> refresh(Collection<String> appIds) {
|
||||
log.info("刷新isv, appId={}", appIds);
|
||||
if (CollectionUtils.isEmpty(appIds)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Map<String, IsvDTO> map = new HashMap<>(appIds.size() * 2);
|
||||
for (String appId : appIds) {
|
||||
IsvInfo isvInfo = isvInfoMapper.getByAppId(appId);
|
||||
IsvDTO isvDTO = CopyUtil.copyBean(isvInfo, IsvDTO::new);
|
||||
map.put(appId, isvDTO);
|
||||
|
||||
cache(appId, isvDTO);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
protected void cache(String appId, IsvDTO isvDTO) {
|
||||
CACHE.put(appId, Optional.ofNullable(isvDTO));
|
||||
log.info("更新isv本地缓存, isvDTO={}", isvDTO);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -3,8 +3,13 @@ package com.gitee.sop.gateway.service.manager.impl;
|
||||
import com.gitee.sop.gateway.dao.entity.IsvKeys;
|
||||
import com.gitee.sop.gateway.dao.mapper.IsvKeysMapper;
|
||||
import com.gitee.sop.gateway.service.manager.SecretManager;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -12,30 +17,48 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Slf4j
|
||||
public class LocalSecretManagerImpl implements SecretManager {
|
||||
|
||||
private static final Map<String, Optional<String>> CACHE = new ConcurrentHashMap<>();
|
||||
private static final Map<Long, Optional<String>> CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
protected IsvKeysMapper isvKeysMapper;
|
||||
|
||||
@Override
|
||||
public String getIsvPublicKey(String appId) {
|
||||
return CACHE.computeIfAbsent(appId, k -> {
|
||||
String publicKey = isvKeysMapper.query()
|
||||
.eq(IsvKeys::getAppId, appId)
|
||||
.getValue(IsvKeys::getPublicKeyIsv);
|
||||
public String getIsvPublicKey(Long isvId) {
|
||||
return CACHE.computeIfAbsent(isvId, k -> {
|
||||
String publicKey = doGetPublicKey(isvId);
|
||||
return Optional.ofNullable(publicKey);
|
||||
})
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String reload(String appId) {
|
||||
String publicKey = isvKeysMapper.query()
|
||||
.eq(IsvKeys::getAppId, appId)
|
||||
.getValue(IsvKeys::getPublicKeyIsv);
|
||||
CACHE.put(appId, Optional.ofNullable(publicKey));
|
||||
return publicKey;
|
||||
public Map<Long, String> refresh(Collection<Long> isvIds) {
|
||||
log.info("刷新isv秘钥, isvId={}", isvIds);
|
||||
if (CollectionUtils.isEmpty(isvIds)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Map<Long, String> map = new HashMap<>(isvIds.size() * 2);
|
||||
for (Long isvId : isvIds) {
|
||||
String publicKey = doGetPublicKey(isvId);
|
||||
map.put(isvId, publicKey);
|
||||
|
||||
this.cache(isvId, publicKey);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
protected void cache(Long isvId, String publicKey) {
|
||||
CACHE.put(isvId, Optional.ofNullable(publicKey));
|
||||
log.info("更新isv秘钥本地缓存, isvId={}", isvId);
|
||||
}
|
||||
|
||||
protected String doGetPublicKey(Long isvId) {
|
||||
return isvKeysMapper.query()
|
||||
.eq(IsvKeys::getIsvId, isvId)
|
||||
.getValue(IsvKeys::getPublicKeyIsv);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,14 +1,17 @@
|
||||
package com.gitee.sop.gateway.service.manager.impl;
|
||||
|
||||
import com.gitee.sop.gateway.common.ApiInfoDTO;
|
||||
import com.gitee.sop.gateway.common.CacheKey;
|
||||
import com.gitee.sop.gateway.dao.entity.ApiInfo;
|
||||
import com.gitee.sop.gateway.util.CopyUtil;
|
||||
import com.gitee.sop.gateway.util.JsonUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.BoundHashOperations;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -19,10 +22,10 @@ import java.util.List;
|
||||
@Slf4j
|
||||
public class RedisApiManagerImpl extends LocalApiManagerImpl {
|
||||
|
||||
private static final String KEY_API = "sop:api";
|
||||
private static final String KEY_API = CacheKey.KEY_API;
|
||||
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
@Autowired
|
||||
StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
@Override
|
||||
public void save(ApiInfoDTO apiInfoDTO) {
|
||||
@@ -30,20 +33,33 @@ public class RedisApiManagerImpl extends LocalApiManagerImpl {
|
||||
stringRedisTemplate.opsForHash().put(KEY_API, key, JsonUtil.toJSONString(apiInfoDTO));
|
||||
}
|
||||
|
||||
protected void cache(String key, ApiInfo apiInfo) {
|
||||
protected ApiInfoDTO cache(ApiInfo apiInfo) {
|
||||
String key = apiInfo.getApiName() + apiInfo.getApiVersion();
|
||||
ApiInfoDTO apiInfoDTO = CopyUtil.copyBean(apiInfo, ApiInfoDTO::new);
|
||||
stringRedisTemplate.opsForHash().put(KEY_API, key, JsonUtil.toJSONString(apiInfoDTO));
|
||||
log.info("更新接口redis缓存, apiInfoDTO={}", apiInfoDTO);
|
||||
return apiInfoDTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiInfoDTO get(String apiName, String apiVersion) {
|
||||
String key = apiName + apiVersion;
|
||||
try {
|
||||
Object value = stringRedisTemplate.opsForHash().get(KEY_API, key);
|
||||
BoundHashOperations<String, String, String> operations = stringRedisTemplate.boundHashOps(KEY_API);
|
||||
String value = operations.get(key);
|
||||
if (value == null) {
|
||||
// 从数据库中读取
|
||||
ApiInfo apiInfo = apiInfoMapper.getByNameVersion(apiName, apiVersion);
|
||||
if (apiInfo == null) {
|
||||
operations.put(key, "");
|
||||
return null;
|
||||
}
|
||||
return this.cache(apiInfo);
|
||||
}
|
||||
if (ObjectUtils.isEmpty(value)) {
|
||||
return null;
|
||||
}
|
||||
return JsonUtil.parseObject(String.valueOf(value), ApiInfoDTO.class);
|
||||
return JsonUtil.parseObject(value, ApiInfoDTO.class);
|
||||
} catch (Exception e) {
|
||||
log.error("redis访问失败", e);
|
||||
return super.get(apiName, apiVersion);
|
||||
@@ -55,8 +71,7 @@ public class RedisApiManagerImpl extends LocalApiManagerImpl {
|
||||
log.info("load apiInfo to redis");
|
||||
List<ApiInfo> apiInfos = this.apiInfoMapper.listAll();
|
||||
for (ApiInfo apiInfo : apiInfos) {
|
||||
String key = apiInfo.getApiName() + apiInfo.getApiVersion();
|
||||
this.cache(key, apiInfo);
|
||||
this.cache(apiInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,71 @@
|
||||
package com.gitee.sop.gateway.service.manager.impl;
|
||||
|
||||
import com.gitee.sop.gateway.common.ApiInfoDTO;
|
||||
import com.gitee.sop.gateway.common.CacheKey;
|
||||
import com.gitee.sop.gateway.common.SopConstants;
|
||||
import com.gitee.sop.gateway.dao.entity.IsvInfo;
|
||||
import com.gitee.sop.gateway.dao.mapper.IsvInfoMapper;
|
||||
import com.gitee.sop.gateway.util.JsonUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.BoundHashOperations;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Slf4j
|
||||
public class RedisIsvApiPermissionManagerImpl extends LocalIsvApiPermissionManagerImpl {
|
||||
|
||||
private static final String CACHE_KEY = CacheKey.KEY_ISV_PERM;
|
||||
|
||||
@Autowired
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
@Autowired
|
||||
private IsvInfoMapper isvInfoMapper;
|
||||
|
||||
@Override
|
||||
public boolean doCheck(Long isvId, ApiInfoDTO apiInfoDTO) {
|
||||
BoundHashOperations<String, Object, String> operations = stringRedisTemplate.boundHashOps(CACHE_KEY);
|
||||
String value = operations.get(isvId);
|
||||
if (Objects.equals(value, SopConstants.NULL)) {
|
||||
return false;
|
||||
}
|
||||
List<Long> apiIdList;
|
||||
if (value == null) {
|
||||
Map<Long, List<Long>> cache = this.refresh(Collections.singletonList(isvId));
|
||||
apiIdList = cache.get(isvId);
|
||||
} else {
|
||||
apiIdList = JsonUtil.parseArray(value, Long.class);
|
||||
}
|
||||
return apiIdList != null && apiIdList.contains(apiInfoDTO.getId());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void cache(Long isvId, List<Long> apiIdList) {
|
||||
stringRedisTemplate.opsForHash().put(CACHE_KEY, isvId, JsonUtil.toJSONString(apiIdList));
|
||||
log.info("更新isv接口id redis缓存, isvId={}, apiIdList={}", isvId, apiIdList);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
@Override
|
||||
public void init() {
|
||||
Set<Long> isvIds = isvInfoMapper.listAll()
|
||||
.stream()
|
||||
.map(IsvInfo::getId)
|
||||
.collect(Collectors.toSet());
|
||||
this.refresh(isvIds);
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,5 +1,7 @@
|
||||
package com.gitee.sop.gateway.service.manager.impl;
|
||||
|
||||
import com.gitee.sop.gateway.common.CacheKey;
|
||||
import com.gitee.sop.gateway.common.SopConstants;
|
||||
import com.gitee.sop.gateway.dao.entity.IsvInfo;
|
||||
import com.gitee.sop.gateway.service.manager.dto.IsvDTO;
|
||||
import com.gitee.sop.gateway.util.CopyUtil;
|
||||
@@ -8,8 +10,11 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
@@ -17,19 +22,21 @@ import java.util.List;
|
||||
@Slf4j
|
||||
public class RedisIsvManagerImpl extends LocalIsvManagerImpl {
|
||||
|
||||
private static final String KEY_ISV = "sop:isv";
|
||||
private static final String KEY_ISV = CacheKey.KEY_ISV;
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
|
||||
@Override
|
||||
public IsvDTO getIsv(String appId) {
|
||||
try {
|
||||
Object value = stringRedisTemplate.opsForHash().get(KEY_ISV, appId);
|
||||
if (Objects.equals(value, SopConstants.NULL)) {
|
||||
return null;
|
||||
}
|
||||
if (value == null) {
|
||||
IsvInfo isvInfo = this.isvInfoMapper.getByAppId(appId);
|
||||
return this.cache(isvInfo);
|
||||
Map<String, IsvDTO> cache = this.refresh(Collections.singletonList(appId));
|
||||
return cache.get(appId);
|
||||
}
|
||||
return JsonUtil.parseObject(String.valueOf(value), IsvDTO.class);
|
||||
} catch (Exception e) {
|
||||
@@ -39,23 +46,19 @@ public class RedisIsvManagerImpl extends LocalIsvManagerImpl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload(String appId) {
|
||||
IsvInfo isvInfo = isvInfoMapper.getByAppId(appId);
|
||||
this.cache(isvInfo);
|
||||
protected void cache(String appId, IsvDTO isvDTO) {
|
||||
stringRedisTemplate.opsForHash().put(KEY_ISV, appId, JsonUtil.toJSONString(isvDTO));
|
||||
log.info("更新isv redis缓存, isvDTO={}", isvDTO);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
@Override
|
||||
public void init() {
|
||||
log.info("load isvInfo to redis");
|
||||
List<IsvInfo> isvInfos = this.isvInfoMapper.listAll();
|
||||
for (IsvInfo isvInfo : isvInfos) {
|
||||
this.cache(isvInfo);
|
||||
this.cache(isvInfo.getAppId(), CopyUtil.copyBean(isvInfo, IsvDTO::new));
|
||||
}
|
||||
}
|
||||
|
||||
protected IsvDTO cache(IsvInfo isvInfo) {
|
||||
IsvDTO isvDTO = CopyUtil.copyBean(isvInfo, IsvDTO::new);
|
||||
stringRedisTemplate.opsForHash().put(KEY_ISV, isvInfo.getAppId(), JsonUtil.toJSONString(isvDTO));
|
||||
return isvDTO;
|
||||
}
|
||||
}
|
||||
|
@@ -1,13 +1,17 @@
|
||||
package com.gitee.sop.gateway.service.manager.impl;
|
||||
|
||||
import com.gitee.sop.gateway.common.CacheKey;
|
||||
import com.gitee.sop.gateway.common.SopConstants;
|
||||
import com.gitee.sop.gateway.dao.entity.IsvKeys;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
@@ -15,44 +19,45 @@ import java.util.Optional;
|
||||
@Slf4j
|
||||
public class RedisSecretManager extends LocalSecretManagerImpl {
|
||||
|
||||
private static final String KEY_ISV = "sop:sec";
|
||||
private static final String KEY_SEC = CacheKey.KEY_SEC;
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
@Override
|
||||
public String getIsvPublicKey(String appId) {
|
||||
public String getIsvPublicKey(Long isvId) {
|
||||
try {
|
||||
Object value = stringRedisTemplate.opsForHash().get(KEY_ISV, appId);
|
||||
Object value = stringRedisTemplate.opsForHash().get(KEY_SEC, isvId);
|
||||
if (Objects.equals(value, SopConstants.NULL)) {
|
||||
return null;
|
||||
}
|
||||
if (value == null) {
|
||||
return this.reload(appId);
|
||||
Map<Long, String> cache = this.refresh(Collections.singletonList(isvId));
|
||||
return cache.get(isvId);
|
||||
}
|
||||
return String.valueOf(value);
|
||||
} catch (Exception e) {
|
||||
log.error("操作redis失败", e);
|
||||
return super.getIsvPublicKey(appId);
|
||||
return super.getIsvPublicKey(isvId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String reload(String appId) {
|
||||
IsvKeys isvKeys = this.isvKeysMapper.getByAppId(appId);
|
||||
return this.cache(appId, isvKeys);
|
||||
}
|
||||
|
||||
|
||||
protected String cache(String appId, IsvKeys isvKeys) {
|
||||
String publicKey = Optional.ofNullable(isvKeys).map(IsvKeys::getPublicKeyIsv).orElse("");
|
||||
stringRedisTemplate.opsForHash().put(KEY_ISV, appId, publicKey);
|
||||
return publicKey;
|
||||
protected void cache(Long isvId, String publicKey) {
|
||||
if (publicKey == null) {
|
||||
publicKey = SopConstants.NULL;
|
||||
}
|
||||
stringRedisTemplate.opsForHash().put(KEY_SEC, isvId, publicKey);
|
||||
log.info("更新isv秘钥redis缓存, isvId={}", isvId);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
@Override
|
||||
public void init() {
|
||||
log.info("load isvKey to redis");
|
||||
List<IsvKeys> isvKeys = this.isvKeysMapper.listAll();
|
||||
for (IsvKeys isvKey : isvKeys) {
|
||||
this.cache(isvKey.getAppId(), isvKey);
|
||||
this.cache(isvKey.getIsvId(), isvKey.getPublicKeyIsv());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
package com.gitee.sop.gateway.service.validate;
|
||||
|
||||
import com.gitee.sop.gateway.common.ApiInfoDTO;
|
||||
import com.gitee.sop.gateway.common.StatusEnum;
|
||||
import com.gitee.sop.gateway.common.enums.StatusEnum;
|
||||
import com.gitee.sop.gateway.config.ApiConfig;
|
||||
import com.gitee.sop.gateway.exception.ApiException;
|
||||
import com.gitee.sop.gateway.message.ErrorEnum;
|
||||
@@ -24,7 +24,7 @@ import org.springframework.util.unit.DataSize;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
@@ -55,25 +55,25 @@ public class ApiValidator implements Validator {
|
||||
@Value("${upload.total-file-max-size}")
|
||||
private DataSize maxFileSize;
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
private Signer signer;
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
private ApiConfig apiConfig;
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
private ApiManager apiCacheManager;
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
private IpBlacklistManager ipBlacklistManager;
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
private IsvApiPermissionManager isvApiPermissionManager;
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
private IsvManager isvManager;
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
private SecretManager secretManager;
|
||||
|
||||
private DateTimeFormatter dateTimeFormatter;
|
||||
@@ -96,7 +96,7 @@ public class ApiValidator implements Validator {
|
||||
ApiRequest apiRequest = apiRequestContext.getApiRequest();
|
||||
ApiInfoDTO apiInfo = apiCacheManager.get(apiRequest.getMethod(), apiRequest.getVersion());
|
||||
// 检查接口信息
|
||||
checkApiInfo(apiRequestContext, apiInfo);
|
||||
checkApiInfo(apiRequestContext, apiInfo, isvDTO);
|
||||
|
||||
// 检查上传文件
|
||||
checkUploadFile(apiRequestContext);
|
||||
@@ -105,7 +105,7 @@ public class ApiValidator implements Validator {
|
||||
return apiInfo;
|
||||
}
|
||||
|
||||
public void checkApiInfo(ApiRequestContext apiRequestContext, ApiInfoDTO apiInfoDTO) {
|
||||
public void checkApiInfo(ApiRequestContext apiRequestContext, ApiInfoDTO apiInfoDTO, IsvDTO isvDTO) {
|
||||
// 检查路由是否存在
|
||||
if (apiInfoDTO == null) {
|
||||
throw new ApiException(ErrorEnum.ISV_INVALID_METHOD, apiRequestContext.getLocale());
|
||||
@@ -119,8 +119,7 @@ public class ApiValidator implements Validator {
|
||||
if (needCheckPermission) {
|
||||
ApiRequest apiRequest = apiRequestContext.getApiRequest();
|
||||
String appKey = apiRequest.getAppId();
|
||||
String nameVersion = apiRequest.takeNameVersion();
|
||||
boolean hasPermission = isvApiPermissionManager.hasPermission(appKey, nameVersion);
|
||||
boolean hasPermission = isvApiPermissionManager.hasPermission(isvDTO.getId(), apiInfoDTO);
|
||||
if (!hasPermission) {
|
||||
throw new ApiException(ErrorEnum.ISV_ROUTE_NO_PERMISSIONS, apiRequestContext.getLocale());
|
||||
}
|
||||
@@ -255,7 +254,7 @@ public class ApiValidator implements Validator {
|
||||
apiRequest.takeNameVersion(), apiConfig.getSignName());
|
||||
}
|
||||
// ISV上传的公钥
|
||||
String publicKey = secretManager.getIsvPublicKey(isv.getAppId());
|
||||
String publicKey = secretManager.getIsvPublicKey(isv.getId());
|
||||
if (ObjectUtils.isEmpty(publicKey)) {
|
||||
throw new ApiException(ErrorEnum.ISV_MISSING_SIGNATURE_CONFIG, apiRequestContext.getLocale(),
|
||||
apiRequest.takeNameVersion());
|
||||
|
@@ -12,7 +12,7 @@ import com.gitee.sop.gateway.service.validate.Signer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.util.Map;
|
||||
@Component
|
||||
public class AlipaySigner implements Signer {
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
private ApiConfig apiConfig;
|
||||
|
||||
@Override
|
||||
|
@@ -3,6 +3,7 @@ package com.gitee.sop.gateway.util;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@@ -26,4 +27,11 @@ public class JsonUtil {
|
||||
return JSON.parseObject(value, clazz);
|
||||
}
|
||||
|
||||
public static <T> List<T> parseArray(String value, Class<T> clazz) {
|
||||
if (Objects.equals(value, "null") || ObjectUtils.isEmpty(value)) {
|
||||
return null;
|
||||
}
|
||||
return JSON.parseArray(value, clazz);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -2,12 +2,8 @@ dubbo.registry.address=nacos://localhost:8848
|
||||
|
||||
mybatis.print-sql=true
|
||||
|
||||
# api manager,local/redis
|
||||
gateway.manager.api=redis
|
||||
# isv manager,local/redis
|
||||
gateway.manager.isv=redis
|
||||
# secret manger,local/redis
|
||||
gateway.manager.secret=redis
|
||||
# manager cache type, local/redis
|
||||
gateway.manager.cache-type=redis
|
||||
|
||||
# mysql config
|
||||
mysql.host=127.0.0.1:3306
|
||||
|
@@ -2,28 +2,32 @@ spring.profiles.active=dev
|
||||
spring.application.name=sop-index
|
||||
server.port=8081
|
||||
|
||||
####### index config #######
|
||||
####### gateway config #######
|
||||
# request entry path
|
||||
gateway.path=/api
|
||||
# manager cache type, local/redis
|
||||
gateway.manager.cache-type=local
|
||||
# api manager,local/redis
|
||||
gateway.manager.api=local
|
||||
gateway.manager.api=${gateway.manager.cache-type}
|
||||
# isv manager,local/redis
|
||||
gateway.manager.isv=local
|
||||
gateway.manager.isv=${gateway.manager.cache-type}
|
||||
# secret manger,local/redis
|
||||
gateway.manager.secret=local
|
||||
gateway.manager.secret=${gateway.manager.cache-type}
|
||||
# isv api permission manager,local/redis
|
||||
gateway.manager.isv-api-perm=${gateway.manager.cache-type}
|
||||
|
||||
####### parameter name config #######
|
||||
api.param.app-id-name=app_id
|
||||
api.param.api-name=method
|
||||
api.param.format-name=format
|
||||
api.param.charset-name=charset
|
||||
api.param.sign-type-name=sign_type
|
||||
api.param.sign-name=sign
|
||||
api.param.timestamp-name=timestamp
|
||||
api.param.version-name=version
|
||||
api.param.notify-url-name=notify_url
|
||||
api.param.app-auth-token-name=app_auth_token
|
||||
api.param.biz-content-name=biz_content
|
||||
api.app-id-name=app_id
|
||||
api.api-name=method
|
||||
api.format-name=format
|
||||
api.charset-name=charset
|
||||
api.sign-type-name=sign_type
|
||||
api.sign-name=sign
|
||||
api.timestamp-name=timestamp
|
||||
api.version-name=version
|
||||
api.notify-url-name=notify_url
|
||||
api.app-auth-token-name=app_auth_token
|
||||
api.biz-content-name=biz_content
|
||||
|
||||
####### other config #######
|
||||
# api request timeout
|
||||
@@ -81,9 +85,10 @@ mybatis.fill.com.gitee.fastmybatis.core.support.LocalDateTimeFillInsert=add_time
|
||||
mybatis.fill.com.gitee.fastmybatis.core.support.LocalDateTimeFillUpdate=update_time
|
||||
# mybatis config file
|
||||
mybatis.config-location=classpath:mybatis/mybatisConfig.xml
|
||||
|
||||
# print sql, true/false
|
||||
mybatis.print-sql=false
|
||||
|
||||
# print SQL
|
||||
logging.level.com.gitee.sop.gateway.dao=error
|
||||
logging.level.com.gitee.fastmybatis=info
|
||||
mybatis.print-sql=false
|
||||
|
||||
|
Reference in New Issue
Block a user