public synchronized void doMigrate(MigrationRule rule) {
        if (migrationInvoker instanceof ServiceDiscoveryMigrationInvoker) {
            refreshInvoker(MigrationStep.FORCE_APPLICATION, 1.0f, rule);
            return;
        }

        // initial step : APPLICATION_FIRST
        MigrationStep step = MigrationStep.APPLICATION_FIRST;
        float threshold = -1f;

        try {
            step = rule.getStep(consumerURL);
            threshold = rule.getThreshold(consumerURL);
        } catch (Exception e) {
            logger.error(
                    REGISTRY_NO_PARAMETERS_URL, "", "", "Failed to get step and threshold info from rule: " + rule, e);
        }

        if (refreshInvoker(step, threshold, rule)) {
            // refresh success, update rule
            setMigrationRule(rule);
        }
    }
@Test
    void test() {
        MigrationClusterInvoker<?> invoker = Mockito.mock(MigrationClusterInvoker.class);
        URL url = Mockito.mock(URL.class);
        Mockito.when(url.getDisplayServiceKey()).thenReturn("test");
        Mockito.when(url.getParameter(Mockito.any(), (String) Mockito.any())).thenAnswer(i -> i.getArgument(1));
        Mockito.when(url.getOrDefaultApplicationModel()).thenReturn(ApplicationModel.defaultModel());
        MigrationRuleHandler<?> handler = new MigrationRuleHandler<>(invoker, url);

        Mockito.when(invoker.migrateToForceApplicationInvoker(Mockito.any())).thenReturn(true);
        Mockito.when(invoker.migrateToForceInterfaceInvoker(Mockito.any())).thenReturn(true);

        MigrationRule initRule = MigrationRule.getInitRule();
        handler.doMigrate(initRule);
        Mockito.verify(invoker, Mockito.times(1)).migrateToApplicationFirstInvoker(initRule);

        MigrationRule rule = Mockito.mock(MigrationRule.class);
        Mockito.when(rule.getStep(url)).thenReturn(MigrationStep.FORCE_APPLICATION);
        handler.doMigrate(rule);
        Mockito.verify(invoker, Mockito.times(1)).migrateToForceApplicationInvoker(rule);

        Mockito.when(rule.getStep(url)).thenReturn(MigrationStep.APPLICATION_FIRST);
        handler.doMigrate(rule);
        Mockito.verify(invoker, Mockito.times(1)).migrateToApplicationFirstInvoker(rule);

        Mockito.when(rule.getStep(url)).thenReturn(MigrationStep.FORCE_INTERFACE);
        handler.doMigrate(rule);
        Mockito.verify(invoker, Mockito.times(1)).migrateToForceInterfaceInvoker(rule);

        // migration failed, current rule not changed
        testMigrationFailed(rule, url, handler, invoker);
        // rule not changed, check migration not actually executed
        testMigrationWithStepUnchanged(rule, url, handler, invoker);
    }