You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shenyu.apache.org by zh...@apache.org on 2024/02/20 09:59:18 UTC

(shenyu) branch master updated: fix rewrite integrated test (#5445)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 8886e31efc fix rewrite integrated test (#5445)
8886e31efc is described below

commit 8886e31efc858b75ba1a069a8186f82f5871799f
Author: loongs-zhang <zh...@apache.org>
AuthorDate: Tue Feb 20 17:59:12 2024 +0800

    fix rewrite integrated test (#5445)
    
    * fix rewrite integrated test
    
    * fix test order
---
 .github/workflows/integrated-test.yml              |   1 +
 shenyu-integrated-test/pom.xml                     |   1 +
 .../script/services.list                           |   1 -
 .../combination/RequestAndResponsePluginTest.java  | 126 +----------------
 .../Dockerfile}                                    |  22 +--
 .../docker-compose.yml                             | 135 ++++++++++++++++++
 .../shenyu-integrated-test-rewrite/pom.xml         | 139 ++++++++++++++++++
 .../script/healthcheck.sh                          |  36 +++++
 .../script/services.list                           |   5 -
 .../test/rewrite/RewriteIntegratedBootstrap.java   |  37 +++++
 .../src/main/resources/application-local.yml       |  59 ++++++++
 .../src/main/resources/application.yml             |  18 +++
 .../rewrite/ContextPathAndRewritePluginTest.java   | 157 +++++++++++++++++++++
 13 files changed, 603 insertions(+), 134 deletions(-)

diff --git a/.github/workflows/integrated-test.yml b/.github/workflows/integrated-test.yml
index 1714d1d677..59b730519a 100644
--- a/.github/workflows/integrated-test.yml
+++ b/.github/workflows/integrated-test.yml
@@ -35,6 +35,7 @@ jobs:
           - shenyu-integrated-test-spring-cloud
           - shenyu-integrated-test-sofa
           - shenyu-integrated-test-websocket
+          - shenyu-integrated-test-rewrite
           - shenyu-integrated-test-combination
           - shenyu-integrated-test-sdk-apache-dubbo
           - shenyu-integrated-test-sdk-http
diff --git a/shenyu-integrated-test/pom.xml b/shenyu-integrated-test/pom.xml
index 8e45463daf..01e568e13c 100644
--- a/shenyu-integrated-test/pom.xml
+++ b/shenyu-integrated-test/pom.xml
@@ -39,6 +39,7 @@
         <module>shenyu-integrated-test-motan</module>
         <module>shenyu-integrated-test-sofa</module>
         <module>shenyu-integrated-test-websocket</module>
+        <module>shenyu-integrated-test-rewrite</module>
         <module>shenyu-integrated-test-combination</module>
         <module>shenyu-integrated-test-sdk-apache-dubbo</module>
         <module>shenyu-integrated-test-sdk-alibaba-dubbo</module>
diff --git a/shenyu-integrated-test/shenyu-integrated-test-combination/script/services.list b/shenyu-integrated-test/shenyu-integrated-test-combination/script/services.list
index a2d019eaef..369dd0c72d 100644
--- a/shenyu-integrated-test/shenyu-integrated-test-combination/script/services.list
+++ b/shenyu-integrated-test/shenyu-integrated-test-combination/script/services.list
@@ -16,7 +16,6 @@
 
 http://localhost:9095/actuator/health
 http://localhost:8189/test/path/123?name=tom
-http://localhost:8190/actuator/health
 http://localhost:8011/actuator/health
 http://localhost:55290/test/grpc/hello
 http://localhost:8081/actuator/health
diff --git a/shenyu-integrated-test/shenyu-integrated-test-combination/src/test/java/org/apache/shenyu/integrated/test/combination/RequestAndResponsePluginTest.java b/shenyu-integrated-test/shenyu-integrated-test-combination/src/test/java/org/apache/shenyu/integrated/test/combination/RequestAndResponsePluginTest.java
index 480d0404bc..a6a8327b79 100644
--- a/shenyu-integrated-test/shenyu-integrated-test-combination/src/test/java/org/apache/shenyu/integrated/test/combination/RequestAndResponsePluginTest.java
+++ b/shenyu-integrated-test/shenyu-integrated-test-combination/src/test/java/org/apache/shenyu/integrated/test/combination/RequestAndResponsePluginTest.java
@@ -19,43 +19,31 @@ package org.apache.shenyu.integrated.test.combination;
 
 import com.google.gson.JsonObject;
 import org.apache.shenyu.common.dto.ConditionData;
-import org.apache.shenyu.common.dto.convert.rule.RewriteHandle;
 import org.apache.shenyu.common.enums.OperatorEnum;
 import org.apache.shenyu.common.enums.ParamTypeEnum;
 import org.apache.shenyu.common.enums.PluginEnum;
 import org.apache.shenyu.common.utils.JsonUtils;
 import org.apache.shenyu.integratedtest.common.AbstractPluginDataInit;
-import org.apache.shenyu.integratedtest.common.dto.OrderDTO;
 import org.apache.shenyu.integratedtest.common.dto.UserDTO;
 import org.apache.shenyu.integratedtest.common.helper.HttpHelper;
 import org.apache.shenyu.plugin.cryptor.handler.CryptorRuleHandler;
 import org.apache.shenyu.plugin.cryptor.strategy.MapTypeEnum;
 import org.apache.shenyu.plugin.cryptor.strategy.RsaStrategy;
 import org.apache.shenyu.web.controller.LocalPluginController;
-import org.hamcrest.CoreMatchers;
-import org.junit.jupiter.api.MethodOrderer;
-import org.junit.jupiter.api.Order;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestMethodOrder;
 
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Base64;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertNull;
 
 /**
  * The integrated test for combination plugins about request and response.
  */
-@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
 public final class RequestAndResponsePluginTest extends AbstractPluginDataInit {
 
     private static final String RSA_PRIVATE_KEY = "MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAvEXyUDh5qliWhM6KrpTFi1OXumoJQzMfSr8XjfKa/kHKb1uxr7N8lJd3I850m2IYrxckFCQW6nrnRKctm"
@@ -72,7 +60,6 @@ public final class RequestAndResponsePluginTest extends AbstractPluginDataInit {
 
     private static final RsaStrategy RSA_STRATEGY = new RsaStrategy();
 
-    @Order(1)
     @Test
     public void testDecryptRequestAndEncryptResponse() throws Exception {
         setupCryptorRequest("data", "decrypt", MapTypeEnum.FIELD.getMapType());
@@ -91,8 +78,7 @@ public final class RequestAndResponsePluginTest extends AbstractPluginDataInit {
         cleanCryptorRequest();
         cleanCryptorResponse();
     }
-    
-    @Order(2)
+
     @Test
     public void testDecryptRequestAndEncryptResponseField() throws Exception {
         setupCryptorRequest("data", "decrypt", MapTypeEnum.FIELD.getMapType());
@@ -110,8 +96,7 @@ public final class RequestAndResponsePluginTest extends AbstractPluginDataInit {
         cleanCryptorRequest();
         cleanCryptorResponse();
     }
-    
-    @Order(3)
+
     @Test
     public void testEncryptRequestAndDecryptResponse() throws Exception {
         setupCryptorRequest("userName", "encrypt", MapTypeEnum.ALL.getMapType());
@@ -127,8 +112,7 @@ public final class RequestAndResponsePluginTest extends AbstractPluginDataInit {
         cleanCryptorRequest();
         cleanCryptorResponse();
     }
-    
-    @Order(4)
+
     @Test
     public void testEncryptRequestAndDecryptResponseField() throws Exception {
         setupCryptorRequest("userName", "encrypt", MapTypeEnum.ALL.getMapType());
@@ -143,102 +127,6 @@ public final class RequestAndResponsePluginTest extends AbstractPluginDataInit {
         cleanCryptorRequest();
         cleanCryptorResponse();
     }
-    
-    @Order(5)
-    @Test
-    public void testRewriteCrossApplication() throws IOException {
-        OrderDTO orderDTO = HttpHelper.INSTANCE.getFromGateway("/http/order/findById?id=1", OrderDTO.class);
-        assertEquals("1", orderDTO.getId());
-        assertEquals("hello world findById", orderDTO.getName());
-        
-        orderDTO = HttpHelper.INSTANCE.getFromGateway("/order/order/findById?id=3", OrderDTO.class);
-        assertNotNull(orderDTO);
-        assertNull(orderDTO.getId());
-        assertNull(orderDTO.getName());
-        
-        setupRewriteContextPath();
-        
-        OrderDTO result = HttpHelper.INSTANCE.getFromGateway("/order/order/findById?id=1", OrderDTO.class);
-        assertEquals("1", result.getId());
-        assertEquals("hello world findById", result.getName());
-        
-//        assertThat(cleanPluginData(PluginEnum.CONTEXT_PATH.getName()), is("success"));
-    }
-    
-    @Order(6)
-    @Test
-    public void testRewriteCrossPlugin() throws IOException {
-        OrderDTO orderDTO = HttpHelper.INSTANCE.getFromGateway("/http/order/findById?id=1", OrderDTO.class);
-        assertEquals("1", orderDTO.getId());
-        assertEquals("hello world findById", orderDTO.getName());
-        
-        setupRewrite();
-        
-        Map<String, Object> request = new HashMap<>();
-        OrderDTO result = HttpHelper.INSTANCE.getFromGateway("/dubbo/findById?id=2", request, OrderDTO.class);
-        assertEquals("2", result.getId());
-        assertEquals("hello world findById", result.getName());
-        
-        assertThat(cleanPluginData(PluginEnum.CONTEXT_PATH.getName()), is("success"));
-        assertThat(cleanPluginData(PluginEnum.REWRITE.getName()), is("success"));
-    }
-    
-    private void setupRewrite() throws IOException {
-        String pluginResult = initPlugin(PluginEnum.CONTEXT_PATH.getName(), "");
-        assertThat(pluginResult, CoreMatchers.is("success"));
-        LocalPluginController.RuleLocalData ruleLocalData = new LocalPluginController.RuleLocalData();
-        ruleLocalData.setRuleHandler("{\"contextPath\":\"/dubbo\", \"addPrefix\":\"\", \"rewriteContextPath\":\"/http\", \"percentage\":100}");
-        ConditionData conditionData = new ConditionData();
-        conditionData.setParamType(ParamTypeEnum.URI.getName());
-        conditionData.setOperator(OperatorEnum.EQ.getAlias());
-        conditionData.setParamValue("/dubbo/findById");
-        ruleLocalData.setConditionDataList(Collections.singletonList(conditionData));
-        String message = initSelectorAndRules(PluginEnum.CONTEXT_PATH.getName(), "", 0,
-                buildSelectorConditionList("/dubbo/findById"), Collections.singletonList(ruleLocalData));
-        assertThat(message, is("success"));
-        
-        pluginResult = initPlugin(PluginEnum.REWRITE.getName(), "");
-        assertThat(pluginResult, is("success"));
-        String selectorAndRulesResult = initSelectorAndRules(PluginEnum.REWRITE.getName(), "", 0,
-                buildSelectorConditionList("/http/findById"), buildRewriteRuleLocalDataList());
-        assertThat(selectorAndRulesResult, is("success"));
-    }
-    
-    private static List<LocalPluginController.RuleLocalData> buildRewriteRuleLocalDataList() {
-        final LocalPluginController.RuleLocalData ruleLocalData = new LocalPluginController.RuleLocalData();
-        
-        ConditionData conditionData = new ConditionData();
-        conditionData.setParamType(ParamTypeEnum.URI.getName());
-        conditionData.setOperator(OperatorEnum.EQ.getAlias());
-        conditionData.setParamName("/");
-        conditionData.setParamValue("/http/findById");
-        ruleLocalData.setConditionDataList(Collections.singletonList(conditionData));
-        ruleLocalData.setRuleName("rewriteMetaData");
-        
-        RewriteHandle rewriteHandle = new RewriteHandle();
-        rewriteHandle.setRegex("/http/findById");
-        rewriteHandle.setReplace("/order/findById");
-        rewriteHandle.setRewriteMetaData(true);
-        rewriteHandle.setPercentage(100);
-        
-        ruleLocalData.setRuleHandler(JsonUtils.toJson(rewriteHandle));
-        return Collections.singletonList(ruleLocalData);
-    }
-    
-    private void setupRewriteContextPath() throws IOException {
-        String pluginResult = initPlugin(PluginEnum.CONTEXT_PATH.getName(), "");
-        assertThat(pluginResult, CoreMatchers.is("success"));
-        LocalPluginController.RuleLocalData ruleLocalData = new LocalPluginController.RuleLocalData();
-        ruleLocalData.setRuleHandler("{\"contextPath\":\"/order\", \"addPrefix\":\"\", \"rewriteContextPath\":\"/http\", \"percentage\":100}");
-        ConditionData conditionData = new ConditionData();
-        conditionData.setParamType(ParamTypeEnum.URI.getName());
-        conditionData.setOperator(OperatorEnum.MATCH.getAlias());
-        conditionData.setParamValue("/order/order/findById");
-        ruleLocalData.setConditionDataList(Collections.singletonList(conditionData));
-        String message = initSelectorAndRules(PluginEnum.CONTEXT_PATH.getName(), "",
-                buildSelectorConditionList("/order/order/findById"), Collections.singletonList(ruleLocalData));
-        assertThat(message, is("success"));
-    }
 
     private List<LocalPluginController.RuleLocalData> buildRuleLocalDataList(final String fieldNames, 
                                                                              final String way,
@@ -268,11 +156,11 @@ public final class RequestAndResponsePluginTest extends AbstractPluginDataInit {
         return ruleLocalData;
     }
 
-    private List<ConditionData> buildSelectorConditionList(final String paramValue) {
+    private List<ConditionData> buildSelectorConditionList() {
         ConditionData conditionData = new ConditionData();
         conditionData.setParamType(ParamTypeEnum.URI.getName());
         conditionData.setOperator(OperatorEnum.EQ.getAlias());
-        conditionData.setParamValue(paramValue);
+        conditionData.setParamValue(TEST_PATH);
         return Collections.singletonList(conditionData);
     }
 
@@ -280,7 +168,7 @@ public final class RequestAndResponsePluginTest extends AbstractPluginDataInit {
         String requestPluginResult = initPlugin(PluginEnum.CRYPTOR_REQUEST.getName(), null);
         assertThat(requestPluginResult, is("success"));
         String initSelectorAndRules = initSelectorAndRules(PluginEnum.CRYPTOR_REQUEST.getName(),
-                "", buildSelectorConditionList(TEST_PATH), buildRuleLocalDataList(fieldNames, way, mapType));
+                "", buildSelectorConditionList(), buildRuleLocalDataList(fieldNames, way, mapType));
         assertThat(initSelectorAndRules, is("success"));
     }
 
@@ -288,7 +176,7 @@ public final class RequestAndResponsePluginTest extends AbstractPluginDataInit {
         String responsePluginResult = initPlugin(PluginEnum.CRYPTOR_RESPONSE.getName(), null);
         assertThat(responsePluginResult, is("success"));
         String cryptorResponseResult = initSelectorAndRules(PluginEnum.CRYPTOR_RESPONSE.getName(),
-                "", buildSelectorConditionList(TEST_PATH), buildRuleLocalDataList(fieldNames, way, mapType));
+                "", buildSelectorConditionList(), buildRuleLocalDataList(fieldNames, way, mapType));
         assertThat(cryptorResponseResult, is("success"));
     }
 
diff --git a/shenyu-integrated-test/shenyu-integrated-test-combination/script/services.list b/shenyu-integrated-test/shenyu-integrated-test-rewrite/Dockerfile
similarity index 69%
copy from shenyu-integrated-test/shenyu-integrated-test-combination/script/services.list
copy to shenyu-integrated-test/shenyu-integrated-test-rewrite/Dockerfile
index a2d019eaef..3bf968dc0f 100644
--- a/shenyu-integrated-test/shenyu-integrated-test-combination/script/services.list
+++ b/shenyu-integrated-test/shenyu-integrated-test-rewrite/Dockerfile
@@ -14,12 +14,16 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-http://localhost:9095/actuator/health
-http://localhost:8189/test/path/123?name=tom
-http://localhost:8190/actuator/health
-http://localhost:8011/actuator/health
-http://localhost:55290/test/grpc/hello
-http://localhost:8081/actuator/health
-http://localhost:8002/actuator/health
-http://localhost:28011/actuator/health
-http://localhost:9195/actuator/health
+FROM openjdk:8-jre-alpine
+
+ENV APP_NAME shenyu-integrated-test-rewrite
+ENV LOCAL_PATH /opt/${APP_NAME}
+
+RUN mkdir -p ${LOCAL_PATH}
+
+ADD target/${APP_NAME}.jar ${LOCAL_PATH}
+
+WORKDIR ${LOCAL_PATH}
+EXPOSE 9195
+
+CMD java -jar ${APP_NAME}.jar
diff --git a/shenyu-integrated-test/shenyu-integrated-test-rewrite/docker-compose.yml b/shenyu-integrated-test/shenyu-integrated-test-rewrite/docker-compose.yml
new file mode 100644
index 0000000000..02394a5fb8
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-rewrite/docker-compose.yml
@@ -0,0 +1,135 @@
+# 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.
+version: "3.9"
+services:
+  shenyu-zk:
+    container_name: shenyu-zk
+    image: zookeeper:latest
+    restart: always
+    networks:
+      - shenyu
+    expose:
+      - 2181
+    healthcheck:
+      test: [ "CMD-SHELL", "echo srvr | nc localhost 2181" ]
+      interval: 10s
+      timeout: 5s
+      retries: 3
+      start_period: 30s
+
+  shenyu-redis:
+    image: redis:latest
+    container_name: shenyu-redis
+    restart: always
+    command: redis-server --requirepass abc
+    networks:
+      - shenyu
+    healthcheck:
+      test: [ "CMD", "redis-cli", "ping" ]
+
+  shenyu-examples-http:
+    deploy:
+      resources:
+        limits:
+          memory: 2048M
+    container_name: shenyu-examples-http
+    image: shenyu-examples-http:latest
+    restart: always
+    environment:
+      - shenyu.register.serverLists=http://shenyu-admin:9095
+    healthcheck:
+      test: ["CMD-SHELL", "wget -q -O - http://shenyu-examples-http:8189/actuator/health | grep UP || exit 1"]
+      timeout: 2s
+      retries: 30
+    ports:
+      - "8189:8189"
+    depends_on:
+      shenyu-integrated-test-rewrite:
+        condition: service_healthy
+    networks:
+      - shenyu
+
+  shenyu-examples-apache-dubbo-service:
+    deploy:
+      resources:
+        limits:
+          memory: 2048M
+    container_name: shenyu-examples-apache-dubbo-service
+    image: shenyu-examples-apache-dubbo-service:latest
+    restart: always
+    healthcheck:
+      test: ["CMD-SHELL", "wget -q -O - http://localhost:8011/actuator/health | grep UP || exit 1"]
+      timeout: 2s
+      retries: 3
+      start_period: 5s
+    ports:
+      - "8011:8011"
+      - "20888:20888"
+    networks:
+      - shenyu
+    depends_on:
+      shenyu-integrated-test-rewrite:
+        condition: service_healthy
+    environment:
+      - dubbo.registry.address=zookeeper://shenyu-zk:2181
+      - shenyu.register.serverLists=http://shenyu-admin:9095
+
+  shenyu-admin:
+    image: apache/shenyu-admin:latest
+    container_name: shenyu-admin
+    restart: always
+    networks:
+      - shenyu
+    depends_on:
+      shenyu-redis:
+        condition: service_healthy
+    ports:
+      - "9095:9095"
+    environment:
+      - SPRING_PROFILES_ACTIVE=h2
+      - shenyu.database.init_script=sql-script/h2/schema.sql
+    healthcheck:
+      test: ["CMD-SHELL", "wget -q -O - http://shenyu-admin:9095/actuator/health | grep UP || exit 1"]
+      timeout: 2s
+      retries: 30
+
+  shenyu-integrated-test-rewrite:
+    container_name: shenyu-integrated-test-rewrite
+    image: apache/shenyu-integrated-test-rewrite:latest
+    restart: always
+    deploy:
+      resources:
+        limits:
+          memory: 2048M
+    environment:
+      - shenyu.sync.websocket.urls=ws://shenyu-admin:9095/websocket
+    depends_on:
+      shenyu-zk:
+        condition: service_healthy
+      shenyu-admin:
+        condition: service_healthy
+    ports:
+      - "9195:9195"
+    networks:
+      - shenyu
+    healthcheck:
+      test: [ "CMD", "wget", "http://shenyu-integrated-test-rewrite:9195/actuator/health" ]
+      timeout: 2s
+      retries: 30
+
+networks:
+  shenyu:
+    name: shenyu
diff --git a/shenyu-integrated-test/shenyu-integrated-test-rewrite/pom.xml b/shenyu-integrated-test/shenyu-integrated-test-rewrite/pom.xml
new file mode 100644
index 0000000000..62eb495f44
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-rewrite/pom.xml
@@ -0,0 +1,139 @@
+<?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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>shenyu-integrated-test</artifactId>
+        <groupId>org.apache.shenyu</groupId>
+        <version>2.7.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>shenyu-integrated-test-rewrite</artifactId>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.shenyu</groupId>
+            <artifactId>shenyu-integrated-test-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.shenyu</groupId>
+            <artifactId>shenyu-spring-boot-starter-plugin-divide</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!--shenyu apache dubbo plugin start-->
+        <dependency>
+            <groupId>org.apache.shenyu</groupId>
+            <artifactId>shenyu-spring-boot-starter-plugin-apache-dubbo</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo</artifactId>
+            <version>3.1.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-dependencies-zookeeper</artifactId>
+            <version>3.1.1</version>
+            <type>pom</type>
+        </dependency>
+        <!--shenyu apache dubbo plugin end-->
+
+        <!-- shenyu rewrite plugin start-->
+        <dependency>
+            <groupId>org.apache.shenyu</groupId>
+            <artifactId>shenyu-spring-boot-starter-plugin-rewrite</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <!-- shenyu rewrite plugin end-->
+
+    </dependencies>
+
+    <profiles>
+        <profile>
+            <id>it</id>
+            <properties>
+                <docker.buildArg.APP_NAME>shenyu-integrated-test-rewrite</docker.buildArg.APP_NAME>
+                <docker.image.tag.repo>apache/shenyu-integrated-test-rewrite</docker.image.tag.repo>
+                <docker.image.tag.tagName>latest</docker.image.tag.tagName>
+            </properties>
+            <build>
+                <finalName>shenyu-integrated-test-rewrite</finalName>
+                <plugins>
+                    <plugin>
+                        <groupId>org.springframework.boot</groupId>
+                        <artifactId>spring-boot-maven-plugin</artifactId>
+                        <version>${spring-boot.version}</version>
+                        <executions>
+                            <execution>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>repackage</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <mainClass>org.apache.shenyu.integrated.test.rewrite.RewriteIntegratedBootstrap</mainClass>
+                            <executable>true</executable>
+                        </configuration>
+                    </plugin>
+                    <plugin>
+                        <groupId>io.fabric8</groupId>
+                        <artifactId>docker-maven-plugin</artifactId>
+                        <version>${docker-maven-plugin.version}</version>
+                        <configuration>
+                            <images>
+                                <image>
+                                    <name>apache/shenyu-integrated-test-rewrite</name>
+                                    <build>
+                                        <contextDir>${project.basedir}</contextDir>
+                                    </build>
+                                </image>
+                            </images>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <id>start</id>
+                                <goals>
+                                    <goal>build</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <configuration>
+                            <skipTests>false</skipTests>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
diff --git a/shenyu-integrated-test/shenyu-integrated-test-rewrite/script/healthcheck.sh b/shenyu-integrated-test/shenyu-integrated-test-rewrite/script/healthcheck.sh
new file mode 100644
index 0000000000..22a76034ab
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-rewrite/script/healthcheck.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+#
+# 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.
+#
+
+PRGDIR=`dirname "$0"`
+for service in `grep -v -E "^$|^#" ${PRGDIR}/services.list`
+do
+    for loop in `seq 1 30`
+    do
+        status=`curl -o /dev/null -s -w %{http_code} $service`
+        echo -e "curl $service response $status"
+
+        if [ $status -eq 200  ]; then
+            break
+        fi
+
+        sleep 2
+    done
+done
+
+sleep 3
+echo -e "\n-------------------"
diff --git a/shenyu-integrated-test/shenyu-integrated-test-combination/script/services.list b/shenyu-integrated-test/shenyu-integrated-test-rewrite/script/services.list
similarity index 83%
copy from shenyu-integrated-test/shenyu-integrated-test-combination/script/services.list
copy to shenyu-integrated-test/shenyu-integrated-test-rewrite/script/services.list
index a2d019eaef..6deb2a6ee3 100644
--- a/shenyu-integrated-test/shenyu-integrated-test-combination/script/services.list
+++ b/shenyu-integrated-test/shenyu-integrated-test-rewrite/script/services.list
@@ -16,10 +16,5 @@
 
 http://localhost:9095/actuator/health
 http://localhost:8189/test/path/123?name=tom
-http://localhost:8190/actuator/health
 http://localhost:8011/actuator/health
-http://localhost:55290/test/grpc/hello
-http://localhost:8081/actuator/health
-http://localhost:8002/actuator/health
-http://localhost:28011/actuator/health
 http://localhost:9195/actuator/health
diff --git a/shenyu-integrated-test/shenyu-integrated-test-rewrite/src/main/java/org/apache/shenyu/integrated/test/rewrite/RewriteIntegratedBootstrap.java b/shenyu-integrated-test/shenyu-integrated-test-rewrite/src/main/java/org/apache/shenyu/integrated/test/rewrite/RewriteIntegratedBootstrap.java
new file mode 100644
index 0000000000..9ae95785a7
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-rewrite/src/main/java/org/apache/shenyu/integrated/test/rewrite/RewriteIntegratedBootstrap.java
@@ -0,0 +1,37 @@
+/*
+ * 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.rewrite;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * The rewrite integrated bootstrap.
+ */
+@SpringBootApplication
+public class RewriteIntegratedBootstrap {
+
+    /**
+     * main method of App.
+     *
+     * @param args args
+     */
+    public static void main(final String[] args) {
+        SpringApplication.run(RewriteIntegratedBootstrap.class);
+    }
+}
diff --git a/shenyu-integrated-test/shenyu-integrated-test-rewrite/src/main/resources/application-local.yml b/shenyu-integrated-test/shenyu-integrated-test-rewrite/src/main/resources/application-local.yml
new file mode 100644
index 0000000000..8c41677851
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-rewrite/src/main/resources/application-local.yml
@@ -0,0 +1,59 @@
+# 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.
+
+server:
+  port: 9195
+  address: 0.0.0.0
+
+spring:
+  main:
+    allow-bean-definition-overriding: true
+  application:
+    name: shenyu-bootstrap
+
+management:
+  health:
+    defaults:
+      enabled: false
+
+shenyu:
+  switchConfig:
+    local: true
+  cross:
+    enabled: true
+  sync:
+    websocket:
+      urls: ws://localhost:9095/websocket
+      allowOrigin: ws://localhost:9195
+  exclude:
+    enabled: true
+    paths:
+      - /favicon.ico
+      - /actuator/health
+  local:
+    enabled: true
+    sha512Key: "BA3253876AED6BC22D4A6FF53D8406C6AD864195ED144AB5C87621B6C233B548BAEAE6956DF346EC8C17F5EA10F35EE3CBC514797ED7DDD3145464E2A0BAB413"
+  sharedPool:
+    enable: true
+
+logging:
+  level:
+    root: info
+    org.springframework.boot: info
+    org.apache.ibatis: info
+    org.apache.shenyu.bonuspoint: info
+    org.apache.shenyu.lottery: info
+    org.apache.shenyu: info
+
diff --git a/shenyu-integrated-test/shenyu-integrated-test-rewrite/src/main/resources/application.yml b/shenyu-integrated-test/shenyu-integrated-test-rewrite/src/main/resources/application.yml
new file mode 100644
index 0000000000..393ad24df1
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-rewrite/src/main/resources/application.yml
@@ -0,0 +1,18 @@
+# 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.
+
+spring:
+  profiles:
+    active: local
diff --git a/shenyu-integrated-test/shenyu-integrated-test-rewrite/src/test/java/org/apache/shenyu/integrated/test/rewrite/ContextPathAndRewritePluginTest.java b/shenyu-integrated-test/shenyu-integrated-test-rewrite/src/test/java/org/apache/shenyu/integrated/test/rewrite/ContextPathAndRewritePluginTest.java
new file mode 100644
index 0000000000..8e54b1dc33
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-rewrite/src/test/java/org/apache/shenyu/integrated/test/rewrite/ContextPathAndRewritePluginTest.java
@@ -0,0 +1,157 @@
+/*
+ * 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.rewrite;
+
+import org.apache.shenyu.common.dto.ConditionData;
+import org.apache.shenyu.common.dto.convert.rule.RewriteHandle;
+import org.apache.shenyu.common.enums.OperatorEnum;
+import org.apache.shenyu.common.enums.ParamTypeEnum;
+import org.apache.shenyu.common.enums.PluginEnum;
+import org.apache.shenyu.common.utils.JsonUtils;
+import org.apache.shenyu.integratedtest.common.AbstractPluginDataInit;
+import org.apache.shenyu.integratedtest.common.dto.OrderDTO;
+import org.apache.shenyu.integratedtest.common.helper.HttpHelper;
+import org.apache.shenyu.web.controller.LocalPluginController;
+import org.hamcrest.CoreMatchers;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+/**
+ * The integrated test for combination plugins about contextPath and rewrite.
+ */
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+public class ContextPathAndRewritePluginTest extends AbstractPluginDataInit {
+    
+    @Order(1)
+    @Test
+    public void testRewriteCrossApplication() throws IOException {
+        OrderDTO orderDTO = HttpHelper.INSTANCE.getFromGateway("/http/order/findById?id=1", OrderDTO.class);
+        assertEquals("1", orderDTO.getId());
+        assertEquals("hello world findById", orderDTO.getName());
+        
+        orderDTO = HttpHelper.INSTANCE.getFromGateway("/order/order/findById?id=3", OrderDTO.class);
+        assertNotNull(orderDTO);
+        assertNull(orderDTO.getId());
+        assertNull(orderDTO.getName());
+        
+        setupRewriteContextPath();
+        
+        OrderDTO result = HttpHelper.INSTANCE.getFromGateway("/order/order/findById?id=1", OrderDTO.class);
+        assertEquals("1", result.getId());
+        assertEquals("hello world findById", result.getName());
+
+//        assertThat(cleanPluginData(PluginEnum.CONTEXT_PATH.getName()), is("success"));
+    }
+    
+    @Order(2)
+    @Test
+    public void testRewriteCrossPlugin() throws IOException {
+        OrderDTO orderDTO = HttpHelper.INSTANCE.getFromGateway("/http/order/findById?id=1", OrderDTO.class);
+        assertEquals("1", orderDTO.getId());
+        assertEquals("hello world findById", orderDTO.getName());
+        
+        setupRewrite();
+        
+        Map<String, Object> request = new HashMap<>();
+        OrderDTO result = HttpHelper.INSTANCE.getFromGateway("/dubbo/findById?id=2", request, OrderDTO.class);
+        assertEquals("2", result.getId());
+        assertEquals("hello world findById", result.getName());
+        
+        assertThat(cleanPluginData(PluginEnum.CONTEXT_PATH.getName()), is("success"));
+        assertThat(cleanPluginData(PluginEnum.REWRITE.getName()), is("success"));
+    }
+    
+    private void setupRewrite() throws IOException {
+        String pluginResult = initPlugin(PluginEnum.CONTEXT_PATH.getName(), "");
+        assertThat(pluginResult, CoreMatchers.is("success"));
+        LocalPluginController.RuleLocalData ruleLocalData = new LocalPluginController.RuleLocalData();
+        ruleLocalData.setRuleHandler("{\"contextPath\":\"/dubbo\", \"addPrefix\":\"\", \"rewriteContextPath\":\"/http\", \"percentage\":100}");
+        ConditionData conditionData = new ConditionData();
+        conditionData.setParamType(ParamTypeEnum.URI.getName());
+        conditionData.setOperator(OperatorEnum.EQ.getAlias());
+        conditionData.setParamValue("/dubbo/findById");
+        ruleLocalData.setConditionDataList(Collections.singletonList(conditionData));
+        String message = initSelectorAndRules(PluginEnum.CONTEXT_PATH.getName(), "", 0,
+                buildSelectorConditionList("/dubbo/findById"), Collections.singletonList(ruleLocalData));
+        assertThat(message, is("success"));
+        
+        pluginResult = initPlugin(PluginEnum.REWRITE.getName(), "");
+        assertThat(pluginResult, is("success"));
+        String selectorAndRulesResult = initSelectorAndRules(PluginEnum.REWRITE.getName(), "", 0,
+                buildSelectorConditionList("/http/findById"), buildRewriteRuleLocalDataList());
+        assertThat(selectorAndRulesResult, is("success"));
+    }
+    
+    private static List<LocalPluginController.RuleLocalData> buildRewriteRuleLocalDataList() {
+        final LocalPluginController.RuleLocalData ruleLocalData = new LocalPluginController.RuleLocalData();
+        
+        ConditionData conditionData = new ConditionData();
+        conditionData.setParamType(ParamTypeEnum.URI.getName());
+        conditionData.setOperator(OperatorEnum.EQ.getAlias());
+        conditionData.setParamName("/");
+        conditionData.setParamValue("/http/findById");
+        ruleLocalData.setConditionDataList(Collections.singletonList(conditionData));
+        ruleLocalData.setRuleName("rewriteMetaData");
+        
+        RewriteHandle rewriteHandle = new RewriteHandle();
+        rewriteHandle.setRegex("/http/findById");
+        rewriteHandle.setReplace("/order/findById");
+        rewriteHandle.setRewriteMetaData(true);
+        rewriteHandle.setPercentage(100);
+        
+        ruleLocalData.setRuleHandler(JsonUtils.toJson(rewriteHandle));
+        return Collections.singletonList(ruleLocalData);
+    }
+    
+    private void setupRewriteContextPath() throws IOException {
+        String pluginResult = initPlugin(PluginEnum.CONTEXT_PATH.getName(), "");
+        assertThat(pluginResult, CoreMatchers.is("success"));
+        LocalPluginController.RuleLocalData ruleLocalData = new LocalPluginController.RuleLocalData();
+        ruleLocalData.setRuleHandler("{\"contextPath\":\"/order\", \"addPrefix\":\"\", \"rewriteContextPath\":\"/http\", \"percentage\":100}");
+        ConditionData conditionData = new ConditionData();
+        conditionData.setParamType(ParamTypeEnum.URI.getName());
+        conditionData.setOperator(OperatorEnum.MATCH.getAlias());
+        conditionData.setParamValue("/order/order/findById");
+        ruleLocalData.setConditionDataList(Collections.singletonList(conditionData));
+        String message = initSelectorAndRules(PluginEnum.CONTEXT_PATH.getName(), "",
+                buildSelectorConditionList("/order/order/findById"), Collections.singletonList(ruleLocalData));
+        assertThat(message, is("success"));
+    }
+    
+    private List<ConditionData> buildSelectorConditionList(final String paramValue) {
+        ConditionData conditionData = new ConditionData();
+        conditionData.setParamType(ParamTypeEnum.URI.getName());
+        conditionData.setOperator(OperatorEnum.EQ.getAlias());
+        conditionData.setParamValue(paramValue);
+        return Collections.singletonList(conditionData);
+    }
+}