Browse Source

Support URL exclusion using UrlCleaner in Spring WebFlux adapter (#1049)

master
于玉桔 Eric Zhao 5 years ago
parent
commit
cdd8d6ff6c
3 changed files with 33 additions and 13 deletions
  1. +1
    -1
      sentinel-adapter/sentinel-spring-webflux-adapter/README.md
  2. +11
    -11
      sentinel-adapter/sentinel-spring-webflux-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/spring/webflux/SentinelWebFluxFilter.java
  3. +21
    -1
      sentinel-adapter/sentinel-spring-webflux-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/spring/webflux/SentinelWebFluxIntegrationTest.java

+ 1
- 1
sentinel-adapter/sentinel-spring-webflux-adapter/README.md View File

@@ -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).

+ 11
- 11
sentinel-adapter/sentinel-spring-webflux-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/spring/webflux/SentinelWebFluxFilter.java View File

@@ -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 = "";


+ 21
- 1
sentinel-adapter/sentinel-spring-webflux-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/spring/webflux/SentinelWebFluxIntegrationTest.java View File

@@ -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…
Cancel
Save