Commit e5d49512 by yuwei

2.0.0项目初始化

parent 5d83b6fa
package cn.datax.common.utils;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
@Slf4j
public class HttpUtil {
public static String getBodyString(HttpServletRequest request) {
StringBuffer sb = new StringBuffer();
InputStream inputStream;
BufferedReader bufferedReader;
try {
//将数据保存到数组中,每次读取的时候,都读取一遍
inputStream = request.getInputStream();
//将字节数组当做输出的目的地
//字节流转换为字符流(处理流)
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line = "";
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
} catch (Exception e) {
log.error("数据读取异常", e);
}
return sb.toString();
}
}
package cn.datax.common.utils;
import javax.servlet.http.HttpServletRequest;
import java.net.*;
import java.util.Enumeration;
public class IPUtil {
public static String getLocalIP() throws SocketException {
String localIP = null;
Enumeration allNetInterfaces = NetworkInterface.getNetworkInterfaces();
InetAddress ip = null;
while (allNetInterfaces.hasMoreElements()) {
NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
Enumeration addresses = netInterface.getInetAddresses();
while (addresses.hasMoreElements()) {
ip = (InetAddress) addresses.nextElement();
if (ip != null && ip instanceof Inet4Address) {
localIP = ip.getHostAddress();
if (!"127.0.0.1".equalsIgnoreCase(localIP)) {
return localIP;
}
}
}
}
return localIP;
}
/**
* 获取当前网络ip
* @param request
* @return
*/
public static String getIpAddr(HttpServletRequest request) {
String ipAddress = request.getHeader("x-forwarded-for");
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
//根据网卡取本机配置的IP
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
ipAddress = inet.getHostAddress();
}
}
//对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if (ipAddress != null && ipAddress.length() > 15) { //"***.***.***.***".length() = 15
if (ipAddress.indexOf(",") > 0) {
ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
}
}
return ipAddress;
}
}
...@@ -21,10 +21,34 @@ public class MD5Util { ...@@ -21,10 +21,34 @@ public class MD5Util {
private Key key = null; private Key key = null;
private String charset = "UTF-8"; private String charset = "UTF-8";
private static volatile MD5Util instance;
/**
* 构造函数
* @throws Exception
*/
private MD5Util() throws Exception {
DESKeySpec keySpec = new DESKeySpec(deSkey.getBytes(this.charset));// 设置密钥参数
iv = new IvParameterSpec(DESIV);// 设置向量
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");// 获得密钥工厂
key = keyFactory.generateSecret(keySpec);// 得到密钥对象
}
public static MD5Util getInstance() throws Exception {
if(instance == null) {
synchronized (MD5Util.class) {
if(instance == null) {
instance = new MD5Util();
}
}
}
return instance;
}
public static void main(String[] args) { public static void main(String[] args) {
try { try {
String value = "1214826565321543682"; String value = "1214826565321543682";
MD5Util mt= new MD5Util(); MD5Util mt = new MD5Util();
System.out.println("加密前的字符:" + value); System.out.println("加密前的字符:" + value);
System.out.println("加密后的字符:" + mt.encode(value)); System.out.println("加密后的字符:" + mt.encode(value));
System.out.println("解密后的字符:" + mt.decode(mt.encode(value))); System.out.println("解密后的字符:" + mt.decode(mt.encode(value)));
...@@ -35,17 +59,6 @@ public class MD5Util { ...@@ -35,17 +59,6 @@ public class MD5Util {
} }
/** /**
* 构造函数
* @throws Exception
*/
public MD5Util() throws Exception {
DESKeySpec keySpec = new DESKeySpec(deSkey.getBytes(this.charset));// 设置密钥参数
iv = new IvParameterSpec(DESIV);// 设置向量
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");// 获得密钥工厂
key = keyFactory.generateSecret(keySpec);// 得到密钥对象
}
/**
* 加密 * 加密
* @param data * @param data
* @return * @return
......
package cn.datax.common.utils; package cn.datax.common.utils;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSON;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
...@@ -20,7 +20,7 @@ public class ResponseUtil { ...@@ -20,7 +20,7 @@ public class ResponseUtil {
int status, Object value) throws IOException { int status, Object value) throws IOException {
response.setContentType(contentType); response.setContentType(contentType);
response.setStatus(status); response.setStatus(status);
response.getOutputStream().write(JSONObject.toJSONString(value).getBytes()); response.getOutputStream().write(JSON.toJSONString(value).getBytes());
} }
} }
...@@ -55,6 +55,15 @@ hystrix: ...@@ -55,6 +55,15 @@ hystrix:
strategy: SEMAPHORE strategy: SEMAPHORE
thread: thread:
timeoutInMilliseconds: 5000 #断路器超时时间,默认1000ms timeoutInMilliseconds: 5000 #断路器超时时间,默认1000ms
dataApiHystrix: #api调用方法的超时时间 60s
fallback:
enabled: true
execution:
timeout:
enabled: true
isolation:
thread:
timeoutInMilliseconds: 60000 #断路器超时时间,默认1000ms
shareSecurityContext: true shareSecurityContext: true
#请求处理的超时时间 #请求处理的超时时间
......
...@@ -33,7 +33,7 @@ spring: ...@@ -33,7 +33,7 @@ spring:
filters: filters:
- name: Hystrix - name: Hystrix
args: args:
name: systemFallback name: systemHystrix
fallbackUri: forward:/fallback fallbackUri: forward:/fallback
# 邮件中心 # 邮件中心
- id: datax-service-email - id: datax-service-email
...@@ -43,7 +43,7 @@ spring: ...@@ -43,7 +43,7 @@ spring:
filters: filters:
- name: Hystrix - name: Hystrix
args: args:
name: emailFallback name: emailHystrix
fallbackUri: forward:/fallback fallbackUri: forward:/fallback
# 文件中心 # 文件中心
- id: datax-service-file - id: datax-service-file
...@@ -53,7 +53,7 @@ spring: ...@@ -53,7 +53,7 @@ spring:
filters: filters:
- name: Hystrix - name: Hystrix
args: args:
name: fileFallback name: fileHystrix
fallbackUri: forward:/fallback fallbackUri: forward:/fallback
# 数据工厂中心 # 数据工厂中心
- id: datax-service-data-factory - id: datax-service-data-factory
...@@ -64,7 +64,7 @@ spring: ...@@ -64,7 +64,7 @@ spring:
- StripPrefix=1 - StripPrefix=1
- name: Hystrix - name: Hystrix
args: args:
name: dataFactoryFallback name: dataFactoryHystrix
fallbackUri: forward:/fallback fallbackUri: forward:/fallback
# 数据工厂中心 # 数据工厂中心
- id: datax-service-data-market - id: datax-service-data-market
...@@ -75,10 +75,15 @@ spring: ...@@ -75,10 +75,15 @@ spring:
- StripPrefix=1 - StripPrefix=1
- name: Hystrix - name: Hystrix
args: args:
name: dataMarketFallback name: dataMarketHystrix
fallbackUri: forward:/fallback fallbackUri: forward:/fallback
# 即时通讯中心 - id: datax-service-data-market
- id: datax-websocket-server uri: lb://datax-service-data-market
uri: ws://localhost:9876
predicates: predicates:
- Path=/websocket/** - Path=/data/api/**
\ No newline at end of file filters:
- StripPrefix=1
- name: Hystrix
args:
name: dataApiHystrix
fallbackUri: forward:/fallback
\ No newline at end of file
package cn.datax.service.data.market.api.dto;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
public class ApiLogDto implements Serializable {
private static final long serialVersionUID=1L;
private String id;
private String apiId;
private String apiName;
private String callerId;
private String callerIp;
private String callerUrl;
private String callerParams;
private LocalDateTime callerDate;
private Long time;
private String msg;
private Integer status;
}
...@@ -8,6 +8,7 @@ import lombok.Data; ...@@ -8,6 +8,7 @@ import lombok.Data;
import javax.validation.Valid; import javax.validation.Valid;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
...@@ -46,6 +47,15 @@ public class DataApiDto implements Serializable { ...@@ -46,6 +47,15 @@ public class DataApiDto 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 resType; private String resType;
@ApiModelProperty(value = "IP黑名单多个用,隔开")
private String deny;
@ApiModelProperty(value = "是否限流:0:否,1:是")
@NotNull(message = "是否限流不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class})
private Integer rateLimit;
@ApiModelProperty(value = "请求次数默认5次")
private Integer times = 5;
@ApiModelProperty(value = "请求时间范围默认60秒")
private Integer seconds = 60;
@ApiModelProperty(value = "执行配置") @ApiModelProperty(value = "执行配置")
@Valid @Valid
private ExecuteConfig executeConfig; private ExecuteConfig executeConfig;
......
package cn.datax.service.data.market.api.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@Accessors(chain = true)
@TableName("data_api_log")
public class ApiLogEntity implements Serializable {
private static final long serialVersionUID=1L;
/**
* 主键
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* 调用api
*/
private String apiId;
/**
* api名称
*/
private String apiName;
/**
* 调用者id
*/
private String callerId;
/**
* 调用者ip
*/
private String callerIp;
/**
* 调用url
*/
private String callerUrl;
/**
* 调用参数
*/
private String callerParams;
/**
* 调用耗时
*/
private Long time;
/**
* 信息记录
*/
private String msg;
/**
* 状态:0:失败,1:成功
*/
private Integer status;
/**
* 调用时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime callerDate;
}
...@@ -60,6 +60,26 @@ public class DataApiEntity extends DataScopeBaseEntity { ...@@ -60,6 +60,26 @@ public class DataApiEntity extends DataScopeBaseEntity {
private String resType; private String resType;
/** /**
* IP黑名单多个,隔开
*/
private String deny;
/**
* 是否限流:0:否,1:是
*/
private Integer rateLimit;
/**
* 请求次数
*/
private Integer times;
/**
* 请求时间范围单位秒
*/
private Integer seconds;
/**
* 执行配置 * 执行配置
*/ */
@TableField(value = "config_json", typeHandler = JacksonTypeHandler.class) @TableField(value = "config_json", typeHandler = JacksonTypeHandler.class)
......
package cn.datax.service.data.market.api.vo;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
public class ApiLogVo implements Serializable {
private static final long serialVersionUID=1L;
private String id;
private String apiId;
private String apiName;
private String callerId;
private String callerIp;
private String callerUrl;
private String callerParams;
private LocalDateTime callerDate;
private Long time;
private String msg;
private Integer status;
}
...@@ -32,7 +32,11 @@ public class DataApiVo implements Serializable { ...@@ -32,7 +32,11 @@ public class DataApiVo implements Serializable {
private String apiUrl; private String apiUrl;
private String remark; private String remark;
private String reqMethod; private String reqMethod;
private String deny;
private String resType; private String resType;
private Integer rateLimit;
private Integer times;
private Integer seconds;
private ExecuteConfig executeConfig; private ExecuteConfig executeConfig;
private List<ReqParam> reqParams; private List<ReqParam> reqParams;
private List<ResParam> resParams; private List<ResParam> resParams;
......
package cn.datax.service.data.market.config; package cn.datax.service.data.market.config;
import cn.datax.common.core.DataConstant;
import cn.datax.common.core.R;
import cn.datax.common.utils.HttpUtil;
import cn.datax.common.utils.IPUtil;
import cn.datax.common.utils.MD5Util;
import cn.datax.common.utils.ResponseUtil;
import cn.datax.service.data.market.api.dto.ApiLogDto;
import cn.datax.service.data.market.api.entity.DataApiEntity;
import cn.datax.service.data.market.service.DataApiService;
import cn.datax.service.data.market.utils.ThreadUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Slf4j
public class ApiInterceptor implements HandlerInterceptor { public class ApiInterceptor implements HandlerInterceptor {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private DataApiService dataApiService;
@Override @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("************TokenInterceptor preHandle executed**********"); System.out.println("************ApiInterceptor preHandle executed**********");
System.out.println("getContextPath:" + request.getContextPath()); String uri = request.getRequestURI();
System.out.println("getServletPath:" + request.getServletPath()); log.info("getRequestURI的值:" + uri);
System.out.println("getRequestURI:" + request.getRequestURI()); String ipAddr = IPUtil.getIpAddr(request);
System.out.println("getRequestURL:" + request.getRequestURL()); log.info("ipAddr的值:" + ipAddr);
// 返回true,postHandler和afterCompletion方法才能执行 String apiKey = request.getHeader("api_key");
// 否则false为拒绝执行,起到拦截器控制作用 String secretKey = request.getHeader("secret_key");
if (StrUtil.isBlank(apiKey) || StrUtil.isBlank(secretKey)) {
ResponseUtil.makeResponse(response, MediaType.APPLICATION_JSON_VALUE,
HttpServletResponse.SC_FORBIDDEN, R.error("api_key或secret_key空"));
return false;
}
MD5Util mt = MD5Util.getInstance();
String apiId = mt.decode(apiKey);
String userId = mt.decode(secretKey);
DataApiEntity dataApiEntity = dataApiService.getById(apiId);
if (dataApiEntity == null) {
ResponseUtil.makeResponse(response, MediaType.APPLICATION_JSON_VALUE,
HttpServletResponse.SC_FORBIDDEN, R.error("API不存在"));
return false;
}
String deny = dataApiEntity.getDeny();
List<String> denyList = Arrays.asList(deny.split(","));
if (CollUtil.isNotEmpty(denyList)) {
for (String ip : denyList) {
if(ip.equals(ipAddr)){
ResponseUtil.makeResponse(response, MediaType.APPLICATION_JSON_VALUE,
HttpServletResponse.SC_FORBIDDEN, R.error("IP已被加入API调用黑名单"));
return false;
}
}
}
String apiName = dataApiEntity.getApiName();
Integer rateLimit = dataApiEntity.getRateLimit();
// 限流
if (rateLimit == 1) {
Integer times = dataApiEntity.getTimes();
Integer seconds = dataApiEntity.getSeconds();
// 请求次数
times = times == null ? 5 : times;
// 请求时间范围60秒
seconds = seconds == null ? 60 : seconds;
// 根据 USER + API 限流
String key = "user:" + userId + "_api:" + apiId;
// 根据key获取已请求次数
Integer maxTimes = (Integer) redisTemplate.opsForValue().get(key);
if (maxTimes == null) {
// set时一定要加过期时间
redisTemplate.opsForValue().set(key, 1, seconds, TimeUnit.SECONDS);
} else if (maxTimes < times) {
redisTemplate.opsForValue().set(key, maxTimes + 1, seconds, TimeUnit.SECONDS);
} else {
// 请求过于频繁
ResponseUtil.makeResponse(response, MediaType.APPLICATION_JSON_VALUE,
HttpServletResponse.SC_FORBIDDEN, R.error("API调用过于频繁"));
return false;
}
}
ApiLogDto log = new ApiLogDto();
log.setApiId(apiId);
log.setApiName(apiName);
log.setCallerId(userId);
log.setCallerIp(ipAddr);
log.setCallerUrl(uri);
log.setCallerParams(HttpUtil.getBodyString(request));
log.setCallerDate(LocalDateTime.now());
log.setTime(System.currentTimeMillis());
log.setStatus(DataConstant.TrueOrFalse.TRUE.getKey());
ThreadUtil.set(log);
return true; return true;
} }
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
ThreadUtil.get().setTime(System.currentTimeMillis() - ThreadUtil.get().getTime());
log.info("调用消耗时间:" + ThreadUtil.get().getTime());
log.info("调用日志:" + ThreadUtil.get());
ThreadUtil.remove();
}
} }
...@@ -59,7 +59,7 @@ public class DataResourceServerConfig extends ResourceServerConfigurerAdapter { ...@@ -59,7 +59,7 @@ public class DataResourceServerConfig extends ResourceServerConfigurerAdapter {
"/swagger-resources/**", "/swagger-resources/**",
"/webjars/**", "/webjars/**",
// feign 内部调用不用授权 // feign 内部调用不用授权
"/api/**", "/v1/**",
"/inner/**" "/inner/**"
).permitAll() ).permitAll()
.anyRequest().authenticated() .anyRequest().authenticated()
......
...@@ -12,7 +12,7 @@ public class WebConfig implements WebMvcConfigurer { ...@@ -12,7 +12,7 @@ public class WebConfig implements WebMvcConfigurer {
public void addInterceptors(InterceptorRegistry registry) { public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(apiInterceptor()) registry.addInterceptor(apiInterceptor())
// 设置需要拦截的路径 // 设置需要拦截的路径
.addPathPatterns("/api/**"); .addPathPatterns("/v1/**");
} }
@Bean @Bean
......
...@@ -2,7 +2,8 @@ package cn.datax.service.data.market.controller; ...@@ -2,7 +2,8 @@ package cn.datax.service.data.market.controller;
import cn.datax.common.base.BaseController; import cn.datax.common.base.BaseController;
import cn.datax.common.core.R; import cn.datax.common.core.R;
import org.springframework.web.bind.annotation.RequestHeader; import cn.datax.service.data.market.service.ApiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
...@@ -10,8 +11,12 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -10,8 +11,12 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
public class ApiController extends BaseController { public class ApiController extends BaseController {
@RequestMapping(value = "/api/**", method = {RequestMethod.GET, RequestMethod.POST}) @Autowired
public R api(@RequestHeader String app_id, @RequestHeader String secret_key){ private ApiService apiService;
@RequestMapping(value = "/v1/**", method = {RequestMethod.GET, RequestMethod.POST})
public R apiV1(){
apiService.v1();
return R.ok(); return R.ok();
} }
} }
package cn.datax.service.data.market.dao;
import cn.datax.common.base.BaseDao;
import cn.datax.service.data.market.api.entity.ApiLogEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface ApiLogDao extends BaseDao<ApiLogEntity> {
}
package cn.datax.service.data.market.mapstruct;
import cn.datax.common.mapstruct.EntityMapper;
import cn.datax.service.data.market.api.dto.ApiLogDto;
import cn.datax.service.data.market.api.entity.ApiLogEntity;
import cn.datax.service.data.market.api.vo.ApiLogVo;
import org.mapstruct.Mapper;
@Mapper(componentModel = "spring")
public interface ApiLogMapper extends EntityMapper<ApiLogDto, ApiLogEntity, ApiLogVo> {
}
package cn.datax.service.data.market.service;
import cn.datax.common.base.BaseService;
import cn.datax.service.data.market.api.dto.ApiLogDto;
import cn.datax.service.data.market.api.entity.ApiLogEntity;
public interface ApiLogService extends BaseService<ApiLogEntity> {
void saveApiLog(ApiLogDto dataApi);
}
package cn.datax.service.data.market.service;
public interface ApiService {
void v1();
}
package cn.datax.service.data.market.service.impl;
import cn.datax.common.base.BaseServiceImpl;
import cn.datax.service.data.market.api.dto.ApiLogDto;
import cn.datax.service.data.market.api.entity.ApiLogEntity;
import cn.datax.service.data.market.dao.ApiLogDao;
import cn.datax.service.data.market.mapstruct.ApiLogMapper;
import cn.datax.service.data.market.service.ApiLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class ApiLogServiceImpl extends BaseServiceImpl<ApiLogDao, ApiLogEntity> implements ApiLogService {
@Autowired
private ApiLogDao apiLogDao;
@Autowired
private ApiLogMapper apiLogMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public void saveApiLog(ApiLogDto apiLogDto) {
ApiLogEntity apiLog = apiLogMapper.toEntity(apiLogDto);
apiLogDao.insert(apiLog);
}
}
package cn.datax.service.data.market.service.impl;
import cn.datax.common.utils.ThrowableUtil;
import cn.datax.service.data.market.service.ApiService;
import cn.datax.service.data.market.utils.ThreadUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class ApiServiceImpl implements ApiService {
@Override
public void v1() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("time:" + ThreadUtil.get().getTime());
try {
int i = 1/1;
} catch (Exception e) {
log.error("全局异常信息ex={}, StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e));
ThreadUtil.get().setStatus(0);
ThreadUtil.get().setMsg(e.getMessage());
}
}
}
...@@ -7,10 +7,16 @@ import cn.datax.service.data.market.mapstruct.DataApiMapper; ...@@ -7,10 +7,16 @@ import cn.datax.service.data.market.mapstruct.DataApiMapper;
import cn.datax.service.data.market.dao.DataApiDao; import cn.datax.service.data.market.dao.DataApiDao;
import cn.datax.common.base.BaseServiceImpl; import cn.datax.common.base.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
/** /**
* <p> * <p>
* 数据API信息表 服务实现类 * 数据API信息表 服务实现类
...@@ -19,6 +25,7 @@ import org.springframework.transaction.annotation.Transactional; ...@@ -19,6 +25,7 @@ import org.springframework.transaction.annotation.Transactional;
* @author yuwei * @author yuwei
* @since 2020-03-31 * @since 2020-03-31
*/ */
@CacheConfig(cacheNames = {"apis"})
@Service @Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) @Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class DataApiServiceImpl extends BaseServiceImpl<DataApiDao, DataApiEntity> implements DataApiService { public class DataApiServiceImpl extends BaseServiceImpl<DataApiDao, DataApiEntity> implements DataApiService {
...@@ -36,6 +43,7 @@ public class DataApiServiceImpl extends BaseServiceImpl<DataApiDao, DataApiEntit ...@@ -36,6 +43,7 @@ public class DataApiServiceImpl extends BaseServiceImpl<DataApiDao, DataApiEntit
dataApiDao.insert(dataApi); dataApiDao.insert(dataApi);
} }
@CachePut(key = "#p0.id")
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateDataApi(DataApiDto dataApiDto) { public void updateDataApi(DataApiDto dataApiDto) {
...@@ -43,6 +51,13 @@ public class DataApiServiceImpl extends BaseServiceImpl<DataApiDao, DataApiEntit ...@@ -43,6 +51,13 @@ public class DataApiServiceImpl extends BaseServiceImpl<DataApiDao, DataApiEntit
dataApiDao.updateById(dataApi); dataApiDao.updateById(dataApi);
} }
@Cacheable(key = "#id", unless = "#result == null")
@Override
public DataApiEntity getById(Serializable id) {
return super.getById(id);
}
@CacheEvict(key = "#id")
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteDataApiById(String id) { public void deleteDataApiById(String id) {
......
package cn.datax.service.data.market.utils;
import cn.datax.service.data.market.api.dto.ApiLogDto;
public class ThreadUtil {
private final static ThreadLocal<ApiLogDto> logHolder = new ThreadLocal<>();
public static void set(ApiLogDto log){
logHolder.set(log);
}
public static void remove(){
logHolder.remove();
}
public static ApiLogDto get(){
return logHolder.get();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.datax.service.data.market.dao.ApiLogDao">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.datax.service.data.market.api.entity.ApiLogEntity">
<result column="id" property="id" />
<result column="status" property="status" />
<result column="api_id" property="apiId" />
<result column="api_name" property="apiName" />
<result column="caller_id" property="callerId" />
<result column="caller_ip" property="callerIp" />
<result column="caller_url" property="callerUrl" />
<result column="caller_params" property="callerParams" />
<result column="caller_date" property="callerDate" />
<result column="time" property="time" />
<result column="msg" property="msg" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
status,
api_id, api_name, caller_id, caller_ip, caller_url, caller_params, caller_date, time, msg
</sql>
</mapper>
...@@ -17,6 +17,10 @@ ...@@ -17,6 +17,10 @@
<result column="remark" property="remark" /> <result column="remark" property="remark" />
<result column="req_method" property="reqMethod" /> <result column="req_method" property="reqMethod" />
<result column="res_type" property="resType" /> <result column="res_type" property="resType" />
<result column="deny" property="deny" />
<result column="rate_limit" property="rateLimit" />
<result column="times" property="times" />
<result column="seconds" property="seconds" />
<result column="config_json" property="executeConfig" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/> <result column="config_json" property="executeConfig" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
<result column="req_json" property="reqParams" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/> <result column="req_json" property="reqParams" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
<result column="res_json" property="resParams" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/> <result column="res_json" property="resParams" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
...@@ -31,7 +35,7 @@ ...@@ -31,7 +35,7 @@
create_dept, create_dept,
update_by, update_by,
update_time, update_time,
api_name, api_version, api_url, remark, req_method, res_type, config_json, req_json, res_json api_name, api_version, api_url, remark, req_method, res_type, deny, rate_limit, times, seconds, config_json, req_json, res_json
</sql> </sql>
</mapper> </mapper>
package cn.datax.service.system.api.vo; package cn.datax.service.system.api.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data; import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime;
@Data @Data
public class LogVo implements Serializable { public class LogVo implements Serializable {
...@@ -24,4 +26,6 @@ public class LogVo implements Serializable { ...@@ -24,4 +26,6 @@ public class LogVo implements Serializable {
private String os; private String os;
private String exCode; private String exCode;
private String exMsg; private String exMsg;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime createTime;
} }
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