diff --git a/fizz-plugin/src/main/java/we/plugin/grayrelease/GrayReleasePlugin.java b/fizz-plugin/src/main/java/we/plugin/grayrelease/GrayReleasePlugin.java index 99e9cde..ea175aa 100644 --- a/fizz-plugin/src/main/java/we/plugin/grayrelease/GrayReleasePlugin.java +++ b/fizz-plugin/src/main/java/we/plugin/grayrelease/GrayReleasePlugin.java @@ -360,54 +360,54 @@ public class GrayReleasePlugin extends RequestBodyPlugin { String type = newRouteConfig.get("type"); String service = newRouteConfig.get("serviceName"); if (StringUtils.isNotBlank(service)) { - route.backendService = service; + route.backendService = service.trim(); } String timeout = newRouteConfig.get("timeout"); if (StringUtils.isNotBlank(timeout)) { - route.timeout(Long.parseLong(timeout)); + route.timeout(Long.parseLong(timeout.trim())); } if (type.equals("http")) { String registry = newRouteConfig.get("registry"); if (StringUtils.isNotBlank(registry)) { - route.registryCenter = registry; + route.registryCenter = registry.trim(); } String method = newRouteConfig.get("methodName"); if (StringUtils.isNotBlank(method)) { - route.method(HttpMethod.resolve(method)); + route.method(HttpMethod.resolve(method.trim())); } String path = newRouteConfig.get("path"); if (StringUtils.isNotBlank(path)) { - route.backendPath = UrlTransformUtils.transform(route.path, path, WebUtils.getClientReqPath(exchange)); + route.backendPath = UrlTransformUtils.transform(route.path, path.trim(), WebUtils.getClientReqPath(exchange)); } String qry = newRouteConfig.get("query"); if (StringUtils.isNotBlank(qry)) { - route.query = qry; + route.query = qry.trim(); } String retryCount = newRouteConfig.get("retryCount"); if (StringUtils.isNotBlank(retryCount)) { - route.retryCount(Integer.parseInt(retryCount)); + route.retryCount(Integer.parseInt(retryCount.trim())); } String retryInterval = newRouteConfig.get("retryInterval"); if (StringUtils.isNotBlank(retryInterval)) { - route.retryInterval(Long.parseLong(retryInterval)); + route.retryInterval(Long.parseLong(retryInterval.trim())); } } else { route.type = ApiConfig.Type.DUBBO; String method = newRouteConfig.get("methodName"); if (StringUtils.isNotBlank(method)) { - route.rpcMethod(method); + route.rpcMethod(method.trim()); } String version = newRouteConfig.get("version"); if (StringUtils.isNotBlank(version)) { - route.rpcVersion(version); + route.rpcVersion(version.trim()); } String group = newRouteConfig.get("group"); if (StringUtils.isNotBlank(group)) { - route.rpcGroup(group); + route.rpcGroup(group.trim()); } String paramTypes = newRouteConfig.get("paramTypes"); if (StringUtils.isNotBlank(paramTypes)) { - route.rpcParamTypes(paramTypes); + route.rpcParamTypes(paramTypes.trim()); } } } @@ -419,12 +419,16 @@ public class GrayReleasePlugin extends RequestBodyPlugin { if (StringUtils.isBlank(httpHostPortStr)) { httpHostPorts = WebUtils.getApiConfig(exchange).httpHostPorts; } else { - httpHostPorts = Arrays.asList(StringUtils.split(httpHostPortStr, Consts.S.COMMA)); + String[] httpHostPortArr = StringUtils.split(httpHostPortStr, Consts.S.COMMA); + for (int i = 0; i < httpHostPortArr.length; i++) { + httpHostPortArr[i] = httpHostPortArr[i].trim(); + } + httpHostPorts = Arrays.asList(httpHostPortArr); } pluginConfig.put("httpHostPorts", httpHostPorts); newRouteConfig.remove("serviceName"); } - int counter = (int) pluginConfig.getOrDefault("counter", 0); + int counter = (int) pluginConfig.getOrDefault("counter", -1); counter++; if (counter < 0) { counter = Math.abs(counter); @@ -437,44 +441,44 @@ public class GrayReleasePlugin extends RequestBodyPlugin { String method = newRouteConfig.get("methodName"); if (StringUtils.isNotBlank(method)) { - route.method(HttpMethod.resolve(method)); + route.method(HttpMethod.resolve(method.trim())); } String path = newRouteConfig.get("path"); if (StringUtils.isNotBlank(path)) { - route.backendPath = UrlTransformUtils.transform(route.path, path, WebUtils.getClientReqPath(exchange)); + route.backendPath = UrlTransformUtils.transform(route.path, path.trim(), WebUtils.getClientReqPath(exchange)); } String qry = newRouteConfig.get("query"); if (StringUtils.isNotBlank(qry)) { - route.query = qry; + route.query = qry.trim(); } String timeout = newRouteConfig.get("timeout"); if (StringUtils.isNotBlank(timeout)) { - route.timeout(Long.parseLong(timeout)); + route.timeout(Long.parseLong(timeout.trim())); } String retryCount = newRouteConfig.get("retryCount"); if (StringUtils.isNotBlank(retryCount)) { - route.retryCount(Integer.parseInt(retryCount)); + route.retryCount(Integer.parseInt(retryCount.trim())); } String retryInterval = newRouteConfig.get("retryInterval"); if (StringUtils.isNotBlank(retryInterval)) { - route.retryInterval(Long.parseLong(retryInterval)); + route.retryInterval(Long.parseLong(retryInterval.trim())); } } private void changeAggregateRoute(ServerWebExchange exchange, Route route, Map newRouteConfig) { String service = newRouteConfig.get("serviceName"); if (StringUtils.isNotBlank(service)) { - route.backendService = service; + route.backendService = service.trim(); WebUtils.setBackendService(exchange, route.backendService); } String path = newRouteConfig.get("path"); if (StringUtils.isNotBlank(path)) { - route.backendPath = UrlTransformUtils.transform(route.path, path, WebUtils.getClientReqPath(exchange)); + route.backendPath = UrlTransformUtils.transform(route.path, path.trim(), WebUtils.getClientReqPath(exchange)); WebUtils.setBackendPath(exchange, route.backendPath); } } @@ -483,25 +487,8 @@ public class GrayReleasePlugin extends RequestBodyPlugin { Map result = new HashMap<>(); String[] lines = StringUtils.split(config, Consts.S.LF); for (String line : lines) { - /*int colonIdx = line.indexOf(Consts.S.COLON); - int start = 0, end = 0; - for (int i = 0; i < line.length(); i++) { - if (line.charAt(i) != Consts.S.SPACE) { - start = i; - break; - } - } - for (int i = line.length() - 1; i > -1; i--) { - if (line.charAt(i) != Consts.S.SPACE) { - end = i; - break; - } - } - String name = line.substring(start, colonIdx); - String value = line.substring(colonIdx + 1, end + 1); - result.put(name, value);*/ - String[] nameValue = StringUtils.split(line, Consts.S.COLON); - result.put(nameValue[0].trim(), nameValue[1].trim()); + int colonIdx = line.indexOf(Consts.S.COLON); + result.put(line.substring(0, colonIdx).trim(), line.substring(colonIdx + 1).trim()); } return result; } diff --git a/fizz-plugin/src/test/java/we/plugin/grayrelease/GrayReleasePluginTests.java b/fizz-plugin/src/test/java/we/plugin/grayrelease/GrayReleasePluginTests.java index 5b8bb34..ee0fe0b 100644 --- a/fizz-plugin/src/test/java/we/plugin/grayrelease/GrayReleasePluginTests.java +++ b/fizz-plugin/src/test/java/we/plugin/grayrelease/GrayReleasePluginTests.java @@ -1,5 +1,7 @@ package we.plugin.grayrelease; +import com.fasterxml.jackson.core.type.TypeReference; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -7,18 +9,31 @@ import org.springframework.http.MediaType; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.test.web.reactive.server.WebTestClient; import reactor.core.publisher.Mono; +import we.filter.AggregateFilter; +import we.filter.FilterResult; +import we.fizz.ConfigLoader; import we.plugin.FizzPluginFilterChain; +import we.plugin.auth.ApiConfig; import we.proxy.Route; import we.util.Consts; +import we.util.JacksonUtils; +import we.util.ReflectionUtils; import we.util.WebUtils; import java.util.HashMap; import java.util.Map; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + public class GrayReleasePluginTests { + /** + * service discovery backend + */ @Test public void simpleTest() { + final Route[] changedRoute = new Route[1]; WebTestClient client = WebTestClient.bindToWebHandler( exchange -> { ServerHttpResponse r = exchange.getResponse(); @@ -36,7 +51,7 @@ public class GrayReleasePluginTests { " and matches('path','^/apath/x*') " + " and clientIpInRange('11.238.145.180', '11.238.145.182') " + " and exist('body.tools.gun') "); - config.put("routeType", 2); + config.put("routeType", Integer.parseInt(String.valueOf(ApiConfig.Type.SERVICE_DISCOVERY))); config.put("routeConfig", "type : http \n " + "serviceName : bservice \n " + @@ -44,6 +59,7 @@ public class GrayReleasePluginTests { // exchange.getAttributes().put("pcsit@", Collections.emptyIterator()); Route route = new Route().path("/apath/**"); + changedRoute[0] = route; exchange.getAttributes().put(WebUtils.ROUTE, route); exchange.getAttributes().put(WebUtils.IGNORE_PLUGIN, Consts.S.EMPTY); exchange.getAttributes().put(FizzPluginFilterChain.WEB_FILTER_CHAIN, chain); @@ -61,8 +77,122 @@ public class GrayReleasePluginTests { .exchange() .expectBody(String.class).value( v -> { - System.err.println("body:\n" + v); + // System.err.println("body:\n" + v); } ); + + Assertions.assertEquals("bservice", changedRoute[0].backendService); + Assertions.assertEquals("/bpath/xxx", changedRoute[0].backendPath); + } + + @Test + public void reverseProxyBackendTest() { + + final Route[] changedRoute = new Route[1]; + + Map config = new HashMap<>(); + config.put("triggerCondition", " method == 'get' "); + config.put("routeType", Integer.parseInt(String.valueOf(ApiConfig.Type.REVERSE_PROXY))); + config.put("routeConfig", + "serviceName : http://1.2.3.4:8080,http://1.2.3.5:8080 \n " + + "path : /a/b/c \n" + + "query : name1=value1&name2=value2 "); + + WebTestClient client = WebTestClient.bindToWebHandler( + exchange -> { + ServerHttpResponse r = exchange.getResponse(); + r.setStatusCode(HttpStatus.OK); + r.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE); + return r.writeWith(Mono.just(r.bufferFactory().wrap("this is web handler response".getBytes()))); + } + ) + .webFilter( + (exchange, chain) -> { + + GrayReleasePlugin grayReleasePlugin = new GrayReleasePlugin(); + + Route route = new Route().path("/apath/**"); + changedRoute[0] = route; + exchange.getAttributes().put(WebUtils.ROUTE, route); + exchange.getAttributes().put(WebUtils.IGNORE_PLUGIN, Consts.S.EMPTY); + exchange.getAttributes().put(FizzPluginFilterChain.WEB_FILTER_CHAIN, chain); + exchange.getAttributes().put("oi@", "11.238.145.181"); + + return grayReleasePlugin.filter(exchange, config); + } + ) + .build(); + + client.get() + .uri("/proxy/aservice/apath/xxx") + .exchange(); + Assertions.assertEquals("/a/b/c?name1=value1&name2=value2", changedRoute[0].getBackendPathQuery()); + Assertions.assertEquals("http://1.2.3.4:8080", changedRoute[0].nextHttpHostPort); + + client.get() + .uri("/proxy/aservice/apath/xxx") + .exchange(); + Assertions.assertEquals("http://1.2.3.5:8080", changedRoute[0].nextHttpHostPort); + + client.get() + .uri("/proxy/aservice/apath/xxx") + .exchange(); + Assertions.assertEquals("http://1.2.3.4:8080", changedRoute[0].nextHttpHostPort); + } + + @Test + public void aggregateBackendTest() { + AggregateFilter aggregateFilter = new AggregateFilter(); + ConfigLoader configLoader = mock(ConfigLoader.class); + when( + configLoader.matchAggregateResource("GET", "/_proxytest/bservice/bpath/xxx") + ) + .thenReturn(null); + ReflectionUtils.set(aggregateFilter, "configLoader", configLoader); + + WebTestClient client = WebTestClient.bindToWebHandler( + exchange -> { + ServerHttpResponse r = exchange.getResponse(); + r.setStatusCode(HttpStatus.OK); + return r.writeWith(Mono.just(r.bufferFactory().wrap("this is web handler response".getBytes()))); + } + ) + .webFilter( + (exchange, chain) -> { + + GrayReleasePlugin grayReleasePlugin = new GrayReleasePlugin(); + Map config = new HashMap<>(); + config.put("triggerCondition", " method == 'get' "); + config.put("routeType", Integer.parseInt(String.valueOf(ApiConfig.Type.SERVICE_AGGREGATE))); + config.put("routeConfig", + "type : http \n " + + "serviceName : bservice \n " + + "path : /bpath/{$1} "); + + Route route = new Route().path("/apath/**"); + exchange.getAttributes().put(WebUtils.ROUTE, route); + exchange.getAttributes().put(WebUtils.IGNORE_PLUGIN, Consts.S.EMPTY); + exchange.getAttributes().put(FizzPluginFilterChain.WEB_FILTER_CHAIN, chain); + exchange.getAttributes().put("oi@", "11.238.145.181"); + + Map filterContext = new HashMap<>(); + exchange.getAttributes().put(WebUtils.FILTER_CONTEXT, filterContext); + filterContext.put(WebUtils.PREV_FILTER_RESULT, FilterResult.SUCCESS("x")); + + return grayReleasePlugin.filter(exchange, config); + }, + aggregateFilter + ) + .build(); + + client.get() + .uri("/_proxytest/aservice/apath/xxx") + .exchange() + .expectBody(String.class).value( + v -> { + Map bodyMap = JacksonUtils.readValue(v, new TypeReference>(){}); + Assertions.assertEquals(bodyMap.get("message"), "API not found in aggregation: /_proxytest/bservice/bpath/xxx"); + } + ); } }