[SCB-2673]Fix NPE problem when auto discovery enabled (#3299)

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/ConfigCenterAddressManager.java
similarity index 89%
rename from clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/AddressManager.java
rename to clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterAddressManager.java
index fc72e36..3b34615 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/ConfigCenterAddressManager.java
@@ -26,9 +26,9 @@
 import com.google.common.eventbus.EventBus;
 import com.google.common.eventbus.Subscribe;
 
-public class AddressManager extends AbstractAddressManager {
+public class ConfigCenterAddressManager extends AbstractAddressManager {
 
-  public AddressManager(String projectName, List<String> addresses, EventBus eventBus) {
+  public ConfigCenterAddressManager(String projectName, List<String> addresses, EventBus eventBus) {
     super(projectName, addresses);
     eventBus.register(this);
   }
diff --git a/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterClient.java b/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterClient.java
index c2dbaeb..a8ee3b9 100644
--- a/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterClient.java
+++ b/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterClient.java
@@ -50,9 +50,9 @@
 
   private final HttpTransport httpTransport;
 
-  private final AddressManager addressManager;
+  private final ConfigCenterAddressManager addressManager;
 
-  public ConfigCenterClient(AddressManager addressManager, HttpTransport httpTransport) {
+  public ConfigCenterClient(ConfigCenterAddressManager addressManager, HttpTransport httpTransport) {
     this.addressManager = addressManager;
     this.httpTransport = httpTransport;
   }
diff --git a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/AbstractAddressManager.java b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/AbstractAddressManager.java
index 71d93a1..ac21483 100644
--- a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/AbstractAddressManager.java
+++ b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/AbstractAddressManager.java
@@ -62,11 +62,20 @@
 
   private String projectName;
 
-  private final Map<String, Boolean> categoryMap = new HashMap<>();
+  // if address in same zone will be true; others will be false.
+  private final Map<String, Boolean> addressCategory = new HashMap<>();
 
-  private final Map<String, Integer> recodeStatus = new ConcurrentHashMap<>();
+  // recording continuous times of failure of an address.
+  private final Map<String, Integer> addressFailureStatus = new ConcurrentHashMap<>();
 
-  private final Map<String, Boolean> history = new ConcurrentHashMap<>();
+  // recording address isolation status, if isolated will be false
+  private final Map<String, Boolean> addressIsolated = new ConcurrentHashMap<>();
+
+  // recording address isolation status, if isolated will be false
+  private final Cache<String, Boolean> addressIsolationStatus = CacheBuilder.newBuilder()
+      .maximumSize(100)
+      .expireAfterWrite(1, TimeUnit.MINUTES)
+      .build();
 
   private volatile List<String> availableZone = new ArrayList<>();
 
@@ -74,7 +83,7 @@
 
   private final List<String> defaultAddress = new ArrayList<>();
 
-  private boolean isAddressRefresh = false;
+  private boolean addressAutoRefreshed = false;
 
   private final Object lock = new Object();
 
@@ -83,12 +92,8 @@
           .setNameFormat("check-available-address-%d")
           .build());
 
-  private final Cache<String, Boolean> cacheAddress = CacheBuilder.newBuilder()
-      .maximumSize(100)
-      .expireAfterWrite(10, TimeUnit.MINUTES)
-      .build();
-
   public AbstractAddressManager(List<String> addresses) {
+    this.projectName = DEFAULT_PROJECT;
     this.addresses.addAll(addresses);
     this.defaultAddress.addAll(addresses);
   }
@@ -99,26 +104,18 @@
     this.defaultAddress.addAll(this.addresses);
   }
 
-  @VisibleForTesting
   public List<String> getAddresses() {
     return addresses;
   }
 
-  @VisibleForTesting
   public List<String> getAvailableZone() {
     return availableZone;
   }
 
-  @VisibleForTesting
   public List<String> getAvailableRegion() {
     return availableRegion;
   }
 
-  @VisibleForTesting
-  protected void setAddressRefresh(boolean addressRefresh) {
-    isAddressRefresh = addressRefresh;
-  }
-
   private void startCheck() {
     executorService.scheduleAtFixedRate(this::checkHistory,
         0,
@@ -130,9 +127,8 @@
     return absoluteUrl ? address + url : formatAddress(address) + url;
   }
 
-  // if isAddressRefresh is false, polling with available initial addresses.
   public String address() {
-    if (!isAddressRefresh) {
+    if (!addressAutoRefreshed) {
       return getDefaultAddress();
     } else {
       return getAvailableZoneAddress();
@@ -204,7 +200,7 @@
   }
 
   private List<String> getAvailableAddress(List<String> endpoints) {
-    return endpoints.stream().filter(uri -> !history.containsKey(uri))
+    return endpoints.stream().filter(uri -> !addressIsolated.containsKey(uri) || addressIsolated.get(uri))
         .collect(Collectors.toList());
   }
 
@@ -213,26 +209,27 @@
   }
 
   public void refreshEndpoint(RefreshEndpointEvent event, String key) {
-    this.setAddressRefresh(true);
     if (null == event || !event.getName().equals(key)) {
       return;
     }
+
     availableZone = event.getSameZone().stream().map(this::normalizeUri).collect(Collectors.toList());
     availableRegion = event.getSameRegion().stream().map(this::normalizeUri).collect(Collectors.toList());
-    availableZone.forEach(address -> categoryMap.put(address, true));
-    availableRegion.forEach(address -> categoryMap.put(address, false));
+    availableZone.forEach(address -> addressCategory.put(address, true));
+    availableRegion.forEach(address -> addressCategory.put(address, false));
     startCheck();
+    addressAutoRefreshed = true;
   }
 
   public void recordFailState(String address) {
     synchronized (lock) {
-      if (!recodeStatus.containsKey(address)) {
-        recodeStatus.put(address, 1);
+      if (!addressFailureStatus.containsKey(address)) {
+        addressFailureStatus.put(address, 1);
         return;
       }
-      int number = recodeStatus.get(address) + 1;
+      int number = addressFailureStatus.get(address) + 1;
       if (number < ISOLATION_THRESHOLD) {
-        recodeStatus.put(address, number);
+        addressFailureStatus.put(address, number);
       } else {
         removeAddress(address);
       }
@@ -240,23 +237,23 @@
   }
 
   public void recordSuccessState(String address) {
-    recodeStatus.put(address, 0);
+    addressFailureStatus.put(address, 0);
   }
 
   @VisibleForTesting
   protected void checkHistory() {
-    history.keySet().stream().filter(this::judgeIsolation).forEach(s -> {
+    addressIsolated.keySet().stream().filter(this::judgeIsolation).forEach(s -> {
       if (telnetTest(s)) {
         rejoinAddress(s);
       } else {
-        cacheAddress.put(s, false);
+        addressIsolationStatus.put(s, false);
       }
     });
   }
 
   private Boolean judgeIsolation(String address) {
     try {
-      return cacheAddress.get(address, () -> true);
+      return addressIsolationStatus.get(address, () -> true);
     } catch (ExecutionException e) {
       return true;
     }
@@ -285,35 +282,50 @@
   // add it to the sequence of, and delete the record in history
   @VisibleForTesting
   void rejoinAddress(String address) {
-    if (!isAddressRefresh) {
+    if (!addressAutoRefreshed) {
       defaultAddress.add(address);
-    } else {
-      if (categoryMap.get(address)) {
-        availableZone.add(address);
-      } else {
-        availableRegion.add(address);
-      }
+      addressFailureStatus.put(address, 0);
+      addressIsolated.remove(address);
+      return;
     }
-    recodeStatus.put(address, 0);
-    history.remove(address);
+
+    if (addressCategory.get(address) == null) {
+      LOGGER.warn("may not happen {}-{}", addressCategory.size(), address);
+      return;
+    }
+
+    if (addressCategory.get(address)) {
+      availableZone.add(address);
+    } else {
+      availableRegion.add(address);
+    }
+    addressFailureStatus.put(address, 0);
+    addressIsolated.remove(address);
   }
 
   //Query whether the current address belongs to the same AZ or the same region through AZMap,
   // and delete it from the record. At the same time, add records in history and cache
   @VisibleForTesting
   void removeAddress(String address) {
-    if (!isAddressRefresh) {
+    if (!addressAutoRefreshed) {
       defaultAddress.remove(address);
-      history.put(address, false);
-    } else {
-      if (categoryMap.get(address)) {
-        availableZone.remove(address);
-      } else {
-        availableRegion.remove(address);
-      }
-      history.put(address, categoryMap.get(address));
+      addressIsolated.put(address, false);
+      addressIsolationStatus.put(address, false);
+      return;
     }
-    recodeStatus.put(address, 0);
-    cacheAddress.put(address, false);
+
+    if (addressCategory.get(address) == null) {
+      LOGGER.warn("may not happen {}-{}", addressCategory.size(), address);
+      return;
+    }
+
+    if (addressCategory.get(address)) {
+      availableZone.remove(address);
+    } else {
+      availableRegion.remove(address);
+    }
+
+    addressIsolated.put(address, false);
+    addressIsolationStatus.put(address, false);
   }
 }
diff --git a/clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/AbstractAddressManagerTest.java b/clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/AbstractAddressManagerTest.java
index 9c6a647..25deb1e 100644
--- a/clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/AbstractAddressManagerTest.java
+++ b/clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/AbstractAddressManagerTest.java
@@ -101,7 +101,7 @@
     Assertions.assertEquals("http://127.0.0.3:30100", addressManager.address());
 
     // test recodeStatus times
-    Map<String, Integer> recodeStatus = Deencapsulation.getField(addressManager, "recodeStatus");
+    Map<String, Integer> recodeStatus = Deencapsulation.getField(addressManager, "addressFailureStatus");
     Assertions.assertEquals(0, (int) recodeStatus.get("http://127.0.0.3:30100"));
 
     // test fail 3 times ,it will be isolated
@@ -120,12 +120,12 @@
     // mock the address telnetTest is access
     new Expectations(addressManager) {
       {
-        Deencapsulation.setField(addressManager, "cacheAddress", cache);
+        Deencapsulation.setField(addressManager, "addressIsolationStatus", cache);
         addressManager.telnetTest("http://127.0.0.3:30100");
         result = true;
       }
     };
-    Cache<String, Boolean> result = Deencapsulation.getField(addressManager, "cacheAddress");
+    Cache<String, Boolean> result = Deencapsulation.getField(addressManager, "addressIsolationStatus");
     Assertions.assertEquals(true, result.get("http://127.0.0.3:30100", () -> false));
 
     // test restore isolation
@@ -151,7 +151,7 @@
     }
     latch.await(30, TimeUnit.SECONDS);
 
-    Map<String, Integer> recodeStatus = Deencapsulation.getField(addressManager, "recodeStatus");
+    Map<String, Integer> recodeStatus = Deencapsulation.getField(addressManager, "addressFailureStatus");
     Assertions.assertEquals(2, (int) recodeStatus.get("http://127.0.0.3:30100"));
   }
 
diff --git a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/AddressManager.java b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManager.java
similarity index 89%
rename from clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/AddressManager.java
rename to clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManager.java
index 1185fde..a5fd128 100644
--- a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/AddressManager.java
+++ b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManager.java
@@ -25,8 +25,8 @@
 import com.google.common.eventbus.EventBus;
 import com.google.common.eventbus.Subscribe;
 
-public class AddressManager extends AbstractAddressManager {
-  public AddressManager(String projectName, List<String> addresses, EventBus eventBus) {
+public class ServiceCenterAddressManager extends AbstractAddressManager {
+  public ServiceCenterAddressManager(String projectName, List<String> addresses, EventBus eventBus) {
     super(projectName, addresses);
     eventBus.register(this);
   }
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 849d518..09f30dc 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
@@ -78,7 +78,7 @@
     return this;

   }

 

-  public ServiceCenterClient(AddressManager addressManager,

+  public ServiceCenterClient(ServiceCenterAddressManager addressManager,

       SSLProperties sslProperties,

       RequestAuthHeaderProvider requestAuthHeaderProvider,

       String tenantName,

diff --git a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClient.java b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClient.java
index ab967f0..6c29300 100755
--- a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClient.java
+++ b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClient.java
@@ -36,10 +36,10 @@
 

   private final HttpTransport httpTransport;

 

-  private final AddressManager addressManager;

+  private final ServiceCenterAddressManager addressManager;

 

   private ServiceCenterRawClient(String tenantName, HttpTransport httpTransport,

-      AddressManager addressManager) {

+      ServiceCenterAddressManager addressManager) {

     this.httpTransport = httpTransport;

     this.tenantName = tenantName;

     this.addressManager = addressManager;

@@ -102,7 +102,7 @@
 

     private HttpTransport httpTransport;

 

-    private AddressManager addressManager;

+    private ServiceCenterAddressManager addressManager;

 

     public Builder() {

     }

@@ -117,7 +117,7 @@
       return this;

     }

 

-    public Builder setAddressManager(AddressManager addressManager) {

+    public Builder setAddressManager(ServiceCenterAddressManager addressManager) {

       this.addressManager = addressManager;

       return this;

     }

diff --git a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterWatch.java b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterWatch.java
index 597f516..a8be8b9 100644
--- a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterWatch.java
+++ b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterWatch.java
@@ -51,7 +51,7 @@
 
   private static final long SLEEP_MAX = 10 * 60 * 10000;
 
-  private final AddressManager addressManager;
+  private final ServiceCenterAddressManager addressManager;
 
   private final SSLProperties sslProperties;
 
@@ -78,7 +78,7 @@
   private final ExecutorService connector = Executors.newFixedThreadPool(1, (r) -> new
       Thread(r, "web-socket-connector"));
 
-  public ServiceCenterWatch(AddressManager addressManager,
+  public ServiceCenterWatch(ServiceCenterAddressManager addressManager,
       SSLProperties sslProperties,
       RequestAuthHeaderProvider requestAuthHeaderProvider,
       String tenantName,
diff --git a/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/AddressManagerTest.java b/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManagerTest.java
similarity index 87%
rename from clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/AddressManagerTest.java
rename to clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManagerTest.java
index 6e18d76..b00612c 100644
--- a/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/AddressManagerTest.java
+++ b/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManagerTest.java
@@ -30,19 +30,19 @@
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
-class AddressManagerTest {
+class ServiceCenterAddressManagerTest {
 
   private static final List<String> addresses = new ArrayList<>();
 
-  private static AddressManager addressManager1;
+  private static ServiceCenterAddressManager addressManager1;
 
-  private static AddressManager addressManager2;
+  private static ServiceCenterAddressManager addressManager2;
 
 
   @Test
   public void getUrlPrefix() {
     addresses.add("http://127.0.0.1:30103");
-    addressManager1 = new AddressManager("project", addresses, new EventBus());
+    addressManager1 = new ServiceCenterAddressManager("project", addresses, new EventBus());
 
     Assertions.assertNotNull(addressManager1);
 
@@ -56,7 +56,7 @@
   @Test
   public void formatUrlTest() {
     addresses.add("http://127.0.0.1:30103");
-    addressManager1 = new AddressManager("project", addresses, new EventBus());
+    addressManager1 = new ServiceCenterAddressManager("project", addresses, new EventBus());
     Assertions.assertNotNull(addressManager1);
 
     String address = addressManager1.address();
@@ -77,7 +77,7 @@
     Map<String, List<String>> zoneAndRegion = new HashMap<>();
     zoneAndRegion.put("sameZone", addressAZ);
     zoneAndRegion.put("sameRegion", addressRG);
-    addressManager1 = new AddressManager("project", addresses, new EventBus());
+    addressManager1 = new ServiceCenterAddressManager("project", addresses, new EventBus());
     RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion, "SERVICECENTER");
     addressManager1.refreshEndpoint(event, "SERVICECENTER");
 
diff --git a/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClientTest.java b/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClientTest.java
index 9cbb090..29337e3 100755
--- a/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClientTest.java
+++ b/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClientTest.java
@@ -41,7 +41,7 @@
   public void TestDefaultParameter() throws IOException {

 

     HttpTransport httpTransport = Mockito.mock(HttpTransport.class);

-    AddressManager addressManager = new AddressManager(PROJECT_NAME, Arrays.asList("http://127.0.0.1:30100"), new EventBus());

+    ServiceCenterAddressManager addressManager = new ServiceCenterAddressManager(PROJECT_NAME, Arrays.asList("http://127.0.0.1:30100"), new EventBus());

     ServiceCenterRawClient client = new ServiceCenterRawClient.Builder()

         .setHttpTransport(httpTransport)

         .setAddressManager(addressManager)

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 9fff0cf..85f0410 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
@@ -28,7 +28,7 @@
 import org.apache.servicecomb.foundation.common.event.SimpleEventBus;
 import org.apache.servicecomb.http.client.auth.DefaultRequestAuthHeaderProvider;
 import org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties;
-import org.apache.servicecomb.service.center.client.AddressManager;
+import org.apache.servicecomb.service.center.client.ServiceCenterAddressManager;
 import org.apache.servicecomb.service.center.client.RegistrationEvents;
 import org.apache.servicecomb.service.center.client.RegistrationEvents.HeartBeatEvent;
 import org.apache.servicecomb.service.center.client.RegistrationEvents.MicroserviceInstanceRegistrationEvent;
@@ -60,7 +60,7 @@
 
   @Override
   public void testRestTransport() throws Exception {
-    AddressManager addressManager = new AddressManager("default", Arrays.asList("http://127.0.0.1:30100"),
+    ServiceCenterAddressManager addressManager = new ServiceCenterAddressManager("default", Arrays.asList("http://127.0.0.1:30100"),
         new EventBus());
     SSLProperties sslProperties = new SSLProperties();
     sslProperties.setEnabled(false);
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestControllerImpl.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestControllerImpl.java
new file mode 100644
index 0000000..37fd873
--- /dev/null
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestControllerImpl.java
@@ -0,0 +1,52 @@
+/*
+ * 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.demo.springmvc.client;
+
+import org.apache.servicecomb.demo.CategorizedTestCase;
+import org.apache.servicecomb.demo.TestMgr;
+import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+import com.netflix.config.DynamicPropertyFactory;
+
+@Component
+public class TestControllerImpl implements CategorizedTestCase {
+  RestTemplate restTemplate = RestTemplateBuilder.create();
+
+  private static final String SERVER = "servicecomb://springmvc";
+
+  public void testRestTransport() throws Exception {
+    testQueryParamSpecial();
+  }
+
+  private void testQueryParamSpecial() {
+    // vert.x and servlet container have different query parameter implementations
+    if (DynamicPropertyFactory.getInstance()
+        .getBooleanProperty("servicecomb.test.vert.transport", true).get()) {
+
+      TestMgr.check(restTemplate.getForObject(
+          SERVER + "/springmvc/controller/sayHello1?name=you;me", String.class), "Hello you,v");
+    } else {
+      TestMgr.check(restTemplate.getForObject(
+          SERVER + "/springmvc/controller/sayHello1?name=you;me", String.class), "Hello you;me,v");
+    }
+    TestMgr.check(restTemplate.getForObject(
+        SERVER + "/springmvc/controller/sayHello1?name={1}",
+        String.class, "you;me"), "Hello you;me,v");
+  }
+}
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/application.yml b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/application.yml
index e139ef0..5144af7 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/application.yml
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/application.yml
@@ -27,5 +27,6 @@
       Consumer:
         default: loadbalance
   loadbalance:
-    isolation:
-      enabled: false
\ No newline at end of file
+    filter:
+      isolation:
+        enabled: false
diff --git a/dependencies/default/pom.xml b/dependencies/default/pom.xml
index c4911ec..eeabea2 100644
--- a/dependencies/default/pom.xml
+++ b/dependencies/default/pom.xml
@@ -516,7 +516,6 @@
         <groupId>io.zipkin.zipkin2</groupId>
         <artifactId>zipkin-junit</artifactId>
         <version>${zipkin.version}</version>
-        <scope>test</scope>
       </dependency>
 
       <dependency>
diff --git a/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/ConfigCenterConfigurationSourceImpl.java b/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/ConfigCenterConfigurationSourceImpl.java
index 1af9136..74834aa 100644
--- a/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/ConfigCenterConfigurationSourceImpl.java
+++ b/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/ConfigCenterConfigurationSourceImpl.java
@@ -31,7 +31,7 @@
 import org.apache.http.client.config.RequestConfig;
 import org.apache.http.impl.client.BasicCredentialsProvider;
 import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.servicecomb.config.center.client.AddressManager;
+import org.apache.servicecomb.config.center.client.ConfigCenterAddressManager;
 import org.apache.servicecomb.config.center.client.ConfigCenterClient;
 import org.apache.servicecomb.config.center.client.model.ConfigCenterConfiguration;
 import org.apache.servicecomb.config.center.client.ConfigCenterManager;
@@ -88,7 +88,7 @@
   public void init(Configuration localConfiguration) {
     configConverter = new ConfigConverter(ConfigCenterConfig.INSTANCE.getFileSources());
 
-    AddressManager kieAddressManager = configKieAddressManager();
+    ConfigCenterAddressManager kieAddressManager = configKieAddressManager();
 
     HttpTransport httpTransport = createHttpTransport(kieAddressManager,
         HttpTransportFactory.defaultRequestConfig().build(),
@@ -146,7 +146,7 @@
     return new ConfigCenterConfiguration().setRefreshIntervalInMillis(ConfigCenterConfig.INSTANCE.getRefreshInterval());
   }
 
-  private HttpTransport createHttpTransport(AddressManager kieAddressManager, RequestConfig requestConfig,
+  private HttpTransport createHttpTransport(ConfigCenterAddressManager kieAddressManager, RequestConfig requestConfig,
       Configuration localConfiguration) {
     List<AuthHeaderProvider> authHeaderProviders = SPIServiceUtils.getOrLoadSortedService(AuthHeaderProvider.class);
 
@@ -184,8 +184,8 @@
     };
   }
 
-  private AddressManager configKieAddressManager() {
-    return new AddressManager(ConfigCenterConfig.INSTANCE.getDomainName(),
+  private ConfigCenterAddressManager configKieAddressManager() {
+    return new ConfigCenterAddressManager(ConfigCenterConfig.INSTANCE.getDomainName(),
         Deployment
             .getSystemBootStrapInfo(ConfigCenterDefaultDeploymentProvider.SYSTEM_KEY_CONFIG_CENTER).getAccessURL(),
         EventManager.getEventBus());
diff --git a/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/ConfigCenterConfigurationSourceImplTest.java b/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/ConfigCenterConfigurationSourceImplTest.java
index a1466a5..76f0cb4 100644
--- a/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/ConfigCenterConfigurationSourceImplTest.java
+++ b/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/ConfigCenterConfigurationSourceImplTest.java
@@ -23,7 +23,7 @@
 import java.util.List;
 import java.util.Map;
 
-import org.apache.servicecomb.config.center.client.AddressManager;
+import org.apache.servicecomb.config.center.client.ConfigCenterAddressManager;
 import org.apache.servicecomb.foundation.common.event.EventManager;
 import org.apache.servicecomb.http.client.event.RefreshEndpointEvent;
 import org.junit.jupiter.api.Assertions;
@@ -36,7 +36,7 @@
     List<String> addresses = new ArrayList<>();
     addresses.add("http://127.0.0.1:30103");
     addresses.add("http://127.0.0.2:30103");
-    AddressManager addressManager = new AddressManager("test", addresses, EventManager.getEventBus());
+    ConfigCenterAddressManager addressManager = new ConfigCenterAddressManager("test", addresses, EventManager.getEventBus());
     Assertions.assertNotNull(addressManager);
 
     String address = addressManager.address();
@@ -44,7 +44,7 @@
     address = addressManager.address();
     Assertions.assertEquals("http://127.0.0.1:30103/v3/test", address);
 
-    addressManager = new AddressManager(null, addresses, EventManager.getEventBus());
+    addressManager = new ConfigCenterAddressManager(null, addresses, EventManager.getEventBus());
     address = addressManager.address();
     Assertions.assertEquals("http://127.0.0.2:30103/v3/default", address);
   }
@@ -59,7 +59,7 @@
     zoneAndRegion.put("sameZone", addressAZ);
     zoneAndRegion.put("sameRegion", new ArrayList<>());
     RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion, "CseConfigCenter");
-    AddressManager addressManager = new AddressManager("test", addresses, EventManager.getEventBus());
+    ConfigCenterAddressManager addressManager = new ConfigCenterAddressManager("test", addresses, EventManager.getEventBus());
     addressManager.onRefreshEndpointEvent(event);
 
     List<String> availableAZ = addressManager.getAvailableZone();
diff --git a/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/center/client/AddressManagerTest.java b/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/center/client/ConfigCenterAddressManagerTest.java
similarity index 86%
rename from dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/center/client/AddressManagerTest.java
rename to dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/center/client/ConfigCenterAddressManagerTest.java
index 1e72e85..86b3e30 100644
--- a/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/center/client/AddressManagerTest.java
+++ b/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/center/client/ConfigCenterAddressManagerTest.java
@@ -28,19 +28,19 @@
 
 import com.google.common.eventbus.EventBus;
 
-class AddressManagerTest {
+class ConfigCenterAddressManagerTest {
   private static final List<String> addresses = new ArrayList<>();
 
-  private static AddressManager addressManager1;
+  private static ConfigCenterAddressManager addressManager1;
 
-  private static AddressManager addressManager2;
+  private static ConfigCenterAddressManager addressManager2;
 
   @Test
   public void addressManagerTest() {
     addresses.add("http://127.0.0.1:30103");
     addresses.add("https://127.0.0.2:30103");
-    addressManager1 = new AddressManager("project", addresses, new EventBus());
-    addressManager2 = new AddressManager(null, addresses, new EventBus());
+    addressManager1 = new ConfigCenterAddressManager("project", addresses, new EventBus());
+    addressManager2 = new ConfigCenterAddressManager(null, addresses, new EventBus());
 
     Assertions.assertNotNull(addressManager1);
     Assertions.assertNotNull(addressManager2);
@@ -63,7 +63,7 @@
     Map<String, List<String>> zoneAndRegion = new HashMap<>();
     zoneAndRegion.put("sameZone", addressAZ);
     zoneAndRegion.put("sameRegion", addressRG);
-    addressManager1 = new AddressManager("project", addresses, new EventBus());
+    addressManager1 = new ConfigCenterAddressManager("project", addresses, new EventBus());
     RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion, "CseConfigCenter");
     addressManager1.refreshEndpoint(event, "CseConfigCenter");
 
diff --git a/handlers/handler-tracing-zipkin/pom.xml b/handlers/handler-tracing-zipkin/pom.xml
index 380448e..d700cee 100644
--- a/handlers/handler-tracing-zipkin/pom.xml
+++ b/handlers/handler-tracing-zipkin/pom.xml
@@ -63,5 +63,10 @@
       <artifactId>zipkin</artifactId>
       <scope>compile</scope>
     </dependency>
+    <dependency>
+      <groupId>io.zipkin.zipkin2</groupId>
+      <artifactId>zipkin-junit</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 </project>
diff --git a/integration-tests/test-common/pom.xml b/integration-tests/test-common/pom.xml
index 70a7669..bb3b8f7 100644
--- a/integration-tests/test-common/pom.xml
+++ b/integration-tests/test-common/pom.xml
@@ -38,6 +38,7 @@
     <dependency>
       <groupId>io.zipkin.zipkin2</groupId>
       <artifactId>zipkin-junit</artifactId>
+      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>com.squareup.okhttp3</groupId>
diff --git a/integration-tests/tracing-tests/pom.xml b/integration-tests/tracing-tests/pom.xml
index ef99df5..815ea02 100644
--- a/integration-tests/tracing-tests/pom.xml
+++ b/integration-tests/tracing-tests/pom.xml
@@ -74,6 +74,7 @@
     <dependency>
       <groupId>io.zipkin.zipkin2</groupId>
       <artifactId>zipkin-junit</artifactId>
+      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>com.squareup.okhttp3</groupId>
diff --git a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/RBACBootStrapService.java b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/RBACBootStrapService.java
index 80250ed..d5a0710 100644
--- a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/RBACBootStrapService.java
+++ b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/RBACBootStrapService.java
@@ -33,7 +33,7 @@
 import org.apache.servicecomb.foundation.ssl.SSLOption;
 import org.apache.servicecomb.http.client.auth.DefaultRequestAuthHeaderProvider;
 import org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties;
-import org.apache.servicecomb.service.center.client.AddressManager;
+import org.apache.servicecomb.service.center.client.ServiceCenterAddressManager;
 import org.apache.servicecomb.service.center.client.ServiceCenterClient;
 import org.apache.servicecomb.serviceregistry.config.ServiceRegistryConfig;
 import org.springframework.core.env.Environment;
@@ -59,7 +59,7 @@
       return;
     }
 
-    AddressManager addressManager = createAddressManager(environment);
+    ServiceCenterAddressManager addressManager = createAddressManager(environment);
     SSLProperties sslProperties = createSSLProperties(environment, "sc.consumer");
     sslProperties.setEnabled(addressManager.sslEnabled());
 
@@ -90,8 +90,8 @@
         .orElseThrow(() -> new IllegalArgumentException("failed to find cipher named " + cipherName));
   }
 
-  private AddressManager createAddressManager(Environment environment) {
-    return new AddressManager(getTenantName(environment),
+  private ServiceCenterAddressManager createAddressManager(Environment environment) {
+    return new ServiceCenterAddressManager(getTenantName(environment),
         getRBACAddressList(environment), EventManager.getEventBus());
   }
 
diff --git a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/IpPortManager.java b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/IpPortManager.java
index d3dda9d..f1dce18 100644
--- a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/IpPortManager.java
+++ b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/IpPortManager.java
@@ -28,7 +28,7 @@
 import org.apache.servicecomb.registry.consumer.AppManager;
 import org.apache.servicecomb.serviceregistry.api.Type;
 import org.apache.servicecomb.serviceregistry.config.ServiceRegistryConfig;
-import org.apache.servicecomb.serviceregistry.refresh.AddressManager;
+import org.apache.servicecomb.serviceregistry.refresh.ServiceRegistryAddressManager;
 import org.apache.servicecomb.serviceregistry.refresh.ClassificationAddress;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -44,7 +44,7 @@
 
   private boolean autoDiscoveryInited = false;
 
-  private final AddressManager addressManger;
+  private final ServiceRegistryAddressManager addressManger;
 
   ClassificationAddress classificationAddress;
 
@@ -66,7 +66,7 @@
       throw new IllegalArgumentException("Service center address is required to start the application.");
     }
     List<String> addresses = defaultIpPort.stream().map(IpPort::toString).collect(Collectors.toList());
-    addressManger = new AddressManager(addresses, EventManager.getEventBus());
+    addressManger = new ServiceRegistryAddressManager(addresses, EventManager.getEventBus());
     classificationAddress = new ClassificationAddress(serviceRegistryConfig, instanceCacheManager);
     LOGGER.info("Initial service center address is {}", getAvailableAddress());
   }
diff --git a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/refresh/AddressManager.java b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/refresh/ServiceRegistryAddressManager.java
similarity index 90%
rename from service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/refresh/AddressManager.java
rename to service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/refresh/ServiceRegistryAddressManager.java
index b09b928..3ced076 100644
--- a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/refresh/AddressManager.java
+++ b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/refresh/ServiceRegistryAddressManager.java
@@ -33,12 +33,12 @@
 import com.google.common.eventbus.EventBus;
 import com.google.common.eventbus.Subscribe;
 
-public class AddressManager extends AbstractAddressManager {
-  private static final Logger LOGGER = LoggerFactory.getLogger(AddressManager.class);
+public class ServiceRegistryAddressManager extends AbstractAddressManager {
+  private static final Logger LOGGER = LoggerFactory.getLogger(ServiceRegistryAddressManager.class);
 
   private static final String URI_PREFIX = "rest://";
 
-  public AddressManager(List<String> addresses, EventBus eventBus) {
+  public ServiceRegistryAddressManager(List<String> addresses, EventBus eventBus) {
     super(addresses);
     eventBus.register(this);
   }
diff --git a/service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/refresh/AddressManagerTest.java b/service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/refresh/ServiceRegistryAddressManagerTest.java
similarity index 88%
rename from service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/refresh/AddressManagerTest.java
rename to service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/refresh/ServiceRegistryAddressManagerTest.java
index de34af9..d6a181b 100644
--- a/service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/refresh/AddressManagerTest.java
+++ b/service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/refresh/ServiceRegistryAddressManagerTest.java
@@ -32,20 +32,20 @@
 import mockit.Deencapsulation;
 import org.junit.jupiter.api.Test;
 
-class AddressManagerTest {
+class ServiceRegistryAddressManagerTest {
 
   private static final List<String> addresses = new ArrayList<>();
 
-  private static AddressManager addressManager1;
+  private static ServiceRegistryAddressManager addressManager1;
 
-  private static AddressManager addressManager2;
+  private static ServiceRegistryAddressManager addressManager2;
 
   @Test
   public void addressManagerTest() {
     IpPort ipPort = new IpPort("127.0.0.1", 30103);
     addresses.add(ipPort.toString());
-    addressManager1 = new AddressManager(addresses, new EventBus());
-    addressManager2 = new AddressManager(addresses, new EventBus());
+    addressManager1 = new ServiceRegistryAddressManager(addresses, new EventBus());
+    addressManager2 = new ServiceRegistryAddressManager(addresses, new EventBus());
 
     Assertions.assertNotNull(addressManager1);
     Assertions.assertNotNull(addressManager2);
@@ -70,7 +70,7 @@
     Map<String, List<String>> zoneAndRegion = new HashMap<>();
     zoneAndRegion.put("sameZone", addressAZ);
     zoneAndRegion.put("sameRegion", addressRG);
-    addressManager1 = new AddressManager(addresses, new EventBus());
+    addressManager1 = new ServiceRegistryAddressManager(addresses, new EventBus());
     RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion, "SERVICECENTER");
     addressManager1.refreshEndpoint(event, "SERVICECENTER");
 
@@ -88,7 +88,7 @@
     Map<String, List<String>> zoneAndRegion = new HashMap<>();
     zoneAndRegion.put("sameZone", addressAZ);
     zoneAndRegion.put("sameRegion", new ArrayList<>());
-    addressManager1 = new AddressManager(addresses, EventManager.getEventBus());
+    addressManager1 = new ServiceRegistryAddressManager(addresses, EventManager.getEventBus());
     RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion, "SERVICECENTER");
     addressManager1.refreshEndpoint(event, "SERVICECENTER");