hqw/feature/aggregate-rpc (#74)
feat: custom gateway request url prefix and app sign header #66 #67
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -38,7 +38,7 @@
|
||||
<reactor-bom.version>Dysprosium-SR17</reactor-bom.version>
|
||||
<lettuce.version>5.3.6.RELEASE</lettuce.version>
|
||||
<nacos.version>0.2.7</nacos.version>
|
||||
<netty.version>4.1.59.Final</netty.version>
|
||||
<netty.version>4.1.60.Final</netty.version>
|
||||
<httpcore.version>4.4.14</httpcore.version>
|
||||
<log4j2.version>2.13.3</log4j2.version>
|
||||
<apache.dubbo.version>2.7.5</apache.dubbo.version>
|
||||
|
||||
@@ -31,9 +31,9 @@ import we.util.Constants;
|
||||
import we.util.WebUtils;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author hongqiaowei
|
||||
@@ -44,6 +44,62 @@ public class SystemConfig {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(SystemConfig.class);
|
||||
|
||||
public static final String DEFAULT_GATEWAY_PREFIX = "/proxy";
|
||||
|
||||
public static final String DEFAULT_GATEWAY_TEST_PREFIX = "/_proxytest";
|
||||
|
||||
public String gatewayPrefix = DEFAULT_GATEWAY_PREFIX;
|
||||
|
||||
public List<String> appHeaders = Stream.of("fizz-appid").collect(Collectors.toList());
|
||||
|
||||
public List<String> signHeaders = Stream.of("fizz-sign") .collect(Collectors.toList());
|
||||
|
||||
public List<String> timestampHeaders = Stream.of("fizz-ts") .collect(Collectors.toList());
|
||||
|
||||
@NacosValue(value = "${gateway.prefix:/proxy}", autoRefreshed = true)
|
||||
@Value( "${gateway.prefix:/proxy}" )
|
||||
public void setGatewayPrefix(String gp) {
|
||||
gatewayPrefix = gp;
|
||||
WebUtils.setGatewayPrefix(gatewayPrefix);
|
||||
log.info("gateway prefix: " + gatewayPrefix);
|
||||
}
|
||||
|
||||
@NacosValue(value = "${custom.header.appid:}", autoRefreshed = true)
|
||||
@Value( "${custom.header.appid:}" )
|
||||
public void setCustomAppHeaders(String hdrs) {
|
||||
if (StringUtils.isNotBlank(hdrs)) {
|
||||
for (String h : StringUtils.split(hdrs, ',')) {
|
||||
appHeaders.add(h.trim());
|
||||
}
|
||||
}
|
||||
WebUtils.setAppHeaders(appHeaders);
|
||||
log.info("app headers: " + appHeaders);
|
||||
}
|
||||
|
||||
@NacosValue(value = "${custom.header.sign:}", autoRefreshed = true)
|
||||
@Value( "${custom.header.sign:}" )
|
||||
public void setCustomSignHeaders(String hdrs) {
|
||||
if (StringUtils.isNotBlank(hdrs)) {
|
||||
for (String h : StringUtils.split(hdrs, ',')) {
|
||||
signHeaders.add(h.trim());
|
||||
}
|
||||
}
|
||||
log.info("sign headers: " + signHeaders);
|
||||
}
|
||||
|
||||
@NacosValue(value = "${custom.header.ts:}", autoRefreshed = true)
|
||||
@Value( "${custom.header.ts:}" )
|
||||
public void setCustomTimestampHeaders(String hdrs) {
|
||||
if (StringUtils.isNotBlank(hdrs)) {
|
||||
for (String h : StringUtils.split(hdrs, ',')) {
|
||||
timestampHeaders.add(h.trim());
|
||||
}
|
||||
}
|
||||
log.info("timestamp headers: " + timestampHeaders);
|
||||
}
|
||||
|
||||
// TODO: below to X
|
||||
|
||||
@Value("${log.response-body:false}")
|
||||
private boolean logResponseBody;
|
||||
|
||||
@@ -67,7 +123,7 @@ public class SystemConfig {
|
||||
}
|
||||
|
||||
private void afterLogResponseBodySet() {
|
||||
WebUtils.logResponseBody = logResponseBody;
|
||||
WebUtils.LOG_RESPONSE_BODY = logResponseBody;
|
||||
log.info("log response body: " + logResponseBody);
|
||||
}
|
||||
|
||||
@@ -76,7 +132,7 @@ public class SystemConfig {
|
||||
Arrays.stream(StringUtils.split(logHeaders, Constants.Symbol.COMMA)).forEach(h -> {
|
||||
logHeaderSet.add(h);
|
||||
});
|
||||
WebUtils.logHeaderSet = logHeaderSet;
|
||||
WebUtils.LOG_HEADER_SET = logHeaderSet;
|
||||
log.info("log header list: " + logHeaderSet.toString());
|
||||
}
|
||||
|
||||
|
||||
@@ -17,10 +17,13 @@
|
||||
|
||||
package we.filter;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
import org.springframework.web.server.WebFilterChain;
|
||||
import reactor.core.publisher.Mono;
|
||||
import we.util.Constants;
|
||||
import we.util.Utils;
|
||||
import we.util.WebUtils;
|
||||
|
||||
/**
|
||||
@@ -29,10 +32,19 @@ import we.util.WebUtils;
|
||||
|
||||
public abstract class FizzWebFilter implements WebFilter {
|
||||
|
||||
private static final String admin = "admin";
|
||||
private static final String actuator = "actuator";
|
||||
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
|
||||
String serviceId = WebUtils.getClientService(exchange);
|
||||
if (serviceId == null) {
|
||||
|
||||
String path = exchange.getRequest().getPath().value();
|
||||
int secFS = path.indexOf(Constants.Symbol.FORWARD_SLASH, 1);
|
||||
if (secFS == -1) {
|
||||
return WebUtils.responseError(exchange, HttpStatus.INTERNAL_SERVER_ERROR.value(), "request path should like /optional-prefix/service-name/real-biz-path");
|
||||
}
|
||||
String s = path.substring(1, secFS);
|
||||
if (s.equals(admin) || s.equals(actuator)) {
|
||||
return chain.filter(exchange);
|
||||
} else {
|
||||
return doFilter(exchange, chain);
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package we.filter;
|
||||
|
||||
import com.alibaba.nacos.api.config.annotation.NacosValue;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -40,7 +39,9 @@ import we.util.ReactorUtils;
|
||||
import we.util.WebUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
@@ -75,11 +76,6 @@ public class PreprocessFilter extends FizzWebFilter {
|
||||
Map<String, Object> eas = exchange.getAttributes(); eas.put(WebUtils.FILTER_CONTEXT, fc);
|
||||
eas.put(WebUtils.APPEND_HEADERS, appendHdrs);
|
||||
|
||||
String app = WebUtils.getHeaderValue(exchange, WebUtils.APP_HEADER);
|
||||
if (StringUtils.isNotBlank(app)) {
|
||||
eas.put(WebUtils.APP_HEADER, app);
|
||||
}
|
||||
|
||||
Mono vm = statPluginFilter.filter(exchange, null, null);
|
||||
return chain(exchange, vm, authPluginFilter).defaultIfEmpty(ReactorUtils.NULL)
|
||||
.flatMap(
|
||||
@@ -110,20 +106,18 @@ public class PreprocessFilter extends FizzWebFilter {
|
||||
}
|
||||
|
||||
private void afterAuth(ServerWebExchange exchange, ApiConfig ac) {
|
||||
if (ac.type != ApiConfig.Type.CALLBACK) {
|
||||
String bs = null, bp;
|
||||
if (ac == null) {
|
||||
bs = WebUtils.getClientService(exchange);
|
||||
bp = WebUtils.getClientReqPath(exchange);
|
||||
} else {
|
||||
if (ac.type != ApiConfig.Type.REVERSE_PROXY) {
|
||||
bs = ac.backendService;
|
||||
}
|
||||
bp = ac.transform(WebUtils.getClientReqPath(exchange));
|
||||
}
|
||||
if (bs != null) {
|
||||
WebUtils.setBackendService(exchange, bs);
|
||||
String bs = null, bp = null;
|
||||
if (ac == null) {
|
||||
bs = WebUtils.getClientService(exchange);
|
||||
bp = WebUtils.getClientReqPath(exchange);
|
||||
} else if (ac.type != ApiConfig.Type.CALLBACK) {
|
||||
if (ac.type != ApiConfig.Type.REVERSE_PROXY) {
|
||||
bs = ac.backendService;
|
||||
}
|
||||
bp = ac.transform(WebUtils.getClientReqPath(exchange));
|
||||
}
|
||||
if (bs != null) {
|
||||
WebUtils.setBackendService(exchange, bs);
|
||||
WebUtils.setBackendPath(exchange, bp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.web.server.ServerWebExchange;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import we.config.AggregateRedisConfig;
|
||||
import we.config.SystemConfig;
|
||||
import we.flume.clients.log4j2appender.LogService;
|
||||
import we.util.*;
|
||||
|
||||
@@ -49,10 +50,6 @@ public class ApiConfigService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ApiConfigService.class);
|
||||
|
||||
private static final String signHeader = "fizz-sign";
|
||||
|
||||
private static final String timestampHeader = "fizz-ts";
|
||||
|
||||
@NacosValue(value = "${fizz-api-config.key:fizz_api_config_route}", autoRefreshed = true)
|
||||
@Value("${fizz-api-config.key:fizz_api_config_route}")
|
||||
private String fizzApiConfig;
|
||||
@@ -81,6 +78,9 @@ public class ApiConfigService {
|
||||
@Resource
|
||||
private GatewayGroupService gatewayGroupService;
|
||||
|
||||
@Resource
|
||||
private SystemConfig systemConfig;
|
||||
|
||||
@Autowired(required = false)
|
||||
private CustomAuth customAuth;
|
||||
|
||||
@@ -250,6 +250,8 @@ public class ApiConfigService {
|
||||
if (ac.checkApp) {
|
||||
if (apiConifg2appsService.contains(ac.id, app)) {
|
||||
return ac;
|
||||
} else if (log.isDebugEnabled()) {
|
||||
log.debug(ac + " not contains app " + app);
|
||||
}
|
||||
} else {
|
||||
return ac;
|
||||
@@ -264,12 +266,11 @@ public class ApiConfigService {
|
||||
ServerHttpRequest req = exchange.getRequest();
|
||||
HttpHeaders hdrs = req.getHeaders();
|
||||
LogService.setBizId(req.getId());
|
||||
return canAccess(exchange, WebUtils.getAppId(exchange), WebUtils.getOriginIp(exchange), hdrs.getFirst(timestampHeader), hdrs.getFirst(signHeader),
|
||||
return canAccess(exchange, WebUtils.getAppId(exchange), WebUtils.getOriginIp(exchange), getTimestamp(hdrs), getSign(hdrs),
|
||||
WebUtils.getClientService(exchange), req.getMethod(), WebUtils.getClientReqPath(exchange));
|
||||
}
|
||||
|
||||
private Mono<Object> canAccess(ServerWebExchange exchange, String app, String ip, String timestamp, String sign,
|
||||
String service, HttpMethod method, String path) {
|
||||
private Mono<Object> canAccess(ServerWebExchange exchange, String app, String ip, String timestamp, String sign, String service, HttpMethod method, String path) {
|
||||
|
||||
ServiceConfig sc = serviceConfigMap.get(service);
|
||||
if (sc == null) {
|
||||
@@ -329,7 +330,7 @@ public class ApiConfigService {
|
||||
}
|
||||
}
|
||||
|
||||
private static Mono authSign(ApiConfig ac, App a, String timestamp, String sign) {
|
||||
private Mono authSign(ApiConfig ac, App a, String timestamp, String sign) {
|
||||
if (StringUtils.isAnyBlank(timestamp, sign)) {
|
||||
return logAndResult(a.app + " lack timestamp " + timestamp + " or sign " + sign, Access.NO_TIMESTAMP_OR_SIGN);
|
||||
} else if (validate(a.app, timestamp, a.secretkey, sign)) {
|
||||
@@ -339,13 +340,13 @@ public class ApiConfigService {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean validate(String app, String timestamp, String secretKey, String sign) {
|
||||
private boolean validate(String app, String timestamp, String secretKey, String sign) {
|
||||
StringBuilder b = ThreadContext.getStringBuilder();
|
||||
b.append(app).append(Constants.Symbol.UNDERLINE).append(timestamp).append(Constants.Symbol.UNDERLINE).append(secretKey);
|
||||
return sign.equalsIgnoreCase(DigestUtils.md532(b.toString()));
|
||||
}
|
||||
|
||||
private static Mono authSecretkey(ApiConfig ac, App a, String sign) {
|
||||
private Mono authSecretkey(ApiConfig ac, App a, String sign) {
|
||||
if (StringUtils.isBlank(sign)) {
|
||||
return logAndResult(a.app + " lack secretkey " + sign, Access.NO_SECRETKEY);
|
||||
} else if (a.secretkey.equals(sign)) {
|
||||
@@ -355,7 +356,7 @@ public class ApiConfigService {
|
||||
}
|
||||
}
|
||||
|
||||
private static Mono<Object> allow(String api, ApiConfig ac) {
|
||||
private Mono<Object> allow(String api, ApiConfig ac) {
|
||||
if (ac.access == ApiConfig.ALLOW) {
|
||||
return Mono.just(ac);
|
||||
} else {
|
||||
@@ -363,8 +364,30 @@ public class ApiConfigService {
|
||||
}
|
||||
}
|
||||
|
||||
private static Mono logAndResult(String msg, Access access) {
|
||||
private Mono logAndResult(String msg, Access access) {
|
||||
log.warn(msg);
|
||||
return Mono.just(access);
|
||||
}
|
||||
|
||||
private String getTimestamp(HttpHeaders reqHdrs) {
|
||||
List<String> tsHdrs = systemConfig.timestampHeaders;
|
||||
for (int i = 0; i < tsHdrs.size(); i++) {
|
||||
String a = reqHdrs.getFirst(tsHdrs.get(i));
|
||||
if (a != null) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getSign(HttpHeaders reqHdrs) {
|
||||
List<String> signHdrs = systemConfig.signHeaders;
|
||||
for (int i = 0; i < signHdrs.size(); i++) {
|
||||
String a = reqHdrs.getFirst(signHdrs.get(i));
|
||||
if (a != null) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
package we.proxy;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
@@ -31,6 +30,7 @@ import org.springframework.web.reactive.function.client.ClientResponse;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import we.config.SystemConfig;
|
||||
import we.constants.CommonConstants;
|
||||
import we.fizz.AggregateResult;
|
||||
import we.fizz.AggregateService;
|
||||
@@ -41,6 +41,7 @@ import we.plugin.auth.CallbackConfig;
|
||||
import we.plugin.auth.Receiver;
|
||||
import we.util.*;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -59,7 +60,7 @@ public class CallbackService {
|
||||
private static final String callback = "callback";
|
||||
|
||||
@Resource
|
||||
private FizzWebClient fizzWebClient;
|
||||
private FizzWebClient fizzWebClient;
|
||||
|
||||
@Resource
|
||||
private AggregateService aggregateService;
|
||||
@@ -67,6 +68,16 @@ public class CallbackService {
|
||||
@Resource
|
||||
private ApiConfigService apiConfigService;
|
||||
|
||||
@Resource
|
||||
private SystemConfig systemConfig;
|
||||
|
||||
private String aggrConfigPrefix;
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
aggrConfigPrefix = systemConfig.gatewayPrefix + '/';
|
||||
}
|
||||
|
||||
public Mono<? extends Void> requestBackends(ServerWebExchange exchange, HttpHeaders headers, DataBuffer body, CallbackConfig cc, Map<String, ServiceInstance> service2instMap) {
|
||||
ServerHttpRequest req = exchange.getRequest();
|
||||
String reqId = req.getId();
|
||||
@@ -197,9 +208,6 @@ public class CallbackService {
|
||||
return Mono.just(ReactiveResult.fail("no api config for " + req.path));
|
||||
}
|
||||
CallbackConfig cc = ac.callbackConfig;
|
||||
// if (req.headers.getContentType().getSubtype().equalsIgnoreCase("json")) {
|
||||
// req.body = JSON.parseObject(req.body, String.class);
|
||||
// }
|
||||
|
||||
List<Mono<Object>> sends = new ArrayList<>(); Mono send;
|
||||
|
||||
@@ -218,7 +226,7 @@ public class CallbackService {
|
||||
}
|
||||
} else {
|
||||
String traceId = CommonConstants.TRACE_ID_PREFIX + req.id;
|
||||
send = aggregateService.request(traceId, "/proxy/", req.method.name(), r.service, r.path, null, req.headers, req.body)
|
||||
send = aggregateService.request(traceId, aggrConfigPrefix, req.method.name(), r.service, r.path, null, req.headers, req.body)
|
||||
.onErrorResume( arError(req, r.service, r.path) );
|
||||
sends.add(send);
|
||||
}
|
||||
@@ -232,7 +240,7 @@ public class CallbackService {
|
||||
.onErrorResume( crError(req, stp.service, stp.path) );
|
||||
} else {
|
||||
String traceId = CommonConstants.TRACE_ID_PREFIX + req.id;
|
||||
send = aggregateService.request(traceId, "/proxy/", req.method.name(), stp.service, stp.path, null, req.headers, req.body)
|
||||
send = aggregateService.request(traceId, aggrConfigPrefix, req.method.name(), stp.service, stp.path, null, req.headers, req.body)
|
||||
.onErrorResume( arError(req, stp.service, stp.path) );
|
||||
}
|
||||
sends.add(send);
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.web.reactive.function.client.ClientResponse;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import reactor.core.publisher.Mono;
|
||||
import we.config.SystemConfig;
|
||||
import we.constants.CommonConstants;
|
||||
import we.filter.FilterResult;
|
||||
import we.flume.clients.log4j2appender.LogService;
|
||||
@@ -44,6 +45,8 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author hongqiaowei
|
||||
@@ -51,47 +54,63 @@ import java.util.Set;
|
||||
|
||||
public abstract class WebUtils {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(WebUtils.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(WebUtils.class);
|
||||
|
||||
private static final String clientService = "clientService";
|
||||
private static final String clientService = "clientService";
|
||||
|
||||
public static final String BACKEND_SERVICE = "backendService";
|
||||
private static final String xForwardedFor = "X-FORWARDED-FOR";
|
||||
|
||||
private static final String xForwardedFor = "X-FORWARDED-FOR";
|
||||
private static final String unknown = "unknown";
|
||||
|
||||
private static final String unknown = "unknown";
|
||||
private static final String loopBack = "127.0.0.1";
|
||||
|
||||
private static final String loopBack = "127.0.0.1";
|
||||
private static final String binaryAddress = "0:0:0:0:0:0:0:1";
|
||||
|
||||
private static final String binaryAddress = "0:0:0:0:0:0:0:1";
|
||||
private static final String directResponse = "directResponse";
|
||||
|
||||
private static final String directResponse = "directResponse";
|
||||
private static final String response = " response ";
|
||||
|
||||
private static final String response = " response ";
|
||||
private static final String originIp = "originIp";
|
||||
|
||||
private static final String originIp = "originIp";
|
||||
private static final String clientRequestPath = "clientRequestPath";
|
||||
|
||||
public static final String APP_HEADER = "fizz-appid";
|
||||
private static final String clientRequestPathPrefix = "clientRequestPathPrefix";
|
||||
|
||||
public static final String FILTER_CONTEXT = "filterContext";
|
||||
private static final String clientRequestQuery = "clientRequestQuery";
|
||||
|
||||
public static final String APPEND_HEADERS = "appendHeaders";
|
||||
private static final String traceId = "traceId";
|
||||
|
||||
public static final String PREV_FILTER_RESULT = "prevFilterResult";
|
||||
private static String gatewayPrefix = SystemConfig.DEFAULT_GATEWAY_PREFIX;
|
||||
|
||||
private static final String CLIENT_REQUEST_PATH = "clientRequestPath";
|
||||
private static List<String> appHeaders = Stream.of("fizz-appid").collect(Collectors.toList());
|
||||
|
||||
private static final String CLIENT_REQUEST_QUERY = "clientRequestQuery";
|
||||
private static final String app = "app";
|
||||
|
||||
private static final String traceId = "traceId";
|
||||
public static final String BACKEND_SERVICE = "backendService";
|
||||
|
||||
public static final String BACKEND_PATH = "backendPath";
|
||||
public static final String FILTER_CONTEXT = "filterContext";
|
||||
|
||||
public static boolean logResponseBody = false;
|
||||
public static final String APPEND_HEADERS = "appendHeaders";
|
||||
|
||||
public static Set<String> logHeaderSet = Collections.EMPTY_SET;
|
||||
public static final String PREV_FILTER_RESULT = "prevFilterResult";
|
||||
|
||||
public static final DataBuffer EMPTY_BODY = new NettyDataBufferFactory(new UnpooledByteBufAllocator(false, true)).wrap(Constants.Symbol.EMPTY.getBytes());
|
||||
public static final String BACKEND_PATH = "backendPath";
|
||||
|
||||
public static boolean LOG_RESPONSE_BODY = false;
|
||||
|
||||
public static Set<String> LOG_HEADER_SET = Collections.EMPTY_SET;
|
||||
|
||||
public static final DataBuffer EMPTY_BODY = new NettyDataBufferFactory(new UnpooledByteBufAllocator(false, true)).wrap(Constants.Symbol.EMPTY.getBytes());
|
||||
|
||||
|
||||
|
||||
public static void setGatewayPrefix(String p) {
|
||||
gatewayPrefix = p;
|
||||
}
|
||||
|
||||
public static void setAppHeaders(List<String> hdrs) {
|
||||
appHeaders = hdrs;
|
||||
}
|
||||
|
||||
public static String getHeaderValue(ServerWebExchange exchange, String header) {
|
||||
return exchange.getRequest().getHeaders().getFirst(header);
|
||||
@@ -102,38 +121,37 @@ public abstract class WebUtils {
|
||||
}
|
||||
|
||||
public static String getAppId(ServerWebExchange exchange) {
|
||||
return exchange.getAttribute(APP_HEADER);
|
||||
String a = exchange.getAttribute(app);
|
||||
if (a == null) {
|
||||
HttpHeaders headers = exchange.getRequest().getHeaders();
|
||||
for (int i = 0; i < appHeaders.size(); i++) {
|
||||
a = headers.getFirst(appHeaders.get(i));
|
||||
if (a != null) {
|
||||
exchange.getAttributes().put(app, a);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
public static String getClientService(ServerWebExchange exchange) {
|
||||
String svc = exchange.getAttribute(clientService);
|
||||
if (svc == null) {
|
||||
String p = exchange.getRequest().getPath().value();
|
||||
int pl = p.length();
|
||||
if (pl < 15) {
|
||||
int secFS = p.indexOf(Constants.Symbol.FORWARD_SLASH, 1);
|
||||
if (StringUtils.isBlank(gatewayPrefix) || Constants.Symbol.FORWARD_SLASH_STR.equals(gatewayPrefix)) {
|
||||
svc = p.substring(1, secFS);
|
||||
} else {
|
||||
boolean b = false;
|
||||
if (p.charAt(2) == 'r' && p.charAt(3) == 'o' && p.charAt(4) == 'x') {
|
||||
b = true;
|
||||
}
|
||||
if (b) {
|
||||
byte i = 9;
|
||||
if (p.charAt(6) == 't') {
|
||||
i = 13;
|
||||
}
|
||||
for (; i < pl; i++) {
|
||||
if (p.charAt(i) == Constants.Symbol.FORWARD_SLASH) {
|
||||
if (p.charAt(6) == 't') {
|
||||
svc = p.substring(11, i);
|
||||
} else {
|
||||
svc = p.substring(7, i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
exchange.getAttributes().put(clientService, svc);
|
||||
String prefix = p.substring(0, secFS);
|
||||
if (gatewayPrefix.equals(prefix) || SystemConfig.DEFAULT_GATEWAY_TEST_PREFIX.equals(prefix)) {
|
||||
int trdFS = p.indexOf(Constants.Symbol.FORWARD_SLASH, secFS + 1);
|
||||
svc = p.substring(secFS + 1, trdFS);
|
||||
} else {
|
||||
throw Utils.runtimeExceptionWithoutStack("wrong prefix " + prefix);
|
||||
}
|
||||
}
|
||||
exchange.getAttributes().put(clientService, svc);
|
||||
}
|
||||
return svc;
|
||||
}
|
||||
@@ -263,13 +281,24 @@ public abstract class WebUtils {
|
||||
}
|
||||
|
||||
public static String getClientReqPath(ServerWebExchange exchange) {
|
||||
String path = exchange.getAttribute(CLIENT_REQUEST_PATH);
|
||||
if (path == null) {
|
||||
path = exchange.getRequest().getPath().value();
|
||||
path = path.substring(path.indexOf(Constants.Symbol.FORWARD_SLASH, 11), path.length());
|
||||
exchange.getAttributes().put(CLIENT_REQUEST_PATH, path);
|
||||
String p = exchange.getAttribute(clientRequestPath);
|
||||
if (p == null) {
|
||||
p = exchange.getRequest().getPath().value();
|
||||
int secFS = p.indexOf(Constants.Symbol.FORWARD_SLASH, 1);
|
||||
if (StringUtils.isBlank(gatewayPrefix) || Constants.Symbol.FORWARD_SLASH_STR.equals(gatewayPrefix)) {
|
||||
p = p.substring(secFS);
|
||||
} else {
|
||||
String prefix = p.substring(0, secFS);
|
||||
if (gatewayPrefix.equals(prefix) || SystemConfig.DEFAULT_GATEWAY_TEST_PREFIX.equals(prefix)) {
|
||||
int trdFS = p.indexOf(Constants.Symbol.FORWARD_SLASH, secFS + 1);
|
||||
p = p.substring(trdFS);
|
||||
} else {
|
||||
throw Utils.runtimeExceptionWithoutStack("wrong prefix " + prefix);
|
||||
}
|
||||
}
|
||||
exchange.getAttributes().put(clientRequestPath, p);
|
||||
}
|
||||
return path;
|
||||
return p;
|
||||
}
|
||||
|
||||
public static void setBackendPath(ServerWebExchange exchange, String path) {
|
||||
@@ -281,16 +310,27 @@ public abstract class WebUtils {
|
||||
}
|
||||
|
||||
public static String getClientReqPathPrefix(ServerWebExchange exchange) {
|
||||
String p = exchange.getRequest().getPath().value();
|
||||
byte i = 7;
|
||||
if (p.charAt(6) == 't') {
|
||||
i = 11;
|
||||
String prefix = exchange.getAttribute(clientRequestPathPrefix);
|
||||
if (prefix == null) {
|
||||
if (StringUtils.isBlank(gatewayPrefix) || Constants.Symbol.FORWARD_SLASH_STR.equals(gatewayPrefix)) {
|
||||
prefix = Constants.Symbol.FORWARD_SLASH_STR;
|
||||
} else {
|
||||
String path = exchange.getRequest().getPath().value();
|
||||
int secFS = path.indexOf(Constants.Symbol.FORWARD_SLASH, 1);
|
||||
prefix = path.substring(0, secFS);
|
||||
if (gatewayPrefix.equals(prefix) || SystemConfig.DEFAULT_GATEWAY_TEST_PREFIX.equals(prefix)) {
|
||||
prefix = prefix + Constants.Symbol.FORWARD_SLASH;
|
||||
} else {
|
||||
throw Utils.runtimeExceptionWithoutStack("wrong prefix " + prefix);
|
||||
}
|
||||
}
|
||||
exchange.getAttributes().put(clientRequestPathPrefix, prefix);
|
||||
}
|
||||
return p.substring(0, i);
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public static String getClientReqQuery(ServerWebExchange exchange) {
|
||||
String qry = exchange.getAttribute(CLIENT_REQUEST_QUERY);
|
||||
String qry = exchange.getAttribute(clientRequestQuery);
|
||||
if (qry != null && StringUtils.EMPTY.equals(qry)) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -298,12 +338,12 @@ public abstract class WebUtils {
|
||||
URI uri = exchange.getRequest().getURI();
|
||||
qry = uri.getQuery();
|
||||
if (qry == null) {
|
||||
exchange.getAttributes().put(CLIENT_REQUEST_QUERY, StringUtils.EMPTY);
|
||||
exchange.getAttributes().put(clientRequestQuery, StringUtils.EMPTY);
|
||||
} else {
|
||||
if (StringUtils.indexOfAny(qry, Constants.Symbol.LEFT_BRACE, Constants.Symbol.FORWARD_SLASH, Constants.Symbol.HASH) > 0) {
|
||||
qry = uri.getRawQuery();
|
||||
}
|
||||
exchange.getAttributes().put(CLIENT_REQUEST_QUERY, qry);
|
||||
exchange.getAttributes().put(clientRequestQuery, qry);
|
||||
}
|
||||
}
|
||||
return qry;
|
||||
@@ -372,7 +412,7 @@ public abstract class WebUtils {
|
||||
b.append(reqId).append(Constants.Symbol.SPACE).append(method).append(Constants.Symbol.SPACE).append(uri);
|
||||
if (headers != null) {
|
||||
final boolean[] f = {false};
|
||||
logHeaderSet.forEach(
|
||||
LOG_HEADER_SET.forEach(
|
||||
h -> {
|
||||
String v = headers.getFirst(h);
|
||||
if (v != null) {
|
||||
@@ -392,7 +432,7 @@ public abstract class WebUtils {
|
||||
b.append(rid).append(response).append(clientResponse.statusCode());
|
||||
HttpHeaders headers = clientResponse.headers().asHttpHeaders();
|
||||
final boolean[] f = {false};
|
||||
logHeaderSet.forEach(
|
||||
LOG_HEADER_SET.forEach(
|
||||
h -> {
|
||||
String v = headers.getFirst(h);
|
||||
if (v != null) {
|
||||
|
||||
@@ -94,4 +94,7 @@ flowControl: true
|
||||
flow-stat-sched:
|
||||
cron: 2/10 * * * * ?
|
||||
dest: redis
|
||||
queue: fizz_resource_access_stat
|
||||
queue: fizz_resource_access_stat
|
||||
|
||||
gateway:
|
||||
prefix: /proxy
|
||||
|
||||
@@ -1,18 +1,9 @@
|
||||
package we.util;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.mock.web.server.MockServerWebExchange;
|
||||
import we.proxy.CallbackReplayReq;
|
||||
import we.proxy.ServiceInstance;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@@ -24,44 +15,30 @@ public class WebUtilsTests {
|
||||
|
||||
@Test
|
||||
void getClientReqPathPrefixTest() throws JsonProcessingException {
|
||||
MockServerHttpRequest mockRequest = MockServerHttpRequest.get("http://127.0.0.1:8600/proxytest/xservice/ybiz").build();
|
||||
WebUtils.setGatewayPrefix("/_proxytestx");
|
||||
MockServerHttpRequest mockRequest = MockServerHttpRequest.get("http://127.0.0.1:8600/_proxytest/xservice/ybiz?a=b").build();
|
||||
MockServerWebExchange mockExchange = MockServerWebExchange.from(mockRequest);
|
||||
String clientService = WebUtils.getClientService(mockExchange);
|
||||
assertEquals(clientService, "xservice");
|
||||
assertEquals("xservice", clientService);
|
||||
String clientReqPath = WebUtils.getClientReqPath(mockExchange);
|
||||
assertEquals("/ybiz", clientReqPath);
|
||||
String clientReqPathPrefix = WebUtils.getClientReqPathPrefix(mockExchange);
|
||||
assertEquals(clientReqPathPrefix, "/proxytest/");
|
||||
assertEquals("/_proxytest/", clientReqPathPrefix);
|
||||
|
||||
MockServerHttpRequest mr = MockServerHttpRequest.get("http://127.0.0.1:8600/proxytest/test/ybiz").build();
|
||||
MockServerWebExchange me = MockServerWebExchange.from(mr);
|
||||
String cs = WebUtils.getClientService(me);
|
||||
// System.err.println(cs);
|
||||
String crpp = WebUtils.getClientReqPathPrefix(me);
|
||||
// System.err.println(crpp);
|
||||
WebUtils.setGatewayPrefix("/prox");
|
||||
mockRequest = MockServerHttpRequest.get("http://127.0.0.1:8600/prox/test/ybiz").build();
|
||||
mockExchange = MockServerWebExchange.from(mockRequest);
|
||||
clientService = WebUtils.getClientService(mockExchange);
|
||||
assertEquals("test", clientService);
|
||||
clientReqPath = WebUtils.getClientReqPath(mockExchange);
|
||||
assertEquals("/ybiz", clientReqPath);
|
||||
|
||||
|
||||
// HttpHeaders httpHeaders = new HttpHeaders();
|
||||
// httpHeaders.add("h0", "v0");
|
||||
// List<String> values = Arrays.asList("v11", "v12");
|
||||
// httpHeaders.addAll("h1", values);
|
||||
//
|
||||
// String s = JSON.toJSONString(JSON.toJSONString(httpHeaders));
|
||||
// System.err.println("s: " + s);
|
||||
// Map<String, List<String>> m = (Map<String, List<String>>) JSON.parse(JSON.parse(s).toString());
|
||||
// System.err.println("m: " + m);
|
||||
|
||||
|
||||
// ServiceInstance si1 = new ServiceInstance("127", 80);
|
||||
// ServiceInstance si2 = new ServiceInstance("128", 90);
|
||||
// Map<String, ServiceInstance> receivers = new HashMap<>();
|
||||
// receivers.put("s1", si1);
|
||||
// receivers.put("s2", si2);
|
||||
// String receiversStr = JSON.toJSONString(JSON.toJSONString(receivers));
|
||||
// System.err.println("receivers: " + receiversStr);
|
||||
// CallbackReplayReq req = new CallbackReplayReq();
|
||||
// req.setReceivers(receiversStr);
|
||||
// System.err.println("s2 ip: " + req.receivers.get("s2").ip);
|
||||
//
|
||||
// String x = JSON.parseObject(receiversStr, String.class);
|
||||
// System.err.println("x: " + x);
|
||||
WebUtils.setGatewayPrefix("");
|
||||
mockRequest = MockServerHttpRequest.get("http://127.0.0.1:8600/aservice/ybiz1").build();
|
||||
mockExchange = MockServerWebExchange.from(mockRequest);
|
||||
clientService = WebUtils.getClientService(mockExchange);
|
||||
assertEquals("aservice", clientService);
|
||||
clientReqPath = WebUtils.getClientReqPath(mockExchange);
|
||||
assertEquals("/ybiz1", clientReqPath);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user