[SCB-2081]add ak/sk auth support
diff --git a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpConfiguration.java b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpConfiguration.java
index 59b6b4c..b233488 100644
--- a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpConfiguration.java
+++ b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpConfiguration.java
@@ -52,4 +52,63 @@
       this.sslCustom = sslCustom;
     }
   }
+
+  class AKSKProperties {
+    private boolean enabled;
+
+    private String accessKey;
+
+    private String secretKey;
+
+    private String cipher;
+
+    private String project;
+
+    public boolean isEnabled() {
+      return enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+      this.enabled = enabled;
+    }
+
+    public String getAccessKey() {
+      return accessKey;
+    }
+
+    public void setAccessKey(String accessKey) {
+      this.accessKey = accessKey;
+    }
+
+    public String getSecretKey() {
+      if ("ShaAKSKCipher".equalsIgnoreCase(this.cipher)) {
+        return this.secretKey;
+      }
+      try {
+        return HttpUtils.sha256Encode(this.secretKey, this.accessKey);
+      } catch (Exception e) {
+        throw new IllegalArgumentException("not able to encode ak sk.", e);
+      }
+    }
+
+    public void setSecretKey(String secretKey) {
+      this.secretKey = secretKey;
+    }
+
+    public String getCipher() {
+      return cipher;
+    }
+
+    public void setCipher(String cipher) {
+      this.cipher = cipher;
+    }
+
+    public String getProject() {
+      return project;
+    }
+
+    public void setProject(String project) {
+      this.project = project;
+    }
+  }
 }
diff --git a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportFactory.java b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportFactory.java
index 3fa5f73..f9c7b6c 100644
--- a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportFactory.java
+++ b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportFactory.java
@@ -43,7 +43,8 @@
   private HttpTransportFactory() {
   }
 
-  public static HttpTransport createHttpTransport(HttpConfiguration.SSLProperties sslProperties) {
+  public static HttpTransport createHttpTransport(HttpConfiguration.SSLProperties sslProperties,
+      HttpConfiguration.AKSKProperties akskProperties) {
     RequestConfig config = RequestConfig.custom()
         .setConnectTimeout(CONNECT_TIMEOUT)
         .setConnectionRequestTimeout(
@@ -72,6 +73,6 @@
         setConnectionManager(connectionManager).
         disableCookieManagement();
 
-    return new HttpTransportImpl(httpClientBuilder.build());
+    return new HttpTransportImpl(httpClientBuilder.build(), akskProperties);
   }
 }
diff --git a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportImpl.java b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportImpl.java
index 06f714d..7019d87 100644
--- a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportImpl.java
+++ b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportImpl.java
@@ -22,6 +22,8 @@
 
 import org.apache.http.client.HttpClient;
 import org.apache.http.util.EntityUtils;
+import org.apache.servicecomb.http.client.common.HttpConfiguration.AKSKProperties;
+import org.apache.servicecomb.http.client.common.auth.AKSKHeaderUtil;
 
 /**
  * Created by   on 2019/10/16.
@@ -36,8 +38,11 @@
 
   private Map<String, String> globalHeaders;
 
-  public HttpTransportImpl(HttpClient httpClient) {
+  private AKSKProperties akskProperties;
+
+  public HttpTransportImpl(HttpClient httpClient, AKSKProperties akskProperties) {
     this.httpClient = httpClient;
+    this.akskProperties = akskProperties;
   }
 
   public HttpClient getHttpClient() {
@@ -82,6 +87,8 @@
       globalHeaders.forEach(httpRequest::addHeader);
     }
 
+    AKSKHeaderUtil.addAKSKHeader(httpRequest, akskProperties);
+
     //get Http response
     org.apache.http.HttpResponse response = httpClient.execute(httpRequest.getRealRequest());
 
diff --git a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpUtils.java b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpUtils.java
index 0ce07e6..e9c4e1f 100644
--- a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpUtils.java
+++ b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpUtils.java
@@ -19,29 +19,45 @@
 
 import java.io.IOException;
 import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
 
-import com.fasterxml.jackson.core.type.TypeReference;
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.commons.codec.binary.Hex;
+
+import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 
 public final class HttpUtils {
+  private static final String ALGORITHM_HMACSHA256 = "HmacSHA256";
+
   private static final ObjectMapper MAPPER = new MessageObjectMapper();
 
   public static <T> T deserialize(String content, Class<T> clazz) throws IOException {
     return MAPPER.readValue(content, clazz);
   }
 
-  public static <T> T deserialize(String content, TypeReference<T> clazz) throws IOException {
-    return MAPPER.readValue(content, clazz);
-  }
-
   public static String serialize(Object value) throws IOException {
     return MAPPER.writeValueAsString(value);
   }
 
+  public static JsonNode readTree(String content) throws IOException {
+    return MAPPER.readTree(content);
+  }
+
   public static String encodeURLParam(String value) throws IOException {
     if (value == null) {
       return "";
     }
     return URLEncoder.encode(value, "UTF-8");
   }
+
+  public static String sha256Encode(String key, String data) throws Exception {
+    Mac mac = Mac.getInstance(ALGORITHM_HMACSHA256);
+    SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8),
+        ALGORITHM_HMACSHA256);
+    mac.init(secretKey);
+    return Hex.encodeHexString(mac.doFinal(data.getBytes(StandardCharsets.UTF_8)));
+  }
 }
diff --git a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/AKSKHeaderExtension.java b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/AKSKHeaderExtension.java
new file mode 100644
index 0000000..85afa7b
--- /dev/null
+++ b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/AKSKHeaderExtension.java
@@ -0,0 +1,86 @@
+/*
+ * 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.http.client.common.auth;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+public abstract class AKSKHeaderExtension {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(AKSKHeaderExtension.class);
+
+  protected static final String DEFAULT_SECRET_AUTH_PATH = "/opt/CSE/etc/auth";
+
+  protected static final String DEFAULT_SECRET_AUTH_NAME = ".dockerconfigjson";
+
+  private static final int EXPECTED_ARR_LENGTH = 2;
+
+  private boolean runOverHWC = !StringUtils.isEmpty(System.getenv("KUBERNETES_SERVICE_HOST"));
+
+  private Map<String, String> defaultAuthHeaders = Collections.emptyMap();
+
+  private boolean loaded = false;
+
+  protected Map<String, String> getHeaders() {
+    if (!runOverHWC) {
+      return defaultAuthHeaders;
+    }
+    if (!loaded) {
+      synchronized (this) {
+        if (!loaded) {
+          createAuthHeaders();
+        }
+      }
+    }
+    return defaultAuthHeaders;
+  }
+
+  public abstract void createAuthHeaders();
+
+  protected void decode(JsonNode authNode) throws IOException {
+    if (authNode == null) {
+      return;
+    }
+    Map<String, String> authHeaders = new HashMap<String, String>();
+    String authStr = authNode.asText();
+    String authBase64Decode = new String(Base64.decodeBase64(authStr), "UTF-8");
+    String[] auths = authBase64Decode.split("@");
+    String[] akAndShaAkSk = auths[1].split(":");
+    if (auths.length != EXPECTED_ARR_LENGTH || akAndShaAkSk.length != EXPECTED_ARR_LENGTH) {
+      LOGGER.error("get docker config failed. The data is not valid cause of unexpected format");
+      return;
+    }
+    String project = auths[0];
+    String ak = akAndShaAkSk[0];
+    String shaAkSk = akAndShaAkSk[1];
+    authHeaders.put("X-Service-AK", ak);
+    authHeaders.put("X-Service-ShaAKSK", shaAkSk);
+    authHeaders.put("X-Service-Project", project);
+    defaultAuthHeaders = authHeaders;
+    loaded = true;
+  }
+}
diff --git a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/AKSKHeaderExtensionUtil.java b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/AKSKHeaderExtensionUtil.java
new file mode 100644
index 0000000..7b97ed5
--- /dev/null
+++ b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/AKSKHeaderExtensionUtil.java
@@ -0,0 +1,36 @@
+/*
+ * 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.http.client.common.auth;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Collections;
+import java.util.Map;
+
+public class AKSKHeaderExtensionUtil {
+
+  private static AKSKHeaderExtension headerExtension = new FileSystemMountAKSKHeaderExtension();
+
+  public static Map<String, String> genAuthHeaders() {
+    if (Files.exists(Paths.get(AKSKHeaderExtension.DEFAULT_SECRET_AUTH_PATH,
+        AKSKHeaderExtension.DEFAULT_SECRET_AUTH_NAME))) {
+      return headerExtension.getHeaders();
+    }
+    return Collections.emptyMap();
+  }
+}
diff --git a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/AKSKHeaderUtil.java b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/AKSKHeaderUtil.java
new file mode 100644
index 0000000..da4d564
--- /dev/null
+++ b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/AKSKHeaderUtil.java
@@ -0,0 +1,48 @@
+/*
+ * 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.http.client.common.auth;
+
+import java.util.Map;
+
+import org.apache.servicecomb.http.client.common.HttpConfiguration.AKSKProperties;
+import org.apache.servicecomb.http.client.common.HttpRequest;
+
+public class AKSKHeaderUtil {
+  public static final String X_SERVICE_AK = "X-Service-AK";
+
+  public static final String X_SERVICE_SHAAKSK = "X-Service-ShaAKSK";
+
+  public static final String X_SERVICE_PROJECT = "X-Service-Project";
+
+  public static void addAKSKHeader(HttpRequest httpRequest,
+      AKSKProperties serviceCombAkSkProperties) {
+    if (serviceCombAkSkProperties.isEnabled()) {
+      httpRequest.addHeader(X_SERVICE_AK, serviceCombAkSkProperties.getAccessKey());
+      httpRequest.addHeader(X_SERVICE_SHAAKSK, serviceCombAkSkProperties.getSecretKey());
+      httpRequest.addHeader(X_SERVICE_PROJECT, serviceCombAkSkProperties.getProject());
+      return;
+    }
+
+    Map<String, String> headerMap = AKSKHeaderExtensionUtil.genAuthHeaders();
+    if (!headerMap.isEmpty()) {
+      httpRequest.addHeader(X_SERVICE_AK, headerMap.get(X_SERVICE_AK));
+      httpRequest.addHeader(X_SERVICE_SHAAKSK, headerMap.get(X_SERVICE_SHAAKSK));
+      httpRequest.addHeader(X_SERVICE_PROJECT, headerMap.get(X_SERVICE_PROJECT));
+    }
+  }
+}
diff --git a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/FileSystemMountAKSKHeaderExtension.java b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/FileSystemMountAKSKHeaderExtension.java
new file mode 100644
index 0000000..0a4256b
--- /dev/null
+++ b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/FileSystemMountAKSKHeaderExtension.java
@@ -0,0 +1,97 @@
+/*
+ * 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.http.client.common.auth;
+
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardWatchEventKinds;
+import java.nio.file.WatchKey;
+import java.nio.file.WatchService;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.apache.servicecomb.http.client.common.HttpUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+public class FileSystemMountAKSKHeaderExtension extends AKSKHeaderExtension {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(FileSystemMountAKSKHeaderExtension.class);
+
+  private ExecutorService executor = Executors.newFixedThreadPool(1);
+
+  public FileSystemMountAKSKHeaderExtension() {
+    try {
+      Path p = Paths.get(DEFAULT_SECRET_AUTH_PATH);
+      if (!p.toFile().exists()) {
+        return;
+      }
+      WatchService watchService = FileSystems.getDefault().newWatchService();
+      p.register(watchService,
+          StandardWatchEventKinds.ENTRY_MODIFY,
+          StandardWatchEventKinds.ENTRY_CREATE);
+      executor.execute(new FileUpdateCheckThread(watchService));
+    } catch (Exception e) {
+      LOGGER.warn("get watch service failed.", e);
+    }
+  }
+
+  @Override
+  public void createAuthHeaders() {
+    try {
+      String content = new String(
+          Files.readAllBytes(Paths.get(DEFAULT_SECRET_AUTH_PATH, DEFAULT_SECRET_AUTH_NAME)),
+          "UTF-8");
+      JsonNode data = HttpUtils.readTree(content);
+      JsonNode authNode = data.findValue("auth");
+      decode(authNode);
+    } catch (Exception e) {
+      LOGGER.warn("read auth info from dockerconfigjson failed.", e);
+    }
+  }
+
+
+  final class FileUpdateCheckThread implements Runnable {
+
+    private WatchService service;
+
+    private FileUpdateCheckThread(WatchService service) {
+      this.service = service;
+    }
+
+    public void run() {
+      while (true) {
+        try {
+          WatchKey watchKey = service.take();
+          // 清理掉已发生的事件,否则会导致事件遗留,进入死循环
+          watchKey.pollEvents();
+          synchronized (this) {
+            createAuthHeaders();
+          }
+          watchKey.reset();
+        } catch (InterruptedException e) {
+          LOGGER.error("error occured. detail : {}", e.getMessage());
+        }
+      }
+    }
+  }
+}
diff --git a/clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/HttpTransportImplTest.java b/clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/HttpTransportImplTest.java
index b71aae8..10dd094 100644
--- a/clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/HttpTransportImplTest.java
+++ b/clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/HttpTransportImplTest.java
@@ -29,6 +29,7 @@
 import org.apache.http.client.HttpClient;
 import org.apache.http.entity.ContentType;
 import org.apache.http.entity.StringEntity;
+import org.apache.servicecomb.http.client.common.HttpConfiguration.AKSKProperties;
 import org.junit.Assert;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -38,6 +39,8 @@
   @Test
   public void TestHttpTransport() throws IOException {
     HttpClient httpClient = mock(HttpClient.class);
+    AKSKProperties akskProperties = new AKSKProperties();
+    akskProperties.setEnabled(false);
 
     org.apache.http.HttpResponse httpResponse = mock(org.apache.http.HttpResponse.class);
     StatusLine statusLine = mock(StatusLine.class);
@@ -50,7 +53,7 @@
 
     when(httpClient.execute(Mockito.any())).thenReturn(httpResponse);
 
-    HttpTransportImpl httpTransport = new HttpTransportImpl(httpClient);
+    HttpTransportImpl httpTransport = new HttpTransportImpl(httpClient, akskProperties);
     Map<String, String> extraHeaders = new HashMap<>();
     extraHeaders.put("test", "testContext");
     httpTransport.addHeaders(extraHeaders);
diff --git a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterClient.java b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterClient.java
index 5fe6a4f..fdbd64a 100755
--- a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterClient.java
+++ b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterClient.java
@@ -26,6 +26,7 @@
 

 import org.apache.http.HttpStatus;

 import org.apache.http.client.utils.URIBuilder;

+import org.apache.servicecomb.http.client.common.HttpConfiguration.AKSKProperties;

 import org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties;

 import org.apache.servicecomb.http.client.common.HttpResponse;

 import org.apache.servicecomb.http.client.common.HttpTransport;

@@ -63,9 +64,11 @@
     this.httpClient = httpClient;

   }

 

-  public ServiceCenterClient(AddressManager addressManager, SSLProperties sslProperties, String tenantName,

+  public ServiceCenterClient(AddressManager addressManager, SSLProperties sslProperties,

+      AKSKProperties akskProperties,

+      String tenantName,

       Map<String, String> extraGlobalHeaders) {

-    HttpTransport httpTransport = HttpTransportFactory.createHttpTransport(sslProperties);

+    HttpTransport httpTransport = HttpTransportFactory.createHttpTransport(sslProperties, akskProperties);

     httpTransport.addHeaders(extraGlobalHeaders);

 

     this.httpClient = new ServiceCenterRawClient.Builder()

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
index ae420e2..794b976 100644
--- 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
@@ -29,56 +29,4 @@
       this.address = address;
     }
   }
-
-  class AKSKProperties {
-    private boolean enabled;
-
-    private String accessKey;
-
-    private String secretKey;
-
-    private String cipher;
-
-    private String project;
-
-    public boolean isEnabled() {
-      return enabled;
-    }
-
-    public void setEnabled(boolean enabled) {
-      this.enabled = enabled;
-    }
-
-    public String getAccessKey() {
-      return accessKey;
-    }
-
-    public void setAccessKey(String accessKey) {
-      this.accessKey = accessKey;
-    }
-
-    public String getSecretKey() {
-      return secretKey;
-    }
-
-    public void setSecretKey(String secretKey) {
-      this.secretKey = secretKey;
-    }
-
-    public String getCipher() {
-      return cipher;
-    }
-
-    public void setCipher(String cipher) {
-      this.cipher = cipher;
-    }
-
-    public String getProject() {
-      return project;
-    }
-
-    public void setProject(String project) {
-      this.project = project;
-    }
-  }
 }
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 60c45d1..c6be065 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
@@ -146,7 +146,7 @@
       StringBuilder sb = new StringBuilder();
       for (MicroserviceInstance instance : instances) {
         for (String endpoint : instance.getEndpoints()) {
-          sb.append(endpoint.length() > 20 ? endpoint.substring(0, 20) : endpoint);
+          sb.append(endpoint.length() > 64 ? endpoint.substring(0, 64) : endpoint);
           sb.append("|");
         }
       }
diff --git a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/Microservice.java b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/Microservice.java
index 9d69bfd..54a183c 100755
--- a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/Microservice.java
+++ b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/Microservice.java
@@ -22,6 +22,9 @@
 import java.util.List;

 import java.util.Map;

 

+import com.fasterxml.jackson.annotation.JsonRootName;

+

+@JsonRootName("service")

 public class Microservice {

 

   private String serviceId;

diff --git a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/MicroserviceInstance.java b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/MicroserviceInstance.java
index f2f7ab0..3fd4c29 100755
--- a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/MicroserviceInstance.java
+++ b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/MicroserviceInstance.java
@@ -22,6 +22,9 @@
 import java.util.List;

 import java.util.Map;

 

+import com.fasterxml.jackson.annotation.JsonRootName;

+

+@JsonRootName("instance")

 public class MicroserviceInstance {

   // even disconnected from service center

   // instanceId will not be changed

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 cbcb675..f8f24a1 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
@@ -26,6 +26,7 @@
 import org.apache.servicecomb.demo.CategorizedTestCase;
 import org.apache.servicecomb.demo.TestMgr;
 import org.apache.servicecomb.foundation.common.event.SimpleEventBus;
+import org.apache.servicecomb.http.client.common.HttpConfiguration.AKSKProperties;
 import org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties;
 import org.apache.servicecomb.service.center.client.AddressManager;
 import org.apache.servicecomb.service.center.client.DiscoveryEvents.InstanceChangedEvent;
@@ -65,7 +66,10 @@
     AddressManager addressManager = new AddressManager("default", Arrays.asList("http://127.0.0.1:30100"));
     SSLProperties sslProperties = new SSLProperties();
     sslProperties.setEnabled(false);
-    ServiceCenterClient serviceCenterClient = new ServiceCenterClient(addressManager, sslProperties, "default", null);
+    AKSKProperties akskProperties = new AKSKProperties();
+    akskProperties.setEnabled(false);
+    ServiceCenterClient serviceCenterClient = new ServiceCenterClient(addressManager, sslProperties, akskProperties,
+        "default", null);
     EventBus eventBus = new SimpleEventBus();
     ServiceCenterRegistration serviceCenterRegistration = new ServiceCenterRegistration(serviceCenterClient, eventBus);
     Microservice microservice = new Microservice();