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 acf772130e add integration motan test (#5148)
acf772130e is described below
commit acf772130e73b55b02ca1ed9cf56383bb0c90415
Author: Runqi Zhao <[email protected]>
AuthorDate: Wed Sep 13 18:22:56 2023 +0800
add integration motan test (#5148)
---
.../integrated-test-k8s-ingress-motan.yml | 135 +++++++++
.../shenyu-examples-motan-service/k8s/ingress.yml | 89 ++++++
.../k8s/shenyu-examples-motan.yml | 86 ++++++
.../k8s/shenyu-zookeeper.yml | 81 +++++
shenyu-integrated-test/pom.xml | 1 +
.../Dockerfile | 29 ++
.../deploy/deploy-shenyu.yaml | 107 +++++++
.../deploy/kind-config.yaml | 36 +++
.../pom.xml | 167 ++++++++++
.../script/healthcheck.sh | 36 +++
.../script/services.list | 17 ++
.../MotanIngressControllerIntegratedBootstrap.java | 38 +++
.../src/main/resources/application.yml | 336 +++++++++++++++++++++
.../test/k8s/ingress/motan/MotanPluginTest.java | 49 +++
.../apache/shenyu/k8s/parser/IngressParser.java | 8 +
.../shenyu/k8s/parser/MotanIngressParser.java | 64 ++--
.../shenyu/k8s/parser/SpringCloudParser.java | 3 -
.../shenyu/k8s/reconciler/IngressReconciler.java | 91 ++++--
18 files changed, 1327 insertions(+), 46 deletions(-)
diff --git a/.github/workflows/integrated-test-k8s-ingress-motan.yml
b/.github/workflows/integrated-test-k8s-ingress-motan.yml
new file mode 100644
index 0000000000..f9d24ee532
--- /dev/null
+++ b/.github/workflows/integrated-test-k8s-ingress-motan.yml
@@ -0,0 +1,135 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+name: it-k8s
+
+on:
+ pull_request:
+ push:
+ branches:
+ - master
+
+jobs:
+ ingress-controller-motan:
+ 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/[email protected]
+ 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-motan/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-motan:latest"
+ kind load docker-image
"apache/shenyu-integrated-test-k8s-ingress-motan:latest"
+ kubectl apply -f
./shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/deploy/deploy-shenyu.yaml
+ kubectl apply -f
./shenyu-examples/shenyu-examples-motan/shenyu-examples-motan-service/k8s/shenyu-zookeeper.yml
+ kubectl apply -f
./shenyu-examples/shenyu-examples-motan/shenyu-examples-motan-service/k8s/shenyu-examples-motan.yml
+ kubectl apply -f
./shenyu-examples/shenyu-examples-motan/shenyu-examples-motan-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-motan/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-motan/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-examples/shenyu-examples-motan/shenyu-examples-motan-service/k8s/ingress.yml
b/shenyu-examples/shenyu-examples-motan/shenyu-examples-motan-service/k8s/ingress.yml
new file mode 100644
index 0000000000..8fbd4aeac2
--- /dev/null
+++
b/shenyu-examples/shenyu-examples-motan/shenyu-examples-motan-service/k8s/ingress.yml
@@ -0,0 +1,89 @@
+# 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: motan-demo-hello
+ namespace: shenyu-ingress
+ annotations:
+ kubernetes.io/ingress.class: shenyu
+ shenyu.apache.org/plugin-motan-enabled: 'true'
+ shenyu.apache.org/plugin-motan-app-name: motan
+ shenyu.apache.org/plugin-motan-path: /demo/hello
+ shenyu.apache.org/plugin-motan-rpc-type: motan
+ shenyu.apache.org/plugin-motan-service-name:
org.apache.shenyu.examples.motan.service.MotanDemoService
+ shenyu.apache.org/plugin-motan-method-name: hello
+ shenyu.apache.org/plugin-motan-params-type: java.lang.String
+ shenyu.apache.org/plugin-motan-rpc-expand: |
+
{"methodInfo":[{"methodName":"hello","params":[{"left":"java.lang.String","right":"name"}]}],"group":"motan-shenyu-rpc","timeout":2000,"rpcProtocol":"motan2"}
+ shenyu.apache.org/zookeeper-register-address: shenyu-zk:2181
+spec:
+ selector:
+ app: shenyu-examples-motan-service
+ ports:
+ - port: 8081 # Assuming this is the motan service port
+
+---
+
+apiVersion: v1
+kind: Service
+metadata:
+ name: motan-demo-test-hello
+ namespace: shenyu-ingress
+ annotations:
+ kubernetes.io/ingress.class: shenyu
+ shenyu.apache.org/plugin-motan-enabled: 'true'
+ shenyu.apache.org/plugin-motan-app-name: motan
+ shenyu.apache.org/plugin-motan-path: /demoTest/hello
+ shenyu.apache.org/plugin-motan-rpc-type: motan
+ shenyu.apache.org/plugin-motan-service-name:
org.apache.shenyu.examples.motan.service.MotanDemoService
+ shenyu.apache.org/plugin-motan-method-name: hello
+ shenyu.apache.org/plugin-motan-params-type: java.lang.String
+ shenyu.apache.org/zookeeper-register-address: shenyu-zk:2181
+ shenyu.apache.org/plugin-motan-rpc-expand: |
+
{"methodInfo":[{"methodName":"hello","params":[{"left":"java.lang.String","right":"name"}]}],"group":"motan-shenyu-rpc","timeout":2000,"rpcProtocol":"motan2"}
+spec:
+ selector:
+ app: shenyu-examples-motan-service
+ ports:
+ - port: 8081 # Assuming this is the motan service port
+
+---
+
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ namespace: shenyu-ingress
+ labels:
+ shenyu.apache.org/metadata-labels-1: motan-demo-hello
+ shenyu.apache.org/metadata-labels-2: motan-demo-test-hello
+ annotations:
+ kubernetes.io/ingress.class: shenyu
+ shenyu.apache.org/plugin-motan-enabled: 'true'
+ shenyu.apache.org/zookeeper-register-address: shenyu-zk:2181
+ name: demo-ingress
+spec:
+ rules:
+ - http:
+ paths:
+ - backend:
+ service:
+ name: shenyu-examples-motan-service
+ port:
+ number: 8081
+ path: /**
+ pathType: ImplementationSpecific
diff --git
a/shenyu-examples/shenyu-examples-motan/shenyu-examples-motan-service/k8s/shenyu-examples-motan.yml
b/shenyu-examples/shenyu-examples-motan/shenyu-examples-motan-service/k8s/shenyu-examples-motan.yml
new file mode 100644
index 0000000000..a44ce747ac
--- /dev/null
+++
b/shenyu-examples/shenyu-examples-motan/shenyu-examples-motan-service/k8s/shenyu-examples-motan.yml
@@ -0,0 +1,86 @@
+# 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-motan-deployment
+ namespace: shenyu-ingress
+ labels:
+ app: shenyu-examples-motan
+ all: shenyu-examples-motan
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: shenyu-examples-motan
+ all: shenyu-examples-motan
+ strategy: {}
+ template:
+ metadata:
+ namespace: shenyu-ingress
+ labels:
+ app: shenyu-examples-motan
+ all: shenyu-examples-motan
+ spec:
+ containers:
+ - image: shenyu-examples-motan
+ name: shenyu-examples-motan
+ livenessProbe:
+ exec:
+ command:
+ - 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: motan.registry.protocol
+ value: zookeeper
+ - name: motan.registry.address
+ value: shenyu-zk:2181
+ ports:
+ - containerPort: 8081
+ imagePullPolicy: IfNotPresent
+ restartPolicy: Always
+status: {}
+
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: shenyu-examples-motan-service
+ namespace: shenyu-ingress
+ labels:
+ app: shenyu-examples-motan
+ all: shenyu-examples-motan
+spec:
+ selector:
+ app: shenyu-examples-motan
+ all: shenyu-examples-motan
+ type: NodePort
+ ports:
+ - name: "8081"
+ port: 8081
+ targetPort: 8081
+ nodePort: 31190
+ - name: "8082"
+ port: 8082
+ targetPort: 8082
+ nodePort: 31191
+status:
+ loadBalancer: {}
diff --git
a/shenyu-examples/shenyu-examples-motan/shenyu-examples-motan-service/k8s/shenyu-zookeeper.yml
b/shenyu-examples/shenyu-examples-motan/shenyu-examples-motan-service/k8s/shenyu-zookeeper.yml
new file mode 100644
index 0000000000..6baac49f0a
--- /dev/null
+++
b/shenyu-examples/shenyu-examples-motan/shenyu-examples-motan-service/k8s/shenyu-zookeeper.yml
@@ -0,0 +1,81 @@
+# 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:
+ namespace: shenyu-ingress
+ labels:
+ app: shenyu-zk
+ all: shenyu-examples-motan
+ name: shenyu-zk
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: shenyu-zk
+ all: shenyu-examples-motan
+ strategy: {}
+ template:
+ metadata:
+ namespace: shenyu-ingress
+ labels:
+ app: shenyu-zk
+ all: shenyu-examples-motan
+ spec:
+ containers:
+ - image: zookeeper:3.5.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
+ namespace: shenyu-ingress
+ labels:
+ app: shenyu-zk
+ all: shenyu-examples-motan
+spec:
+ type: NodePort
+ selector:
+ app: shenyu-zk
+ all: shenyu-examples-motan
+ 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-integrated-test/pom.xml b/shenyu-integrated-test/pom.xml
index 7a4f183a13..e043c3c434 100644
--- a/shenyu-integrated-test/pom.xml
+++ b/shenyu-integrated-test/pom.xml
@@ -47,6 +47,7 @@
<module>shenyu-integrated-test-upload-plugin</module>
<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>
</modules>
<properties>
diff --git
a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/Dockerfile
b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/Dockerfile
new file mode 100644
index 0000000000..f438397e76
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/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-motan
+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-motan/deploy/deploy-shenyu.yaml
b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/deploy/deploy-shenyu.yaml
new file mode 100644
index 0000000000..b592f2bee6
--- /dev/null
+++
b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/deploy/deploy-shenyu.yaml
@@ -0,0 +1,107 @@
+# 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: Namespace
+metadata:
+ name: shenyu-ingress
+---
+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-motan: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
+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-motan/deploy/kind-config.yaml
b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/deploy/kind-config.yaml
new file mode 100644
index 0000000000..18b7da990e
--- /dev/null
+++
b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/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-motan/pom.xml
b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/pom.xml
new file mode 100644
index 0000000000..4cb77e8a1e
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/pom.xml
@@ -0,0 +1,167 @@
+<?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-motan</artifactId>
+ <name>shenyu-integrated-test-k8s-ingress-motan</name>
+
+ <dependencies>
+ <!-- apache shenyu motan plugin start-->
+ <dependency>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-spring-boot-starter-plugin-motan</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.weibo</groupId>
+ <artifactId>motan-core</artifactId>
+ <version>${motan.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.weibo</groupId>
+ <artifactId>motan-registry-zookeeper</artifactId>
+ <version>${motan.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.weibo</groupId>
+ <artifactId>motan-transport-netty4</artifactId>
+ <version>${motan.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.weibo</groupId>
+ <artifactId>motan-springsupport</artifactId>
+ <version>${motan.version}</version>
+ </dependency>
+ <!-- apache shenyu motan 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>
+
+ <!-- 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-motan</docker.buildArg.APP_NAME>
+
<docker.image.tag.repo>apache/shenyu-integrated-test-k8s-ingress-motan</docker.image.tag.repo>
+ <docker.image.tag.tagName>latest</docker.image.tag.tagName>
+ </properties>
+ <build>
+ <finalName>shenyu-integrated-test-k8s-ingress-motan</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.motan.MotanIngressControllerIntegratedBootstrap
+ </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-motan</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-motan/script/healthcheck.sh
b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/script/healthcheck.sh
new file mode 100644
index 0000000000..896e784144
--- /dev/null
+++
b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/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 20
+echo -e "\n-------------------"
diff --git
a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/script/services.list
b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/script/services.list
new file mode 100644
index 0000000000..7d66040a11
--- /dev/null
+++
b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/script/services.list
@@ -0,0 +1,17 @@
+# 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:31190/demoTest/hello
diff --git
a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/src/main/java/org/apache/shenyu/integrated/test/k8s/ingress/motan/MotanIngressControllerIntegratedBootstrap.java
b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/src/main/java/org/apache/shenyu/integrated/test/k8s/ingress/motan/MotanIngressControllerIntegratedBootstrap.java
new file mode 100644
index 0000000000..35df5149e7
--- /dev/null
+++
b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/src/main/java/org/apache/shenyu/integrated/test/k8s/ingress/motan/MotanIngressControllerIntegratedBootstrap.java
@@ -0,0 +1,38 @@
+/*
+ * 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.motan;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * The type motan integrated bootstrap.
+ */
+@SpringBootApplication
+public class MotanIngressControllerIntegratedBootstrap {
+
+ /**
+ * main method of App.
+ *
+ * @param args args
+ */
+ public static void main(final String[] args) {
+ SpringApplication.run(MotanIngressControllerIntegratedBootstrap.class);
+ }
+
+}
diff --git
a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/src/main/resources/application.yml
b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/src/main/resources/application.yml
new file mode 100644
index 0000000000..a376fed923
--- /dev/null
+++
b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/src/main/resources/application.yml
@@ -0,0 +1,336 @@
+# 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
+ compression:
+ enabled: true
+ minResponseSize: 1MB # If the response data is greater than 1MB, enable
compression.
+
+spring:
+ main:
+ allow-bean-definition-overriding: true
+ application:
+ name: shenyu-bootstrap
+ codec:
+ max-in-memory-size: 2MB
+ cloud:
+ discovery:
+ enabled: true
+ 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: true
+ serviceUrl:
+ defaultZone: http://127.0.0.1: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: webClient # 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:
+ # polaris:
+ # url: 127.0.0.1:8093
+ # namespace:
+ # fileGroup:
+ # etcd:
+ # url: http://localhost:2379
+ # consul:
+ # url: http://localhost:8500
+ # waitTime: 10000
+ # watchDelay: 10000
+ 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-motan/src/test/java/org/apache/shenyu/integrated/test/k8s/ingress/motan/MotanPluginTest.java
b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/src/test/java/org/apache/shenyu/integrated/test/k8s/ingress/motan/MotanPluginTest.java
new file mode 100644
index 0000000000..a7cab3072f
--- /dev/null
+++
b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-motan/src/test/java/org/apache/shenyu/integrated/test/k8s/ingress/motan/MotanPluginTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.motan;
+
+import com.google.gson.reflect.TypeToken;
+import org.apache.shenyu.integratedtest.common.AbstractPluginDataInit;
+import org.apache.shenyu.integratedtest.common.dto.MotanDTO;
+import org.apache.shenyu.integratedtest.common.helper.HttpHelper;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import java.lang.reflect.Type;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class MotanPluginTest extends AbstractPluginDataInit {
+
+ private static final HttpHelper HTTP_HELPER = HttpHelper.INSTANCE;
+
+ @BeforeAll
+ public static void setup() {
+ HTTP_HELPER.setGatewayEndpoint("http://localhost:30095");
+ }
+
+ @Test
+ public void testHelloWorld() throws Exception {
+ MotanDTO request = new MotanDTO("shenyu");
+ Type returnType = new TypeToken<String>() {
+ }.getType();
+ String response = HttpHelper.INSTANCE.postGateway("/demo/hello",
request, returnType);
+ assertEquals("hello shenyu", response);
+ }
+
+}
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 de72c4b5d2..faab0f7608 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
@@ -78,4 +78,12 @@ public class IngressParser implements
K8sResourceParser<V1Ingress> {
return divideIngressParser.parse(ingress, coreV1Api);
}
}
+
+ /**
+ * get endpointsLister.
+ * @return endpointsLister
+ */
+ public Lister<V1Endpoints> getEndpointsLister() {
+ return endpointsLister;
+ }
}
diff --git
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/MotanIngressParser.java
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/MotanIngressParser.java
index 0bac71ec82..58475c272d 100644
---
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/MotanIngressParser.java
+++
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/MotanIngressParser.java
@@ -105,7 +105,7 @@ public class MotanIngressParser implements
K8sResourceParser<V1Ingress> {
List<IngressConfiguration> routeList = new
ArrayList<>(rules.size());
for (V1IngressRule ingressRule : rules) {
List<IngressConfiguration> routes =
parseIngressRule(ingressRule,
-
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);
@@ -138,7 +138,8 @@ public class MotanIngressParser implements
K8sResourceParser<V1Ingress> {
private List<IngressConfiguration> parseIngressRule(final V1IngressRule
ingressRule,
final String namespace,
- final Map<String,
String> annotations) {
+ final Map<String,
String> annotations,
+ final Map<String,
String> labels) {
List<IngressConfiguration> res = new ArrayList<>();
ConditionData hostCondition = null;
@@ -195,43 +196,54 @@ public class MotanIngressParser implements
K8sResourceParser<V1Ingress> {
.continued(true)
.conditionList(conditionList).build();
- RuleData ruleData = RuleData.builder()
- .name(path.getPath())
- .pluginName(PluginEnum.MOTAN.getName())
- .matchMode(MatchModeEnum.AND.getCode())
- .conditionDataList(ruleConditionDataList)
- .loged(false)
- .enabled(true).build();
+ 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();
+ List<ConditionData> ruleConditionList =
getRuleConditionList(metadataAnnotations);
+ RuleData ruleData =
createRuleData(metadataAnnotations, ruleConditionList);
+ MetaData metaData = parseMetaData(metadataAnnotations);
+ ruleDataList.add(ruleData);
+ metaDataList.add(metaData);
+ }
- MetaData metaData = parseMetaData(path, namespace);
- res.add(new IngressConfiguration(selectorData,
Arrays.asList(ruleData), Arrays.asList(metaData)));
+ res.add(new IngressConfiguration(selectorData,
ruleDataList, metaDataList));
}
}
}
return res;
}
- private MetaData parseMetaData(final V1HTTPIngressPath path, final String
namespace) {
- String serviceName = path.getBackend().getService().getName();
- V1Service v1Service =
serviceLister.namespace(namespace).get(serviceName);
- Map<String, String> annotations =
v1Service.getMetadata().getAnnotations();
- if (!annotations.containsKey(IngressConstants.PLUGIN_MOTAN_APP_NAME)
- ||
!annotations.containsKey(IngressConstants.PLUGIN_MOTAN_METHOD_NAME)
- || !annotations.containsKey(IngressConstants.PLUGIN_MOTAN_PATH)
- ||
!annotations.containsKey(IngressConstants.PLUGIN_MOTAN_SREVICE_NAME)
- ||
!annotations.containsKey(IngressConstants.PLUGIN_MOTAN_RPC_TYPE)) {
- LOG.error("motan metadata is error, please check motan service.
MetaData: [{}]", v1Service.getMetadata());
- throw new ShenyuException(annotations + " is is missing.");
- }
+ 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_MOTAN_PATH));
+ ruleConditionList.add(ruleCondition);
+ return ruleConditionList;
+ }
+
+ private RuleData createRuleData(final Map<String, String>
metadataAnnotations, final List<ConditionData> ruleConditionList) {
+ return RuleData.builder()
+
.name(metadataAnnotations.get(IngressConstants.PLUGIN_MOTAN_PATH))
+ .pluginName(PluginEnum.MOTAN.getName())
+ .matchMode(MatchModeEnum.AND.getCode())
+ .conditionDataList(ruleConditionList)
+ .loged(true)
+ .enabled(true)
+ .build();
+ }
+
+ private MetaData parseMetaData(final Map<String, String> annotations) {
return MetaData.builder()
.appName(annotations.get(IngressConstants.PLUGIN_MOTAN_APP_NAME))
.path(annotations.get(IngressConstants.PLUGIN_MOTAN_PATH))
- .contextPath("/motan")
.rpcType(annotations.get(IngressConstants.PLUGIN_MOTAN_RPC_TYPE))
-
.rpcExt(annotations.getOrDefault(IngressConstants.PLUGIN_MOTAN_RPC_EXPAND, ""))
+
.rpcExt(annotations.get(IngressConstants.PLUGIN_MOTAN_RPC_EXPAND))
.serviceName(annotations.get(IngressConstants.PLUGIN_MOTAN_SREVICE_NAME))
.methodName(annotations.get(IngressConstants.PLUGIN_MOTAN_METHOD_NAME))
-
.parameterTypes(annotations.getOrDefault(IngressConstants.PLUGIN_MOTAN_PARAMS_TYPE,
""))
+
.parameterTypes(annotations.get(IngressConstants.PLUGIN_MOTAN_PARAMS_TYPE))
.enabled(true)
.build();
}
diff --git
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/SpringCloudParser.java
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/SpringCloudParser.java
index 8beb9e98d9..68c2ff4b47 100644
---
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/SpringCloudParser.java
+++
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/SpringCloudParser.java
@@ -281,9 +281,6 @@ public class SpringCloudParser implements
K8sResourceParser<V1Ingress> {
if (Objects.nonNull(path) &&
Objects.nonNull(path.getBackend().getService()) &&
Objects.nonNull(path.getBackend().getService().getName())) {
// shenyu routes directly to the container
String serviceName = path.getBackend().getService().getName();
-// V1Endpoints v1Endpoints =
endpointsLister.namespace(namespace).get(serviceName);
-// List<V1EndpointSubset> subsets = v1Endpoints.getSubsets();
- V1Service v1Service =
serviceLister.namespace(namespace).get(serviceName);
V1Endpoints v1Endpoints =
endpointsLister.namespace(namespace).get(serviceName);
List<V1EndpointSubset> subsets = v1Endpoints.getSubsets();
String[] protocols =
annotations.get(IngressConstants.UPSTREAMS_PROTOCOL_ANNOTATION_KEY).split(",");
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 2944ce47a0..ff5185f26c 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
@@ -24,11 +24,15 @@ import io.kubernetes.client.informer.SharedIndexInformer;
import io.kubernetes.client.informer.cache.Lister;
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.apis.CoreV1Api;
+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.V1IngressBuilder;
import io.kubernetes.client.openapi.models.V1IngressRule;
import io.kubernetes.client.openapi.models.V1Secret;
+import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.shenyu.common.config.ssl.ShenyuSniAsyncMapping;
import org.apache.shenyu.common.config.ssl.SslCrtAndKeyStream;
@@ -38,6 +42,7 @@ import org.apache.shenyu.common.dto.RuleData;
import org.apache.shenyu.common.dto.SelectorData;
import org.apache.shenyu.common.enums.PluginEnum;
import org.apache.shenyu.common.enums.PluginRoleEnum;
+import org.apache.shenyu.common.exception.ShenyuException;
import org.apache.shenyu.k8s.cache.IngressCache;
import org.apache.shenyu.k8s.cache.IngressSecretCache;
import org.apache.shenyu.k8s.cache.IngressSelectorCache;
@@ -52,7 +57,6 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -122,13 +126,15 @@ public class IngressReconciler implements Reconciler {
final V1Ingress oldIngress =
IngressCache.getInstance().get(request.getNamespace(), request.getName());
Map<String, String> annotations =
v1Ingress.getMetadata().getAnnotations();
if
(Objects.equals(annotations.get(IngressConstants.PLUGIN_DUBBO_ENABLED),
"true")) {
- enablePlugin(shenyuCacheRepository, PluginEnum.DUBBO, annotations);
+ String zookeeperUrl = getZookeeperUrl(annotations, request);
+ enablePlugin(shenyuCacheRepository, PluginEnum.DUBBO,
zookeeperUrl);
} else if
(Objects.equals(annotations.get(IngressConstants.PLUGIN_MOTAN_ENABLED),
"true")) {
- enablePlugin(shenyuCacheRepository, PluginEnum.MOTAN, annotations);
+ String zookeeperUrl = getZookeeperUrl(annotations, request);
+ enablePlugin(shenyuCacheRepository, PluginEnum.MOTAN,
zookeeperUrl);
} else if
(Objects.equals(annotations.get(IngressConstants.PLUGIN_SPRING_CLOUD_ENABLED),
"true")) {
- enablePlugin(shenyuCacheRepository, PluginEnum.SPRING_CLOUD,
annotations);
+ enablePlugin(shenyuCacheRepository, PluginEnum.SPRING_CLOUD, null);
} else if
(Objects.equals(annotations.get(IngressConstants.PLUGIN_WEB_SOCKET_ENABLED),
"true")) {
- enablePlugin(shenyuCacheRepository, PluginEnum.WEB_SOCKET,
annotations);
+ enablePlugin(shenyuCacheRepository, PluginEnum.WEB_SOCKET, null);
}
if (Objects.isNull(v1Ingress)) {
if (Objects.nonNull(oldIngress)) {
@@ -195,8 +201,8 @@ public class IngressReconciler implements Reconciler {
selectorList = deleteSelectorByIngressName(request.getNamespace(),
request.getName(), PluginEnum.DUBBO.getName(),
oldIngress.getMetadata().getAnnotations().get(IngressConstants.PLUGIN_DUBBO_CONTEXT_PATH));
} else if
(Objects.equals(oldIngress.getMetadata().getAnnotations().get(IngressConstants.PLUGIN_MOTAN_ENABLED),
"true")) {
- selectorList = deleteSelectorByIngressName(request.getNamespace(),
request.getName(), PluginEnum.MOTAN.getName(),
-
oldIngress.getMetadata().getAnnotations().get(IngressConstants.PLUGIN_MOTAN_CONTEXT_PATH));
+ selectorList = deleteSelectorByIngressName(request.getNamespace(),
request.getName(), PluginEnum.MOTAN.getName(),
+
oldIngress.getMetadata().getAnnotations().get(IngressConstants.PLUGIN_MOTAN_CONTEXT_PATH));
} else if
(Objects.equals(oldIngress.getMetadata().getAnnotations().get(IngressConstants.PLUGIN_SPRING_CLOUD_ENABLED),
"true")) {
selectorList = deleteSelectorByIngressName(request.getNamespace(),
request.getName(), PluginEnum.SPRING_CLOUD.getName(), "");
} else if
(Objects.equals(oldIngress.getMetadata().getAnnotations().get(IngressConstants.PLUGIN_WEB_SOCKET_ENABLED),
"true")) {
@@ -232,18 +238,18 @@ public class IngressReconciler implements Reconciler {
}
private void initPlugins(final ShenyuCacheRepository
shenyuCacheRepository) {
- enablePlugin(shenyuCacheRepository, PluginEnum.GLOBAL, new
HashMap<>());
- enablePlugin(shenyuCacheRepository, PluginEnum.URI, new HashMap<>());
- enablePlugin(shenyuCacheRepository, PluginEnum.NETTY_HTTP_CLIENT, new
HashMap<>());
- enablePlugin(shenyuCacheRepository, PluginEnum.DIVIDE, new
HashMap<>());
- enablePlugin(shenyuCacheRepository, PluginEnum.GENERAL_CONTEXT, new
HashMap<>());
+ enablePlugin(shenyuCacheRepository, PluginEnum.GLOBAL, null);
+ enablePlugin(shenyuCacheRepository, PluginEnum.URI, null);
+ enablePlugin(shenyuCacheRepository, PluginEnum.NETTY_HTTP_CLIENT,
null);
+ enablePlugin(shenyuCacheRepository, PluginEnum.DIVIDE, null);
+ enablePlugin(shenyuCacheRepository, PluginEnum.GENERAL_CONTEXT, null);
}
- private void enablePlugin(final ShenyuCacheRepository
shenyuCacheRepository, final PluginEnum pluginEnum, final Map<String, String>
annotations) {
+ private void enablePlugin(final ShenyuCacheRepository
shenyuCacheRepository, final PluginEnum pluginEnum, final String zookeeperUrl) {
PluginData pluginData = PluginData.builder()
.id(String.valueOf(pluginEnum.getCode()))
.name(pluginEnum.getName())
- .config(getPluginConfig(pluginEnum, annotations))
+ .config(getPluginConfig(pluginEnum, zookeeperUrl))
.role(PluginRoleEnum.SYS.getName())
.enabled(true)
.sort(pluginEnum.getCode())
@@ -251,15 +257,14 @@ public class IngressReconciler implements Reconciler {
shenyuCacheRepository.saveOrUpdatePluginData(pluginData);
}
- private String getPluginConfig(final PluginEnum pluginEnum, final
Map<String, String> annotations) {
- String zookeeperUrl =
annotations.get(IngressConstants.ZOOKEEPER_REGISTER_ADDRESS);
+ private String getPluginConfig(final PluginEnum pluginEnum, final String
zookeeperUrl) {
switch (pluginEnum) {
case DIVIDE:
return "{multiSelectorHandle: 1, multiRuleHandle:0}";
case DUBBO:
return "{multiSelectorHandle:
1,threadpool:shared,corethreads:0,threads:2147483647,queues:0,register: " +
zookeeperUrl + "}";
case MOTAN:
- return "{register: " + zookeeperUrl + ",corethreads: 0,
threads :2147483647,queues:0,threadpool:shared}";
+ return "{\"registerProtocol\":\"zk\",\"registerAddress\":\"" +
zookeeperUrl +
"\",\"corethreads\":0,\"threads\":2147483647,\"queues\":0,\"threadpool\":\"shared\"}";
case WEB_SOCKET:
return "{multiSelectorHandle: 1}";
default:
@@ -267,6 +272,58 @@ public class IngressReconciler implements Reconciler {
}
}
+ private String getZookeeperUrl(final Map<String, String> annotations,
final Request request) {
+ String[] zookeeperPartUrl =
annotations.get(IngressConstants.ZOOKEEPER_REGISTER_ADDRESS).split(":");
+ String zookeeperUrl = null;
+ if (isCorrectIp(zookeeperPartUrl[0])) {
+ zookeeperUrl =
annotations.get(IngressConstants.ZOOKEEPER_REGISTER_ADDRESS);
+ } else {
+ Lister<V1Endpoints> endpointsLister =
ingressParser.getEndpointsLister();
+ V1Endpoints v1Endpoints =
endpointsLister.namespace(request.getNamespace()).get(zookeeperPartUrl[0]);
+ List<V1EndpointSubset> subsets = v1Endpoints.getSubsets();
+ if (Objects.isNull(subsets) || CollectionUtils.isEmpty(subsets)) {
+ LOG.info("Endpoints {} do not have subsets", v1Endpoints);
+ } else {
+ for (V1EndpointSubset subset : subsets) {
+ List<V1EndpointAddress> addresses = subset.getAddresses();
+ if (Objects.isNull(addresses) || addresses.isEmpty()) {
+ continue;
+ }
+ for (V1EndpointAddress address : addresses) {
+ zookeeperUrl = address.getIp();
+ }
+ }
+ }
+ }
+ if (!isCorrectIp(zookeeperUrl)) {
+ LOG.info("Please enter the correct zookeeperUrl address");
+ throw new ShenyuException("zookeeper url:" + zookeeperUrl + " is
is error.");
+ }
+ zookeeperUrl = zookeeperUrl + ":" + zookeeperPartUrl[1];
+ 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.
*