@Deprecated
    public List<Invoker<T>> route(URL url, BitList<Invoker<T>> availableInvokers, Invocation invocation) {
        return getSingleChain(url, availableInvokers, invocation).route(url, availableInvokers, invocation);
    }
@Test
    void testRoute() {
        RouterChain<DemoService> routerChain = createRouterChanin();

        // mockInvoker will be filtered out by MockInvokersSelector
        Invoker<DemoService> mockInvoker = createMockInvoker();

        // invoker1 will be filtered out by MeshStateRouter
        Map<String, String> map1 = new HashMap<>();
        map1.put("env-sign", "yyyyyyy");
        Invoker<DemoService> invoker1 = createNormalInvoker(map1);

        // invoker2 will be filtered out by TagStateRouter
        Map<String, String> map2 = new HashMap<>();
        map2.put("env-sign", "xxx");
        map2.put("tag1", "hello");
        Invoker<DemoService> invoker2 = createNormalInvoker(map2);

        // invoker3 will be filtered out by AppStateRouter
        Map<String, String> map3 = new HashMap<>();
        map3.put("env-sign", "xxx");
        map3.put("tag1", "hello");
        map3.put(TAG_KEY, "TAG_");
        Invoker<DemoService> invoker3 = createNormalInvoker(map3);

        // invoker4 will be filtered out by ServiceStateRouter
        Map<String, String> map4 = new HashMap<>();
        map4.put("env-sign", "xxx");
        map4.put("tag1", "hello");
        map4.put(TAG_KEY, "TAG_");
        map4.put("timeout", "5000");
        Invoker<DemoService> invoker4 = createNormalInvoker(map4);

        // invoker5 is the only one returned at the end that is not filtered out
        Map<String, String> map5 = new HashMap<>();
        map5.put("env-sign", "xxx");
        map5.put("tag1", "hello");
        map5.put(TAG_KEY, "TAG_");
        map5.put("timeout", "5000");
        map5.put("serialization", "hessian2");
        Invoker<DemoService> invoker5 = createNormalInvoker(map5);

        BitList<Invoker<DemoService>> invokers =
                new BitList<>(Arrays.asList(mockInvoker, invoker1, invoker2, invoker3, invoker4, invoker5));
        routerChain.setInvokers(invokers, () -> {});

        // mesh rule for MeshStateRouter
        MeshRuleManager meshRuleManager =
                mockInvoker.getUrl().getOrDefaultModuleModel().getBeanFactory().getBean(MeshRuleManager.class);
        ConcurrentHashMap<String, MeshAppRuleListener> appRuleListeners = meshRuleManager.getAppRuleListeners();
        MeshAppRuleListener meshAppRuleListener =
                appRuleListeners.get(invoker1.getUrl().getRemoteApplication());
        ConfigChangedEvent configChangedEvent = new ConfigChangedEvent(
                "demo-route" + MESH_RULE_DATA_ID_SUFFIX,
                DynamicConfiguration.DEFAULT_GROUP,
                MESH_RULE1 + "---\n" + MESH_RULE2,
                ConfigChangeType.ADDED);
        meshAppRuleListener.process(configChangedEvent);

        // condition rule for AppStateRouter&ServiceStateRouter
        ListenableStateRouter serviceRouter = routerChain.getStateRouters().stream()
                .filter(s -> s instanceof ServiceStateRouter)
                .map(s -> (ListenableStateRouter) s)
                .findAny()
                .orElse(null);
        ConfigChangedEvent serviceConditionEvent = new ConfigChangedEvent(
                DynamicConfiguration.getRuleKey(mockInvoker.getUrl()) + ".condition-router",
                DynamicConfiguration.DEFAULT_GROUP,
                SERVICE_CONDITION_RULE,
                ConfigChangeType.ADDED);
        serviceRouter.process(serviceConditionEvent);

        ListenableStateRouter appRouter = routerChain.getStateRouters().stream()
                .filter(s -> s instanceof AppStateRouter)
                .map(s -> (ListenableStateRouter) s)
                .findAny()
                .orElse(null);
        ConfigChangedEvent appConditionEvent = new ConfigChangedEvent(
                "app.condition-router", DynamicConfiguration.DEFAULT_GROUP, APP_CONDITION_RULE, ConfigChangeType.ADDED);
        appRouter.process(appConditionEvent);

        // prepare consumerUrl and RpcInvocation
        URL consumerUrl = URL.valueOf("consumer://localhost/DemoInterface?remote.application=app1");
        RpcInvocation rpcInvocation = new RpcInvocation();
        rpcInvocation.setServiceName("DemoService");
        rpcInvocation.setObjectAttachment("trafficLabel", "xxx");
        rpcInvocation.setObjectAttachment(TAG_KEY, "TAG_");

        RpcContext.getServiceContext().setNeedPrintRouterSnapshot(true);
        RouterSnapshotSwitcher routerSnapshotSwitcher =
                FrameworkModel.defaultModel().getBeanFactory().getBean(RouterSnapshotSwitcher.class);
        routerSnapshotSwitcher.addEnabledService("org.apache.dubbo.demo.DemoService");
        // route
        List<Invoker<DemoService>> result = routerChain
                .getSingleChain(consumerUrl, invokers, rpcInvocation)
                .route(consumerUrl, invokers, rpcInvocation);
        Assertions.assertEquals(result.size(), 1);
        Assertions.assertTrue(result.contains(invoker5));

        String snapshotLog =
                "[ Parent (Input: 6) (Current Node Output: 6) (Chain Node Output: 1) ] Input: localhost:9103,localhost:9103,localhost:9103,localhost:9103,localhost:9103 -> Chain Node Output: localhost:9103...\n"
                        + "  [ MockInvokersSelector (Input: 6) (Current Node Output: 5) (Chain Node Output: 1) Router message: invocation.need.mock not set. Return normal Invokers. ] Current Node Output: localhost:9103,localhost:9103,localhost:9103,localhost:9103,localhost:9103\n"
                        + "    [ StandardMeshRuleRouter (Input: 5) (Current Node Output: 4) (Chain Node Output: 1) Router message: Match App: app Subset: isolation  ] Current Node Output: localhost:9103,localhost:9103,localhost:9103,localhost:9103\n"
                        + "      [ TagStateRouter (Input: 4) (Current Node Output: 3) (Chain Node Output: 1) Router message: Disable Tag Router. Reason: tagRouterRule is invalid or disabled ] Current Node Output: localhost:9103,localhost:9103,localhost:9103\n"
                        + "        [ ServiceStateRouter (Input: 3) (Current Node Output: 3) (Chain Node Output: 1) Router message: null ] Current Node Output: localhost:9103,localhost:9103,localhost:9103\n"
                        + "          [ ConditionStateRouter (Input: 3) (Current Node Output: 2) (Chain Node Output: 2) Router message: Match return. ] Current Node Output: localhost:9103,localhost:9103\n"
                        + "          [ ProviderAppStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 1) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: localhost:9103,localhost:9103\n"
                        + "            [ AppStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 1) Router message: null ] Current Node Output: localhost:9103,localhost:9103\n"
                        + "              [ ConditionStateRouter (Input: 2) (Current Node Output: 1) (Chain Node Output: 1) Router message: Match return. ] Current Node Output: localhost:9103\n"
                        + "              [ AppScriptStateRouter (Input: 1) (Current Node Output: 1) (Chain Node Output: 1) Router message: Directly return from script router. Reason: Invokers from previous router is empty or script is not enabled. Script rule is: null ] Current Node Output: localhost:9103";
        String[] snapshot = routerSnapshotSwitcher.cloneSnapshot();
        Assertions.assertTrue(snapshot[0].contains(snapshotLog));

        RpcContext.getServiceContext().setNeedPrintRouterSnapshot(false);
        result = routerChain
                .getSingleChain(consumerUrl, invokers, rpcInvocation)
                .route(consumerUrl, invokers, rpcInvocation);
        Assertions.assertEquals(result.size(), 1);
        Assertions.assertTrue(result.contains(invoker5));

        routerChain.destroy();
        Assertions.assertEquals(routerChain.getRouters().size(), 0);
        Assertions.assertEquals(routerChain.getStateRouters().size(), 0);
    }