You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shenyu.apache.org by jo...@apache.org on 2023/09/14 15:43:18 UTC
[shenyu] branch master updated: add ingress-controller integration apache dubbo test (#5154)
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 e8c496f6f0 add ingress-controller integration apache dubbo test (#5154)
e8c496f6f0 is described below
commit e8c496f6f098f9309a88dd820eb5b8d5198e7ac8
Author: Runqi Zhao <40...@users.noreply.github.com>
AuthorDate: Thu Sep 14 23:43:12 2023 +0800
add ingress-controller integration apache dubbo test (#5154)
* add ingress-controller integration apache dubbo test
* add ingress-controller integration apache dubbo test
* add ingress-controller integration apache dubbo test
---------
Co-authored-by: Kunshuai Zhu <jo...@gmail.com>
---
.../integrated-test-k8s-ingress-apache-dubbo.yml | 136 +++++++++
.../org/apache/shenyu/common/utils/IpUtils.java | 44 +++
.../k8s/ingress.yml | 62 ++--
.../k8s/shenyu-examples-dubbo.yml | 17 +-
...nyu-examples-dubbo.yml => shenyu-zookeeper.yml} | 68 +++--
shenyu-integrated-test/pom.xml | 1 +
.../Dockerfile | 29 ++
.../deploy/deploy-shenyu.yaml | 103 +++++++
.../deploy/kind-config.yaml | 36 +++
.../pom.xml | 185 ++++++++++++
.../script/healthcheck.sh | 36 +++
.../script/services.list | 18 ++
...eDubboIngressControllerIntegratedBootstrap.java | 37 +++
.../src/main/resources/application.yml | 329 +++++++++++++++++++++
.../apache/dubbo/ApacheDubboPluginTest.java | 51 ++++
.../apache/shenyu/k8s/common/IngressConstants.java | 11 +-
.../shenyu/k8s/parser/DubboIngressParser.java | 233 +++++++++------
.../shenyu/k8s/reconciler/EndpointsReconciler.java | 1 +
.../shenyu/k8s/reconciler/IngressReconciler.java | 46 ++-
19 files changed, 1253 insertions(+), 190 deletions(-)
diff --git a/.github/workflows/integrated-test-k8s-ingress-apache-dubbo.yml b/.github/workflows/integrated-test-k8s-ingress-apache-dubbo.yml
new file mode 100644
index 0000000000..65def08f42
--- /dev/null
+++ b/.github/workflows/integrated-test-k8s-ingress-apache-dubbo.yml
@@ -0,0 +1,136 @@
+# 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.
+
+name: it-k8s
+
+on:
+ pull_request:
+ push:
+ branches:
+ - master
+
+jobs:
+ ingress-controller-apche-dubbo:
+ runs-on: ubuntu-latest
+ if: (github.repository == 'apache/shenyu')
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+
+ - uses: dorny/paths-filter@v2
+ id: filter
+ with:
+ filters: '.github/filters.yml'
+ list-files: json
+
+ - name: Clean Space
+ if: steps.filter.outputs.changed == 'true'
+ run: |
+ sudo rm -rf /usr/share/dotnet
+ sudo rm -rf /opt/ghc
+ sudo rm -rf "/usr/local/share/boost"
+ sudo rm -rf "$AGENT_TOOLSDIRECTORY"
+
+ - name: Cache Maven Repos
+ if: steps.filter.outputs.changed == 'true'
+ uses: actions/cache@v3
+ with:
+ path: ~/.m2/repository
+ key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+ restore-keys: |
+ ${{ runner.os }}-maven-
+
+ - uses: actions/setup-java@v3
+ if: steps.filter.outputs.changed == 'true'
+ with:
+ java-version: 8
+ distribution: 'temurin'
+
+ - name: Install Go
+ uses: actions/setup-go@v3
+ with:
+ go-version: 1.17.x
+
+ - name: Install k8s
+ if: steps.filter.outputs.changed == 'true'
+ run: |
+ go install sigs.k8s.io/kind@v0.14.0
+ curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.24.14/bin/linux/amd64/kubectl && sudo install kubectl /usr/local/bin/kubectl
+ kind create cluster --image=kindest/node:v1.21.1 --config=./shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/deploy/kind-config.yaml
+
+ - name: Cache Maven Repos
+ if: steps.filter.outputs.changed == 'true'
+ uses: actions/cache@v3
+ with:
+ path: ~/.m2/repository
+ key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+ restore-keys: |
+ ${{ runner.os }}-maven-
+
+ - uses: actions/setup-java@v3
+ if: steps.filter.outputs.changed == 'true'
+ with:
+ java-version: 8
+ distribution: 'temurin'
+
+ - name: Build with Maven
+ if: steps.filter.outputs.changed == 'true'
+ run: ./mvnw -B clean install -Dmaven.javadoc.skip=true -Dmaven.test.skip=true
+
+ - name: Build integrated tests
+ if: steps.filter.outputs.changed == 'true'
+ run: ./mvnw -B clean install -Pit -DskipTests -f ./shenyu-integrated-test/pom.xml
+
+ - name: Build examples
+ if: steps.filter.outputs.changed == 'true'
+ run: ./mvnw -B clean install -Pexample -Dmaven.javadoc.skip=true -Dmaven.test.skip=true -f ./shenyu-examples/pom.xml
+
+ - name: Build k8s Cluster
+ if: steps.filter.outputs.changed == 'true'
+ run: |
+ kind load docker-image "shenyu-examples-apache-dubbo-service:latest"
+ kind load docker-image "apache/shenyu-integrated-test-k8s-ingress-apache-dubbo:latest"
+ kubectl apply -f ./shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/shenyu-zookeeper.yml
+ kubectl wait --for=condition=Ready pod -l app=shenyu-zk -n shenyu-ingress
+ kubectl apply -f ./shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/shenyu-examples-dubbo.yml
+ kubectl apply -f ./shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/deploy/deploy-shenyu.yaml
+ kubectl apply -f ./shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/ingress.yml
+
+ - name: Wait for k8s Cluster Start up
+ if: steps.filter.outputs.changed == 'true'
+ run: |
+ bash ./shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/script/healthcheck.sh
+
+ - name: Run test
+ id: test
+ if: steps.filter.outputs.changed == 'true'
+ run: ./mvnw test -Pit -f ./shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/pom.xml
+ continue-on-error: true
+
+ - name: Cluster Test after Healthcheck
+ if: steps.filter.outputs.changed == 'true'
+ run: |
+ kubectl get all
+ kubectl get all -n shenyu-ingress
+ kubectl get events --all-namespaces
+ kubectl logs -l app=shenyu-ingress-controller -n shenyu-ingress --tail=-1
+ if [[ ${{steps.test.outcome}} == "failure" ]]; then
+ echo "Test Failed"
+ exit 1
+ else
+ echo "Test Successful"
+ exit 0
+ fi
diff --git a/shenyu-common/src/main/java/org/apache/shenyu/common/utils/IpUtils.java b/shenyu-common/src/main/java/org/apache/shenyu/common/utils/IpUtils.java
index c2acc37ad5..e510b533bd 100644
--- a/shenyu-common/src/main/java/org/apache/shenyu/common/utils/IpUtils.java
+++ b/shenyu-common/src/main/java/org/apache/shenyu/common/utils/IpUtils.java
@@ -20,6 +20,8 @@ package org.apache.shenyu.common.utils;
import java.io.Serializable;
import java.net.Inet4Address;
import java.net.InetAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.net.SocketException;
import java.net.NetworkInterface;
@@ -247,6 +249,48 @@ public final class IpUtils {
return -1;
}
+ /**
+ * get Zookeeper Url.
+ * @param zookeeperUrl zookeeperUrl.
+ * @return ip form zookeeperUrl
+ */
+ public static String getZookeeperHost(final String zookeeperUrl) {
+ if (Objects.isNull(zookeeperUrl) || zookeeperUrl.isEmpty()) {
+ return null;
+ }
+ try {
+ URI uri = new URI(zookeeperUrl);
+ String scheme = uri.getScheme();
+ if (Objects.nonNull(scheme) && ("zookeeper".equals(scheme) || "zk".equals(scheme))) {
+ return uri.getHost();
+ }
+ } catch (URISyntaxException ignored) {
+ }
+
+ String[] parts = zookeeperUrl.split(":");
+ if (parts.length >= 1) {
+ return parts[0];
+ }
+ return null;
+ }
+
+ /**
+ * replace Zookeeper Url.
+ * @param zookeeperUrl String zookeeper address
+ * @param replacement ip form zookeeper address
+ * @return full zookeeper address
+ */
+ public static String replaceZookeeperHost(final String zookeeperUrl, final String replacement) {
+ String extractedHost = getZookeeperHost(zookeeperUrl);
+ if (Objects.nonNull(extractedHost)) {
+ if (isCompleteHost(extractedHost)) {
+ return zookeeperUrl;
+ }
+ return zookeeperUrl.replaceFirst(extractedHost, replacement);
+ }
+ return zookeeperUrl;
+ }
+
private static class NetCard implements Serializable {
private String ip;
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
index ee16556d5d..d8bc3e41d1 100644
--- 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
@@ -16,54 +16,63 @@
apiVersion: v1
kind: Service
metadata:
- name: dubbo-findbyid
+ name: dubbo-find-id
+ namespace: shenyu-ingress
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
+ kubernetes.io/ingress.class: shenyu
+ shenyu.apache.org/plugin-dubbo-enabled: 'true'
+ shenyu.apache.org/plugin-dubbo-app-name: dubbo
+ shenyu.apache.org/plugin-dubbo-path: /findById
+ shenyu.apache.org/plugin-dubbo-rpc-type: dubbo
+ shenyu.apache.org/plugin-dubbo-service-name: org.apache.shenyu.examples.dubbo.api.service.DubboTestService
+ shenyu.apache.org/plugin-dubbo-method-name: findById
+ shenyu.apache.org/plugin-dubbo-params-type: java.lang.String
+ shenyu.apache.org/plugin-dubbo-rpc-expand: |
+ {"group":"","version":"v0.0.2","loadbalance":"random","retries":2,"timeout":10000,"url":"","sent":false,"cluster":"failover","protocol":"dubbo"}
+# shenyu.apache.org/zookeeper-register-address: zookeeper://shenyu-zk:2181
spec:
selector:
- app: shenyu-examples-dubbo
+ app: shenyu-examples-apache-dubbo-service
ports:
- - port: 20880 # Assuming this is the Dubbo service port
+ - port: 8011
---
apiVersion: v1
kind: Service
metadata:
- name: dubbo-findall
+ name: dubbo-find-all
+ namespace: shenyu-ingress
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-path: /findAll
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-service-name: org.apache.shenyu.examples.dubbo.api.service.DubboTestService
shenyu.apache.org/plugin-dubbo-method-name: findAll
- shenyu.apache.org/plugin-dubbo-rule-name: /dubbo/findAll
+ shenyu.apache.org/plugin-dubbo-rpc-expand: |
+ {"group":"","version":"v0.0.2","loadbalance":"random","retries":2,"timeout":10000,"url":"","sent":false,"cluster":"failover","protocol":"dubbo"}
spec:
selector:
- app: shenyu-examples-dubbo
+ app: shenyu-examples-apache-dubbo-service
ports:
- - port: 20880 # Assuming this is the Dubbo service port
+ - port: 8011
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
+ namespace: shenyu-ingress
+ labels:
+ shenyu.apache.org/metadata-labels-1: dubbo-find-id
+ shenyu.apache.org/metadata-labels-2: dubbo-find-all
annotations:
kubernetes.io/ingress.class: shenyu
shenyu.apache.org/plugin-dubbo-enabled: 'true'
+ shenyu.apache.org/zookeeper-register-address: zookeeper://shenyu-zk:2181
+ shenyu.apache.org/upstreams-protocol: dubbo://,dubbo://
name: demo-ingress
spec:
rules:
@@ -71,15 +80,8 @@ spec:
paths:
- backend:
service:
- name: dubbo-findbyid
- port:
- number: 20880
- path: /dubbo/findById
- pathType: ImplementationSpecific
- - backend:
- service:
- name: dubbo-findall
+ name: shenyu-examples-apache-dubbo-service
port:
- number: 20880
- path: /dubbo/findAll
+ number: 20888 # please use dubbo protocol port
+ path: /**
pathType: ImplementationSpecific
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
index 3fec086406..e90bfa33f6 100644
--- 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
@@ -18,6 +18,7 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: shenyu-examples-dubbo-deployment
+ namespace: shenyu-ingress
labels:
app: shenyu-examples-dubbo
all: shenyu-examples-dubbo
@@ -35,20 +36,23 @@ spec:
all: shenyu-examples-dubbo
spec:
containers:
- - image: shenyu-examples-dubbo
+ - image: shenyu-examples-apache-dubbo-service
name: shenyu-examples-dubbo
livenessProbe:
exec:
command:
- - wget -q -O - http://localhost:8189/actuator/health | grep UP || exit 1
+ - wget -q -O - http://localhost:8081/actuator/health | grep UP || exit 1
initialDelaySeconds: 10
failureThreshold: 3
timeoutSeconds: 2
env:
- name: shenyu.register.serverLists
value: http://shenyu-admin:9095
+ - name: dubbo.registry.address
+ value: zookeeper://shenyu-zk:2181
ports:
- - containerPort: 8189
+ - containerPort: 8011
+ - containerPort: 20888
imagePullPolicy: IfNotPresent
restartPolicy: Always
status: {}
@@ -58,6 +62,7 @@ apiVersion: v1
kind: Service
metadata:
name: shenyu-examples-apache-dubbo-service
+ namespace: shenyu-ingress
labels:
app: shenyu-examples-dubbo
all: shenyu-examples-dubbo
@@ -67,9 +72,9 @@ spec:
all: shenyu-examples-dubbo
type: NodePort
ports:
- - name: "8189"
- port: 8189
- targetPort: 8189
+ - name: "8011"
+ port: 8011
+ targetPort: 8011
nodePort: 31190
status:
loadBalancer: {}
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-zookeeper.yml
similarity index 59%
copy from shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/shenyu-examples-dubbo.yml
copy to shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/k8s/shenyu-zookeeper.yml
index 3fec086406..3823508f51 100644
--- 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-zookeeper.yml
@@ -14,42 +14,47 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: shenyu-ingress
+
+---
apiVersion: apps/v1
kind: Deployment
metadata:
- name: shenyu-examples-dubbo-deployment
+ namespace: shenyu-ingress
labels:
- app: shenyu-examples-dubbo
+ app: shenyu-zk
all: shenyu-examples-dubbo
+ name: shenyu-zk
spec:
replicas: 1
selector:
matchLabels:
- app: shenyu-examples-dubbo
+ app: shenyu-zk
all: shenyu-examples-dubbo
strategy: {}
template:
metadata:
+ namespace: shenyu-ingress
labels:
- app: shenyu-examples-dubbo
+ app: shenyu-zk
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
+ - image: zookeeper:latest
+ name: shenyu-zk
+ resources: {}
ports:
- - containerPort: 8189
- imagePullPolicy: IfNotPresent
+ - containerPort: 2181
+ name: client
+ - containerPort: 2888
+ name: server
+ - containerPort: 3888
+ name: leader-election
+ - containerPort: 8080
+ name: website
restartPolicy: Always
status: {}
@@ -57,19 +62,26 @@ status: {}
apiVersion: v1
kind: Service
metadata:
- name: shenyu-examples-apache-dubbo-service
+ name: shenyu-zk
+ namespace: shenyu-ingress
labels:
- app: shenyu-examples-dubbo
+ app: shenyu-zk
all: shenyu-examples-dubbo
spec:
+ type: NodePort
selector:
- app: shenyu-examples-dubbo
+ app: shenyu-zk
all: shenyu-examples-dubbo
- type: NodePort
ports:
- - name: "8189"
- port: 8189
- targetPort: 8189
- nodePort: 31190
-status:
- loadBalancer: {}
+ - 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-integrated-test/pom.xml b/shenyu-integrated-test/pom.xml
index e043c3c434..4e70e6e764 100644
--- a/shenyu-integrated-test/pom.xml
+++ b/shenyu-integrated-test/pom.xml
@@ -48,6 +48,7 @@
<module>shenyu-integrated-test-k8s-ingress-http</module>
<module>shenyu-integrated-test-k8s-ingress-spring-cloud</module>
<module>shenyu-integrated-test-k8s-ingress-motan</module>
+ <module>shenyu-integrated-test-k8s-ingress-apache-dubbo</module>
</modules>
<properties>
diff --git a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/Dockerfile b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/Dockerfile
new file mode 100644
index 0000000000..2b09f50b1f
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/Dockerfile
@@ -0,0 +1,29 @@
+# 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.
+
+FROM openjdk:8-jre-alpine
+
+ENV APP_NAME shenyu-integrated-test-k8s-ingress-apache-dubbo
+ENV LOCAL_PATH /opt/${APP_NAME}
+
+RUN mkdir -p ${LOCAL_PATH}
+
+ADD target/${APP_NAME}.jar ${LOCAL_PATH}
+
+WORKDIR ${LOCAL_PATH}
+EXPOSE 9195
+
+CMD java -jar ${APP_NAME}.jar
diff --git a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/deploy/deploy-shenyu.yaml b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/deploy/deploy-shenyu.yaml
new file mode 100644
index 0000000000..57ee595d36
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/deploy/deploy-shenyu.yaml
@@ -0,0 +1,103 @@
+# 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
+automountServiceAccountToken: true
+kind: ServiceAccount
+metadata:
+ name: shenyu-ingress-controller
+ namespace: shenyu-ingress
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: shenyu-ingress-controller
+ namespace: shenyu-ingress
+ labels:
+ app: shenyu-ingress-controller
+ all: shenyu-ingress-controller
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: shenyu-ingress-controller
+ template:
+ metadata:
+ labels:
+ app: shenyu-ingress-controller
+ spec:
+ containers:
+ - name: shenyu-ingress-controller
+ image: apache/shenyu-integrated-test-k8s-ingress-apache-dubbo:latest
+ ports:
+ - containerPort: 9195
+ imagePullPolicy: IfNotPresent
+ serviceAccountName: shenyu-ingress-controller
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: shenyu-ingress-controller
+ namespace: shenyu-ingress
+spec:
+ selector:
+ app: shenyu-ingress-controller
+ type: NodePort
+ ports:
+ - port: 9195
+ targetPort: 9195
+ nodePort: 30095
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: shenyu-ingress-controller
+ namespace: shenyu-ingress
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - namespaces
+ - services
+ - endpoints
+ - secrets
+ - pods
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - networking.k8s.io
+ resources:
+ - ingresses
+ verbs:
+ - get
+ - list
+ - watch
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: shenyu-ingress-controller
+ namespace: shenyu-ingress
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: shenyu-ingress-controller
+subjects:
+- kind: ServiceAccount
+ name: shenyu-ingress-controller
+ namespace: shenyu-ingress
diff --git a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/deploy/kind-config.yaml b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/deploy/kind-config.yaml
new file mode 100644
index 0000000000..18b7da990e
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/deploy/kind-config.yaml
@@ -0,0 +1,36 @@
+# 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.
+
+kind: Cluster
+apiVersion: kind.x-k8s.io/v1alpha4
+nodes:
+ - role: control-plane
+ kubeadmConfigPatches:
+ - |
+ kind: InitConfiguration
+ nodeRegistration:
+ kubeletExtraArgs:
+ node-labels: "ingress-ready=true"
+ extraPortMappings:
+ - containerPort: 80
+ hostPort: 80
+ protocol: TCP
+ - containerPort: 443
+ hostPort: 443
+ protocol: TCP
+ - containerPort: 30095
+ hostPort: 30095
+ protocol: TCP
\ No newline at end of file
diff --git a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/pom.xml b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/pom.xml
new file mode 100644
index 0000000000..f5974c8f70
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/pom.xml
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-integrated-test</artifactId>
+ <version>2.6.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>shenyu-integrated-test-k8s-ingress-apache-dubbo</artifactId>
+ <name>shenyu-integrated-test-k8s-ingress-apache-dubbo</name>
+
+
+ <dependencies>
+
+ <!--shenyu apache dubbo plugin start-->
+ <dependency>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-spring-boot-starter-plugin-apache-dubbo</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo</artifactId>
+ <version>${apache.dubbo.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>curator-client</artifactId>
+ <version>${curator.version}</version>
+ <exclusions>
+ <exclusion>
+ <artifactId>log4j</artifactId>
+ <groupId>log4j</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>curator-framework</artifactId>
+ <version>${curator.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>curator-recipes</artifactId>
+ <version>${curator.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>curator-x-discovery</artifactId>
+ <version>5.1.0</version>
+ </dependency>
+ <!--shenyu apache dubbo plugin end-->
+
+
+ <dependency>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-integrated-test-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-spring-boot-starter-plugin-httpclient</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-spring-boot-starter-plugin-global</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-spring-boot-starter-plugin-uri</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-spring-boot-starter-plugin-general-context</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-spring-boot-starter-plugin-apache-dubbo</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <!-- shenyu kubernetes controller begin -->
+ <dependency>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-spring-boot-starter-k8s</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <!-- shenyu kubernetes controller end -->
+ </dependencies>
+
+ <profiles>
+ <profile>
+ <id>it</id>
+ <properties>
+ <docker.buildArg.APP_NAME>shenyu-integrated-test-k8s-ingress-apache-dubbo</docker.buildArg.APP_NAME>
+ <docker.image.tag.repo>apache/shenyu-integrated-test-k8s-ingress-apache-dubbo</docker.image.tag.repo>
+ <docker.image.tag.tagName>latest</docker.image.tag.tagName>
+ </properties>
+ <build>
+ <finalName>shenyu-integrated-test-k8s-ingress-apache-dubbo</finalName>
+ <plugins>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>${spring-boot.version}</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <mainClass>org.apache.shenyu.integrated.test.k8s.ingress.apache.dubbo.ApacheDubboIngressControllerIntegratedBootstrap
+ </mainClass>
+ <executable>true</executable>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>io.fabric8</groupId>
+ <artifactId>docker-maven-plugin</artifactId>
+ <version>${docker-maven-plugin.version}</version>
+ <configuration>
+ <images>
+ <image>
+ <name>apache/shenyu-integrated-test-k8s-ingress-apache-dubbo</name>
+ <build>
+ <contextDir>${project.basedir}</contextDir>
+ </build>
+ </image>
+ </images>
+ </configuration>
+ <executions>
+ <execution>
+ <id>start</id>
+ <goals>
+ <goal>build</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <skipTests>false</skipTests>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+</project>
\ No newline at end of file
diff --git a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/script/healthcheck.sh b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/script/healthcheck.sh
new file mode 100644
index 0000000000..22a76034ab
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/script/healthcheck.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+PRGDIR=`dirname "$0"`
+for service in `grep -v -E "^$|^#" ${PRGDIR}/services.list`
+do
+ for loop in `seq 1 30`
+ do
+ status=`curl -o /dev/null -s -w %{http_code} $service`
+ echo -e "curl $service response $status"
+
+ if [ $status -eq 200 ]; then
+ break
+ fi
+
+ sleep 2
+ done
+done
+
+sleep 3
+echo -e "\n-------------------"
diff --git a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/script/services.list b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/script/services.list
new file mode 100644
index 0000000000..a162741c47
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/script/services.list
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+http://localhost:30095/actuator/health
+http://localhost:31190/actuator/health
diff --git a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/src/main/java/org/apache/shenyu/integrated/test/k8s/ingress/apache/dubbo/ApacheDubboIngressControllerIntegratedBootstrap.java b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/src/main/java/org/apache/shenyu/integrated/test/k8s/ingress/apache/dubbo/ApacheDubboIngressControllerIntegratedBootstrap.java
new file mode 100644
index 0000000000..8f89e0a4a7
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/src/main/java/org/apache/shenyu/integrated/test/k8s/ingress/apache/dubbo/ApacheDubboIngressControllerIntegratedBootstrap.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.integrated.test.k8s.ingress.apache.dubbo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * The type Alibaba dubbo integrated bootstrap.
+ */
+@SpringBootApplication
+public class ApacheDubboIngressControllerIntegratedBootstrap {
+
+ /**
+ * The entry point of application.
+ *
+ * @param args the input arguments
+ */
+ public static void main(final String[] args) {
+ SpringApplication.run(ApacheDubboIngressControllerIntegratedBootstrap.class);
+ }
+}
diff --git a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/src/main/resources/application.yml b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/src/main/resources/application.yml
new file mode 100644
index 0000000000..854a16e169
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/src/main/resources/application.yml
@@ -0,0 +1,329 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+server:
+ port: 9195
+ address: 0.0.0.0
+
+spring:
+ main:
+ allow-bean-definition-overriding: true
+ application:
+ name: shenyu-bootstrap
+ codec:
+ max-in-memory-size: 2MB
+ cloud:
+ discovery:
+ enabled: false
+ nacos:
+ discovery:
+ server-addr: 127.0.0.1:8848 # Spring Cloud Alibaba Dubbo use this.
+ enabled: false
+ namespace: ShenyuRegisterCenter
+
+# if you want use ribbon please config every server.
+#springCloud-test:
+# ribbon:
+# NIWSServerListClassName: com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
+
+eureka:
+ client:
+ enabled: false
+ serviceUrl:
+ defaultZone: http://localhost:8761/eureka/
+ instance:
+ prefer-ip-address: true
+
+# security:
+# oauth2:
+# client:
+# registration:
+# <your client-registration-id>:
+# client-id: <your client-id>
+# client-secret: <your client-secret>
+# provider:
+# <your client-registration-id>:
+# authorization-uri: <your authorization-uri>
+# token-uri: <your access-token-uri>
+# user-info-uri: <your user-info-uri>
+# jwk-set-uri: <your jwk-set-uri>
+
+management:
+ health:
+ redis:
+ enabled: false
+ elasticsearch:
+ enabled: false
+ endpoint:
+ health:
+ enabled: true
+ show-details: always
+ endpoints:
+ web:
+ exposure:
+ include: "*" # or health,info
+
+
+shenyu:
+ selectorMatchCache:
+ ## selector L1 cache
+ cache:
+ enabled: false
+ initialCapacity: 10000 # initial capacity in cache
+ maximumSize: 10000 # max size in cache
+ ## selector L2 cache, use trie as L2 cache
+ trie:
+ enabled: false
+ cacheSize: 128 # the number of plug-ins
+ matchMode: antPathMatch
+ ruleMatchCache:
+ ## rule L1 cache
+ cache:
+ enabled: true
+ initialCapacity: 10000 # initial capacity in cache
+ maximumSize: 65536 # max size in cache
+ ## rule L2 cache, use trie as L2 cache
+ trie:
+ enabled: false
+ cacheSize: 1024 # the number of selectors
+ matchMode: antPathMatch
+ netty:
+ http:
+ # set to false, user can custom the netty tcp server config.
+ webServerFactoryEnabled: true
+ selectCount: 1
+ workerCount: 8
+ accessLog: false
+ serverSocketChannel:
+ soRcvBuf: 87380
+ soBackLog: 128
+ soReuseAddr: false
+ connectTimeoutMillis: 10000
+ writeBufferHighWaterMark: 65536
+ writeBufferLowWaterMark: 32768
+ writeSpinCount: 16
+ autoRead: false
+ allocType: "pooled"
+ messageSizeEstimator: 8
+ singleEventExecutorPerGroup: true
+ socketChannel:
+ soKeepAlive: false
+ soReuseAddr: false
+ soLinger: -1
+ tcpNoDelay: true
+ soRcvBuf: 87380
+ soSndBuf: 16384
+ ipTos: 0
+ allowHalfClosure: false
+ connectTimeoutMillis: 10000
+ writeBufferHighWaterMark: 65536
+ writeBufferLowWaterMark: 32768
+ writeSpinCount: 16
+ autoRead: false
+ allocType: "pooled"
+ messageSizeEstimator: 8
+ singleEventExecutorPerGroup: true
+ sni:
+ enabled: false
+ mod: k8s #manul
+ defaultK8sSecretNamespace: shenyu-ingress
+ defaultK8sSecretName: default-cert
+# mod: manual
+# certificates:
+# - domain: 'localhost'
+# keyCertChainFile: '/Users/zhukunshuai/Desktop/cert/example.com+1.pem'
+# keyFile: '/Users/zhukunshuai/Desktop/cert/example.com+1-key.pem'
+# - domain: 'example.com'
+# keyCertChainFile: '/Users/zhukunshuai/Desktop/cert/example.com+1.pem'
+# keyFile: '/Users/zhukunshuai/Desktop/cert/example.com+1-key.pem'
+ httpclient:
+ strategy: netty
+# connectTimeout: 45000
+# responseTimeout: 3000
+# readerIdleTime: 3000
+# writerIdleTime: 3000
+# allIdleTime: 3000
+# readTimeout: 3000
+# writeTimeout: 3000
+# wiretap: false
+# keepAlive: false
+# maxInMemorySize: 1 #1mb
+# pool:
+# type: ELASTIC
+# name: proxy
+# maxConnections: 16
+# acquireTimeout: 45000
+# maxIdleTime: 3000
+# proxy:
+# host:
+# port:
+# username:
+# password:
+# nonProxyHostsPattern:
+# ssl:
+# useInsecureTrustManager: true
+# keyStoreType: PKCS12
+# keyStorePath: classpath:keystore.p12
+# keyStorePassword: 123456
+# keyStoreProvider:
+# keyPassword: 123456
+# trustedX509Certificates:
+# handshakeTimeout:
+# closeNotifyFlushTimeout:
+# closeNotifyReadTimeout:
+# defaultConfigurationType:
+# threadPool:
+# prefix: shenyu
+# selectCount: 1
+# workerCount: 8
+# daemon: true
+ register:
+ enabled: false
+ registerType: zookeeper #etcd #consul
+ serverLists: localhost:2181 #http://localhost:2379 #localhost:8848
+ props:
+ cross:
+ enabled: true
+ allowedHeaders:
+ allowedMethods: "*"
+ allowedAnyOrigin: true # the same of Access-Control-Allow-Origin: "*"
+# allowedOrigin:
+ # format : schema://prefix spacer domain
+ # Access-Control-Allow-Origin: "http://a.apache.org,http://b.apache.org"
+# spacer: "."
+# domain: apache.org
+# prefixes:
+# - a # a.apache.org
+# - b # b.apache.org
+# origins:
+# - c.apache.org
+# - d.apache.org
+# - http://e.apache.org
+# originRegex: ^http(|s)://(.*\.|)abc.com$
+ allowedExpose: ""
+ maxAge: "18000"
+ allowCredentials: true
+
+ switchConfig:
+ local: true
+ collapseSlashes: false
+ file:
+ enabled: true
+ maxSize : 10
+# sync:
+# websocket:
+# urls: ws://localhost:9095/websocket
+# allowOrigin: ws://localhost:9195
+# apollo:
+# appId: shenyu
+# meta: http://localhost:8080
+# env: dev
+# clusterName: test
+# namespace: application
+# zookeeper:
+# url: localhost:2181
+# sessionTimeout: 5000
+# connectionTimeout: 2000
+# http:
+# url: http://localhost:9095
+# username:
+# password:
+# nacos:
+# url: localhost:8848
+# namespace: 1c10d748-af86-43b9-8265-75f487d20c6c
+# username:
+# password:
+# acm:
+# enabled: false
+# endpoint: acm.aliyun.com
+# namespace:
+# accessKey:
+# secretKey:
+# etcd:
+# url: http://localhost:2379
+# consul:
+# url: http://localhost:8500
+# waitTime: 1000
+# watchDelay: 1000
+ exclude:
+ enabled: false
+ paths:
+ - /favicon.ico
+ fallback:
+ enabled: false
+ paths:
+ - /fallback/hystrix
+ - /fallback/resilience4j
+ - /fallback/sentinel
+ health:
+ enabled: true
+ paths:
+ - /actuator
+ - /health_check
+ extPlugin:
+ path:
+ enabled: true
+ threads: 1
+ scheduleTime: 300
+ scheduleDelay: 30
+ scheduler:
+ enabled: false
+ type: fixed
+ threads: 16
+ upstreamCheck:
+ enabled: false
+ poolSize: 10
+ timeout: 3000
+ healthyThreshold: 1
+ unhealthyThreshold: 1
+ interval: 5000
+ printEnabled: true
+ printInterval: 60000
+ springCloudCache:
+ enabled: false
+ ribbon:
+ serverListRefreshInterval: 10000
+ metrics:
+ enabled: false
+ name : prometheus
+ host: 127.0.0.1
+ port: 8090
+ jmxConfig:
+ props:
+ jvm_enabled: true
+# plugins:
+# rate-limiter.enabled: false
+ local:
+ enabled: false
+ sha512Key: "BA3253876AED6BC22D4A6FF53D8406C6AD864195ED144AB5C87621B6C233B548BAEAE6956DF346EC8C17F5EA10F35EE3CBC514797ED7DDD3145464E2A0BAB413"
+# sharedPool:
+# enable: true
+# prefix: "shenyu-shared"
+# corePoolSize: 200
+# maximumPoolSize: 2000
+# keepAliveTime: 60000
+# # 1GB
+# maxWorkQueueMemory: 1073741824
+# # 256MB
+# maxFreeMemory: 268435456
+
+logging:
+ level:
+ root: info
+ org.springframework.boot: info
+ org.apache.ibatis: info
+ org.apache.shenyu.bonuspoint: info
+ org.apache.shenyu.lottery: info
+ org.apache.shenyu: info
diff --git a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/src/test/java/org/apache/shenyu/integrated/test/k8s/ingress/apache/dubbo/ApacheDubboPluginTest.java b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/src/test/java/org/apache/shenyu/integrated/test/k8s/ingress/apache/dubbo/ApacheDubboPluginTest.java
new file mode 100644
index 0000000000..2923e378f2
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-apache-dubbo/src/test/java/org/apache/shenyu/integrated/test/k8s/ingress/apache/dubbo/ApacheDubboPluginTest.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.integrated.test.k8s.ingress.apache.dubbo;
+
+import org.apache.shenyu.integratedtest.common.AbstractPluginDataInit;
+import org.apache.shenyu.integratedtest.common.dto.DubboTest;
+import org.apache.shenyu.integratedtest.common.helper.HttpHelper;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class ApacheDubboPluginTest extends AbstractPluginDataInit {
+
+ private static final HttpHelper HTTP_HELPER = HttpHelper.INSTANCE;
+
+ @BeforeAll
+ public static void setup() {
+ HTTP_HELPER.setGatewayEndpoint("http://localhost:30095");
+ }
+
+ @Test
+ public void testFindById() throws IOException {
+ DubboTest dubboTest = HttpHelper.INSTANCE.getFromGateway("/findById?id=1", DubboTest.class);
+ assertEquals("hello world shenyu Apache, findById", dubboTest.getName());
+ assertEquals("1", dubboTest.getId());
+ }
+
+ @Test
+ public void testFindAll() throws IOException {
+ DubboTest dubboTest = HttpHelper.INSTANCE.getFromGateway("/findAll", DubboTest.class);
+ assertEquals("hello world shenyu Apache, findAll", dubboTest.getName());
+ }
+}
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 22be06a9d3..30a975e72b 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
@@ -55,7 +55,7 @@ public class IngressConstants {
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";
+ 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";
@@ -66,6 +66,15 @@ public class IngressConstants {
// 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 the context path for the Dubbo rpc expand, in string
+ public static final String PLUGIN_DUBBO_RPC_EXPAND = "shenyu.apache.org/plugin-dubbo-rpc-expand";
+
+ //The configuration key to specify the context path for the Dubbo service name, in string
+ public static final String PLUGIN_DUBBO_SREVICE_NAME = "shenyu.apache.org/plugin-dubbo-service-name";
+
+ //The configuration key to specify the context path for the Dubbo service name, in string
+ public static final String PLUGIN_DUBBO_PARAMS_TYPE = "shenyu.apache.org/plugin-dubbo-params-type";
+
// 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";
diff --git a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/DubboIngressParser.java b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/DubboIngressParser.java
index feb32b40d1..c63118620c 100644
--- a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/DubboIngressParser.java
+++ b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/DubboIngressParser.java
@@ -117,7 +117,7 @@ public class DubboIngressParser implements K8sResourceParser<V1Ingress> {
List<IngressConfiguration> routeList = new ArrayList<>(rules.size());
for (V1IngressRule ingressRule : rules) {
List<IngressConfiguration> routes = parseIngressRule(ingressRule, dubboUpstreamList,
- Objects.requireNonNull(ingress.getMetadata()).getNamespace(), ingress.getMetadata().getAnnotations());
+ Objects.requireNonNull(ingress.getMetadata()).getNamespace(), ingress.getMetadata().getAnnotations(), ingress.getMetadata().getLabels());
routeList.addAll(routes);
}
res.setRouteConfigList(routeList);
@@ -196,18 +196,12 @@ public class DubboIngressParser implements K8sResourceParser<V1Ingress> {
}
private List<IngressConfiguration> parseIngressRule(final V1IngressRule ingressRule,
- final List<DubboUpstream> dubboUpstreamList,
- final String namespace,
- final Map<String, String> annotations) {
+ final List<DubboUpstream> dubboUpstreamList,
+ final String namespace,
+ final Map<String, String> annotations,
+ final Map<String, String> labels) {
List<IngressConfiguration> res = new ArrayList<>();
-
- ConditionData hostCondition = null;
- if (Objects.nonNull(ingressRule.getHost())) {
- hostCondition = new ConditionData();
- hostCondition.setParamType(ParamTypeEnum.DOMAIN.getName());
- hostCondition.setOperator(OperatorEnum.EQ.getAlias());
- hostCondition.setParamValue(ingressRule.getHost());
- }
+ ConditionData hostCondition = Objects.nonNull(ingressRule.getHost()) ? createHostCondition(ingressRule.getHost()) : null;
if (Objects.nonNull(ingressRule.getHttp())) {
List<V1HTTPIngressPath> paths = ingressRule.getHttp().getPaths();
if (Objects.nonNull(paths)) {
@@ -215,91 +209,143 @@ public class DubboIngressParser implements K8sResourceParser<V1Ingress> {
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());
+ OperatorEnum operator = getOperator(path.getPathType());
+ ConditionData pathCondition = createPathCondition(path.getPath(), operator);
List<ConditionData> conditionList = new ArrayList<>(2);
if (Objects.nonNull(hostCondition)) {
conditionList.add(hostCondition);
}
conditionList.add(pathCondition);
- SelectorData selectorData = SelectorData.builder()
- .pluginId(String.valueOf(PluginEnum.DUBBO.getCode()))
- .pluginName(PluginEnum.DUBBO.getName())
- .name(path.getPath())
- .matchMode(MatchModeEnum.AND.getCode())
- .type(SelectorTypeEnum.CUSTOM_FLOW.getCode())
- .enabled(true)
- .logged(false)
- .continued(true)
- .conditionList(conditionList).build();
- List<DubboUpstream> upstreamList = parseUpstream(path.getBackend(), namespace);
+ List<DubboUpstream> upstreamList = parseUpstream(path, namespace, annotations);
if (upstreamList.isEmpty()) {
upstreamList = dubboUpstreamList;
}
- selectorData.setHandle(GsonUtils.getInstance().toJson(upstreamList));
-
- DubboRuleHandle dubboRuleHandle = new DubboRuleHandle();
- if (Objects.nonNull(annotations)) {
- dubboRuleHandle.setLoadBalance(annotations.getOrDefault(IngressConstants.LOADBALANCER_ANNOTATION_KEY, LoadBalanceEnum.RANDOM.getName()));
+ SelectorData selectorData = createSelectorData(path.getPath(), conditionList, upstreamList);
+ List<RuleData> ruleDataList = new ArrayList<>();
+ List<MetaData> metaDataList = new ArrayList<>();
+ for (String label : labels.keySet()) {
+ Map<String, String> metadataAnnotations = serviceLister.namespace(namespace).get(labels.get(label)).getMetadata().getAnnotations();
+ DubboRuleHandle ruleHandle = createDubboRuleHandle(annotations);
+ List<ConditionData> ruleConditionList = getRuleConditionList(metadataAnnotations);
+ RuleData ruleData = createRuleData(metadataAnnotations, ruleHandle, ruleConditionList);
+ MetaData metaData = parseMetaData(metadataAnnotations);
+ ruleDataList.add(ruleData);
+ metaDataList.add(metaData);
}
- RuleData ruleData = RuleData.builder()
- .name(path.getPath())
- .pluginName(PluginEnum.DUBBO.getName())
- .matchMode(MatchModeEnum.AND.getCode())
- .conditionDataList(conditionList)
- .handle(GsonUtils.getInstance().toJson(dubboRuleHandle))
- .loged(false)
- .enabled(true).build();
-
- List<MetaData> metaDataList = parseMetaData(paths, namespace);
- res.add(new IngressConfiguration(selectorData, Arrays.asList(ruleData), metaDataList));
+ res.add(new IngressConfiguration(selectorData, ruleDataList, metaDataList));
}
}
}
return res;
}
- private List<DubboUpstream> parseUpstream(final V1IngressBackend backend, final String namespace) {
+ private List<ConditionData> getRuleConditionList(final Map<String, String> annotations) {
+ final List<ConditionData> ruleConditionList = new ArrayList<>();
+ ConditionData ruleCondition = new ConditionData();
+ ruleCondition.setOperator(OperatorEnum.EQ.getAlias());
+ ruleCondition.setParamType(ParamTypeEnum.URI.getName());
+ ruleCondition.setParamValue(annotations.get(IngressConstants.PLUGIN_DUBBO_PATH));
+ ruleConditionList.add(ruleCondition);
+ return ruleConditionList;
+ }
+
+ private ConditionData createHostCondition(final String host) {
+ ConditionData hostCondition = new ConditionData();
+ hostCondition.setParamType(ParamTypeEnum.DOMAIN.getName());
+ hostCondition.setOperator(OperatorEnum.EQ.getAlias());
+ hostCondition.setParamValue(host);
+ return hostCondition;
+ }
+
+ private OperatorEnum getOperator(final String pathType) {
+ if ("ImplementationSpecific".equals(pathType)) {
+ return OperatorEnum.MATCH;
+ } else if ("Prefix".equals(pathType)) {
+ return OperatorEnum.STARTS_WITH;
+ } else if ("Exact".equals(pathType)) {
+ return OperatorEnum.EQ;
+ } else {
+ LOG.info("Invalid path type, set it with match operator");
+ return OperatorEnum.MATCH;
+ }
+ }
+
+ private ConditionData createPathCondition(final String path, final OperatorEnum operator) {
+ ConditionData pathCondition = new ConditionData();
+ pathCondition.setOperator(operator.getAlias());
+ pathCondition.setParamType(ParamTypeEnum.URI.getName());
+ pathCondition.setParamValue(path);
+ return pathCondition;
+ }
+
+ private DubboRuleHandle createDubboRuleHandle(final Map<String, String> annotations) {
+ DubboRuleHandle dubboRuleHandle = new DubboRuleHandle();
+ if (Objects.nonNull(annotations)) {
+ dubboRuleHandle.setLoadBalance(annotations.getOrDefault(IngressConstants.LOADBALANCER_ANNOTATION_KEY, LoadBalanceEnum.RANDOM.getName()));
+ dubboRuleHandle.setTimeout(Long.parseLong(annotations.getOrDefault(IngressConstants.TIMEOUT_ANNOTATION_KEY, "3000")));
+ dubboRuleHandle.setRetries(Integer.parseInt(annotations.getOrDefault(IngressConstants.RETRY_ANNOTATION_KEY, "3")));
+ }
+ return dubboRuleHandle;
+ }
+
+ private SelectorData createSelectorData(final String path, final List<ConditionData> conditionList, final List<DubboUpstream> upstreamList) {
+ return SelectorData.builder()
+ .pluginId(String.valueOf(PluginEnum.DUBBO.getCode()))
+ .pluginName(PluginEnum.DUBBO.getName())
+ .name(path)
+ .matchMode(MatchModeEnum.AND.getCode())
+ .type(SelectorTypeEnum.CUSTOM_FLOW.getCode())
+ .enabled(true)
+ .logged(false)
+ .continued(true)
+ .conditionList(conditionList)
+ .handle(GsonUtils.getInstance().toJson(upstreamList))
+ .build();
+ }
+
+ private RuleData createRuleData(final Map<String, String> metadataAnnotations, final DubboRuleHandle ruleHandle, final List<ConditionData> ruleConditionList) {
+ return RuleData.builder()
+ .name(metadataAnnotations.get(IngressConstants.PLUGIN_DUBBO_PATH))
+ .pluginName(PluginEnum.DUBBO.getName())
+ .matchMode(MatchModeEnum.AND.getCode())
+ .conditionDataList(ruleConditionList)
+ .handle(GsonUtils.getInstance().toJson(ruleHandle))
+ .loged(true)
+ .enabled(true)
+ .build();
+ }
+
+ private List<DubboUpstream> parseUpstream(final V1HTTPIngressPath path, final String namespace, final Map<String, String> annotations) {
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
- V1Service v1Service = serviceLister.namespace(namespace).get(serviceName);
- List<String> clusterIPs = v1Service.getSpec().getClusterIPs();
- Map<String, String> annotations = v1Service.getMetadata().getAnnotations();
+ if (Objects.nonNull(path) && Objects.nonNull(path.getBackend().getService()) && Objects.nonNull(path.getBackend().getService().getName())) {
+ String serviceName = path.getBackend().getService().getName();
+ V1Endpoints v1Endpoints = endpointsLister.namespace(namespace).get(serviceName);
+ List<V1EndpointSubset> subsets = v1Endpoints.getSubsets();
String[] protocols = annotations.get(IngressConstants.UPSTREAMS_PROTOCOL_ANNOTATION_KEY).split(",");
- if (Objects.isNull(clusterIPs) || CollectionUtils.isEmpty(clusterIPs)) {
- LOG.info("Endpoints {} do not have clusterIPs", serviceName);
+ if (Objects.isNull(subsets) || CollectionUtils.isEmpty(subsets)) {
+ LOG.info("Endpoints {} do not have subsets", serviceName);
} else {
- int i = 0;
- for (String clusterIP : clusterIPs) {
- String defaultPort = parsePort(backend.getService());
- if (Objects.nonNull(defaultPort)) {
- DubboUpstream upstream = DubboUpstream.builder()
- .upstreamUrl(clusterIP + ":" + defaultPort)
- .weight(100)
- .protocol(Objects.isNull(protocols[i++]) ? "dubbo" : protocols[i++])
- .warmup(0)
- .status(true)
- .upstreamHost("")
- .build();
- upstreamList.add(upstream);
+ for (V1EndpointSubset subset : subsets) {
+ List<V1EndpointAddress> addresses = subset.getAddresses();
+ if (Objects.isNull(addresses) || addresses.isEmpty()) {
+ continue;
+ }
+ int i = 0;
+ for (V1EndpointAddress address : addresses) {
+ String upstreamIp = address.getIp();
+ String defaultPort = parsePort(path.getBackend().getService());
+ if (Objects.nonNull(defaultPort)) {
+ DubboUpstream upstream = DubboUpstream.builder()
+ .upstreamUrl(upstreamIp + ":" + defaultPort)
+ .weight(100)
+ .protocol(Objects.isNull(protocols[i++]) ? "dubbo://" : protocols[i++])
+ .warmup(0)
+ .status(true)
+ .upstreamHost("")
+ .build();
+ upstreamList.add(upstream);
+ }
}
}
}
@@ -307,25 +353,18 @@ public class DubboIngressParser implements K8sResourceParser<V1Ingress> {
return upstreamList;
}
- 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 MetaData parseMetaData(final Map<String, String> annotations) {
+ return MetaData.builder()
+ .appName(annotations.get(IngressConstants.PLUGIN_DUBBO_APP_NAME))
+ .path(annotations.get(IngressConstants.PLUGIN_DUBBO_PATH))
+ .rpcType(annotations.get(IngressConstants.PLUGIN_DUBBO_RPC_TYPE))
+ .rpcExt(annotations.get(IngressConstants.PLUGIN_DUBBO_RPC_EXPAND))
+ .serviceName(annotations.get(IngressConstants.PLUGIN_DUBBO_SREVICE_NAME))
+ .methodName(annotations.get(IngressConstants.PLUGIN_DUBBO_METHOD_NAME))
+ .parameterTypes(annotations.get(IngressConstants.PLUGIN_DUBBO_PARAMS_TYPE))
+
+ .enabled(true)
+ .build();
}
private IngressConfiguration getDubboRouteConfig(final List<DubboUpstream> dubboUpstreamList, final Map<String, String> annotations) {
diff --git a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/reconciler/EndpointsReconciler.java b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/reconciler/EndpointsReconciler.java
index d96cea67cb..5f2c4511ba 100644
--- a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/reconciler/EndpointsReconciler.java
+++ b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/reconciler/EndpointsReconciler.java
@@ -105,6 +105,7 @@ public class EndpointsReconciler implements Reconciler {
// 2. Update the handler of the selector
List<SelectorData> totalSelectors = shenyuCacheRepository.findSelectorDataList(PluginEnum.DIVIDE.getName());
Set<String> needUpdateSelectorId = new HashSet<>();
+ //TODO Adaptation of other plugins
ingressList.forEach(item -> {
List<String> selectorIdList = IngressSelectorCache.getInstance().get(item.getLeft(), item.getRight(), PluginEnum.DIVIDE.getName());
needUpdateSelectorId.addAll(selectorIdList);
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 ff5185f26c..9258353793 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
@@ -64,6 +64,10 @@ import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import static org.apache.shenyu.common.utils.IpUtils.getZookeeperHost;
+import static org.apache.shenyu.common.utils.IpUtils.isCompleteHost;
+import static org.apache.shenyu.common.utils.IpUtils.replaceZookeeperHost;
+
/**
* The Reconciler of Ingress.
*/
@@ -262,7 +266,7 @@ public class IngressReconciler implements Reconciler {
case DIVIDE:
return "{multiSelectorHandle: 1, multiRuleHandle:0}";
case DUBBO:
- return "{multiSelectorHandle: 1,threadpool:shared,corethreads:0,threads:2147483647,queues:0,register: " + zookeeperUrl + "}";
+ return "{\"register\":\"" + zookeeperUrl + "\",\"multiSelectorHandle\":\"1\",\"threadpool\":\"shared\",\"corethreads\":0,\"threads\":2147483647,\"queues\":0}";
case MOTAN:
return "{\"registerProtocol\":\"zk\",\"registerAddress\":\"" + zookeeperUrl + "\",\"corethreads\":0,\"threads\":2147483647,\"queues\":0,\"threadpool\":\"shared\"}";
case WEB_SOCKET:
@@ -272,17 +276,24 @@ public class IngressReconciler implements Reconciler {
}
}
+ /**
+ * get zookeeper Url.
+ * @param annotations annotations from k8s
+ * @param request request
+ * @return ip form of zookeeper Url
+ */
private String getZookeeperUrl(final Map<String, String> annotations, final Request request) {
- String[] zookeeperPartUrl = annotations.get(IngressConstants.ZOOKEEPER_REGISTER_ADDRESS).split(":");
+ String zookeeperK8sUrl = annotations.get(IngressConstants.ZOOKEEPER_REGISTER_ADDRESS);
String zookeeperUrl = null;
- if (isCorrectIp(zookeeperPartUrl[0])) {
+ String zookeeperK8sIpUrl = getZookeeperHost(zookeeperK8sUrl);
+ if (isCompleteHost(zookeeperK8sIpUrl)) {
zookeeperUrl = annotations.get(IngressConstants.ZOOKEEPER_REGISTER_ADDRESS);
} else {
Lister<V1Endpoints> endpointsLister = ingressParser.getEndpointsLister();
- V1Endpoints v1Endpoints = endpointsLister.namespace(request.getNamespace()).get(zookeeperPartUrl[0]);
+ V1Endpoints v1Endpoints = endpointsLister.namespace(request.getNamespace()).get(zookeeperK8sIpUrl);
List<V1EndpointSubset> subsets = v1Endpoints.getSubsets();
if (Objects.isNull(subsets) || CollectionUtils.isEmpty(subsets)) {
- LOG.info("Endpoints {} do not have subsets", v1Endpoints);
+ LOG.info("Endpoints do not have subsets");
} else {
for (V1EndpointSubset subset : subsets) {
List<V1EndpointAddress> addresses = subset.getAddresses();
@@ -295,35 +306,14 @@ public class IngressReconciler implements Reconciler {
}
}
}
- if (!isCorrectIp(zookeeperUrl)) {
+ if (!isCompleteHost(zookeeperUrl)) {
LOG.info("Please enter the correct zookeeperUrl address");
throw new ShenyuException("zookeeper url:" + zookeeperUrl + " is is error.");
}
- zookeeperUrl = zookeeperUrl + ":" + zookeeperPartUrl[1];
+ zookeeperUrl = replaceZookeeperHost(zookeeperK8sUrl, zookeeperUrl);
return zookeeperUrl;
}
- private boolean isCorrectIp(final String ipString) {
- if (ipString.length() < 7 || ipString.length() > 15) {
- return false;
- }
- String[] ipArray = ipString.split("\\.");
- if (ipArray.length != 4) {
- return false;
- }
- for (int i = 0; i < ipArray.length; i++) {
- try {
- int number = Integer.parseInt(ipArray[i]);
- if (number < 0 || number > 255) {
- return false;
- }
- } catch (Exception e) {
- return false;
- }
- }
- return true;
- }
-
/**
* Check whether the IngressClass is shenyu, check the annotation first.
*