You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shenyu.apache.org by xi...@apache.org on 2022/06/19 02:13:01 UTC

[incubator-shenyu] branch master updated: [ISSUE #3521] task6 add integration test for shared thread pool (#3575)

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

xiaoyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new 3ca55a900 [ISSUE #3521] task6 add integration test for shared thread pool (#3575)
3ca55a900 is described below

commit 3ca55a9006c6bcec1898b9f71d4cfd3e67036c8c
Author: dragon-zhang <ha...@webuy.ai>
AuthorDate: Sun Jun 19 10:12:56 2022 +0800

    [ISSUE #3521] task6 add integration test for shared thread pool (#3575)
    
    * [ISSUE #3521] task6 add integration test for shared thread pool
    
    * fix code style
    
    * fix property name bug
    
    * fix code style
    
    * complete docker config
    
    * exclude dependencies
    
    * Regardless of sofa
    
    * exclude dependencies
    
    * add some log
    
    * remove motan catch
    
    * remove sofa catch
    
    * Revert "remove sofa catch"
    
    * remove some dependency exclusion
---
 pom.xml                                            |   2 +-
 .../docker-compose.yml                             |  75 ++++++++++++
 .../shenyu-integrated-test-combination/pom.xml     |  55 +++++++++
 .../controller/SharedThreadPoolController.java     |  98 ++++++++++++++++
 .../test/combination/dto/SofaTestData.java         |  51 +++++++++
 .../src/main/resources/application-local.yml       |   2 +
 .../test/combination/SharedThreadPoolTest.java     | 126 +++++++++++++++++++++
 .../plugin/grpc/client/GrpcClientBuilder.java      |   7 +-
 .../plugin/motan/proxy/MotanProxyService.java      |   9 ++
 .../plugin/sofa/cache/ApplicationConfigCache.java  |  21 +++-
 .../httpclient/HttpClientPluginConfiguration.java  |   2 +-
 .../plugin/motan/MotanPluginConfiguration.java     |  15 ++-
 .../ShenyuThreadPoolConfiguration.java             |   6 +-
 13 files changed, 455 insertions(+), 14 deletions(-)

diff --git a/pom.xml b/pom.xml
index 180e7d8a9..b8edfc629 100644
--- a/pom.xml
+++ b/pom.xml
@@ -145,7 +145,7 @@
         <frontend-maven-plugin.node.version>v12.14.1</frontend-maven-plugin.node.version>
         <bytebuddy.version>1.12.6</bytebuddy.version>
         <spring-ldap.version>2.3.4.RELEASE</spring-ldap.version>
-        <jaxb.api.version>2.3.0</jaxb.api.version>
+        <jaxb.api.version>2.3.1</jaxb.api.version>
         <mail.version>1.6.2</mail.version>
         <dockerfile-maven-plugin.version>1.4.6</dockerfile-maven-plugin.version>
         <ojdbc8.version>19.3.0.0</ojdbc8.version>
diff --git a/shenyu-integrated-test/shenyu-integrated-test-combination/docker-compose.yml b/shenyu-integrated-test/shenyu-integrated-test-combination/docker-compose.yml
index c13413f7d..cb1d14223 100644
--- a/shenyu-integrated-test/shenyu-integrated-test-combination/docker-compose.yml
+++ b/shenyu-integrated-test/shenyu-integrated-test-combination/docker-compose.yml
@@ -79,6 +79,81 @@ services:
       - dubbo.registry.address=zookeeper://shenyu-zk:2181
       - shenyu.register.serverLists=http://shenyu-admin:9095
 
+  shenyu-examples-grpc:
+    deploy:
+      resources:
+        limits:
+          memory: 2048M
+    container_name: shenyu-examples-grpc
+    image: shenyu-examples-grpc:latest
+    restart: always
+    environment:
+      - shenyu.register.serverLists=http://shenyu-admin:9095
+    healthcheck:
+      test: [ "CMD-SHELL", "wget -q -O - http://localhost:55290/test/grpc/hello | grep UP || exit 1" ]
+      timeout: 2s
+      retries: 3
+      start_period: 5s
+    ports:
+      - "55290:55290"
+      - "8080:8080"
+    networks:
+      - shenyu
+    depends_on:
+      shenyu-integrated-test-combination:
+        condition: service_healthy
+
+  shenyu-examples-motan:
+    deploy:
+      resources:
+        limits:
+          memory: 2048M
+    container_name: shenyu-examples-motan
+    image: shenyu-examples-motan:latest
+    restart: always
+    environment:
+      - motan.registry.protocol=zookeeper
+      - motan.registry.address=shenyu-zk:2181
+      - shenyu.register.serverLists=http://shenyu-admin:9095
+    healthcheck:
+      test: [ "CMD-SHELL", "wget -q -O - http://localhost:8081/actuator/health | grep UP || exit 1" ]
+      timeout: 2s
+      retries: 3
+      start_period: 5s
+    ports:
+      - "8081:8081"
+      - "8002:8002"
+    networks:
+      - shenyu
+    depends_on:
+      shenyu-integrated-test-combination:
+        condition: service_healthy
+
+  shenyu-examples-sofa:
+    deploy:
+      resources:
+        limits:
+          memory: 2048M
+    container_name: shenyu-examples-sofa
+    image: shenyu-examples-sofa:latest
+    restart: always
+    environment:
+      - shenyu.register.serverLists=http://shenyu-admin:9095
+      - com.alipay.sofa.rpc.registry-address=zookeeper://shenyu-zk:2181
+    healthcheck:
+      test: [ "CMD-SHELL", "wget -q -O - http://localhost:28011/sofa/findAll | grep UP || exit 1" ]
+      timeout: 2s
+      retries: 3
+      start_period: 5s
+    ports:
+      - "28011:28011"
+      - "8888:8888"
+    networks:
+      - shenyu
+    depends_on:
+      shenyu-integrated-test-combination:
+        condition: service_healthy
+
   shenyu-admin:
     image: apache/shenyu-admin:latest
     container_name: shenyu-admin
diff --git a/shenyu-integrated-test/shenyu-integrated-test-combination/pom.xml b/shenyu-integrated-test/shenyu-integrated-test-combination/pom.xml
index 296904174..323d3687e 100644
--- a/shenyu-integrated-test/shenyu-integrated-test-combination/pom.xml
+++ b/shenyu-integrated-test/shenyu-integrated-test-combination/pom.xml
@@ -130,6 +130,61 @@
             <version>${project.version}</version>
         </dependency>
         <!-- apache shenyu request plugin end-->
+
+        <!--shenyu grpc plugin start-->
+        <dependency>
+            <groupId>org.apache.shenyu</groupId>
+            <artifactId>shenyu-spring-boot-starter-plugin-grpc</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <!--shenyu grpc plugin end-->
+
+        <!-- apache shenyu motan plugin start-->
+        <dependency>
+            <groupId>org.apache.shenyu</groupId>
+            <artifactId>shenyu-spring-boot-starter-plugin-motan</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.weibo</groupId>
+            <artifactId>motan-core</artifactId>
+            <version>1.1.9</version>
+        </dependency>
+        <dependency>
+            <groupId>com.weibo</groupId>
+            <artifactId>motan-registry-zookeeper</artifactId>
+            <version>1.1.9</version>
+        </dependency>
+        <dependency>
+            <groupId>com.weibo</groupId>
+            <artifactId>motan-transport-netty4</artifactId>
+            <version>1.1.9</version>
+        </dependency>
+        <dependency>
+            <groupId>com.weibo</groupId>
+            <artifactId>motan-springsupport</artifactId>
+            <version>1.1.9</version>
+        </dependency>
+        <!-- apache shenyu motan plugin end-->
+
+        <!-- apache shenyu sofa plugin start-->
+        <dependency>
+            <groupId>com.alipay.sofa</groupId>
+            <artifactId>sofa-rpc-all</artifactId>
+            <version>5.7.6</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>net.jcip</groupId>
+                    <artifactId>jcip-annotations</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shenyu</groupId>
+            <artifactId>shenyu-spring-boot-starter-plugin-sofa</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <!-- apache shenyu sofa plugin end-->
     </dependencies>
 
     <profiles>
diff --git a/shenyu-integrated-test/shenyu-integrated-test-combination/src/main/java/org/apache/shenyu/integrated/test/combination/controller/SharedThreadPoolController.java b/shenyu-integrated-test/shenyu-integrated-test-combination/src/main/java/org/apache/shenyu/integrated/test/combination/controller/SharedThreadPoolController.java
new file mode 100644
index 000000000..6abc02e18
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-combination/src/main/java/org/apache/shenyu/integrated/test/combination/controller/SharedThreadPoolController.java
@@ -0,0 +1,98 @@
+/*
+ * 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.shenyu.integrated.test.combination.controller;
+
+import org.apache.dubbo.common.extension.ExtensionLoader;
+import org.apache.dubbo.common.threadpool.ThreadPool;
+import org.apache.shenyu.common.concurrent.ShenyuThreadPoolExecutor;
+import org.apache.shenyu.plugin.api.utils.SpringBeanUtils;
+import org.apache.shenyu.plugin.grpc.client.GrpcClientBuilder;
+import org.apache.shenyu.plugin.motan.proxy.MotanProxyService;
+import org.apache.shenyu.plugin.sofa.cache.ApplicationConfigCache;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Objects;
+import java.util.Optional;
+
+@RestController
+@RequestMapping(value = "/shenyu", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
+public class SharedThreadPoolController {
+    
+    /**
+     * get the shared thread pool from spring container.
+     *
+     * @return the shared thread pool
+     */
+    @GetMapping("/getFromSpring")
+    public String getFromSpring() {
+        return SpringBeanUtils.getInstance().getBean(ShenyuThreadPoolExecutor.class).toString();
+    }
+    
+    /**
+     * get the shared thread pool from apache dubbo.
+     *
+     * @return the shared thread pool
+     */
+    @GetMapping("/getFromDubbo")
+    public String getFromDubbo() {
+        return Optional.ofNullable(ExtensionLoader.getExtensionLoader(ThreadPool.class))
+                .map(loader -> loader.getExtension("shared"))
+                .map(shared -> shared.getExecutor(null))
+                .map(Object::toString)
+                .orElse("");
+    }
+    
+    /**
+     * get the shared thread pool from grpc.
+     *
+     * @return the shared thread pool
+     */
+    @GetMapping("/getFromGrpc")
+    public String getFromGrpc() {
+        return Optional.ofNullable(GrpcClientBuilder.buildExecutor())
+                .map(Object::toString)
+                .orElse("");
+    }
+    
+    /**
+     * get the shared thread pool from motan.
+     *
+     * @return the shared thread pool
+     */
+    @GetMapping("/getFromMotan")
+    public String getFromMotan() {
+        return Optional.ofNullable(SpringBeanUtils.getInstance().getBean(MotanProxyService.class).getThreadPool())
+                .map(Objects::toString)
+                .orElse("");
+    }
+    
+    /**
+     * get the shared thread pool from sofa.
+     *
+     * @return the shared thread pool
+     */
+    @GetMapping("/getFromSofa")
+    public String getFromSofa() {
+        return Optional.ofNullable(ApplicationConfigCache.getInstance().getThreadPool())
+                .map(Objects::toString)
+                .orElse("");
+    }
+}
diff --git a/shenyu-integrated-test/shenyu-integrated-test-combination/src/main/java/org/apache/shenyu/integrated/test/combination/dto/SofaTestData.java b/shenyu-integrated-test/shenyu-integrated-test-combination/src/main/java/org/apache/shenyu/integrated/test/combination/dto/SofaTestData.java
new file mode 100644
index 000000000..5f4f10a21
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-combination/src/main/java/org/apache/shenyu/integrated/test/combination/dto/SofaTestData.java
@@ -0,0 +1,51 @@
+/*
+ * 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.shenyu.integrated.test.combination.dto;
+
+public class SofaTestData {
+
+    private String id;
+
+    private String name;
+
+    /**
+     * get id.
+     *
+     * @return id
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * get name.
+     *
+     * @return name
+     */
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        return "SofaTest{"
+                + "id='" + id + '\''
+                + ", name='" + name + '\''
+                + '}';
+    }
+}
diff --git a/shenyu-integrated-test/shenyu-integrated-test-combination/src/main/resources/application-local.yml b/shenyu-integrated-test/shenyu-integrated-test-combination/src/main/resources/application-local.yml
index 218e1d41e..b6c11e4d2 100644
--- a/shenyu-integrated-test/shenyu-integrated-test-combination/src/main/resources/application-local.yml
+++ b/shenyu-integrated-test/shenyu-integrated-test-combination/src/main/resources/application-local.yml
@@ -44,6 +44,8 @@ shenyu:
   local:
     enabled: true
     sha512Key: "BA3253876AED6BC22D4A6FF53D8406C6AD864195ED144AB5C87621B6C233B548BAEAE6956DF346EC8C17F5EA10F35EE3CBC514797ED7DDD3145464E2A0BAB413"
+  sharedPool:
+    enable: true
 
 logging:
   level:
diff --git a/shenyu-integrated-test/shenyu-integrated-test-combination/src/test/java/org/apache/shenyu/integrated/test/combination/SharedThreadPoolTest.java b/shenyu-integrated-test/shenyu-integrated-test-combination/src/test/java/org/apache/shenyu/integrated/test/combination/SharedThreadPoolTest.java
new file mode 100644
index 000000000..457624246
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-combination/src/test/java/org/apache/shenyu/integrated/test/combination/SharedThreadPoolTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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.shenyu.integrated.test.combination;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.reflect.TypeToken;
+import org.apache.shenyu.common.enums.PluginEnum;
+import org.apache.shenyu.common.utils.GsonUtils;
+import org.apache.shenyu.integrated.test.combination.dto.SofaTestData;
+import org.apache.shenyu.integratedtest.common.AbstractPluginDataInit;
+import org.apache.shenyu.integratedtest.common.dto.DubboTest;
+import org.apache.shenyu.integratedtest.common.dto.MotanDTO;
+import org.apache.shenyu.integratedtest.common.helper.HttpHelper;
+import org.hamcrest.Matchers;
+import org.hamcrest.core.Is;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * The integrated test for combination plugins about shared thread pool.
+ */
+public class SharedThreadPoolTest extends AbstractPluginDataInit {
+    
+    private static final Logger LOG = LoggerFactory.getLogger(SharedThreadPoolTest.class);
+    
+    @BeforeAll
+    public static void setup() throws IOException {
+        // for apache dubbo
+        String pluginResult = initPlugin(PluginEnum.DUBBO.getName(), "{\"register\":\"zookeeper://shenyu-zk:2181\",\"threadpool\": \"shared\"}");
+        assertThat(pluginResult, is("success"));
+        // for grpc
+        pluginResult = initPlugin(PluginEnum.GRPC.getName(), "{\"register\":\"zookeeper://shenyu-zk:2181\",\"threadpool\": \"shared\"}");
+        assertThat(pluginResult, is("success"));
+        // for motan
+        pluginResult = initPlugin(PluginEnum.MOTAN.getName(), "{\"register\":\"shenyu-zk:2181\",\"threadpool\": \"shared\"}");
+        assertThat(pluginResult, is("success"));
+        // for sofa
+        pluginResult = initPlugin(PluginEnum.SOFA.getName(), "{\"protocol\":\"zookeeper\",\"register\":\"shenyu-zk:2181\",\"threadpool\": \"shared\"}");
+        assertThat(pluginResult, Matchers.is("success"));
+    }
+    
+    @Test
+    public void testApacheDubbo() throws IOException {
+        DubboTest dubboTest = HttpHelper.INSTANCE.getFromGateway("/dubbo/findById?id=1", DubboTest.class);
+        assertEquals("hello world shenyu Apache, findById", dubboTest.getName());
+        assertEquals("1", dubboTest.getId());
+    }
+    
+    @Test
+    public void testGrpc() throws Exception {
+        JsonArray jsonArray = new JsonArray();
+        JsonObject child = new JsonObject();
+        child.addProperty("message", "hello rpc");
+        jsonArray.add(child);
+        JsonObject request = new JsonObject();
+        request.add("data", jsonArray);
+        JsonArray response = HttpHelper.INSTANCE.postGateway("/grpc/echo", request, JsonArray.class);
+        Map<String, Object> result = GsonUtils.getInstance().toObjectMap(response.get(0).toString(), Object.class);
+        assertEquals("ReceivedHELLO", result.get("message"));
+    }
+    
+    @Test
+    public void testMotan() throws Exception {
+        MotanDTO request = new MotanDTO("shenyu");
+        Type returnType = new TypeToken<String>() {
+        }.getType();
+        String response = HttpHelper.INSTANCE.postGateway("/motan/demo/hello", request, returnType);
+        assertEquals("hello shenyu", response);
+    }
+    
+    @Test
+    public void testSofa() {
+        try {
+            SofaTestData response = HttpHelper.INSTANCE.getFromGateway("/sofa/findById?id=1001", new TypeToken<SofaTestData>() {
+            }.getType());
+            assertThat(response.getName(), Is.is("hello world shenyu Sofa, findById"));
+            assertThat(response.getId(), Is.is("1001"));
+        } catch (Throwable e) {
+            LOG.error("testSofa failed !", e);
+        }
+    }
+    
+    @AfterAll
+    public static void testIsOneThreadPool() throws IOException {
+        String spring = HttpHelper.INSTANCE.getFromGateway("/shenyu/getFromSpring", String.class);
+        String dubbo = HttpHelper.INSTANCE.getFromGateway("/shenyu/getFromDubbo", String.class);
+        assertEquals(spring, dubbo);
+        String grpc = HttpHelper.INSTANCE.getFromGateway("/shenyu/getFromGrpc", String.class);
+        assertEquals(spring, grpc);
+        String motan = HttpHelper.INSTANCE.getFromGateway("/shenyu/getFromMotan", String.class);
+        assertEquals(spring, motan);
+        try {
+            String sofa = HttpHelper.INSTANCE.getFromGateway("/shenyu/getFromSofa", String.class);
+            assertEquals(spring, sofa);
+        } catch (Throwable e) {
+            LOG.error("testIsOneThreadPool sofa failed !", e);
+        }
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/client/GrpcClientBuilder.java b/shenyu-plugin/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/client/GrpcClientBuilder.java
index bbbf32c09..6282f567a 100644
--- a/shenyu-plugin/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/client/GrpcClientBuilder.java
+++ b/shenyu-plugin/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/client/GrpcClientBuilder.java
@@ -70,7 +70,12 @@ public final class GrpcClientBuilder {
         return new ShenyuGrpcClient(channel);
     }
 
-    private static Executor buildExecutor() {
+    /**
+     * get thread pool, just for integrated test.
+     *
+     * @return the thread pool
+     */
+    public static Executor buildExecutor() {
         GrpcRegisterConfig config = Singleton.INST.get(GrpcRegisterConfig.class);
         if (null == config) {
             return null;
diff --git a/shenyu-plugin/shenyu-plugin-motan/src/main/java/org/apache/shenyu/plugin/motan/proxy/MotanProxyService.java b/shenyu-plugin/shenyu-plugin-motan/src/main/java/org/apache/shenyu/plugin/motan/proxy/MotanProxyService.java
index 3c7c95408..5e33cb14f 100644
--- a/shenyu-plugin/shenyu-plugin-motan/src/main/java/org/apache/shenyu/plugin/motan/proxy/MotanProxyService.java
+++ b/shenyu-plugin/shenyu-plugin-motan/src/main/java/org/apache/shenyu/plugin/motan/proxy/MotanProxyService.java
@@ -149,4 +149,13 @@ public class MotanProxyService {
                         queueSize > 0 ? new LinkedBlockingQueue<>(queueSize) : new SynchronousQueue<>(), factory);
         }
     }
+
+    /**
+     * get thread pool, just for integrated test.
+     *
+     * @return the thread pool
+     */
+    public ExecutorService getThreadPool() {
+        return threadPool;
+    }
 }
diff --git a/shenyu-plugin/shenyu-plugin-sofa/src/main/java/org/apache/shenyu/plugin/sofa/cache/ApplicationConfigCache.java b/shenyu-plugin/shenyu-plugin-sofa/src/main/java/org/apache/shenyu/plugin/sofa/cache/ApplicationConfigCache.java
index 27c9a6bf7..1715a1edc 100644
--- a/shenyu-plugin/shenyu-plugin-sofa/src/main/java/org/apache/shenyu/plugin/sofa/cache/ApplicationConfigCache.java
+++ b/shenyu-plugin/shenyu-plugin-sofa/src/main/java/org/apache/shenyu/plugin/sofa/cache/ApplicationConfigCache.java
@@ -59,15 +59,15 @@ import java.util.concurrent.TimeUnit;
 public final class ApplicationConfigCache {
     
     private static final Logger LOG = LoggerFactory.getLogger(ApplicationConfigCache.class);
-
+    
     private final ThreadFactory factory = ShenyuThreadFactory.create("shenyu-sofa", true);
-
+    
     private ApplicationConfig applicationConfig;
     
     private RegistryConfig registryConfig;
-
+    
     private ThreadPoolExecutor threadPool;
-
+    
     private final LoadingCache<String, ConsumerConfig<GenericService>> cache = CacheBuilder.newBuilder()
             .maximumSize(Constants.CACHE_MAX_COUNT)
             .removalListener(notification -> {
@@ -128,7 +128,7 @@ public final class ApplicationConfigCache {
             Optional.ofNullable(threadPool).ifPresent(this::setAsyncRuntimeThreadPool);
         }
     }
-
+    
     /**
      * Set sofa asyncRuntime thread pool.
      */
@@ -137,7 +137,7 @@ public final class ApplicationConfigCache {
         ReflectionUtils.makeAccessible(field);
         ReflectionUtils.setField(field, AsyncRuntime.class, threadPool);
     }
-
+    
     /**
      * Init thread pool.
      */
@@ -269,6 +269,15 @@ public final class ApplicationConfigCache {
         cache.invalidateAll();
     }
     
+    /**
+     * get thread pool, just for integrated test.
+     *
+     * @return the thread pool
+     */
+    public ThreadPoolExecutor getThreadPool() {
+        return threadPool;
+    }
+    
     /**
      * The type Application config cache instance.
      */
diff --git a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-httpclient/src/main/java/org/apache/shenyu/springboot/starter/plugin/httpclient/HttpClientPluginConfiguration.java b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-httpclient/src/main/java/org/apache/shenyu/springboot/starter/plugin/httpclient/HttpClientPluginConfiguration.java
index 0178c4990..c522ccb8f 100644
--- a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-httpclient/src/main/java/org/apache/shenyu/springboot/starter/plugin/httpclient/HttpClientPluginConfiguration.java
+++ b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-httpclient/src/main/java/org/apache/shenyu/springboot/starter/plugin/httpclient/HttpClientPluginConfiguration.java
@@ -72,7 +72,7 @@ public class HttpClientPluginConfiguration {
      * @return the http client loop resource
      */
     @Bean
-    @ConditionalOnProperty("shenyu.httpclient.threadPool.prefix")
+    @ConditionalOnProperty("shenyu.httpclient.thread-pool.prefix")
     public LoopResources httpClientLoopResource(final HttpClientProperties properties) {
         HttpClientProperties.ThreadPool threadPool = properties.getThreadPool();
         return LoopResources.create(threadPool.getPrefix(), threadPool.getSelectCount(),
diff --git a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-motan/src/main/java/org/apache/shenyu/springboot/starter/plugin/motan/MotanPluginConfiguration.java b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-motan/src/main/java/org/apache/shenyu/springboot/starter/plugin/motan/MotanPluginConfiguration.java
index 3cc90b91f..7edd63b31 100644
--- a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-motan/src/main/java/org/apache/shenyu/springboot/starter/plugin/motan/MotanPluginConfiguration.java
+++ b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-motan/src/main/java/org/apache/shenyu/springboot/starter/plugin/motan/MotanPluginConfiguration.java
@@ -40,14 +40,25 @@ import org.springframework.context.annotation.Configuration;
 @ConditionalOnProperty(value = {"shenyu.plugins.motan.enabled"}, havingValue = "true", matchIfMissing = true)
 public class MotanPluginConfiguration {
 
+    /**
+     * Motan proxy service.
+     *
+     * @return the motan proxy service
+     */
+    @Bean
+    public MotanProxyService motanProxyService() {
+        return new MotanProxyService();
+    }
+
     /**
      * Motan plugin.
      *
+     * @param motanProxyService the motan proxy service
      * @return the shenyu plugin
      */
     @Bean
-    public ShenyuPlugin motanPlugin() {
-        return new MotanPlugin(new MotanProxyService());
+    public ShenyuPlugin motanPlugin(final MotanProxyService motanProxyService) {
+        return new MotanPlugin(motanProxyService);
     }
 
     /**
diff --git a/shenyu-web/src/main/java/org/apache/shenyu/web/configuration/ShenyuThreadPoolConfiguration.java b/shenyu-web/src/main/java/org/apache/shenyu/web/configuration/ShenyuThreadPoolConfiguration.java
index 31cf19f00..dff73a31b 100644
--- a/shenyu-web/src/main/java/org/apache/shenyu/web/configuration/ShenyuThreadPoolConfiguration.java
+++ b/shenyu-web/src/main/java/org/apache/shenyu/web/configuration/ShenyuThreadPoolConfiguration.java
@@ -54,7 +54,7 @@ public class ShenyuThreadPoolConfiguration {
      */
     @Bean
     @ConditionalOnMissingBean(TaskQueue.class)
-    @ConditionalOnProperty("shenyu.sharedPool.maxWorkQueueMemory")
+    @ConditionalOnProperty("shenyu.shared-pool.max-work-queue-memory")
     public TaskQueue<Runnable> memoryLimitedTaskQueue(final ShenyuConfig shenyuConfig) {
         final Instrumentation instrumentation = ByteBuddyAgent.install();
         final ShenyuConfig.SharedPool sharedPool = shenyuConfig.getSharedPool();
@@ -73,7 +73,7 @@ public class ShenyuThreadPoolConfiguration {
      */
     @Bean
     @ConditionalOnMissingBean(TaskQueue.class)
-    @ConditionalOnProperty("shenyu.sharedPool.maxFreeMemory")
+    @ConditionalOnProperty("shenyu.shared-pool.max-free-memory")
     public TaskQueue<Runnable> memorySafeTaskQueue(final ShenyuConfig shenyuConfig) {
         final ShenyuConfig.SharedPool sharedPool = shenyuConfig.getSharedPool();
         final Integer maxFreeMemory = sharedPool.getMaxFreeMemory();
@@ -91,7 +91,7 @@ public class ShenyuThreadPoolConfiguration {
      * @return the shenyu thread pool executor
      */
     @Bean
-    @ConditionalOnProperty(name = "shenyu.sharedPool.enable", havingValue = "true")
+    @ConditionalOnProperty(name = "shenyu.shared-pool.enable", havingValue = "true")
     public ShenyuThreadPoolExecutor shenyuThreadPoolExecutor(final ShenyuConfig shenyuConfig,
                                                              final ObjectProvider<TaskQueue<Runnable>> provider) {
         final ShenyuConfig.SharedPool sharedPool = shenyuConfig.getSharedPool();