private Map<String, String> appendConfig() {
        Map<String, String> map = new HashMap<>(16);

        map.put(INTERFACE_KEY, interfaceName);
        map.put(SIDE_KEY, CONSUMER_SIDE);

        ReferenceConfigBase.appendRuntimeParameters(map);

        if (!ProtocolUtils.isGeneric(generic)) {
            String revision = Version.getVersion(interfaceClass, version);
            if (StringUtils.isNotEmpty(revision)) {
                map.put(REVISION_KEY, revision);
            }

            String[] methods = methods(interfaceClass);
            if (methods.length == 0) {
                logger.warn(
                        CONFIG_NO_METHOD_FOUND,
                        "",
                        "",
                        "No method found in service interface: " + interfaceClass.getName());
                map.put(METHODS_KEY, ANY_VALUE);
            } else {
                map.put(METHODS_KEY, StringUtils.join(new TreeSet<>(Arrays.asList(methods)), COMMA_SEPARATOR));
            }
        }

        AbstractConfig.appendParameters(map, getApplication());
        AbstractConfig.appendParameters(map, getModule());
        AbstractConfig.appendParameters(map, consumer);
        AbstractConfig.appendParameters(map, this);

        String hostToRegistry = ConfigUtils.getSystemProperty(DUBBO_IP_TO_REGISTRY);
        if (StringUtils.isEmpty(hostToRegistry)) {
            hostToRegistry = NetUtils.getLocalHost();
        } else if (isInvalidLocalHost(hostToRegistry)) {
            throw new IllegalArgumentException("Specified invalid registry ip from property:" + DUBBO_IP_TO_REGISTRY
                    + ", value:" + hostToRegistry);
        }

        map.put(REGISTER_IP_KEY, hostToRegistry);

        if (CollectionUtils.isNotEmpty(getMethods())) {
            for (MethodConfig methodConfig : getMethods()) {
                AbstractConfig.appendParameters(map, methodConfig, methodConfig.getName());
                String retryKey = methodConfig.getName() + ".retry";
                if (map.containsKey(retryKey)) {
                    String retryValue = map.remove(retryKey);
                    if ("false".equals(retryValue)) {
                        map.put(methodConfig.getName() + ".retries", "0");
                    }
                }
            }
        }

        return map;
    }
@Test
    void testAppendConfig() {

        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("application1");
        applicationConfig.setVersion("v1");
        applicationConfig.setOwner("owner1");
        applicationConfig.setOrganization("bu1");
        applicationConfig.setArchitecture("architecture1");
        applicationConfig.setEnvironment("test");
        applicationConfig.setCompiler("javassist");
        applicationConfig.setLogger("log4j");
        applicationConfig.setDumpDirectory("/");
        applicationConfig.setQosEnable(false);
        applicationConfig.setQosHost("127.0.0.1");
        applicationConfig.setQosPort(77777);
        applicationConfig.setQosAcceptForeignIp(false);
        Map<String, String> parameters = new HashMap<>();
        parameters.put("key1", "value1");
        parameters.put("key2", "value2");
        applicationConfig.setParameters(parameters);
        applicationConfig.setShutwait("5");
        applicationConfig.setMetadataType("local");
        applicationConfig.setRegisterConsumer(false);
        applicationConfig.setRepository("repository1");
        applicationConfig.setEnableFileCache(false);
        applicationConfig.setProtocol("dubbo");
        applicationConfig.setMetadataServicePort(88888);
        applicationConfig.setMetadataServiceProtocol("tri");
        applicationConfig.setLivenessProbe("livenessProbe");
        applicationConfig.setReadinessProbe("readinessProb");
        applicationConfig.setStartupProbe("startupProbe");

        ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<>();
        referenceConfig.setClient("netty");
        referenceConfig.setGeneric(Boolean.FALSE.toString());
        referenceConfig.setProtocol("dubbo");
        referenceConfig.setInit(true);
        referenceConfig.setLazy(false);
        referenceConfig.setInjvm(false);
        referenceConfig.setReconnect("reconnect");
        referenceConfig.setSticky(false);
        referenceConfig.setStub(DEFAULT_STUB_EVENT);
        referenceConfig.setRouter("default");
        referenceConfig.setReferAsync(true);

        MonitorConfig monitorConfig = new MonitorConfig();
        applicationConfig.setMonitor(monitorConfig);

        ModuleConfig moduleConfig = new ModuleConfig();
        moduleConfig.setMonitor("default");
        moduleConfig.setName("module1");
        moduleConfig.setOrganization("application1");
        moduleConfig.setVersion("v1");
        moduleConfig.setOwner("owner1");

        ConsumerConfig consumerConfig = new ConsumerConfig();
        consumerConfig.setClient("netty");
        consumerConfig.setThreadpool("fixed");
        consumerConfig.setCorethreads(200);
        consumerConfig.setQueues(500);
        consumerConfig.setThreads(300);
        consumerConfig.setShareconnections(10);
        consumerConfig.setUrlMergeProcessor("default");
        consumerConfig.setReferThreadNum(20);
        consumerConfig.setReferBackground(false);
        referenceConfig.setConsumer(consumerConfig);

        MethodConfig methodConfig = new MethodConfig();
        methodConfig.setName("sayName");
        methodConfig.setStat(1);
        methodConfig.setRetries(0);
        methodConfig.setExecutes(10);
        methodConfig.setDeprecated(false);
        methodConfig.setSticky(false);
        methodConfig.setReturn(false);
        methodConfig.setService("service");
        methodConfig.setServiceId(DemoService.class.getName());
        methodConfig.setParentPrefix("demo");

        referenceConfig.setMethods(Collections.singletonList(methodConfig));

        referenceConfig.setInterface(DemoService.class);
        referenceConfig.getInterfaceClass();
        referenceConfig.setCheck(false);
        RegistryConfig registry = new RegistryConfig();
        registry.setAddress(zkUrl1);
        applicationConfig.setRegistries(Collections.singletonList(registry));
        applicationConfig.setRegistryIds(registry.getId());
        moduleConfig.setRegistries(Collections.singletonList(registry));

        referenceConfig.setRegistry(registry);

        DubboBootstrap dubboBootstrap = DubboBootstrap.newInstance(FrameworkModel.defaultModel());
        dubboBootstrap
                .application(applicationConfig)
                .reference(referenceConfig)
                .registry(registry)
                .module(moduleConfig)
                .initialize();

        referenceConfig.init();

        ServiceMetadata serviceMetadata = referenceConfig.getServiceMetadata();

        // verify additional side parameter
        Assertions.assertEquals(CONSUMER_SIDE, serviceMetadata.getAttachments().get(SIDE_KEY));

        // verify additional interface parameter
        Assertions.assertEquals(
                DemoService.class.getName(), serviceMetadata.getAttachments().get(INTERFACE_KEY));

        // verify additional metadata-type parameter
        Assertions.assertEquals(
                DEFAULT_METADATA_STORAGE_TYPE, serviceMetadata.getAttachments().get(METADATA_KEY));

        // verify additional register.ip parameter
        Assertions.assertEquals(
                NetUtils.getLocalHost(), serviceMetadata.getAttachments().get(REGISTER_IP_KEY));

        // verify additional runtime parameters
        Assertions.assertEquals(
                Version.getProtocolVersion(), serviceMetadata.getAttachments().get(DUBBO_VERSION_KEY));
        Assertions.assertEquals(
                Version.getVersion(), serviceMetadata.getAttachments().get(RELEASE_KEY));
        Assertions.assertTrue(serviceMetadata.getAttachments().containsKey(TIMESTAMP_KEY));
        Assertions.assertEquals(
                String.valueOf(ConfigUtils.getPid()),
                serviceMetadata.getAttachments().get(PID_KEY));

        // verify additional application config
        Assertions.assertEquals(
                applicationConfig.getName(), serviceMetadata.getAttachments().get(APPLICATION_KEY));
        Assertions.assertEquals(
                applicationConfig.getOwner(), serviceMetadata.getAttachments().get("owner"));
        Assertions.assertEquals(
                applicationConfig.getVersion(), serviceMetadata.getAttachments().get(APPLICATION_VERSION_KEY));
        Assertions.assertEquals(
                applicationConfig.getOrganization(),
                serviceMetadata.getAttachments().get("organization"));
        Assertions.assertEquals(
                applicationConfig.getArchitecture(),
                serviceMetadata.getAttachments().get("architecture"));
        Assertions.assertEquals(
                applicationConfig.getEnvironment(),
                serviceMetadata.getAttachments().get("environment"));
        Assertions.assertEquals(
                applicationConfig.getCompiler(),
                serviceMetadata.getAttachments().get("compiler"));
        Assertions.assertEquals(
                applicationConfig.getLogger(), serviceMetadata.getAttachments().get("logger"));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("registries"));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("registry.ids"));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("monitor"));
        Assertions.assertEquals(
                applicationConfig.getDumpDirectory(),
                serviceMetadata.getAttachments().get(DUMP_DIRECTORY));
        Assertions.assertEquals(
                applicationConfig.getQosEnable().toString(),
                serviceMetadata.getAttachments().get(QOS_ENABLE));
        Assertions.assertEquals(
                applicationConfig.getQosHost(), serviceMetadata.getAttachments().get(QOS_HOST));
        Assertions.assertEquals(
                applicationConfig.getQosPort().toString(),
                serviceMetadata.getAttachments().get(QOS_PORT));
        Assertions.assertEquals(
                applicationConfig.getQosAcceptForeignIp().toString(),
                serviceMetadata.getAttachments().get(ACCEPT_FOREIGN_IP));
        Assertions.assertEquals(
                applicationConfig.getParameters().get("key1"),
                serviceMetadata.getAttachments().get("key1"));
        Assertions.assertEquals(
                applicationConfig.getParameters().get("key2"),
                serviceMetadata.getAttachments().get("key2"));
        Assertions.assertEquals(
                applicationConfig.getShutwait(),
                serviceMetadata.getAttachments().get("shutwait"));
        Assertions.assertEquals(
                applicationConfig.getMetadataType(),
                serviceMetadata.getAttachments().get(METADATA_KEY));
        Assertions.assertEquals(
                applicationConfig.getRegisterConsumer().toString(),
                serviceMetadata.getAttachments().get("register.consumer"));
        Assertions.assertEquals(
                applicationConfig.getRepository(),
                serviceMetadata.getAttachments().get("repository"));
        Assertions.assertEquals(
                applicationConfig.getEnableFileCache().toString(),
                serviceMetadata.getAttachments().get(REGISTRY_LOCAL_FILE_CACHE_ENABLED));
        Assertions.assertEquals(
                applicationConfig.getMetadataServicePort().toString(),
                serviceMetadata.getAttachments().get(METADATA_SERVICE_PORT_KEY));
        Assertions.assertEquals(
                applicationConfig.getMetadataServiceProtocol().toString(),
                serviceMetadata.getAttachments().get(METADATA_SERVICE_PROTOCOL_KEY));
        Assertions.assertEquals(
                applicationConfig.getLivenessProbe(),
                serviceMetadata.getAttachments().get(LIVENESS_PROBE_KEY));
        Assertions.assertEquals(
                applicationConfig.getReadinessProbe(),
                serviceMetadata.getAttachments().get(READINESS_PROBE_KEY));
        Assertions.assertEquals(
                applicationConfig.getStartupProbe(),
                serviceMetadata.getAttachments().get(STARTUP_PROBE));

        // verify additional module config
        Assertions.assertEquals(
                moduleConfig.getName(), serviceMetadata.getAttachments().get("module"));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("monitor"));
        Assertions.assertEquals(
                moduleConfig.getOrganization(), serviceMetadata.getAttachments().get("module.organization"));
        Assertions.assertEquals(
                moduleConfig.getOwner(), serviceMetadata.getAttachments().get("module.owner"));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("registries"));
        Assertions.assertEquals(
                moduleConfig.getVersion(), serviceMetadata.getAttachments().get("module.version"));

        // verify additional consumer config
        Assertions.assertEquals(
                consumerConfig.getClient(), serviceMetadata.getAttachments().get("client"));
        Assertions.assertEquals(
                consumerConfig.getThreadpool(), serviceMetadata.getAttachments().get("threadpool"));
        Assertions.assertEquals(
                consumerConfig.getCorethreads().toString(),
                serviceMetadata.getAttachments().get("corethreads"));
        Assertions.assertEquals(
                consumerConfig.getQueues().toString(),
                serviceMetadata.getAttachments().get("queues"));
        Assertions.assertEquals(
                consumerConfig.getThreads().toString(),
                serviceMetadata.getAttachments().get("threads"));
        Assertions.assertEquals(
                consumerConfig.getShareconnections().toString(),
                serviceMetadata.getAttachments().get("shareconnections"));
        Assertions.assertEquals(
                consumerConfig.getUrlMergeProcessor(),
                serviceMetadata.getAttachments().get(URL_MERGE_PROCESSOR_KEY));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey(REFER_THREAD_NUM_KEY));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey(REFER_BACKGROUND_KEY));

        // verify additional reference config
        Assertions.assertEquals(
                referenceConfig.getClient(), serviceMetadata.getAttachments().get("client"));
        Assertions.assertEquals(
                referenceConfig.getGeneric(), serviceMetadata.getAttachments().get("generic"));
        Assertions.assertEquals(
                referenceConfig.getProtocol(), serviceMetadata.getAttachments().get("protocol"));
        Assertions.assertEquals(
                referenceConfig.isInit().toString(),
                serviceMetadata.getAttachments().get("init"));
        Assertions.assertEquals(
                referenceConfig.getLazy().toString(),
                serviceMetadata.getAttachments().get("lazy"));
        Assertions.assertEquals(
                referenceConfig.isInjvm().toString(),
                serviceMetadata.getAttachments().get("injvm"));
        Assertions.assertEquals(
                referenceConfig.getReconnect(), serviceMetadata.getAttachments().get("reconnect"));
        Assertions.assertEquals(
                referenceConfig.getSticky().toString(),
                serviceMetadata.getAttachments().get("sticky"));
        Assertions.assertEquals(
                referenceConfig.getStub(), serviceMetadata.getAttachments().get("stub"));
        Assertions.assertEquals(
                referenceConfig.getProvidedBy(),
                serviceMetadata.getAttachments().get("provided-by"));
        Assertions.assertEquals(
                referenceConfig.getRouter(), serviceMetadata.getAttachments().get("router"));
        Assertions.assertEquals(
                referenceConfig.getReferAsync().toString(),
                serviceMetadata.getAttachments().get(REFER_ASYNC_KEY));

        // verify additional method config
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("name"));
        Assertions.assertEquals(
                methodConfig.getStat().toString(),
                serviceMetadata.getAttachments().get("sayName.stat"));
        Assertions.assertEquals(
                methodConfig.getRetries().toString(),
                serviceMetadata.getAttachments().get("sayName.retries"));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("sayName.reliable"));
        Assertions.assertEquals(
                methodConfig.getExecutes().toString(),
                serviceMetadata.getAttachments().get("sayName.executes"));
        Assertions.assertEquals(
                methodConfig.getDeprecated().toString(),
                serviceMetadata.getAttachments().get("sayName.deprecated"));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("sayName.stick"));
        Assertions.assertEquals(
                methodConfig.isReturn().toString(),
                serviceMetadata.getAttachments().get("sayName.return"));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("sayName.service"));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("sayName.service.id"));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("sayName.parent.prefix"));

        // verify additional revision and methods parameter
        Assertions.assertEquals(
                Version.getVersion(referenceConfig.getInterfaceClass(), referenceConfig.getVersion()),
                serviceMetadata.getAttachments().get(REVISION_KEY));
        Assertions.assertTrue(serviceMetadata.getAttachments().containsKey(METHODS_KEY));
        Assertions.assertEquals(
                DemoService.class.getMethods().length,
                StringUtils.split((String) serviceMetadata.getAttachments().get(METHODS_KEY), ',').length);

        dubboBootstrap.stop();
    }