feat:V3.1.1整合remi-comm到remi-cloud中
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
package ai.remi.comm.feign.annotation;
|
||||
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
|
||||
/**
|
||||
* @author Remi
|
||||
* @email remi@dianjiu.cc
|
||||
* @desc 自定义feign注解,添加basePackages路径
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@EnableFeignClients
|
||||
public @interface EnableRemiFeignClients {
|
||||
String[] value() default {};
|
||||
|
||||
String[] basePackages() default {"ai.remi"};
|
||||
|
||||
Class<?>[] basePackageClasses() default {};
|
||||
|
||||
Class<?>[] defaultConfiguration() default {};
|
||||
|
||||
Class<?>[] clients() default {};
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package ai.remi.comm.feign.aspect;
|
||||
|
||||
import feign.Logger;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.codec.ErrorDecoder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
|
||||
/**
|
||||
* @author Remi
|
||||
* @email remi@dianjiu.cc
|
||||
* @desc Feign 配置注册
|
||||
*/
|
||||
@Configuration
|
||||
public class FeignAutoConfiguration {
|
||||
|
||||
/**
|
||||
* 自定义请求拦截器
|
||||
* 传递用户信息请求头,防止丢失
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public RequestInterceptor requestInterceptor() {
|
||||
return new FeignRequestInterceptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置Feign客户端日志级别
|
||||
* <p>
|
||||
* 有四种日志记录级别可供选择:
|
||||
* <p>
|
||||
* - NONE – 不记录日志,这是默认设置
|
||||
* - BASIC – 仅记录请求方法、URL 和响应状态
|
||||
* - HEADERS – 将基本信息与请求和响应标头一起记录
|
||||
* - FULL – 记录请求和响应的主体、标头和元数据
|
||||
*/
|
||||
@Bean
|
||||
Logger.Level level() {
|
||||
return Logger.Level.FULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Feign 的默认错误处理程序ErrorDecoder.default总是抛出FeignException。
|
||||
* 种行为并不总是最有用的。因此,要自定义抛出的异常
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public ErrorDecoder errorDecoder() {
|
||||
return new RemiFeignErrorDecoder();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package ai.remi.comm.feign.aspect;
|
||||
|
||||
import ai.remi.comm.core.constant.HeaderConstant;
|
||||
import ai.remi.comm.core.enums.IdentityTypeEnum;
|
||||
import ai.remi.comm.core.enums.PermissionScopeEnum;
|
||||
import ai.remi.comm.util.auth.AuthInfoUtils;
|
||||
import ai.remi.comm.util.http.ServletUtils;
|
||||
import ai.remi.comm.util.ip.IpAddrUtils;
|
||||
import ai.remi.comm.util.string.StringUtils;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.RequestTemplate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author Remi
|
||||
* @email remi@dianjiu.cc
|
||||
* @desc Feign 请求拦截器
|
||||
*/
|
||||
@Component
|
||||
public class FeignRequestInterceptor implements RequestInterceptor {
|
||||
private Logger log = LoggerFactory.getLogger(FeignRequestInterceptor.class);
|
||||
|
||||
@Override
|
||||
public void apply(RequestTemplate requestTemplate) {
|
||||
HttpServletRequest httpServletRequest = ServletUtils.getRequest();
|
||||
Map<String, String> headers = ServletUtils.getHeaders(httpServletRequest);
|
||||
// 传递用户信息请求头,防止丢失
|
||||
//String userId = headers.get(HeaderConstant.X_UNIQUE_ID);
|
||||
if (StringUtils.isNotNull(httpServletRequest)) {
|
||||
// 传递服务类型请求头,防止丢失
|
||||
log.info("FeignHeaderRequestInterceptor X_SERVICE_TYPE:{}", AuthInfoUtils.getServiceTypeCode());
|
||||
requestTemplate.header(HeaderConstant.X_SERVICE_TYPE, AuthInfoUtils.getServiceTypeCode());
|
||||
// 传递部门租户请求头,防止丢失
|
||||
requestTemplate.header(HeaderConstant.X_DEPT_TENANT_ID, AuthInfoUtils.getDeptTenantId());
|
||||
// 传递公司租户请求头,防止丢失
|
||||
requestTemplate.header(HeaderConstant.X_COMPANY_TENANT_ID, AuthInfoUtils.getCompanyTenantId());
|
||||
// 传递用户信息请求头,防止丢失
|
||||
requestTemplate.header(HeaderConstant.X_UNIQUE_ID, AuthInfoUtils.getUniqueId());
|
||||
// 传递系统语言请求头,防止丢失
|
||||
requestTemplate.header(HeaderConstant.X_USER_LANGUAGE, AuthInfoUtils.getUserLanguage());
|
||||
// 传递用户设备请求头,防止丢失
|
||||
requestTemplate.header(HeaderConstant.X_DISTINCT_ID, headers.get(HeaderConstant.X_DISTINCT_ID));
|
||||
// 传递鉴权信息请求头,防止丢失
|
||||
requestTemplate.header(HeaderConstant.X_ACCESS_TOKEN, headers.get(HeaderConstant.X_ACCESS_TOKEN));
|
||||
|
||||
// 判断用户类型是否为集团公司,是的话进一步判断是否为集团权限,是集团权限需要传递集团下属公司IDs
|
||||
IdentityTypeEnum identityTypeEnum = AuthInfoUtils.getIdentityTypeEnum();
|
||||
//集团公司的用户
|
||||
if (identityTypeEnum == IdentityTypeEnum.COMPANY) {
|
||||
//权限范围
|
||||
String permissionScope = Optional.ofNullable(AuthInfoUtils.getPermissionScopeEnum())
|
||||
.map(PermissionScopeEnum::getCode).orElse("");
|
||||
requestTemplate.header(HeaderConstant.X_PERMISSION_SCOPE, permissionScope);
|
||||
//当权限范围为集团时,为这个用户管理公司的id
|
||||
requestTemplate.header(HeaderConstant.X_COMPANY_IDS, AuthInfoUtils.getHasPermissionCompanyIds());
|
||||
//当权限范围为公司时,为这个用户管理部门的id
|
||||
requestTemplate.header(HeaderConstant.X_COMPANY_IDS, AuthInfoUtils.getHasPermissionCompanyIds());
|
||||
} else if (identityTypeEnum == IdentityTypeEnum.VISITOR) {
|
||||
//访客体验的用户 do anything
|
||||
}
|
||||
|
||||
// 传递请求来源请求头,防止丢失
|
||||
requestTemplate.header("X-Forwarded-For", IpAddrUtils.getIpAddr(ServletUtils.getRequest()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package ai.remi.comm.feign.aspect;
|
||||
|
||||
import ai.remi.comm.feign.exception.BadRequestException;
|
||||
import ai.remi.comm.feign.exception.NotFoundException;
|
||||
import ai.remi.comm.feign.exception.OpenFeignException;
|
||||
import feign.Response;
|
||||
import feign.codec.ErrorDecoder;
|
||||
|
||||
public class RemiFeignErrorDecoder implements ErrorDecoder {
|
||||
@Override
|
||||
public Exception decode(String methodKey, Response response) {
|
||||
|
||||
return switch (response.status()) {
|
||||
case 400 -> new BadRequestException();
|
||||
case 404 -> new NotFoundException("Remi Feign ");
|
||||
default -> new OpenFeignException("Remi Feign error");
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package ai.remi.comm.feign.exception;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author Remi
|
||||
* @email remi@dianjiu.cc
|
||||
* @desc BadRequestException
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class BadRequestException extends RuntimeException {
|
||||
public BadRequestException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package ai.remi.comm.feign.exception;
|
||||
|
||||
import ai.remi.comm.core.constant.Constants;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author Remi
|
||||
* @email remi@dianjiu.cc
|
||||
* @desc NotFoundException
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class NotFoundException extends Exception {
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Getter
|
||||
@Setter
|
||||
private String code;
|
||||
@Getter
|
||||
@Setter
|
||||
private String message;
|
||||
|
||||
public NotFoundException(String msg) {
|
||||
super(msg);
|
||||
this.code = Constants.ERROR;
|
||||
}
|
||||
|
||||
public NotFoundException(String msg, Exception e) {
|
||||
super(msg + " not found,because of" + e.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package ai.remi.comm.feign.exception;
|
||||
|
||||
import ai.remi.comm.core.constant.Constants;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author Remi
|
||||
* @email remi@dianjiu.cc
|
||||
* @desc OpenFeignException
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class OpenFeignException extends RuntimeException {
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private String code;
|
||||
@Getter
|
||||
@Setter
|
||||
private String message;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private Object data;
|
||||
|
||||
public OpenFeignException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public OpenFeignException(String message) {
|
||||
super(message);
|
||||
this.code = Constants.ERROR;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public OpenFeignException(String code, String message) {
|
||||
super(message);
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public OpenFeignException(String code, Throwable cause) {
|
||||
super(cause);
|
||||
this.code = code;
|
||||
this.message = cause.getMessage();
|
||||
}
|
||||
|
||||
public OpenFeignException(String code, String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public OpenFeignException(String code, String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user