Support URL exclusion using UrlCleaner in Spring WebFlux adapter (#1049)
This commit is contained in:
parent
c505ca8aa5
commit
cdd8d6ff6c
|
|
@ -50,7 +50,7 @@ public class WebFluxConfig {
|
||||||
You can register various customized callback in `WebFluxCallbackManager`:
|
You can register various customized callback in `WebFluxCallbackManager`:
|
||||||
|
|
||||||
- `setBlockHandler`: register a customized `BlockRequestHandler` to handle the blocked request. The default implementation is `DefaultBlockRequestHandler`, which returns default message like `Blocked by Sentinel: FlowException`.
|
- `setBlockHandler`: register a customized `BlockRequestHandler` to handle the blocked request. The default implementation is `DefaultBlockRequestHandler`, which returns default message like `Blocked by Sentinel: FlowException`.
|
||||||
- `setUrlCleaner`: used for normalization of URL. The function type is `(ServerWebExchange, String) → String`, which means `(webExchange, originalUrl) → finalUrl`.
|
- `setUrlCleaner`: used for normalization of URL. The function type is `(ServerWebExchange, String) → String`, which means `(webExchange, originalUrl) → finalUrl`, if the finalUrl is `"""` or `null`, the URLs will be excluded (since Sentinel 1.7.0)..
|
||||||
- `setRequestOriginParser`: used to resolve the origin from the HTTP request. The function type is `ServerWebExchange → String`.
|
- `setRequestOriginParser`: used to resolve the origin from the HTTP request. The function type is `ServerWebExchange → String`.
|
||||||
|
|
||||||
You can also refer to the demo: [sentinel-demo-spring-webflux](https://github.com/alibaba/Sentinel/tree/master/sentinel-demo/sentinel-demo-spring-webflux).
|
You can also refer to the demo: [sentinel-demo-spring-webflux](https://github.com/alibaba/Sentinel/tree/master/sentinel-demo/sentinel-demo-spring-webflux).
|
||||||
|
|
@ -22,6 +22,7 @@ import com.alibaba.csp.sentinel.adapter.reactor.ContextConfig;
|
||||||
import com.alibaba.csp.sentinel.adapter.reactor.EntryConfig;
|
import com.alibaba.csp.sentinel.adapter.reactor.EntryConfig;
|
||||||
import com.alibaba.csp.sentinel.adapter.reactor.SentinelReactorTransformer;
|
import com.alibaba.csp.sentinel.adapter.reactor.SentinelReactorTransformer;
|
||||||
import com.alibaba.csp.sentinel.adapter.spring.webflux.callback.WebFluxCallbackManager;
|
import com.alibaba.csp.sentinel.adapter.spring.webflux.callback.WebFluxCallbackManager;
|
||||||
|
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||||
|
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
import org.springframework.web.server.WebFilter;
|
import org.springframework.web.server.WebFilter;
|
||||||
|
|
@ -36,24 +37,23 @@ public class SentinelWebFluxFilter implements WebFilter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
|
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
|
||||||
return chain.filter(exchange)
|
|
||||||
.transform(buildSentinelTransformer(exchange));
|
|
||||||
}
|
|
||||||
|
|
||||||
private SentinelReactorTransformer<Void> buildSentinelTransformer(ServerWebExchange exchange) {
|
|
||||||
// Maybe we can get the URL pattern elsewhere via:
|
// Maybe we can get the URL pattern elsewhere via:
|
||||||
// exchange.getAttributeOrDefault(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, path)
|
// exchange.getAttributeOrDefault(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, path)
|
||||||
|
|
||||||
String path = exchange.getRequest().getPath().value();
|
String path = exchange.getRequest().getPath().value();
|
||||||
String finalPath = Optional.ofNullable(WebFluxCallbackManager.getUrlCleaner())
|
|
||||||
.map(f -> f.apply(exchange, path))
|
String finalPath = WebFluxCallbackManager.getUrlCleaner().apply(exchange, path);
|
||||||
.orElse(path);
|
if (StringUtil.isEmpty(finalPath)) {
|
||||||
|
return chain.filter(exchange);
|
||||||
|
}
|
||||||
|
return chain.filter(exchange).transform(buildSentinelTransformer(exchange, finalPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
private SentinelReactorTransformer<Void> buildSentinelTransformer(ServerWebExchange exchange, String finalPath) {
|
||||||
String origin = Optional.ofNullable(WebFluxCallbackManager.getRequestOriginParser())
|
String origin = Optional.ofNullable(WebFluxCallbackManager.getRequestOriginParser())
|
||||||
.map(f -> f.apply(exchange))
|
.map(f -> f.apply(exchange))
|
||||||
.orElse(EMPTY_ORIGIN);
|
.orElse(EMPTY_ORIGIN);
|
||||||
|
|
||||||
return new SentinelReactorTransformer<>(
|
return new SentinelReactorTransformer<>(new EntryConfig(finalPath, EntryType.IN, new ContextConfig(finalPath, origin)));
|
||||||
new EntryConfig(finalPath, EntryType.IN, new ContextConfig(finalPath, origin)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String EMPTY_ORIGIN = "";
|
private static final String EMPTY_ORIGIN = "";
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,26 @@ public class SentinelWebFluxIntegrationTest {
|
||||||
WebFluxCallbackManager.resetUrlCleaner();
|
WebFluxCallbackManager.resetUrlCleaner();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCustomizedIgnoreUrlCleaner() throws Exception {
|
||||||
|
final String fooPrefix = "/foo/";
|
||||||
|
String url1 = fooPrefix + 1;
|
||||||
|
WebFluxCallbackManager.setUrlCleaner(((exchange, originUrl) -> {
|
||||||
|
if (originUrl.startsWith(fooPrefix)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return originUrl;
|
||||||
|
}));
|
||||||
|
this.webClient.get()
|
||||||
|
.uri(url1)
|
||||||
|
.exchange()
|
||||||
|
.expectStatus().isOk()
|
||||||
|
.expectBody(String.class).isEqualTo("Hello 1");
|
||||||
|
|
||||||
|
assertNull(ClusterBuilderSlot.getClusterNode(url1));
|
||||||
|
WebFluxCallbackManager.resetUrlCleaner();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCustomizedBlockRequestHandler() throws Exception {
|
public void testCustomizedBlockRequestHandler() throws Exception {
|
||||||
String url = "/error";
|
String url = "/error";
|
||||||
|
|
@ -166,4 +186,4 @@ public class SentinelWebFluxIntegrationTest {
|
||||||
FlowRuleManager.loadRules(new ArrayList<>());
|
FlowRuleManager.loadRules(new ArrayList<>());
|
||||||
ClusterBuilderSlot.resetClusterNodes();
|
ClusterBuilderSlot.resetClusterNodes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue