@Override
    protected Mono<Void> doExecute(final ServerWebExchange exchange, final ShenyuPluginChain chain, final SelectorData selector, final RuleData rule) {
        final ShenyuContext shenyuContext = exchange.getAttribute(Constants.CONTEXT);
        assert shenyuContext != null;
        final HystrixHandle hystrixHandle = HystrixPluginDataHandler.CACHED_HANDLE.get().obtainHandle(CacheKeyUtils.INST.getKey(rule));
        String groupKey = hystrixHandle.getGroupKey();
        if (StringUtils.isBlank(hystrixHandle.getGroupKey())) {
            groupKey = Objects.requireNonNull(shenyuContext).getModule();
        }
        String commandKey = hystrixHandle.getCommandKey();
        if (StringUtils.isBlank(hystrixHandle.getCommandKey())) {
            commandKey = Objects.requireNonNull(shenyuContext).getMethod();
        }
        Command command = fetchCommand(hystrixHandle, exchange, chain, commandKey, groupKey);
        return Mono.create(s -> {
            Subscription sub = command.fetchObservable().subscribe(s::success,
                    s::error, s::success);
            s.onCancel(sub::unsubscribe);
            if (command.isCircuitBreakerOpen()) {
                LOG.error("hystrix execute have circuitBreaker is Open! groupKey:{},commandKey:{}", hystrixHandle.getGroupKey(), hystrixHandle.getCommandKey());
            }
        }).doOnError(throwable -> {
            LOG.error("hystrix execute exception:", throwable);
            exchange.getAttributes().put(Constants.CLIENT_RESPONSE_RESULT_TYPE, ResultEnum.ERROR.getName());
            chain.execute(exchange);
        }).then().doFinally(monoV -> {
            final Consumer<HttpStatusCode> consumer = exchange.getAttribute(Constants.METRICS_HYSTRIX);
            Optional.ofNullable(consumer).ifPresent(c -> c.accept(exchange.getResponse().getStatusCode()));
        });
    }
@Test
    public void testDoExecute() {
        final ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("localhost").build());
        ShenyuContext shenyuContext = mock(ShenyuContext.class);
        exchange.getAttributes().put(Constants.CONTEXT, shenyuContext);
        ShenyuPluginChain chain = mock(ShenyuPluginChain.class);
        when(chain.execute(exchange)).thenReturn(Mono.empty());
        HystrixHandle hystrixHandle = new HystrixHandle();
        hystrixHandle.setGroupKey("groupKey");
        hystrixHandle.setCommandKey(" commandKey");
        hystrixHandle.setMaxConcurrentRequests(0);
        hystrixHandle.setErrorThresholdPercentage(0);
        hystrixHandle.setRequestVolumeThreshold(0);
        hystrixHandle.setSleepWindowInMilliseconds(0);
        RuleData rule = new RuleData();
        HystrixPluginDataHandler.CACHED_HANDLE.get().cachedHandle(CacheKeyUtils.INST.getKey(rule), hystrixHandle);
        rule.setHandle(GsonUtils.getInstance().toJson(hystrixHandle));
        SelectorData selectorData = mock(SelectorData.class);
        Mono<Void> mono = hystrixPlugin.doExecute(exchange, chain, selectorData, rule);
        StepVerifier.create(mono).expectSubscription().verifyComplete();
        hystrixHandle.setExecutionIsolationStrategy(HystrixIsolationModeEnum.THREAD_POOL.getCode());
        rule.setHandle(GsonUtils.getInstance().toJson(hystrixHandle));
        Mono<Void> threadMono = hystrixPlugin.doExecute(exchange, chain, selectorData, rule);
        StepVerifier.create(threadMono).expectSubscription().verifyComplete();
    }