Commit d7a480a1 by yuwei

项目初始化

parent c45748a3
package cn.datax.common.utils; package cn.datax.common.utils;
import cn.datax.common.core.DataUser; import cn.datax.common.core.DataUser;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import java.util.Optional;
public class SecurityUtil { public class SecurityUtil {
/** /**
...@@ -13,11 +12,14 @@ public class SecurityUtil { ...@@ -13,11 +12,14 @@ public class SecurityUtil {
* @return user * @return user
*/ */
public static DataUser getDataUser() { public static DataUser getDataUser() {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null) {
Object principal = authentication.getPrincipal();
if (principal instanceof DataUser) { if (principal instanceof DataUser) {
DataUser user = (DataUser) principal; DataUser user = (DataUser) principal;
return user; return user;
} }
}
return null; return null;
} }
...@@ -27,9 +29,8 @@ public class SecurityUtil { ...@@ -27,9 +29,8 @@ public class SecurityUtil {
* @return id * @return id
*/ */
public static String getUserId() { public static String getUserId() {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); DataUser user = getDataUser();
if (principal instanceof DataUser) { if (user != null){
DataUser user = (DataUser) principal;
return user.getId(); return user.getId();
} }
return null; return null;
...@@ -41,9 +42,8 @@ public class SecurityUtil { ...@@ -41,9 +42,8 @@ public class SecurityUtil {
* @return id * @return id
*/ */
public static String getUserDeptId() { public static String getUserDeptId() {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); DataUser user = getDataUser();
if (principal instanceof DataUser) { if (user != null){
DataUser user = (DataUser) principal;
return user.getDept(); return user.getDept();
} }
return null; return null;
...@@ -55,9 +55,8 @@ public class SecurityUtil { ...@@ -55,9 +55,8 @@ public class SecurityUtil {
* @return username * @return username
*/ */
public static String getUserName() { public static String getUserName() {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); DataUser user = getDataUser();
if (principal instanceof DataUser) { if (user != null){
DataUser user = (DataUser) principal;
return user.getUsername(); return user.getUsername();
} }
return null; return null;
......
...@@ -24,10 +24,5 @@ ...@@ -24,10 +24,5 @@
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId> <artifactId>commons-pool2</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>${redisson.version}</version>
</dependency>
</dependencies> </dependencies>
</project> </project>
package cn.datax.common.redis.annotation;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RedisCacheAop {
// 缓存名
String cacheName() default "";
// 过期时间(秒) time要大于0 如果time小于等于0 将设置无限期
long expire() default -1;
// 缓存反序列化获取的对象
Class clazz() default Object.class;
// 序列化后的对象是否是数组 比如 List<Object>
boolean isArray() default false;
}
package cn.datax.common.redis.aspectj;
import cn.datax.common.redis.annotation.RedisCacheAop;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Aspect
@Slf4j
public class RedisCacheAspect {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private ObjectMapper objectMapper;
/**
* 分隔符 生成key 格式为 类全类名|方法名|参数所属类全类名
*/
private static final String DELIMITER = ":";
/**
* Service层切点 使用到了我们定义的 RedisCacheAspect 作为切点表达式。
* 而且我们可以看出此表达式基于 annotation。
* 并且用于内建属性为查询的方法之上
*/
@Pointcut("@annotation(cn.datax.common.redis.annotation.RedisCacheAop)")
public void redisCacheAspect() {
}
/**
* Around 手动控制调用核心业务逻辑,以及调用前和调用后的处理,
* <p>
* 注意:当核心业务抛异常后,立即退出,转向AfterAdvice 执行完AfterAdvice,再转到ThrowingAdvice
*/
@Around(value = "redisCacheAspect()")
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
// 得到类名、方法名和参数
String clazzName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
// 根据类名、方法名和参数生成Key
log.info("key参数: " + clazzName + "." + methodName);
String key = getKey(clazzName, methodName, args);
log.info("生成key: " + key);
// 得到被代理的方法
Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
String cacheName = method.getAnnotation(RedisCacheAop.class).cacheName();
long expire = method.getAnnotation(RedisCacheAop.class).expire();
Class objectType = method.getAnnotation(RedisCacheAop.class).clazz();
boolean isArray = method.getAnnotation(RedisCacheAop.class).isArray();
// 检查Redis中是否有缓存
String value = (String) redisTemplate.opsForValue().get(key + DELIMITER + cacheName);
// result是方法的最终返回结果
Object result = null;
try {
if (null == value) {
log.info("缓存未命中");
// 调用数据库查询方法
result = joinPoint.proceed(args);
// 结果放入缓存
if (expire > 0) {
redisTemplate.opsForValue().set(key + DELIMITER + cacheName, objectMapper.writeValueAsString(result), expire, TimeUnit.SECONDS);
} else {
redisTemplate.opsForValue().set(key + DELIMITER + cacheName, objectMapper.writeValueAsString(result));
}
} else {
/**
* 可以直接针对mapper进行缓存,如果mapper查询返回的List<Objec> 需要isArray 为true 否则转换异常
*/
if (isArray){
JavaType javaType = objectMapper.getTypeFactory().constructCollectionType(List.class, objectType);
return objectMapper.readValue(value, javaType);
}else {
return objectMapper.readValue(value, objectType);
}
}
} catch (Throwable e) {
log.error("程序异常", e.getMessage());
throw e;
}
return result;
}
/**
* 根据类名、方法名和参数生成Key
* @param clazzName
* @param methodName
* @param args
* @return key格式:全类名:方法名:参数类型
*/
private String getKey(String clazzName, String methodName, Object[] args) {
StringBuilder key = new StringBuilder(clazzName);
key.append(DELIMITER);
key.append(methodName);
key.append(DELIMITER);
key.append(Arrays.stream(args).map(x -> x.toString()).collect(Collectors.joining(DELIMITER)));
return key.toString();
}
}
package cn.datax.common.redis.config;
import cn.datax.common.redis.service.impl.RedissonLocker;
import cn.datax.common.redis.utils.LockUtil;
import lombok.AllArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
@EnableConfigurationProperties({RedisProperties.class})
@AllArgsConstructor
public class RedissonConfig {
private RedisProperties redisProperties;
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
if(redisProperties.getCluster() != null){
// 集群模式配置
config.useClusterServers()
.addNodeAddress(redisProperties.getCluster().getNodes().stream().toArray(String[]::new))
.setPassword(StringUtils.isBlank(redisProperties.getPassword()) ? null : redisProperties.getPassword());
}else if(redisProperties.getSentinel() != null){
//添加哨兵配置
config.useMasterSlaveServers().setMasterAddress(redisProperties.getSentinel().getMaster())
.addSlaveAddress(redisProperties.getSentinel().getNodes().stream().toArray(String[]::new))
.setPassword(StringUtils.isBlank(redisProperties.getPassword()) ? null : redisProperties.getPassword());
}else {
//单节点
config.useSingleServer().setAddress("redis://" + redisProperties.getHost() + ":" + redisProperties.getPort())
.setPassword(StringUtils.isBlank(redisProperties.getPassword()) ? null : redisProperties.getPassword());
}
return Redisson.create(config);
}
@Bean
public RedissonLocker redissonLocker(RedissonClient redissonClient) {
RedissonLocker locker = new RedissonLocker(redissonClient);
// 设置LockUtil的锁处理对象
LockUtil.setLocker(locker);
return locker;
}
}
package cn.datax.common.redis.service;
import org.redisson.api.RLock;
import java.util.concurrent.TimeUnit;
/**
* 锁接口
*/
public interface Locker {
/**
* 获取锁,如果锁不可用,则当前线程处于休眠状态,直到获得锁为止。
*
* @param lockKey
*/
RLock lock(String lockKey);
/**
* 释放锁
*
* @param lockKey
*/
RLock unlock(String lockKey);
/**
* 获取锁,如果锁不可用,则当前线程处于休眠状态,直到获得锁为止。如果获取到锁后,执行结束后解锁或达到超时时间后会自动释放锁
*
* @param lockKey
* @param timeout
*/
RLock lock(String lockKey, int timeout);
/**
* 获取锁,如果锁不可用,则当前线程处于休眠状态,直到获得锁为止。如果获取到锁后,执行结束后解锁或达到超时时间后会自动释放锁
*
* @param lockKey
* @param unit
* @param timeout
*/
RLock lock(String lockKey, TimeUnit unit, int timeout);
/**
* 尝试获取锁,获取到立即返回true,未获取到立即返回false
*
* @param lockKey
* @return
*/
boolean tryLock(String lockKey);
/**
* 尝试获取锁,在等待时间内获取到锁则返回true,否则返回false,如果获取到锁,则要么执行完后程序释放锁,
* 要么在给定的超时时间leaseTime后释放锁
*
* @param lockKey
* @param waitTime
* @param leaseTime
* @param unit
* @return
*/
boolean tryLock(String lockKey, long waitTime, long leaseTime, TimeUnit unit);
/**
* 锁是否被任意一个线程锁持有
*
* @param lockKey
* @return
*/
boolean isLocked(String lockKey);
}
package cn.datax.common.redis.service.impl;
import cn.datax.common.redis.service.Locker;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import java.util.concurrent.TimeUnit;
/**
* 基于Redisson的分布式锁
*/
public class RedissonLocker implements Locker {
private RedissonClient redissonClient;
public RedissonLocker(RedissonClient redissonClient) {
super();
this.redissonClient = redissonClient;
}
public void setRedissonClient(RedissonClient redissonClient) {
this.redissonClient = redissonClient;
}
@Override
public RLock lock(String lockKey) {
RLock lock = redissonClient.getLock(lockKey);
lock.lock();
return lock;
}
@Override
public RLock unlock(String lockKey) {
RLock lock = redissonClient.getLock(lockKey);
lock.unlock();
return lock;
}
@Override
public RLock lock(String lockKey, int leaseTime) {
RLock lock = redissonClient.getLock(lockKey);
lock.lock(leaseTime, TimeUnit.SECONDS);
return lock;
}
@Override
public RLock lock(String lockKey, TimeUnit unit, int timeout) {
RLock lock = redissonClient.getLock(lockKey);
lock.lock(timeout, unit);
return lock;
}
@Override
public boolean tryLock(String lockKey) {
RLock lock = redissonClient.getLock(lockKey);
return lock.tryLock();
}
@Override
public boolean tryLock(String lockKey, long waitTime, long leaseTime, TimeUnit unit) {
RLock lock = redissonClient.getLock(lockKey);
try {
return lock.tryLock(waitTime, leaseTime, unit);
} catch (InterruptedException e) {
return false;
}
}
@Override
public boolean isLocked(String lockKey) {
RLock lock = redissonClient.getLock(lockKey);
return lock.isLocked();
}
}
package cn.datax.common.redis.utils;
import cn.datax.common.redis.service.Locker;
import java.util.concurrent.TimeUnit;
/**
* redis分布式锁工具类
*/
public final class LockUtil {
private static Locker locker;
/**
* 设置工具类使用的locker
*
* @param locker
*/
public static void setLocker(Locker locker) {
LockUtil.locker = locker;
}
/**
* 获取锁
*
* @param lockKey
*/
public static void lock(String lockKey) {
locker.lock(lockKey);
}
/**
* 释放锁
*
* @param lockKey
*/
public static void unlock(String lockKey) {
locker.unlock(lockKey);
}
/**
* 获取锁,超时释放
*
* @param lockKey
* @param timeout
*/
public static void lock(String lockKey, int timeout) {
locker.lock(lockKey, timeout);
}
/**
* 获取锁,超时释放,指定时间单位
*
* @param lockKey
* @param unit
* @param timeout
*/
public static void lock(String lockKey, TimeUnit unit, int timeout) {
locker.lock(lockKey, unit, timeout);
}
/**
* 尝试获取锁,获取到立即返回true,获取失败立即返回false
*
* @param lockKey
* @return
*/
public static boolean tryLock(String lockKey) {
return locker.tryLock(lockKey);
}
/**
* 尝试获取锁,在给定的waitTime时间内尝试,获取到返回true,获取失败返回false,获取到后再给定的leaseTime时间超时释放
*
* @param lockKey
* @param waitTime
* @param leaseTime
* @param unit
* @return
* @throws InterruptedException
*/
public static boolean tryLock(String lockKey, long waitTime, long leaseTime, TimeUnit unit) {
return locker.tryLock(lockKey, waitTime, leaseTime, unit);
}
/**
* 锁释放被任意一个线程持有
*
* @param lockKey
* @return
*/
public static boolean isLocked(String lockKey) {
return locker.isLocked(lockKey);
}
}
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.datax.common.redis.config.RedisConfig,\ cn.datax.common.redis.config.RedisConfig
cn.datax.common.redis.aspectj.RedisCacheAspect,\
cn.datax.common.redis.config.RedissonConfig
...@@ -30,4 +30,7 @@ public class ResParam implements Serializable { ...@@ -30,4 +30,7 @@ public class ResParam implements Serializable {
@ApiModelProperty(value = "示例值") @ApiModelProperty(value = "示例值")
@NotBlank(message = "示例值不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) @NotBlank(message = "示例值不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class})
private String exampleValue; private String exampleValue;
@ApiModelProperty(value = "字段别名")
private String fieldAliasName;
} }
package cn.datax.service.data.market.mapping.config; package cn.datax.service.data.market.mapping.config;
import cn.datax.common.core.DataConstant; import cn.datax.common.core.DataConstant;
import cn.datax.common.core.R;
import cn.datax.common.database.core.PageResult;
import cn.datax.common.utils.IPUtil; import cn.datax.common.utils.IPUtil;
import cn.datax.common.utils.MD5Util; import cn.datax.common.utils.MD5Util;
import cn.datax.common.utils.RequestHolder; import cn.datax.common.utils.RequestHolder;
import cn.datax.service.data.market.api.dto.ApiLogDto; import cn.datax.service.data.market.api.dto.ApiLogDto;
import cn.datax.service.data.market.mapping.async.AsyncTask; import cn.datax.service.data.market.mapping.async.AsyncTask;
import cn.hutool.core.map.MapUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.ProceedingJoinPoint;
...@@ -18,6 +23,8 @@ import org.springframework.stereotype.Component; ...@@ -18,6 +23,8 @@ import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
@Slf4j @Slf4j
@Aspect @Aspect
...@@ -40,10 +47,14 @@ public class ApiLogAspect { ...@@ -40,10 +47,14 @@ public class ApiLogAspect {
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
Object result = joinPoint.proceed(); Object result = joinPoint.proceed();
long endTime = System.currentTimeMillis(); long endTime = System.currentTimeMillis();
System.out.println("endTime:" + endTime); ApiLogDto log = getLog();
// ApiLogDto log = getLog(); log.setTime(endTime - startTime);
// log.setTime(endTime - startTime); if (result instanceof R) {
// handleLog(joinPoint, log); if (((R) result).getData() instanceof PageResult) {
log.setCallerSize(((PageResult) ((R) result).getData()).getData().size());
}
}
handleLog(joinPoint, log);
return result; return result;
} }
...@@ -56,10 +67,10 @@ public class ApiLogAspect { ...@@ -56,10 +67,10 @@ public class ApiLogAspect {
@AfterThrowing(value = "logPointCut()", throwing = "e") @AfterThrowing(value = "logPointCut()", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Exception e) { public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
log.error("出错{}", e.getMessage()); log.error("出错{}", e.getMessage());
// ApiLogDto log = getLog(); ApiLogDto log = getLog();
// log.setStatus(DataConstant.EnableState.DISABLE.getKey()); log.setStatus(DataConstant.EnableState.DISABLE.getKey());
// log.setMsg(e.getMessage()); log.setMsg(e.getMessage());
// handleLog(joinPoint, log); handleLog(joinPoint, log);
} }
private ApiLogDto getLog() { private ApiLogDto getLog() {
...@@ -67,9 +78,8 @@ public class ApiLogAspect { ...@@ -67,9 +78,8 @@ public class ApiLogAspect {
HttpServletRequest request = RequestHolder.getHttpServletRequest(); HttpServletRequest request = RequestHolder.getHttpServletRequest();
String apiKey = request.getHeader("api_key"); String apiKey = request.getHeader("api_key");
String secretKey = request.getHeader("secret_key"); String secretKey = request.getHeader("secret_key");
MD5Util mt = null;
try { try {
mt = MD5Util.getInstance(); MD5Util mt = MD5Util.getInstance();
String apiId = mt.decode(apiKey); String apiId = mt.decode(apiKey);
String userId = mt.decode(secretKey); String userId = mt.decode(secretKey);
log.setCallerId(userId); log.setCallerId(userId);
...@@ -85,6 +95,22 @@ public class ApiLogAspect { ...@@ -85,6 +95,22 @@ public class ApiLogAspect {
} }
protected void handleLog(final JoinPoint joinPoint, ApiLogDto log) { protected void handleLog(final JoinPoint joinPoint, ApiLogDto log) {
// asyncTask.doTask(log); Map<String, Object> pathVariables = (Map<String, Object>) joinPoint.getArgs()[2];
Map<String, Object> requestParams = (Map<String, Object>) joinPoint.getArgs()[3];
Map<String, Object> requestBodys = (Map<String, Object>) joinPoint.getArgs()[4];
Map<String, Object> params = new HashMap<>();
if (MapUtil.isNotEmpty(pathVariables)) {
params.putAll(pathVariables);
}
if (MapUtil.isNotEmpty(requestParams)) {
params.putAll(requestParams);
}
if (MapUtil.isNotEmpty(requestBodys)) {
params.putAll(requestBodys);
}
try {
log.setCallerParams(new ObjectMapper().writeValueAsString(params));
} catch (JsonProcessingException e) {}
asyncTask.doTask(log);
} }
} }
package cn.datax.service.data.market.mapping.config; package cn.datax.service.data.market.mapping.config;
import cn.datax.service.data.market.mapping.async.AsyncTask;
import cn.datax.service.data.market.mapping.handler.MappingHandlerMapping; import cn.datax.service.data.market.mapping.handler.MappingHandlerMapping;
import cn.datax.service.data.market.mapping.handler.RequestHandler; import cn.datax.service.data.market.mapping.handler.RequestHandler;
import cn.datax.service.data.market.mapping.handler.RequestInterceptor; import cn.datax.service.data.market.mapping.handler.RequestInterceptor;
...@@ -18,19 +17,17 @@ public class ApiMappingConfig { ...@@ -18,19 +17,17 @@ public class ApiMappingConfig {
public MappingHandlerMapping mappingHandlerMapping(RequestMappingHandlerMapping requestMappingHandlerMapping, public MappingHandlerMapping mappingHandlerMapping(RequestMappingHandlerMapping requestMappingHandlerMapping,
ApiMappingEngine apiMappingEngine, ApiMappingEngine apiMappingEngine,
RedisTemplate redisTemplate, RedisTemplate redisTemplate,
ObjectMapper objectMapper, ObjectMapper objectMapper) {
AsyncTask asyncTask) {
MappingHandlerMapping mappingHandlerMapping = new MappingHandlerMapping(); MappingHandlerMapping mappingHandlerMapping = new MappingHandlerMapping();
mappingHandlerMapping.setHandler(requestHandler(apiMappingEngine, redisTemplate, objectMapper, asyncTask)); mappingHandlerMapping.setHandler(requestHandler(apiMappingEngine, redisTemplate, objectMapper));
mappingHandlerMapping.setRequestMappingHandlerMapping(requestMappingHandlerMapping); mappingHandlerMapping.setRequestMappingHandlerMapping(requestMappingHandlerMapping);
return mappingHandlerMapping; return mappingHandlerMapping;
} }
@Bean @Bean
public RequestHandler requestHandler(ApiMappingEngine apiMappingEngine, RedisTemplate redisTemplate, ObjectMapper objectMapper, AsyncTask asyncTask) { public RequestHandler requestHandler(ApiMappingEngine apiMappingEngine, RedisTemplate redisTemplate, ObjectMapper objectMapper) {
RequestHandler handler = new RequestHandler(); RequestHandler handler = new RequestHandler();
handler.setApiMappingEngine(apiMappingEngine); handler.setApiMappingEngine(apiMappingEngine);
handler.setAsyncTask(asyncTask);
handler.setObjectMapper(objectMapper); handler.setObjectMapper(objectMapper);
handler.setRequestInterceptor(new RequestInterceptor(redisTemplate)); handler.setRequestInterceptor(new RequestInterceptor(redisTemplate));
return handler; return handler;
......
package cn.datax.service.data.market.mapping.handler; package cn.datax.service.data.market.mapping.handler;
import cn.datax.common.core.DataConstant;
import cn.datax.common.core.R; import cn.datax.common.core.R;
import cn.datax.common.database.core.PageResult; import cn.datax.common.database.core.PageResult;
import cn.datax.common.utils.ThrowableUtil;
import cn.datax.service.data.market.api.dto.ApiLogDto;
import cn.datax.service.data.market.api.entity.DataApiEntity; import cn.datax.service.data.market.api.entity.DataApiEntity;
import cn.datax.service.data.market.mapping.async.AsyncTask;
import cn.datax.service.data.market.mapping.service.impl.ApiMappingEngine; import cn.datax.service.data.market.mapping.service.impl.ApiMappingEngine;
import cn.datax.service.data.market.mapping.utils.ThreadUtil;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
...@@ -31,8 +27,6 @@ public class RequestHandler { ...@@ -31,8 +27,6 @@ public class RequestHandler {
private ObjectMapper objectMapper; private ObjectMapper objectMapper;
private AsyncTask asyncTask;
public void setRequestInterceptor(RequestInterceptor requestInterceptor) { public void setRequestInterceptor(RequestInterceptor requestInterceptor) {
this.requestInterceptor = requestInterceptor; this.requestInterceptor = requestInterceptor;
} }
...@@ -45,17 +39,12 @@ public class RequestHandler { ...@@ -45,17 +39,12 @@ public class RequestHandler {
this.objectMapper = objectMapper; this.objectMapper = objectMapper;
} }
public void setAsyncTask(AsyncTask asyncTask) { @SneakyThrows
this.asyncTask = asyncTask;
}
@ResponseBody @ResponseBody
public Object invoke(HttpServletRequest request, HttpServletResponse response, public Object invoke(HttpServletRequest request, HttpServletResponse response,
@PathVariable(required = false) Map<String, Object> pathVariables, @PathVariable(required = false) Map<String, Object> pathVariables,
@RequestParam(required = false) Map<String, Object> requestParams, @RequestParam(required = false) Map<String, Object> requestParams,
@RequestBody(required = false) Map<String, Object> requestBodys) { @RequestBody(required = false) Map<String, Object> requestBodys) {
try {
long start = System.currentTimeMillis();
DataApiEntity api; DataApiEntity api;
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();
if (MapUtil.isNotEmpty(pathVariables)) { if (MapUtil.isNotEmpty(pathVariables)) {
...@@ -71,31 +60,13 @@ public class RequestHandler { ...@@ -71,31 +60,13 @@ public class RequestHandler {
params.putAll(requestBodys); params.putAll(requestBodys);
} }
api = MappingHandlerMapping.getMappingApiInfo(request); api = MappingHandlerMapping.getMappingApiInfo(request);
// 序列化出错 // 序列化
api = objectMapper.readValue(objectMapper.writeValueAsString(api), DataApiEntity.class); api = objectMapper.readValue(objectMapper.writeValueAsString(api), DataApiEntity.class);
// 执行前置拦截器 // 执行前置拦截器
Object obj = requestInterceptor.preHandle(request, response, api, params); requestInterceptor.preHandle(request, response, api, params);
if (obj != null) {
return obj;
}
PageResult<Map<String, Object>> value = apiMappingEngine.execute(api, params); PageResult<Map<String, Object>> value = apiMappingEngine.execute(api, params);
// 执行后置拦截器 // 执行后置拦截器
requestInterceptor.postHandle(request, response, api, params, value); requestInterceptor.postHandle(request, response, api, params, value);
ThreadUtil.getInstance().get().setCallerSize(value.getData().size());
ThreadUtil.getInstance().get().setTime(System.currentTimeMillis() - start);
return R.ok().setData(value); return R.ok().setData(value);
} catch (Exception e) {
log.error("全局异常信息ex={}, StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e));
ThreadUtil.getInstance().get().setStatus(DataConstant.EnableState.DISABLE.getKey());
ThreadUtil.getInstance().get().setMsg(e.getMessage());
return R.error(e.getMessage());
} finally {
ApiLogDto apiLogDto = ThreadUtil.getInstance().get();
log.info("ApiLogDto信息={}", apiLogDto);
if (apiLogDto != null) {
asyncTask.doTask(apiLogDto);
}
ThreadUtil.getInstance().remove();
}
} }
} }
package cn.datax.service.data.market.mapping.handler; package cn.datax.service.data.market.mapping.handler;
import cn.datax.common.core.DataConstant; import cn.datax.common.core.DataConstant;
import cn.datax.common.core.R; import cn.datax.common.exception.DataException;
import cn.datax.common.utils.IPUtil; import cn.datax.common.utils.IPUtil;
import cn.datax.common.utils.MD5Util; import cn.datax.common.utils.MD5Util;
import cn.datax.service.data.market.api.dto.ApiLogDto; import cn.datax.service.data.market.api.dto.ApiLogDto;
...@@ -39,37 +39,23 @@ public class RequestInterceptor { ...@@ -39,37 +39,23 @@ public class RequestInterceptor {
* @return 当返回对象时,直接将此对象返回到页面,返回null时,继续执行后续操作 * @return 当返回对象时,直接将此对象返回到页面,返回null时,继续执行后续操作
* @throws Exception * @throws Exception
*/ */
public Object preHandle(HttpServletRequest request, HttpServletResponse response, DataApiEntity api, Map<String, Object> params) throws Exception { public void preHandle(HttpServletRequest request, HttpServletResponse response, DataApiEntity api, Map<String, Object> params) throws Exception {
System.out.println("************ApiInterceptor preHandle executed**********"); System.out.println("************ApiInterceptor preHandle executed**********");
String uri = request.getRequestURI(); String uri = request.getRequestURI();
log.info("getRequestURI的值:" + uri); log.info("getRequestURI的值:" + uri);
String ipAddr = IPUtil.getIpAddr(request); String ipAddr = IPUtil.getIpAddr(request);
log.info("ipAddr的值:" + ipAddr); log.info("ipAddr的值:" + ipAddr);
// 记录日志
ApiLogDto log = new ApiLogDto();
log.setCallerIp(ipAddr);
log.setCallerUrl(uri);
log.setCallerParams(new ObjectMapper().writeValueAsString(params));
log.setCallerDate(LocalDateTime.now());
log.setStatus(DataConstant.EnableState.ENABLE.getKey());
ThreadUtil.getInstance().set(log);
// 密钥校验 // 密钥校验
String apiKey = request.getHeader("api_key"); String apiKey = request.getHeader("api_key");
String secretKey = request.getHeader("secret_key"); String secretKey = request.getHeader("secret_key");
if (StrUtil.isBlank(apiKey) || StrUtil.isBlank(secretKey)) { if (StrUtil.isBlank(apiKey) || StrUtil.isBlank(secretKey)) {
ThreadUtil.getInstance().get().setStatus(DataConstant.EnableState.DISABLE.getKey()); throw new DataException("api_key或secret_key空");
ThreadUtil.getInstance().get().setMsg("api_key或secret_key空");
return R.error("api_key或secret_key空");
} }
MD5Util mt = MD5Util.getInstance(); MD5Util mt = MD5Util.getInstance();
String apiId = mt.decode(apiKey); String apiId = mt.decode(apiKey);
String userId = mt.decode(secretKey); String userId = mt.decode(secretKey);
ThreadUtil.getInstance().get().setApiId(apiId);
ThreadUtil.getInstance().get().setCallerId(userId);
// 黑名单校验 // 黑名单校验
String deny = api.getDeny(); String deny = api.getDeny();
if (StrUtil.isNotBlank(deny)) { if (StrUtil.isNotBlank(deny)) {
...@@ -77,33 +63,23 @@ public class RequestInterceptor { ...@@ -77,33 +63,23 @@ public class RequestInterceptor {
if (CollUtil.isNotEmpty(denyList)) { if (CollUtil.isNotEmpty(denyList)) {
for (String ip : denyList) { for (String ip : denyList) {
if(ip.equals(ipAddr)){ if(ip.equals(ipAddr)){
ThreadUtil.getInstance().get().setStatus(DataConstant.EnableState.DISABLE.getKey()); throw new DataException(ip + "已被加入IP黑名单");
ThreadUtil.getInstance().get().setMsg("此IP已被加入API调用黑名单");
return R.error("此IP已被加入API调用黑名单");
} }
} }
} }
} }
// 参数校验 // 参数校验
if (MapUtil.isNotEmpty(params)) { if (MapUtil.isNotEmpty(params)) {
try {
api.getReqParams().stream().forEach(param -> { api.getReqParams().stream().forEach(param -> {
if (params.containsKey(param.getParamName())) { if (params.containsKey(param.getParamName())) {
// 参数类型是否正确 // 参数类型是否正确
ParamType.parse(ParamType.getParamType(param.getParamType()), params.get(param.getParamName())); ParamType.parse(ParamType.getParamType(param.getParamType()), params.get(param.getParamName()));
} }
}); });
} catch (Exception e) {
ThreadUtil.getInstance().get().setStatus(DataConstant.EnableState.DISABLE.getKey());
ThreadUtil.getInstance().get().setMsg(e.getMessage());
return R.error(e.getMessage());
}
} }
// 限流校验
String apiName = api.getApiName();
ThreadUtil.getInstance().get().setApiName(apiName);
// 限流校验
String rateLimit = api.getRateLimit(); String rateLimit = api.getRateLimit();
rateLimit = Optional.ofNullable(rateLimit).orElse(DataConstant.TrueOrFalse.TRUE.getKey()); rateLimit = Optional.ofNullable(rateLimit).orElse(DataConstant.TrueOrFalse.TRUE.getKey());
if (DataConstant.TrueOrFalse.TRUE.getKey().equals(rateLimit)) { if (DataConstant.TrueOrFalse.TRUE.getKey().equals(rateLimit)) {
...@@ -123,13 +99,9 @@ public class RequestInterceptor { ...@@ -123,13 +99,9 @@ public class RequestInterceptor {
} else if (maxTimes < times) { } else if (maxTimes < times) {
redisTemplate.opsForValue().set(key, maxTimes + 1, seconds, TimeUnit.SECONDS); redisTemplate.opsForValue().set(key, maxTimes + 1, seconds, TimeUnit.SECONDS);
} else { } else {
// 请求过于频繁 throw new DataException("API调用过于频繁");
ThreadUtil.getInstance().get().setStatus(DataConstant.EnableState.DISABLE.getKey());
ThreadUtil.getInstance().get().setMsg("API调用过于频繁");
return R.error("API调用过于频繁");
} }
} }
return null;
} }
/** /**
......
...@@ -49,8 +49,8 @@ public class ApiMappingEngine { ...@@ -49,8 +49,8 @@ public class ApiMappingEngine {
dbSchema.getUsername(), dbSchema.getPassword(), dbSchema.getPort(), dbSchema.getDbName(), dbSchema.getSid()); dbSchema.getUsername(), dbSchema.getPassword(), dbSchema.getPort(), dbSchema.getDbName(), dbSchema.getSid());
DbQuery dbQuery = dataSourceFactory.createDbQuery(dbQueryProperty); DbQuery dbQuery = dataSourceFactory.createDbQuery(dbQueryProperty);
// 参数 // 参数
Integer pageNum = (Integer) params.getOrDefault("pageNum", 1); Integer pageNum = Integer.parseInt((String) params.getOrDefault("pageNum", 1));
Integer pageSize = (Integer) params.getOrDefault("pageSize", 20); Integer pageSize = Integer.parseInt((String) params.getOrDefault("pageSize", 20));
PageUtil pageUtil = new PageUtil(pageNum, pageSize); PageUtil pageUtil = new PageUtil(pageNum, pageSize);
Integer offset = pageUtil.getOffset(); Integer offset = pageUtil.getOffset();
SqlBuilderUtil.SqlFilterResult sqlFilterResult; SqlBuilderUtil.SqlFilterResult sqlFilterResult;
...@@ -62,11 +62,9 @@ public class ApiMappingEngine { ...@@ -62,11 +62,9 @@ public class ApiMappingEngine {
} }
Map<String, Object> acceptedFilters = sqlFilterResult.getAcceptedFilters(); Map<String, Object> acceptedFilters = sqlFilterResult.getAcceptedFilters();
// 数据脱敏 // 数据脱敏
List<FieldRule> rules; List<FieldRule> rules = null;
ApiMaskEntity apiMaskEntity = apiMaskServiceFeign.getApiMaskByApiId(dataApi.getId()); ApiMaskEntity apiMaskEntity = apiMaskServiceFeign.getApiMaskByApiId(dataApi.getId());
if (apiMaskEntity == null) { if (apiMaskEntity != null) {
throw new DataException("API调用查询数据脱敏出错");
} else {
rules = apiMaskEntity.getRules(); rules = apiMaskEntity.getRules();
} }
PageResult<Map<String, Object>> pageResult; PageResult<Map<String, Object>> pageResult;
......
...@@ -69,6 +69,7 @@ export default { ...@@ -69,6 +69,7 @@ export default {
.main-container{ .main-container{
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 6px; width: 6px;
height: 6px;
} }
::-webkit-scrollbar-track-piece { ::-webkit-scrollbar-track-piece {
background: #d3dce6; background: #d3dce6;
......
...@@ -83,7 +83,7 @@ ...@@ -83,7 +83,7 @@
<el-checkbox v-model="scope.row.nullable" true-label="1" false-label="0" disabled /> <el-checkbox v-model="scope.row.nullable" true-label="1" false-label="0" disabled />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="remark" label="描述" align="center" show-overflow-tooltip /> <el-table-column prop="paramComment" label="描述" align="center" show-overflow-tooltip />
<el-table-column prop="paramType" label="参数类型" align="center" show-overflow-tooltip> <el-table-column prop="paramType" label="参数类型" align="center" show-overflow-tooltip>
<template slot-scope="scope"> <template slot-scope="scope">
<el-select v-model="scope.row.paramType" placeholder="请选择参数类型" disabled> <el-select v-model="scope.row.paramType" placeholder="请选择参数类型" disabled>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment