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`:
|
||||
|
||||
- `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`.
|
||||
|
||||
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.SentinelReactorTransformer;
|
||||
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.WebFilter;
|
||||
|
|
@ -36,24 +37,23 @@ public class SentinelWebFluxFilter implements WebFilter {
|
|||
|
||||
@Override
|
||||
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:
|
||||
// exchange.getAttributeOrDefault(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, path)
|
||||
|
||||
String path = exchange.getRequest().getPath().value();
|
||||
String finalPath = Optional.ofNullable(WebFluxCallbackManager.getUrlCleaner())
|
||||
.map(f -> f.apply(exchange, path))
|
||||
.orElse(path);
|
||||
|
||||
String finalPath = WebFluxCallbackManager.getUrlCleaner().apply(exchange, 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())
|
||||
.map(f -> f.apply(exchange))
|
||||
.orElse(EMPTY_ORIGIN);
|
||||
|
||||
return new SentinelReactorTransformer<>(
|
||||
new EntryConfig(finalPath, EntryType.IN, new ContextConfig(finalPath, origin)));
|
||||
return new SentinelReactorTransformer<>(new EntryConfig(finalPath, EntryType.IN, new ContextConfig(finalPath, origin)));
|
||||
}
|
||||
|
||||
private static final String EMPTY_ORIGIN = "";
|
||||
|
|
|
|||
|
|
@ -101,6 +101,26 @@ public class SentinelWebFluxIntegrationTest {
|
|||
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
|
||||
public void testCustomizedBlockRequestHandler() throws Exception {
|
||||
String url = "/error";
|
||||
|
|
@ -166,4 +186,4 @@ public class SentinelWebFluxIntegrationTest {
|
|||
FlowRuleManager.loadRules(new ArrayList<>());
|
||||
ClusterBuilderSlot.resetClusterNodes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue