|
@@ -1,14 +1,31 @@
|
|
|
package com.chelvc.framework.feign.interceptor;
|
|
|
|
|
|
+import java.net.URI;
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Objects;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.function.Predicate;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
import com.chelvc.framework.base.context.Session;
|
|
|
import com.chelvc.framework.base.context.SessionContextHolder;
|
|
|
import com.chelvc.framework.base.context.Using;
|
|
|
+import com.chelvc.framework.base.util.HttpUtils;
|
|
|
import com.chelvc.framework.common.model.Platform;
|
|
|
import com.chelvc.framework.common.model.Terminal;
|
|
|
import com.chelvc.framework.common.util.ObjectUtils;
|
|
|
+import com.chelvc.framework.common.util.StringUtils;
|
|
|
+import com.chelvc.framework.feign.config.FeignProperties;
|
|
|
import feign.RequestInterceptor;
|
|
|
import feign.RequestTemplate;
|
|
|
+import feign.Target;
|
|
|
import lombok.NonNull;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.context.ApplicationContext;
|
|
|
+import org.springframework.core.env.Environment;
|
|
|
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
|
|
|
|
|
/**
|
|
|
* Feign调用处理拦截器
|
|
@@ -16,7 +33,64 @@ import lombok.NonNull;
|
|
|
* @author Woody
|
|
|
* @date 2024/1/30
|
|
|
*/
|
|
|
+@Slf4j
|
|
|
public class FeignInvokeInterceptor implements RequestInterceptor {
|
|
|
+ private final Set<String> servers;
|
|
|
+ private final Map<String, ?> mappings;
|
|
|
+ private final List<FeignProperties.Forward> forwards;
|
|
|
+
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ public FeignInvokeInterceptor(@NonNull ApplicationContext applicationContext) {
|
|
|
+ Environment environment = applicationContext.getEnvironment();
|
|
|
+ RequestMappingHandlerMapping handlerMapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
|
|
|
+ Map<String, Predicate<Class<?>>> prefixes = handlerMapping.getPathPrefixes();
|
|
|
+ this.servers = ObjectUtils.isEmpty(prefixes) ? Collections.emptySet() : prefixes.keySet();
|
|
|
+ Object registry = ObjectUtils.getValue(handlerMapping, "mappingRegistry");
|
|
|
+ Map<?, ?> mappings = (Map<?, ?>) ObjectUtils.getValue(registry, "urlLookup");
|
|
|
+ this.mappings = ObjectUtils.isEmpty(mappings) ? Collections.emptyMap() : (Map<String, ?>) mappings;
|
|
|
+ FeignProperties properties = applicationContext.getBean(FeignProperties.class);
|
|
|
+ this.forwards = ObjectUtils.ifEmpty(properties.getForwards(), forwards -> forwards.stream().map(forward -> {
|
|
|
+ FeignProperties.Forward copy = new FeignProperties.Forward();
|
|
|
+ copy.setSource(forward.getSource());
|
|
|
+ copy.setTarget(forward.getTarget());
|
|
|
+ copy.setPrefixed(forward.isPrefixed());
|
|
|
+ if (StringUtils.notEmpty(copy.getTarget())) {
|
|
|
+ copy.setTarget(environment.resolvePlaceholders(copy.getTarget()));
|
|
|
+ }
|
|
|
+ return copy;
|
|
|
+ }).collect(Collectors.toList()), Collections::emptyList);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 请求转发
|
|
|
+ *
|
|
|
+ * @param template 请求模版对象实例
|
|
|
+ */
|
|
|
+ protected void forward(@NonNull RequestTemplate template) {
|
|
|
+ Target<?> target = template.feignTarget();
|
|
|
+ String server = target.name();
|
|
|
+ for (FeignProperties.Forward forward : this.forwards) {
|
|
|
+ String source = forward.getSource(), mapping = forward.getTarget();
|
|
|
+ if (ObjectUtils.equals(source, server) || ObjectUtils.equals(source, "*")) {
|
|
|
+ boolean internal = this.servers.contains(server);
|
|
|
+ if (internal || forward.isPrefixed()) {
|
|
|
+ String uri = HttpUtils.uri(server, template.path());
|
|
|
+ if (!internal || this.mappings.containsKey(uri)) {
|
|
|
+ template.uri(uri);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (StringUtils.notEmpty(mapping) && !Objects.equals(mapping, server)) {
|
|
|
+ URI uri = URI.create(target.url());
|
|
|
+ String url = uri.getScheme() + "://" + mapping;
|
|
|
+ template.target(url);
|
|
|
+ template.feignTarget(new Target.HardCodedTarget<>(target.type(), mapping, url));
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
/**
|
|
|
* 初始化请求头
|
|
|
*
|
|
@@ -47,5 +121,13 @@ public class FeignInvokeInterceptor implements RequestInterceptor {
|
|
|
@Override
|
|
|
public void apply(RequestTemplate template) {
|
|
|
this.initializeRequestHeader(template);
|
|
|
+
|
|
|
+ if (ObjectUtils.notEmpty(this.forwards)) {
|
|
|
+ this.forward(template);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (log.isDebugEnabled()) {
|
|
|
+ log.debug("Feign request: {}", template);
|
|
|
+ }
|
|
|
}
|
|
|
}
|