Adds attribute for PathContainer to avoid repeating parsePath in PathRoutePredicateFactory
Fixes gh-2884
This commit is contained in:
@@ -170,6 +170,17 @@
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-core</artifactId>
|
||||
<version>1.20</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-generator-annprocess</artifactId>
|
||||
<version>1.20</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
@@ -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,12 @@ public class PathRoutePredicateFactory extends AbstractRoutePredicateFactory<Pat
|
||||
return new GatewayPredicate() {
|
||||
@Override
|
||||
public boolean test(ServerWebExchange exchange) {
|
||||
PathContainer path = parsePath(exchange.getRequest().getURI().getRawPath());
|
||||
PathContainer path = (PathContainer) exchange.getAttributes()
|
||||
.get(GATEWAY_PREDICATE_PATH_CONTAINER_ATTR);
|
||||
if (path == null) {
|
||||
path = parsePath(exchange.getRequest().getURI().getRawPath());
|
||||
exchange.getAttributes().put(GATEWAY_PREDICATE_PATH_CONTAINER_ATTR, path);
|
||||
}
|
||||
|
||||
PathPattern match = null;
|
||||
for (int i = 0; i < pathPatterns.size(); i++) {
|
||||
|
||||
@@ -122,6 +122,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.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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<Predicate<ServerWebExchange>> 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<ServerWebExchange> 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<ServerWebExchange> predicate : predicates) {
|
||||
if (predicate.test(exchange)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user