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

jooks 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 9b5b84485 Adding a Dubbo plugin to shenyu ingress-controller (#5000)
9b5b84485 is described below

commit 9b5b844859bfe9aa714a1028079413c30bfd625a
Author: Runqi Zhao <[email protected]>
AuthorDate: Sun Aug 13 14:19:18 2023 +0800

    Adding a Dubbo plugin to shenyu ingress-controller (#5000)
    
    * Add dubbo annotation analysis for shenyu ingress controller
    
    * Add dubbo annotation analysis for shenyu ingress controller
    
    * fix: fix checkstyle
    
    * style: Improve coding style
    
    * fix: Fix the encoding format, set the id value and dubboIngerssParser
    
    * style: Fix code style
    
    * fix: Replace upstream with metdata and fix the ID
    
    * fix
    
    * fix
    
    * fix
    
    * fix
    
    * fix
    
    * style: ci
    
    * fix: fix
    
    * fix: fix
    
    * fix: fix
    
    ---------
    
    Co-authored-by: Kunshuai Zhu <[email protected]>
---
 .../k8s/ingress.yml                                |  85 ++++++
 .../k8s/script/healthcheck.sh                      |  48 ++++
 .../k8s/script/services.list                       |  19 ++
 .../k8s/shenyu-deployment.yml                      |  82 ++++++
 .../k8s/shenyu-examples-dubbo.yml                  |  75 ++++++
 .../k8s/shenyu-service.yml                         |  52 ++++
 .../k8s/shenyu-zookeeper.yml                       |  78 ++++++
 .../shenyu/k8s/common/IngressConfiguration.java    |  67 +++++
 .../apache/shenyu/k8s/common/IngressConstants.java |  29 ++
 .../shenyu/k8s/common/ShenyuMemoryConfig.java      |  14 +-
 ...IngressParser.java => DivideIngressParser.java} |  94 +++----
 ...{IngressParser.java => DubboIngressParser.java} | 279 ++++++++++---------
 .../apache/shenyu/k8s/parser/IngressParser.java    | 296 +--------------------
 .../shenyu/k8s/reconciler/IngressReconciler.java   | 187 +++++++------
 .../k8s/repository/ShenyuCacheRepository.java      |  33 ++-
 .../k8s/IngressControllerConfiguration.java        |   8 +-
 16 files changed, 891 insertions(+), 555 deletions(-)

diff --git 
a/shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/ingress.yml
 
b/shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/ingress.yml
new file mode 100644
index 000000000..41b0e8df8
--- /dev/null
+++ 
b/shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/ingress.yml
@@ -0,0 +1,85 @@
+# 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.
+apiVersion: v1
+kind: Service
+metadata:
+  name: dubbo-findbyid
+  annotations:
+      kubernetes.io/ingress.class: shenyu
+      shenyu.apache.org/plugin-dubbo-enabled: 'true'
+      shenyu.apache.org/plugin-dubbo-app-name: dubbo
+      shenyu.apache.org/plugin-context-path: /dubbo
+      shenyu.apache.org/plugin-dubbo-path: /dubbo/findById
+      shenyu.apache.org/plugin-dubbo-rpc-type: dubbo
+      shenyu.apache.org/plugin-dubbo-servive-name: 
org.apache.shenyu.examples.dubbo.api.service.DubboTestService
+      shenyu.apache.org/plugin-dubbo-method-name: findById
+      shenyu.apache.org/plugin-dubbo-rule-name: /dubbo/findById
+      shenyu.apache.org/plugin-dubbo-param-types: java.lang.String
+spec:
+  selector:
+    app: shenyu-examples-dubbo
+  ports:
+    - port: 20880  # Assuming this is the Dubbo service port
+
+---
+
+apiVersion: v1
+kind: Service
+metadata:
+  name: dubbo-findall
+  annotations:
+    kubernetes.io/ingress.class: shenyu
+    shenyu.apache.org/plugin-dubbo-enabled: 'true'
+    shenyu.apache.org/plugin-dubbo-app-name: dubbo
+    shenyu.apache.org/plugin-context-path: /dubbo
+    shenyu.apache.org/plugin-dubbo-path: /dubbo/findAll
+    shenyu.apache.org/plugin-dubbo-rpc-type: dubbo
+    shenyu.apache.org/plugin-dubbo-servive-name: 
org.dromara.shenyu.examples.dubbo.api.service.DubboTestService
+    shenyu.apache.org/plugin-dubbo-method-name: findAll
+    shenyu.apache.org/plugin-dubbo-rule-name: /dubbo/findAll
+spec:
+  selector:
+    app: shenyu-examples-dubbo
+  ports:
+    - port: 20880  # Assuming this is the Dubbo service port
+
+---
+
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+  annotations:
+    kubernetes.io/ingress.class: shenyu
+    shenyu.apache.org/plugin-dubbo-enabled: 'true'
+  name: demo-ingress
+spec:
+  rules:
+    - http:
+        paths:
+          - backend:
+              service:
+                name: dubbo-findbyid
+                port:
+                  number: 20880
+            path: /dubbo/findById
+            pathType: ImplementationSpecific
+          - backend:
+              service:
+                name: dubbo-findall
+                port:
+                  number: 20880
+            path: /dubbo/findAll
+            pathType: ImplementationSpecific
diff --git 
a/shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/script/healthcheck.sh
 
b/shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/script/healthcheck.sh
new file mode 100644
index 000000000..c7a4c7b44
--- /dev/null
+++ 
b/shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/script/healthcheck.sh
@@ -0,0 +1,48 @@
+#!/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 5
+
+status=`curl -s -o /dev/null -w "%{http_code}" -X POST -H 
"Content-Type:application/json" http://localhost:31195/http/order/save --data 
'{"name":"test", "id": 123}'`
+
+sleep 3
+
+if [ $status -eq 200 ]; then
+    echo -e "Success to send request: $status"
+    echo -e "\n-------------------"
+    exit 0
+fi
+echo -e "Failed to send request from shenyu-bootstrap to dubbo example: 
$status"
+echo -e "\n-------------------"
+exit 1
diff --git 
a/shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/script/services.list
 
b/shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/script/services.list
new file mode 100644
index 000000000..fb77cd36a
--- /dev/null
+++ 
b/shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/script/services.list
@@ -0,0 +1,19 @@
+# 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.
+
+http://localhost:31095/actuator/health
+http://localhost:31195/actuator/health
+http://localhost:31189/test/path/123?name=tom
diff --git 
a/shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/shenyu-deployment.yml
 
b/shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/shenyu-deployment.yml
new file mode 100644
index 000000000..05d8c10c0
--- /dev/null
+++ 
b/shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/shenyu-deployment.yml
@@ -0,0 +1,82 @@
+# 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.
+
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: shenyu-admin
+  labels:
+    app: shenyu-admin
+    all: shenyu-examples-dubbo
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: shenyu-admin
+      all: shenyu-examples-dubbo
+  template:
+    metadata:
+      labels:
+        app: shenyu-admin
+        all: shenyu-examples-dubbo
+    spec:
+      containers:
+        - name: shenyu-admin
+          image: apache/shenyu-admin:latest
+          resources: {}
+          env:
+            - name: SPRING_PROFILES_ACTIVE
+              value: h2
+            - name: shenyu.database.init_script
+              value: sql-script/h2/schema.sql
+          ports:
+            - containerPort: 9095
+          imagePullPolicy: IfNotPresent
+      restartPolicy: Always
+status: {}
+
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: shenyu-bootstrap
+  labels:
+    app: shenyu-bootstrap
+    all: shenyu-examples-dubbo
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: shenyu-bootstrap
+      all: shenyu-examples-dubbo
+  template:
+    metadata:
+      labels:
+        app: shenyu-bootstrap
+        all: shenyu-examples-dubbo
+    spec:
+      containers:
+        - name: shenyu-bootstrap
+          image: apache/shenyu-bootstrap:latest
+          resources: {}
+          env:
+            - name: shenyu.sync.websocket.urls
+              value: ws://shenyu-admin:9095/websocket
+          ports:
+            - containerPort: 9195
+          imagePullPolicy: IfNotPresent
+      restartPolicy: Always
+status: {}
\ No newline at end of file
diff --git 
a/shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/shenyu-examples-dubbo.yml
 
b/shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/shenyu-examples-dubbo.yml
new file mode 100644
index 000000000..3fec08640
--- /dev/null
+++ 
b/shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/shenyu-examples-dubbo.yml
@@ -0,0 +1,75 @@
+# 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.
+
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: shenyu-examples-dubbo-deployment
+  labels:
+    app: shenyu-examples-dubbo
+    all: shenyu-examples-dubbo
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: shenyu-examples-dubbo
+      all: shenyu-examples-dubbo
+  strategy: {}
+  template:
+    metadata:
+      labels:
+        app: shenyu-examples-dubbo
+        all: shenyu-examples-dubbo
+    spec:
+      containers:
+        - image: shenyu-examples-dubbo
+          name: shenyu-examples-dubbo
+          livenessProbe:
+            exec:
+              command:
+                - wget -q -O - http://localhost:8189/actuator/health | grep UP 
|| exit 1
+            initialDelaySeconds: 10
+            failureThreshold: 3
+            timeoutSeconds: 2
+          env:
+            - name: shenyu.register.serverLists
+              value: http://shenyu-admin:9095
+          ports:
+            - containerPort: 8189
+          imagePullPolicy: IfNotPresent
+      restartPolicy: Always
+status: {}
+
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: shenyu-examples-apache-dubbo-service
+  labels:
+    app: shenyu-examples-dubbo
+    all: shenyu-examples-dubbo
+spec:
+  selector:
+    app: shenyu-examples-dubbo
+    all: shenyu-examples-dubbo
+  type: NodePort
+  ports:
+    - name: "8189"
+      port: 8189
+      targetPort: 8189
+      nodePort: 31190
+status:
+  loadBalancer: {}
diff --git 
a/shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/shenyu-service.yml
 
b/shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/shenyu-service.yml
new file mode 100644
index 000000000..57f720aaf
--- /dev/null
+++ 
b/shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/shenyu-service.yml
@@ -0,0 +1,52 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+apiVersion: v1
+kind: Service
+metadata:
+  name: shenyu-admin
+  labels:
+    app: shenyu-admin
+    all: shenyu-examples-dubbo
+spec:
+  type: NodePort
+  selector:
+    app: shenyu-admin
+    all: shenyu-examples-dubbo
+  ports:
+  - name: "9095"
+    port: 9095
+    targetPort: 9095
+    nodePort: 31095
+
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: shenyu-bootstrap
+  labels:
+    app: shenyu-bootstrap
+    all: shenyu-examples-dubbo
+spec:
+  type: NodePort
+  selector:
+    app: shenyu-bootstrap
+    all: shenyu-examples-dubbo
+  ports:
+  - name: "9195"
+    port: 9195
+    targetPort: 9195
+    nodePort: 31195
\ No newline at end of file
diff --git 
a/shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/shenyu-zookeeper.yml
 
b/shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/shenyu-zookeeper.yml
new file mode 100644
index 000000000..e311194fb
--- /dev/null
+++ 
b/shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/shenyu-zookeeper.yml
@@ -0,0 +1,78 @@
+# 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.
+
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  labels:
+    app: shenyu-zk
+    all: shenyu-examples-dubbo
+  name: shenyu-zk
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: shenyu-zk
+      all: shenyu-examples-dubbo
+  strategy: {}
+  template:
+    metadata:
+      labels:
+        app: shenyu-zk
+        all: shenyu-examples-dubbo
+    spec:
+      containers:
+        - image: zookeeper:3.5
+          name: shenyu-zk
+          resources: {}
+          ports:
+            - containerPort: 2181
+              name: client
+            - containerPort: 2888
+              name: server
+            - containerPort: 3888
+              name: leader-election
+            - containerPort: 8080
+              name: website
+      restartPolicy: Always
+status: {}
+
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: shenyu-zk
+  labels:
+    app: shenyu-zk
+    all: shenyu-examples-dubbo
+spec:
+  type: NodePort
+  selector:
+    app: shenyu-zk
+    all: shenyu-examples-dubbo
+  ports:
+    - name: "client"
+      port: 2181
+      targetPort: 2181
+    - name: "server"
+      port: 2888
+      targetPort: 2888
+    - name: "election"
+      port: 3888
+      targetPort: 3888
+    - name: "website"
+      port: 8080
+      targetPort: 8080
diff --git 
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/common/IngressConfiguration.java
 
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/common/IngressConfiguration.java
new file mode 100644
index 000000000..e0fd7bb6d
--- /dev/null
+++ 
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/common/IngressConfiguration.java
@@ -0,0 +1,67 @@
+/*
+ * 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.k8s.common;
+
+import org.apache.shenyu.common.dto.MetaData;
+import org.apache.shenyu.common.dto.RuleData;
+import org.apache.shenyu.common.dto.SelectorData;
+
+public class IngressConfiguration {
+
+    private final SelectorData selectorData;
+
+    private final RuleData ruleData;
+
+    private final MetaData metaData;
+
+    /**
+     * constructor.
+     * @param selectorData selectorData
+     * @param ruleData ruleData
+     * @param metaData metaData
+     */
+    public IngressConfiguration(final SelectorData selectorData, final 
RuleData ruleData, final MetaData metaData) {
+        this.selectorData = selectorData;
+        this.ruleData = ruleData;
+        this.metaData = metaData;
+    }
+
+    /**
+     * get selectorData.
+     * @return selectorData
+     */
+    public SelectorData getSelectorData() {
+        return selectorData;
+    }
+
+    /**
+     * get ruleData.
+     * @return ruleData
+     */
+    public RuleData getRuleData() {
+        return ruleData;
+    }
+
+    /**
+     * get metaData.
+     * @return metaData
+     */
+    public MetaData getMetaData() {
+        return metaData;
+    }
+}
diff --git 
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/common/IngressConstants.java
 
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/common/IngressConstants.java
index e3383c171..2d48ee615 100644
--- 
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/common/IngressConstants.java
+++ 
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/common/IngressConstants.java
@@ -23,6 +23,8 @@ public class IngressConstants {
 
     public static final String SHENYU_INGRESS_CLASS = "shenyu";
 
+    public static final String ID = "1";
+
     // Load balance type name, refer to LoadBalanceEnum
     public static final String LOADBALANCER_ANNOTATION_KEY = 
"shenyu.apache.org/loadbalancer";
 
@@ -37,4 +39,31 @@ public class IngressConstants {
 
     // The maximum length of the request header, in bytes
     public static final String REQUEST_MAX_SIZE_ANNOTATION_KEY = 
"shenyu.apache.org/request-max-size";
+
+    //Determine if the dubbo plugin is enabled, in bool
+    public static final String PLUGIN_DUBBO_ENABLED = 
"shenyu.apache.org/plugin-dubbo-enabled";
+
+    // The configuration key to specify the Dubbo application name for the 
plugin, in string
+    public static final String PLUGIN_DUBBO_APP_NAME = 
"shenyu.apache.org/plugin-dubbo-app-name";
+
+    // The configuration key to specify the Dubbo method name for the plugin, 
in string
+    public static final String PLUGIN_DUBBO_METHOD_NAME = 
"shenyu.apache.org/plugin-dubbo-method-name";
+
+    // The configuration key to specify the Dubbo path for the plugin, in 
string
+    public static final String PLUGIN_DUBBO_PATH = 
"shenyu.apache.org/plugin-dubbo-PATH";
+
+    // The configuration key to specify the Dubbo RPC type for the plugin, in 
string
+    public static final String PLUGIN_DUBBO_RPC_TYPE = 
"shenyu.apache.org/plugin-dubbo-rpc-type";
+
+    // The configuration key to specify the Dubbo service name for the plugin, 
in string
+    public static final String PLUGIN_DUBBO_SERVICE_NAME = 
"shenyu.apache.org/plugin-dubbo-service-name";
+
+    // The configuration key to specify the context path for the Dubbo 
service, in string
+    public static final String PLUGIN_DUBBO_CONTEXT_PATH = 
"shenyu.apache.org/plugin-dubbo-context-path";
+
+    // The configuration key to specify additional RPC extension for the Dubbo 
plugin, in string
+    public static final String PLUGIN_DUBBO_RPC_EXT = 
"shenyu.apache.org/plugin-dubbo-rpc-ext";
+
+    // The configuration key to specify parameter types for the Dubbo plugin, 
in string
+    public static final String PLUGIN_DUBBO_PARAMENT_TYPE = 
"shenyu.apache.org/plugin-dubbo-parament-type";
 }
diff --git 
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/common/ShenyuMemoryConfig.java
 
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/common/ShenyuMemoryConfig.java
index 702000413..96011398d 100644
--- 
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/common/ShenyuMemoryConfig.java
+++ 
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/common/ShenyuMemoryConfig.java
@@ -19,8 +19,6 @@ package org.apache.shenyu.k8s.common;
 
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.shenyu.common.config.ssl.SslCrtAndKeyStream;
-import org.apache.shenyu.common.dto.RuleData;
-import org.apache.shenyu.common.dto.SelectorData;
 
 import java.util.List;
 
@@ -29,9 +27,9 @@ import java.util.List;
  */
 public class ShenyuMemoryConfig {
 
-    private Pair<Pair<String, String>, Pair<SelectorData, RuleData>> 
globalDefaultBackend;
+    private Pair<Pair<String, String>, IngressConfiguration> 
globalDefaultBackend;
 
-    private List<Pair<SelectorData, RuleData>> routeConfigList;
+    private List<IngressConfiguration> routeConfigList;
 
     private List<SslCrtAndKeyStream> tlsConfigList;
 
@@ -46,7 +44,7 @@ public class ShenyuMemoryConfig {
      *
      * @return GlobalDefaultBackend
      */
-    public Pair<Pair<String, String>, Pair<SelectorData, RuleData>> 
getGlobalDefaultBackend() {
+    public Pair<Pair<String, String>, IngressConfiguration> 
getGlobalDefaultBackend() {
         return globalDefaultBackend;
     }
 
@@ -55,7 +53,7 @@ public class ShenyuMemoryConfig {
      *
      * @param globalDefaultBackend GlobalDefaultBackend
      */
-    public void setGlobalDefaultBackend(final Pair<Pair<String, String>, 
Pair<SelectorData, RuleData>> globalDefaultBackend) {
+    public void setGlobalDefaultBackend(final Pair<Pair<String, String>, 
IngressConfiguration> globalDefaultBackend) {
         this.globalDefaultBackend = globalDefaultBackend;
     }
 
@@ -64,7 +62,7 @@ public class ShenyuMemoryConfig {
      *
      * @return RouteConfigList
      */
-    public List<Pair<SelectorData, RuleData>> getRouteConfigList() {
+    public List<IngressConfiguration> getRouteConfigList() {
         return routeConfigList;
     }
 
@@ -73,7 +71,7 @@ public class ShenyuMemoryConfig {
      *
      * @param routeConfigList RouteConfigList
      */
-    public void setRouteConfigList(final List<Pair<SelectorData, RuleData>> 
routeConfigList) {
+    public void setRouteConfigList(final List<IngressConfiguration> 
routeConfigList) {
         this.routeConfigList = routeConfigList;
     }
 
diff --git 
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/IngressParser.java
 
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/DivideIngressParser.java
similarity index 84%
copy from 
shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/IngressParser.java
copy to 
shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/DivideIngressParser.java
index 2483c7bc4..f065ae3b4 100644
--- 
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/IngressParser.java
+++ 
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/DivideIngressParser.java
@@ -17,21 +17,21 @@
 
 package org.apache.shenyu.k8s.parser;
 
-import io.kubernetes.client.informer.SharedIndexInformer;
 import io.kubernetes.client.informer.cache.Lister;
 import io.kubernetes.client.openapi.ApiException;
 import io.kubernetes.client.openapi.apis.CoreV1Api;
-import io.kubernetes.client.openapi.models.V1Endpoints;
-import io.kubernetes.client.openapi.models.V1EndpointSubset;
 import io.kubernetes.client.openapi.models.V1EndpointAddress;
+import io.kubernetes.client.openapi.models.V1EndpointSubset;
+import io.kubernetes.client.openapi.models.V1Endpoints;
+import io.kubernetes.client.openapi.models.V1HTTPIngressPath;
 import io.kubernetes.client.openapi.models.V1Ingress;
 import io.kubernetes.client.openapi.models.V1IngressBackend;
 import io.kubernetes.client.openapi.models.V1IngressRule;
-import io.kubernetes.client.openapi.models.V1IngressTLS;
-import io.kubernetes.client.openapi.models.V1HTTPIngressPath;
-import io.kubernetes.client.openapi.models.V1Service;
 import io.kubernetes.client.openapi.models.V1IngressServiceBackend;
+import io.kubernetes.client.openapi.models.V1IngressTLS;
 import io.kubernetes.client.openapi.models.V1Secret;
+import io.kubernetes.client.openapi.models.V1Service;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.shenyu.common.config.ssl.SslCrtAndKeyStream;
 import org.apache.shenyu.common.dto.ConditionData;
@@ -39,13 +39,14 @@ import org.apache.shenyu.common.dto.RuleData;
 import org.apache.shenyu.common.dto.SelectorData;
 import org.apache.shenyu.common.dto.convert.rule.impl.DivideRuleHandle;
 import org.apache.shenyu.common.dto.convert.selector.DivideUpstream;
-import org.apache.shenyu.common.enums.MatchModeEnum;
 import org.apache.shenyu.common.enums.LoadBalanceEnum;
+import org.apache.shenyu.common.enums.MatchModeEnum;
 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.enums.SelectorTypeEnum;
 import org.apache.shenyu.common.utils.GsonUtils;
+import org.apache.shenyu.k8s.common.IngressConfiguration;
 import org.apache.shenyu.k8s.common.IngressConstants;
 import org.apache.shenyu.k8s.common.ShenyuMemoryConfig;
 import org.slf4j.Logger;
@@ -56,13 +57,13 @@ import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.Objects;
 import java.util.Map;
+import java.util.Objects;
 
 /**
- * Parser of Ingress.
+ * Parser of Ingress Divide Annotations.
  */
-public class IngressParser implements K8sResourceParser<V1Ingress> {
+public class DivideIngressParser implements K8sResourceParser<V1Ingress> {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(IngressParser.class);
 
@@ -73,12 +74,12 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
     /**
      * IngressParser Constructor.
      *
-     * @param serviceInformer serviceInformer
-     * @param endpointsInformer endpointsInformer
+     * @param serviceLister serviceLister
+     * @param endpointsLister endpointsLister
      */
-    public IngressParser(final SharedIndexInformer<V1Service> serviceInformer, 
final SharedIndexInformer<V1Endpoints> endpointsInformer) {
-        this.serviceLister = new Lister<>(serviceInformer.getIndexer());
-        this.endpointsLister = new Lister<>(endpointsInformer.getIndexer());
+    public DivideIngressParser(final Lister<V1Service> serviceLister, final 
Lister<V1Endpoints> endpointsLister) {
+        this.serviceLister = serviceLister;
+        this.endpointsLister = endpointsLister;
     }
 
     /**
@@ -92,7 +93,7 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
     public ShenyuMemoryConfig parse(final V1Ingress ingress, final CoreV1Api 
coreV1Api) {
         ShenyuMemoryConfig res = new ShenyuMemoryConfig();
 
-        if (ingress.getSpec() != null) {
+        if (Objects.nonNull(ingress.getSpec())) {
             // Parse the default backend
             V1IngressBackend defaultBackend = 
ingress.getSpec().getDefaultBackend();
             List<V1IngressRule> rules = ingress.getSpec().getRules();
@@ -101,18 +102,18 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
             String namespace = 
Objects.requireNonNull(ingress.getMetadata()).getNamespace();
             List<DivideUpstream> defaultUpstreamList = 
parseDefaultService(defaultBackend, namespace);
 
-            if (rules == null || rules.isEmpty()) {
+            if (Objects.isNull(rules) || CollectionUtils.isEmpty(rules)) {
                 // if rules is null, defaultBackend become global default
-                if (defaultBackend != null && defaultBackend.getService() != 
null) {
-                    Pair<SelectorData, RuleData> defaultRouteConfig = 
getDefaultRouteConfig(defaultUpstreamList, 
ingress.getMetadata().getAnnotations());
+                if (Objects.nonNull(defaultBackend) && 
Objects.nonNull(defaultBackend.getService())) {
+                    IngressConfiguration defaultRouteConfig = 
getDefaultRouteConfig(defaultUpstreamList, 
ingress.getMetadata().getAnnotations());
                     res.setGlobalDefaultBackend(Pair.of(Pair.of(namespace + 
"/" + ingress.getMetadata().getName(), defaultBackend.getService().getName()),
                             defaultRouteConfig));
                 }
             } else {
                 // if rules is not null, defaultBackend is default in this 
ingress
-                List<Pair<SelectorData, RuleData>> routeList = new 
ArrayList<>(rules.size());
+                List<IngressConfiguration> routeList = new 
ArrayList<>(rules.size());
                 for (V1IngressRule ingressRule : rules) {
-                    List<Pair<SelectorData, RuleData>> routes = 
parseIngressRule(ingressRule, defaultUpstreamList,
+                    List<IngressConfiguration> routes = 
parseIngressRule(ingressRule, defaultUpstreamList,
                             
Objects.requireNonNull(ingress.getMetadata()).getNamespace(), 
ingress.getMetadata().getAnnotations());
                     routeList.addAll(routes);
                 }
@@ -120,17 +121,17 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
             }
 
             // Parse tls
-            if (tlsList != null && !tlsList.isEmpty()) {
+            if (Objects.nonNull(tlsList) && 
CollectionUtils.isNotEmpty(tlsList)) {
                 List<SslCrtAndKeyStream> sslList = new ArrayList<>();
                 for (V1IngressTLS tls : tlsList) {
-                    if (tls.getSecretName() != null && tls.getHosts() != null 
&& !tls.getHosts().isEmpty()) {
+                    if (tls.getSecretName() != null && tls.getHosts() != null 
&& CollectionUtils.isNotEmpty(tls.getHosts())) {
                         try {
                             V1Secret secret = 
coreV1Api.readNamespacedSecret(tls.getSecretName(), namespace, "ture");
-                            if (secret.getData() != null) {
+                            if (Objects.nonNull(secret.getData())) {
                                 InputStream keyCertChainInputStream = new 
ByteArrayInputStream(secret.getData().get("tls.crt"));
                                 InputStream keyInputStream = new 
ByteArrayInputStream(secret.getData().get("tls.key"));
                                 tls.getHosts().forEach(host ->
-                                    sslList.add(new SslCrtAndKeyStream(host, 
keyCertChainInputStream, keyInputStream))
+                                        sslList.add(new 
SslCrtAndKeyStream(host, keyCertChainInputStream, keyInputStream))
                                 );
                             }
                         } catch (ApiException e) {
@@ -146,23 +147,23 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
 
     private List<DivideUpstream> parseDefaultService(final V1IngressBackend 
defaultBackend, final String namespace) {
         List<DivideUpstream> defaultUpstreamList = new ArrayList<>();
-        if (defaultBackend != null && defaultBackend.getService() != null) {
+        if (Objects.nonNull(defaultBackend) && 
Objects.nonNull(defaultBackend.getService())) {
             String serviceName = defaultBackend.getService().getName();
             // shenyu routes directly to the container
             V1Endpoints v1Endpoints = 
endpointsLister.namespace(namespace).get(serviceName);
             List<V1EndpointSubset> subsets = v1Endpoints.getSubsets();
-            if (subsets == null || subsets.isEmpty()) {
+            if (Objects.isNull(subsets) || CollectionUtils.isEmpty(subsets)) {
                 LOG.info("Endpoints {} do not have subsets", serviceName);
             } else {
                 for (V1EndpointSubset subset : subsets) {
                     List<V1EndpointAddress> addresses = subset.getAddresses();
-                    if (addresses == null || addresses.isEmpty()) {
+                    if (Objects.isNull(addresses) || 
CollectionUtils.isEmpty(addresses)) {
                         continue;
                     }
                     for (V1EndpointAddress address : addresses) {
                         String upstreamIp = address.getIp();
                         String defaultPort = 
parsePort(defaultBackend.getService());
-                        if (defaultPort != null) {
+                        if (Objects.nonNull(defaultPort)) {
                             DivideUpstream upstream = new DivideUpstream();
                             upstream.setUpstreamUrl(upstreamIp + ":" + 
defaultPort);
                             upstream.setWeight(100);
@@ -180,20 +181,20 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
         return defaultUpstreamList;
     }
 
-    private List<Pair<SelectorData, RuleData>> parseIngressRule(final 
V1IngressRule ingressRule,
+    private List<IngressConfiguration> parseIngressRule(final V1IngressRule 
ingressRule,
                                                                 final 
List<DivideUpstream> defaultUpstream,
                                                                 final String 
namespace,
                                                                 final 
Map<String, String> annotations) {
-        List<Pair<SelectorData, RuleData>> res = new ArrayList<>();
+        List<IngressConfiguration> res = new ArrayList<>();
 
         ConditionData hostCondition = null;
-        if (ingressRule.getHost() != null) {
+        if (Objects.nonNull(ingressRule.getHost())) {
             hostCondition = new ConditionData();
             hostCondition.setParamType(ParamTypeEnum.DOMAIN.getName());
             hostCondition.setOperator(OperatorEnum.EQ.getAlias());
             hostCondition.setParamValue(ingressRule.getHost());
         }
-        if (ingressRule.getHttp() != null) {
+        if (Objects.nonNull(ingressRule.getHttp())) {
             List<V1HTTPIngressPath> paths = ingressRule.getHttp().getPaths();
             if (paths != null) {
                 for (V1HTTPIngressPath path : paths) {
@@ -218,7 +219,7 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
                     pathCondition.setParamType(ParamTypeEnum.URI.getName());
                     pathCondition.setParamValue(path.getPath());
                     List<ConditionData> conditionList = new ArrayList<>(2);
-                    if (hostCondition != null) {
+                    if (Objects.nonNull(hostCondition)) {
                         conditionList.add(hostCondition);
                     }
                     conditionList.add(pathCondition);
@@ -240,7 +241,7 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
                     
selectorData.setHandle(GsonUtils.getInstance().toJson(upstreamList));
 
                     DivideRuleHandle divideRuleHandle = new DivideRuleHandle();
-                    if (annotations != null) {
+                    if (Objects.nonNull(annotations)) {
                         
divideRuleHandle.setLoadBalance(annotations.getOrDefault(IngressConstants.LOADBALANCER_ANNOTATION_KEY,
 LoadBalanceEnum.RANDOM.getName()));
                         
divideRuleHandle.setRetry(Integer.parseInt(annotations.getOrDefault(IngressConstants.RETRY_ANNOTATION_KEY,
 "3")));
                         
divideRuleHandle.setTimeout(Long.parseLong(annotations.getOrDefault(IngressConstants.TIMEOUT_ANNOTATION_KEY,
 "3000")));
@@ -256,7 +257,7 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
                             .loged(false)
                             .enabled(true).build();
 
-                    res.add(Pair.of(selectorData, ruleData));
+                    res.add(new IngressConfiguration(selectorData, ruleData, 
null));
                 }
             }
         }
@@ -264,7 +265,7 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
     }
 
     private String parsePort(final V1IngressServiceBackend service) {
-        if (service.getPort() != null) {
+        if (Objects.nonNull(service.getPort())) {
             if (service.getPort().getNumber() != null && 
service.getPort().getNumber() > 0) {
                 return String.valueOf(service.getPort().getNumber());
             } else if (service.getPort().getName() != null && 
!"".equals(service.getPort().getName().trim())) {
@@ -276,23 +277,23 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
 
     private List<DivideUpstream> parseUpstream(final V1IngressBackend backend, 
final String namespace) {
         List<DivideUpstream> upstreamList = new ArrayList<>();
-        if (backend != null && backend.getService() != null && 
backend.getService().getName() != null) {
+        if (Objects.nonNull(backend) && Objects.nonNull(backend.getService()) 
&& Objects.nonNull(backend.getService().getName())) {
             String serviceName = backend.getService().getName();
             // shenyu routes directly to the container
             V1Endpoints v1Endpoints = 
endpointsLister.namespace(namespace).get(serviceName);
             List<V1EndpointSubset> subsets = v1Endpoints.getSubsets();
-            if (subsets == null || subsets.isEmpty()) {
+            if (Objects.isNull(subsets) || CollectionUtils.isEmpty(subsets)) {
                 LOG.info("Endpoints {} do not have subsets", serviceName);
             } else {
                 for (V1EndpointSubset subset : subsets) {
                     List<V1EndpointAddress> addresses = subset.getAddresses();
-                    if (addresses == null || addresses.isEmpty()) {
+                    if (Objects.isNull(addresses) || addresses.isEmpty()) {
                         continue;
                     }
                     for (V1EndpointAddress address : addresses) {
                         String upstreamIp = address.getIp();
                         String defaultPort = parsePort(backend.getService());
-                        if (defaultPort != null) {
+                        if (Objects.nonNull(defaultPort)) {
                             DivideUpstream upstream = new DivideUpstream();
                             upstream.setUpstreamUrl(upstreamIp + ":" + 
defaultPort);
                             upstream.setWeight(100);
@@ -310,7 +311,7 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
         return upstreamList;
     }
 
-    private Pair<SelectorData, RuleData> getDefaultRouteConfig(final 
List<DivideUpstream> divideUpstream, final Map<String, String> annotations) {
+    private IngressConfiguration getDefaultRouteConfig(final 
List<DivideUpstream> divideUpstream, final Map<String, String> annotations) {
         final ConditionData conditionData = new ConditionData();
         conditionData.setParamName("default");
         conditionData.setParamType(ParamTypeEnum.URI.getName());
@@ -323,7 +324,7 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
                 .conditionList(Collections.singletonList(conditionData))
                 .handle(GsonUtils.getInstance().toJson(divideUpstream))
                 .enabled(true)
-                .id("1")
+                .id(IngressConstants.ID)
                 .pluginName(PluginEnum.DIVIDE.getName())
                 .pluginId(String.valueOf(PluginEnum.DIVIDE.getCode()))
                 .logged(false)
@@ -332,8 +333,7 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
                 .type(SelectorTypeEnum.FULL_FLOW.getCode()).build();
 
         DivideRuleHandle divideRuleHandle = new DivideRuleHandle();
-        // TODO need an annotation parsing common way
-        if (annotations != null) {
+        if (Objects.nonNull(annotations)) {
             
divideRuleHandle.setLoadBalance(annotations.getOrDefault(IngressConstants.LOADBALANCER_ANNOTATION_KEY,
 LoadBalanceEnum.RANDOM.getName()));
             
divideRuleHandle.setRetry(Integer.parseInt(annotations.getOrDefault(IngressConstants.RETRY_ANNOTATION_KEY,
 "3")));
             
divideRuleHandle.setTimeout(Long.parseLong(annotations.getOrDefault(IngressConstants.TIMEOUT_ANNOTATION_KEY,
 "3000")));
@@ -341,7 +341,7 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
             
divideRuleHandle.setRequestMaxSize(Long.parseLong(annotations.getOrDefault(IngressConstants.REQUEST_MAX_SIZE_ANNOTATION_KEY,
 "102400")));
         }
         final RuleData ruleData = RuleData.builder()
-                .selectorId("1")
+                .selectorId(IngressConstants.ID)
                 .pluginName(PluginEnum.DIVIDE.getName())
                 .name("default-rule")
                 .matchMode(MatchModeEnum.AND.getCode())
@@ -351,6 +351,6 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
                 .enabled(true)
                 .sort(Integer.MAX_VALUE).build();
 
-        return Pair.of(selectorData, ruleData);
+        return new IngressConfiguration(selectorData, ruleData, null);
     }
 }
diff --git 
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/IngressParser.java
 
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/DubboIngressParser.java
similarity index 53%
copy from 
shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/IngressParser.java
copy to 
shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/DubboIngressParser.java
index 2483c7bc4..303e6cc00 100644
--- 
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/IngressParser.java
+++ 
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/DubboIngressParser.java
@@ -17,35 +17,38 @@
 
 package org.apache.shenyu.k8s.parser;
 
-import io.kubernetes.client.informer.SharedIndexInformer;
 import io.kubernetes.client.informer.cache.Lister;
 import io.kubernetes.client.openapi.ApiException;
 import io.kubernetes.client.openapi.apis.CoreV1Api;
-import io.kubernetes.client.openapi.models.V1Endpoints;
-import io.kubernetes.client.openapi.models.V1EndpointSubset;
 import io.kubernetes.client.openapi.models.V1EndpointAddress;
+import io.kubernetes.client.openapi.models.V1EndpointSubset;
+import io.kubernetes.client.openapi.models.V1Endpoints;
+import io.kubernetes.client.openapi.models.V1HTTPIngressPath;
 import io.kubernetes.client.openapi.models.V1Ingress;
 import io.kubernetes.client.openapi.models.V1IngressBackend;
 import io.kubernetes.client.openapi.models.V1IngressRule;
-import io.kubernetes.client.openapi.models.V1IngressTLS;
-import io.kubernetes.client.openapi.models.V1HTTPIngressPath;
-import io.kubernetes.client.openapi.models.V1Service;
 import io.kubernetes.client.openapi.models.V1IngressServiceBackend;
+import io.kubernetes.client.openapi.models.V1IngressTLS;
 import io.kubernetes.client.openapi.models.V1Secret;
+import io.kubernetes.client.openapi.models.V1Service;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.shenyu.common.config.ssl.SslCrtAndKeyStream;
 import org.apache.shenyu.common.dto.ConditionData;
+import org.apache.shenyu.common.dto.MetaData;
 import org.apache.shenyu.common.dto.RuleData;
 import org.apache.shenyu.common.dto.SelectorData;
-import org.apache.shenyu.common.dto.convert.rule.impl.DivideRuleHandle;
-import org.apache.shenyu.common.dto.convert.selector.DivideUpstream;
-import org.apache.shenyu.common.enums.MatchModeEnum;
+import org.apache.shenyu.common.dto.convert.rule.impl.DubboRuleHandle;
+import org.apache.shenyu.common.dto.convert.selector.DubboUpstream;
 import org.apache.shenyu.common.enums.LoadBalanceEnum;
+import org.apache.shenyu.common.enums.MatchModeEnum;
 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.enums.RpcTypeEnum;
 import org.apache.shenyu.common.enums.SelectorTypeEnum;
 import org.apache.shenyu.common.utils.GsonUtils;
+import org.apache.shenyu.k8s.common.IngressConfiguration;
 import org.apache.shenyu.k8s.common.IngressConstants;
 import org.apache.shenyu.k8s.common.ShenyuMemoryConfig;
 import org.slf4j.Logger;
@@ -56,35 +59,35 @@ import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.Objects;
 import java.util.Map;
+import java.util.Objects;
 
 /**
- * Parser of Ingress.
+ * Parser of Ingress Dubbo Annotations.
  */
-public class IngressParser implements K8sResourceParser<V1Ingress> {
+public class DubboIngressParser implements K8sResourceParser<V1Ingress> {
 
-    private static final Logger LOG = 
LoggerFactory.getLogger(IngressParser.class);
+    private static final Logger LOG = 
LoggerFactory.getLogger(DubboIngressParser.class);
 
     private final Lister<V1Service> serviceLister;
 
     private final Lister<V1Endpoints> endpointsLister;
 
     /**
-     * IngressParser Constructor.
+     * DubboIngressParser Constructor.
      *
-     * @param serviceInformer serviceInformer
+     * @param serviceInformer   serviceInformer
      * @param endpointsInformer endpointsInformer
      */
-    public IngressParser(final SharedIndexInformer<V1Service> serviceInformer, 
final SharedIndexInformer<V1Endpoints> endpointsInformer) {
-        this.serviceLister = new Lister<>(serviceInformer.getIndexer());
-        this.endpointsLister = new Lister<>(endpointsInformer.getIndexer());
+    public DubboIngressParser(final Lister<V1Service> serviceInformer, final 
Lister<V1Endpoints> endpointsInformer) {
+        this.serviceLister = serviceInformer;
+        this.endpointsLister = endpointsInformer;
     }
 
     /**
      * Parse ingress to ShenyuMemoryConfig.
      *
-     * @param ingress ingress resource
+     * @param ingress   ingress resource
      * @param coreV1Api coreV1Api
      * @return ShenyuMemoryConfig
      */
@@ -92,27 +95,27 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
     public ShenyuMemoryConfig parse(final V1Ingress ingress, final CoreV1Api 
coreV1Api) {
         ShenyuMemoryConfig res = new ShenyuMemoryConfig();
 
-        if (ingress.getSpec() != null) {
-            // Parse the default backend
-            V1IngressBackend defaultBackend = 
ingress.getSpec().getDefaultBackend();
+        if (Objects.nonNull(ingress.getSpec())) {
+            // Parse the dubbo backend
+            V1IngressBackend dubboBackend = 
ingress.getSpec().getDefaultBackend();
             List<V1IngressRule> rules = ingress.getSpec().getRules();
             List<V1IngressTLS> tlsList = ingress.getSpec().getTls();
 
             String namespace = 
Objects.requireNonNull(ingress.getMetadata()).getNamespace();
-            List<DivideUpstream> defaultUpstreamList = 
parseDefaultService(defaultBackend, namespace);
+            List<DubboUpstream> dubboUpstreamList = 
getDefaultDubboRouteConfig(dubboBackend, namespace);
 
-            if (rules == null || rules.isEmpty()) {
-                // if rules is null, defaultBackend become global default
-                if (defaultBackend != null && defaultBackend.getService() != 
null) {
-                    Pair<SelectorData, RuleData> defaultRouteConfig = 
getDefaultRouteConfig(defaultUpstreamList, 
ingress.getMetadata().getAnnotations());
-                    res.setGlobalDefaultBackend(Pair.of(Pair.of(namespace + 
"/" + ingress.getMetadata().getName(), defaultBackend.getService().getName()),
+            if (Objects.isNull(rules) || CollectionUtils.isEmpty(rules)) {
+                // if rules is null, dubboBackend become global default
+                if (Objects.nonNull(dubboBackend) && 
Objects.nonNull(dubboBackend.getService())) {
+                    IngressConfiguration defaultRouteConfig = 
getDubboRouteConfig(dubboUpstreamList, ingress.getMetadata().getAnnotations());
+                    res.setGlobalDefaultBackend(Pair.of(Pair.of(namespace + 
"/" + ingress.getMetadata().getName(), dubboBackend.getService().getName()),
                             defaultRouteConfig));
                 }
             } else {
-                // if rules is not null, defaultBackend is default in this 
ingress
-                List<Pair<SelectorData, RuleData>> routeList = new 
ArrayList<>(rules.size());
+                // if rules is not null, dubboBackend is default in this 
ingress
+                List<IngressConfiguration> routeList = new 
ArrayList<>(rules.size());
                 for (V1IngressRule ingressRule : rules) {
-                    List<Pair<SelectorData, RuleData>> routes = 
parseIngressRule(ingressRule, defaultUpstreamList,
+                    List<IngressConfiguration> routes = 
parseIngressRule(ingressRule, dubboUpstreamList,
                             
Objects.requireNonNull(ingress.getMetadata()).getNamespace(), 
ingress.getMetadata().getAnnotations());
                     routeList.addAll(routes);
                 }
@@ -120,17 +123,17 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
             }
 
             // Parse tls
-            if (tlsList != null && !tlsList.isEmpty()) {
+            if (Objects.nonNull(tlsList) && 
CollectionUtils.isNotEmpty(tlsList)) {
                 List<SslCrtAndKeyStream> sslList = new ArrayList<>();
                 for (V1IngressTLS tls : tlsList) {
-                    if (tls.getSecretName() != null && tls.getHosts() != null 
&& !tls.getHosts().isEmpty()) {
+                    if (Objects.nonNull(tls.getSecretName()) && 
Objects.nonNull(tls.getHosts()) && CollectionUtils.isNotEmpty(tls.getHosts())) {
                         try {
                             V1Secret secret = 
coreV1Api.readNamespacedSecret(tls.getSecretName(), namespace, "ture");
                             if (secret.getData() != null) {
                                 InputStream keyCertChainInputStream = new 
ByteArrayInputStream(secret.getData().get("tls.crt"));
                                 InputStream keyInputStream = new 
ByteArrayInputStream(secret.getData().get("tls.key"));
                                 tls.getHosts().forEach(host ->
-                                    sslList.add(new SslCrtAndKeyStream(host, 
keyCertChainInputStream, keyInputStream))
+                                        sslList.add(new 
SslCrtAndKeyStream(host, keyCertChainInputStream, keyInputStream))
                                 );
                             }
                         } catch (ApiException e) {
@@ -144,56 +147,67 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
         return res;
     }
 
-    private List<DivideUpstream> parseDefaultService(final V1IngressBackend 
defaultBackend, final String namespace) {
-        List<DivideUpstream> defaultUpstreamList = new ArrayList<>();
-        if (defaultBackend != null && defaultBackend.getService() != null) {
+    private List<DubboUpstream> getDefaultDubboRouteConfig(final 
V1IngressBackend defaultBackend, final String namespace) {
+        List<DubboUpstream> dubboUpstreamList = new ArrayList<>();
+        if (Objects.nonNull(defaultBackend) && 
Objects.nonNull(defaultBackend.getService())) {
             String serviceName = defaultBackend.getService().getName();
             // shenyu routes directly to the container
             V1Endpoints v1Endpoints = 
endpointsLister.namespace(namespace).get(serviceName);
             List<V1EndpointSubset> subsets = v1Endpoints.getSubsets();
-            if (subsets == null || subsets.isEmpty()) {
+            if (Objects.isNull(subsets) || CollectionUtils.isEmpty(subsets)) {
                 LOG.info("Endpoints {} do not have subsets", serviceName);
             } else {
                 for (V1EndpointSubset subset : subsets) {
                     List<V1EndpointAddress> addresses = subset.getAddresses();
-                    if (addresses == null || addresses.isEmpty()) {
+                    if (Objects.isNull(addresses) || 
CollectionUtils.isEmpty(addresses)) {
                         continue;
                     }
                     for (V1EndpointAddress address : addresses) {
                         String upstreamIp = address.getIp();
                         String defaultPort = 
parsePort(defaultBackend.getService());
-                        if (defaultPort != null) {
-                            DivideUpstream upstream = new DivideUpstream();
-                            upstream.setUpstreamUrl(upstreamIp + ":" + 
defaultPort);
-                            upstream.setWeight(100);
-                            // TODO support config protocol in annotation
-                            upstream.setProtocol("http://";);
-                            upstream.setWarmup(0);
-                            upstream.setStatus(true);
-                            upstream.setUpstreamHost("");
-                            defaultUpstreamList.add(upstream);
+                        if (Objects.nonNull(defaultPort)) {
+                            DubboUpstream upstream = DubboUpstream.builder()
+                                    .upstreamUrl(upstreamIp + ":" + 
defaultPort)
+                                    .weight(100)
+                                    .protocol("http://";)
+                                    .warmup(0)
+                                    .status(true)
+                                    .upstreamHost("")
+                                    .build();
+                            dubboUpstreamList.add(upstream);
                         }
                     }
                 }
             }
         }
-        return defaultUpstreamList;
+        return dubboUpstreamList;
     }
 
-    private List<Pair<SelectorData, RuleData>> parseIngressRule(final 
V1IngressRule ingressRule,
-                                                                final 
List<DivideUpstream> defaultUpstream,
-                                                                final String 
namespace,
-                                                                final 
Map<String, String> annotations) {
-        List<Pair<SelectorData, RuleData>> res = new ArrayList<>();
+    private String parsePort(final V1IngressServiceBackend service) {
+        if (Objects.nonNull(service.getPort())) {
+            if (service.getPort().getNumber() != null && 
service.getPort().getNumber() > 0) {
+                return String.valueOf(service.getPort().getNumber());
+            } else if (service.getPort().getName() != null && 
!"".equals(service.getPort().getName().trim())) {
+                return service.getPort().getName().trim();
+            }
+        }
+        return null;
+    }
+
+    private List<IngressConfiguration> parseIngressRule(final V1IngressRule 
ingressRule,
+                                                                            
final List<DubboUpstream> dubboUpstreamList,
+                                                                            
final String namespace,
+                                                                            
final Map<String, String> annotations) {
+        List<IngressConfiguration> res = new ArrayList<>();
 
         ConditionData hostCondition = null;
-        if (ingressRule.getHost() != null) {
+        if (Objects.nonNull(ingressRule.getHost())) {
             hostCondition = new ConditionData();
             hostCondition.setParamType(ParamTypeEnum.DOMAIN.getName());
             hostCondition.setOperator(OperatorEnum.EQ.getAlias());
             hostCondition.setParamValue(ingressRule.getHost());
         }
-        if (ingressRule.getHttp() != null) {
+        if (Objects.nonNull(ingressRule.getHttp())) {
             List<V1HTTPIngressPath> paths = ingressRule.getHttp().getPaths();
             if (paths != null) {
                 for (V1HTTPIngressPath path : paths) {
@@ -218,14 +232,14 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
                     pathCondition.setParamType(ParamTypeEnum.URI.getName());
                     pathCondition.setParamValue(path.getPath());
                     List<ConditionData> conditionList = new ArrayList<>(2);
-                    if (hostCondition != null) {
+                    if (Objects.nonNull(hostCondition)) {
                         conditionList.add(hostCondition);
                     }
                     conditionList.add(pathCondition);
 
                     SelectorData selectorData = SelectorData.builder()
-                            
.pluginId(String.valueOf(PluginEnum.DIVIDE.getCode()))
-                            .pluginName(PluginEnum.DIVIDE.getName())
+                            
.pluginId(String.valueOf(PluginEnum.DUBBO.getCode()))
+                            .pluginName(PluginEnum.DUBBO.getName())
                             .name(path.getPath())
                             .matchMode(MatchModeEnum.AND.getCode())
                             .type(SelectorTypeEnum.CUSTOM_FLOW.getCode())
@@ -233,76 +247,57 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
                             .logged(false)
                             .continued(true)
                             .conditionList(conditionList).build();
-                    List<DivideUpstream> upstreamList = 
parseUpstream(path.getBackend(), namespace);
+                    List<DubboUpstream> upstreamList = 
parseUpstream(path.getBackend(), namespace);
                     if (upstreamList.isEmpty()) {
-                        upstreamList = defaultUpstream;
+                        upstreamList = dubboUpstreamList;
                     }
                     
selectorData.setHandle(GsonUtils.getInstance().toJson(upstreamList));
 
-                    DivideRuleHandle divideRuleHandle = new DivideRuleHandle();
-                    if (annotations != null) {
-                        
divideRuleHandle.setLoadBalance(annotations.getOrDefault(IngressConstants.LOADBALANCER_ANNOTATION_KEY,
 LoadBalanceEnum.RANDOM.getName()));
-                        
divideRuleHandle.setRetry(Integer.parseInt(annotations.getOrDefault(IngressConstants.RETRY_ANNOTATION_KEY,
 "3")));
-                        
divideRuleHandle.setTimeout(Long.parseLong(annotations.getOrDefault(IngressConstants.TIMEOUT_ANNOTATION_KEY,
 "3000")));
-                        
divideRuleHandle.setHeaderMaxSize(Long.parseLong(annotations.getOrDefault(IngressConstants.HEADER_MAX_SIZE_ANNOTATION_KEY,
 "10240")));
-                        
divideRuleHandle.setRequestMaxSize(Long.parseLong(annotations.getOrDefault(IngressConstants.REQUEST_MAX_SIZE_ANNOTATION_KEY,
 "102400")));
+                    DubboRuleHandle dubboRuleHandle = new DubboRuleHandle();
+                    if (Objects.nonNull(annotations)) {
+                        
dubboRuleHandle.setLoadbalance(annotations.getOrDefault(IngressConstants.LOADBALANCER_ANNOTATION_KEY,
 LoadBalanceEnum.RANDOM.getName()));
                     }
                     RuleData ruleData = RuleData.builder()
                             .name(path.getPath())
-                            .pluginName(PluginEnum.DIVIDE.getName())
+                            .pluginName(PluginEnum.DUBBO.getName())
                             .matchMode(MatchModeEnum.AND.getCode())
                             .conditionDataList(conditionList)
-                            
.handle(GsonUtils.getInstance().toJson(divideRuleHandle))
+                            
.handle(GsonUtils.getInstance().toJson(dubboRuleHandle))
                             .loged(false)
                             .enabled(true).build();
 
-                    res.add(Pair.of(selectorData, ruleData));
+                    List<MetaData> metaDataList = parseMetaData(paths, 
namespace);
+                    for (MetaData metaData : metaDataList) {
+                        res.add(new IngressConfiguration(selectorData, 
ruleData, metaData));
+                    }
                 }
             }
         }
         return res;
     }
 
-    private String parsePort(final V1IngressServiceBackend service) {
-        if (service.getPort() != null) {
-            if (service.getPort().getNumber() != null && 
service.getPort().getNumber() > 0) {
-                return String.valueOf(service.getPort().getNumber());
-            } else if (service.getPort().getName() != null && 
!"".equals(service.getPort().getName().trim())) {
-                return service.getPort().getName().trim();
-            }
-        }
-        return null;
-    }
-
-    private List<DivideUpstream> parseUpstream(final V1IngressBackend backend, 
final String namespace) {
-        List<DivideUpstream> upstreamList = new ArrayList<>();
-        if (backend != null && backend.getService() != null && 
backend.getService().getName() != null) {
+    private List<DubboUpstream> parseUpstream(final V1IngressBackend backend, 
final String namespace) {
+        List<DubboUpstream> upstreamList = new ArrayList<>();
+        if (Objects.nonNull(backend) && Objects.nonNull(backend.getService()) 
&& Objects.nonNull(backend.getService().getName())) {
             String serviceName = backend.getService().getName();
             // shenyu routes directly to the container
-            V1Endpoints v1Endpoints = 
endpointsLister.namespace(namespace).get(serviceName);
-            List<V1EndpointSubset> subsets = v1Endpoints.getSubsets();
-            if (subsets == null || subsets.isEmpty()) {
-                LOG.info("Endpoints {} do not have subsets", serviceName);
+            V1Service v1Service = 
serviceLister.namespace(namespace).get(serviceName);
+            List<String> clusterIPs = v1Service.getSpec().getClusterIPs();
+            if (Objects.isNull(clusterIPs) || 
CollectionUtils.isEmpty(clusterIPs)) {
+                LOG.info("Endpoints {} do not have clusterIPs", serviceName);
             } else {
-                for (V1EndpointSubset subset : subsets) {
-                    List<V1EndpointAddress> addresses = subset.getAddresses();
-                    if (addresses == null || addresses.isEmpty()) {
-                        continue;
-                    }
-                    for (V1EndpointAddress address : addresses) {
-                        String upstreamIp = address.getIp();
-                        String defaultPort = parsePort(backend.getService());
-                        if (defaultPort != null) {
-                            DivideUpstream upstream = new DivideUpstream();
-                            upstream.setUpstreamUrl(upstreamIp + ":" + 
defaultPort);
-                            upstream.setWeight(100);
-                            // TODO support config protocol in annotation
-                            upstream.setProtocol("http://";);
-                            upstream.setWarmup(0);
-                            upstream.setStatus(true);
-                            upstream.setUpstreamHost("");
-                            upstreamList.add(upstream);
-                        }
+                for (String clusterIP : clusterIPs) {
+                    String defaultPort = parsePort(backend.getService());
+                    if (Objects.nonNull(defaultPort)) {
+                        DubboUpstream upstream = DubboUpstream.builder()
+                                .upstreamUrl(clusterIP + ":" + defaultPort)
+                                .weight(100)
+                                .protocol("http://";)
+                                .warmup(0)
+                                .status(true)
+                                .upstreamHost("")
+                                .build();
+                        upstreamList.add(upstream);
                     }
                 }
             }
@@ -310,47 +305,71 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
         return upstreamList;
     }
 
-    private Pair<SelectorData, RuleData> getDefaultRouteConfig(final 
List<DivideUpstream> divideUpstream, final Map<String, String> annotations) {
+    private List<MetaData> parseMetaData(final List<V1HTTPIngressPath> paths, 
final String namespace) {
+        List<MetaData> metaData = new ArrayList<>();
+        for (V1HTTPIngressPath path : paths) {
+            if (path.getPath() == null) {
+                continue;
+            }
+            String serviceName = path.getBackend().getService().getName();
+            V1Service v1Service = 
serviceLister.namespace(namespace).get(serviceName);
+            Map<String, String> annotations = 
v1Service.getMetadata().getAnnotations();
+            metaData.add(MetaData.builder()
+                    
.appName(annotations.getOrDefault(IngressConstants.PLUGIN_DUBBO_APP_NAME, 
"dubbo"))
+                    
.path(annotations.getOrDefault(IngressConstants.PLUGIN_DUBBO_PATH, 
"/dubbo/findById"))
+                    
.rpcType(annotations.getOrDefault(IngressConstants.PLUGIN_DUBBO_RPC_TYPE, 
RpcTypeEnum.DUBBO.getName()))
+                    
.serviceName(annotations.getOrDefault(IngressConstants.PLUGIN_DUBBO_SERVICE_NAME,
 "org.apache.shenyu.examples.apache.dubbo.service.impl.DubboTestServiceImpl"))
+                    
.methodName(annotations.getOrDefault(IngressConstants.PLUGIN_DUBBO_METHOD_NAME, 
"findById"))
+                    .enabled(true)
+                    .build());
+        }
+        return metaData;
+    }
+
+    private IngressConfiguration getDubboRouteConfig(final List<DubboUpstream> 
dubboUpstreamList, final Map<String, String> annotations) {
         final ConditionData conditionData = new ConditionData();
-        conditionData.setParamName("default");
+        conditionData.setParamName("dubbo");
         conditionData.setParamType(ParamTypeEnum.URI.getName());
         conditionData.setOperator(OperatorEnum.PATH_PATTERN.getAlias());
         conditionData.setParamValue("/**");
 
         final SelectorData selectorData = SelectorData.builder()
-                .name("default-selector")
+                .name("dubbo-selector")
                 .sort(Integer.MAX_VALUE)
                 .conditionList(Collections.singletonList(conditionData))
-                .handle(GsonUtils.getInstance().toJson(divideUpstream))
+                .handle(GsonUtils.getInstance().toJson(dubboUpstreamList))
                 .enabled(true)
-                .id("1")
-                .pluginName(PluginEnum.DIVIDE.getName())
-                .pluginId(String.valueOf(PluginEnum.DIVIDE.getCode()))
+                .id(IngressConstants.ID)
+                .pluginName(PluginEnum.DUBBO.getName())
+                .pluginId(String.valueOf(PluginEnum.DUBBO.getCode()))
                 .logged(false)
                 .continued(true)
                 .matchMode(MatchModeEnum.AND.getCode())
                 .type(SelectorTypeEnum.FULL_FLOW.getCode()).build();
 
-        DivideRuleHandle divideRuleHandle = new DivideRuleHandle();
-        // TODO need an annotation parsing common way
-        if (annotations != null) {
-            
divideRuleHandle.setLoadBalance(annotations.getOrDefault(IngressConstants.LOADBALANCER_ANNOTATION_KEY,
 LoadBalanceEnum.RANDOM.getName()));
-            
divideRuleHandle.setRetry(Integer.parseInt(annotations.getOrDefault(IngressConstants.RETRY_ANNOTATION_KEY,
 "3")));
-            
divideRuleHandle.setTimeout(Long.parseLong(annotations.getOrDefault(IngressConstants.TIMEOUT_ANNOTATION_KEY,
 "3000")));
-            
divideRuleHandle.setHeaderMaxSize(Long.parseLong(annotations.getOrDefault(IngressConstants.HEADER_MAX_SIZE_ANNOTATION_KEY,
 "10240")));
-            
divideRuleHandle.setRequestMaxSize(Long.parseLong(annotations.getOrDefault(IngressConstants.REQUEST_MAX_SIZE_ANNOTATION_KEY,
 "102400")));
-        }
         final RuleData ruleData = RuleData.builder()
-                .selectorId("1")
-                .pluginName(PluginEnum.DIVIDE.getName())
-                .name("default-rule")
+                .selectorId(IngressConstants.ID)
+                .pluginName(PluginEnum.DUBBO.getName())
+                .name("dubbo-rule")
                 .matchMode(MatchModeEnum.AND.getCode())
                 .conditionDataList(Collections.singletonList(conditionData))
-                .handle(GsonUtils.getInstance().toJson(divideRuleHandle))
                 .loged(false)
                 .enabled(true)
                 .sort(Integer.MAX_VALUE).build();
 
-        return Pair.of(selectorData, ruleData);
+        MetaData metaData = new MetaData();
+        if (Objects.nonNull(annotations)) {
+            
metaData.setAppName(annotations.getOrDefault(IngressConstants.PLUGIN_DUBBO_APP_NAME,
 "dubbo"));
+            
metaData.setMethodName(annotations.getOrDefault(IngressConstants.PLUGIN_DUBBO_METHOD_NAME,
 "methodName"));
+            
metaData.setPath(annotations.getOrDefault(IngressConstants.PLUGIN_DUBBO_PATH, 
"/dubbo/findAll"));
+            
metaData.setRpcType(annotations.getOrDefault(IngressConstants.PLUGIN_DUBBO_RPC_TYPE,
 RpcTypeEnum.DUBBO.getName()));
+            
metaData.setServiceName(annotations.getOrDefault(IngressConstants.PLUGIN_DUBBO_SERVICE_NAME,
 "dubboService"));
+            
metaData.setContextPath(annotations.getOrDefault(IngressConstants.PLUGIN_DUBBO_CONTEXT_PATH,
 "contextPath"));
+            
metaData.setRpcExt(annotations.getOrDefault(IngressConstants.PLUGIN_DUBBO_RPC_EXT,
 "rpcExt"));
+            
metaData.setServiceName(annotations.getOrDefault(IngressConstants.PLUGIN_DUBBO_SERVICE_NAME,
 "serviceName"));
+            
metaData.setParameterTypes(annotations.getOrDefault(IngressConstants.PLUGIN_DUBBO_PARAMENT_TYPE,
 ""));
+            
metaData.setEnabled(Boolean.parseBoolean(annotations.getOrDefault(IngressConstants.PLUGIN_DUBBO_ENABLED,
 "true")));
+        }
+        return new IngressConfiguration(selectorData, ruleData, metaData);
     }
 }
diff --git 
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/IngressParser.java
 
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/IngressParser.java
index 2483c7bc4..8b523d210 100644
--- 
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/IngressParser.java
+++ 
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/IngressParser.java
@@ -19,45 +19,16 @@ package org.apache.shenyu.k8s.parser;
 
 import io.kubernetes.client.informer.SharedIndexInformer;
 import io.kubernetes.client.informer.cache.Lister;
-import io.kubernetes.client.openapi.ApiException;
 import io.kubernetes.client.openapi.apis.CoreV1Api;
 import io.kubernetes.client.openapi.models.V1Endpoints;
-import io.kubernetes.client.openapi.models.V1EndpointSubset;
-import io.kubernetes.client.openapi.models.V1EndpointAddress;
 import io.kubernetes.client.openapi.models.V1Ingress;
-import io.kubernetes.client.openapi.models.V1IngressBackend;
-import io.kubernetes.client.openapi.models.V1IngressRule;
-import io.kubernetes.client.openapi.models.V1IngressTLS;
-import io.kubernetes.client.openapi.models.V1HTTPIngressPath;
 import io.kubernetes.client.openapi.models.V1Service;
-import io.kubernetes.client.openapi.models.V1IngressServiceBackend;
-import io.kubernetes.client.openapi.models.V1Secret;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.shenyu.common.config.ssl.SslCrtAndKeyStream;
-import org.apache.shenyu.common.dto.ConditionData;
-import org.apache.shenyu.common.dto.RuleData;
-import org.apache.shenyu.common.dto.SelectorData;
-import org.apache.shenyu.common.dto.convert.rule.impl.DivideRuleHandle;
-import org.apache.shenyu.common.dto.convert.selector.DivideUpstream;
-import org.apache.shenyu.common.enums.MatchModeEnum;
-import org.apache.shenyu.common.enums.LoadBalanceEnum;
-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.enums.SelectorTypeEnum;
-import org.apache.shenyu.common.utils.GsonUtils;
 import org.apache.shenyu.k8s.common.IngressConstants;
 import org.apache.shenyu.k8s.common.ShenyuMemoryConfig;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
 import java.util.Objects;
-import java.util.Map;
 
 /**
  * Parser of Ingress.
@@ -90,267 +61,12 @@ public class IngressParser implements 
K8sResourceParser<V1Ingress> {
      */
     @Override
     public ShenyuMemoryConfig parse(final V1Ingress ingress, final CoreV1Api 
coreV1Api) {
-        ShenyuMemoryConfig res = new ShenyuMemoryConfig();
-
-        if (ingress.getSpec() != null) {
-            // Parse the default backend
-            V1IngressBackend defaultBackend = 
ingress.getSpec().getDefaultBackend();
-            List<V1IngressRule> rules = ingress.getSpec().getRules();
-            List<V1IngressTLS> tlsList = ingress.getSpec().getTls();
-
-            String namespace = 
Objects.requireNonNull(ingress.getMetadata()).getNamespace();
-            List<DivideUpstream> defaultUpstreamList = 
parseDefaultService(defaultBackend, namespace);
-
-            if (rules == null || rules.isEmpty()) {
-                // if rules is null, defaultBackend become global default
-                if (defaultBackend != null && defaultBackend.getService() != 
null) {
-                    Pair<SelectorData, RuleData> defaultRouteConfig = 
getDefaultRouteConfig(defaultUpstreamList, 
ingress.getMetadata().getAnnotations());
-                    res.setGlobalDefaultBackend(Pair.of(Pair.of(namespace + 
"/" + ingress.getMetadata().getName(), defaultBackend.getService().getName()),
-                            defaultRouteConfig));
-                }
-            } else {
-                // if rules is not null, defaultBackend is default in this 
ingress
-                List<Pair<SelectorData, RuleData>> routeList = new 
ArrayList<>(rules.size());
-                for (V1IngressRule ingressRule : rules) {
-                    List<Pair<SelectorData, RuleData>> routes = 
parseIngressRule(ingressRule, defaultUpstreamList,
-                            
Objects.requireNonNull(ingress.getMetadata()).getNamespace(), 
ingress.getMetadata().getAnnotations());
-                    routeList.addAll(routes);
-                }
-                res.setRouteConfigList(routeList);
-            }
-
-            // Parse tls
-            if (tlsList != null && !tlsList.isEmpty()) {
-                List<SslCrtAndKeyStream> sslList = new ArrayList<>();
-                for (V1IngressTLS tls : tlsList) {
-                    if (tls.getSecretName() != null && tls.getHosts() != null 
&& !tls.getHosts().isEmpty()) {
-                        try {
-                            V1Secret secret = 
coreV1Api.readNamespacedSecret(tls.getSecretName(), namespace, "ture");
-                            if (secret.getData() != null) {
-                                InputStream keyCertChainInputStream = new 
ByteArrayInputStream(secret.getData().get("tls.crt"));
-                                InputStream keyInputStream = new 
ByteArrayInputStream(secret.getData().get("tls.key"));
-                                tls.getHosts().forEach(host ->
-                                    sslList.add(new SslCrtAndKeyStream(host, 
keyCertChainInputStream, keyInputStream))
-                                );
-                            }
-                        } catch (ApiException e) {
-                            LOG.error("parse tls failed ", e);
-                        }
-                    }
-                }
-                res.setTlsConfigList(sslList);
-            }
+        if 
(Objects.equals(ingress.getMetadata().getAnnotations().get(IngressConstants.PLUGIN_DUBBO_ENABLED),
 "true")) {
+            DubboIngressParser dubboIngressParser = new 
DubboIngressParser(serviceLister, endpointsLister);
+            return dubboIngressParser.parse(ingress, coreV1Api);
+        } else {
+            DivideIngressParser divideIngressParser = new 
DivideIngressParser(serviceLister, endpointsLister);
+            return divideIngressParser.parse(ingress, coreV1Api);
         }
-        return res;
-    }
-
-    private List<DivideUpstream> parseDefaultService(final V1IngressBackend 
defaultBackend, final String namespace) {
-        List<DivideUpstream> defaultUpstreamList = new ArrayList<>();
-        if (defaultBackend != null && defaultBackend.getService() != null) {
-            String serviceName = defaultBackend.getService().getName();
-            // shenyu routes directly to the container
-            V1Endpoints v1Endpoints = 
endpointsLister.namespace(namespace).get(serviceName);
-            List<V1EndpointSubset> subsets = v1Endpoints.getSubsets();
-            if (subsets == null || subsets.isEmpty()) {
-                LOG.info("Endpoints {} do not have subsets", serviceName);
-            } else {
-                for (V1EndpointSubset subset : subsets) {
-                    List<V1EndpointAddress> addresses = subset.getAddresses();
-                    if (addresses == null || addresses.isEmpty()) {
-                        continue;
-                    }
-                    for (V1EndpointAddress address : addresses) {
-                        String upstreamIp = address.getIp();
-                        String defaultPort = 
parsePort(defaultBackend.getService());
-                        if (defaultPort != null) {
-                            DivideUpstream upstream = new DivideUpstream();
-                            upstream.setUpstreamUrl(upstreamIp + ":" + 
defaultPort);
-                            upstream.setWeight(100);
-                            // TODO support config protocol in annotation
-                            upstream.setProtocol("http://";);
-                            upstream.setWarmup(0);
-                            upstream.setStatus(true);
-                            upstream.setUpstreamHost("");
-                            defaultUpstreamList.add(upstream);
-                        }
-                    }
-                }
-            }
-        }
-        return defaultUpstreamList;
-    }
-
-    private List<Pair<SelectorData, RuleData>> parseIngressRule(final 
V1IngressRule ingressRule,
-                                                                final 
List<DivideUpstream> defaultUpstream,
-                                                                final String 
namespace,
-                                                                final 
Map<String, String> annotations) {
-        List<Pair<SelectorData, RuleData>> res = new ArrayList<>();
-
-        ConditionData hostCondition = null;
-        if (ingressRule.getHost() != null) {
-            hostCondition = new ConditionData();
-            hostCondition.setParamType(ParamTypeEnum.DOMAIN.getName());
-            hostCondition.setOperator(OperatorEnum.EQ.getAlias());
-            hostCondition.setParamValue(ingressRule.getHost());
-        }
-        if (ingressRule.getHttp() != null) {
-            List<V1HTTPIngressPath> paths = ingressRule.getHttp().getPaths();
-            if (paths != null) {
-                for (V1HTTPIngressPath path : paths) {
-                    if (path.getPath() == null) {
-                        continue;
-                    }
-
-                    OperatorEnum operator;
-                    if ("ImplementationSpecific".equals(path.getPathType())) {
-                        operator = OperatorEnum.MATCH;
-                    } else if ("Prefix".equals(path.getPathType())) {
-                        operator = OperatorEnum.STARTS_WITH;
-                    } else if ("Exact".equals(path.getPathType())) {
-                        operator = OperatorEnum.EQ;
-                    } else {
-                        LOG.info("Invalid path type, set it with match 
operator");
-                        operator = OperatorEnum.MATCH;
-                    }
-
-                    ConditionData pathCondition = new ConditionData();
-                    pathCondition.setOperator(operator.getAlias());
-                    pathCondition.setParamType(ParamTypeEnum.URI.getName());
-                    pathCondition.setParamValue(path.getPath());
-                    List<ConditionData> conditionList = new ArrayList<>(2);
-                    if (hostCondition != null) {
-                        conditionList.add(hostCondition);
-                    }
-                    conditionList.add(pathCondition);
-
-                    SelectorData selectorData = SelectorData.builder()
-                            
.pluginId(String.valueOf(PluginEnum.DIVIDE.getCode()))
-                            .pluginName(PluginEnum.DIVIDE.getName())
-                            .name(path.getPath())
-                            .matchMode(MatchModeEnum.AND.getCode())
-                            .type(SelectorTypeEnum.CUSTOM_FLOW.getCode())
-                            .enabled(true)
-                            .logged(false)
-                            .continued(true)
-                            .conditionList(conditionList).build();
-                    List<DivideUpstream> upstreamList = 
parseUpstream(path.getBackend(), namespace);
-                    if (upstreamList.isEmpty()) {
-                        upstreamList = defaultUpstream;
-                    }
-                    
selectorData.setHandle(GsonUtils.getInstance().toJson(upstreamList));
-
-                    DivideRuleHandle divideRuleHandle = new DivideRuleHandle();
-                    if (annotations != null) {
-                        
divideRuleHandle.setLoadBalance(annotations.getOrDefault(IngressConstants.LOADBALANCER_ANNOTATION_KEY,
 LoadBalanceEnum.RANDOM.getName()));
-                        
divideRuleHandle.setRetry(Integer.parseInt(annotations.getOrDefault(IngressConstants.RETRY_ANNOTATION_KEY,
 "3")));
-                        
divideRuleHandle.setTimeout(Long.parseLong(annotations.getOrDefault(IngressConstants.TIMEOUT_ANNOTATION_KEY,
 "3000")));
-                        
divideRuleHandle.setHeaderMaxSize(Long.parseLong(annotations.getOrDefault(IngressConstants.HEADER_MAX_SIZE_ANNOTATION_KEY,
 "10240")));
-                        
divideRuleHandle.setRequestMaxSize(Long.parseLong(annotations.getOrDefault(IngressConstants.REQUEST_MAX_SIZE_ANNOTATION_KEY,
 "102400")));
-                    }
-                    RuleData ruleData = RuleData.builder()
-                            .name(path.getPath())
-                            .pluginName(PluginEnum.DIVIDE.getName())
-                            .matchMode(MatchModeEnum.AND.getCode())
-                            .conditionDataList(conditionList)
-                            
.handle(GsonUtils.getInstance().toJson(divideRuleHandle))
-                            .loged(false)
-                            .enabled(true).build();
-
-                    res.add(Pair.of(selectorData, ruleData));
-                }
-            }
-        }
-        return res;
-    }
-
-    private String parsePort(final V1IngressServiceBackend service) {
-        if (service.getPort() != null) {
-            if (service.getPort().getNumber() != null && 
service.getPort().getNumber() > 0) {
-                return String.valueOf(service.getPort().getNumber());
-            } else if (service.getPort().getName() != null && 
!"".equals(service.getPort().getName().trim())) {
-                return service.getPort().getName().trim();
-            }
-        }
-        return null;
-    }
-
-    private List<DivideUpstream> parseUpstream(final V1IngressBackend backend, 
final String namespace) {
-        List<DivideUpstream> upstreamList = new ArrayList<>();
-        if (backend != null && backend.getService() != null && 
backend.getService().getName() != null) {
-            String serviceName = backend.getService().getName();
-            // shenyu routes directly to the container
-            V1Endpoints v1Endpoints = 
endpointsLister.namespace(namespace).get(serviceName);
-            List<V1EndpointSubset> subsets = v1Endpoints.getSubsets();
-            if (subsets == null || subsets.isEmpty()) {
-                LOG.info("Endpoints {} do not have subsets", serviceName);
-            } else {
-                for (V1EndpointSubset subset : subsets) {
-                    List<V1EndpointAddress> addresses = subset.getAddresses();
-                    if (addresses == null || addresses.isEmpty()) {
-                        continue;
-                    }
-                    for (V1EndpointAddress address : addresses) {
-                        String upstreamIp = address.getIp();
-                        String defaultPort = parsePort(backend.getService());
-                        if (defaultPort != null) {
-                            DivideUpstream upstream = new DivideUpstream();
-                            upstream.setUpstreamUrl(upstreamIp + ":" + 
defaultPort);
-                            upstream.setWeight(100);
-                            // TODO support config protocol in annotation
-                            upstream.setProtocol("http://";);
-                            upstream.setWarmup(0);
-                            upstream.setStatus(true);
-                            upstream.setUpstreamHost("");
-                            upstreamList.add(upstream);
-                        }
-                    }
-                }
-            }
-        }
-        return upstreamList;
-    }
-
-    private Pair<SelectorData, RuleData> getDefaultRouteConfig(final 
List<DivideUpstream> divideUpstream, final Map<String, String> annotations) {
-        final ConditionData conditionData = new ConditionData();
-        conditionData.setParamName("default");
-        conditionData.setParamType(ParamTypeEnum.URI.getName());
-        conditionData.setOperator(OperatorEnum.PATH_PATTERN.getAlias());
-        conditionData.setParamValue("/**");
-
-        final SelectorData selectorData = SelectorData.builder()
-                .name("default-selector")
-                .sort(Integer.MAX_VALUE)
-                .conditionList(Collections.singletonList(conditionData))
-                .handle(GsonUtils.getInstance().toJson(divideUpstream))
-                .enabled(true)
-                .id("1")
-                .pluginName(PluginEnum.DIVIDE.getName())
-                .pluginId(String.valueOf(PluginEnum.DIVIDE.getCode()))
-                .logged(false)
-                .continued(true)
-                .matchMode(MatchModeEnum.AND.getCode())
-                .type(SelectorTypeEnum.FULL_FLOW.getCode()).build();
-
-        DivideRuleHandle divideRuleHandle = new DivideRuleHandle();
-        // TODO need an annotation parsing common way
-        if (annotations != null) {
-            
divideRuleHandle.setLoadBalance(annotations.getOrDefault(IngressConstants.LOADBALANCER_ANNOTATION_KEY,
 LoadBalanceEnum.RANDOM.getName()));
-            
divideRuleHandle.setRetry(Integer.parseInt(annotations.getOrDefault(IngressConstants.RETRY_ANNOTATION_KEY,
 "3")));
-            
divideRuleHandle.setTimeout(Long.parseLong(annotations.getOrDefault(IngressConstants.TIMEOUT_ANNOTATION_KEY,
 "3000")));
-            
divideRuleHandle.setHeaderMaxSize(Long.parseLong(annotations.getOrDefault(IngressConstants.HEADER_MAX_SIZE_ANNOTATION_KEY,
 "10240")));
-            
divideRuleHandle.setRequestMaxSize(Long.parseLong(annotations.getOrDefault(IngressConstants.REQUEST_MAX_SIZE_ANNOTATION_KEY,
 "102400")));
-        }
-        final RuleData ruleData = RuleData.builder()
-                .selectorId("1")
-                .pluginName(PluginEnum.DIVIDE.getName())
-                .name("default-rule")
-                .matchMode(MatchModeEnum.AND.getCode())
-                .conditionDataList(Collections.singletonList(conditionData))
-                .handle(GsonUtils.getInstance().toJson(divideRuleHandle))
-                .loged(false)
-                .enabled(true)
-                .sort(Integer.MAX_VALUE).build();
-
-        return Pair.of(selectorData, ruleData);
     }
 }
diff --git 
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/reconciler/IngressReconciler.java
 
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/reconciler/IngressReconciler.java
index 792275d98..8ee10acec 100644
--- 
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/reconciler/IngressReconciler.java
+++ 
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/reconciler/IngressReconciler.java
@@ -26,12 +26,13 @@ import io.kubernetes.client.openapi.ApiClient;
 import io.kubernetes.client.openapi.apis.CoreV1Api;
 import io.kubernetes.client.openapi.models.V1HTTPIngressPath;
 import io.kubernetes.client.openapi.models.V1Ingress;
+import io.kubernetes.client.openapi.models.V1IngressBuilder;
 import io.kubernetes.client.openapi.models.V1IngressRule;
 import io.kubernetes.client.openapi.models.V1Secret;
-import io.kubernetes.client.openapi.models.V1IngressBuilder;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.shenyu.common.config.ssl.ShenyuSniAsyncMapping;
 import org.apache.shenyu.common.config.ssl.SslCrtAndKeyStream;
+import org.apache.shenyu.common.dto.MetaData;
 import org.apache.shenyu.common.dto.PluginData;
 import org.apache.shenyu.common.dto.RuleData;
 import org.apache.shenyu.common.dto.SelectorData;
@@ -41,6 +42,7 @@ import org.apache.shenyu.k8s.cache.IngressCache;
 import org.apache.shenyu.k8s.cache.IngressSecretCache;
 import org.apache.shenyu.k8s.cache.IngressSelectorCache;
 import org.apache.shenyu.k8s.cache.ServiceIngressCache;
+import org.apache.shenyu.k8s.common.IngressConfiguration;
 import org.apache.shenyu.k8s.common.IngressConstants;
 import org.apache.shenyu.k8s.common.ShenyuMemoryConfig;
 import org.apache.shenyu.k8s.parser.IngressParser;
@@ -49,13 +51,13 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import java.util.Set;
-import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.Optional;
+import java.util.Set;
 
 /**
  * The Reconciler of Ingress.
@@ -65,7 +67,7 @@ public class IngressReconciler implements Reconciler {
     private static final Logger LOG = 
LoggerFactory.getLogger(IngressReconciler.class);
 
     // ingressName serviceName selectorData ruleData
-    private static Pair<Pair<String, String>, Pair<SelectorData, RuleData>> 
globalDefaultBackend;
+    private static Pair<Pair<String, String>, IngressConfiguration> 
globalDefaultBackend;
 
     private final Lister<V1Ingress> ingressLister;
 
@@ -90,11 +92,11 @@ public class IngressReconciler implements Reconciler {
      * @param apiClient             apiClient
      */
     public IngressReconciler(final SharedIndexInformer<V1Ingress> 
ingressInformer,
-        final SharedIndexInformer<V1Secret> secretInformer,
-        final ShenyuCacheRepository shenyuCacheRepository,
-        final ShenyuSniAsyncMapping shenyuSniAsyncMapping,
-        final IngressParser ingressParser,
-        final ApiClient apiClient) {
+                             final SharedIndexInformer<V1Secret> 
secretInformer,
+                             final ShenyuCacheRepository shenyuCacheRepository,
+                             final ShenyuSniAsyncMapping shenyuSniAsyncMapping,
+                             final IngressParser ingressParser,
+                             final ApiClient apiClient) {
         this.ingressLister = new Lister<>(ingressInformer.getIndexer());
         this.secretLister = new Lister<>(secretInformer.getIndexer());
         this.shenyuCacheRepository = shenyuCacheRepository;
@@ -177,9 +179,19 @@ public class IngressReconciler implements Reconciler {
     }
 
     private void doDeleteConfigByIngress(final Request request, final 
V1Ingress oldIngress) {
-        List<String> selectorList = 
deleteSelectorByIngressName(request.getNamespace(), request.getName(), 
PluginEnum.DIVIDE.getName());
+        List<String> selectorList = new ArrayList<>();
+        if 
(Objects.equals(oldIngress.getMetadata().getAnnotations().get(IngressConstants.PLUGIN_DUBBO_ENABLED),
 "true")) {
+            selectorList = deleteSelectorByIngressName(request.getNamespace(), 
request.getName(), PluginEnum.DUBBO.getName(),
+                    
oldIngress.getMetadata().getAnnotations().get(IngressConstants.PLUGIN_DUBBO_CONTEXT_PATH));
+        } else {
+            selectorList = deleteSelectorByIngressName(request.getNamespace(), 
request.getName(), PluginEnum.DIVIDE.getName(), "");
+        }
         if (Objects.nonNull(selectorList) && !selectorList.isEmpty()) {
-            IngressSelectorCache.getInstance().remove(request.getNamespace(), 
request.getName(), PluginEnum.DIVIDE.getName());
+            if 
(Objects.equals(oldIngress.getMetadata().getAnnotations().get(IngressConstants.PLUGIN_DUBBO_ENABLED),
 "true")) {
+                
IngressSelectorCache.getInstance().remove(request.getNamespace(), 
request.getName(), PluginEnum.DUBBO.getName());
+            } else {
+                
IngressSelectorCache.getInstance().remove(request.getNamespace(), 
request.getName(), PluginEnum.DIVIDE.getName());
+            }
         }
         List<Pair<String, String>> serviceList = 
parseServiceFromIngress(oldIngress);
         Objects.requireNonNull(serviceList).forEach(pair -> {
@@ -198,54 +210,64 @@ public class IngressReconciler implements Reconciler {
     private void initPlugins(final ShenyuCacheRepository 
shenyuCacheRepository) {
         //GLOBAL
         PluginData globalPlugin = PluginData.builder()
-            .id(String.valueOf(PluginEnum.GLOBAL.getCode()))
-            .name(PluginEnum.GLOBAL.getName())
-            .config("")
-            .role(PluginRoleEnum.SYS.getName())
-            .enabled(true)
-            .sort(PluginEnum.GLOBAL.getCode())
-            .build();
+                .id(String.valueOf(PluginEnum.GLOBAL.getCode()))
+                .name(PluginEnum.GLOBAL.getName())
+                .config("")
+                .role(PluginRoleEnum.SYS.getName())
+                .enabled(true)
+                .sort(PluginEnum.GLOBAL.getCode())
+                .build();
         shenyuCacheRepository.saveOrUpdatePluginData(globalPlugin);
         //uri
         PluginData uriPlugin = PluginData.builder()
-            .id(String.valueOf(PluginEnum.URI.getCode()))
-            .name(PluginEnum.URI.getName())
-            .config("")
-            .role(PluginRoleEnum.SYS.getName())
-            .enabled(true)
-            .sort(PluginEnum.URI.getCode())
-            .build();
+                .id(String.valueOf(PluginEnum.URI.getCode()))
+                .name(PluginEnum.URI.getName())
+                .config("")
+                .role(PluginRoleEnum.SYS.getName())
+                .enabled(true)
+                .sort(PluginEnum.URI.getCode())
+                .build();
         shenyuCacheRepository.saveOrUpdatePluginData(uriPlugin);
         //nettyHttpClient
         PluginData webclientPlugin = PluginData.builder()
-            .id(String.valueOf(PluginEnum.NETTY_HTTP_CLIENT.getCode()))
-            .config("")
-            .name(PluginEnum.NETTY_HTTP_CLIENT.getName())
-            .role(PluginRoleEnum.SYS.getName())
-            .enabled(true)
-            .sort(PluginEnum.NETTY_HTTP_CLIENT.getCode())
-            .build();
+                .id(String.valueOf(PluginEnum.NETTY_HTTP_CLIENT.getCode()))
+                .config("")
+                .name(PluginEnum.NETTY_HTTP_CLIENT.getName())
+                .role(PluginRoleEnum.SYS.getName())
+                .enabled(true)
+                .sort(PluginEnum.NETTY_HTTP_CLIENT.getCode())
+                .build();
         shenyuCacheRepository.saveOrUpdatePluginData(webclientPlugin);
         //divide
         PluginData dividePlugin = PluginData.builder()
-            .id(String.valueOf(PluginEnum.DIVIDE.getCode()))
-            .name(PluginEnum.DIVIDE.getName())
-            .config("{multiSelectorHandle: 1, multiRuleHandle:0}")
-            .role(PluginRoleEnum.SYS.getName())
-            .enabled(true)
-            .sort(PluginEnum.DIVIDE.getCode())
-            .build();
+                .id(String.valueOf(PluginEnum.DIVIDE.getCode()))
+                .name(PluginEnum.DIVIDE.getName())
+                .config("{multiSelectorHandle: 1, multiRuleHandle:0}")
+                .role(PluginRoleEnum.SYS.getName())
+                .enabled(true)
+                .sort(PluginEnum.DIVIDE.getCode())
+                .build();
         shenyuCacheRepository.saveOrUpdatePluginData(dividePlugin);
         //GeneralContextPlugin
         PluginData generalContextPlugin = PluginData.builder()
-            .id(String.valueOf(PluginEnum.GENERAL_CONTEXT.getCode()))
-            .config("")
-            .name(PluginEnum.GENERAL_CONTEXT.getName())
-            .role(PluginRoleEnum.SYS.getName())
-            .enabled(true)
-            .sort(PluginEnum.GENERAL_CONTEXT.getCode())
-            .build();
+                .id(String.valueOf(PluginEnum.GENERAL_CONTEXT.getCode()))
+                .config("")
+                .name(PluginEnum.GENERAL_CONTEXT.getName())
+                .role(PluginRoleEnum.SYS.getName())
+                .enabled(true)
+                .sort(PluginEnum.GENERAL_CONTEXT.getCode())
+                .build();
         shenyuCacheRepository.saveOrUpdatePluginData(generalContextPlugin);
+        //duubo
+        PluginData dubboPlugin = PluginData.builder()
+                .id(String.valueOf(PluginEnum.DUBBO.getCode()))
+                .name(PluginEnum.DUBBO.getName())
+                .config("")
+                .role(PluginRoleEnum.SYS.getName())
+                .enabled(true)
+                .sort(PluginEnum.DUBBO.getCode())
+                .build();
+        shenyuCacheRepository.saveOrUpdatePluginData(dubboPlugin);
     }
 
     /**
@@ -258,7 +280,7 @@ public class IngressReconciler implements Reconciler {
         if (Objects.nonNull(v1Ingress.getMetadata())) {
             Map<String, String> annotations = 
v1Ingress.getMetadata().getAnnotations();
             if (Objects.nonNull(annotations)
-                && 
Objects.nonNull(annotations.get(IngressConstants.K8S_INGRESS_CLASS_ANNOTATION_KEY)))
 {
+                    && 
Objects.nonNull(annotations.get(IngressConstants.K8S_INGRESS_CLASS_ANNOTATION_KEY)))
 {
                 return 
IngressConstants.SHENYU_INGRESS_CLASS.equals(annotations.get(IngressConstants.K8S_INGRESS_CLASS_ANNOTATION_KEY));
             } else {
                 return Objects.nonNull(v1Ingress.getSpec()) && 
IngressConstants.SHENYU_INGRESS_CLASS.equals(v1Ingress.getSpec().getIngressClassName());
@@ -269,7 +291,7 @@ public class IngressReconciler implements Reconciler {
     }
 
     private List<String> deleteSelectorByIngressName(final String namespace, 
final String name,
-        final String pluginName) {
+                                                     final String pluginName, 
final String path) {
         final List<String> selectorList = 
IngressSelectorCache.getInstance().get(namespace, name, pluginName);
         if (Objects.nonNull(selectorList) && !selectorList.isEmpty()) {
             for (String selectorId : selectorList) {
@@ -278,6 +300,10 @@ public class IngressReconciler implements Reconciler {
                 List<String> ruleIdList = new ArrayList<>();
                 ruleList.forEach(rule -> ruleIdList.add(rule.getId()));
                 for (String id : ruleIdList) {
+                    MetaData metaData = 
shenyuCacheRepository.findMetaData(path);
+                    if (Objects.nonNull(metaData)) {
+                        shenyuCacheRepository.deleteMetaData(metaData);
+                    }
                     shenyuCacheRepository.deleteRuleData(pluginName, 
selectorId, id);
                 }
                 shenyuCacheRepository.deleteSelectorData(pluginName, 
selectorId);
@@ -339,45 +365,54 @@ public class IngressReconciler implements Reconciler {
     private void addNewIngressConfigToShenyu(final V1Ingress v1Ingress, final 
CoreV1Api apiClient) throws IOException {
         V1Ingress ingressCopy = new V1IngressBuilder(v1Ingress).build();
         ShenyuMemoryConfig shenyuMemoryConfig = 
ingressParser.parse(ingressCopy, apiClient);
+        String pluginName = 
Objects.equals(ingressCopy.getMetadata().getAnnotations().get(IngressConstants.PLUGIN_DUBBO_ENABLED),
 "true")
+                ? PluginEnum.DUBBO.getName() : PluginEnum.DIVIDE.getName();
         if (Objects.nonNull(shenyuMemoryConfig)) {
-            List<Pair<SelectorData, RuleData>> routeConfigList = 
shenyuMemoryConfig.getRouteConfigList();
-            List<SslCrtAndKeyStream> tlsConfigList = 
shenyuMemoryConfig.getTlsConfigList();
-
-            if (Objects.nonNull(routeConfigList)) {
-                routeConfigList.forEach(routeConfig -> {
-                    SelectorData selectorData = routeConfig.getLeft();
-                    RuleData ruleData = routeConfig.getRight();
-                    if (Objects.nonNull(selectorData)) {
-                        
selectorData.setId(IngressSelectorCache.getInstance().generateSelectorId());
-                        selectorData.setSort(100);
-                        
shenyuCacheRepository.saveOrUpdateSelectorData(selectorData);
-                        if (Objects.nonNull(ruleData)) {
-                            ruleData.setId(selectorData.getId());
-                            ruleData.setSelectorId(selectorData.getId());
-                            ruleData.setSort(100);
-                            
shenyuCacheRepository.saveOrUpdateRuleData(ruleData);
-                            
IngressSelectorCache.getInstance().put(Objects.requireNonNull(v1Ingress.getMetadata()).getNamespace(),
-                                v1Ingress.getMetadata().getName(), 
PluginEnum.DIVIDE.getName(), selectorData.getId());
-                        } else {
-                            
shenyuCacheRepository.deleteSelectorData(selectorData.getPluginName(), 
selectorData.getId());
-                        }
-                    }
-                });
+            List<IngressConfiguration> routeConfigList = 
shenyuMemoryConfig.getRouteConfigList();
+            if (Objects.isNull(routeConfigList)) {
+                return;
             }
+            routeConfigList.forEach(routeConfig -> {
+                SelectorData selectorData = routeConfig.getSelectorData();
+                if (Objects.isNull(selectorData)) {
+                    return;
+                }
+                
selectorData.setId(IngressSelectorCache.getInstance().generateSelectorId());
+                selectorData.setSort(100);
+                shenyuCacheRepository.saveOrUpdateSelectorData(selectorData);
+                RuleData ruleData = routeConfig.getRuleData();
+                if (Objects.isNull(ruleData)) {
+                    
shenyuCacheRepository.deleteSelectorData(selectorData.getPluginName(), 
selectorData.getId());
+                    return;
+                }
+
+                ruleData.setId(selectorData.getId());
+                ruleData.setSelectorId(selectorData.getId());
+                ruleData.setSort(100);
+                shenyuCacheRepository.saveOrUpdateRuleData(ruleData);
+                IngressSelectorCache.getInstance().put(
+                        
Objects.requireNonNull(v1Ingress.getMetadata()).getNamespace(),
+                        v1Ingress.getMetadata().getName(), pluginName, 
selectorData.getId());
+                MetaData metaData = routeConfig.getMetaData();
+                if (Objects.nonNull(metaData)) {
+                    metaData.setId(ruleData.getId());
+                    shenyuCacheRepository.saveOrUpdateMetaData(metaData);
+                }
+            });
 
             if (Objects.nonNull(shenyuMemoryConfig.getGlobalDefaultBackend())) 
{
                 synchronized (IngressReconciler.class) {
                     if (globalDefaultBackend == null) {
                         // Add a default backend
-                        
shenyuCacheRepository.saveOrUpdateSelectorData(shenyuMemoryConfig.getGlobalDefaultBackend().getRight().getLeft());
-                        
shenyuCacheRepository.saveOrUpdateRuleData(shenyuMemoryConfig.getGlobalDefaultBackend().getRight().getRight());
+                        
shenyuCacheRepository.saveOrUpdateSelectorData(shenyuMemoryConfig.getGlobalDefaultBackend().getRight().getSelectorData());
+                        
shenyuCacheRepository.saveOrUpdateRuleData(shenyuMemoryConfig.getGlobalDefaultBackend().getRight().getRuleData());
                         globalDefaultBackend = 
shenyuMemoryConfig.getGlobalDefaultBackend();
                         
IngressSelectorCache.getInstance().put(Objects.requireNonNull(v1Ingress.getMetadata()).getNamespace(),
-                            v1Ingress.getMetadata().getName(), 
PluginEnum.DIVIDE.getName(), 
shenyuMemoryConfig.getGlobalDefaultBackend().getRight().getLeft().getId());
+                                v1Ingress.getMetadata().getName(), pluginName, 
shenyuMemoryConfig.getGlobalDefaultBackend().getRight().getSelectorData().getId());
                     }
                 }
             }
-
+            List<SslCrtAndKeyStream> tlsConfigList = 
shenyuMemoryConfig.getTlsConfigList();
             if (Objects.nonNull(tlsConfigList)) {
                 final String namespace = 
Objects.requireNonNull(v1Ingress.getMetadata()).getNamespace();
                 final String ingressName = v1Ingress.getMetadata().getName();
diff --git 
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/repository/ShenyuCacheRepository.java
 
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/repository/ShenyuCacheRepository.java
index d5c7ac456..d2b5023a4 100644
--- 
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/repository/ShenyuCacheRepository.java
+++ 
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/repository/ShenyuCacheRepository.java
@@ -17,10 +17,13 @@
 
 package org.apache.shenyu.k8s.repository;
 
+import org.apache.shenyu.common.dto.MetaData;
 import org.apache.shenyu.common.dto.PluginData;
 import org.apache.shenyu.common.dto.RuleData;
 import org.apache.shenyu.common.dto.SelectorData;
 import org.apache.shenyu.plugin.base.cache.BaseDataCache;
+import org.apache.shenyu.plugin.base.cache.CommonMetaDataSubscriber;
+import org.apache.shenyu.plugin.base.cache.MetaDataCache;
 import org.apache.shenyu.sync.data.api.PluginDataSubscriber;
 
 import java.util.List;
@@ -37,13 +40,16 @@ public class ShenyuCacheRepository {
 
     private final PluginDataSubscriber subscriber;
 
+    private final CommonMetaDataSubscriber metaDataSubscriber;
+
     /**
      * Shenyu Cache Repository Constructor.
      *
      * @param subscriber PluginDataSubscriber
      */
-    public ShenyuCacheRepository(final PluginDataSubscriber subscriber) {
+    public ShenyuCacheRepository(final PluginDataSubscriber subscriber, final 
CommonMetaDataSubscriber metaDataSubscriber) {
         this.subscriber = subscriber;
+        this.metaDataSubscriber = metaDataSubscriber;
     }
 
     /**
@@ -132,4 +138,29 @@ public class ShenyuCacheRepository {
     public void deleteRuleData(final String pluginName, final String 
selectorId, final String ruleId) {
         
subscriber.unRuleSubscribe(RuleData.builder().pluginName(pluginName).selectorId(selectorId).id(ruleId).build());
     }
+
+    /**
+     * Find MetaData by path.
+     * @param path path
+     * @return MetaData
+     */
+    public MetaData findMetaData(final String path) {
+        return MetaDataCache.getInstance().obtain(path);
+    }
+
+    /**
+     * Save or update MetaData by MetaData.
+     * @param metaData MetaData
+     */
+    public void saveOrUpdateMetaData(final MetaData metaData) {
+        metaDataSubscriber.onSubscribe(metaData);
+    }
+
+    /**
+     * Delete MetaData by MetaData.
+     * @param metaData MetaData
+     */
+    public void deleteMetaData(final MetaData metaData) {
+        metaDataSubscriber.unSubscribe(metaData);
+    }
 }
diff --git 
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-k8s/src/main/java/org/apache/shenyu/springboot/starter/k8s/IngressControllerConfiguration.java
 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-k8s/src/main/java/org/apache/shenyu/springboot/starter/k8s/IngressControllerConfiguration.java
index e54a42638..f151322fd 100644
--- 
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-k8s/src/main/java/org/apache/shenyu/springboot/starter/k8s/IngressControllerConfiguration.java
+++ 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-k8s/src/main/java/org/apache/shenyu/springboot/starter/k8s/IngressControllerConfiguration.java
@@ -42,6 +42,7 @@ import org.apache.shenyu.k8s.parser.IngressParser;
 import org.apache.shenyu.k8s.reconciler.EndpointsReconciler;
 import org.apache.shenyu.k8s.reconciler.IngressReconciler;
 import org.apache.shenyu.k8s.repository.ShenyuCacheRepository;
+import org.apache.shenyu.plugin.base.cache.CommonMetaDataSubscriber;
 import org.apache.shenyu.sync.data.api.PluginDataSubscriber;
 import org.springframework.beans.factory.ObjectProvider;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -157,12 +158,13 @@ public class IngressControllerConfiguration {
     /**
      * ShenyuCacheRepository.
      *
-     * @param subscriber PluginDataSubscriber
+     * @param pluginDataSubscriber PluginDataSubscriber
+     * @param metaDataSubscriber CommonMetaDataSubscriber
      * @return ShenyuCacheRepository
      */
     @Bean
-    public ShenyuCacheRepository shenyuCacheRepository(final 
PluginDataSubscriber subscriber) {
-        return new ShenyuCacheRepository(subscriber);
+    public ShenyuCacheRepository shenyuCacheRepository(final 
PluginDataSubscriber pluginDataSubscriber, final CommonMetaDataSubscriber 
metaDataSubscriber) {
+        return new ShenyuCacheRepository(pluginDataSubscriber, 
metaDataSubscriber);
     }
 
     /**

Reply via email to