Merge branch 'dev' of axzsource.com:universal/infrastructure/backend/pokonyan into dev
This commit is contained in:
commit
45e84a8518
4
pom.xml
4
pom.xml
@ -100,6 +100,10 @@
|
|||||||
<groupId>org.aspectj</groupId>
|
<groupId>org.aspectj</groupId>
|
||||||
<artifactId>aspectjrt</artifactId>
|
<artifactId>aspectjrt</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.axzo.framework</groupId>
|
||||||
|
<artifactId>axzo-common-domain</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package cn.axzo.pokonyan.config.redis;
|
|||||||
import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
|
import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Primary;
|
||||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
@ -30,8 +31,9 @@ public class RedisConfiguration {
|
|||||||
/**
|
/**
|
||||||
* RedisTemplate配置
|
* RedisTemplate配置
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Primary
|
||||||
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory, RedisSerializer<String> redisKeySerializer, RedisSerializer<Object> redisValueSerializer) {
|
@Bean(name = "genericRedisTemplate")
|
||||||
|
public StringRedisTemplate genericRedisTemplate(RedisConnectionFactory factory, RedisSerializer<String> redisKeySerializer, RedisSerializer<Object> redisValueSerializer) {
|
||||||
StringRedisTemplate redisTemplate = new StringRedisTemplate();
|
StringRedisTemplate redisTemplate = new StringRedisTemplate();
|
||||||
redisTemplate.setConnectionFactory(factory);
|
redisTemplate.setConnectionFactory(factory);
|
||||||
|
|
||||||
@ -48,4 +50,9 @@ public class RedisConfiguration {
|
|||||||
return redisTemplate;
|
return redisTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean(name = "stringRedisTemplate")
|
||||||
|
public StringRedisTemplate redisTemplate(RedisConnectionFactory factory) {
|
||||||
|
return new StringRedisTemplate(factory);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -6,6 +6,7 @@ import cn.hutool.json.JSONUtil;
|
|||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.method.HandlerMethod;
|
import org.springframework.web.method.HandlerMethod;
|
||||||
import org.springframework.web.servlet.HandlerInterceptor;
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
@ -24,8 +25,9 @@ import java.util.Map;
|
|||||||
* @author tanjie@axzo.cn
|
* @author tanjie@axzo.cn
|
||||||
* @date 2021/12/13 11:13
|
* @date 2021/12/13 11:13
|
||||||
*/
|
*/
|
||||||
@Component
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ConditionalOnProperty(prefix = "axzo.log.pokonya", name = "enable", havingValue = "true", matchIfMissing = true)
|
||||||
|
@Component
|
||||||
public class RequestLogHandlerInterceptor implements HandlerInterceptor, WebMvcConfigurer {
|
public class RequestLogHandlerInterceptor implements HandlerInterceptor, WebMvcConfigurer {
|
||||||
|
|
||||||
private static final String SPLIT_EXCLUDE_PARAM = "\\|";
|
private static final String SPLIT_EXCLUDE_PARAM = "\\|";
|
||||||
@ -81,6 +83,8 @@ public class RequestLogHandlerInterceptor implements HandlerInterceptor, WebMvcC
|
|||||||
JSON.toJSONString(request.getParameterMap()),
|
JSON.toJSONString(request.getParameterMap()),
|
||||||
isJson ? JSON.toJSONString(JSONUtil.toBean(body, Map.class)) : body);
|
isJson ? JSON.toJSONString(JSONUtil.toBean(body, Map.class)) : body);
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
log.warn("request body too long, ignore print");
|
||||||
}
|
}
|
||||||
log.info("requestUrl:{}", requestUrl);
|
log.info("requestUrl:{}", requestUrl);
|
||||||
|
|
||||||
|
|||||||
@ -4,10 +4,9 @@ package cn.axzo.pokonyan.filter;
|
|||||||
import cn.axzo.pokonyan.util.ExceptionUtil;
|
import cn.axzo.pokonyan.util.ExceptionUtil;
|
||||||
import cn.axzo.pokonyan.wrapper.BodyReaderHttpServletRequestWrapper;
|
import cn.axzo.pokonyan.wrapper.BodyReaderHttpServletRequestWrapper;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.google.common.base.Strings;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.skywalking.apm.toolkit.trace.TraceContext;
|
|
||||||
import org.slf4j.MDC;
|
import org.slf4j.MDC;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
@ -17,19 +16,23 @@ import javax.servlet.FilterChain;
|
|||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author TanJ
|
* @author TanJ
|
||||||
* @date 2021/5/24
|
* @date 2021/5/24
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ConditionalOnProperty(prefix = "axzo.log.pokonya", name = "enable", havingValue = "true", matchIfMissing = true)
|
||||||
@Component
|
@Component
|
||||||
@Order(-99999)
|
@Order(-99999)
|
||||||
public class TraceIdFilter extends OncePerRequestFilter {
|
public class TraceIdFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
private static final String TRACE_ID = "traceId";
|
private static final String TRACE_ID = "traceId";
|
||||||
|
private static final String CTX_LOG_ID = "ctxLogId";
|
||||||
|
private static final String X_REQUEST_ID = "x-request-id";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -47,21 +50,27 @@ public class TraceIdFilter extends OncePerRequestFilter {
|
|||||||
|
|
||||||
|
|
||||||
//do
|
//do
|
||||||
|
try {
|
||||||
filterChain.doFilter(bodyRequest, response);
|
filterChain.doFilter(bodyRequest, response);
|
||||||
|
} finally {
|
||||||
|
MDC.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void setTraceId(@Nonnull HttpServletRequest request,
|
private void setTraceId(@Nonnull HttpServletRequest request,
|
||||||
@Nonnull HttpServletResponse response) {
|
@Nonnull HttpServletResponse response) {
|
||||||
|
|
||||||
request.getParameterMap();
|
//header: ctxLogId -> traceId -> x-request-id
|
||||||
String traceId = request.getHeader(TRACE_ID);
|
String traceId = StrUtil.blankToDefault(request.getHeader(CTX_LOG_ID),
|
||||||
traceId = StrUtil.isBlank(traceId) ? MDC.get(TRACE_ID) : traceId;
|
StrUtil.blankToDefault(request.getHeader(TRACE_ID),
|
||||||
//设置SkyWalking
|
request.getHeader(X_REQUEST_ID)));
|
||||||
if (Strings.isNullOrEmpty(traceId)) {
|
// blank to new
|
||||||
MDC.put(TRACE_ID, TraceContext.traceId());
|
traceId = StrUtil.blankToDefault(traceId, UUID.randomUUID().toString().replaceAll("-", ""));
|
||||||
response.setHeader(TRACE_ID, MDC.get(TRACE_ID));
|
//set
|
||||||
}
|
MDC.put(TRACE_ID, traceId);
|
||||||
|
MDC.put(CTX_LOG_ID, traceId);
|
||||||
|
response.setHeader(TRACE_ID, traceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
48
src/main/java/cn/axzo/pokonyan/util/KeysUtil.java
Normal file
48
src/main/java/cn/axzo/pokonyan/util/KeysUtil.java
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package cn.axzo.pokonyan.util;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author tanjie@axzo.cn
|
||||||
|
* @date 2023/11/17 18:04
|
||||||
|
*/
|
||||||
|
public class KeysUtil {
|
||||||
|
|
||||||
|
private static final String DEFAULT_SEPARATOR = "-";
|
||||||
|
|
||||||
|
|
||||||
|
public static String createKey(Object... keys) {
|
||||||
|
if (ArrayUtil.isEmpty(keys)) {
|
||||||
|
return StrUtil.EMPTY;
|
||||||
|
}
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
for (int i = 0; i < keys.length; i++) {
|
||||||
|
if (null == keys[i]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
stringBuilder.append(keys[i]);
|
||||||
|
if (i != keys.length - 1) {
|
||||||
|
stringBuilder.append(DEFAULT_SEPARATOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stringBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String createKeyBySeparator(String separator,Object... keys) {
|
||||||
|
if (ArrayUtil.isEmpty(keys)) {
|
||||||
|
return StrUtil.EMPTY;
|
||||||
|
}
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
for (int i = 0; i < keys.length; i++) {
|
||||||
|
if (null == keys[i]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
stringBuilder.append(keys[i]);
|
||||||
|
if (i != keys.length - 1) {
|
||||||
|
stringBuilder.append(separator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stringBuilder.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
96
src/main/java/cn/axzo/pokonyan/util/RpcUtil.java
Normal file
96
src/main/java/cn/axzo/pokonyan/util/RpcUtil.java
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
package cn.axzo.pokonyan.util;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.axzo.framework.domain.ServiceException;
|
||||||
|
import cn.axzo.framework.domain.data.AssertUtil;
|
||||||
|
import cn.axzo.framework.domain.web.result.ApiResult;
|
||||||
|
import cn.azxo.framework.common.model.CommonResponse;
|
||||||
|
import cn.hutool.core.date.StopWatch;
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
|
import cn.hutool.core.lang.TypeReference;
|
||||||
|
import cn.hutool.http.HttpStatus;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 外部rpc接口 返回 CommonResponse
|
||||||
|
* @author tanjie@axzo.cn
|
||||||
|
* @date 2022/5/23 11:08
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class RpcUtil {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 常用的RPC请求返回值解析,如果 被请求方 返回非200会抛出异常
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static <T> T rpcCommonProcessor(Supplier<CommonResponse<T>> supplier, String operationType, Object... param) {
|
||||||
|
|
||||||
|
return rpcProcessorMayThrow(supplier, operationType, commonResponse -> {
|
||||||
|
throw new ServiceException(commonResponse.getMsg());
|
||||||
|
}, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T rpcApiResultProcessor(Supplier<ApiResult<T>> supplier, String operationType, Object... param) {
|
||||||
|
log.info(operationType + "-Param: " + JSONUtil.toJsonStr(param));
|
||||||
|
ApiResult<T> result = printLatency(supplier,operationType);
|
||||||
|
log.info(operationType + "-Result: " + JSONUtil.toJsonStr(result));
|
||||||
|
Assert.notNull(result, "服务调用异常");
|
||||||
|
Assert.isTrue(result.getCode() == 200, "服务调用异常:" + result.getMsg());
|
||||||
|
return result.getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 第三方发生异常时,自定义处理逻辑
|
||||||
|
*
|
||||||
|
* @param supplier
|
||||||
|
* @param operationType
|
||||||
|
* @param throwConsumer
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static <T> T rpcProcessorMayThrow(Supplier<CommonResponse<T>> supplier, String operationType, Consumer<CommonResponse<T>> throwConsumer, Object... param) {
|
||||||
|
Assert.notNull(throwConsumer, "自定义的异常处理不可为空");
|
||||||
|
log.info(operationType + "-Param: " + JSONUtil.toJsonStr(param));
|
||||||
|
CommonResponse<T> result = printLatency(supplier, operationType);
|
||||||
|
log.info(operationType + "-Result: " + JSONUtil.toJsonStr(result));
|
||||||
|
Assert.notNull(result, "服务调用异常");
|
||||||
|
// 200自定义处理
|
||||||
|
if (HttpStatus.HTTP_OK != result.getCode()) {
|
||||||
|
throwConsumer.accept(result);
|
||||||
|
}
|
||||||
|
return result.getData();
|
||||||
|
}
|
||||||
|
public static <R> R printLatency(Supplier< R> function,String optType) {
|
||||||
|
StopWatch stopWatch = new StopWatch(optType);
|
||||||
|
stopWatch.start(optType);
|
||||||
|
R r = function.get();
|
||||||
|
stopWatch.stop();
|
||||||
|
log.info(stopWatch.shortSummary(TimeUnit.MILLISECONDS));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Response<E> {
|
||||||
|
private Integer code;
|
||||||
|
private String msg;
|
||||||
|
private E data;
|
||||||
|
|
||||||
|
public static Response create(String data) {
|
||||||
|
return JSONUtil.toBean(data, Response.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
42
src/main/java/cn/axzo/pokonyan/util/TraceSupplier.java
Normal file
42
src/main/java/cn/axzo/pokonyan/util/TraceSupplier.java
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package cn.axzo.pokonyan.util;
|
||||||
|
|
||||||
|
import org.slf4j.MDC;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 封装Supplier
|
||||||
|
*
|
||||||
|
* @version V1.0
|
||||||
|
* @author: ZhanSiHu
|
||||||
|
* @date: 2023/11/13 15:47
|
||||||
|
*/
|
||||||
|
public class TraceSupplier<T> implements Supplier<T> {
|
||||||
|
|
||||||
|
private static final String CTX_LOG_ID = "ctxLogId";
|
||||||
|
|
||||||
|
private String traceId;
|
||||||
|
|
||||||
|
private Supplier<T> supplier;
|
||||||
|
|
||||||
|
private TraceSupplier() {}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T get() {
|
||||||
|
MDC.put(CTX_LOG_ID, this.traceId);
|
||||||
|
try {
|
||||||
|
return supplier.get();
|
||||||
|
} finally {
|
||||||
|
MDC.remove(CTX_LOG_ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> TraceSupplier<T> create(Supplier<T> supplier) {
|
||||||
|
TraceSupplier<T> traceSupplier = new TraceSupplier<>();
|
||||||
|
traceSupplier.supplier = supplier;
|
||||||
|
traceSupplier.traceId = MDC.get(CTX_LOG_ID);
|
||||||
|
return traceSupplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user