You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2020/06/16 09:03:54 UTC

[servicecomb-java-chassis] 01/06: [SCB-2000]schema discovery working in edge service

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 ba6db7694af98089e19e86d66f1cd7ea9d6b9c1f
Author: liubao <bi...@qq.com>
AuthorDate: Fri Jun 12 18:05:07 2020 +0800

    [SCB-2000]schema discovery working in edge service
---
 .../org/apache/servicecomb/core/SCBEngine.java     | 27 ++++++++++++
 .../README.md                                      |  6 ++-
 .../pom.xml                                        |  2 +-
 .../{Application.java => ClientApplication.java}   |  4 +-
 .../pom.xml                                        | 14 +++---
 .../demo/zeroconfig/edge/EdgeApplication.java}     | 21 ++++++---
 .../demo/zeroconfig/edge/SelfServiceInvoker.java}  | 31 +++++++++-----
 .../demo/zeroconfig/edge/ServerEndpoint.java       | 41 ++++++++++++++++++
 .../src/main/resources/application.yml}            | 40 ++++++++++++-----
 .../src/main/resources/logback.xml                 | 50 ++++++++++++++++++++++
 .../pom.xml                                        |  4 --
 .../demo/zeroconfig/tests/ServerTest.java          | 37 +++++++++++++---
 .../ClientServerEndpoint.yaml                      | 39 +++++++++++++++++
 .../src/main/resources/registry.yaml               | 12 +++++-
 .../pom.xml                                        |  5 +--
 .../servicecomb/edge/core/EdgeInvocation.java      | 30 ++++++++-----
 .../servicecomb/registry/DiscoveryManager.java     |  6 +++
 .../servicecomb/registry/consumer/AppManager.java  |  7 +++
 .../registry/consumer/MicroserviceManager.java     | 31 +++++++++++++-
 .../schemadiscovery/SchemaDiscovery.java           |  4 +-
 .../client/Http2TransportHttpClientOptionsSPI.java |  5 +++
 .../client/HttpTransportHttpClientOptionsSPI.java  |  7 ++-
 .../transport/rest/vertx/VertxRestTransport.java   |  4 ++
 23 files changed, 362 insertions(+), 65 deletions(-)

diff --git a/core/src/main/java/org/apache/servicecomb/core/SCBEngine.java b/core/src/main/java/org/apache/servicecomb/core/SCBEngine.java
index feea662..b62537a 100644
--- a/core/src/main/java/org/apache/servicecomb/core/SCBEngine.java
+++ b/core/src/main/java/org/apache/servicecomb/core/SCBEngine.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Comparator;
 import java.util.List;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicLong;
@@ -505,6 +506,32 @@ public class SCBEngine {
    * @param versionRule if is empty, then use configuration value
    * @return
    */
+  public CompletableFuture<MicroserviceReferenceConfig> createMicroserviceReferenceConfigAsync(String microserviceName,
+      String versionRule) {
+    CompletableFuture<MicroserviceReferenceConfig> result = new CompletableFuture<>();
+
+    CompletableFuture<MicroserviceVersions> microserviceVersions = DiscoveryManager.INSTANCE
+        .getOrCreateMicroserviceVersionsAsync(parseAppId(microserviceName), microserviceName);
+
+    microserviceVersions.whenComplete((r, e) -> {
+      if (e != null) {
+        result.completeExceptionally(e);
+      } else {
+        ConsumerMicroserviceVersionsMeta microserviceVersionsMeta = CoreMetaUtils
+            .getMicroserviceVersionsMeta(r);
+        result.complete(new MicroserviceReferenceConfig(microserviceVersionsMeta, versionRule));
+      }
+    });
+
+    return result;
+  }
+
+  /**
+   * for edge, versionRule maybe controlled by url rule
+   * @param microserviceName hortName, or appId:shortName when invoke cross app
+   * @param versionRule if is empty, then use configuration value
+   * @return
+   */
   public MicroserviceReferenceConfig createMicroserviceReferenceConfig(String microserviceName, String versionRule) {
     MicroserviceVersions microserviceVersions = DiscoveryManager.INSTANCE
         .getOrCreateMicroserviceVersions(parseAppId(microserviceName), microserviceName);
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/README.md b/demo/demo-zeroconfig-schemadiscovery-registry/README.md
index 34c4da9..44cd553 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/README.md
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/README.md
@@ -10,8 +10,12 @@ This demo tests zeroconfig.
 
   run in docker, and find server instances through zeroconfig, find schemas through
   schema discovery
+
+* edge
+  run in docker, and find server instances through zeroconfig, find schemas through
+  schema discovery
   
 * tests
 
-  integration tests run in host machine, find client instances through local, 
+  integration tests run in host machine, find client/edge instances through local, 
   and schemas from schema discovery. 
\ No newline at end of file
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/pom.xml b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/pom.xml
index f49aaba..a25bd68 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/pom.xml
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/pom.xml
@@ -29,7 +29,7 @@
   </parent>
 
   <properties>
-    <demo.main>org.apache.servicecomb.demo.zeroconfig.client.Application</demo.main>
+    <demo.main>org.apache.servicecomb.demo.zeroconfig.client.ClientApplication</demo.main>
   </properties>
   <dependencies>
     <dependency>
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/Application.java b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/ClientApplication.java
similarity index 90%
copy from demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/Application.java
copy to demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/ClientApplication.java
index f2ed3c8..3206cb9 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/Application.java
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/ClientApplication.java
@@ -24,10 +24,10 @@ import org.springframework.boot.builder.SpringApplicationBuilder;
 
 @SpringBootApplication
 @EnableServiceComb
-public class Application {
+public class ClientApplication {
 
   public static void main(final String[] args) throws Exception {
-    new SpringApplicationBuilder().sources(Application.class).web(WebApplicationType.SERVLET)
+    new SpringApplicationBuilder().sources(ClientApplication.class).web(WebApplicationType.SERVLET)
         .build().run(args);
   }
 }
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/pom.xml b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-edge/pom.xml
similarity index 89%
copy from demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/pom.xml
copy to demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-edge/pom.xml
index f49aaba..4b6a12f 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/pom.xml
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-edge/pom.xml
@@ -20,8 +20,8 @@
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
   xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <modelVersion>4.0.0</modelVersion>
-  <artifactId>demo-zeroconfig-schemadiscovery-registry-client</artifactId>
-  <name>Java Chassis::Demo::ZeroConfig-SchemaDiscovery Registry Client</name>
+  <artifactId>demo-zeroconfig-schemadiscovery-registry-edge</artifactId>
+  <name>Java Chassis::Demo::ZeroConfig-SchemaDiscovery Registry Edge</name>
   <parent>
     <groupId>org.apache.servicecomb.demo</groupId>
     <artifactId>demo-zeroconfig-schemadiscovery-registry</artifactId>
@@ -29,7 +29,7 @@
   </parent>
 
   <properties>
-    <demo.main>org.apache.servicecomb.demo.zeroconfig.client.Application</demo.main>
+    <demo.main>org.apache.servicecomb.demo.zeroconfig.edge.EdgeApplication</demo.main>
   </properties>
   <dependencies>
     <dependency>
@@ -38,7 +38,11 @@
     </dependency>
     <dependency>
       <groupId>org.apache.servicecomb</groupId>
-      <artifactId>java-chassis-spring-boot-starter-servlet</artifactId>
+      <artifactId>edge-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.servicecomb</groupId>
+      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>
     </dependency>
     <dependency>
       <groupId>org.apache.servicecomb</groupId>
@@ -93,4 +97,4 @@
       </build>
     </profile>
   </profiles>
-</project>
+</project>
\ No newline at end of file
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/Application.java b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-edge/src/main/java/org/apache/servicecomb/demo/zeroconfig/edge/EdgeApplication.java
similarity index 66%
copy from demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/Application.java
copy to demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-edge/src/main/java/org/apache/servicecomb/demo/zeroconfig/edge/EdgeApplication.java
index f2ed3c8..91685d0 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/Application.java
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-edge/src/main/java/org/apache/servicecomb/demo/zeroconfig/edge/EdgeApplication.java
@@ -15,8 +15,12 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.demo.zeroconfig.client;
+package org.apache.servicecomb.demo.zeroconfig.edge;
 
+import java.util.concurrent.TimeUnit;
+
+import org.apache.servicecomb.demo.TestMgr;
+import org.apache.servicecomb.foundation.common.utils.BeanUtils;
 import org.apache.servicecomb.springboot2.starter.EnableServiceComb;
 import org.springframework.boot.WebApplicationType;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -24,10 +28,17 @@ import org.springframework.boot.builder.SpringApplicationBuilder;
 
 @SpringBootApplication
 @EnableServiceComb
-public class Application {
-
+public class EdgeApplication {
   public static void main(final String[] args) throws Exception {
-    new SpringApplicationBuilder().sources(Application.class).web(WebApplicationType.SERVLET)
-        .build().run(args);
+    new SpringApplicationBuilder().sources(EdgeApplication.class).web(WebApplicationType.NONE).build().run(args);
+
+    SelfServiceInvoker invoker = BeanUtils.getBean("SelfServiceInvoker");
+    invoker.latch.await(10, TimeUnit.SECONDS);
+    TestMgr.check(invoker.result, "hello");
+
+    TestMgr.summary();
+    if (!TestMgr.errors().isEmpty()) {
+      System.exit(1);
+    }
   }
 }
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/Application.java b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-edge/src/main/java/org/apache/servicecomb/demo/zeroconfig/edge/SelfServiceInvoker.java
similarity index 51%
rename from demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/Application.java
rename to demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-edge/src/main/java/org/apache/servicecomb/demo/zeroconfig/edge/SelfServiceInvoker.java
index f2ed3c8..e653524 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/Application.java
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-edge/src/main/java/org/apache/servicecomb/demo/zeroconfig/edge/SelfServiceInvoker.java
@@ -15,19 +15,28 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.demo.zeroconfig.client;
+package org.apache.servicecomb.demo.zeroconfig.edge;
 
-import org.apache.servicecomb.springboot2.starter.EnableServiceComb;
-import org.springframework.boot.WebApplicationType;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.builder.SpringApplicationBuilder;
+import java.util.concurrent.CountDownLatch;
+import org.apache.servicecomb.core.BootListener;
+import org.apache.servicecomb.provider.pojo.RpcReference;
+import org.springframework.stereotype.Component;
 
-@SpringBootApplication
-@EnableServiceComb
-public class Application {
+@Component("SelfServiceInvoker")
+public class SelfServiceInvoker implements BootListener {
+  interface IServerEndpoint {
+    String getName(String name);
+  }
+
+  @RpcReference(microserviceName = "demo-zeroconfig-schemadiscovery-registry-edge", schemaId = "ServerEndpoint")
+  IServerEndpoint endpoint;
+
+  public CountDownLatch latch = new CountDownLatch(1);
+
+  public String result = "";
 
-  public static void main(final String[] args) throws Exception {
-    new SpringApplicationBuilder().sources(Application.class).web(WebApplicationType.SERVLET)
-        .build().run(args);
+  public void onAfterRegistry(BootEvent event) {
+    result = endpoint.getName("hello");
+    latch.countDown();
   }
 }
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-edge/src/main/java/org/apache/servicecomb/demo/zeroconfig/edge/ServerEndpoint.java b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-edge/src/main/java/org/apache/servicecomb/demo/zeroconfig/edge/ServerEndpoint.java
new file mode 100644
index 0000000..24e25ed
--- /dev/null
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-edge/src/main/java/org/apache/servicecomb/demo/zeroconfig/edge/ServerEndpoint.java
@@ -0,0 +1,41 @@
+/*
+ * 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.zeroconfig.edge;
+
+import javax.ws.rs.core.MediaType;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.apache.servicecomb.swagger.invocation.context.ContextUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@RestSchema(schemaId = "ServerEndpoint")
+@RequestMapping(path = "/edge/prefix", produces = MediaType.APPLICATION_JSON)
+public class ServerEndpoint {
+  private static final Logger LOGGER
+      = LoggerFactory.getLogger(ServerEndpoint.class);
+
+  @GetMapping(path = "/getName")
+  public String getName(@RequestParam(name = "name") String name) {
+    ((Invocation) ContextUtils.getInvocationContext()).getTraceIdLogger().info(LOGGER, "get name invoked.");
+    return name;
+  }
+}
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/registry.yaml b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-edge/src/main/resources/application.yml
similarity index 58%
copy from demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/registry.yaml
copy to demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-edge/src/main/resources/application.yml
index 2dc9fa4..5062701 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/registry.yaml
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-edge/src/main/resources/application.yml
@@ -15,13 +15,33 @@
 ## limitations under the License.
 ## ---------------------------------------------------------------------------
 
-demo-zeroconfig-schemadiscovery-registry-client:
-  - id: "001"
-    version: "0.0.2"
-    appid: demo-zeroconfig-schemadiscovery-registry
-    schemaIds:
-      - ClientServerEndpoint
-      - SchemaDiscoveryEndpoint
-    instances:
-      - endpoints:
-          - rest://localhost:8082
\ No newline at end of file
+server:
+  port: 8888
+
+# java-chassis configurations
+
+APPLICATION_ID: demo-zeroconfig-schemadiscovery-registry
+service_description:
+  name: demo-zeroconfig-schemadiscovery-registry-edge
+  version: 0.0.2
+servicecomb:
+  rest:
+    address: 0.0.0.0:8888
+  handler:
+    chain:
+      Consumer:
+        default: loadbalance
+  http:
+    dispatcher:
+      edge:
+        default:
+          enabled: false
+        url:
+          enabled: true
+          pattern: /(.*)
+          mappings:
+            client:
+              prefixSegmentCount: 0
+              path: "/register/url/prefix/.*"
+              microserviceName: demo-zeroconfig-schemadiscovery-registry-client
+              versionRule: 0+
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-edge/src/main/resources/logback.xml b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-edge/src/main/resources/logback.xml
new file mode 100644
index 0000000..0d627f2
--- /dev/null
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-edge/src/main/resources/logback.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<configuration scan="true">
+  <appender name="STDOUT-TRACING" class="ch.qos.logback.core.ConsoleAppender">
+    <!-- If applicable, can use ch.qos.logback.classic.filter.MarkerFilter -->
+    <filter class="org.apache.servicecomb.foundation.logback.MarkerFilter">
+      <Marker>SERVICECOMB_MARKER</Marker>
+      <OnMismatch>DENY</OnMismatch>
+      <OnMatch>ACCEPT</OnMatch>
+    </filter>
+
+    <encoder>
+      <pattern>%d [%level] [%thread][%X{SERVICECOMB_TRACE_ID}] - %msg (%F:%L\)%n</pattern>
+    </encoder>
+  </appender>
+
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <!-- If applicable, can use ch.qos.logback.classic.filter.MarkerFilter -->
+    <filter class="org.apache.servicecomb.foundation.logback.MarkerFilter">
+      <Marker>SERVICECOMB_MARKER</Marker>
+      <OnMismatch>ACCEPT</OnMismatch>
+      <OnMatch>DENY</OnMatch>
+    </filter>
+
+    <encoder>
+      <pattern>%d [%level] [%thread] - %msg (%F:%L\)%n</pattern>
+    </encoder>
+  </appender>
+
+  <root level="info">
+    <appender-ref ref="STDOUT"/>
+    <appender-ref ref="STDOUT-TRACING"/>
+  </root>
+</configuration>
\ No newline at end of file
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/pom.xml b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/pom.xml
index 08a0b5f..0fb56ae 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/pom.xml
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/pom.xml
@@ -41,10 +41,6 @@
       <artifactId>registry-schema-discovery</artifactId>
     </dependency>
     <dependency>
-      <groupId>org.apache.servicecomb</groupId>
-      <artifactId>registry-zero-config</artifactId>
-    </dependency>
-    <dependency>
       <groupId>org.apache.servicecomb.demo</groupId>
       <artifactId>demo-schema</artifactId>
     </dependency>
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/java/org/apache/servicecomb/demo/zeroconfig/tests/ServerTest.java b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/java/org/apache/servicecomb/demo/zeroconfig/tests/ServerTest.java
index b77e009..23ab351 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/java/org/apache/servicecomb/demo/zeroconfig/tests/ServerTest.java
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/java/org/apache/servicecomb/demo/zeroconfig/tests/ServerTest.java
@@ -18,6 +18,7 @@
 package org.apache.servicecomb.demo.zeroconfig.tests;
 
 import java.util.List;
+import java.util.concurrent.CountDownLatch;
 
 import org.apache.servicecomb.demo.CategorizedTestCase;
 import org.apache.servicecomb.demo.TestMgr;
@@ -31,26 +32,52 @@ public class ServerTest implements CategorizedTestCase {
   RestTemplate template = RestTemplateBuilder.create();
 
   @Override
-  public void testRestTransport() {
+  public void testRestTransport() throws Exception {
     testServerGetName();
     testGetAllMicroservice();
   }
 
-  private void testGetAllMicroservice() {
+  private void testServerGetName() throws Exception {
     // invoke demo-zeroconfig-schemadiscovery-registry-client
-    TestMgr.check("2", template
+    TestMgr.check("world", template
         .getForObject(
-            "cse://demo-zeroconfig-schemadiscovery-registry-client/register/url/prefix/getName?name=2",
+            "cse://demo-zeroconfig-schemadiscovery-registry-client/register/url/prefix/getName?name=world",
             String.class));
+    // invoke demo-zeroconfig-schemadiscovery-registry-edge
+    int thread = 32;
+    CountDownLatch latch = new CountDownLatch(thread);
+    for (int i = 0; i < thread; i++) {
+      new Thread(() -> {
+        for (int j = 0; j < 20; j++) {
+          try {
+            TestMgr.check("world", template
+                .getForObject(
+                    "cse://demo-zeroconfig-schemadiscovery-registry-edge/register/url/prefix/getName?name=world",
+                    String.class));
+          } catch (Exception e) {
+            TestMgr.failed("test failed", e);
+          }
+        }
+        latch.countDown();
+      }).start();
+    }
+
+    latch.await();
   }
 
   @SuppressWarnings("rawTypes")
-  private void testServerGetName() {
+  private void testGetAllMicroservice() {
     // invoke demo-zeroconfig-schemadiscovery-registry-client
     TestMgr.check("2", template
         .getForObject(
             "cse://demo-zeroconfig-schemadiscovery-registry-client"
                 + "/register/url/prefix/getRegisteredMicroservice",
             List.class).size());
+    // invoke demo-zeroconfig-schemadiscovery-registry-edge
+    TestMgr.check("2", template
+        .getForObject(
+            "cse://demo-zeroconfig-schemadiscovery-registry-edge"
+                + "/register/url/prefix/getRegisteredMicroservice",
+            List.class).size());
   }
 }
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/microservices/demo-zeroconfig-schemadiscovery-registry-edge/ClientServerEndpoint.yaml b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/microservices/demo-zeroconfig-schemadiscovery-registry-edge/ClientServerEndpoint.yaml
new file mode 100644
index 0000000..9061817
--- /dev/null
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/microservices/demo-zeroconfig-schemadiscovery-registry-edge/ClientServerEndpoint.yaml
@@ -0,0 +1,39 @@
+---
+swagger: "2.0"
+info:
+  version: "1.0.0"
+  title: "swagger definition for org.apache.servicecomb.demo.zeroconfig.client.ClientServerEndpoint"
+  x-java-interface: "gen.swagger.ClientServerEndpointIntf"
+basePath: "/register/url/prefix"
+schemes:
+  - "http"
+consumes:
+  - "application/json"
+produces:
+  - "application/json"
+paths:
+  /getName:
+    get:
+      operationId: "getName"
+      parameters:
+        - name: "name"
+          in: "query"
+          required: true
+          type: "string"
+      responses:
+        "200":
+          description: "response of 200"
+          schema:
+            type: "string"
+  /getRegisteredMicroservice:
+    get:
+      operationId: "getRegisteredMicroservice"
+      parameters: []
+      responses:
+        "200":
+          description: "response of 200"
+          schema:
+            type: "array"
+            items:
+              type: "string"
+            uniqueItems: true
\ No newline at end of file
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/registry.yaml b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/registry.yaml
index 2dc9fa4..df728fc 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/registry.yaml
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/registry.yaml
@@ -24,4 +24,14 @@ demo-zeroconfig-schemadiscovery-registry-client:
       - SchemaDiscoveryEndpoint
     instances:
       - endpoints:
-          - rest://localhost:8082
\ No newline at end of file
+          - rest://localhost:8082
+demo-zeroconfig-schemadiscovery-registry-edge:
+  - id: "002"
+    version: "0.0.2"
+    appid: demo-zeroconfig-schemadiscovery-registry
+    schemaIds:
+      - ClientServerEndpoint
+      - SchemaDiscoveryEndpoint
+    instances:
+      - endpoints:
+          - rest://localhost:8888
\ No newline at end of file
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/pom.xml b/demo/demo-zeroconfig-schemadiscovery-registry/pom.xml
index 7c9e2b4..83be7f0 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/pom.xml
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/pom.xml
@@ -29,6 +29,7 @@
   <packaging>pom</packaging>
   <modules>
     <module>demo-zeroconfig-schemadiscovery-registry-server</module>
+    <module>demo-zeroconfig-schemadiscovery-registry-edge</module>
     <module>demo-zeroconfig-schemadiscovery-registry-client</module>
     <module>demo-zeroconfig-schemadiscovery-registry-tests</module>
   </modules>
@@ -36,10 +37,6 @@
   <dependencies>
     <dependency>
       <groupId>org.apache.servicecomb</groupId>
-      <artifactId>java-chassis-spring-boot-starter-servlet</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.servicecomb</groupId>
       <artifactId>foundation-test-scaffolding</artifactId>
       <scope>compile</scope>
     </dependency>
diff --git a/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/EdgeInvocation.java b/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/EdgeInvocation.java
index b0a6f32..962c72e 100644
--- a/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/EdgeInvocation.java
+++ b/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/EdgeInvocation.java
@@ -18,6 +18,7 @@
 package org.apache.servicecomb.edge.core;
 
 import java.util.List;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.servicecomb.common.rest.AbstractRestInvocation;
 import org.apache.servicecomb.common.rest.RestConst;
@@ -32,6 +33,7 @@ import org.apache.servicecomb.core.provider.consumer.ReferenceConfig;
 import org.apache.servicecomb.foundation.vertx.http.VertxServerRequestToHttpServletRequest;
 import org.apache.servicecomb.foundation.vertx.http.VertxServerResponseToHttpServletResponse;
 
+import io.vertx.core.Context;
 import io.vertx.core.Vertx;
 import io.vertx.ext.web.RoutingContext;
 
@@ -59,17 +61,25 @@ public class EdgeInvocation extends AbstractRestInvocation {
   }
 
   public void edgeInvoke() {
-    findMicroserviceVersionMeta();
-    findRestOperation(microserviceReferenceConfig.getLatestMicroserviceMeta());
-
-    scheduleInvocation();
+    Context currentContext = Vertx.currentContext();
+    findMicroserviceVersionMeta().whenComplete((r, e) -> {
+          // get back to the context so that registered handlers can work properly
+          currentContext.runOnContext((event) -> {
+            if (e != null) {
+              sendFailResponse(e);
+            } else {
+              microserviceReferenceConfig = r;
+              findRestOperation(microserviceReferenceConfig.getLatestMicroserviceMeta());
+              scheduleInvocation();
+            }
+          });
+        }
+    );
   }
 
-  protected void findMicroserviceVersionMeta() {
-    // if not present, should use configured value
-    String versionRule = chooseVersionRule();
-    microserviceReferenceConfig = SCBEngine.getInstance()
-        .createMicroserviceReferenceConfig(microserviceName, versionRule);
+  protected CompletableFuture<MicroserviceReferenceConfig> findMicroserviceVersionMeta() {
+    return SCBEngine.getInstance()
+        .createMicroserviceReferenceConfigAsync(microserviceName, chooseVersionRule());
   }
 
   public void setVersionRule(String versionRule) {
@@ -83,7 +93,7 @@ public class EdgeInvocation extends AbstractRestInvocation {
   //   v1->1.0.0-2.0.0
   //   v2->2.0.0-3.0.0
   // that means if a(1.x.x) bigger then b(1.y.y), then a compatible to b
-  //        but a(2.x.x) not compatible to b   
+  //        but a(2.x.x) not compatible to b
   protected String chooseVersionRule() {
     // this will use all instance of the microservice
     // and this required all new version compatible to old version
diff --git a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/DiscoveryManager.java b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/DiscoveryManager.java
index ab0c6f7..8ce351f 100644
--- a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/DiscoveryManager.java
+++ b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/DiscoveryManager.java
@@ -20,6 +20,7 @@ package org.apache.servicecomb.registry;
 import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.concurrent.CompletableFuture;
 import java.util.stream.Collectors;
 
 import org.apache.servicecomb.config.ConfigUtil;
@@ -130,6 +131,11 @@ public class DiscoveryManager {
     return result;
   }
 
+  public CompletableFuture<MicroserviceVersions> getOrCreateMicroserviceVersionsAsync(String appId,
+      String microserviceName) {
+    return appManager.getOrCreateMicroserviceVersionsAsync(appId, microserviceName);
+  }
+
   public MicroserviceVersions getOrCreateMicroserviceVersions(String appId, String microserviceName) {
     return appManager.getOrCreateMicroserviceVersions(appId, microserviceName);
   }
diff --git a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/consumer/AppManager.java b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/consumer/AppManager.java
index cfa3f09..0dd13cd 100644
--- a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/consumer/AppManager.java
+++ b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/consumer/AppManager.java
@@ -18,6 +18,7 @@
 package org.apache.servicecomb.registry.consumer;
 
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
 import org.apache.servicecomb.foundation.common.event.EventManager;
@@ -54,6 +55,12 @@ public class AppManager {
     return apps.computeIfAbsent(appId, id -> new MicroserviceManager(this, appId));
   }
 
+  public CompletableFuture<MicroserviceVersions> getOrCreateMicroserviceVersionsAsync(String appId
+      , String microserviceName) {
+    MicroserviceManager microserviceManager = getOrCreateMicroserviceManager(appId);
+    return microserviceManager.getOrCreateMicroserviceVersionsAsync(microserviceName);
+  }
+
   public MicroserviceVersions getOrCreateMicroserviceVersions(String appId, String microserviceName) {
     MicroserviceManager microserviceManager = getOrCreateMicroserviceManager(appId);
     return microserviceManager.getOrCreateMicroserviceVersions(microserviceName);
diff --git a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/consumer/MicroserviceManager.java b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/consumer/MicroserviceManager.java
index 4fb414e..0c6482a 100644
--- a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/consumer/MicroserviceManager.java
+++ b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/consumer/MicroserviceManager.java
@@ -17,8 +17,8 @@
 
 package org.apache.servicecomb.registry.consumer;
 
-import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
 import org.apache.servicecomb.registry.api.event.MicroserviceInstanceChangedEvent;
@@ -26,6 +26,8 @@ import org.apache.servicecomb.registry.api.event.task.SafeModeChangeEvent;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import io.vertx.core.Vertx;
+
 public class MicroserviceManager {
   private static final Logger LOGGER = LoggerFactory.getLogger(MicroserviceManager.class);
 
@@ -69,6 +71,33 @@ public class MicroserviceManager {
     return microserviceVersions;
   }
 
+  public CompletableFuture<MicroserviceVersions> getOrCreateMicroserviceVersionsAsync(String microserviceName) {
+    CompletableFuture<MicroserviceVersions> result = new CompletableFuture<>();
+    MicroserviceVersions microserviceVersions = versionsByName.get(microserviceName);
+    if (microserviceVersions == null) {
+      if (Vertx.currentContext() == null) {
+        // not in event-loop, execute in current thread
+        result.complete(getOrCreateMicroserviceVersions(microserviceName));
+      } else {
+        // executing blocking code in event-loop
+        Vertx.currentContext().<MicroserviceVersions>executeBlocking(blockingCodeHandler -> {
+          blockingCodeHandler.complete(getOrCreateMicroserviceVersions(microserviceName));
+        }, r -> {
+          if (r.failed()) {
+            result.completeExceptionally(r.cause());
+          } else {
+            result.complete(r.result());
+          }
+        });
+      }
+    } else {
+      result.complete(microserviceVersions);
+      tryRemoveInvalidMicroservice(microserviceVersions);
+    }
+
+    return result;
+  }
+
   private void tryRemoveInvalidMicroservice(MicroserviceVersions microserviceVersions) {
     if (!microserviceVersions.isWaitingDelete()) {
       return;
diff --git a/service-registry/registry-schema-discovery/src/main/java/org/apache/servicecomb/schemadiscovery/SchemaDiscovery.java b/service-registry/registry-schema-discovery/src/main/java/org/apache/servicecomb/schemadiscovery/SchemaDiscovery.java
index fd4cf00..772942a 100644
--- a/service-registry/registry-schema-discovery/src/main/java/org/apache/servicecomb/schemadiscovery/SchemaDiscovery.java
+++ b/service-registry/registry-schema-discovery/src/main/java/org/apache/servicecomb/schemadiscovery/SchemaDiscovery.java
@@ -21,6 +21,7 @@ import java.util.Collection;
 import java.util.List;
 
 import org.apache.commons.lang3.StringUtils;
+import org.apache.servicecomb.core.invocation.endpoint.EndpointUtils;
 import org.apache.servicecomb.foundation.common.base.ServiceCombConstants;
 import org.apache.servicecomb.loadbalance.LoadbalanceHandler;
 import org.apache.servicecomb.provider.pojo.Invoker;
@@ -70,7 +71,8 @@ public class SchemaDiscovery implements Discovery {
 
       for (String endpoint : endpoints) {
         InvocationContext invocationContext = new InvocationContext();
-        invocationContext.addLocalContext(LoadbalanceHandler.SERVICECOMB_SERVER_ENDPOINT, endpoint);
+        invocationContext
+            .addLocalContext(LoadbalanceHandler.SERVICECOMB_SERVER_ENDPOINT, EndpointUtils.parse(endpoint));
         SchemaDiscoveryService schemaDiscoveryService = getOrCreateSchemaDiscoveryService();
         try {
           String schema = schemaDiscoveryService.getSchema(invocationContext, schemaId);
diff --git a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/Http2TransportHttpClientOptionsSPI.java b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/Http2TransportHttpClientOptionsSPI.java
index e201c67..24bbd5b 100644
--- a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/Http2TransportHttpClientOptionsSPI.java
+++ b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/Http2TransportHttpClientOptionsSPI.java
@@ -43,6 +43,11 @@ public class Http2TransportHttpClientOptionsSPI extends HttpTransportHttpClientO
   }
 
   @Override
+  public String getWorkerPoolName() {
+    return "pool-transport-client-http2";
+  }
+
+  @Override
   public boolean isUseAlpn() {
     return TransportClientConfig.getUseAlpn();
   }
diff --git a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/HttpTransportHttpClientOptionsSPI.java b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/HttpTransportHttpClientOptionsSPI.java
index 3bee8df..b449520 100644
--- a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/HttpTransportHttpClientOptionsSPI.java
+++ b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/HttpTransportHttpClientOptionsSPI.java
@@ -21,7 +21,6 @@ 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;
 
@@ -73,17 +72,17 @@ public class HttpTransportHttpClientOptionsSPI implements HttpClientOptionsSPI {
 
   @Override
   public boolean isWorker() {
-    return false;
+    return true;
   }
 
   @Override
   public String getWorkerPoolName() {
-    return null;
+    return "pool-transport-client-http";
   }
 
   @Override
   public int getWorkerPoolSize() {
-    return VertxOptions.DEFAULT_WORKER_POOL_SIZE;
+    return 2;
   }
 
   @Override
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxRestTransport.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxRestTransport.java
index a8dee62..626df93 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxRestTransport.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxRestTransport.java
@@ -76,6 +76,10 @@ public class VertxRestTransport extends AbstractTransport {
     json.put(ENDPOINT_KEY, getEndpoint());
     json.put(RestTransportClient.class.getName(), restClient);
     options.setConfig(json);
+    // now used not very frequently, hard code its options
+    options.setWorker(true);
+    options.setWorkerPoolName("pool-transport");
+    options.setWorkerPoolSize(2);
     return VertxUtils.blockDeploy(transportVertx, TransportConfig.getRestServerVerticle(), options);
   }