This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git

commit b74bcd79b50a808f46eb2ad80ff63ded6e519e7f
Author: liubao68 <[email protected]>
AuthorDate: Wed Jun 2 17:09:27 2021 +0800

    [SCB-2273]support kie latest layered configuration. Part1: kie 
implementation
---
 .../config/center/client/AddressManager.java       |   4 +
 .../config/center/client/ConfigCenterManager.java  |  20 +--
 .../servicecomb/config/common/ConfigConverter.java |  92 ++++++++++
 .../servicecomb/config/kie/client/KieClient.java   | 148 ++++-----------
 .../config/kie/client/KieConfigManager.java        |  87 +++++++--
 .../kie/client/model/ConfigurationsRequest.java    |  61 ++++---
 .../client/model/ConfigurationsRequestFactory.java |  94 ++++++++++
 .../config/kie/client/model/KieAddressManager.java |  19 +-
 .../config/kie/client/model/KieConfiguration.java  | 152 ++++++++++++++++
 .../servicecomb/http/client/task/AbstractTask.java |  27 ++-
 .../center/client/ServiceCenterConfiguration.java  |  32 ----
 .../center/client/ServiceCenterDiscovery.java      |  35 +++-
 .../center/client/ServiceCenterRegistration.java   |  38 ++--
 .../client/model/ServiceCenterConfiguration.java   |  24 +--
 .../RegistryClientTest.java                        |   5 +-
 dynamic-config/config-kie/pom.xml                  |   4 +
 .../config/kie/{client => }/KieConfig.java         |  50 +++++-
 .../config/kie/KieConfigurationSourceImpl.java     | 172 ++++++++++++++++++
 .../servicecomb/config/kie/TransportUtils.java     | 118 ++++++++++++
 .../sources/KieConfigurationSourceImpl.java        | 138 --------------
 .../kie/client/ConfigKieHttpClientOptionsSPI.java  | 175 ------------------
 .../config/kie/client/ConnSuccEvent.java           |  22 ---
 .../servicecomb/config/kie/client/KieClient.java   | 176 ------------------
 .../servicecomb/config/kie/client/KieUtil.java     | 154 ----------------
 .../servicecomb/config/kie/client/KieWatcher.java  |  86 ---------
 .../servicecomb/config/kie/model/KVBody.java       |  65 -------
 .../apache/servicecomb/config/kie/model/KVDoc.java | 127 -------------
 .../servicecomb/config/kie/model/KVResponse.java   |  53 ------
 .../config/kie/model/LabelDocResponse.java         |  46 -----
 .../servicecomb/config/kie/model/ValueType.java    |  27 ---
 ...comb.config.spi.ConfigCenterConfigurationSource |   2 +-
 .../config/kie/client/TestKieClient.java           | 200 ---------------------
 .../config/kie/client/TestKieConfig.java           |  46 -----
 .../servicecomb/config/kie/client/TestKieUtil.java |  62 -------
 .../config/kie/client/TestKieWatcher.java          |  54 ------
 .../kie/sources/TestKieConfigurationSource.java    |  96 ----------
 36 files changed, 939 insertions(+), 1772 deletions(-)

diff --git 
a/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/AddressManager.java
 
b/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/AddressManager.java
index fb4e7ef..cc073ff 100644
--- 
a/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/AddressManager.java
+++ 
b/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/AddressManager.java
@@ -63,4 +63,8 @@ public class AddressManager {
       return addresses.get(index);
     }
   }
+
+  public boolean sslEnabled() {
+    return address().startsWith("https://";);
+  }
 }
diff --git 
a/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterManager.java
 
b/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterManager.java
index ab63198..054d565 100644
--- 
a/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterManager.java
+++ 
b/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterManager.java
@@ -17,11 +17,9 @@
 
 package org.apache.servicecomb.config.center.client;
 
-import java.util.Collections;
-import java.util.Map;
-
 import 
org.apache.servicecomb.config.center.client.model.QueryConfigurationsRequest;
 import 
org.apache.servicecomb.config.center.client.model.QueryConfigurationsResponse;
+import org.apache.servicecomb.config.common.ConfigConverter;
 import org.apache.servicecomb.config.common.ConfigurationChangedEvent;
 import org.apache.servicecomb.http.client.task.AbstractTask;
 import org.apache.servicecomb.http.client.task.Task;
@@ -42,18 +40,14 @@ public class ConfigCenterManager extends AbstractTask {
 
   private QueryConfigurationsRequest queryConfigurationsRequest;
 
-  private Map<String, Object> lastConfiguration;
-
-  public ConfigCenterManager(ConfigCenterClient configCenterClient, EventBus 
eventBus) {
-    this(configCenterClient, eventBus, Collections.emptyMap());
-  }
+  private ConfigConverter configConverter;
 
   public ConfigCenterManager(ConfigCenterClient configCenterClient, EventBus 
eventBus,
-      Map<String, Object> lastConfiguration) {
+      ConfigConverter configConverter) {
     super("config-center-configuration-task");
     this.configCenterClient = configCenterClient;
     this.eventBus = eventBus;
-    this.lastConfiguration = lastConfiguration;
+    this.configConverter = configConverter;
   }
 
   public void setQueryConfigurationsRequest(QueryConfigurationsRequest 
queryConfigurationsRequest) {
@@ -77,8 +71,10 @@ public class ConfigCenterManager extends AbstractTask {
         QueryConfigurationsResponse response = 
configCenterClient.queryConfigurations(queryConfigurationsRequest);
         if (response.isChanged()) {
           queryConfigurationsRequest.setRevision(response.getRevision());
-          
eventBus.post(ConfigurationChangedEvent.createIncremental(response.getConfigurations(),
 lastConfiguration));
-          lastConfiguration = response.getConfigurations();
+          ConfigurationChangedEvent event = ConfigurationChangedEvent
+              .createIncremental(response.getConfigurations(), 
configConverter.getLastRawData());
+          configConverter.updateData(response.getConfigurations());
+          eventBus.post(event);
         }
         startTask(new BackOffSleepTask(POLL_INTERVAL, new 
PollConfigurationTask(0)));
       } catch (Exception e) {
diff --git 
a/clients/config-common/src/main/java/org/apache/servicecomb/config/common/ConfigConverter.java
 
b/clients/config-common/src/main/java/org/apache/servicecomb/config/common/ConfigConverter.java
new file mode 100644
index 0000000..5f55f99
--- /dev/null
+++ 
b/clients/config-common/src/main/java/org/apache/servicecomb/config/common/ConfigConverter.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.config.common;
+
+import java.nio.charset.Charset;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
+import org.springframework.core.io.ByteArrayResource;
+import org.springframework.util.CollectionUtils;
+
+public class ConfigConverter {
+  private Map<String, Object> currentData = Collections.emptyMap();
+
+  private Map<String, Object> lastRawData;
+
+  private final List<String> fileSources;
+
+  public ConfigConverter(List<String> fileSources) {
+    this.fileSources = fileSources;
+  }
+
+  public Map<String, Object> getLastRawData() {
+    return this.lastRawData;
+  }
+
+  public Map<String, Object> getCurrentData() {
+    return this.currentData;
+  }
+
+  public void updateData(Map<String, Object> rawData) {
+    this.lastRawData = rawData;
+
+    if (CollectionUtils.isEmpty(fileSources)) {
+      this.currentData = rawData;
+      return;
+    }
+
+    Map<String, Object> fileProperties = new HashMap<>();
+    fileSources.forEach(source -> {
+      if (rawData.get(source) != null) {
+        fileProperties.put(source, rawData.get(source));
+      }
+    });
+
+    Map<String, Object> result = new HashMap<>(rawData.size());
+    result.putAll(rawData);
+    fileProperties.forEach((k, v) -> result.putAll(createFileSource(v)));
+    this.currentData = result;
+  }
+
+  private Map<String, Object> createFileSource(Object v) {
+    YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
+    yamlFactory.setResources(new 
ByteArrayResource(v.toString().getBytes(Charset.forName("UTF-8"))));
+    return propertiesToMap(yamlFactory.getObject());
+  }
+
+  @SuppressWarnings("unchecked")
+  private Map<String, Object> propertiesToMap(Properties properties) {
+    if (properties == null) {
+      return Collections.emptyMap();
+    }
+    Map<String, Object> result = new HashMap<>();
+    Enumeration<String> keys = (Enumeration<String>) 
properties.propertyNames();
+    while (keys.hasMoreElements()) {
+      String key = keys.nextElement();
+      Object value = properties.getProperty(key);
+      result.put(key, value);
+    }
+    return result;
+  }
+}
diff --git 
a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieClient.java
 
b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieClient.java
index 6b24969..4a1fdb6 100644
--- 
a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieClient.java
+++ 
b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieClient.java
@@ -17,7 +17,14 @@
 
 package org.apache.servicecomb.config.kie.client;
 
-import org.apache.commons.lang3.StringUtils;
+import java.io.StringReader;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.stream.Collectors;
+
 import org.apache.http.HttpStatus;
 import org.apache.servicecomb.config.kie.client.exception.OperationException;
 import org.apache.servicecomb.config.kie.client.model.ConfigConstants;
@@ -26,6 +33,7 @@ import 
org.apache.servicecomb.config.kie.client.model.ConfigurationsResponse;
 import org.apache.servicecomb.config.kie.client.model.KVDoc;
 import org.apache.servicecomb.config.kie.client.model.KVResponse;
 import org.apache.servicecomb.config.kie.client.model.KieAddressManager;
+import org.apache.servicecomb.config.kie.client.model.KieConfiguration;
 import org.apache.servicecomb.config.kie.client.model.ValueType;
 import org.apache.servicecomb.http.client.common.HttpRequest;
 import org.apache.servicecomb.http.client.common.HttpResponse;
@@ -36,76 +44,52 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
 import org.springframework.core.io.ByteArrayResource;
 
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.atomic.AtomicBoolean;
-
 public class KieClient implements KieConfigOperation {
 
   private static final Logger LOGGER = 
LoggerFactory.getLogger(KieClient.class);
 
-  private AtomicBoolean isFirst = new AtomicBoolean(true);
-
   protected HttpTransport httpTransport;
 
   protected String revision = "0";
 
-  private String url;
+  private final KieAddressManager addressManager;
 
-  private HttpResponse httpResponse = null;
-
-  private KieAddressManager addressManager;
-
-  private Map<String, String> labelsMap;
+  private final KieConfiguration kieConfiguration;
 
   public static final String DEFAULT_KIE_API_VERSION = "v1";
 
-  public KieClient(KieAddressManager addressManager, HttpTransport 
httpTransport) {
+  public KieClient(KieAddressManager addressManager, HttpTransport 
httpTransport, KieConfiguration kieConfiguration) {
     this.httpTransport = httpTransport;
     this.addressManager = addressManager;
+    this.kieConfiguration = kieConfiguration;
   }
 
   @Override
   public ConfigurationsResponse queryConfigurations(ConfigurationsRequest 
request) {
-    boolean isWatch = false;
-    if 
(Boolean.valueOf(getPropertiesValue(getConfigKeyValue(ConfigConstants.KEY_ENABLELONGPOLLING))))
 {
-      isWatch = true;
-    }
     try {
-      url = addressManager.address()
+      String url = addressManager.address()
           + "/"
           + DEFAULT_KIE_API_VERSION
           + "/"
-          + getPropertiesValue(getConfigKeyValue(ConfigConstants.KEY_PROJECT))
-          + "/kie/kv?label=app:"
-          //app 名称作为筛选条件
-          + request.getApplication()
+          + kieConfiguration.getProject()
+          + "/kie/kv?"
+          + request.getLabelsQuery()
           + "&revision="
-          + revision;
+          + request.getRevision()
+          + "&withExact="
+          + request.isWithExact();
 
-      if (isWatch && !isFirst.get()) {
-        url +=
-            "&wait=" + 
getPropertiesValue(getConfigKeyValue(ConfigConstants.KEY_POLLINGWAITSEC)) + "s";
-      }
-      isFirst.compareAndSet(true, false);
-      Map<String, String> headers = new HashMap<>();
-      headers.put("environment", request.getEnvironment());
-      HttpRequest httpRequest = new HttpRequest(url, headers, null, 
HttpRequest.GET);
-      httpResponse = httpTransport.doRequest(httpRequest);
-      if (httpResponse == null) {
-        return null;
+      if (kieConfiguration.isEnableLongPolling()) {
+        url += "&wait=" + kieConfiguration.getPollingWaitInSeconds() + "s";
       }
+
+      HttpRequest httpRequest = new HttpRequest(url, null, null, 
HttpRequest.GET);
+      HttpResponse httpResponse = httpTransport.doRequest(httpRequest);
       ConfigurationsResponse configurationsResponse = new 
ConfigurationsResponse();
       if (httpResponse.getStatusCode() == HttpStatus.SC_OK) {
         revision = httpResponse.getHeader("X-Kie-Revision");
         KVResponse allConfigList = 
HttpUtils.deserialize(httpResponse.getContent(), KVResponse.class);
-        Map<String, Object> configurations = getConfigByLabel(allConfigList, 
request);
+        Map<String, Object> configurations = getConfigByLabel(allConfigList);
         configurationsResponse.setConfigurations(configurations);
         configurationsResponse.setChanged(true);
         configurationsResponse.setRevision(revision);
@@ -121,80 +105,41 @@ public class KieClient implements KieConfigOperation {
       throw new OperationException(
           "read response failed. status:" + httpResponse.getStatusCode() + "; 
message:" +
               httpResponse.getMessage() + "; content:" + 
httpResponse.getContent());
-
     } catch (Exception e) {
       addressManager.nextAddress();
       throw new OperationException("read response failed. ", e);
     }
   }
 
-  private Map<String, Object> getConfigByLabel(KVResponse resp, 
ConfigurationsRequest request) {
+  private Map<String, Object> getConfigByLabel(KVResponse resp) {
     Map<String, Object> resultMap = new HashMap<>();
-    List<KVDoc> appList = new ArrayList<>();
-    List<KVDoc> serviceList = new ArrayList<>();
-    List<KVDoc> versionList = new ArrayList<>();
-    for (KVDoc kvDoc : resp.getData()) {
-      if (!StringUtils.isEmpty(kvDoc.getStatus()) && !kvDoc.getStatus()
-          .equals(ConfigConstants.STATUS_ENABLED)) {
-        continue;
-      }
-      labelsMap = kvDoc.getLabels();
-      boolean checkApplication = checkValue(ConfigConstants.LABEL_APP, 
request.getApplication());
-      boolean checkEnvironment = checkValue(ConfigConstants.LABEL_ENV, 
request.getEnvironment());
-      boolean checkServer = checkValue(ConfigConstants.LABEL_SERVICE, 
request.getServiceName());
-      boolean checkVersion = checkValue(ConfigConstants.LABEL_VERSION, 
request.getVersion());
-      if (checkApplication && checkEnvironment && 
!labelsMap.containsKey(ConfigConstants.LABEL_SERVICE)) {
-          appList.add(kvDoc);
-      }
-      if (checkApplication && checkEnvironment && checkServer && 
!kvDoc.getLabels().containsKey(ConfigConstants.LABEL_VERSION)) {
-        serviceList.add(kvDoc);
-      }
-      if (checkApplication && checkEnvironment && checkServer && checkVersion) 
{
-        versionList.add(kvDoc);
-      }
-    }
-    //kv is priority
-    for (KVDoc kvDoc : appList) {
-      resultMap.putAll(processValueType(kvDoc));
-    }
-    for (KVDoc kvDoc : serviceList) {
-      resultMap.putAll(processValueType(kvDoc));
-    }
-    for (KVDoc kvDoc : versionList) {
-      resultMap.putAll(processValueType(kvDoc));
-    }
+    resp.getData().stream()
+        .filter(doc -> doc.getStatus() == null || 
ConfigConstants.STATUS_ENABLED.equalsIgnoreCase(doc.getStatus()))
+        .map(this::processValueType)
+        .collect(Collectors.toList())
+        .forEach(resultMap::putAll);
     return resultMap;
   }
 
-  private boolean checkValue(String key, String propertyName) {
-    if (!labelsMap.containsKey(key)) {
-      return false;
-    }
-    if (!labelsMap.get(key).equals(propertyName)) {
-      return false;
-    }
-    return true;
-  }
-
   private Map<String, Object> processValueType(KVDoc kvDoc) {
-    ValueType vtype;
+    ValueType valueType;
     try {
-      vtype = ValueType.valueOf(kvDoc.getValueType());
+      valueType = ValueType.valueOf(kvDoc.getValueType());
     } catch (IllegalArgumentException e) {
       throw new OperationException("value type not support");
     }
     Properties properties = new Properties();
     Map<String, Object> kvMap = new HashMap<>();
     try {
-      switch (vtype) {
+      switch (valueType) {
         case yml:
         case yaml:
           YamlPropertiesFactoryBean yamlFactory = new 
YamlPropertiesFactoryBean();
           yamlFactory.setResources(new 
ByteArrayResource(kvDoc.getValue().getBytes()));
-          return toMap(kvDoc.getKey(), yamlFactory.getObject());
+          return toMap(yamlFactory.getObject());
         case properties:
           properties.load(new StringReader(kvDoc.getValue()));
-          return toMap(kvDoc.getKey(), properties);
+          return toMap(properties);
         case text:
         case string:
         default:
@@ -208,7 +153,7 @@ public class KieClient implements KieConfigOperation {
   }
 
   @SuppressWarnings("unchecked")
-  private Map<String, Object> toMap(String prefix, Properties properties) {
+  private Map<String, Object> toMap(Properties properties) {
     if (properties == null) {
       return Collections.emptyMap();
     }
@@ -217,23 +162,8 @@ public class KieClient implements KieConfigOperation {
     while (keys.hasMoreElements()) {
       String key = keys.nextElement();
       Object value = properties.getProperty(key);
-      if (!StringUtils.isEmpty(prefix)) {
-        key = prefix + "." + key;
-      }
-      if (value != null) {
-        result.put(key, value);
-      } else {
-        result.put(key, null);
-      }
+      result.put(key, value);
     }
     return result;
   }
-
-  private String getPropertiesValue(String key) {
-    return this.addressManager.getProperties().getProperty(key);
-  }
-
-  private String getConfigKeyValue(String key) {
-    return this.addressManager.getConfigKey().get(key);
-  }
 }
diff --git 
a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieConfigManager.java
 
b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieConfigManager.java
index f636ffe..567e8fa 100644
--- 
a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieConfigManager.java
+++ 
b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieConfigManager.java
@@ -17,12 +17,17 @@
 
 package org.apache.servicecomb.config.kie.client;
 
-import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.concurrent.Executors;
 
+import org.apache.servicecomb.config.common.ConfigConverter;
 import org.apache.servicecomb.config.common.ConfigurationChangedEvent;
 import org.apache.servicecomb.config.kie.client.model.ConfigurationsRequest;
+import 
org.apache.servicecomb.config.kie.client.model.ConfigurationsRequestFactory;
 import org.apache.servicecomb.config.kie.client.model.ConfigurationsResponse;
+import org.apache.servicecomb.config.kie.client.model.KieConfiguration;
 import org.apache.servicecomb.http.client.task.AbstractTask;
 import org.apache.servicecomb.http.client.task.Task;
 import org.slf4j.Logger;
@@ -40,35 +45,77 @@ public class KieConfigManager extends AbstractTask {
 
   private final EventBus eventBus;
 
-  private ConfigurationsRequest configurationsRequest;
+  private ConfigConverter configConverter;
 
-  private Map<String, Object> lastConfiguration;
+  private List<ConfigurationsRequest> configurationsRequests;
 
-  public KieConfigManager(KieConfigOperation configKieClient, EventBus 
eventBus) {
-    this(configKieClient, eventBus, Collections.emptyMap());
-  }
+  private KieConfiguration kieConfiguration;
 
   public KieConfigManager(KieConfigOperation configKieClient, EventBus 
eventBus,
-      Map<String, Object> lastConfiguration) {
+      KieConfiguration kieConfiguration,
+      ConfigConverter configConverter) {
     super("config-center-configuration-task");
+    this.configurationsRequests = 
ConfigurationsRequestFactory.buildConfigurationRequests(kieConfiguration);
+    this.configurationsRequests.sort(ConfigurationsRequest::compareTo);
     this.configKieClient = configKieClient;
     this.eventBus = eventBus;
-    this.lastConfiguration = lastConfiguration;
+    this.configConverter = configConverter;
+    this.kieConfiguration = kieConfiguration;
+  }
+
+  public void firstPull() {
+    try {
+      Map<String, Object> data = new HashMap<>();
+      this.configurationsRequests.forEach(r -> {
+        r.setRevision(ConfigurationsRequest.INITIAL_REVISION);
+        ConfigurationsResponse response = 
configKieClient.queryConfigurations(r);
+        if (response.isChanged()) {
+          r.setRevision(response.getRevision());
+          r.setLastRawData(response.getConfigurations());
+          data.putAll(response.getConfigurations());
+        } else {
+          throw new IllegalStateException("can not fetch config data.");
+        }
+      });
+      this.configConverter.updateData(data);
+    } catch (RuntimeException e) {
+      if (this.kieConfiguration.isFirstPullRequired()) {
+        throw e;
+      } else {
+        LOGGER.warn("first pull failed, and ignore {}", e.getMessage());
+      }
+    }
+  }
+
+  private void onDataChanged() {
+    Map<String, Object> lastData = new HashMap<>();
+    this.configurationsRequests.forEach(r -> 
lastData.putAll(r.getLastRawData()));
+
+    ConfigurationChangedEvent event = ConfigurationChangedEvent
+        .createIncremental(lastData, configConverter.getLastRawData());
+    configConverter.updateData(lastData);
+    eventBus.post(event);
   }
 
-  public void setConfigurationsRequest(ConfigurationsRequest 
configurationsRequest) {
-    this.configurationsRequest = configurationsRequest;
+  @Override
+  protected void initTaskPool(String taskName) {
+    this.taskPool = Executors.newFixedThreadPool(3, (task) ->
+        new Thread(task, taskName));
   }
 
   public void startConfigKieManager() {
-    this.startTask(new PollConfigurationTask(0));
+    this.configurationsRequests.forEach((t) ->
+        this.startTask(new PollConfigurationTask(0, t)));
   }
 
   class PollConfigurationTask implements Task {
-    int failCount = 0;
+    final int failCount;
+
+    ConfigurationsRequest configurationsRequest;
 
-    public PollConfigurationTask(int failCount) {
+    public PollConfigurationTask(int failCount, ConfigurationsRequest 
configurationsRequest) {
       this.failCount = failCount;
+      this.configurationsRequest = configurationsRequest;
     }
 
     @Override
@@ -76,15 +123,19 @@ public class KieConfigManager extends AbstractTask {
       try {
         ConfigurationsResponse response = 
configKieClient.queryConfigurations(configurationsRequest);
         if (response.isChanged()) {
-          LOGGER.info("The configurations are change, will refresh local 
configurations.");
           configurationsRequest.setRevision(response.getRevision());
-          
eventBus.post(ConfigurationChangedEvent.createIncremental(response.getConfigurations(),
 lastConfiguration));
-          lastConfiguration = response.getConfigurations();
+          configurationsRequest.setLastRawData(response.getConfigurations());
+          onDataChanged();
+        }
+        if (KieConfigManager.this.kieConfiguration.isEnableLongPolling()) {
+          startTask(new BackOffSleepTask(POLL_INTERVAL, new 
PollConfigurationTask(0, this.configurationsRequest)));
+        } else {
+          startTask(new PollConfigurationTask(0, this.configurationsRequest));
         }
-        startTask(new BackOffSleepTask(POLL_INTERVAL, new 
PollConfigurationTask(0)));
       } catch (Exception e) {
         LOGGER.error("get configurations from KieConfigCenter failed, and will 
try again.", e);
-        startTask(new BackOffSleepTask(failCount + 1, new 
PollConfigurationTask(failCount + 1)));
+        startTask(
+            new BackOffSleepTask(failCount + 1, new 
PollConfigurationTask(failCount + 1, this.configurationsRequest)));
       }
     }
   }
diff --git 
a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/ConfigurationsRequest.java
 
b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/ConfigurationsRequest.java
index 1523334..cbf9647 100644
--- 
a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/ConfigurationsRequest.java
+++ 
b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/ConfigurationsRequest.java
@@ -17,59 +17,68 @@
 
 package org.apache.servicecomb.config.kie.client.model;
 
-public class ConfigurationsRequest {
-  private String environment;
+import java.util.Map;
 
-  private String application;
+public class ConfigurationsRequest implements 
Comparable<ConfigurationsRequest> {
+  public static final String INITIAL_REVISION = "0";
 
-  private String serviceName;
+  private int order;
 
-  private String version;
+  private String revision = INITIAL_REVISION;
 
-  private String revision;
+  private boolean withExact;
 
-  public String getEnvironment() {
-    return environment;
+  private String labelsQuery;
+
+  private Map<String, Object> lastRawData;
+
+  public int getOrder() {
+    return order;
   }
 
-  public ConfigurationsRequest setEnvironment(String environment) {
-    this.environment = environment;
+  public ConfigurationsRequest setOrder(int order) {
+    this.order = order;
     return this;
   }
 
-  public String getApplication() {
-    return application;
+  public String getRevision() {
+    return revision;
   }
 
-  public ConfigurationsRequest setApplication(String application) {
-    this.application = application;
+  public ConfigurationsRequest setRevision(String revision) {
+    this.revision = revision;
     return this;
   }
 
-  public String getServiceName() {
-    return serviceName;
+  public boolean isWithExact() {
+    return withExact;
   }
 
-  public ConfigurationsRequest setServiceName(String serviceName) {
-    this.serviceName = serviceName;
+  public ConfigurationsRequest setWithExact(boolean withExact) {
+    this.withExact = withExact;
     return this;
   }
 
-  public String getVersion() {
-    return version;
+  public String getLabelsQuery() {
+    return labelsQuery;
   }
 
-  public ConfigurationsRequest setVersion(String version) {
-    this.version = version;
+  public ConfigurationsRequest setLabelsQuery(String labelsQuery) {
+    this.labelsQuery = labelsQuery;
     return this;
   }
 
-  public String getRevision() {
-    return revision;
+  public Map<String, Object> getLastRawData() {
+    return lastRawData;
   }
 
-  public ConfigurationsRequest setRevision(String revision) {
-    this.revision = revision;
+  public ConfigurationsRequest setLastRawData(Map<String, Object> lastRawData) 
{
+    this.lastRawData = lastRawData;
     return this;
   }
+
+  @Override
+  public int compareTo(ConfigurationsRequest o) {
+    return o.getOrder() - this.order;
+  }
 }
diff --git 
a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/ConfigurationsRequestFactory.java
 
b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/ConfigurationsRequestFactory.java
new file mode 100644
index 0000000..dd766aa
--- /dev/null
+++ 
b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/ConfigurationsRequestFactory.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.config.kie.client.model;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.servicecomb.http.client.common.HttpUtils;
+
+public class ConfigurationsRequestFactory {
+  private static final String KEY_APP = "app";
+
+  private static final String KEY_ENVIRONMENT = "environment";
+
+  private static final String KEY_SERVICE = "service";
+
+  private static final int SERVICE_ORDER = 100;
+
+  private static final int APP_ORDER = 200;
+
+  private static final int CUSTOM_ORDER = 300;
+
+  public static List<ConfigurationsRequest> 
buildConfigurationRequests(KieConfiguration configuration) {
+    List<ConfigurationsRequest> result = new ArrayList<>();
+    if (configuration.isEnableAppConfig()) {
+      result.add(createAppConfigurationsRequest(configuration));
+    }
+    if (configuration.isEnableServiceConfig()) {
+      result.add(createServiceConfigurationsRequest(configuration));
+    }
+    if (configuration.isEnableCustomConfig()) {
+      result.add(createCustomConfigurationsRequest(configuration));
+    }
+    return result;
+  }
+
+  private static ConfigurationsRequest 
createAppConfigurationsRequest(KieConfiguration configuration) {
+    return new ConfigurationsRequest()
+        .setOrder(APP_ORDER)
+        .setWithExact(true)
+        .setLabelsQuery(buildLabelQuery(buildLabelQueryItem(KEY_APP, 
configuration.getAppName()),
+            buildLabelQueryItem(KEY_ENVIRONMENT, 
configuration.getEnvironment())));
+  }
+
+  private static ConfigurationsRequest 
createServiceConfigurationsRequest(KieConfiguration configuration) {
+    return new ConfigurationsRequest()
+        .setOrder(SERVICE_ORDER)
+        .setWithExact(true)
+        .setLabelsQuery(buildLabelQuery(buildLabelQueryItem(KEY_APP, 
configuration.getAppName()),
+            buildLabelQueryItem(KEY_SERVICE, configuration.getServiceName()),
+            buildLabelQueryItem(KEY_ENVIRONMENT, 
configuration.getEnvironment())));
+  }
+
+  private static ConfigurationsRequest 
createCustomConfigurationsRequest(KieConfiguration configuration) {
+    return new ConfigurationsRequest()
+        .setOrder(CUSTOM_ORDER)
+        .setWithExact(false)
+        .setLabelsQuery(
+            
buildLabelQuery(buildLabelQueryItem(configuration.getCustomLabel(), 
configuration.getCustomLabelValue())));
+  }
+
+  private static String buildLabelQuery(String... labels) {
+    StringBuilder result = new StringBuilder();
+    for (String label : labels) {
+      result.append(label);
+      result.append("&");
+    }
+    return result.toString();
+  }
+
+  private static String buildLabelQueryItem(String key, String value) {
+    try {
+      return "label=" + HttpUtils.encodeURLParam(key + ":" + value);
+    } catch (IOException e) {
+      throw new IllegalArgumentException("unexpected param", e);
+    }
+  }
+}
diff --git 
a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/KieAddressManager.java
 
b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/KieAddressManager.java
index 1b32be6..de21237 100644
--- 
a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/KieAddressManager.java
+++ 
b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/KieAddressManager.java
@@ -19,24 +19,15 @@ package org.apache.servicecomb.config.kie.client.model;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
-import java.util.Properties;
 import java.util.Random;
 
 public class KieAddressManager {
-
-  private final Properties properties;
-
   private final List<String> addresses;
 
-  private final Map<String, String> configKey;
-
   private int index;
 
-  public KieAddressManager(Properties properties, List<String> addresses, 
Map<String, String> configKey) {
-    this.properties = properties;
+  public KieAddressManager(List<String> addresses) {
     this.addresses = new ArrayList<>(addresses.size());
-    this.configKey = configKey;
     addresses.forEach((address -> this.addresses.add(address)));
     this.index = new Random().nextInt(addresses.size());
   }
@@ -57,11 +48,7 @@ public class KieAddressManager {
     }
   }
 
-  public Properties getProperties() {
-    return properties;
-  }
-
-  public Map<String, String> getConfigKey() {
-    return configKey;
+  public boolean sslEnabled() {
+    return address().startsWith("https://";);
   }
 }
diff --git 
a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/KieConfiguration.java
 
b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/KieConfiguration.java
new file mode 100644
index 0000000..8bf93c1
--- /dev/null
+++ 
b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/KieConfiguration.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.config.kie.client.model;
+
+public class KieConfiguration {
+  private boolean enableLongPolling;
+
+  private int pollingWaitInSeconds;
+
+  private String project;
+
+  private String appName;
+
+  private String serviceName;
+
+  private String environment;
+
+  private boolean enableAppConfig;
+
+  private boolean enableServiceConfig;
+
+  private boolean enableCustomConfig;
+
+  private String customLabelValue;
+
+  private String customLabel;
+
+  private boolean firstPullRequired;
+
+  public String getAppName() {
+    return appName;
+  }
+
+  public KieConfiguration setAppName(String appName) {
+    this.appName = appName;
+    return this;
+  }
+
+  public String getServiceName() {
+    return serviceName;
+  }
+
+  public KieConfiguration setServiceName(String serviceName) {
+    this.serviceName = serviceName;
+    return this;
+  }
+
+  public String getEnvironment() {
+    return environment;
+  }
+
+  public KieConfiguration setEnvironment(String environment) {
+    this.environment = environment;
+    return this;
+  }
+
+  public String getCustomLabelValue() {
+    return customLabelValue;
+  }
+
+  public KieConfiguration setCustomLabelValue(String customLabelValue) {
+    this.customLabelValue = customLabelValue;
+    return this;
+  }
+
+  public boolean isEnableAppConfig() {
+    return enableAppConfig;
+  }
+
+  public KieConfiguration setEnableAppConfig(boolean enableAppConfig) {
+    this.enableAppConfig = enableAppConfig;
+    return this;
+  }
+
+  public boolean isEnableServiceConfig() {
+    return enableServiceConfig;
+  }
+
+  public KieConfiguration setEnableServiceConfig(boolean enableServiceConfig) {
+    this.enableServiceConfig = enableServiceConfig;
+    return this;
+  }
+
+  public boolean isEnableCustomConfig() {
+    return enableCustomConfig;
+  }
+
+  public KieConfiguration setEnableCustomConfig(boolean enableCustomConfig) {
+    this.enableCustomConfig = enableCustomConfig;
+    return this;
+  }
+
+  public String getCustomLabel() {
+    return customLabel;
+  }
+
+  public KieConfiguration setCustomLabel(String customLabel) {
+    this.customLabel = customLabel;
+    return this;
+  }
+
+  public boolean isEnableLongPolling() {
+    return enableLongPolling;
+  }
+
+  public KieConfiguration setEnableLongPolling(boolean enableLongPolling) {
+    this.enableLongPolling = enableLongPolling;
+    return this;
+  }
+
+  public int getPollingWaitInSeconds() {
+    return pollingWaitInSeconds;
+  }
+
+  public KieConfiguration setPollingWaitInSeconds(int pollingWaitInSeconds) {
+    this.pollingWaitInSeconds = pollingWaitInSeconds;
+    return this;
+  }
+
+  public String getProject() {
+    return project;
+  }
+
+  public KieConfiguration setProject(String project) {
+    this.project = project;
+    return this;
+  }
+
+  public boolean isFirstPullRequired() {
+    return firstPullRequired;
+  }
+
+  public KieConfiguration setFirstPullRequired(boolean firstPullRequired) {
+    this.firstPullRequired = firstPullRequired;
+    return this;
+  }
+}
diff --git 
a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/task/AbstractTask.java
 
b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/task/AbstractTask.java
index e05eef2..c33c04a 100644
--- 
a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/task/AbstractTask.java
+++ 
b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/task/AbstractTask.java
@@ -20,6 +20,7 @@ package org.apache.servicecomb.http.client.task;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.TimeUnit;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -58,14 +59,30 @@ public class AbstractTask {
 
   private static final Logger LOGGER = 
LoggerFactory.getLogger(AbstractTask.class);
 
-  private final ExecutorService taskPool;
+  protected ExecutorService taskPool;
+
+  private volatile boolean running = true;
 
   protected AbstractTask(String taskName) {
+    initTaskPool(taskName);
+    Runtime.getRuntime().addShutdownHook(new Thread(taskName + 
"-shutdown-hook") {
+      @Override
+      public void run() {
+        AbstractTask.this.stop();
+      }
+    });
+  }
+
+  protected void initTaskPool(String taskName) {
     this.taskPool = Executors.newSingleThreadExecutor((task) ->
         new Thread(task, taskName));
   }
 
   protected void startTask(Task task) {
+    if (!running) {
+      return;
+    }
+
     try {
       this.taskPool.execute(() -> {
         try {
@@ -80,6 +97,12 @@ public class AbstractTask {
   }
 
   public void stop() {
-    this.taskPool.shutdownNow();
+    try {
+      running = false;
+      this.taskPool.shutdown();
+      this.taskPool.awaitTermination(10, TimeUnit.SECONDS);
+    } catch (InterruptedException e) {
+      LOGGER.warn("tasks not shutdown in time {}", e.getMessage());
+    }
   }
 }
diff --git 
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterConfiguration.java
 
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterConfiguration.java
deleted file mode 100644
index 794b976..0000000
--- 
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterConfiguration.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.service.center.client;
-
-public interface ServiceCenterConfiguration {
-  class AddressProperties {
-    private boolean address;
-
-    public boolean isAddress() {
-      return address;
-    }
-
-    public void setAddress(boolean address) {
-      this.address = address;
-    }
-  }
-}
diff --git 
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterDiscovery.java
 
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterDiscovery.java
index 1b63035..0e2df3b 100644
--- 
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterDiscovery.java
+++ 
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterDiscovery.java
@@ -17,6 +17,7 @@
 
 package org.apache.servicecomb.service.center.client;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -27,6 +28,7 @@ import org.apache.servicecomb.http.client.task.Task;
 import 
org.apache.servicecomb.service.center.client.DiscoveryEvents.InstanceChangedEvent;
 import 
org.apache.servicecomb.service.center.client.DiscoveryEvents.PullInstanceEvent;
 import 
org.apache.servicecomb.service.center.client.model.FindMicroserviceInstancesResponse;
+import org.apache.servicecomb.service.center.client.model.Microservice;
 import org.apache.servicecomb.service.center.client.model.MicroserviceInstance;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -86,6 +88,8 @@ public class ServiceCenterDiscovery extends AbstractTask {
 
   private final Map<SubscriptionKey, SubscriptionValue> instancesCache = new 
ConcurrentHashMap<>();
 
+  private final Map<String, Microservice> microserviceCache = new 
ConcurrentHashMap<>();
+
   public ServiceCenterDiscovery(ServiceCenterClient serviceCenterClient, 
EventBus eventBus) {
     super("service-center-discovery-task");
     this.serviceCenterClient = serviceCenterClient;
@@ -123,32 +127,53 @@ public class ServiceCenterDiscovery extends AbstractTask {
   }
 
   private void pullInstance(SubscriptionKey k, SubscriptionValue v) {
+    if (myselfServiceId == null) {
+      // registration not ready
+      return;
+    }
     try {
       FindMicroserviceInstancesResponse instancesResponse = serviceCenterClient
           .findMicroserviceInstance(myselfServiceId, k.appId, k.serviceName, 
ALL_VERSION, v.revision);
       if (instancesResponse.isModified()) {
-        // java chassis 实现了空实例保护,这里暂时不实现。
+        List<MicroserviceInstance> instances = 
instancesResponse.getMicroserviceInstancesResponse().getInstances()
+            == null ? Collections.emptyList() : 
instancesResponse.getMicroserviceInstancesResponse().getInstances();
+        setMicroserviceInfo(instances);
         LOGGER.info("Instance changed event, "
                 + "current: revision={}, instances={}; "
                 + "origin: revision={}, instances={}; "
                 + "appId={}, serviceName={}",
             instancesResponse.getRevision(),
-            
instanceToString(instancesResponse.getMicroserviceInstancesResponse().getInstances()),
+            instanceToString(instances),
             v.revision,
             instanceToString(v.instancesCache),
             k.appId,
             k.serviceName
         );
-        v.instancesCache = 
instancesResponse.getMicroserviceInstancesResponse().getInstances();
+        v.instancesCache = instances;
         v.revision = instancesResponse.getRevision();
         eventBus.post(new InstanceChangedEvent(k.appId, k.serviceName,
             v.instancesCache));
       }
     } catch (Exception e) {
-      LOGGER.error("find service instance failed.", e);
+      LOGGER.error("find service {}#{} instance failed.", k.appId, 
k.serviceName, e);
     }
   }
 
+  private void setMicroserviceInfo(List<MicroserviceInstance> instances) {
+    instances.forEach(instance -> {
+      Microservice microservice = microserviceCache
+          .computeIfAbsent(instance.getServiceId(), id -> {
+            try {
+              return serviceCenterClient.getMicroserviceByServiceId(id);
+            } catch (Exception e) {
+              LOGGER.error("Find microservice by id={} failed", id, e);
+              throw e;
+            }
+          });
+      instance.setMicroservice(microservice);
+    });
+  }
+
   class PullInstanceTask implements Task {
     @Override
     public void execute() {
@@ -175,6 +200,8 @@ public class ServiceCenterDiscovery extends AbstractTask {
         sb.append(endpoint.length() > 64 ? endpoint.substring(0, 64) : 
endpoint);
         sb.append("|");
       }
+      sb.append(instance.getServiceName());
+      sb.append("|");
     }
     sb.append("#");
     return sb.toString();
diff --git 
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRegistration.java
 
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRegistration.java
index a9d8fbf..a10f7e6 100644
--- 
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRegistration.java
+++ 
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRegistration.java
@@ -32,6 +32,7 @@ import 
org.apache.servicecomb.service.center.client.model.MicroserviceInstance;
 import 
org.apache.servicecomb.service.center.client.model.RegisteredMicroserviceInstanceResponse;
 import 
org.apache.servicecomb.service.center.client.model.RegisteredMicroserviceResponse;
 import org.apache.servicecomb.service.center.client.model.SchemaInfo;
+import 
org.apache.servicecomb.service.center.client.model.ServiceCenterConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -50,9 +51,13 @@ public class ServiceCenterRegistration extends AbstractTask {
 
   private List<SchemaInfo> schemaInfos;
 
-  public ServiceCenterRegistration(ServiceCenterClient serviceCenterClient, 
EventBus eventBus) {
+  private ServiceCenterConfiguration serviceCenterConfiguration;
+
+  public ServiceCenterRegistration(ServiceCenterClient serviceCenterClient, 
ServiceCenterConfiguration
+      serviceCenterConfiguration, EventBus eventBus) {
     super("service-center-registration-task");
     this.serviceCenterClient = serviceCenterClient;
+    this.serviceCenterConfiguration = serviceCenterConfiguration;
     this.eventBus = eventBus;
   }
 
@@ -89,20 +94,16 @@ public class ServiceCenterRegistration extends AbstractTask 
{
             LOGGER.error("register microservice failed, and will try again.");
             eventBus.post(new MicroserviceRegistrationEvent(false));
             startTask(new BackOffSleepTask(failedCount + 1, new 
RegisterMicroserviceTask(failedCount + 1)));
-          } else {
-            microservice.setServiceId(response.getServiceId());
-            microserviceInstance.setServiceId(response.getServiceId());
-            microserviceInstance.setMicroservice(microservice);
-            eventBus.post(new MicroserviceRegistrationEvent(true));
-            startTask(new RegisterSchemaTask(0));
+            return;
           }
-          return;
+          microservice.setServiceId(response.getServiceId());
+          microserviceInstance.setServiceId(response.getServiceId());
+          microserviceInstance.setMicroservice(microservice);
+          eventBus.post(new MicroserviceRegistrationEvent(true));
+          startTask(new RegisterSchemaTask(0));
         } else {
           Microservice newMicroservice = 
serviceCenterClient.getMicroserviceByServiceId(serviceResponse.getServiceId());
-          if (!isListEquals(newMicroservice.getSchemas(), 
microservice.getSchemas())) {
-            throw new IllegalStateException("Service has already registered, 
but schema ids not equal, stop register. "
-                + "Change the microservice version or delete the old 
microservice info and try again.");
-          }
+          dealIsSwaggerDifferent(newMicroservice);
           microservice.setServiceId(serviceResponse.getServiceId());
           microserviceInstance.setServiceId(serviceResponse.getServiceId());
           microserviceInstance.setMicroservice(microservice);
@@ -120,6 +121,19 @@ public class ServiceCenterRegistration extends 
AbstractTask {
     }
   }
 
+  private void dealIsSwaggerDifferent(Microservice newMicroservice) {
+    if (isListEquals(newMicroservice.getSchemas(), microservice.getSchemas())) 
{
+      return;
+    }
+    if (!serviceCenterConfiguration.isIgnoreSwaggerDifferent()) {
+      throw new IllegalStateException("Service has already registered, but 
schema ids not equal, stop register. "
+          + "Change the microservice version or delete the old microservice 
info and try again.");
+    }
+    LOGGER.warn("Service has already registered, but schema ids not equal. 
However, it will continue to register. "
+        + "If you want to eliminate this warning. you can Change the 
microservice version or delete the old " +
+        "microservice info and try again. eg: version:1.0.0 -> 1.0.1");
+  }
+
   private boolean isListEquals(List<String> one, List<String> two) {
     return one.size() == two.size() && one.containsAll(two) && 
two.containsAll(one);
   }
diff --git 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/ConnFailEvent.java
 
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/ServiceCenterConfiguration.java
similarity index 55%
rename from 
dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/ConnFailEvent.java
rename to 
clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/ServiceCenterConfiguration.java
index 1e34810..a452259 100644
--- 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/ConnFailEvent.java
+++ 
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/ServiceCenterConfiguration.java
@@ -15,21 +15,23 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.config.kie.client;
+package org.apache.servicecomb.service.center.client.model;
 
-public class ConnFailEvent {
+public class ServiceCenterConfiguration {
 
-  private String msg;
+  /**
+   * for registration service
+   * when swagger is different between local with remote serviceCenter. if 
ignoreSwaggerDifferent is true.
+   * it will ignore the different and continue the program. otherwise, the 
program will be stop.
+   */
+  private Boolean ignoreSwaggerDifferent;
 
-  public ConnFailEvent(String msg) {
-    this.msg = msg;
+  public Boolean isIgnoreSwaggerDifferent() {
+    return ignoreSwaggerDifferent;
   }
 
-  public String getMsg() {
-    return msg;
-  }
-
-  public void setMsg(String msg) {
-    this.msg = msg;
+  public ServiceCenterConfiguration setIgnoreSwaggerDifferent(Boolean 
ignoreSwaggerDifferent) {
+    this.ignoreSwaggerDifferent = ignoreSwaggerDifferent;
+    return this;
   }
 }
diff --git 
a/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/RegistryClientTest.java
 
b/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/RegistryClientTest.java
index 87ec262..d64dc24 100644
--- 
a/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/RegistryClientTest.java
+++ 
b/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/RegistryClientTest.java
@@ -42,6 +42,7 @@ import 
org.apache.servicecomb.service.center.client.ServiceCenterRegistration;
 import org.apache.servicecomb.service.center.client.model.Microservice;
 import org.apache.servicecomb.service.center.client.model.MicroserviceInstance;
 import org.apache.servicecomb.service.center.client.model.SchemaInfo;
+import 
org.apache.servicecomb.service.center.client.model.ServiceCenterConfiguration;
 import org.springframework.stereotype.Component;
 
 import com.google.common.base.Charsets;
@@ -70,7 +71,9 @@ public class RegistryClientTest implements 
CategorizedTestCase {
     ServiceCenterClient serviceCenterClient = new 
ServiceCenterClient(addressManager, sslProperties,
         new DefaultRequestAuthHeaderProvider(), "default", null);
     EventBus eventBus = new SimpleEventBus();
-    ServiceCenterRegistration serviceCenterRegistration = new 
ServiceCenterRegistration(serviceCenterClient, eventBus);
+    ServiceCenterConfiguration serviceCenterConfiguration = new 
ServiceCenterConfiguration();
+    ServiceCenterRegistration serviceCenterRegistration = new 
ServiceCenterRegistration(serviceCenterClient,
+        serviceCenterConfiguration, eventBus);
     Microservice microservice = new Microservice();
     microservice.setAppId("app_registry");
     microservice.setServiceName("name_registry");
diff --git a/dynamic-config/config-kie/pom.xml 
b/dynamic-config/config-kie/pom.xml
index 7a6c3b5..7e89420 100644
--- a/dynamic-config/config-kie/pom.xml
+++ b/dynamic-config/config-kie/pom.xml
@@ -61,5 +61,9 @@
       <artifactId>foundation-test-scaffolding</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.apache.servicecomb</groupId>
+      <artifactId>config-kie-client</artifactId>
+    </dependency>
   </dependencies>
 </project>
\ No newline at end of file
diff --git 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/KieConfig.java
 
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieConfig.java
similarity index 73%
rename from 
dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/KieConfig.java
rename to 
dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieConfig.java
index 38c68bf..ac43c86 100644
--- 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/KieConfig.java
+++ 
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieConfig.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.config.kie.client;
+package org.apache.servicecomb.config.kie;
 
 import org.apache.servicecomb.config.BootStrapProperties;
 import org.apache.servicecomb.foundation.vertx.VertxConst;
@@ -38,6 +38,20 @@ public class KieConfig {
 
   private static final String ENABLE_LONG_POLLING = 
"servicecomb.kie.enableLongPolling";
 
+  private static final String POLLING_WAIT_TIME = 
"servicecomb.kie.pollingWaitTime";
+
+  private static final String FIRST_PULL_REQUIRED = 
"servicecomb.kie.firstPullRequired";
+
+  private static final String CUSTOM_LABEL = "servicecomb.kie.customLabel";
+
+  private static final String CUSTOM_LABEL_VALUE = 
"servicecomb.kie.customLabelValue";
+
+  private static final String ENABLE_APP_CONFIG = 
"servicecomb.kie.enableAppConfig";
+
+  private static final String ENABLE_SERVICE_CONFIG = 
"servicecomb.kie.enableServiceConfig";
+
+  private static final String ENABLE_CUSTOM_CONFIG = 
"servicecomb.kie.enableCustomConfig";
+
   public static final String CONNECTION_TIME_OUT = 
"servicecomb.kie.client.timeout.connection";
 
   public static final String EVENT_LOOP_SIZE = 
"servicecomb.kie.client.eventLoopSize";
@@ -48,10 +62,16 @@ public class KieConfig {
 
   private static final int DEFAULT_REFRESH_INTERVAL = 3000;
 
+  private static final int DEFAULT_POLLING_WAIT_TIME = 10;
+
   private static final int DEFAULT_FIRST_REFRESH_INTERVAL = 0;
 
   private static final boolean DEFAULT_ENABLE_LONG_POLLING = true;
 
+  private static final String CUSTOM_LABEL_DEFAULT = "public";
+
+  private static final String CUSTOM_LABEL_VALUE_DEFAULT = "";
+
   private KieConfig() {
   }
 
@@ -115,10 +135,38 @@ public class KieConfig {
     return finalConfig.getInt(FIRST_REFRESH_INTERVAL, 
DEFAULT_FIRST_REFRESH_INTERVAL);
   }
 
+  public boolean enableAppConfig() {
+    return finalConfig.getBoolean(ENABLE_APP_CONFIG, true);
+  }
+
+  public boolean enableServiceConfig() {
+    return finalConfig.getBoolean(ENABLE_SERVICE_CONFIG, true);
+  }
+
+  public boolean enableCustomConfig() {
+    return finalConfig.getBoolean(ENABLE_CUSTOM_CONFIG, true);
+  }
+
   public boolean enableLongPolling() {
     return finalConfig.getBoolean(ENABLE_LONG_POLLING, 
DEFAULT_ENABLE_LONG_POLLING);
   }
 
+  public int getPollingWaitTime() {
+    return finalConfig.getInt(POLLING_WAIT_TIME, DEFAULT_POLLING_WAIT_TIME);
+  }
+
+  public boolean firstPullRequired() {
+    return finalConfig.getBoolean(FIRST_PULL_REQUIRED, false);
+  }
+
+  public String getCustomLabel() {
+    return finalConfig.getString(CUSTOM_LABEL, CUSTOM_LABEL_DEFAULT);
+  }
+
+  public String getCustomLabelValue() {
+    return finalConfig.getString(CUSTOM_LABEL_VALUE, 
CUSTOM_LABEL_VALUE_DEFAULT);
+  }
+
   public Boolean isProxyEnable() {
     return finalConfig.getBoolean(VertxConst.PROXY_ENABLE, false);
   }
diff --git 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieConfigurationSourceImpl.java
 
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieConfigurationSourceImpl.java
new file mode 100644
index 0000000..18d3fb4
--- /dev/null
+++ 
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieConfigurationSourceImpl.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.config.kie;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.servicecomb.config.common.ConfigConverter;
+import org.apache.servicecomb.config.common.ConfigurationChangedEvent;
+import org.apache.servicecomb.config.kie.client.KieClient;
+import org.apache.servicecomb.config.kie.client.KieConfigManager;
+import org.apache.servicecomb.config.kie.client.model.KieAddressManager;
+import org.apache.servicecomb.config.kie.client.model.KieConfiguration;
+import org.apache.servicecomb.config.spi.ConfigCenterConfigurationSource;
+import org.apache.servicecomb.foundation.auth.AuthHeaderProvider;
+import org.apache.servicecomb.foundation.common.event.EventManager;
+import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
+import org.apache.servicecomb.http.client.auth.RequestAuthHeaderProvider;
+import org.apache.servicecomb.http.client.common.HttpTransport;
+import org.apache.servicecomb.http.client.common.HttpTransportFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.eventbus.Subscribe;
+import com.netflix.config.ConcurrentCompositeConfiguration;
+import com.netflix.config.WatchedUpdateListener;
+import com.netflix.config.WatchedUpdateResult;
+
+public class KieConfigurationSourceImpl implements 
ConfigCenterConfigurationSource {
+
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(KieConfigurationSourceImpl.class);
+
+  private List<WatchedUpdateListener> listeners = new CopyOnWriteArrayList<>();
+
+  private KieConfigManager kieConfigManager;
+
+  private ConfigConverter configConverter = new ConfigConverter(null);
+
+  @Override
+  public int getOrder() {
+    return ORDER_BASE * 2;
+  }
+
+  @Override
+  public boolean isValidSource(Configuration localConfiguration) {
+    KieConfig.setFinalConfig((ConcurrentCompositeConfiguration) 
localConfiguration);
+
+    if (StringUtils.isEmpty(KieConfig.INSTANCE.getServerUri())) {
+      LOGGER.info("Kie server is not configured.");
+      return false;
+    }
+    return true;
+  }
+
+  @Override
+  public void init(Configuration localConfiguration) {
+    KieAddressManager kieAddressManager = configKieAddressManager();
+
+    RequestConfig.Builder requestBuilder = 
HttpTransportFactory.defaultRequestConfig();
+    if (KieConfig.INSTANCE.enableLongPolling()
+        && KieConfig.INSTANCE.getPollingWaitTime() >= 0) {
+      
requestBuilder.setConnectionRequestTimeout(KieConfig.INSTANCE.getPollingWaitTime()
 * 2 * 1000);
+      requestBuilder.setSocketTimeout(KieConfig.INSTANCE.getPollingWaitTime() 
* 2 * 1000);
+    }
+    HttpTransport httpTransport = createHttpTransport(requestBuilder.build(), 
localConfiguration);
+    KieConfiguration kieConfiguration = createKieConfiguration();
+    KieClient kieClient = new KieClient(kieAddressManager, httpTransport, 
kieConfiguration);
+    EventManager.register(this);
+    kieConfigManager = new KieConfigManager(kieClient, 
EventManager.getEventBus(), kieConfiguration, configConverter);
+    kieConfigManager.firstPull();
+    kieConfigManager.startConfigKieManager();
+    
updateConfiguration(WatchedUpdateResult.createIncremental(configConverter.getCurrentData(),
 null, null));
+  }
+
+  @Subscribe
+  public void onConfigurationChangedEvent(ConfigurationChangedEvent event) {
+    updateConfiguration(
+        WatchedUpdateResult.createIncremental(event.getAdded(), 
event.getUpdated(), event.getDeleted()));
+  }
+
+  private KieConfiguration createKieConfiguration() {
+    return new KieConfiguration().setAppName(KieConfig.INSTANCE.getAppName())
+        .setFirstPullRequired(KieConfig.INSTANCE.firstPullRequired())
+        .setCustomLabel(KieConfig.INSTANCE.getCustomLabel())
+        .setCustomLabelValue(KieConfig.INSTANCE.getCustomLabelValue())
+        .setEnableAppConfig(KieConfig.INSTANCE.enableAppConfig())
+        .setEnableCustomConfig(KieConfig.INSTANCE.enableCustomConfig())
+        .setEnableLongPolling(KieConfig.INSTANCE.enableLongPolling())
+        .setEnableServiceConfig(KieConfig.INSTANCE.enableServiceConfig())
+        .setEnvironment(KieConfig.INSTANCE.getEnvironment())
+        .setPollingWaitInSeconds(KieConfig.INSTANCE.getPollingWaitTime())
+        .setProject(KieConfig.INSTANCE.getDomainName())
+        .setServiceName(KieConfig.INSTANCE.getServiceName());
+  }
+
+  private HttpTransport createHttpTransport(RequestConfig requestConfig, 
Configuration localConfiguration) {
+    List<AuthHeaderProvider> authHeaderProviders = 
SPIServiceUtils.getOrLoadSortedService(AuthHeaderProvider.class);
+
+    return HttpTransportFactory
+        .createHttpTransport(
+            TransportUtils.createSSLProperties(localConfiguration, "kie"),
+            getRequestAuthHeaderProvider(authHeaderProviders), requestConfig);
+  }
+
+  private static RequestAuthHeaderProvider 
getRequestAuthHeaderProvider(List<AuthHeaderProvider> authHeaderProviders) {
+    return signRequest -> {
+      Map<String, String> headers = new HashMap<>();
+      authHeaderProviders.forEach(provider -> 
headers.putAll(provider.authHeaders()));
+      return headers;
+    };
+  }
+
+  private KieAddressManager configKieAddressManager() {
+    KieAddressManager kieAddressManager = new KieAddressManager(
+        Arrays.asList(KieConfig.INSTANCE.getServerUri().split(",")));
+    return kieAddressManager;
+  }
+
+  private void updateConfiguration(WatchedUpdateResult result) {
+    for (WatchedUpdateListener l : listeners) {
+      try {
+        l.updateConfiguration(result);
+      } catch (Throwable ex) {
+        LOGGER.error("Error in invoking WatchedUpdateListener", ex);
+      }
+    }
+  }
+
+  @Override
+  public void destroy() {
+    if (kieConfigManager == null) {
+      return;
+    }
+    kieConfigManager.stop();
+  }
+
+  @Override
+  public void addUpdateListener(WatchedUpdateListener watchedUpdateListener) {
+    listeners.add(watchedUpdateListener);
+  }
+
+  @Override
+  public void removeUpdateListener(WatchedUpdateListener 
watchedUpdateListener) {
+    listeners.remove(watchedUpdateListener);
+  }
+
+  @Override
+  public Map<String, Object> getCurrentData() throws Exception {
+    return configConverter.getCurrentData();
+  }
+}
diff --git 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/TransportUtils.java
 
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/TransportUtils.java
new file mode 100644
index 0000000..d335fd5
--- /dev/null
+++ 
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/TransportUtils.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.config.kie;
+
+import static org.apache.servicecomb.foundation.ssl.SSLOption.DEFAULT_OPTION;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.servicecomb.foundation.ssl.SSLCustom;
+import org.apache.servicecomb.foundation.ssl.SSLOption;
+import 
org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties;
+
+public class TransportUtils {
+  public static SSLProperties createSSLProperties(Configuration configuration, 
String tag) {
+    SSLProperties sslProperties = new SSLProperties();
+
+    SSLOption option = new SSLOption();
+    option.setEngine(getStringProperty(configuration,
+        DEFAULT_OPTION.getEngine(),
+        "ssl." + tag + ".engine",
+        "ssl.engine"));
+    option.setProtocols(
+        getStringProperty(configuration,
+            DEFAULT_OPTION.getProtocols(),
+            "ssl." + tag + ".protocols",
+            "ssl.protocols"));
+    option.setCiphers(
+        getStringProperty(configuration, DEFAULT_OPTION.getCiphers(), "ssl." + 
tag + ".ciphers", "ssl.ciphers"));
+    option.setAuthPeer(
+        getBooleanProperty(configuration, DEFAULT_OPTION.isAuthPeer(), "ssl." 
+ tag + ".authPeer", "ssl.authPeer"));
+    option.setCheckCNHost(
+        getBooleanProperty(configuration,
+            DEFAULT_OPTION.isCheckCNHost(),
+            "ssl." + tag + ".checkCN.host",
+            "ssl.checkCN.host"));
+    option.setCheckCNWhite(
+        getBooleanProperty(configuration,
+            DEFAULT_OPTION.isCheckCNWhite(),
+            "ssl." + tag + ".checkCN.white",
+            "ssl.checkCN.white"));
+    option.setCheckCNWhiteFile(getStringProperty(configuration,
+        DEFAULT_OPTION.getCiphers(),
+        "ssl." + tag + ".checkCN.white.file",
+        "ssl.checkCN.white.file"));
+    option.setAllowRenegociate(getBooleanProperty(configuration,
+        DEFAULT_OPTION.isAllowRenegociate(),
+        "ssl." + tag + ".allowRenegociate",
+        "ssl.allowRenegociate"));
+    option.setStorePath(
+        getStringProperty(configuration,
+            DEFAULT_OPTION.getStorePath(),
+            "ssl." + tag + ".storePath",
+            "ssl.storePath"));
+    option.setTrustStore(
+        getStringProperty(configuration,
+            DEFAULT_OPTION.getTrustStore(),
+            "ssl." + tag + ".trustStore",
+            "ssl.trustStore"));
+    option.setTrustStoreType(getStringProperty(configuration,
+        DEFAULT_OPTION.getTrustStoreType(),
+        "ssl." + tag + ".trustStoreType",
+        "ssl.trustStoreType"));
+    option.setTrustStoreValue(getStringProperty(configuration,
+        DEFAULT_OPTION.getTrustStoreValue(),
+        "ssl." + tag + ".trustStoreValue",
+        "ssl.trustStoreValue"));
+    option.setKeyStore(
+        getStringProperty(configuration, DEFAULT_OPTION.getKeyStore(), "ssl." 
+ tag + ".keyStore", "ssl.keyStore"));
+    option.setKeyStoreType(
+        getStringProperty(configuration,
+            DEFAULT_OPTION.getKeyStoreType(),
+            "ssl." + tag + ".keyStoreType",
+            "ssl.keyStoreType"));
+    option.setKeyStoreValue(getStringProperty(configuration,
+        DEFAULT_OPTION.getKeyStoreValue(),
+        "ssl." + tag + ".keyStoreValue",
+        "ssl.keyStoreValue"));
+    option.setCrl(getStringProperty(configuration, DEFAULT_OPTION.getCrl(), 
"ssl." + tag + ".crl", "ssl.crl"));
+    option.setSslCustomClass(
+        getStringProperty(configuration, null, "ssl." + tag + 
".sslCustomClass", "ssl.sslCustomClass"));
+
+    sslProperties.setSslOption(option);
+    
sslProperties.setSslCustom(SSLCustom.createSSLCustom(option.getSslCustomClass()));
+    return sslProperties;
+  }
+
+  private static String getStringProperty(Configuration configuration, String 
defaultValue, String... keys) {
+    for (String key : keys) {
+      if (configuration.containsKey(key)) {
+        return configuration.getString(key);
+      }
+    }
+    return defaultValue;
+  }
+
+  private static boolean getBooleanProperty(Configuration configuration, 
boolean defaultValue, String... keys) {
+    for (String key : keys) {
+      if (configuration.containsKey(key)) {
+        return configuration.getBoolean(key);
+      }
+    }
+    return defaultValue;
+  }
+}
diff --git 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/archaius/sources/KieConfigurationSourceImpl.java
 
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/archaius/sources/KieConfigurationSourceImpl.java
deleted file mode 100644
index 7b0b764..0000000
--- 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/archaius/sources/KieConfigurationSourceImpl.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.config.kie.archaius.sources;
-
-import static com.netflix.config.WatchedUpdateResult.createIncremental;
-
-import com.google.common.collect.ImmutableMap;
-import com.netflix.config.ConcurrentCompositeConfiguration;
-import com.netflix.config.WatchedUpdateListener;
-import com.netflix.config.WatchedUpdateResult;
-
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.servicecomb.config.ConfigMapping;
-import org.apache.servicecomb.config.kie.client.KieClient;
-import org.apache.servicecomb.config.kie.client.KieConfig;
-import org.apache.servicecomb.config.spi.ConfigCenterConfigurationSource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class KieConfigurationSourceImpl implements 
ConfigCenterConfigurationSource {
-
-  private static final Logger LOGGER = 
LoggerFactory.getLogger(KieConfigurationSourceImpl.class);
-
-  private static final String KIE_CONFIG_URL_KEY = "servicecomb.kie.serverUri";
-
-  private final Map<String, Object> valueCache = new ConcurrentHashMap<>();
-
-  private List<WatchedUpdateListener> listeners = new CopyOnWriteArrayList<>();
-
-  private UpdateHandler updateHandler = new UpdateHandler();
-
-  private KieClient kieClient;
-
-  @Override
-  public int getOrder() {
-    return ORDER_BASE * 2;
-  }
-
-  @Override
-  public boolean isValidSource(Configuration localConfiguration) {
-    if (localConfiguration.getProperty(KIE_CONFIG_URL_KEY) == null) {
-      LOGGER.warn("Kie configuration source is not configured!");
-      return false;
-    }
-    return true;
-  }
-
-  @Override
-  public void init(Configuration localConfiguration) {
-    KieConfig.setFinalConfig((ConcurrentCompositeConfiguration) 
localConfiguration);
-    kieClient = new KieClient(updateHandler);
-    kieClient.refreshKieConfig();
-  }
-
-  @Override
-  public void destroy() {
-    if (kieClient == null) {
-      return;
-    }
-    kieClient.destroy();
-  }
-
-  @Override
-  public void addUpdateListener(WatchedUpdateListener watchedUpdateListener) {
-    listeners.add(watchedUpdateListener);
-  }
-
-  @Override
-  public void removeUpdateListener(WatchedUpdateListener 
watchedUpdateListener) {
-    listeners.remove(watchedUpdateListener);
-  }
-
-  @Override
-  public Map<String, Object> getCurrentData() throws Exception {
-    return valueCache;
-  }
-
-
-  private void updateConfiguration(WatchedUpdateResult result) {
-    for (WatchedUpdateListener l : listeners) {
-      try {
-        l.updateConfiguration(result);
-      } catch (Throwable ex) {
-        LOGGER.error("Error in invoking WatchedUpdateListener", ex);
-      }
-    }
-  }
-
-  public class UpdateHandler {
-
-    public void handle(String action, Map<String, Object> parseConfigs) {
-      if (parseConfigs == null || parseConfigs.isEmpty()) {
-        return;
-      }
-      Map<String, Object> configuration = 
ConfigMapping.getConvertedMap(parseConfigs);
-      if ("create".equals(action)) {
-        valueCache.putAll(configuration);
-        updateConfiguration(createIncremental(ImmutableMap.<String, 
Object>copyOf(configuration),
-            null,
-            null));
-      } else if ("set".equals(action)) {
-        valueCache.putAll(configuration);
-        updateConfiguration(
-            createIncremental(null, ImmutableMap.<String, 
Object>copyOf(configuration),
-                null));
-      } else if ("delete".equals(action)) {
-        configuration.keySet().forEach(valueCache::remove);
-        updateConfiguration(createIncremental(null,
-            null,
-            ImmutableMap.<String, Object>copyOf(configuration)));
-      } else {
-        LOGGER.error("action: {} is invalid.", action);
-        return;
-      }
-      LOGGER.warn("Config value cache changed: action:{}; item:{}", action, 
configuration.keySet());
-    }
-  }
-}
diff --git 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/ConfigKieHttpClientOptionsSPI.java
 
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/ConfigKieHttpClientOptionsSPI.java
deleted file mode 100644
index 7b46738..0000000
--- 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/ConfigKieHttpClientOptionsSPI.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.config.kie.client;
-
-import 
org.apache.servicecomb.foundation.vertx.client.http.HttpClientOptionsSPI;
-
-import com.netflix.config.ConcurrentCompositeConfiguration;
-
-import io.vertx.core.VertxOptions;
-import io.vertx.core.http.HttpClientOptions;
-import io.vertx.core.http.HttpVersion;
-
-public class ConfigKieHttpClientOptionsSPI implements HttpClientOptionsSPI {
-  public static final String CLIENT_NAME = "config-kie";
-
-  @Override
-  public String clientName() {
-    return CLIENT_NAME;
-  }
-
-  @Override
-  public int getOrder() {
-    return -200;
-  }
-
-  @Override
-  public boolean enabled() {
-    return KieConfig.INSTANCE.getServerUri() != null;
-  }
-
-  @Override
-  public String getConfigTag() {
-    return "kie.consumer";
-  }
-
-  @Override
-  public ConcurrentCompositeConfiguration getConfigReader() {
-    return KieConfig.getFinalConfig();
-  }
-
-  @Override
-  public int getEventLoopPoolSize() {
-    return KieConfig.INSTANCE.getEventLoopSize();
-  }
-
-  @Override
-  public boolean useSharedVertx() {
-    return false;
-  }
-
-  @Override
-  public int getInstanceCount() {
-    return KieConfig.INSTANCE.getVerticalInstanceCount();
-  }
-
-  @Override
-  public boolean isWorker() {
-    return false;
-  }
-
-  @Override
-  public String getWorkerPoolName() {
-    return "pool-worker-kie-client";
-  }
-
-  @Override
-  public int getWorkerPoolSize() {
-    return VertxOptions.DEFAULT_WORKER_POOL_SIZE;
-  }
-
-  @Override
-  public HttpVersion getHttpVersion() {
-    return HttpVersion.HTTP_1_1;
-  }
-
-  @Override
-  public int getConnectTimeoutInMillis() {
-    return KieConfig.INSTANCE.getConnectionTimeOut();
-  }
-
-  @Override
-  public int getIdleTimeoutInSeconds() {
-    return KieConfig.INSTANCE.getIdleTimeoutInSeconds();
-  }
-
-  @Override
-  public boolean isTryUseCompression() {
-    return HttpClientOptions.DEFAULT_TRY_USE_COMPRESSION;
-  }
-
-  @Override
-  public int getMaxWaitQueueSize() {
-    return HttpClientOptions.DEFAULT_MAX_WAIT_QUEUE_SIZE;
-  }
-
-  @Override
-  public int getMaxPoolSize() {
-    return HttpClientOptions.DEFAULT_MAX_POOL_SIZE;
-  }
-
-  @Override
-  public boolean isKeepAlive() {
-    return HttpClientOptions.DEFAULT_KEEP_ALIVE;
-  }
-
-  @Override
-  public int getMaxHeaderSize() {
-    return HttpClientOptions.DEFAULT_MAX_HEADER_SIZE;
-  }
-
-  @Override
-  public int getKeepAliveTimeout() {
-    return HttpClientOptions.DEFAULT_KEEP_ALIVE_TIMEOUT;
-  }
-
-  @Override
-  public int getHttp2MultiplexingLimit() {
-    return HttpClientOptions.DEFAULT_HTTP2_MULTIPLEXING_LIMIT;
-  }
-
-  @Override
-  public int getHttp2MaxPoolSize() {
-    return HttpClientOptions.DEFAULT_HTTP2_MAX_POOL_SIZE;
-  }
-
-  @Override
-  public boolean isUseAlpn() {
-    return HttpClientOptions.DEFAULT_USE_ALPN;
-  }
-
-  @Override
-  public boolean isProxyEnable() {
-    return KieConfig.INSTANCE.isProxyEnable();
-  }
-
-  @Override
-  public String getProxyHost() {
-    return KieConfig.INSTANCE.getProxyHost();
-  }
-
-  @Override
-  public int getProxyPort() {
-    return KieConfig.INSTANCE.getProxyPort();
-  }
-
-  @Override
-  public String getProxyUsername() {
-    return KieConfig.INSTANCE.getProxyUsername();
-  }
-
-  @Override
-  public String getProxyPassword() {
-    return KieConfig.INSTANCE.getProxyPasswd();
-  }
-
-  @Override
-  public boolean isSsl() {
-    return KieConfig.INSTANCE.getServerUri() != null && 
KieConfig.INSTANCE.getServerUri().startsWith("https");
-  }
-}
diff --git 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/ConnSuccEvent.java
 
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/ConnSuccEvent.java
deleted file mode 100644
index 95d9758..0000000
--- 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/ConnSuccEvent.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.config.kie.client;
-
-public class ConnSuccEvent {
-
-}
diff --git 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/KieClient.java
 
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/KieClient.java
deleted file mode 100644
index e130bee..0000000
--- 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/KieClient.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.config.kie.client;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.http.HttpStatus;
-import 
org.apache.servicecomb.config.kie.archaius.sources.KieConfigurationSourceImpl.UpdateHandler;
-import org.apache.servicecomb.config.kie.model.KVResponse;
-import org.apache.servicecomb.foundation.common.event.EventManager;
-import org.apache.servicecomb.foundation.common.net.IpPort;
-import org.apache.servicecomb.foundation.common.net.NetUtils;
-import org.apache.servicecomb.foundation.common.utils.JsonUtils;
-import org.apache.servicecomb.foundation.vertx.client.http.HttpClients;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import io.vertx.core.http.HttpClientRequest;
-
-public class KieClient {
-
-  private static final Logger LOGGER = 
LoggerFactory.getLogger(KieClient.class);
-
-  private ScheduledExecutorService EXECUTOR = 
Executors.newScheduledThreadPool(1, (r) -> {
-    Thread thread = new Thread(r);
-    thread.setName("org.apache.servicecomb.config.kie");
-    thread.setDaemon(true);
-    return thread;
-  });
-
-  private static final long PULL_REQUEST_TIME_OUT_IN_MILLIS = 10000;
-
-  private static final long LONG_POLLING_REQUEST_TIME_OUT_IN_MILLIS = 60000;
-
-  private static AtomicBoolean IS_FIRST_PULL = new AtomicBoolean(true);
-
-  private static final int LONG_POLLING_WAIT_TIME_IN_SECONDS = 30;
-
-  private static String revision = "0";
-
-  private static final KieConfig KIE_CONFIG = KieConfig.INSTANCE;
-
-  private final int refreshInterval = KIE_CONFIG.getRefreshInterval();
-
-  private final int firstRefreshInterval = 
KIE_CONFIG.getFirstRefreshInterval();
-
-  private final boolean enableLongPolling = KIE_CONFIG.enableLongPolling();
-
-  private final String serviceUri = KIE_CONFIG.getServerUri();
-
-  public KieClient(UpdateHandler updateHandler) {
-    HttpClients.addNewClientPoolManager(new ConfigKieHttpClientOptionsSPI());
-    KieWatcher.INSTANCE.setUpdateHandler(updateHandler);
-  }
-
-  public void refreshKieConfig() {
-    if (enableLongPolling) {
-      EXECUTOR.execute(new ConfigRefresh(serviceUri));
-    } else {
-      EXECUTOR.scheduleWithFixedDelay(new ConfigRefresh(serviceUri), 
firstRefreshInterval,
-          refreshInterval, TimeUnit.MILLISECONDS);
-    }
-  }
-
-  public void destroy() {
-    if (EXECUTOR != null) {
-      EXECUTOR.shutdown();
-      EXECUTOR = null;
-    }
-  }
-
-  class ConfigRefresh implements Runnable {
-
-    private final String serviceUri;
-
-    ConfigRefresh(String serviceUris) {
-      this.serviceUri = serviceUris;
-    }
-
-    @Override
-    public void run() {
-      try {
-        CountDownLatch latch = new CountDownLatch(1);
-        refreshConfig(latch);
-        latch.await();
-      } catch (Throwable e) {
-        LOGGER.error("client refresh thread exception ", e);
-      }
-      if (enableLongPolling) {
-        EXECUTOR.execute(this);
-      }
-    }
-
-    @SuppressWarnings("deprecation")
-    void refreshConfig(CountDownLatch latch) {
-      String path = "/v1/"
-          + KieConfig.INSTANCE.getDomainName()
-          + "/kie/kv?label=app:"
-          + KieConfig.INSTANCE.getAppName()
-          + "&revision=" + revision;
-      long timeout;
-      if (enableLongPolling && !IS_FIRST_PULL.get()) {
-        path += "&wait=" + LONG_POLLING_WAIT_TIME_IN_SECONDS + "s";
-        timeout = LONG_POLLING_REQUEST_TIME_OUT_IN_MILLIS;
-      } else {
-        IS_FIRST_PULL.compareAndSet(true, false);
-        timeout = PULL_REQUEST_TIME_OUT_IN_MILLIS;
-      }
-      String finalPath = path;
-      
HttpClients.getClient(ConfigKieHttpClientOptionsSPI.CLIENT_NAME).runOnContext(client
 -> {
-        IpPort ipPort = NetUtils.parseIpPortFromURI(serviceUri);
-        HttpClientRequest request = client
-            .get(ipPort.getPort(), ipPort.getHostOrIp(), finalPath, rsp -> {
-              if (rsp.statusCode() == HttpStatus.SC_OK) {
-                revision = rsp.getHeader("X-Kie-Revision");
-                rsp.bodyHandler(buf -> {
-                  try {
-                    Map<String, Object> resMap = 
KieUtil.getConfigByLabel(JsonUtils.OBJ_MAPPER
-                        .readValue(buf.toString(), KVResponse.class));
-                    KieWatcher.INSTANCE.refreshConfigItems(resMap);
-                    EventManager.post(new ConnSuccEvent());
-                  } catch (IOException e) {
-                    EventManager.post(new ConnFailEvent(
-                        "config update result parse fail " + e.getMessage()));
-                    LOGGER.error("Config update from {} failed. Error message 
is [{}].",
-                        serviceUri,
-                        e.getMessage());
-                  }
-                  latch.countDown();
-                });
-              } else if (rsp.statusCode() == HttpStatus.SC_NOT_MODIFIED) {
-                EventManager.post(new ConnSuccEvent());
-                latch.countDown();
-              } else {
-                EventManager.post(new ConnFailEvent("fetch config fail"));
-                LOGGER.error("Config update from {} failed. Error code is {}, 
error message is [{}].",
-                    serviceUri,
-                    rsp.statusCode(),
-                    rsp.statusMessage());
-                latch.countDown();
-              }
-            }).setTimeout(timeout);
-
-        request.exceptionHandler(e -> {
-          EventManager.post(new ConnFailEvent("fetch config fail"));
-          LOGGER.error("Config update from {} failed. Error message is [{}].",
-              serviceUri,
-              e.getMessage());
-          latch.countDown();
-        });
-        request.end();
-      });
-    }
-  }
-}
diff --git 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/KieUtil.java
 
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/KieUtil.java
deleted file mode 100644
index 63ebefa..0000000
--- 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/KieUtil.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.config.kie.client;
-
-import java.math.BigInteger;
-import java.nio.charset.StandardCharsets;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.servicecomb.config.kie.model.KVDoc;
-import org.apache.servicecomb.config.kie.model.KVResponse;
-import org.apache.servicecomb.config.kie.model.ValueType;
-import org.apache.servicecomb.config.parser.Parser;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class KieUtil {
-
-  private static final Logger LOGGER = LoggerFactory.getLogger(KieUtil.class);
-
-  private static final String LABEL_ENV = "environment";
-
-  private static final String LABEL_APP = "app";
-
-  private static final String LABEL_SERVICE = "service";
-
-  private static final String LABEL_VERSION = "version";
-
-  private static final String STATUS_ENABLED = "enabled";
-
-  public static String encrypt(String dataStr) {
-    MessageDigest messageDigest = null;
-    String result = "";
-    try {
-      messageDigest = MessageDigest.getInstance("MD5");
-      messageDigest.update(dataStr.getBytes(StandardCharsets.UTF_8));
-      result = new BigInteger(1, 
messageDigest.digest(dataStr.getBytes(StandardCharsets.UTF_8)))
-          .toString(16);
-    } catch (NoSuchAlgorithmException e) {
-      LOGGER.error("Failed to generate MD5 . ", e);
-    }
-    return result;
-  }
-
-  public static Map<String, Object> getConfigByLabel(KVResponse resp) {
-    Map<String, Object> resultMap = new HashMap<>();
-    List<KVDoc> appList = new ArrayList<>();
-    List<KVDoc> serviceList = new ArrayList<>();
-    List<KVDoc> versionList = new ArrayList<>();
-    for (KVDoc kvDoc : resp.getData()) {
-      if (!StringUtils.isEmpty(kvDoc.getStatus()) && 
!kvDoc.getStatus().equals(STATUS_ENABLED)) {
-        continue;
-      }
-      Map<String, String> labelsMap = kvDoc.getLabels();
-      if (labelsMap.containsKey(LABEL_APP) && labelsMap.get(LABEL_APP)
-          .equals(KieConfig.INSTANCE.getAppName())
-          && labelsMap.containsKey(LABEL_ENV) && labelsMap.get(LABEL_ENV)
-          .equals(KieConfig.INSTANCE.getEnvironment())) {
-        if (!labelsMap.containsKey(LABEL_SERVICE)) {
-          appList.add(kvDoc);
-        }
-        if (labelsMap.containsKey(LABEL_SERVICE) && 
labelsMap.get(LABEL_SERVICE)
-            .equals(KieConfig.INSTANCE.getServiceName())) {
-          if (!kvDoc.getLabels().containsKey(LABEL_VERSION)) {
-            serviceList.add(kvDoc);
-          }
-          if (labelsMap.containsKey(LABEL_VERSION) && 
labelsMap.get(LABEL_VERSION)
-              .equals(KieConfig.INSTANCE.getVersion())) {
-            versionList.add(kvDoc);
-          }
-        }
-      }
-    }
-    //kv is priority
-    for (KVDoc kvDoc : appList) {
-      resultMap.putAll(processValueType(kvDoc));
-    }
-    for (KVDoc kvDoc : serviceList) {
-      resultMap.putAll(processValueType(kvDoc));
-    }
-    for (KVDoc kvDoc : versionList) {
-      resultMap.putAll(processValueType(kvDoc));
-    }
-    return resultMap;
-  }
-
-  public static Map<String, Object> processValueType(KVDoc kvDoc) {
-    ValueType valueType = parseValueType(kvDoc.getValueType());
-    if (valueType == (ValueType.YAML) || valueType == (ValueType.YML)) {
-      return 
Parser.findParser(Parser.CONTENT_TYPE_YAML).parse(kvDoc.getValue(), 
kvDoc.getKey(), true);
-    } else if (valueType == (ValueType.PROPERTIES)) {
-      return 
Parser.findParser(Parser.CONTENT_TYPE_PROPERTIES).parse(kvDoc.getValue(), 
kvDoc.getKey(), true);
-    } else {
-      return 
Parser.findParser(Parser.CONTENT_TYPE_RAW).parse(kvDoc.getValue(), 
kvDoc.getKey(), true);
-    }
-  }
-
-  private static ValueType parseValueType(String valueType) {
-    if (StringUtils.isEmpty(valueType)) {
-      return ValueType.STRING;
-    }
-
-    try {
-      return ValueType.valueOf(valueType.toUpperCase());
-    } catch (IllegalArgumentException e) {
-      LOGGER.warn("read unrecognized value type {}", valueType);
-      return ValueType.STRING;
-    }
-  }
-
-
-  @SuppressWarnings("unchecked")
-  private static Map<String, String> toMap(String prefix, Properties 
properties) {
-    Map<String, String> result = new HashMap<>();
-    Enumeration<String> keys = (Enumeration<String>) 
properties.propertyNames();
-    while (keys.hasMoreElements()) {
-      String key = keys.nextElement();
-      Object value = properties.getProperty(key);
-
-      if (!StringUtils.isEmpty(prefix)) {
-        key = prefix + "." + key;
-      }
-
-      if (value != null) {
-        result.put(key, ((String) value).trim());
-      } else {
-        result.put(key, null);
-      }
-    }
-    return result;
-  }
-}
diff --git 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/KieWatcher.java
 
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/KieWatcher.java
deleted file mode 100644
index 0d7ba32..0000000
--- 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/KieWatcher.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.config.kie.client;
-
-import java.util.HashMap;
-import java.util.Map;
-import 
org.apache.servicecomb.config.kie.archaius.sources.KieConfigurationSourceImpl.UpdateHandler;
-import org.springframework.util.CollectionUtils;
-import org.springframework.util.StringUtils;
-
-public class KieWatcher {
-
-  public static final KieWatcher INSTANCE = new KieWatcher();
-
-  private UpdateHandler updateHandler;
-
-  private String refreshRecord;
-
-  Map<String, Object> lastTimeData;
-
-  private KieWatcher() {
-  }
-
-  public void setUpdateHandler(UpdateHandler updateHandler) {
-    this.updateHandler = updateHandler;
-  }
-
-  public void refreshConfigItems(Map<String, Object> remoteItems) {
-    String md5Vaule = KieUtil.encrypt(remoteItems.toString());
-    if (CollectionUtils.isEmpty(remoteItems)) {
-      updateHandler.handle("delete", lastTimeData);
-      lastTimeData = remoteItems;
-      return;
-    }
-    if (StringUtils.isEmpty(refreshRecord)) {
-      refreshRecord = md5Vaule;
-      updateHandler.handle("create", remoteItems);
-      lastTimeData = remoteItems;
-      return;
-    }
-    if (md5Vaule.equals(refreshRecord)) {
-      return;
-    }
-    refreshRecord = md5Vaule;
-    doRefresh(remoteItems);
-    lastTimeData = remoteItems;
-  }
-
-
-  private void doRefresh(Map<String, Object> remoteItems) {
-    Map<String, Object> itemsCreated = new HashMap<>();
-    Map<String, Object> itemsDeleted = new HashMap<>();
-    Map<String, Object> itemsModified = new HashMap<>();
-    for (String itemKey : remoteItems.keySet()) {
-      if (!lastTimeData.containsKey(itemKey)) {
-        itemsCreated.put(itemKey, remoteItems.get(itemKey));
-      } else if (!remoteItems.get(itemKey).equals(lastTimeData.get(itemKey))) {
-        itemsModified.put(itemKey, remoteItems.get(itemKey));
-      }
-    }
-    for (String itemKey : lastTimeData.keySet()) {
-      if (!remoteItems.containsKey(itemKey)) {
-        itemsDeleted.put(itemKey, "");
-      }
-    }
-    updateHandler.handle("create", itemsCreated);
-    updateHandler.handle("set", itemsModified);
-    updateHandler.handle("delete", itemsDeleted);
-  }
-
-}
diff --git 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/model/KVBody.java
 
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/model/KVBody.java
deleted file mode 100644
index b7deee0..0000000
--- 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/model/KVBody.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.config.kie.model;
-
-import com.fasterxml.jackson.annotation.JsonAlias;
-import java.util.HashMap;
-import java.util.Map;
-import org.apache.servicecomb.config.kie.client.KieConfig;
-
-public class KVBody {
-
-  private Map<String, String> labels = new HashMap<String, String>();
-
-  private String value;
-
-  @JsonAlias("value_type")
-  private String valueType;
-
-  public Map<String, String> getLabels() {
-    return labels;
-  }
-
-  public void setLabels(Map<String, String> labels) {
-    this.labels = labels;
-  }
-
-  public void initLabels() {
-    labels.put("env", KieConfig.INSTANCE.getEnvironment());
-    labels.put("app", KieConfig.INSTANCE.getAppName());
-    labels.put("service", KieConfig.INSTANCE.getServiceName());
-    labels.put("version", KieConfig.INSTANCE.getVersion());
-    labels.put("tags", KieConfig.INSTANCE.getTags());
-  }
-
-  public String getValue() {
-    return value;
-  }
-
-  public void setValue(String value) {
-    this.value = value;
-  }
-
-  public String getValueType() {
-    return valueType;
-  }
-
-  public void setValueType(String valueType) {
-    this.valueType = valueType;
-  }
-}
diff --git 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/model/KVDoc.java
 
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/model/KVDoc.java
deleted file mode 100644
index e969442..0000000
--- 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/model/KVDoc.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.config.kie.model;
-
-import com.fasterxml.jackson.annotation.JsonAlias;
-import java.util.HashMap;
-import java.util.Map;
-
-public class KVDoc {
-
-  private String id;
-
-  private String check;
-
-  private String domain;
-
-  private String key;
-
-  @JsonAlias("label_id")
-  private String labelId;
-
-  private Map<String, String> labels = new HashMap<String, String>();
-
-  private Integer revision;
-
-  private String value;
-
-  @JsonAlias("value_type")
-  private String valueType;
-
-  private String status;
-
-  public String getStatus() {
-    return status;
-  }
-
-  public void setStatus(String status) {
-    this.status = status;
-  }
-
-  public String getId() {
-    return id;
-  }
-
-  public void setId(String id) {
-    this.id = id;
-  }
-
-  public String getKey() {
-    return key;
-  }
-
-  public void setKey(String key) {
-    this.key = key;
-  }
-
-  public String getCheck() {
-    return check;
-  }
-
-  public String getDomain() {
-    return domain;
-  }
-
-  public String getLabelId() {
-    return labelId;
-  }
-
-  public Map<String, String> getLabels() {
-    return labels;
-  }
-
-  public Integer getRevision() {
-    return revision;
-  }
-
-  public String getValue() {
-    return value;
-  }
-
-  public void setCheck(String check) {
-    this.check = check;
-  }
-
-  public void setDomain(String domain) {
-    this.domain = domain;
-  }
-
-  public void setLabelId(String labelId) {
-    this.labelId = labelId;
-  }
-
-  public void setLabels(Map<String, String> labels) {
-    this.labels = labels;
-  }
-
-  public void setRevision(Integer revision) {
-    this.revision = revision;
-  }
-
-  public void setValueType(String valueType) {
-    this.valueType = valueType;
-  }
-
-  public void setValue(String value) {
-    this.value = value;
-  }
-
-  public String getValueType() {
-    return valueType;
-  }
-}
diff --git 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/model/KVResponse.java
 
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/model/KVResponse.java
deleted file mode 100644
index f67fa00..0000000
--- 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/model/KVResponse.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.config.kie.model;
-
-import java.util.List;
-
-public class KVResponse {
-
-  private List<KVDoc> data;
-
-  private LabelDocResponse label;
-
-  private Integer total;
-
-  public Integer getTotal() {
-    return total;
-  }
-
-  public void setTotal(Integer total) {
-    this.total = total;
-  }
-
-  public List<KVDoc> getData() {
-    return data;
-  }
-
-  public LabelDocResponse getLabel() {
-    return label;
-  }
-
-  public void setData(List<KVDoc> data) {
-    this.data = data;
-  }
-
-  public void setLabel(LabelDocResponse label) {
-    this.label = label;
-  }
-}
diff --git 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/model/LabelDocResponse.java
 
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/model/LabelDocResponse.java
deleted file mode 100644
index fb2b541..0000000
--- 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/model/LabelDocResponse.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.config.kie.model;
-
-import com.fasterxml.jackson.annotation.JsonAlias;
-import java.util.HashMap;
-import java.util.Map;
-
-public class LabelDocResponse {
-
-  @JsonAlias("label_id")
-  private String labelId;
-
-  private Map<String, String> labels = new HashMap<String, String>();
-
-  public String getLabelId() {
-    return labelId;
-  }
-
-  public Map<String, String> getLabels() {
-    return labels;
-  }
-
-  public void setLabelId(String labelId) {
-    this.labelId = labelId;
-  }
-
-  public void setLabels(Map<String, String> labels) {
-    this.labels = labels;
-  }
-}
diff --git 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/model/ValueType.java
 
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/model/ValueType.java
deleted file mode 100644
index 8190878..0000000
--- 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/model/ValueType.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.config.kie.model;
-
-public enum ValueType {
-  YML,
-  YAML,
-  STRING,
-  TEXT,
-  JSON,
-  PROPERTIES
-}
diff --git 
a/dynamic-config/config-kie/src/main/resources/META-INF/services/org.apache.servicecomb.config.spi.ConfigCenterConfigurationSource
 
b/dynamic-config/config-kie/src/main/resources/META-INF/services/org.apache.servicecomb.config.spi.ConfigCenterConfigurationSource
index c696fa9..67520d4 100644
--- 
a/dynamic-config/config-kie/src/main/resources/META-INF/services/org.apache.servicecomb.config.spi.ConfigCenterConfigurationSource
+++ 
b/dynamic-config/config-kie/src/main/resources/META-INF/services/org.apache.servicecomb.config.spi.ConfigCenterConfigurationSource
@@ -15,4 +15,4 @@
 # limitations under the License.
 #
 
-org.apache.servicecomb.config.kie.archaius.sources.KieConfigurationSourceImpl
\ No newline at end of file
+org.apache.servicecomb.config.kie.KieConfigurationSourceImpl
\ No newline at end of file
diff --git 
a/dynamic-config/config-kie/src/test/java/org/apache/servicecomb/config/kie/client/TestKieClient.java
 
b/dynamic-config/config-kie/src/test/java/org/apache/servicecomb/config/kie/client/TestKieClient.java
deleted file mode 100644
index 4b73db2..0000000
--- 
a/dynamic-config/config-kie/src/test/java/org/apache/servicecomb/config/kie/client/TestKieClient.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.config.kie.client;
-
-import com.google.common.eventbus.Subscribe;
-import io.vertx.core.Handler;
-import io.vertx.core.MultiMap;
-import io.vertx.core.buffer.Buffer;
-import io.vertx.core.http.HttpClient;
-import io.vertx.core.http.HttpClientRequest;
-import io.vertx.core.http.HttpClientResponse;
-import io.vertx.core.http.HttpMethod;
-import io.vertx.core.json.JsonObject;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.ScheduledExecutorService;
-import mockit.Deencapsulation;
-import mockit.Expectations;
-import mockit.Mock;
-import mockit.MockUp;
-import mockit.Mocked;
-import org.apache.servicecomb.config.ConfigUtil;
-import 
org.apache.servicecomb.config.kie.archaius.sources.KieConfigurationSourceImpl;
-import 
org.apache.servicecomb.config.kie.archaius.sources.KieConfigurationSourceImpl.UpdateHandler;
-import org.apache.servicecomb.config.kie.client.KieClient.ConfigRefresh;
-import org.apache.servicecomb.foundation.common.event.EventManager;
-import org.apache.servicecomb.foundation.vertx.client.ClientPoolManager;
-import 
org.apache.servicecomb.foundation.vertx.client.http.HttpClientWithContext;
-import 
org.apache.servicecomb.foundation.vertx.client.http.HttpClientWithContext.RunHandler;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-@SuppressWarnings("deprecation")
-public class TestKieClient {
-
-  String mockKvResponse = "{\n"
-      + "  \"data\": [\n"
-      + "    {\n"
-      + "      \"id\": \"string\",\n"
-      + "      \"check\": \"string\",\n"
-      + "      \"domain\": \"string\",\n"
-      + "      \"key\": \"string\",\n"
-      + "      \"label_id\": \"string\",\n"
-      + "      \"labels\": {\n"
-      + "        \"additionalProp1\": \"string\",\n"
-      + "        \"additionalProp2\": \"string\",\n"
-      + "        \"additionalProp3\": \"string\"\n"
-      + "      },\n"
-      + "      \"project\": \"string\",\n"
-      + "      \"revision\": 0,\n"
-      + "      \"value\": \"string\",\n"
-      + "      \"value_type\": \"string\"\n"
-      + "    }\n"
-      + "  ],\n"
-      + "  \"label\": {\n"
-      + "    \"label_id\": \"string\",\n"
-      + "    \"labels\": {\n"
-      + "      \"additionalProp1\": \"string\",\n"
-      + "      \"additionalProp2\": \"string\",\n"
-      + "      \"additionalProp3\": \"string\"\n"
-      + "    }\n"
-      + "  },\n"
-      + "  \"num\": 0,\n"
-      + "  \"size\": 0,\n"
-      + "  \"total\": 0\n"
-      + "}";
-
-  @BeforeClass
-  public static void setUpClass() {
-    KieConfig.setFinalConfig(ConfigUtil.createLocalConfig());
-  }
-
-  @SuppressWarnings("unchecked")
-  @Test
-  public void testRefreshKieConfig() {
-    HttpClientRequest request = Mockito.mock(HttpClientRequest.class);
-    Mockito.when(request.method()).thenReturn(HttpMethod.GET);
-    
Mockito.when(request.headers()).thenReturn(MultiMap.caseInsensitiveMultiMap());
-    Buffer rsp = Mockito.mock(Buffer.class);
-    Mockito.when(rsp.toJsonObject()).thenReturn(new 
JsonObject(mockKvResponse));
-    HttpClientResponse event = Mockito.mock(HttpClientResponse.class);
-    
Mockito.when(event.bodyHandler(Mockito.any(Handler.class))).then(invocation -> {
-      Handler<Buffer> handler = invocation.getArgumentAt(0, Handler.class);
-      handler.handle(rsp);
-      return null;
-    });
-    Mockito.when(event.statusCode()).thenReturn(200);
-    HttpClient httpClient = Mockito.mock(HttpClient.class);
-    Mockito.when(
-        httpClient.get(Mockito.anyInt(), Mockito.anyString(), 
Mockito.anyString(),
-            Mockito.any(Handler.class)))
-        .then(invocation -> {
-          Handler<HttpClientResponse> handler = invocation.getArgumentAt(3, 
Handler.class);
-          handler.handle(event);
-          return request;
-        });
-    new MockUp<HttpClientWithContext>() {
-      @Mock
-      public void runOnContext(RunHandler handler) {
-        handler.run(httpClient);
-      }
-    };
-    UpdateHandler updateHandler = new KieConfigurationSourceImpl().new 
UpdateHandler();
-    KieClient kie = new KieClient(updateHandler);
-    kie.refreshKieConfig();
-  }
-
-
-  public static class ConfigRefreshExceptionEvent {
-    Map<String, String> map;
-
-    public ConfigRefreshExceptionEvent(Map<String, String> map) {
-      this.map = map;
-    }
-
-    @Subscribe
-    public void testMsg(Object event) {
-      if (event instanceof ConnFailEvent) {
-        map.put("result", "Fail event trigger");
-      }
-      if (event instanceof ConnSuccEvent) {
-        map.put("result", "Succ event trigger");
-      }
-    }
-  }
-
-  @SuppressWarnings("unchecked")
-  @Test
-  public void testConfigRefreshException(@Mocked 
ClientPoolManager<HttpClientWithContext> clientMgr,
-      @Mocked HttpClientWithContext httpClientWithContext) {
-    KieConfigurationSourceImpl impl = new KieConfigurationSourceImpl();
-    Map<String, String> map = new HashMap<>();
-    EventManager.register(new ConfigRefreshExceptionEvent(map));
-    UpdateHandler updateHandler = impl.new UpdateHandler();
-    HttpClientRequest request = Mockito.mock(HttpClientRequest.class);
-    
Mockito.when(request.headers()).thenReturn(MultiMap.caseInsensitiveMultiMap());
-    Buffer rsp = Mockito.mock(Buffer.class);
-    Mockito.when(rsp.toString()).thenReturn(mockKvResponse);
-
-    HttpClientResponse event = Mockito.mock(HttpClientResponse.class);
-    
Mockito.when(event.bodyHandler(Mockito.any(Handler.class))).then(invocation -> {
-      Handler<Buffer> handler = invocation.getArgumentAt(0, Handler.class);
-      handler.handle(rsp);
-      return null;
-    });
-    Mockito.when(event.statusCode()).thenReturn(400);
-    Buffer buf = Mockito.mock(Buffer.class);
-    Mockito.when(buf.toJsonObject()).thenReturn(new 
JsonObject(mockKvResponse));
-    HttpClient httpClient = Mockito.mock(HttpClient.class);
-    Mockito.when(
-        httpClient.get(Mockito.anyInt(), Mockito.anyString(), 
Mockito.anyString(),
-            Mockito.any(Handler.class)))
-        .then(invocation -> {
-          Handler<HttpClientResponse> handler = invocation.getArgumentAt(3, 
Handler.class);
-          handler.handle(event);
-          return request;
-        });
-    new MockUp<HttpClientWithContext>() {
-      @Mock
-      public void runOnContext(RunHandler handler) {
-        handler.run(httpClient);
-      }
-    };
-
-    KieClient kie = new KieClient(updateHandler);
-
-    ConfigRefresh refresh = kie.new 
ConfigRefresh("http://configcentertest:30110";);
-    refresh.run();
-    Assert.assertEquals("Fail event trigger", map.get("result"));
-    Mockito.when(event.statusCode()).thenReturn(200);
-    refresh.run();
-    Assert.assertEquals("Succ event trigger", map.get("result"));
-  }
-
-  @Test
-  public void destroy() {
-    KieClient kieClient = new KieClient(null);
-    ScheduledExecutorService executor = Deencapsulation.getField(kieClient, 
"EXECUTOR");
-    Assert.assertFalse(executor.isShutdown());
-    executor.shutdown();
-    Assert.assertTrue(executor.isShutdown());
-  }
-}
diff --git 
a/dynamic-config/config-kie/src/test/java/org/apache/servicecomb/config/kie/client/TestKieConfig.java
 
b/dynamic-config/config-kie/src/test/java/org/apache/servicecomb/config/kie/client/TestKieConfig.java
deleted file mode 100644
index 1f8e6d2..0000000
--- 
a/dynamic-config/config-kie/src/test/java/org/apache/servicecomb/config/kie/client/TestKieConfig.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.config.kie.client;
-
-import org.apache.servicecomb.config.ConfigUtil;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-public class TestKieConfig {
-
-  @BeforeClass
-  public static void setUpClass() {
-    KieConfig.setFinalConfig(ConfigUtil.createLocalConfig());
-  }
-
-  @Test
-  public void getServerUri() {
-    String servers = KieConfig.INSTANCE.getServerUri();
-    Assert.assertEquals("https://172.16.8.7:30110";, servers);
-  }
-
-  @Test
-  public void getEnvironment() {
-    Assert.assertEquals("testing", KieConfig.INSTANCE.getEnvironment());
-    System.setProperty("SERVICECOMB_ENV", "development");
-    KieConfig.setFinalConfig(ConfigUtil.createLocalConfig());
-    Assert.assertEquals("development", KieConfig.INSTANCE.getEnvironment());
-  }
-
-}
diff --git 
a/dynamic-config/config-kie/src/test/java/org/apache/servicecomb/config/kie/client/TestKieUtil.java
 
b/dynamic-config/config-kie/src/test/java/org/apache/servicecomb/config/kie/client/TestKieUtil.java
deleted file mode 100644
index 55e991e..0000000
--- 
a/dynamic-config/config-kie/src/test/java/org/apache/servicecomb/config/kie/client/TestKieUtil.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.config.kie.client;
-
-import java.util.Map;
-
-import org.apache.servicecomb.config.kie.model.KVDoc;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class TestKieUtil {
-  @Test
-  public void test_processValueType() {
-    KVDoc kvDoc = new KVDoc();
-    kvDoc.setKey("hello");
-    kvDoc.setValue("world");
-    Map<String, Object> result = KieUtil.processValueType(kvDoc);
-    Assert.assertEquals("world", result.get("hello"));
-
-    kvDoc.setValueType("text");
-    result = KieUtil.processValueType(kvDoc);
-    Assert.assertEquals("world", result.get("hello"));
-
-    kvDoc.setValueType("string");
-    result = KieUtil.processValueType(kvDoc);
-    Assert.assertEquals("world", result.get("hello"));
-
-    kvDoc.setValueType("json");
-    result = KieUtil.processValueType(kvDoc);
-    Assert.assertEquals("world", result.get("hello"));
-
-    kvDoc.setValueType("yml");
-    kvDoc.setValue("hello: world");
-    result = KieUtil.processValueType(kvDoc);
-    Assert.assertEquals("world", result.get("hello.hello"));
-
-    kvDoc.setValueType("yaml");
-    kvDoc.setValue("hello: world");
-    result = KieUtil.processValueType(kvDoc);
-    Assert.assertEquals("world", result.get("hello.hello"));
-
-    kvDoc.setValueType("properties");
-    kvDoc.setValue("hello=world");
-    result = KieUtil.processValueType(kvDoc);
-    Assert.assertEquals("world", result.get("hello.hello"));
-  }
-}
diff --git 
a/dynamic-config/config-kie/src/test/java/org/apache/servicecomb/config/kie/client/TestKieWatcher.java
 
b/dynamic-config/config-kie/src/test/java/org/apache/servicecomb/config/kie/client/TestKieWatcher.java
deleted file mode 100644
index 126107e..0000000
--- 
a/dynamic-config/config-kie/src/test/java/org/apache/servicecomb/config/kie/client/TestKieWatcher.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.config.kie.client;
-
-import java.util.HashMap;
-import java.util.Map;
-import mockit.Deencapsulation;
-import 
org.apache.servicecomb.config.kie.archaius.sources.KieConfigurationSourceImpl;
-import 
org.apache.servicecomb.config.kie.archaius.sources.KieConfigurationSourceImpl.UpdateHandler;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class TestKieWatcher {
-
-  private KieConfigurationSourceImpl kieSource = new 
KieConfigurationSourceImpl();
-
-  private UpdateHandler uh = kieSource.new UpdateHandler();
-
-  {
-    KieWatcher.INSTANCE.setUpdateHandler(uh);
-  }
-
-  @Test
-  public void testRefreshConfigItems() {
-    boolean status = true;
-    Map<String, Object> configMap = new HashMap<>();
-    configMap.put("key1", "application1");
-    configMap.put("key2", "application2");
-    configMap.put("key3", "application3");
-    configMap.put("key4", "application4");
-    Map<String, Object> result = null;
-    try {
-      result = Deencapsulation.invoke(KieWatcher.INSTANCE, 
"refreshConfigItems", configMap);
-    } catch (Exception e) {
-      status = false;
-    }
-    Assert.assertTrue(status);
-  }
-}
diff --git 
a/dynamic-config/config-kie/src/test/java/org/apache/servicecomb/config/kie/sources/TestKieConfigurationSource.java
 
b/dynamic-config/config-kie/src/test/java/org/apache/servicecomb/config/kie/sources/TestKieConfigurationSource.java
deleted file mode 100644
index 73cfae5..0000000
--- 
a/dynamic-config/config-kie/src/test/java/org/apache/servicecomb/config/kie/sources/TestKieConfigurationSource.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.servicecomb.config.kie.sources;
-
-import com.netflix.config.WatchedUpdateListener;
-import com.netflix.config.WatchedUpdateResult;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
-import mockit.Deencapsulation;
-import mockit.Mock;
-import mockit.MockUp;
-import org.apache.commons.lang.reflect.FieldUtils;
-import 
org.apache.servicecomb.config.kie.archaius.sources.KieConfigurationSourceImpl;
-import 
org.apache.servicecomb.config.kie.archaius.sources.KieConfigurationSourceImpl.UpdateHandler;
-import org.apache.servicecomb.config.kie.client.KieClient;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class TestKieConfigurationSource {
-
-  @Test
-  public void testCreate() {
-
-    KieConfigurationSourceImpl kieSource = new KieConfigurationSourceImpl();
-    kieSource.addUpdateListener(result -> 
Assert.assertTrue(!result.getAdded().isEmpty()));
-    UpdateHandler udateHandler = Deencapsulation.getField(kieSource, 
UpdateHandler.class);
-    Map<String, Object> addedItems = new HashMap<>();
-    addedItems.put("testKey", "testValue");
-    udateHandler.handle("create", addedItems);
-  }
-
-  @Test
-  public void testUpdate() {
-
-    KieConfigurationSourceImpl kieSource = new KieConfigurationSourceImpl();
-    kieSource.addUpdateListener(result -> 
Assert.assertTrue(!result.getChanged().isEmpty()));
-    UpdateHandler udateHandler = Deencapsulation.getField(kieSource, 
UpdateHandler.class);
-    Map<String, Object> addedItems = new HashMap<>();
-    addedItems.put("testKey", "testValue");
-    udateHandler.handle("set", addedItems);
-  }
-
-  @Test
-  public void testDelete() throws Exception {
-    KieConfigurationSourceImpl kieSource = new KieConfigurationSourceImpl();
-    kieSource.addUpdateListener(result -> 
Assert.assertTrue(!result.getDeleted().isEmpty()));
-    UpdateHandler udateHandler = Deencapsulation.getField(kieSource, 
UpdateHandler.class);
-    Map<String, Object> addedItems = new HashMap<>();
-    addedItems.put("testKey", "testValue");
-
-    kieSource.getCurrentData().put("testKey", "testValue");
-    udateHandler.handle("delete", addedItems);
-    Assert.assertTrue(kieSource.getCurrentData().isEmpty());
-  }
-
-  @Test
-  public void destroy_notInit() {
-    KieConfigurationSourceImpl kieSource = new KieConfigurationSourceImpl();
-
-    // need not throw exception
-    kieSource.destroy();
-  }
-
-  @Test
-  public void destroy_inited() throws IllegalAccessException {
-    AtomicInteger count = new AtomicInteger();
-    KieClient kieClient = new MockUp<KieClient>() {
-      @Mock
-      void destroy() {
-        count.incrementAndGet();
-      }
-    }.getMockInstance();
-    KieConfigurationSourceImpl kieSource = new KieConfigurationSourceImpl();
-    FieldUtils
-        .writeDeclaredField(kieSource, "kieClient", kieClient, true);
-
-    kieSource.destroy();
-
-    Assert.assertEquals(1, count.get());
-  }
-}

Reply via email to