diff --git a/.gitignore b/.gitignore index b606a64..d66696f 100644 --- a/.gitignore +++ b/.gitignore @@ -38,4 +38,7 @@ functions/mock .umi-production screenshot .firebase -application-localhost.properties \ No newline at end of file +application-localhost.properties +/sofa-dashboard-backend/sofa-dashboard-web/docker/sofadashboard/sofa-dashboard-web-1.0.0-SNAPSHOT.jar +/sofa-dashboard-backend/sofa-dashboard-web/docker/jenkins/Jenkins/ +/sofa-dashboard-backend/sofa-dashboard-web/docker/sofadashboard/SOFADashboard/ diff --git a/sofa-dashboard-backend/pom.xml b/sofa-dashboard-backend/pom.xml index 2cf385f..d98ee9c 100644 --- a/sofa-dashboard-backend/pom.xml +++ b/sofa-dashboard-backend/pom.xml @@ -35,10 +35,26 @@ 1.0.17 1.14 1.3.2 + 2.0.7 + 20.0 + + + com.github.xiaoymin + knife4j-spring-boot-starter + ${knife4j.version} + + + com.google.guava + guava + ${guava.version} + + + + com.alipay.sofa sofa-dashboard-core diff --git a/sofa-dashboard-backend/sofa-dashboard-arkmng/src/main/java/com/alipay/sofa/dashboard/dao/ArkDao.java b/sofa-dashboard-backend/sofa-dashboard-arkmng/src/main/java/com/alipay/sofa/dashboard/dao/ArkDao.java index 70a7b2e..3bb8f5e 100644 --- a/sofa-dashboard-backend/sofa-dashboard-arkmng/src/main/java/com/alipay/sofa/dashboard/dao/ArkDao.java +++ b/sofa-dashboard-backend/sofa-dashboard-arkmng/src/main/java/com/alipay/sofa/dashboard/dao/ArkDao.java @@ -167,4 +167,12 @@ ArkModuleVersionDO queryByModuleIdAndModuleVersion(@Param("moduleId") int module * @return */ int deletePluginVersion(@Param("id") int id, @Param("version") String version); + + /*** + * 根据模块id和应用名字 获取模块-应用关联信息 + * @param mId + * @param appName + * @return + */ + List queryRelationByModuleIdAndAppName(int mId, String appName); } diff --git a/sofa-dashboard-backend/sofa-dashboard-arkmng/src/main/java/com/alipay/sofa/dashboard/impl/ArkMngServiceImpl.java b/sofa-dashboard-backend/sofa-dashboard-arkmng/src/main/java/com/alipay/sofa/dashboard/impl/ArkMngServiceImpl.java index c4288d8..232a592 100644 --- a/sofa-dashboard-backend/sofa-dashboard-arkmng/src/main/java/com/alipay/sofa/dashboard/impl/ArkMngServiceImpl.java +++ b/sofa-dashboard-backend/sofa-dashboard-arkmng/src/main/java/com/alipay/sofa/dashboard/impl/ArkMngServiceImpl.java @@ -16,12 +16,10 @@ */ package com.alipay.sofa.dashboard.impl; +import com.alipay.sofa.ark.spi.service.ArkService; +import com.alipay.sofa.dashboard.app.AppServiceImpl; import com.alipay.sofa.dashboard.dao.ArkDao; -import com.alipay.sofa.dashboard.model.AppArkDO; -import com.alipay.sofa.dashboard.model.ArkModuleUserDO; -import com.alipay.sofa.dashboard.model.ArkModuleVersionDO; -import com.alipay.sofa.dashboard.model.ArkPluginDO; -import com.alipay.sofa.dashboard.model.ArkPluginModel; +import com.alipay.sofa.dashboard.model.*; import com.alipay.sofa.dashboard.service.ArkMngService; import com.alipay.sofa.dashboard.utils.SofaDashboardUtil; import org.slf4j.Logger; @@ -29,6 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; import java.util.ArrayList; import java.util.List; @@ -46,6 +45,13 @@ public class ArkMngServiceImpl implements ArkMngService { @Autowired private ArkDao arkDao; + @Autowired + private ZkHelper zkHelper; + + @Override + public boolean isRelatedByModuleAndApp(int mId, String appName) { + return arkDao.queryRelationByModuleIdAndAppName(mId, appName).size() > 0; + } @Override public List fetchRegisteredPlugins() { @@ -121,12 +127,20 @@ public int relatedAppToPlugin(int moduleId, String appName) { if (moduleId < 0) { return -1; } - AppArkDO appArkDO = new AppArkDO(); - appArkDO.setAppName(appName); - appArkDO.setCreateTime(SofaDashboardUtil.now()); - appArkDO.setModuleId(moduleId); - arkDao.insertAppArk(appArkDO); - return appArkDO.getId(); + List arkAppList = zkHelper.getArkAppList(); + boolean relatedByModuleAndApp = isRelatedByModuleAndApp(moduleId, appName); + for (String appApp : arkAppList) { + //zk中已存在应用 并且 未关联 + if (appApp.equals(appName) && isRelatedByModuleAndApp(moduleId, appName) == false) { + AppArkDO appArkDO = new AppArkDO(); + appArkDO.setAppName(appName); + appArkDO.setCreateTime(SofaDashboardUtil.now()); + appArkDO.setModuleId(moduleId); + arkDao.insertAppArk(appArkDO); + return appArkDO.getId(); + } + } + return -1; } @Override diff --git a/sofa-dashboard-backend/sofa-dashboard-arkmng/src/main/java/com/alipay/sofa/dashboard/impl/ZkHelper.java b/sofa-dashboard-backend/sofa-dashboard-arkmng/src/main/java/com/alipay/sofa/dashboard/impl/ZkHelper.java index dfbc8e6..511d8b8 100644 --- a/sofa-dashboard-backend/sofa-dashboard-arkmng/src/main/java/com/alipay/sofa/dashboard/impl/ZkHelper.java +++ b/sofa-dashboard-backend/sofa-dashboard-arkmng/src/main/java/com/alipay/sofa/dashboard/impl/ZkHelper.java @@ -103,6 +103,29 @@ private List getInstanceIpList(String appName) { return result; } + /** + * 获取 /sofa-ark 下面所有的应用 + * @return + */ + public List getArkAppList() { + List result = null; + CuratorFramework curatorClient = zkCommandClient.getCuratorClient(); + String arkAppBasePath = SofaDashboardConstants.SOFA_ARK_ROOT; + try { + if (checkExist(arkAppBasePath, curatorClient)) { + // 获取所有应用信息 + result = curatorClient.getChildren().forPath(arkAppBasePath); + } + } catch (Exception e) { + LOGGER.error("Failed to get ark app list.", e); + } finally { + if (result == null) { + result = new ArrayList<>(); + } + } + return result; + } + /** * 获取当前应用实例的个数 * diff --git a/sofa-dashboard-backend/sofa-dashboard-arkmng/src/main/java/com/alipay/sofa/dashboard/service/ArkMngService.java b/sofa-dashboard-backend/sofa-dashboard-arkmng/src/main/java/com/alipay/sofa/dashboard/service/ArkMngService.java index d1379bf..826036b 100644 --- a/sofa-dashboard-backend/sofa-dashboard-arkmng/src/main/java/com/alipay/sofa/dashboard/service/ArkMngService.java +++ b/sofa-dashboard-backend/sofa-dashboard-arkmng/src/main/java/com/alipay/sofa/dashboard/service/ArkMngService.java @@ -28,6 +28,14 @@ **/ public interface ArkMngService { + /*** + * 根据模块Id和应用名字 获取模块是否已关联该应用 + * @param mId + * @param appName + * @return + */ + boolean isRelatedByModuleAndApp(int mId, String appName); + /** * 获取当前所有注册的 plugin 信息 * @@ -83,9 +91,8 @@ public interface ArkMngService { */ List fetchPluginsByName(String pluginName); - /** + /*** * 关联应用和插件 - * * @param moduleId * @param appName * @return diff --git a/sofa-dashboard-backend/sofa-dashboard-core/src/main/java/com/alipay/sofa/dashboard/constants/SofaDashboardConstants.java b/sofa-dashboard-backend/sofa-dashboard-core/src/main/java/com/alipay/sofa/dashboard/constants/SofaDashboardConstants.java index 9cd7d61..98188db 100644 --- a/sofa-dashboard-backend/sofa-dashboard-core/src/main/java/com/alipay/sofa/dashboard/constants/SofaDashboardConstants.java +++ b/sofa-dashboard-backend/sofa-dashboard-core/src/main/java/com/alipay/sofa/dashboard/constants/SofaDashboardConstants.java @@ -70,4 +70,11 @@ public class SofaDashboardConstants { public static final String ZOOKEEPER_PREFIX = "zookeeper://"; public static final String SOFA_PREFIX = "sofa://"; + // API接口类 + public static final String API_ARK_TAGS = "Ark相关接口"; + public static final String API_APPLICATION_TAGS = "Application相关接口"; + public static final String API_ARK_APPLICATION_TAGS ="Ark与application相关应用"; + public static final String API_INSTANCE_TAGS ="Instance相关接口"; + public static final String API_SERVICES_TAGS ="Services相关接口"; + } diff --git a/sofa-dashboard-backend/sofa-dashboard-web/docker/jenkins/Docker-compose.yml b/sofa-dashboard-backend/sofa-dashboard-web/docker/jenkins/Docker-compose.yml new file mode 100644 index 0000000..c8691a8 --- /dev/null +++ b/sofa-dashboard-backend/sofa-dashboard-web/docker/jenkins/Docker-compose.yml @@ -0,0 +1,22 @@ +version: '3.8' +services: + jenkins: + + image: jenkins/jenkins:lts + volumes: +# - ./Jenkins/jenkins_mount/jenkins/:/var/jenkins_mount/ + - ./Jenkins/data/jenkins/:/var/jenkins_home + - ./Jenkins/run/docker.sock:/var/run/docker.sock + - ./Jenkins/bin/docker:/usr/bin/docker + - ./Jenkins/lib/x86_64-linux-gnu/libltdl.so.7:/usr/lib/x86_64-linux-gnu/libltdl.so.7 + ports: + - "4396:8080" + expose: + - "4396" + + privileged: true + user: root + restart: always + container_name: jenkins + environment: + JAVA_OPTS: '-Djava.util.logging.config.file=/var/jenkins_home/log.properties' diff --git a/sofa-dashboard-backend/sofa-dashboard-web/docker/sofadashboard/Docker-compose.yml b/sofa-dashboard-backend/sofa-dashboard-web/docker/sofadashboard/Docker-compose.yml new file mode 100644 index 0000000..95d1ed9 --- /dev/null +++ b/sofa-dashboard-backend/sofa-dashboard-web/docker/sofadashboard/Docker-compose.yml @@ -0,0 +1,52 @@ +version: '3.8' +services: + sofadashboard: + build: . + image: sofadashboard + depends_on: + - mysql + - zk01 + ports: + - "8099:8099" + links: + - zk01 + - mysql + + mysql: + container_name: mysql57 + image: mysql:5.7.31 + restart: always + ports: + - "3306:3306" + privileged: true + volumes: + - ./SOFADashboard/mysql57/log:/var/log/mysql +# - /dockerImages/DockerFileSharing/home/SOFADashboard/mysql57/conf/my.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf + - ./SOFADashboard/mysql57/data:/var/lib/mysql + environment: + MYSQL_ROOT_PASSWORD: "123456" + MYSQL_USER: 'root' + MYSQL_PASS: '123456' + command: [ + '--character-set-server=utf8mb4', + '--collation-server=utf8mb4_general_ci', + '--max_connections=3000' + ] + + zk01: + image: zookeeper:3.4.11 + restart: always + hostname: zk01 + container_name: zk01 + ports: + - "2181:2181" + volumes: + - ./SOFADashboard/zookeeper/zk01/data:/data + - ./SOFADashboard/zookeeper/zk01/datalog:/datalog + - ./SOFADashboard/zookeeper/zk01/logs:/logs + + +networks: + default: + external: + name: my_network diff --git a/sofa-dashboard-backend/sofa-dashboard-web/docker/sofadashboard/Dockerfile b/sofa-dashboard-backend/sofa-dashboard-web/docker/sofadashboard/Dockerfile new file mode 100644 index 0000000..dfd857f --- /dev/null +++ b/sofa-dashboard-backend/sofa-dashboard-web/docker/sofadashboard/Dockerfile @@ -0,0 +1,9 @@ +FROM java:8 + +COPY *.jar /app.jar + +CMD ["--server.port=8099"] + +EXPOSE 8099 + +ENTRYPOINT ["java","-jar","/app.jar"] \ No newline at end of file diff --git a/sofa-dashboard-backend/sofa-dashboard-web/pom.xml b/sofa-dashboard-backend/sofa-dashboard-web/pom.xml index ef21e52..7c80f0e 100644 --- a/sofa-dashboard-backend/sofa-dashboard-web/pom.xml +++ b/sofa-dashboard-backend/sofa-dashboard-web/pom.xml @@ -18,6 +18,23 @@ + + + com.github.xiaoymin + knife4j-spring-boot-starter + + + + com.google.guava + guava + + + + org.springframework.plugin + spring-plugin-core + 2.0.0.RELEASE + + com.alipay.sofa sofa-dashboard-governance diff --git a/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/configuration/Swagger2Config.java b/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/configuration/Swagger2Config.java new file mode 100644 index 0000000..0be5883 --- /dev/null +++ b/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/configuration/Swagger2Config.java @@ -0,0 +1,47 @@ +/* + * 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 com.alipay.sofa.dashboard.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc; + +@Configuration +@EnableSwagger2WebMvc +public class Swagger2Config { + @Bean + public Docket createRestApi() { + return new Docket(DocumentationType.SWAGGER_2).useDefaultResponseMessages(false) + .apiInfo(apiInfo()).groupName("default").select() + .apis(RequestHandlerSelectors.basePackage("com.alipay.sofa.dashboard.controller")) + .paths(PathSelectors.any()).build(); + + } + + private ApiInfo apiInfo() { + return new ApiInfoBuilder().title("SOFADashboard APIs").description("SOFADashboard 接口对接文档") + .termsOfServiceUrl("http://localhost:8099/").version("1.0").build(); + } + +} diff --git a/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/controller/ApplicationController.java b/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/controller/ApplicationController.java index 5ec1a45..9f714b5 100644 --- a/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/controller/ApplicationController.java +++ b/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/controller/ApplicationController.java @@ -16,9 +16,13 @@ */ package com.alipay.sofa.dashboard.controller; +import com.alipay.sofa.dashboard.constants.SofaDashboardConstants; import com.alipay.sofa.dashboard.model.ApplicationInfo; import com.alipay.sofa.dashboard.spi.AppService; import com.alipay.sofa.rpc.common.utils.StringUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -31,12 +35,15 @@ * @author guolei.sgl (guolei.sgl@antfin.com) 18/12/7 下午5:15 */ @RestController +@Api(value = SofaDashboardConstants.API_APPLICATION_TAGS, tags = SofaDashboardConstants.API_APPLICATION_TAGS) @RequestMapping("/api/application") public class ApplicationController { @Autowired private AppService appService; + + @ApiOperation(value = "获取应用信息") @GetMapping public List getApplication(@RequestParam(value = "keyword", required = false) String keyword) { return StringUtils.isEmpty(keyword) ? appService.getAllStatistics() : appService diff --git a/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/controller/ArkAppMngController.java b/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/controller/ArkAppMngController.java index 01bcb2b..fb43f2a 100644 --- a/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/controller/ArkAppMngController.java +++ b/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/controller/ArkAppMngController.java @@ -27,6 +27,9 @@ import com.alipay.sofa.dashboard.response.ResponseEntity; import com.alipay.sofa.dashboard.service.ArkMngService; import com.alipay.sofa.dashboard.spi.CommandPushManager; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -44,8 +47,10 @@ * @author: guolei.sgl (guolei.sgl@antfin.com) 18/12/21 下午2:26 * @since: **/ + @RestController @RequestMapping("/api/arkapp") +@Api(value = SofaDashboardConstants.API_ARK_APPLICATION_TAGS,tags = SofaDashboardConstants.API_ARK_APPLICATION_TAGS) public class ArkAppMngController { private static final Logger LOGGER = LoggerFactory.getLogger(ArkAppMngController.class); @@ -58,6 +63,8 @@ public class ArkAppMngController { private ZkHelper zkHelper; @RequestMapping("/ark-app") + @ApiOperation(value = "获取插件的所有关联应用",tags = SofaDashboardConstants.API_ARK_APPLICATION_TAGS) + @ApiOperationSupport(order = 1) @Deprecated public AppModuleModel fetchArkApps(@RequestParam("pluginName") String pluginName,@RequestParam("appName") String appName, @RequestParam("version") String version) throws Exception { @@ -91,7 +98,8 @@ public AppModuleModel fetchArkApps(@RequestParam("pluginName") String pluginName appModuleModel.setIpUnitList(ipUnitList); return appModuleModel; } - + @ApiOperation(value = "推送命令",tags = SofaDashboardConstants.API_ARK_APPLICATION_TAGS) + @ApiOperationSupport(order = 2) @RequestMapping("/command") public boolean command(@RequestBody Map commandMap) { // parse commandMap @@ -104,7 +112,8 @@ public boolean command(@RequestBody Map commandMap) { } return true; } - + @ApiOperation(value = "fetchBiz状态信息",tags = SofaDashboardConstants.API_ARK_APPLICATION_TAGS) + @ApiOperationSupport(order = 3) @RequestMapping("biz-state-detail") public ClientResponseModel fetchBizState(@RequestParam("ip") String ip, @RequestParam("appName") String appName) { @@ -116,6 +125,8 @@ public ClientResponseModel fetchBizState(@RequestParam("ip") String ip, return new ClientResponseModel(); } + @ApiOperation(value = "获取Biz状态信息",tags = SofaDashboardConstants.API_ARK_APPLICATION_TAGS) + @ApiOperationSupport(order = 4) @RequestMapping("biz-state") public ResponseEntity getBizState(@RequestParam("ip") String ip, @RequestParam("appName") String appName, diff --git a/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/controller/ArkMngController.java b/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/controller/ArkMngController.java index 45bcc10..33a9957 100644 --- a/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/controller/ArkMngController.java +++ b/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/controller/ArkMngController.java @@ -25,6 +25,9 @@ import com.alipay.sofa.dashboard.response.ResponseEntity; import com.alipay.sofa.dashboard.service.ArkMngService; import com.alipay.sofa.dashboard.utils.SofaDashboardUtil; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -42,6 +45,7 @@ * @author: guolei.sgl (guolei.sgl@antfin.com) 18/12/19 上午11:06 * @since: **/ +@Api(value = SofaDashboardConstants.API_ARK_TAGS, tags = SofaDashboardConstants.API_ARK_TAGS) @RestController @RequestMapping("/api/ark") public class ArkMngController { @@ -59,6 +63,8 @@ public class ArkMngController { * * @return */ + @ApiOperation(value = "查询全部插件",tags = SofaDashboardConstants.API_ARK_TAGS) + @ApiOperationSupport(order = 1) @RequestMapping("/plugin-list") public List queryArkPluginList() { List list = arkMngService.fetchRegisteredPlugins(); @@ -87,6 +93,8 @@ public List queryArkPluginList() { * @param map * @return */ + @ApiOperation(value = "注册插件", tags = SofaDashboardConstants.API_ARK_TAGS) + @ApiOperationSupport(order = 2) @RequestMapping("/register") public boolean registerPlugin(@RequestBody Map map) { if (map == null) { @@ -98,6 +106,8 @@ public boolean registerPlugin(@RequestBody Map map) { return arkMngService.registerPlugin(arkPluginDO); } + @ApiOperation(value = "更新插件", tags = SofaDashboardConstants.API_ARK_TAGS) + @ApiOperationSupport(order = 3) @RequestMapping("/update-plugin") public boolean updatePlugin(@RequestBody ArkPluginDO arkPluginDO) { if (arkPluginDO == null) { @@ -106,6 +116,8 @@ public boolean updatePlugin(@RequestBody ArkPluginDO arkPluginDO) { return arkMngService.updatePlugin(arkPluginDO); } + @ApiOperation(value = "更新插件版本", tags = SofaDashboardConstants.API_ARK_TAGS) + @ApiOperationSupport(order = 4) @RequestMapping("/register-new-version") public boolean registerNewVersion(@RequestBody Map map) { if (map == null) { @@ -121,6 +133,8 @@ public boolean registerNewVersion(@RequestBody Map map) { return arkMngService.addNewVersion(Integer.valueOf(id), version, address); } + @ApiOperation(value = "删除插件版本", tags = SofaDashboardConstants.API_ARK_TAGS) + @ApiOperationSupport(order = 8) @RequestMapping("/delete-version") public ResponseEntity deleteVersion(@RequestParam("id") int id, @RequestParam("version") String version) { @@ -137,6 +151,8 @@ public ResponseEntity deleteVersion(@RequestParam("id") int id, return result; } + @ApiOperation(value = "删除插件", tags = SofaDashboardConstants.API_ARK_TAGS) + @ApiOperationSupport(order = 9) @RequestMapping("/delete-plugin") public boolean deletePluginModel(@RequestParam("id") int id) { if (id < 0) { @@ -145,6 +161,8 @@ public boolean deletePluginModel(@RequestParam("id") int id) { return arkMngService.removePlugins(id); } + @ApiOperation(value = "查询插件", tags = SofaDashboardConstants.API_ARK_TAGS) + @ApiOperationSupport(order = 7) @RequestMapping("/search-plugin") public List searchPlugins(@RequestParam("pluginName") String pluginName) { if (StringUtils.isEmpty(pluginName)) { @@ -154,11 +172,15 @@ public List searchPlugins(@RequestParam("pluginName") String plu return arkMngService.fetchPluginsByName(pluginName); } + @ApiOperation(value = "关联应用", tags = SofaDashboardConstants.API_ARK_TAGS) + @ApiOperationSupport(order = 5) @RequestMapping("/related-app") public boolean relatedApp(@RequestParam("id") int id, @RequestParam("appName") String appName) { return arkMngService.relatedAppToPlugin(id, appName) > 0; } + @ApiOperation(value = "取消关联应用", tags = SofaDashboardConstants.API_ARK_TAGS) + @ApiOperationSupport(order = 6) @RequestMapping("/cancel-related-app") public boolean cancelRelatedApp(@RequestParam("pluginName") String pluginName, @RequestParam("appName") String appName) { diff --git a/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/controller/InstanceController.java b/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/controller/InstanceController.java index fd1f88e..577aca7 100644 --- a/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/controller/InstanceController.java +++ b/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/controller/InstanceController.java @@ -25,6 +25,7 @@ import com.alipay.sofa.dashboard.client.model.mappings.MappingsDescriptor; import com.alipay.sofa.dashboard.client.model.memory.MemoryDescriptor; import com.alipay.sofa.dashboard.client.model.thread.ThreadSummaryDescriptor; +import com.alipay.sofa.dashboard.constants.SofaDashboardConstants; import com.alipay.sofa.dashboard.model.InstanceRecord; import com.alipay.sofa.dashboard.model.RecordResponse; import com.alipay.sofa.dashboard.model.StampedValueEntity; @@ -33,6 +34,9 @@ import com.alipay.sofa.dashboard.utils.HostPortUtils; import com.alipay.sofa.dashboard.utils.MapUtils; import com.alipay.sofa.dashboard.utils.TreeNodeConverter; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.GetMapping; @@ -56,6 +60,7 @@ */ @RestController @RequestMapping("/api/instance") +@Api(value = SofaDashboardConstants.API_INSTANCE_TAGS,tags = SofaDashboardConstants.API_INSTANCE_TAGS) public class InstanceController { @Autowired @@ -64,6 +69,7 @@ public class InstanceController { @Autowired private MonitorService service; + @GetMapping public List instances( @RequestParam(value = "applicationName", required = false) String applicationName) { @@ -76,6 +82,8 @@ public List instances( .collect(Collectors.toList()); } + @ApiOperation(value = "获取实例环境",tags = SofaDashboardConstants.API_INSTANCE_TAGS) + @ApiOperationSupport(order = 1) @GetMapping("/{instanceId}/env") public RecordResponse getEnv( @PathVariable("instanceId") String instanceId) { @@ -104,7 +112,8 @@ public RecordResponse getEnv( .detail(TreeNodeConverter.convert(descriptor)) .build(); } - + @ApiOperation(value = "获取实例信息",tags = SofaDashboardConstants.API_INSTANCE_TAGS) + @ApiOperationSupport(order = 2) @GetMapping("/{instanceId}/info") public RecordResponse getInfo(@PathVariable("instanceId") String instanceId) { HostAndPort hostAndPort = HostPortUtils.getById(instanceId); @@ -127,7 +136,8 @@ public RecordResponse getInfo(@PathVariable("instanceId") String instanceId) { .detail(TreeNodeConverter.convert(descriptor)) .build(); } - + @ApiOperation(value = "获取实例健康状态",tags = SofaDashboardConstants.API_INSTANCE_TAGS) + @ApiOperationSupport(order = 3) @GetMapping("/{instanceId}/health") public RecordResponse getHealth(@PathVariable("instanceId") String instanceId) { HostAndPort hostAndPort = HostPortUtils.getById(instanceId); @@ -148,7 +158,8 @@ public RecordResponse getHealth(@PathVariable("instanceId") String instanceId) { String.format("%s:%d", hostAndPort.getHost(), hostAndPort.getPort())) .detail(TreeNodeConverter.convert(descriptor)).build(); } - + @ApiOperation(value = "获取实例日志",tags = SofaDashboardConstants.API_INSTANCE_TAGS) + @ApiOperationSupport(order = 4) @GetMapping("/{instanceId}/loggers") public RecordResponse getLoggers(@PathVariable("instanceId") String instanceId) { HostAndPort hostAndPort = HostPortUtils.getById(instanceId); @@ -157,7 +168,8 @@ public RecordResponse getLoggers(@PathVariable("instanceId") String instanceId) return RecordResponse.newBuilder().overview(new HashMap<>(16)) .detail(TreeNodeConverter.convert(descriptor)).build(); } - + @ApiOperation(value = "获取实例映射",tags = SofaDashboardConstants.API_INSTANCE_TAGS) + @ApiOperationSupport(order = 5) @GetMapping("/{instanceId}/mappings") public RecordResponse getMappings(@PathVariable("instanceId") String instanceId) { HostAndPort hostAndPort = HostPortUtils.getById(instanceId); @@ -186,13 +198,15 @@ public RecordResponse getMappings(@PathVariable("instanceId") String instanceId) .detail(TreeNodeConverter.convert(descriptor)) .build(); } - + @ApiOperation(value = "获取内存记录",tags = SofaDashboardConstants.API_INSTANCE_TAGS) + @ApiOperationSupport(order = 6) @GetMapping("/{instanceId}/memory") public List> getMemoryRecords(@PathVariable("instanceId") String instanceId) { HostAndPort hostAndPort = HostPortUtils.getById(instanceId); return service.fetchMemoryInfo(hostAndPort); } - + @ApiOperation(value = "获取线程记录",tags = SofaDashboardConstants.API_INSTANCE_TAGS) + @ApiOperationSupport(order = 7) @GetMapping("/{instanceId}/thread") public List> getThreadRecords(@PathVariable("instanceId") String instanceId) { HostAndPort hostAndPort = HostPortUtils.getById(instanceId); diff --git a/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/controller/ServiceManageController.java b/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/controller/ServiceManageController.java index 90a5902..e82abf0 100644 --- a/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/controller/ServiceManageController.java +++ b/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/controller/ServiceManageController.java @@ -18,12 +18,16 @@ import com.alipay.sofa.common.utils.StringUtil; import com.alipay.sofa.dashboard.cache.RegistryDataCache; +import com.alipay.sofa.dashboard.constants.SofaDashboardConstants; import com.alipay.sofa.dashboard.domain.RpcConsumer; import com.alipay.sofa.dashboard.domain.RpcProvider; import com.alipay.sofa.dashboard.domain.RpcService; import com.alipay.sofa.dashboard.model.ServiceAppModel; import com.alipay.sofa.dashboard.model.ServiceModel; import com.alipay.sofa.rpc.common.utils.StringUtils; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -46,11 +50,14 @@ **/ @RestController @RequestMapping("/api/service") +@Api(value = SofaDashboardConstants.API_SERVICES_TAGS,tags = SofaDashboardConstants.API_SERVICES_TAGS) public class ServiceManageController { @Autowired private RegistryDataCache registryDataCache; + @ApiOperation(value = "获取全部服务列表",tags = SofaDashboardConstants.API_SERVICES_TAGS) + @ApiOperationSupport(order = 1) @GetMapping("/all-service") public List queryServiceListByService(@RequestParam("query") String query) { List data = new ArrayList<>(); @@ -70,6 +77,8 @@ public List queryServiceListByService(@RequestParam("query") Strin * * @return */ + @ApiOperation(value = "获取服务列表-应用维度",tags = SofaDashboardConstants.API_SERVICES_TAGS) + @ApiOperationSupport(order = 2) @GetMapping("/all-app") public List> queryServiceListByApp(@RequestParam("query") String query) { List> data = new ArrayList<>(); @@ -110,6 +119,8 @@ public List> queryServiceListByApp(@RequestParam("query") St * @param appName * @return */ + @ApiOperation(value = "获取应用服务信息",tags = SofaDashboardConstants.API_SERVICES_TAGS) + @ApiOperationSupport(order = 2) @GetMapping("service-app") public ServiceAppModel queryServiceByAppName(@RequestParam("appName") String appName) { List providersData = new ArrayList<>(); @@ -152,33 +163,39 @@ private List fetchConsumerData(String serviceName) { return registryDataCache.fetchConsumersByService(serviceName); } - /** + /*** * 获取某个服务的所有提供方 - * + * @param serviceName * @return */ + @ApiOperation(value = "获取指定服务所有提供方",tags = SofaDashboardConstants.API_SERVICES_TAGS) + @ApiOperationSupport(order = 3) @GetMapping("query/providers") public List queryServiceProviders(@RequestParam("dataid") String serviceName) { String dataId = URLDecoder.decode(serviceName); return fetchProviderData(dataId); } - /** - * 获取某个服务的所有提供方 - * + /*** + * 获取某个服务的所有接受方 + * @param serviceName * @return */ + @ApiOperation(value = "获取指定服务所有接受方",tags = SofaDashboardConstants.API_SERVICES_TAGS) + @ApiOperationSupport(order = 4) @GetMapping("query/consumers") public List queryServiceConsumers(@RequestParam("dataid") String serviceName) { String dataId = URLDecoder.decode(serviceName); return fetchConsumerData(dataId); } - /** - * 获取某个服务的所有提供方 - * + /*** + * 获取某个服务的所有信息 + * @param serviceName * @return */ + @ApiOperation(value = "根据名字获取指定服务",tags = SofaDashboardConstants.API_SERVICES_TAGS) + @ApiOperationSupport(order = 5) @GetMapping("query/services") public List queryService(@RequestParam("serviceName") String serviceName) { List data = new ArrayList<>(); diff --git a/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/model/InstanceRecord.java b/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/model/InstanceRecord.java index 1db3d5c..c052bb1 100644 --- a/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/model/InstanceRecord.java +++ b/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/model/InstanceRecord.java @@ -25,30 +25,30 @@ */ public class InstanceRecord extends Application { - public InstanceRecord() { - } + public InstanceRecord() { + } - public InstanceRecord(Application other) { - setAppName(other.getAppName()); - setHostName(other.getHostName()); - setInternalHost(other.getInternalHost()); - setPort(other.getPort()); - setAppState(other.getAppState()); - setStartTime(other.getStartTime()); - setLastRecover(other.getLastRecover()); - } + public InstanceRecord(Application other) { + setAppName(other.getAppName()); + setHostName(other.getHostName()); + setInternalHost(other.getInternalHost()); + setPort(other.getPort()); + setAppState(other.getAppState()); + setStartTime(other.getStartTime()); + setLastRecover(other.getLastRecover()); + } - /** - * Id 是接口层概念,用来和前端交换一个短的 host&port 描述 - * - * @return 唯一id - */ - public String getId() { - return HostPortUtils.uniqueId(new HostAndPort(getHostName(), getInternalHost(), getPort())); - } + /** + * Id 是接口层概念,用来和前端交换一个短的 host&port 描述 + * + * @return 唯一id + */ + public String getId() { + return HostPortUtils.uniqueId(new HostAndPort(getHostName(), getInternalHost(), getPort())); + } - public void setId(String instanceId) { - // Do nothing for json serializer - } + public void setId(String instanceId) { + // Do nothing for json serializer + } } diff --git a/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/utils/HostPortUtils.java b/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/utils/HostPortUtils.java index f36d6ef..6478ba5 100644 --- a/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/utils/HostPortUtils.java +++ b/sofa-dashboard-backend/sofa-dashboard-web/src/main/java/com/alipay/sofa/dashboard/utils/HostPortUtils.java @@ -30,142 +30,139 @@ */ public final class HostPortUtils { - /** - * 0~255 - */ - private static final String SEGMENT_REG = "((2[0-4]\\d)|(25[0-5])|(1\\d{2})|([1-9]\\d)|(\\d))"; + /** + * 0~255 + */ + private static final String SEGMENT_REG = "((2[0-4]\\d)|(25[0-5])|(1\\d{2})|([1-9]\\d)|(\\d))"; - private static final Pattern IP_PATTERN = getIpv4Reg(); + private static final Pattern IP_PATTERN = getIpv4Reg(); - /** - * 工具类隐藏构造方法 - */ - private HostPortUtils() { - } + /** + * 工具类隐藏构造方法 + */ + private HostPortUtils() { + } - /** - * 根据 Host and port 获取唯一id - * - * @param hostAndPort - * 地址 - * @return 唯一id:(真实IP+内部IP)编码 & 端口编码 - */ - public static String uniqueId(HostAndPort hostAndPort) { - long ipSeg = toDigital(hostAndPort.getHost(), 0); - long portSeg = ((long) hostAndPort.getPort() & 0xFFFF); - String internalHost = hostAndPort.getInternalHost(); - if (StringUtils.isEmpty(internalHost) == false) { - long internalIpSeg = toDigital(internalHost, 1); - return Long.toHexString(ipSeg + internalIpSeg) + "&" + Long.toHexString(portSeg); - } else { - return Long.toHexString(ipSeg) + "&" + Long.toHexString(portSeg); - } - } + /** + * 根据 Host and port 获取唯一id + * + * @param hostAndPort + * 地址 + * @return 唯一id:(真实IP+内部IP)编码 & 端口编码 + */ + public static String uniqueId(HostAndPort hostAndPort) { + long ipSeg = toDigital(hostAndPort.getHost(), 0); + long portSeg = ((long) hostAndPort.getPort() & 0xFFFF); + String internalHost = hostAndPort.getInternalHost(); + if (StringUtils.isEmpty(internalHost) == false) { + long internalIpSeg = toDigital(internalHost, 1); + return Long.toHexString(ipSeg + internalIpSeg) + "&" + Long.toHexString(portSeg); + } else { + return Long.toHexString(ipSeg) + "&" + Long.toHexString(portSeg); + } + } - /** - * 从id中获取ipv4地址 - * - * @param uniqueId - * 唯一id - * @return ipv4地址 - */ - public static HostAndPort getById(String uniqueId) { - String[] segment = uniqueId.split("&"); - int port = ((Number) (Long.parseLong(segment[1], 16) & 0xFFFF)).intValue(); - long ipPartSeg = Long.parseLong(segment[0], 16); - String ipv4 = fromDigital(ipPartSeg & 0xFFFFFFFFL); - long virtualPart = ipPartSeg >> 32; - if (virtualPart <= 0) { - return new HostAndPort(ipv4, null, port); - } else { - String virtualIp = fromDigital(virtualPart & 0xFFFFFFFFL); - return new HostAndPort(ipv4, virtualIp, port); - } - } + /** + * 从id中获取ipv4地址 + * + * @param uniqueId + * 唯一id + * @return ipv4地址 + */ + public static HostAndPort getById(String uniqueId) { + String[] segment = uniqueId.split("&"); + int port = ((Number) (Long.parseLong(segment[1], 16) & 0xFFFF)).intValue(); + long ipPartSeg = Long.parseLong(segment[0], 16); + String ipv4 = fromDigital(ipPartSeg & 0xFFFFFFFFL); + long virtualPart = ipPartSeg >> 32; + if (virtualPart <= 0) { + return new HostAndPort(ipv4, null, port); + } else { + String virtualIp = fromDigital(virtualPart & 0xFFFFFFFFL); + return new HostAndPort(ipv4, virtualIp, port); + } + } - /** - * ipv4正则 - * - * @return 正则对象 - */ - private static Pattern getIpv4Reg() { - StringJoiner sj = new StringJoiner("\\."); - sj.add(SEGMENT_REG); - sj.add(SEGMENT_REG); - sj.add(SEGMENT_REG); - sj.add(SEGMENT_REG); - return Pattern.compile(sj.toString()); - } + /** + * ipv4正则 + * + * @return 正则对象 + */ + private static Pattern getIpv4Reg() { + StringJoiner sj = new StringJoiner("\\."); + sj.add(SEGMENT_REG); + sj.add(SEGMENT_REG); + sj.add(SEGMENT_REG); + sj.add(SEGMENT_REG); + return Pattern.compile(sj.toString()); + } - /** - * 非法ipv4抛异常 - * - * @param ipv4 - * ipv4 - */ - private static void checkIPv4(String ipv4) { - if (!isLegalV4(ipv4)) { - throw new IllegalArgumentException("Illegal ipv4 value " + ipv4); - } - } + /** + * 非法ipv4抛异常 + * + * @param ipv4 + * ipv4 + */ + private static void checkIPv4(String ipv4) { + if (!isLegalV4(ipv4)) { + throw new IllegalArgumentException("Illegal ipv4 value " + ipv4); + } + } - /** - * ip转换为对应32bit数字 - * - * @param ipv4 - * 点分十进制ipv4 - * @param segmentPart - * TODO - * @return ipv4 对应数字 - */ - private static long toDigital(String ipv4, int segmentPart) { - checkIPv4(ipv4); - String[] segments = ipv4.split("\\."); - long result = 0; - for (int i = 0; i < 4; i++) { - result += Long.parseLong(segments[3 - i]) << ((8 * i) + segmentPart * Integer.SIZE); - } - return result; - } + /** + * ip转换为对应32bit数字 + * + * @param ipv4 + * 点分十进制ipv4 + * @param segmentPart + * TODO + * @return ipv4 对应数字 + */ + private static long toDigital(String ipv4, int segmentPart) { + checkIPv4(ipv4); + String[] segments = ipv4.split("\\."); + long result = 0; + for (int i = 0; i < 4; i++) { + result += Long.parseLong(segments[3 - i]) << ((8 * i) + segmentPart * Integer.SIZE); + } + return result; + } - /** - * 检查是否合法ipv4 - * - * @param ipv4 - * ipv4地址 - * @return 是否匹配 - */ - private static boolean isLegalV4(String ipv4) { - return !StringUtils.isEmpty(ipv4) && IP_PATTERN.matcher(ipv4).matches(); - } + /** + * 检查是否合法ipv4 + * + * @param ipv4 + * ipv4地址 + * @return 是否匹配 + */ + private static boolean isLegalV4(String ipv4) { + return !StringUtils.isEmpty(ipv4) && IP_PATTERN.matcher(ipv4).matches(); + } - /** - * 数字转换为string ip格式 - * - * @param ipv4 - * 32位数字ip - * @return 点分十进制ip - */ - public static String fromDigital(Long ipv4) { - if (ipv4 > 0xFFFFFFFFL || ipv4 < 0) { - throw new IllegalArgumentException("Illegal ipv4 digital " + ipv4); - } - int[] segments = new int[4]; - for (int i = 0; i < 4; i++) { - segments[3 - i] = ipv4.intValue() & 0xFF; - ipv4 >>= 8; - } - StringJoiner sj = new StringJoiner("."); - for (int segment : segments) { - sj.add(String.valueOf(segment)); - } - return sj.toString(); - } + /** + * 数字转换为string ip格式 + * + * @param ipv4 + * 32位数字ip + * @return 点分十进制ip + */ + public static String fromDigital(Long ipv4) { + if (ipv4 > 0xFFFFFFFFL || ipv4 < 0) { + throw new IllegalArgumentException("Illegal ipv4 digital " + ipv4); + } + int[] segments = new int[4]; + for (int i = 0; i < 4; i++) { + segments[3 - i] = ipv4.intValue() & 0xFF; + ipv4 >>= 8; + } + StringJoiner sj = new StringJoiner("."); + for (int segment : segments) { + sj.add(String.valueOf(segment)); + } + return sj.toString(); + } - public static void main(String[] args) { - String id = uniqueId(new HostAndPort("192.168.0.104", "8.16.32.64", 38081)); - System.out.println(id); - HostAndPort hostAndPort = getById(id); - System.out.println(hostAndPort); - } + public static void main(String[] args) { + String id = uniqueId(new HostAndPort("192.168.0.104", "8.16.32.64", 38081)); + } } diff --git a/sofa-dashboard-backend/sofa-dashboard-web/src/main/resources/application-knife4j.yml b/sofa-dashboard-backend/sofa-dashboard-web/src/main/resources/application-knife4j.yml new file mode 100644 index 0000000..a9f3796 --- /dev/null +++ b/sofa-dashboard-backend/sofa-dashboard-web/src/main/resources/application-knife4j.yml @@ -0,0 +1,9 @@ +knife4j: + enable: true + + +# 开启验证 +# basic: +# password: 123456 +# username: root +# enable: true \ No newline at end of file diff --git a/sofa-dashboard-backend/sofa-dashboard-web/src/main/resources/application.properties b/sofa-dashboard-backend/sofa-dashboard-web/src/main/resources/application.properties index e54f3f7..1b9ae77 100644 --- a/sofa-dashboard-backend/sofa-dashboard-web/src/main/resources/application.properties +++ b/sofa-dashboard-backend/sofa-dashboard-web/src/main/resources/application.properties @@ -15,4 +15,4 @@ mybatis.config-location=classpath:spring/mybatis-configuration.xml # server port server.port=8099 -spring.profiles.active=localhost +spring.profiles.active=localhost,knife4j diff --git a/sofa-dashboard-backend/sofa-dashboard-web/src/main/resources/spring/mybatis/ArkMapper.xml b/sofa-dashboard-backend/sofa-dashboard-web/src/main/resources/spring/mybatis/ArkMapper.xml index 7c28b2c..2b03cf3 100644 --- a/sofa-dashboard-backend/sofa-dashboard-web/src/main/resources/spring/mybatis/ArkMapper.xml +++ b/sofa-dashboard-backend/sofa-dashboard-web/src/main/resources/spring/mybatis/ArkMapper.xml @@ -95,6 +95,9 @@ select * from ark_module_version where module_id=#{moduleId} and module_version=#{moduleVersion} + update ark_module_info set plugin_name = #{pluginName}, description = #{description} where id=#{id} diff --git a/sofa-dashboard-front/src/pages/Ark/index.jsx b/sofa-dashboard-front/src/pages/Ark/index.jsx index 67ed631..537f305 100644 --- a/sofa-dashboard-front/src/pages/Ark/index.jsx +++ b/sofa-dashboard-front/src/pages/Ark/index.jsx @@ -154,6 +154,9 @@ class Ark extends React.Component { }); } else { message.info('关联失败,请联系管理员'); + this.setState({ + confirmRelatedAppLoading: false, + }); } }); });