diff --git a/fizz-bootstrap/pom.xml b/fizz-bootstrap/pom.xml index bfab05e..21ea75c 100644 --- a/fizz-bootstrap/pom.xml +++ b/fizz-bootstrap/pom.xml @@ -26,7 +26,7 @@ 1.7.36 3.12.0 1.18.22 - 2.7.5 + 2.7.7 1.16.1 3.4.6 4.0.1 diff --git a/fizz-core/src/main/java/we/filter/RouteFilter.java b/fizz-core/src/main/java/we/filter/RouteFilter.java index 52bcbe8..4e564bf 100644 --- a/fizz-core/src/main/java/we/filter/RouteFilter.java +++ b/fizz-core/src/main/java/we/filter/RouteFilter.java @@ -45,10 +45,7 @@ import we.util.*; import javax.annotation.Resource; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; +import java.util.*; import java.util.function.Function; /** @@ -110,21 +107,37 @@ public class RouteFilter extends FizzWebFilter { } if (route == null) { - String pathQuery = WebUtils.getClientReqPathQuery(exchange); + /*String pathQuery = WebUtils.getClientReqPathQuery(exchange); return fizzWebClient.send2service(traceId, req.getMethod(), WebUtils.getClientService(exchange), pathQuery, hdrs, req.getBody(), 0, 0, 0) + .flatMap(genServerResponse(exchange));*/ + + Map.Entry> pathQueryTemplate = WebUtils.getClientReqPathQueryTemplate(exchange).entrySet().iterator().next(); + return fizzWebClient.send2service(traceId, req.getMethod(), WebUtils.getClientService(exchange), pathQueryTemplate.getKey(), hdrs, req.getBody(), 0, 0, 0, pathQueryTemplate.getValue().toArray(new String[0])) .flatMap(genServerResponse(exchange)); } else if (route.type == ApiConfig.Type.SERVICE_DISCOVERY) { - String pathQuery = getBackendPathQuery(req, route); + /*String pathQuery = getBackendPathQuery(req, route); String svc = RegistryCenterService.getServiceNameSpace(route.registryCenter, route.backendService); return fizzWebClient.send2service(traceId, route.method, svc, pathQuery, hdrs, req.getBody(), route.timeout, route.retryCount, route.retryInterval) + .flatMap(genServerResponse(exchange));*/ + + Map.Entry> pathQueryTemplate = getBackendPathQueryTemplate(req, route).entrySet().iterator().next(); + String svc = RegistryCenterService.getServiceNameSpace(route.registryCenter, route.backendService); + return fizzWebClient.send2service(traceId, route.method, svc, pathQueryTemplate.getKey(), hdrs, req.getBody(), route.timeout, route.retryCount, route.retryInterval, pathQueryTemplate.getValue().toArray(new String[0])) .flatMap(genServerResponse(exchange)); } else if (route.type == ApiConfig.Type.REVERSE_PROXY) { - String uri = ThreadContext.getStringBuilder().append(route.nextHttpHostPort) + /*String uri = ThreadContext.getStringBuilder().append(route.nextHttpHostPort) .append(getBackendPathQuery(req, route)) .toString(); return fizzWebClient.send(traceId, route.method, uri, hdrs, req.getBody(), route.timeout, route.retryCount, route.retryInterval) + .flatMap(genServerResponse(exchange));*/ + + Map.Entry> pathQueryTemplate = getBackendPathQueryTemplate(req, route).entrySet().iterator().next(); + String uri = ThreadContext.getStringBuilder().append(route.nextHttpHostPort) + .append(pathQueryTemplate.getKey()) + .toString(); + return fizzWebClient.send(traceId, route.method, uri, hdrs, req.getBody(), route.timeout, route.retryCount, route.retryInterval, pathQueryTemplate.getValue().toArray(new String[0])) .flatMap(genServerResponse(exchange)); } else { @@ -146,6 +159,23 @@ public class RouteFilter extends FizzWebFilter { } } + private Map> getBackendPathQueryTemplate(ServerHttpRequest request, Route route) { + String qry = route.query; + if (qry == null) { + MultiValueMap queryParams = request.getQueryParams(); + if (queryParams.isEmpty()) { + return Collections.singletonMap(route.backendPath, Collections.emptyList()); + } else { + Map> queryStringTemplate = WebUtils.toQueryStringTemplate(queryParams); + Map.Entry> entry = queryStringTemplate.entrySet().iterator().next(); + qry = route.backendPath + Consts.S.QUESTION + entry.getKey(); + return Collections.singletonMap(qry, entry.getValue()); + } + } else { + return Collections.singletonMap(route.backendPath + Consts.S.QUESTION + qry, Collections.emptyList()); + } + } + private Function> genServerResponse(ServerWebExchange exchange) { return remoteResp -> { ServerHttpResponse clientResp = exchange.getResponse(); diff --git a/fizz-core/src/main/java/we/plugin/auth/ApiConfigService.java b/fizz-core/src/main/java/we/plugin/auth/ApiConfigService.java index e785603..36b524c 100644 --- a/fizz-core/src/main/java/we/plugin/auth/ApiConfigService.java +++ b/fizz-core/src/main/java/we/plugin/auth/ApiConfigService.java @@ -401,7 +401,8 @@ public class ApiConfigService implements ApplicationListener send(String traceId, - HttpMethod method, String uriOrSvc, @Nullable HttpHeaders headers, @Nullable Object body) { + HttpMethod method, String uriOrSvc, @Nullable HttpHeaders headers, @Nullable Object body) { - return send(traceId, method, uriOrSvc, headers, body, 0, 0, 0); + return send(traceId, method, uriOrSvc, headers, body, ArrayUtils.EMPTY_STRING_ARRAY); + } + + public Mono send(String traceId, + HttpMethod method, String uriOrSvc, @Nullable HttpHeaders headers, @Nullable Object body, String... uriQryParamVals) { + + return send(traceId, method, uriOrSvc, headers, body, 0, 0, 0, uriQryParamVals); + } + + public Mono send(String traceId, + HttpMethod method, String uriOrSvc, @Nullable HttpHeaders headers, @Nullable Object body, + long timeout, long numRetries, long retryInterval) { + return send(traceId, method, uriOrSvc, headers, body, timeout, numRetries, retryInterval, ArrayUtils.EMPTY_STRING_ARRAY); } public Mono send(String traceId, HttpMethod method, String uriOrSvc, @Nullable HttpHeaders headers, @Nullable Object body, - long timeout, long numRetries, long retryInterval) { + long timeout, long numRetries, long retryInterval, String... uriQryParamVals) { String s = extractServiceOrAddress(uriOrSvc); @@ -97,9 +111,9 @@ public class FizzWebClient { } else { uri = discoveryClientUriSelector.getNextUri(s, path); } - return send2uri(traceId, method, uri, headers, body, timeout); + return send2uri(traceId, method, uri, headers, body, timeout, uriQryParamVals); } else { - return send2uri(traceId, method, uriOrSvc, headers, body, timeout); + return send2uri(traceId, method, uriOrSvc, headers, body, timeout, uriQryParamVals); } }); @@ -124,14 +138,28 @@ public class FizzWebClient { } public Mono send2service(@Nullable String traceId, - HttpMethod method, String service, String relativeUri, @Nullable HttpHeaders headers, @Nullable Object body) { + HttpMethod method, String service, String relativeUri, @Nullable HttpHeaders headers, @Nullable Object body) { return send2service(traceId, method, service, relativeUri, headers, body, 0, 0, 0); } + public Mono send2service(@Nullable String traceId, + HttpMethod method, String service, String relativeUri, @Nullable HttpHeaders headers, @Nullable Object body, + String... relativeUriQryParamVals) { + + return send2service(traceId, method, service, relativeUri, headers, body, 0, 0, 0, relativeUriQryParamVals); + } + + public Mono send2service(@Nullable String traceId, + HttpMethod method, String service, String relativeUri, @Nullable HttpHeaders headers, @Nullable Object body, + long timeout, long numRetries, long retryInterval) { + + return send2service(traceId, method, service, relativeUri, headers, body, timeout, numRetries, retryInterval, ArrayUtils.EMPTY_STRING_ARRAY); + } + public Mono send2service(@Nullable String traceId, HttpMethod method, String service, String relativeUri, @Nullable HttpHeaders headers, @Nullable Object body, - long timeout, long numRetries, long retryInterval) { + long timeout, long numRetries, long retryInterval, String... relativeUriQryParamVals) { Mono cr = Mono.just(Consts.S.EMPTY).flatMap(dummy -> { String uri = null; @@ -144,7 +172,7 @@ public class FizzWebClient { } else { uri = discoveryClientUriSelector.getNextUri(service, relativeUri); } - return send2uri(traceId, method, uri, headers, body, timeout); + return send2uri(traceId, method, uri, headers, body, timeout, relativeUriQryParamVals); }); if (numRetries > 0) { cr = cr.flatMap(resp -> { @@ -170,9 +198,19 @@ public class FizzWebClient { return send2uri(traceId, method, uri, headers, body, 0); } + public Mono send2uri(@Nullable String traceId, HttpMethod method, String uri, @Nullable HttpHeaders headers, @Nullable Object body, String... uriQryParamVals) { + return send2uri(traceId, method, uri, headers, body, 0, uriQryParamVals); + } + + public Mono send2uri(@Nullable String traceId, + HttpMethod method, String uri, @Nullable HttpHeaders headers, @Nullable Object body, + long timeout) { + return send2uri(traceId, method, uri, headers, body, timeout, ArrayUtils.EMPTY_STRING_ARRAY); + } + public Mono send2uri(@Nullable String traceId, HttpMethod method, String uri, @Nullable HttpHeaders headers, @Nullable Object body, - long timeout) { + long timeout, String... uriQryParamVals) { if (log.isDebugEnabled()) { StringBuilder b = ThreadContext.getStringBuilder(); @@ -180,18 +218,25 @@ public class FizzWebClient { log.debug(b.toString(), LogService.BIZ_ID, traceId); } - WebClient.RequestBodySpec req = webClient.method(method).uri(uri).headers( - hdrs -> { - if (headers != null) { - headers.forEach( - (h, vs) -> { - hdrs.addAll(h, vs); - } - ); - } - setHostHeader(uri, hdrs); - } - ); + WebClient.RequestBodyUriSpec requestBodyUriSpec = webClient.method(method); + WebClient.RequestBodySpec requestBodySpec = null; + if (uriQryParamVals.length == 0) { + requestBodySpec = requestBodyUriSpec.uri(uri); + } else { + requestBodySpec = requestBodyUriSpec.uri(uri, Arrays.stream(uriQryParamVals).toArray()); + } + WebClient.RequestBodySpec req = requestBodySpec.headers( + hdrs -> { + if (headers != null) { + headers.forEach( + (h, vs) -> { + hdrs.addAll(h, vs); + } + ); + } + setHostHeader(uri, hdrs); + } + ); if (body != null) { if (body instanceof BodyInserter) { diff --git a/fizz-core/src/main/java/we/util/WebUtils.java b/fizz-core/src/main/java/we/util/WebUtils.java index d7455f2..d02f8f2 100644 --- a/fizz-core/src/main/java/we/util/WebUtils.java +++ b/fizz-core/src/main/java/we/util/WebUtils.java @@ -44,10 +44,7 @@ import java.net.URI; import java.net.URLDecoder; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -406,6 +403,19 @@ public abstract class WebUtils { return pathQry; } + public static Map> getClientReqPathQueryTemplate(ServerWebExchange exchange) { + String pathQry = getClientReqPath(exchange); + MultiValueMap queryParams = exchange.getRequest().getQueryParams(); + if (queryParams.isEmpty()) { + return Collections.singletonMap(pathQry, Collections.emptyList()); + } else { + Map> queryStringTemplate = toQueryStringTemplate(queryParams); + Map.Entry> entry = queryStringTemplate.entrySet().iterator().next(); + pathQry = pathQry + Consts.S.QUESTION + entry.getKey(); + return Collections.singletonMap(pathQry, entry.getValue()); + } + } + public static String appendQuery(String path, ServerWebExchange exchange) { String qry = getClientReqQuery(exchange); if (qry != null) { @@ -667,6 +677,40 @@ public abstract class WebUtils { } } + public static Map> toQueryStringTemplate(MultiValueMap queryParams) { + StringBuilder b = ThreadContext.getStringBuilder(ThreadContext.sb0); + Set>> params = queryParams.entrySet(); + int ps = params.size(), cnt = 0; + List paramValues = new ArrayList<>(); + for (Map.Entry> param : params) { + String name = param.getKey(); + List values = param.getValue(); + if (values.isEmpty()) { + b.append(name); + } else { + int vs = values.size(); + for (int i = 0; i < vs; ) { + b.append(name); + String v = values.get(i); + if (v != null) { + b.append(Consts.S.EQUAL); + if (!Consts.S.EMPTY.equals(v)) { + paramValues.add(v); + b.append(Consts.S.LEFT_BRACE).append(paramValues.size()).append(Consts.S.RIGHT_BRACE); + } + } + if ((++i) != vs) { + b.append(Consts.S.AND); + } + } + } + if ((++cnt) != ps) { + b.append(Consts.S.AND); + } + } + return Collections.singletonMap(b.toString(), paramValues); + } + // the method below will be deprecated. @Deprecated diff --git a/pom.xml b/pom.xml index dbed724..3d29380 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ 4.4.15 2.17.2 1.7.36 - 2.7.5 + 2.7.7 1.16.1 3.4.6 4.0.1