release 0.5.0 (#930)
* set branch protection
* rat exclude ".asf.yaml"
* add master-0.2.0 to branch protection
* Exclude the".flattened-pom.xml" file into the source package (#799)
* Update copyright year (#801)
* fix NPE in ServiceTestUtil.java (#804)
* polish dockerfile for 0.3.0 (#805)
* update dockerfile and enable autotest
* fix test script
* fix zookeeper version
* fix rat
* develop-for-dubbo-3.x branch merge to develop branch (#808)
* [3.0]Add mesh rule route (#789)
* add mesh rule route
* add mesh rule check
* For #756 (#791)
* [ISSUE #760]Application discover support (#807)
* application discover support
* fix checkstyle
* fix ci
* remove useless pom import,modify Chinese comment
* fix UT bug
Co-authored-by: haoyann <1064645534@qq.com>
Co-authored-by: Aaron-boom <55744718+Aaron-boom@users.noreply.github.com>
* Fix generic invoke fail (#810)
* fix generic invoke fail
* fix ci
* Nacos support application discover (#812)
* Fix generic can't invoke repeatedly (#814)
* Reduce nacos mapping service storage (#817)
* optimize some code for RegistryServerSync (#822)
* Fix circular reference (#823)
* Fix service version spell (#824)
* For #756 (#815)
* For #756
* for 830 (#832)
* for 830
* For 830
* For 830
* For 830
* For 830
* For 830
* [Feature] Dubbo Admin provides service mock ability. (#838)
* commit the API
* develop the front page.
* add edit logic
* develop the front page and test.
* ui change
* change the config key and group
* change rule enable to config center.
* update GlobalMockRule update logic.
* remove the GlobalMockRule
* [feature admin mock] move the diver dependency out of the project.
* [feature admin mock] remove the contributor name and date in javadoc.
* [feature admin mock] optimize the delete mock rule step.
* [feature admin mock] fix the dialog cannot be closed when delete successfully.
* [feature admin mock] add the support for h2 database.
* [feature admin mock] rollback to zookeeper registry.
* [feature admin mock] fix properties.
* [feature admin mock] change mock-admin-api maven version.
* [feature admin mock] fix the feedback and add the parameters in docker-compose.
* [feature admin mock] fix the ci problem.
* [feature admin mock] fix the ci problem.
* [feature admin mock] removed unused import.
* [feature admin mock] add license.
* GovernanceConfiguration use dubbo instead DynamicConfiguration (#840)
* GovernanceConfiguration use dubbo instead DynamicConfiguration
* remove useless change
* for release 0.4.0 (#850)
* [ISSUE #856] update README.md (#857)
* 修复更新,删除service类型的条件路由异常的问题 (#861)
* Fix flaky (#883)
* fix flaky test
* Delete dubbo-admin-server/.nondex directory
Co-authored-by: Ubuntu <rootadmin@vm001.qmx3d0w2ozeuflvliyjbpujvhf.bx.internal.cloudapp.net>
* support jdk11 #862 (#886)
* support jdk11 #862
* support jdk11 #862
Co-authored-by: 卫龙 <weilong@yeteam.com>
* fix #895 (#896)
Co-authored-by: 卫龙 <weilong@yeteam.com>
* fix #893 (#894)
fix #893
Co-authored-by: 卫龙 <weilong@yeteam.com>
* Update index.html (#899)
原cdn.bootcss.com域名失效,需要切换到新域名cdn.bootcdn.net
官网申明:https://www.bootcdn.cn
* support swagger.enable (#902)
* support swagger.enable
* enable swagger by default
Co-authored-by: 璟源 <jingyuan.mj@alibaba-inc.com>
* support dubbo 3.0.8 (#903)
* [Fix bug](#908) (#910)
* ZookeeperMetaDataCollector init method add zk digest acl support (#911)
* Fix notice and opt registry source (#913)
* update year
* fix search
* add relation support
* disable swagger
* Bump fastjson from 1.2.67 to 1.2.83 (#907)
Bumps [fastjson](https://github.com/alibaba/fastjson) from 1.2.67 to 1.2.83.
- [Release notes](https://github.com/alibaba/fastjson/releases)
- [Commits](https://github.com/alibaba/fastjson/compare/1.2.67...1.2.83)
---
updated-dependencies:
- dependency-name: com.alibaba:fastjson
dependency-type: direct:production
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Add seriialization & timeout (#914)
* update year
* fix search
* add relation support
* disable swagger
* fix interface
* fix interface
* 解决重复点功能,浏览器控制台报错问题,如点击:服务查询-搜索按钮 (#916)
* Fix error when host is null (#920)
* 解决重复点功能,浏览器控制台报错问题,如点击:服务查询-搜索按钮
* 解决可能产生的空指针问题,导致 '消费者'标签无法显示数据
* 解决在服务测试,方法执行成功后。动态生成的consumer元数据,host取值为空的问题情况(dubbo version 3.0.8)
* Update ServiceDetail.vue (#921)
* Up develop (#926)
* release 0.5.0
Co-authored-by: wuwen <wuwen.55@aliyun.com>
Co-authored-by: Huang YunKun <htynkn@gmail.com>
Co-authored-by: haoyann <1064645534@qq.com>
Co-authored-by: Aaron-boom <55744718+Aaron-boom@users.noreply.github.com>
Co-authored-by: Wang Chengming <634749869@qq.com>
Co-authored-by: brotherlu-xcq <1285823170@qq.com>
Co-authored-by: Robert LU <robberphex@gmail.com>
Co-authored-by: ymybxx <775289630@qq.com>
Co-authored-by: plzdoo <55066376+plzdoo@users.noreply.github.com>
Co-authored-by: Ubuntu <rootadmin@vm001.qmx3d0w2ozeuflvliyjbpujvhf.bx.internal.cloudapp.net>
Co-authored-by: chenjjl <50745778+chenjjl@users.noreply.github.com>
Co-authored-by: 卫龙 <weilong@yeteam.com>
Co-authored-by: VirensCn <595170292@qq.com>
Co-authored-by: itmajing <itmajing@163.com>
Co-authored-by: 璟源 <jingyuan.mj@alibaba-inc.com>
Co-authored-by: sherl0ckLiu <108274057+sherl0ckLiu@users.noreply.github.com>
Co-authored-by: sage.xue <job.xueqi@outlook.com>
Co-authored-by: Albumen Kevin <jhq0812@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: cnjxzhao <85160585+cnjxzhao@users.noreply.github.com>
diff --git a/NOTICE b/NOTICE
index 6367c40..9776704 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,5 +1,5 @@
Apache Dubbo Admin
-Copyright 2018-2021 The Apache Software Foundation
+Copyright 2018-2022 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
diff --git a/README.md b/README.md
index e018245..20b1122 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,11 @@
- [Vue.js](https://vuejs.org) and [Vue Cli](https://cli.vuejs.org/)
- [dubbo-admin-ui/README.md](dubbo-admin-ui/README.md) for more detail
-- Set npm **proxy mirror**: if you have network issue, you can set npm proxy mirror to speedup npm install: add `registry =https://registry.npm.taobao.org` to ~/.npmrc
+- Set npm **proxy mirror**:
+
+ if you have network issue, you can set npm proxy mirror to speedup npm install:
+
+ add `registry=https://registry.npmmirror.com` to ~/.npmrc
### admin Server
@@ -35,10 +39,9 @@
1. Clone source code on develop branch `git clone https://github.com/apache/dubbo-admin.git`
2. Specify registry address in `dubbo-admin-server/src/main/resources/application.properties`
3. Build
-
- > - `mvn clean package -Dmaven.test.skip=true`
+ - `mvn clean package -Dmaven.test.skip=true`
4. Start
- * `mvn --projects dubbo-admin-server spring-boot:run`
+ * `mvn --projects dubbo-admin-server spring-boot:run`
OR
* `cd dubbo-admin-distribution/target`; `java -jar dubbo-admin-0.1.jar`
5. Visit `http://localhost:8080`
@@ -47,10 +50,15 @@
### Development Setup
* Run admin server project
- backend is a standard spring boot project, you can run it in any java IDE
+
+ backend is a standard spring boot project, you can run it in any java IDE
+
* Run admin ui project
+
run with `npm run dev`.
+
* visit web page
+
visit `http://localhost:8081`, frontend supports hot reload.
### Swagger support
diff --git a/README_ZH.md b/README_ZH.md
index c1a21d1..4d35128 100644
--- a/README_ZH.md
+++ b/README_ZH.md
@@ -20,7 +20,11 @@
- 使用[Vue.js](https://vuejs.org)作为javascript框架
- [dubbo-admin-ui/README.md](dubbo-admin-ui/README.md)中有更详细的介绍
-- 设置 npm **代理镜像** : 如果遇到了网络问题,可以设置npm代理镜像来加速npm install的过程:在~/.npmrc中增加 `registry =https://registry.npm.taobao.org`
+- 设置 npm **代理镜像** :
+
+ 如果遇到了网络问题,可以设置npm代理镜像来加速npm install的过程:
+
+ 在~/.npmrc中增加 `registry=https://registry.npmmirror.com`
### 后端部分
@@ -33,21 +37,25 @@
1. 下载代码: `git clone https://github.com/apache/dubbo-admin.git`
2. 在 `dubbo-admin-server/src/main/resources/application.properties`中指定注册中心地址
3. 构建
-
- > - `mvn clean package -Dmaven.test.skip=true`
+ - `mvn clean package -Dmaven.test.skip=true`
4. 启动
- * `mvn --projects dubbo-admin-server spring-boot:run`
- 或者
- * `cd dubbo-admin-distribution/target; java -jar dubbo-admin-0.1.jar`
+ * `mvn --projects dubbo-admin-server spring-boot:run`
+ 或者
+ * `cd dubbo-admin-distribution/target; java -jar dubbo-admin-0.1.jar`
5. 访问 `http://localhost:8080`
---
### 开发环境配置
* 运行`dubbo admin server`
- `dubbo admin server`是一个标准的spring boot项目, 可以在任何java IDE中运行它
+
+ `dubbo admin server`是一个标准的spring boot项目, 可以在任何java IDE中运行它
+
* 运行`dubbo admin ui`
+
`dubbo admin ui`由npm管理和构建,在开发环境中,可以单独运行: `npm run dev`
+
* 页面访问
+
访问 `http://localhost:8081`, 由于前后端分开部署,前端支持热加载,任何页面的修改都可以实时反馈,不需要重启应用。
### Swagger 支持
diff --git a/docker/0.4.0/Dockerfile b/docker/0.4.0/Dockerfile
new file mode 100644
index 0000000..621959c
--- /dev/null
+++ b/docker/0.4.0/Dockerfile
@@ -0,0 +1,30 @@
+# 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 maven:3-openjdk-8
+RUN mkdir /source && wget https://github.com/apache/dubbo-admin/archive/0.4.0.zip && unzip -q 0.4.0.zip -d /source
+WORKDIR /source/dubbo-admin-0.4.0
+RUN mvn --batch-mode clean package -Dmaven.test.skip=true
+
+FROM openjdk:8-jre
+LABEL maintainer="dev@dubbo.apache.org"
+RUN apt-get update && apt-get install -y tini
+COPY --from=0 /source/dubbo-admin-0.4.0/dubbo-admin-distribution/target/dubbo-admin-0.4.0.jar /app.jar
+COPY --from=0 /source/dubbo-admin-0.4.0/docker/entrypoint.sh /usr/local/bin/entrypoint.sh
+
+ENV JAVA_OPTS ""
+
+ENTRYPOINT ["tini", "--", "/usr/local/bin/entrypoint.sh"]
+EXPOSE 8080
diff --git a/docker/0.4.0/Dockerfile.test b/docker/0.4.0/Dockerfile.test
new file mode 100644
index 0000000..dee4d1d
--- /dev/null
+++ b/docker/0.4.0/Dockerfile.test
@@ -0,0 +1,23 @@
+# 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 ubuntu:trusty
+RUN apt-get update && apt-get install -yq curl && apt-get clean
+
+WORKDIR /app
+
+ADD test.sh /app/test.sh
+
+CMD ["bash", "test.sh"]
\ No newline at end of file
diff --git a/docker/0.4.0/docker-compose.test.yml b/docker/0.4.0/docker-compose.test.yml
new file mode 100644
index 0000000..9ac7fec
--- /dev/null
+++ b/docker/0.4.0/docker-compose.test.yml
@@ -0,0 +1,33 @@
+# 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.
+
+zookeeper:
+ image: zookeeper:3.5
+admin:
+ build: .
+ dockerfile: Dockerfile
+ links:
+ - zookeeper
+ environment:
+ - admin.registry.address=zookeeper://zookeeper:2181
+ - admin.config-center=zookeeper://zookeeper:2181
+ - admin.metadata-report.address=zookeeper://zookeeper:2181
+ ports:
+ - 8080
+sut:
+ build: .
+ dockerfile: Dockerfile.test
+ links:
+ - admin
\ No newline at end of file
diff --git a/docker/0.4.0/test.sh b/docker/0.4.0/test.sh
new file mode 100644
index 0000000..d342e35
--- /dev/null
+++ b/docker/0.4.0/test.sh
@@ -0,0 +1,34 @@
+# 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.
+
+LOOP_SIZE=60
+i=0
+
+while [[ $i -lt LOOP_SIZE ]]; do
+ status_code=$(curl --write-out %{http_code} --silent --output /dev/null http://admin:8080)
+
+ if [[ "$status_code" -eq 200 ]] ; then
+ echo "Tests passed!"
+ exit 0
+ else
+ curl -v http://admin:8080
+ echo "status is incorrect, waiting for next turn"
+ fi
+ sleep 5
+ i=$i+1
+done
+
+echo "Tests failed!"
+exit 1
\ No newline at end of file
diff --git a/docker/0.5.0/Dockerfile b/docker/0.5.0/Dockerfile
new file mode 100644
index 0000000..0cf7bcd
--- /dev/null
+++ b/docker/0.5.0/Dockerfile
@@ -0,0 +1,30 @@
+# 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 maven:3-openjdk-8
+RUN mkdir /source && wget https://github.com/apache/dubbo-admin/archive/0.5.0.zip && unzip -q 0.5.0.zip -d /source
+WORKDIR /source/dubbo-admin-0.5.0
+RUN mvn --batch-mode clean package -Dmaven.test.skip=true
+
+FROM openjdk:8-jre
+LABEL maintainer="dev@dubbo.apache.org"
+RUN apt-get update && apt-get install -y tini
+COPY --from=0 /source/dubbo-admin-0.5.0/dubbo-admin-distribution/target/dubbo-admin-0.5.0.jar /app.jar
+COPY --from=0 /source/dubbo-admin-0.5.0/docker/entrypoint.sh /usr/local/bin/entrypoint.sh
+
+ENV JAVA_OPTS ""
+
+ENTRYPOINT ["tini", "--", "/usr/local/bin/entrypoint.sh"]
+EXPOSE 8080
diff --git a/docker/0.5.0/Dockerfile.test b/docker/0.5.0/Dockerfile.test
new file mode 100644
index 0000000..dee4d1d
--- /dev/null
+++ b/docker/0.5.0/Dockerfile.test
@@ -0,0 +1,23 @@
+# 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 ubuntu:trusty
+RUN apt-get update && apt-get install -yq curl && apt-get clean
+
+WORKDIR /app
+
+ADD test.sh /app/test.sh
+
+CMD ["bash", "test.sh"]
\ No newline at end of file
diff --git a/docker/0.5.0/docker-compose.test.yml b/docker/0.5.0/docker-compose.test.yml
new file mode 100644
index 0000000..9ac7fec
--- /dev/null
+++ b/docker/0.5.0/docker-compose.test.yml
@@ -0,0 +1,33 @@
+# 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.
+
+zookeeper:
+ image: zookeeper:3.5
+admin:
+ build: .
+ dockerfile: Dockerfile
+ links:
+ - zookeeper
+ environment:
+ - admin.registry.address=zookeeper://zookeeper:2181
+ - admin.config-center=zookeeper://zookeeper:2181
+ - admin.metadata-report.address=zookeeper://zookeeper:2181
+ ports:
+ - 8080
+sut:
+ build: .
+ dockerfile: Dockerfile.test
+ links:
+ - admin
\ No newline at end of file
diff --git a/docker/0.5.0/test.sh b/docker/0.5.0/test.sh
new file mode 100644
index 0000000..d342e35
--- /dev/null
+++ b/docker/0.5.0/test.sh
@@ -0,0 +1,34 @@
+# 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.
+
+LOOP_SIZE=60
+i=0
+
+while [[ $i -lt LOOP_SIZE ]]; do
+ status_code=$(curl --write-out %{http_code} --silent --output /dev/null http://admin:8080)
+
+ if [[ "$status_code" -eq 200 ]] ; then
+ echo "Tests passed!"
+ exit 0
+ else
+ curl -v http://admin:8080
+ echo "status is incorrect, waiting for next turn"
+ fi
+ sleep 5
+ i=$i+1
+done
+
+echo "Tests failed!"
+exit 1
\ No newline at end of file
diff --git a/dubbo-admin-distribution/pom.xml b/dubbo-admin-distribution/pom.xml
index e8e42fa..3cd4dda 100644
--- a/dubbo-admin-distribution/pom.xml
+++ b/dubbo-admin-distribution/pom.xml
@@ -53,6 +53,8 @@
<tasks>
<copy file="../dubbo-admin-server/target/dubbo-admin-server-${project.version}.jar"
tofile="target/dubbo-admin-${project.version}.jar"/>
+ <copy file="../dubbo-admin-server/target/classes/application.properties"
+ tofile="src/bin/config/application.properties"/>
</tasks>
</configuration>
<goals>
diff --git a/dubbo-admin-distribution/src/NOTICE b/dubbo-admin-distribution/src/NOTICE
index df92423..05c73d6 100644
--- a/dubbo-admin-distribution/src/NOTICE
+++ b/dubbo-admin-distribution/src/NOTICE
@@ -1,5 +1,5 @@
Apache Dubbo Admin
-Copyright 2018-2021 The Apache Software Foundation
+Copyright 2018-2022 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
@@ -100,7 +100,7 @@
========================================================================
Apache Dubbo
-Copyright 2018-2021 The Apache Software Foundation
+Copyright 2018-2022 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
diff --git a/dubbo-admin-distribution/src/bin/config/application.properties b/dubbo-admin-distribution/src/bin/config/application.properties
index dbbc16c..232b05e 100644
--- a/dubbo-admin-distribution/src/bin/config/application.properties
+++ b/dubbo-admin-distribution/src/bin/config/application.properties
@@ -57,6 +57,11 @@
server.compression.mime-types=text/css,text/javascript,application/javascript
server.compression.min-response-size=10240
+#token timeout, default is one hour
+admin.check.tokenTimeoutMilli=3600000
+#Jwt signingKey
+admin.check.signSecret=86295dd0c4ef69a1036b0b0c15158d77
+
#dubbo config
dubbo.application.name=dubbo-admin
dubbo.registry.address=${admin.registry.address}
@@ -68,7 +73,7 @@
#spring.datasource.password=mysql
# h2
-spring.datasource.url=jdbc:h2:mem:~/dubbo-admin;
+spring.datasource.url=jdbc:h2:mem:~/dubbo-admin;MODE=MYSQL;
spring.datasource.username=sa
spring.datasource.password=
diff --git a/dubbo-admin-server/pom.xml b/dubbo-admin-server/pom.xml
index 73be90f..f03e523 100644
--- a/dubbo-admin-server/pom.xml
+++ b/dubbo-admin-server/pom.xml
@@ -228,6 +228,11 @@
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
+
+ <dependency>
+ <groupId>javax.xml.bind</groupId>
+ <artifactId>jaxb-api</artifactId>
+ </dependency>
</dependencies>
<build>
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/SyncUtils.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/SyncUtils.java
index 7a36c0b..34b4e65 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/SyncUtils.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/SyncUtils.java
@@ -21,6 +21,8 @@
import org.apache.dubbo.admin.model.domain.RegistrySource;
import org.apache.dubbo.common.BaseServiceMetadata;
import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.common.url.component.DubboServiceAddressURL;
import org.apache.dubbo.common.utils.StringUtils;
import java.util.ArrayList;
@@ -57,11 +59,13 @@
p.setService(service);
p.setAddress(url.getAddress());
p.setApplication(url.getParameter(Constants.APPLICATION_KEY));
- p.setUrl(url.toIdentityString());
+ p.setUrl(url.toFullString());
p.setParameters(url.toParameterString());
p.setDynamic(url.getParameter("dynamic", true));
p.setEnabled(url.getParameter(Constants.ENABLED_KEY, true));
+ p.setSerialization(url.getParameter(org.apache.dubbo.remoting.Constants.SERIALIZATION_KEY, "hessian2"));
+ p.setTimeout(url.getParameter(CommonConstants.TIMEOUT_KEY, CommonConstants.DEFAULT_TIMEOUT));
p.setWeight(url.getParameter(Constants.WEIGHT_KEY, Constants.DEFAULT_WEIGHT));
p.setUsername(url.getParameter("owner"));
p.setRegistrySource(RegistrySource.INTERFACE);
@@ -94,7 +98,13 @@
String version = url.getUrlParam().getParameter(Constants.VERSION_KEY);
String service = BaseServiceMetadata.buildServiceKey(getServiceInterface(url), group, version);
c.setService(service);
- c.setAddress(url.getHost());
+ if (url.getHost() == null) {
+ if (url instanceof DubboServiceAddressURL) {
+ c.setAddress(((DubboServiceAddressURL) url).getConsumerURL().getRawParameter("host"));
+ }
+ } else {
+ c.setAddress(url.getHost());
+ }
c.setApplication(url.getParameter(Constants.APPLICATION_KEY));
c.setParameters(url.toParameterString());
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/config/ConfigCenter.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/config/ConfigCenter.java
index 8c39771..f354d6d 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/config/ConfigCenter.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/config/ConfigCenter.java
@@ -38,6 +38,7 @@
import org.apache.dubbo.registry.RegistryService;
import org.apache.dubbo.registry.client.ServiceDiscovery;
import org.apache.dubbo.registry.client.ServiceDiscoveryFactory;
+import org.apache.dubbo.rpc.model.ApplicationModel;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -46,6 +47,7 @@
import java.util.Arrays;
import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
+import static org.apache.dubbo.common.constants.RegistryConstants.ENABLE_EMPTY_PROTECTION_KEY;
import static org.apache.dubbo.registry.client.ServiceDiscoveryFactory.getExtension;
@Configuration
@@ -147,8 +149,8 @@
}
registryUrl = formUrl(registryAddress, registryGroup, registryNameSpace, username, password);
}
- RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
- registry = registryFactory.getRegistry(registryUrl);
+ RegistryFactory registryFactory = ApplicationModel.defaultModel().getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
+ registry = registryFactory.getRegistry(registryUrl.addParameter(ENABLE_EMPTY_PROTECTION_KEY, String.valueOf(false)));
return registry;
}
@@ -166,7 +168,7 @@
}
}
if (metadataUrl != null) {
- metaDataCollector = ExtensionLoader.getExtensionLoader(MetaDataCollector.class).getExtension(metadataUrl.getProtocol());
+ metaDataCollector = ApplicationModel.defaultModel().getExtensionLoader(MetaDataCollector.class).getExtension(metadataUrl.getProtocol());
metaDataCollector.setUrl(metadataUrl);
metaDataCollector.init();
} else {
@@ -179,11 +181,10 @@
@Bean(destroyMethod = "destroy")
@DependsOn("dubboRegistry")
ServiceDiscovery getServiceDiscoveryRegistry() throws Exception {
- URL registryURL = registryUrl.setPath(RegistryService.class.getName());
+ URL registryURL = registryUrl.setPath(RegistryService.class.getName())
+ .addParameter(ENABLE_EMPTY_PROTECTION_KEY, String.valueOf(false));
ServiceDiscoveryFactory factory = getExtension(registryURL);
- ServiceDiscovery serviceDiscovery = factory.getServiceDiscovery(registryURL);
- serviceDiscovery.initialize(registryURL);
- return serviceDiscovery;
+ return factory.getServiceDiscovery(registryURL);
}
@Bean
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/config/SwaggerConfiguration.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/config/SwaggerConfiguration.java
index a4a4e8a..ef44250 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/config/SwaggerConfiguration.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/config/SwaggerConfiguration.java
@@ -17,6 +17,7 @@
package org.apache.dubbo.admin.config;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
@@ -29,6 +30,7 @@
@Configuration
@EnableSwagger2
+@ConditionalOnProperty(name = "swagger.enable", havingValue = "true")
public class SwaggerConfiguration {
@Bean
public Docket createRestApi() {
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/Entity.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/Entity.java
index 3982d62..9778d1b 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/Entity.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/Entity.java
@@ -19,10 +19,10 @@
import java.io.Serializable;
import java.util.Date;
import java.util.List;
+import java.util.Objects;
/**
* Entity
- *
*/
public abstract class Entity implements Serializable {
@@ -128,4 +128,20 @@
this.miss = miss;
}
+ @java.lang.Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Entity entity = (Entity) o;
+ return miss == entity.miss && Objects.equals(ids, entity.ids) && Objects.equals(id, entity.id) && Objects.equals(hash, entity.hash) && Objects.equals(created, entity.created) && Objects.equals(modified, entity.modified) && Objects.equals(now, entity.now) && Objects.equals(operator, entity.operator) && Objects.equals(operatorAddress, entity.operatorAddress);
+ }
+
+ @java.lang.Override
+ public int hashCode() {
+ return Objects.hash(ids, id, hash, created, modified, now, operator, operatorAddress, miss);
+ }
}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/Provider.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/Provider.java
index 2de0ad0..3d4b151 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/Provider.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/Provider.java
@@ -23,10 +23,10 @@
import java.util.Date;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
/**
* Provider
- *
*/
public class Provider extends Entity {
@@ -46,6 +46,10 @@
private boolean enabled; /* provider enabled or not */
+ private int timeout; /* provider timeout */
+
+ private String serialization; /* provider serialization */
+
private int weight; /* provider weight */
private String application; /* application name */
@@ -191,6 +195,22 @@
this.registrySource = registrySource;
}
+ public int getTimeout() {
+ return timeout;
+ }
+
+ public void setTimeout(int timeout) {
+ this.timeout = timeout;
+ }
+
+ public String getSerialization() {
+ return serialization;
+ }
+
+ public void setSerialization(String serialization) {
+ this.serialization = serialization;
+ }
+
public URL toUrl() {
Map<String, String> serviceName2Map = ConvertUtil.serviceName2Map(getService());
/*if(!serviceName2Map.containsKey(Constants.INTERFACE_KEY)) {
@@ -221,4 +241,23 @@
return url;
}
+ @java.lang.Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+ Provider provider = (Provider) o;
+ return dynamic == provider.dynamic && enabled == provider.enabled && timeout == provider.timeout && weight == provider.weight && alived == provider.alived && Objects.equals(service, provider.service) && Objects.equals(url, provider.url) && Objects.equals(parameters, provider.parameters) && Objects.equals(address, provider.address) && Objects.equals(registry, provider.registry) && Objects.equals(serialization, provider.serialization) && Objects.equals(application, provider.application) && Objects.equals(username, provider.username) && Objects.equals(expired, provider.expired) && Objects.equals(override, provider.override) && Objects.equals(overrides, provider.overrides) && registrySource == provider.registrySource;
+ }
+
+ @java.lang.Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), service, url, parameters, address, registry, dynamic, enabled, timeout, serialization, weight, application, username, expired, alived, override, overrides, registrySource);
+ }
}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/RegistrySource.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/RegistrySource.java
index e54644c..a6a9939 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/RegistrySource.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/RegistrySource.java
@@ -19,6 +19,8 @@
public enum RegistrySource {
+ ALL,
+
INTERFACE,
INSTANCE
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/mapping/AdminMappingListener.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/mapping/AdminMappingListener.java
index 750c734..e335755 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/mapping/AdminMappingListener.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/mapping/AdminMappingListener.java
@@ -115,6 +115,7 @@
List<InstanceAddressURL> instanceAddressUrls = urls.stream().map(url -> (InstanceAddressURL) url).collect(Collectors.toList());
serviceMap.put(serviceKey, instanceAddressUrls);
}
+ instanceRegistryCache.refreshConsumer(false);
}
private String removeProtocol(String protocolServiceKey) {
@@ -126,4 +127,9 @@
}
}
+ @Override
+ public void stop() {
+ // ignore
+ }
+
}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/mapping/impl/ZookeeperServiceMapping.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/mapping/impl/ZookeeperServiceMapping.java
index 799c040..4c5dc5d 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/mapping/impl/ZookeeperServiceMapping.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/mapping/impl/ZookeeperServiceMapping.java
@@ -26,6 +26,7 @@
import org.apache.dubbo.metadata.MappingListener;
import org.apache.dubbo.remoting.zookeeper.ZookeeperClient;
import org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter;
+import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.List;
import java.util.Set;
@@ -45,7 +46,7 @@
@Override
public void init(URL url) {
- ZookeeperTransporter zookeeperTransporter = ZookeeperTransporter.getExtension();
+ ZookeeperTransporter zookeeperTransporter = ZookeeperTransporter.getExtension(ApplicationModel.defaultModel());
zkClient = zookeeperTransporter.connect(url);
listenerAll();
}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/metadata/impl/NacosMetaDataCollector.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/metadata/impl/NacosMetaDataCollector.java
index 4379eca..f03ca39 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/metadata/impl/NacosMetaDataCollector.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/metadata/impl/NacosMetaDataCollector.java
@@ -110,8 +110,11 @@
private String getMetaData(MetadataIdentifier identifier) {
try {
- return configService.getConfig(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY),
- group, 1000 * 10);
+ String fromDubboGroup = configService.getConfig(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY),
+ "dubbo", 1000 * 10);
+ return org.apache.dubbo.common.utils.StringUtils.isNotEmpty(fromDubboGroup) ? fromDubboGroup :
+ configService.getConfig(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY),
+ group, 1000 * 10);
} catch (NacosException e) {
logger.warn("Failed to get " + identifier + " from nacos, cause: " + e.getMessage(), e);
}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/metadata/impl/ZookeeperMetaDataCollector.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/metadata/impl/ZookeeperMetaDataCollector.java
index 3048f64..9bba742 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/metadata/impl/ZookeeperMetaDataCollector.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/metadata/impl/ZookeeperMetaDataCollector.java
@@ -53,7 +53,15 @@
group = Constants.PATH_SEPARATOR + group;
}
root = group;
- client = CuratorFrameworkFactory.newClient(url.getAddress(), new ExponentialBackoffRetry(1000, 3));
+ CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.
+ builder()
+ .connectString(url.getAddress())
+ .retryPolicy(new ExponentialBackoffRetry(1000, 3));
+ String userInformation = url.getUserInformation();
+ if (userInformation != null && userInformation.length() > 0) {
+ builder = builder.authorization("digest", userInformation.getBytes());
+ }
+ client = builder.build();
client.start();
}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/RegistryServerSync.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/RegistryServerSync.java
index 3e66694..886c5b6 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/RegistryServerSync.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/RegistryServerSync.java
@@ -98,7 +98,12 @@
for (URL url : urls) {
String category = url.getUrlParam().getParameter(Constants.CATEGORY_KEY);
if (category == null) {
- category = Constants.PROVIDERS_CATEGORY;
+ // Assign an initial value to category according to the information in url
+ if (Constants.CONSUMER_SIDE.equals(url.getSide()) || Constants.CONSUMER_PROTOCOL.equals(url.getProtocol())) {
+ category = Constants.CONSUMERS_CATEGORY;
+ } else {
+ category = Constants.PROVIDERS_CATEGORY;
+ }
}
// NOTE: group and version in empty protocol is *
if (Constants.EMPTY_PROTOCOL.equalsIgnoreCase(url.getProtocol())) {
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/ConsumerServiceImpl.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/ConsumerServiceImpl.java
index 0d0f2e5..8395026 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/ConsumerServiceImpl.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/ConsumerServiceImpl.java
@@ -24,6 +24,8 @@
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
+
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
@@ -33,15 +35,22 @@
@Component
public class ConsumerServiceImpl extends AbstractService implements ConsumerService {
+ @Autowired
+ private InstanceRegistryQueryHelper instanceRegistryQueryHelper;
+
@Override
public List<Consumer> findByService(String service) {
- return SyncUtils.url2ConsumerList(findConsumerUrlByService(service));
+ List<Consumer> consumers = SyncUtils.url2ConsumerList(findConsumerUrlByService(service));
+ consumers.addAll(instanceRegistryQueryHelper.findConsumerByService(service));
+ return consumers;
}
@Override
public List<Consumer> findAll() {
- return SyncUtils.url2ConsumerList(findAllConsumerUrl());
+ List<Consumer> consumers = SyncUtils.url2ConsumerList(findAllConsumerUrl());
+ consumers.addAll(instanceRegistryQueryHelper.findAllConsumer());
+ return consumers;
}
@Override
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/InstanceRegistryCache.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/InstanceRegistryCache.java
index 9f1b5ac..520f0db 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/InstanceRegistryCache.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/InstanceRegistryCache.java
@@ -17,16 +17,29 @@
package org.apache.dubbo.admin.service.impl;
+import org.apache.dubbo.admin.common.util.Constants;
import org.apache.dubbo.admin.service.RegistryCache;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.NamedThreadFactory;
+import org.apache.dubbo.metadata.MetadataService;
import org.apache.dubbo.registry.client.InstanceAddressURL;
+import org.apache.dubbo.registry.client.metadata.MetadataUtils;
+import org.apache.dubbo.rpc.service.Destroyable;
import org.springframework.stereotype.Component;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
+import java.util.stream.Collectors;
/**
* instance registry url {@link InstanceAddressURL} cache
@@ -37,6 +50,10 @@
private final ConcurrentMap<String, ConcurrentMap<String, Map<String, List<InstanceAddressURL>>>> registryCache = new ConcurrentHashMap<>();
+ private final Map<String, Map<String, List<URL>>> subscribedCache = new ConcurrentHashMap<>();
+
+ private final AtomicBoolean startRefresh = new AtomicBoolean(false);
+
@Override
public void put(String key, ConcurrentMap<String, Map<String, List<InstanceAddressURL>>> value) {
registryCache.put(key, value);
@@ -52,4 +69,44 @@
Function<? super String, ? extends ConcurrentMap<String, Map<String, List<InstanceAddressURL>>>> mappingFunction) {
return registryCache.computeIfAbsent(key, mappingFunction);
}
+
+ public Map<String, Map<String, List<URL>>> getSubscribedCache() {
+ return subscribedCache;
+ }
+
+ public synchronized void refreshConsumer(boolean refreshAll) {
+ if (startRefresh.compareAndSet(false, true)) {
+ ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new NamedThreadFactory("Consumer-Refresh"));
+ executorService.scheduleAtFixedRate(() -> refreshConsumer(true), 60, 60, TimeUnit.MINUTES);
+ }
+
+ Map<String, Map<String, List<URL>>> origin;
+
+ if (refreshAll) {
+ origin = new ConcurrentHashMap<>();
+ } else {
+ origin = subscribedCache;
+ }
+
+ Map<String, List<InstanceAddressURL>> providers = get(Constants.PROVIDERS_CATEGORY).values().stream()
+ .flatMap((e) -> e.values().stream())
+ .flatMap(Collection::stream)
+ .collect(Collectors.groupingBy(InstanceAddressURL::getAddress));
+
+ // remove cached
+ origin.keySet().forEach(providers::remove);
+
+ for (List<InstanceAddressURL> instanceAddressURLs : providers.values()) {
+ MetadataService metadataService = MetadataUtils.referProxy(instanceAddressURLs.get(0).getInstance());
+ try {
+ Set<String> subscribedURLs = metadataService.getSubscribedURLs();
+
+ Map<String, List<URL>> subscribed = subscribedURLs.stream().map(URL::valueOf).collect(Collectors.groupingBy(URL::getServiceKey));
+ origin.put(instanceAddressURLs.get(0).getAddress(), subscribed);
+ } catch (Throwable ignored) {
+
+ }
+ ((Destroyable) metadataService).$destroy();
+ }
+ }
}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/InstanceRegistryQueryHelper.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/InstanceRegistryQueryHelper.java
index aae6e65..c6d075d 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/InstanceRegistryQueryHelper.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/InstanceRegistryQueryHelper.java
@@ -18,17 +18,25 @@
package org.apache.dubbo.admin.service.impl;
import org.apache.dubbo.admin.common.util.Constants;
+import org.apache.dubbo.admin.common.util.Pair;
+import org.apache.dubbo.admin.common.util.SyncUtils;
+import org.apache.dubbo.admin.model.domain.Consumer;
import org.apache.dubbo.admin.model.domain.Provider;
import org.apache.dubbo.admin.model.domain.RegistrySource;
+import org.apache.dubbo.common.URLBuilder;
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.common.url.component.ServiceConfigURL;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.metadata.MetadataInfo;
import org.apache.dubbo.registry.client.InstanceAddressURL;
import org.apache.dubbo.registry.client.ServiceInstance;
+import org.apache.dubbo.rpc.RpcContext;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.springframework.stereotype.Component;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -85,6 +93,23 @@
.collect(Collectors.toList());
}
+ public List<Consumer> findAllConsumer() {
+ return instanceRegistryCache.getSubscribedCache().values().stream()
+ .flatMap(m -> m.values().stream())
+ .flatMap(Collection::stream)
+ .map(m -> new Pair<>(m.toFullString(), m))
+ .map(SyncUtils::url2Consumer)
+ .collect(Collectors.toList());
+ }
+
+ public List<Consumer> findConsumerByService(String serviceName) {
+ return instanceRegistryCache.getSubscribedCache().values().stream().filter(m -> m.containsKey(serviceName))
+ .flatMap(m -> m.get(serviceName).stream())
+ .map(m -> new Pair<>(m.toFullString(), m))
+ .map(SyncUtils::url2Consumer)
+ .collect(Collectors.toList());
+ }
+
public List<Provider> findByAddress(String providerAddress) {
ConcurrentMap<String, Map<String, List<InstanceAddressURL>>> appInterfaceMap = instanceRegistryCache.get(Constants.PROVIDERS_CATEGORY);
if (appInterfaceMap == null) {
@@ -136,18 +161,31 @@
MetadataInfo metadataInfo = url.getMetadataInfo();
metadataInfo.getServices().forEach((serviceKey, serviceInfo) -> {
+ // build consumer url
+
+ ServiceConfigURL consumerUrl = new URLBuilder()
+ .setProtocol(serviceInfo.getProtocol())
+ .setPath(serviceInfo.getPath())
+ .addParameter("group", serviceInfo.getGroup())
+ .addParameter("version", serviceInfo.getVersion())
+ .build();
+ RpcContext.getServiceContext().setConsumerUrl(consumerUrl);
Provider p = new Provider();
String service = serviceInfo.getServiceKey();
p.setService(service);
p.setAddress(url.getAddress());
p.setApplication(instance.getServiceName());
- p.setUrl(url.toParameterString());
+ p.setUrl(url.toFullString());
p.setDynamic(url.getParameter("dynamic", true));
p.setEnabled(url.getParameter(Constants.ENABLED_KEY, true));
+ p.setSerialization(url.getParameter(org.apache.dubbo.remoting.Constants.SERIALIZATION_KEY, "hessian2"));
+ p.setTimeout(url.getParameter(CommonConstants.TIMEOUT_KEY, CommonConstants.DEFAULT_TIMEOUT));
p.setWeight(url.getParameter(Constants.WEIGHT_KEY, Constants.DEFAULT_WEIGHT));
p.setUsername(url.getParameter("owner"));
p.setRegistrySource(RegistrySource.INSTANCE);
providers.add(p);
+
+ RpcContext.getServiceContext().setConsumerUrl(null);
});
});
return providers;
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/ProviderServiceImpl.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/ProviderServiceImpl.java
index 1defce7..5e09ed7 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/ProviderServiceImpl.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/ProviderServiceImpl.java
@@ -21,10 +21,12 @@
import org.apache.dubbo.admin.common.util.SyncUtils;
import org.apache.dubbo.admin.common.util.Tool;
import org.apache.dubbo.admin.model.domain.Provider;
+import org.apache.dubbo.admin.model.domain.RegistrySource;
import org.apache.dubbo.admin.model.dto.ServiceDTO;
import org.apache.dubbo.admin.service.ProviderService;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
+
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -292,19 +294,40 @@
*/
public Set<ServiceDTO> convertProviders2DTO(List<Provider> providers) {
Set<ServiceDTO> result = new TreeSet<>();
- for (Provider provider : providers) {
- String app = provider.getApplication();
- String service = provider.getService();
+ Map<String, List<Provider>> providerMap = providers.stream().collect(Collectors.groupingBy(Provider::getService));
+ for (Map.Entry<String, List<Provider>> entry : providerMap.entrySet()) {
+ String service = entry.getKey();
String group = Tool.getGroup(service);
String version = Tool.getVersion(service);
String interfaze = Tool.getInterface(service);
- ServiceDTO s = new ServiceDTO();
- s.setAppName(app);
- s.setService(interfaze);
- s.setGroup(group);
- s.setVersion(version);
- s.setRegistrySource(provider.getRegistrySource());
- result.add(s);
+
+ List<Provider> value = entry.getValue();
+ if (value.size() == 1) {
+ Provider provider = value.get(0);
+ ServiceDTO s = new ServiceDTO();
+ s.setAppName(provider.getApplication());
+ s.setService(interfaze);
+ s.setGroup(group);
+ s.setVersion(version);
+ s.setRegistrySource(provider.getRegistrySource());
+ result.add(s);
+ } else {
+ String app = value.stream().map(Provider::getApplication).distinct().collect(Collectors.joining(", "));
+ RegistrySource registrySource = value.get(0).getRegistrySource();
+
+ boolean matchInterface = value.stream().map(Provider::getRegistrySource).anyMatch(e -> e.equals(RegistrySource.INTERFACE));
+ boolean matchInstance = value.stream().map(Provider::getRegistrySource).anyMatch(e -> e.equals(RegistrySource.INSTANCE));
+ if (matchInterface && matchInstance) {
+ registrySource = RegistrySource.ALL;
+ }
+ ServiceDTO s = new ServiceDTO();
+ s.setAppName(app);
+ s.setService(interfaze);
+ s.setGroup(group);
+ s.setVersion(version);
+ s.setRegistrySource(registrySource);
+ result.add(s);
+ }
}
return result;
}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/RouteServiceImpl.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/RouteServiceImpl.java
index 4856a5f..e15375e 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/RouteServiceImpl.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/RouteServiceImpl.java
@@ -77,6 +77,7 @@
//for 2.6
if (StringUtils.isNotEmpty(newConditionRoute.getService())) {
for (Route old : convertRouteToOldRoute(oldConditionRoute)) {
+ old.setService(id);
registry.unregister(old.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
}
for (Route updated : convertRouteToOldRoute(newConditionRoute)) {
@@ -101,6 +102,7 @@
RoutingRule originRule = YamlParser.loadObject(config, RoutingRule.class);
ConditionRouteDTO conditionRouteDTO = RouteUtils.createConditionRouteFromRule(originRule);
for (Route old : convertRouteToOldRoute(conditionRouteDTO)) {
+ old.setService(id);
URL oldUrl = old.toUrl();
if(oldUrl.getParameter("rule").contains("host") && oldUrl.getParameter("rule").contains("false")) {
registry.unregister(oldUrl);
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/utils/ApiDocsDubboGenericUtil.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/utils/ApiDocsDubboGenericUtil.java
index 12b54af..896749f 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/utils/ApiDocsDubboGenericUtil.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/utils/ApiDocsDubboGenericUtil.java
@@ -121,6 +121,8 @@
referenceConfig.setTimeout(timeout);
referenceConfig.setVersion(version);
referenceConfig.setGroup(group);
+ //Keep it consistent with the ConfigManager cache
+ referenceConfig.setSticky(false);
referenceConfig.setApplication(application);
if (address.startsWith("dubbo")) {
diff --git a/dubbo-admin-server/src/main/resources/application.properties b/dubbo-admin-server/src/main/resources/application.properties
index 4aa924b..232b05e 100644
--- a/dubbo-admin-server/src/main/resources/application.properties
+++ b/dubbo-admin-server/src/main/resources/application.properties
@@ -73,7 +73,7 @@
#spring.datasource.password=mysql
# h2
-spring.datasource.url=jdbc:h2:mem:~/dubbo-admin;
+spring.datasource.url=jdbc:h2:mem:~/dubbo-admin;MODE=MYSQL;
spring.datasource.username=sa
spring.datasource.password=
diff --git a/dubbo-admin-server/src/test/java/org/apache/dubbo/admin/common/util/UrlUtilsTest.java b/dubbo-admin-server/src/test/java/org/apache/dubbo/admin/common/util/UrlUtilsTest.java
index 6d74e9a..bdba1e8 100644
--- a/dubbo-admin-server/src/test/java/org/apache/dubbo/admin/common/util/UrlUtilsTest.java
+++ b/dubbo-admin-server/src/test/java/org/apache/dubbo/admin/common/util/UrlUtilsTest.java
@@ -19,14 +19,14 @@
import org.junit.Assert;
import org.junit.Test;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.Map;
public class UrlUtilsTest {
@Test
public void testParamsMapToString() {
- Map<String, String[]> params = new HashMap<>();
+ Map<String, String[]> params = new LinkedHashMap<>();
params.put("a", new String[]{"1", "2", "3"});
params.put("b", new String[]{"8", "7", "6"});
String result = UrlUtils.paramsMapToString(params);
diff --git a/dubbo-admin-ui/public/dubbo-admin-info.json b/dubbo-admin-ui/public/dubbo-admin-info.json
index dfcc3af..156772d 100644
--- a/dubbo-admin-ui/public/dubbo-admin-info.json
+++ b/dubbo-admin-ui/public/dubbo-admin-info.json
@@ -1,3 +1,3 @@
{
- "version": "0.3.0"
+ "version": "0.5.0"
}
diff --git a/dubbo-admin-ui/public/index.html b/dubbo-admin-ui/public/index.html
index 63dadb1..01be2e7 100644
--- a/dubbo-admin-ui/public/index.html
+++ b/dubbo-admin-ui/public/index.html
@@ -23,7 +23,7 @@
<title>Dubbo Admin</title>
<link href='OpenSans.css' rel="stylesheet" type="text/css">
<link rel="shortcut icon" href="dubbo.ico" type="image/x-icon">
- <script src="https://cdn.bootcss.com/echarts/4.0.4/echarts-en.min.js"></script>
+ <script src="https://cdn.bootcdn.net/ajax/libs/echarts/4.0.4/echarts-en.min.js"></script>
</head>
<body>
<div id="app"></div>
diff --git a/dubbo-admin-ui/src/components/ServiceDetail.vue b/dubbo-admin-ui/src/components/ServiceDetail.vue
index 79fa779..554e5ba 100644
--- a/dubbo-admin-ui/src/components/ServiceDetail.vue
+++ b/dubbo-admin-ui/src/components/ServiceDetail.vue
@@ -55,8 +55,8 @@
<td>{{getIp(props.item.address)}}</td>
<td>{{getPort(props.item.address)}}</td>
<td>{{props.item.registrySource}}</td>
- <td></td>
- <td></td>
+ <td>{{props.item.timeout}}</td>
+ <td>{{props.item.serialization}}</td>
<td>{{props.item.weight}}</td>
<td>
<v-tooltip top>
@@ -84,7 +84,6 @@
>
<template slot="items" slot-scope="props">
<td>{{getIp(props.item.address)}}</td>
- <td>{{getPort(props.item.address)}}</td>
<td>{{props.item.application}}</td>
</template>
</v-data-table>
@@ -177,7 +176,7 @@
},
{
text: this.$t('serialization'),
- value: 'serial'
+ value: 'serialization'
},
{
text: this.$t('weight'),
@@ -195,10 +194,6 @@
value: 'ip'
},
{
- text: this.$t('port'),
- value: 'port'
- },
- {
text: this.$t('appName'),
value: 'appName'
}
@@ -211,6 +206,7 @@
this.providerDetails = response.data.providers
const instanceRegistry = this.$t('instanceRegistry')
const interfaceRegistry = this.$t('interfaceRegistry')
+ const allRegistry = this.$t('allRegistry')
for (let i = 0; i < this.providerDetails.length; i++) {
if (this.providerDetails[i].registrySource === 'INSTANCE') {
this.providerDetails[i].registrySource = instanceRegistry
@@ -218,6 +214,9 @@
if (this.providerDetails[i].registrySource === 'INTERFACE') {
this.providerDetails[i].registrySource = interfaceRegistry
}
+ if (this.providerDetails[i].registrySource === 'ALL') {
+ this.providerDetails[i].registrySource = allRegistry
+ }
console.log(this.providerDetails[i])
this.$set(this.providerDetails[i], 'hint', 'url')
}
@@ -228,10 +227,10 @@
})
},
getIp: function (address) {
- return address.split(':')[0]
+ return address != null ? address.split(':')[0] : null
},
getPort: function (address) {
- return address.split(':')[1]
+ return address != null && address.split(':').length >= 2 ? address.split(':')[1] : null
},
toCopyText (text) {
this.$copyText(text).then(() => {
diff --git a/dubbo-admin-ui/src/components/ServiceSearch.vue b/dubbo-admin-ui/src/components/ServiceSearch.vue
index c5ce4fb..4627fbd 100644
--- a/dubbo-admin-ui/src/components/ServiceSearch.vue
+++ b/dubbo-admin-ui/src/components/ServiceSearch.vue
@@ -201,6 +201,7 @@
}
const instanceRegistry = this.$t('instanceRegistry')
const interfaceRegistry = this.$t('interfaceRegistry')
+ const allRegistry = this.$t('allRegistry')
return this.resultPage.content.filter(function (item) {
if (item.registrySource === 'INSTANCE') {
item.registrySource = instanceRegistry
@@ -208,6 +209,9 @@
if (item.registrySource === 'INTERFACE') {
item.registrySource = interfaceRegistry
}
+ if (item.registrySource === 'ALL') {
+ item.registrySource = allRegistry
+ }
return item
})
}
diff --git a/dubbo-admin-ui/src/components/public/Footers.vue b/dubbo-admin-ui/src/components/public/Footers.vue
index 6ad8ae6..08e4016 100644
--- a/dubbo-admin-ui/src/components/public/Footers.vue
+++ b/dubbo-admin-ui/src/components/public/Footers.vue
@@ -18,7 +18,7 @@
<template>
<v-footer inset height="auto" class="pa-3 footer-border-top">
<v-spacer></v-spacer>
- <span class="caption mr-1"><strong>Copyright</strong> ©2018-2021 <strong>The Apache Software Foundation.</strong></span>
+ <span class="caption mr-1"><strong>Copyright</strong> ©2018-2022 <strong>The Apache Software Foundation.</strong></span>
</v-footer>
</template>
<script>
diff --git a/dubbo-admin-ui/src/lang/en.js b/dubbo-admin-ui/src/lang/en.js
index c84fd7a..f534e81 100644
--- a/dubbo-admin-ui/src/lang/en.js
+++ b/dubbo-admin-ui/src/lang/en.js
@@ -49,6 +49,7 @@
registrySource: 'Registry Source',
instanceRegistry: 'Instance Registry',
interfaceRegistry: 'Interface Registry',
+ allRegistry: 'Instance / Interface Registry',
operation: 'Operation',
searchResult: 'Search Result',
search: 'Search',
diff --git a/dubbo-admin-ui/src/lang/zh.js b/dubbo-admin-ui/src/lang/zh.js
index fa979c4..2b97382 100644
--- a/dubbo-admin-ui/src/lang/zh.js
+++ b/dubbo-admin-ui/src/lang/zh.js
@@ -49,6 +49,7 @@
registrySource: '注册来源',
instanceRegistry: '应用级',
interfaceRegistry: '接口级',
+ allRegistry: '应用级/接口级',
operation: '操作',
searchResult: '查询结果',
search: '搜索',
diff --git a/dubbo-admin-ui/src/router/index.js b/dubbo-admin-ui/src/router/index.js
index 8cb9574..96a3af3 100644
--- a/dubbo-admin-ui/src/router/index.js
+++ b/dubbo-admin-ui/src/router/index.js
@@ -36,6 +36,11 @@
import Index from '@/Index'
import Login from '@/Login'
+const originalPush = Router.prototype.push
+Router.prototype.push = function push(location) {
+ return originalPush.call(this, location).catch(err => err)
+}
+
Vue.use(Router)
export default new Router({
diff --git a/pom.xml b/pom.xml
index c9ec158..fec0211 100644
--- a/pom.xml
+++ b/pom.xml
@@ -53,17 +53,18 @@
</repositories>
<properties>
- <revision>0.3.0</revision>
+ <revision>0.5.0</revision>
<main.basedir>${project.basedir}</main.basedir>
<commons-lang3-version>3.7</commons-lang3-version>
- <dubbo-version>3.0.2.1</dubbo-version>
- <fastjson-version>1.2.67</fastjson-version>
+ <dubbo-version>3.0.8</dubbo-version>
+ <fastjson-version>1.2.83</fastjson-version>
<springfox-swagger-version>2.9.2</springfox-swagger-version>
<jacoco-version>0.8.2</jacoco-version>
<apollo-version>1.2.0</apollo-version>
<guava-version>20.0</guava-version>
<dubbo-mock-version>3.0.0</dubbo-mock-version>
<mybatis-plus-boot-version>3.4.2</mybatis-plus-boot-version>
+ <curator-test-veriosn>2.12.0</curator-test-veriosn>
<maven-checkstyle-plugin-version>3.0.0</maven-checkstyle-plugin-version>
<spring-boot-version>2.3.12.RELEASE</spring-boot-version>
@@ -143,6 +144,11 @@
<version>${mybatis-plus-boot-version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>curator-test</artifactId>
+ <version>${curator-test-veriosn}</version>
+ </dependency>
</dependencies>
</dependencyManagement>