@Override
    protected Mono<Void> doExecute(final ServerWebExchange exchange, final ShenyuPluginChain chain, final SelectorData selector, final RuleData rule) {
        RateLimiterHandle limiterHandle = RateLimiterPluginDataHandler.CACHED_HANDLE.get()
                .obtainHandle(CacheKeyUtils.INST.getKey(rule));
        String resolverKey = Optional.ofNullable(limiterHandle.getKeyResolverName())
                .flatMap(name -> Optional.of("-" + RateLimiterKeyResolverFactory.newInstance(name).resolve(exchange)))
                .orElse("");
        return redisRateLimiter.isAllowed(rule.getId() + resolverKey, limiterHandle)
                .flatMap(response -> {
                    if (!response.isAllowed()) {
                        exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
                        final Consumer<HttpStatusCode> consumer = exchange.getAttribute(Constants.METRICS_RATE_LIMITER);
                        Optional.ofNullable(consumer).ifPresent(c -> c.accept(exchange.getResponse().getStatusCode()));
                        Object error = ShenyuResultWrap.error(exchange, ShenyuResultEnum.TOO_MANY_REQUESTS);
                        return WebFluxResultUtils.result(exchange, error);
                    }
                    return chain.execute(exchange).doFinally(signalType -> {
                        RateLimiterAlgorithm<?> rateLimiterAlgorithm = RateLimiterAlgorithmFactory.newInstance(limiterHandle.getAlgorithmName());
                        rateLimiterAlgorithm.callback(rateLimiterAlgorithm.getScript(), response.getKeys(), null);
                    });
                });
    }
@Test
    public void doExecuteAllowedTest() {
        doExecutePreInit();
        when(redisRateLimiter.isAllowed(anyString(), any(RateLimiterHandle.class))).thenReturn(
                Mono.just(new RateLimiterResponse(true, 1, null)));
        Mono<Void> result = rateLimiterPlugin.doExecute(exchange, chain, selectorData, ruleData);
        StepVerifier.create(result).expectSubscription().verifyComplete();
    }