diff --git a/spring-cloud-gateway-server/pom.xml b/spring-cloud-gateway-server/pom.xml index 1a68615a..b4a57709 100644 --- a/spring-cloud-gateway-server/pom.xml +++ b/spring-cloud-gateway-server/pom.xml @@ -223,6 +223,18 @@ junit-jupiter test + + org.openjdk.jmh + jmh-core + 1.20 + test + + + org.openjdk.jmh + jmh-generator-annprocess + 1.20 + test + diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/predicate/PathRoutePredicateFactory.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/predicate/PathRoutePredicateFactory.java index e9772fc3..f4a1d7c7 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/predicate/PathRoutePredicateFactory.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/predicate/PathRoutePredicateFactory.java @@ -34,6 +34,7 @@ import org.springframework.web.util.pattern.PathPatternParser; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_PREDICATE_MATCHED_PATH_ATTR; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_PREDICATE_MATCHED_PATH_ROUTE_ID_ATTR; +import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_PREDICATE_PATH_CONTAINER_ATTR; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_PREDICATE_ROUTE_ATTR; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.putUriTemplateVariables; import static org.springframework.http.server.PathContainer.parsePath; @@ -89,7 +90,9 @@ public class PathRoutePredicateFactory extends AbstractRoutePredicateFactory parsePath(exchange.getRequest().getURI().getRawPath())); PathPattern match = null; for (int i = 0; i < pathPatterns.size(); i++) { diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java index 6094c933..dfcc8036 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java @@ -127,6 +127,11 @@ public final class ServerWebExchangeUtils { public static final String GATEWAY_PREDICATE_MATCHED_PATH_ROUTE_ID_ATTR = qualify( "gatewayPredicateMatchedPathRouteIdAttr"); + /** + * Gateway predicate path container attribute name. + */ + public static final String GATEWAY_PREDICATE_PATH_CONTAINER_ATTR = qualify("gatewayPredicatePathContainer"); + /** * Weight attribute name. */ diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/predicate/PathRoutePredicatePathContainerAttrBenchMarkTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/predicate/PathRoutePredicatePathContainerAttrBenchMarkTests.java new file mode 100644 index 00000000..92032d0e --- /dev/null +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/predicate/PathRoutePredicatePathContainerAttrBenchMarkTests.java @@ -0,0 +1,82 @@ +/* + * Copyright 2013-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.gateway.handler.predicate; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; +import java.util.function.Predicate; + +import org.apache.commons.lang3.RandomStringUtils; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; + +import org.springframework.mock.http.server.reactive.MockServerHttpRequest; +import org.springframework.mock.web.server.MockServerWebExchange; +import org.springframework.web.server.ServerWebExchange; + +public class PathRoutePredicatePathContainerAttrBenchMarkTests { + + private static List> predicates; + + private static String PATH_PATTERN_PREFIX; + + private final static String HOST = "http://localhost:8080"; + + private final static int ROUTES_NUM = 2000; + + static { + predicates = new LinkedList<>(); + PATH_PATTERN_PREFIX = String.format("/%s/%s/", RandomStringUtils.random(20, true, false), + RandomStringUtils.random(10, true, false)); + for (int i = 0; i < ROUTES_NUM; i++) { + PathRoutePredicateFactory.Config config = new PathRoutePredicateFactory.Config() + .setPatterns(Collections.singletonList(PATH_PATTERN_PREFIX + i)).setMatchTrailingSlash(true); + Predicate predicate = new PathRoutePredicateFactory().apply(config); + predicates.add(predicate); + } + } + + @Benchmark + @Threads(2) + @Fork(2) + @BenchmarkMode(Mode.All) + @Warmup(iterations = 1, time = 3) + @Measurement(iterations = 10, time = 1) + public void testPathContainerAttr() { + Random random = new Random(); + MockServerHttpRequest request = MockServerHttpRequest + .get(HOST + PATH_PATTERN_PREFIX + random.nextInt(ROUTES_NUM)).build(); + MockServerWebExchange exchange = MockServerWebExchange.from(request); + for (Predicate predicate : predicates) { + if (predicate.test(exchange)) { + break; + } + } + } + + public static void main(String[] args) throws Exception { + org.openjdk.jmh.Main.main(args); + } + +}