All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.nepxion.discovery.console.endpoint.ConsoleEndpoint Maven / Gradle / Ivy

There is a newer version: 6.22.0
Show newest version
package com.nepxion.discovery.console.endpoint;

/**
 * 

Title: Nepxion Discovery

*

Description: Nepxion Discovery

*

Copyright: Copyright (c) 2017-2050

*

Company: Nepxion

* @author Haojun Ren * @version 1.0 */ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClient; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import com.nepxion.discovery.common.constant.DiscoveryConstant; import com.nepxion.discovery.common.entity.InstanceEntity; import com.nepxion.discovery.common.entity.InstanceEntityWrapper; import com.nepxion.discovery.common.entity.UserEntity; import com.nepxion.discovery.common.handler.RestErrorHandler; import com.nepxion.discovery.console.adapter.ConfigAdapter; import com.nepxion.discovery.console.authentication.AuthenticationResource; import com.nepxion.discovery.console.rest.ConfigClearRestInvoker; import com.nepxion.discovery.console.rest.ConfigUpdateRestInvoker; import com.nepxion.discovery.console.rest.SentinelClearRestInvoker; import com.nepxion.discovery.console.rest.SentinelUpdateRestInvoker; import com.nepxion.discovery.console.rest.VersionClearRestInvoker; import com.nepxion.discovery.console.rest.VersionUpdateRestInvoker; @RestController @RequestMapping(path = "/console") @Api(tags = { "控制台接口" }) public class ConsoleEndpoint { private static final Logger LOG = LoggerFactory.getLogger(ConsoleEndpoint.class); private static final String[] DISCOVERY_TYPES = { "Eureka", "Consul", "Zookeeper", "Nacos" }; @Autowired private DiscoveryClient discoveryClient; @Autowired(required = false) private ConfigAdapter configAdapter; @Autowired private AuthenticationResource authenticationResource; private RestTemplate consoleRestTemplate; public ConsoleEndpoint() { consoleRestTemplate = new RestTemplate(); consoleRestTemplate.setErrorHandler(new RestErrorHandler()); } @RequestMapping(path = "/authenticate", method = RequestMethod.POST) @ApiOperation(value = "登录认证", notes = "", response = ResponseEntity.class, httpMethod = "POST") @ResponseBody public ResponseEntity authenticate(@RequestBody @ApiParam(value = "UserEntity实例", required = true) UserEntity userEntity) { return executeAuthenticate(userEntity); } @RequestMapping(path = "/discovery-type", method = RequestMethod.GET) @ApiOperation(value = "获取注册发现中心类型", notes = "", response = ResponseEntity.class, httpMethod = "GET") @ResponseBody public ResponseEntity discoveryType() { return getDiscoveryType(); } @RequestMapping(path = "/config-type", method = RequestMethod.GET) @ApiOperation(value = "获取配置中心类型", notes = "", response = ResponseEntity.class, httpMethod = "GET") @ResponseBody public ResponseEntity configType() { return getConfigType(); } @RequestMapping(path = "/groups", method = RequestMethod.GET) @ApiOperation(value = "获取服务注册中心的服务组名列表", notes = "", response = List.class, httpMethod = "GET") @ResponseBody public List groups() { return getGroups(); } @RequestMapping(path = "/services", method = RequestMethod.GET) @ApiOperation(value = "获取服务注册中心的服务名列表", notes = "", response = List.class, httpMethod = "GET") @ResponseBody public List services() { return getServices(); } @RequestMapping(path = "/instances/{serviceId}", method = RequestMethod.GET) @ApiOperation(value = "获取服务注册中心的服务实例列表", notes = "", response = List.class, httpMethod = "GET") @ResponseBody public List instances(@PathVariable(value = "serviceId") @ApiParam(value = "服务名", required = true) String serviceId) { return getInstances(serviceId); } @RequestMapping(path = "/instance-list/{serviceId}", method = RequestMethod.GET) @ApiOperation(value = "获取服务注册中心的服务实例列表(精简数据)", notes = "", response = List.class, httpMethod = "GET") @ResponseBody public List instanceList(@PathVariable(value = "serviceId") @ApiParam(value = "服务名", required = true) String serviceId) { return getInstanceList(serviceId); } @RequestMapping(path = "/instance-map", method = RequestMethod.POST) @ApiOperation(value = "获取服务注册中心的服务实例的Map(精简数据)", notes = "服务组名列表", response = Map.class, httpMethod = "POST") @ResponseBody public Map> instanceMap(@RequestBody @ApiParam(value = "服务组名列表,传入空列则可以获取全部服务实例数据", required = true) List groups) { return getInstanceMap(groups); } @RequestMapping(path = "/remote-config/update/{group}/{serviceId}", method = RequestMethod.POST) @ApiOperation(value = "推送更新规则配置信息到远程配置中心", notes = "", response = ResponseEntity.class, httpMethod = "POST") @ResponseBody public ResponseEntity remoteConfigUpdate(@PathVariable(value = "group") @ApiParam(value = "组名", required = true) String group, @PathVariable(value = "serviceId") @ApiParam(value = "服务名。当全局推送模式下,服务名必须由组名来代替", required = true) String serviceId, @RequestBody @ApiParam(value = "规则配置内容,XML格式", required = true) String config) { return executeRemoteConfigUpdate(group, serviceId, config); } @RequestMapping(path = "/remote-config/clear/{group}/{serviceId}", method = RequestMethod.POST) @ApiOperation(value = "清除规则配置信息到远程配置中心", notes = "", response = ResponseEntity.class, httpMethod = "POST") @ResponseBody public ResponseEntity remoteConfigClear(@PathVariable(value = "group") @ApiParam(value = "组名", required = true) String group, @PathVariable(value = "serviceId") @ApiParam(value = "服务名。当全局推送模式下,服务名必须由组名来代替", required = true) String serviceId) { return executeRemoteConfigClear(group, serviceId); } @RequestMapping(path = "/remote-config/view/{group}/{serviceId}", method = RequestMethod.GET) @ApiOperation(value = "查看远程配置中心的规则配置信息", notes = "", response = ResponseEntity.class, httpMethod = "GET") @ResponseBody public ResponseEntity remoteConfigView(@PathVariable(value = "group") @ApiParam(value = "组名", required = true) String group, @PathVariable(value = "serviceId") @ApiParam(value = "服务名。当全局推送模式下,服务名必须由组名来代替", required = true) String serviceId) { return executeRemoteConfigView(group, serviceId); } @RequestMapping(path = "/config/update-async/{serviceId}", method = RequestMethod.POST) @ApiOperation(value = "批量异步推送更新规则配置信息", notes = "", response = ResponseEntity.class, httpMethod = "POST") @ResponseBody public ResponseEntity configUpdateAsync(@PathVariable(value = "serviceId") @ApiParam(value = "服务名", required = true) String serviceId, @RequestBody @ApiParam(value = "规则配置内容,XML格式", required = true) String config) { return executeConfigUpdate(serviceId, config, true); } @RequestMapping(path = "/config/update-sync/{serviceId}", method = RequestMethod.POST) @ApiOperation(value = "批量同步推送更新规则配置信息", notes = "", response = ResponseEntity.class, httpMethod = "POST") @ResponseBody public ResponseEntity configUpdateSync(@PathVariable(value = "serviceId") @ApiParam(value = "服务名", required = true) String serviceId, @RequestBody @ApiParam(value = "规则配置内容,XML格式", required = true) String config) { return executeConfigUpdate(serviceId, config, false); } @RequestMapping(path = "/config/clear-async/{serviceId}", method = RequestMethod.POST) @ApiOperation(value = "批量异步清除更新的规则配置信息", notes = "", response = ResponseEntity.class, httpMethod = "POST") @ResponseBody public ResponseEntity configClearAsync(@PathVariable(value = "serviceId") @ApiParam(value = "服务名", required = true) String serviceId) { return executeConfigClear(serviceId, true); } @RequestMapping(path = "/config/clear-sync/{serviceId}", method = RequestMethod.POST) @ApiOperation(value = "批量同步清除更新的规则配置信息", notes = "", response = ResponseEntity.class, httpMethod = "POST") @ResponseBody public ResponseEntity configClearSync(@PathVariable(value = "serviceId") @ApiParam(value = "服务名", required = true) String serviceId) { return executeConfigClear(serviceId, false); } @RequestMapping(path = "/version/update-async/{serviceId}", method = RequestMethod.POST) @ApiOperation(value = "批量异步更新服务的动态版本", notes = "根据指定的localVersion更新服务的dynamicVersion。如果输入的localVersion不匹配服务的localVersion,则忽略;如果如果输入的localVersion为空,则直接更新服务的dynamicVersion", response = ResponseEntity.class, httpMethod = "POST") @ResponseBody public ResponseEntity versionUpdateAsync(@PathVariable(value = "serviceId") @ApiParam(value = "服务名", required = true) String serviceId, @RequestBody @ApiParam(value = "版本号,格式为[dynamicVersion]或者[dynamicVersion];[localVersion]", required = true) String version) { return executeVersionUpdate(serviceId, version, true); } @RequestMapping(path = "/version/update-sync/{serviceId}", method = RequestMethod.POST) @ApiOperation(value = "批量同步更新服务的动态版本", notes = "根据指定的localVersion更新服务的dynamicVersion。如果输入的localVersion不匹配服务的localVersion,则忽略;如果如果输入的localVersion为空,则直接更新服务的dynamicVersion", response = ResponseEntity.class, httpMethod = "POST") @ResponseBody public ResponseEntity versionUpdateSync(@PathVariable(value = "serviceId") @ApiParam(value = "服务名", required = true) String serviceId, @RequestBody @ApiParam(value = "版本号,格式为[dynamicVersion]或者[dynamicVersion];[localVersion]", required = true) String version) { return executeVersionUpdate(serviceId, version, false); } @RequestMapping(path = "/version/clear-async/{serviceId}", method = RequestMethod.POST) @ApiOperation(value = "批量异步清除服务的动态版本", notes = "根据指定的localVersion清除服务的dynamicVersion。如果输入的localVersion不匹配服务的localVersion,则忽略;如果如果输入的localVersion为空,则直接清除服务的dynamicVersion", response = ResponseEntity.class, httpMethod = "POST") @ResponseBody public ResponseEntity versionClearAsync(@PathVariable(value = "serviceId") @ApiParam(value = "服务名", required = true) String serviceId, @RequestBody(required = false) @ApiParam(value = "版本号,指localVersion,可以为空") String version) { return executeVersionClear(serviceId, version, true); } @RequestMapping(path = "/version/clear-sync/{serviceId}", method = RequestMethod.POST) @ApiOperation(value = "批量同步清除服务的动态版本", notes = "根据指定的localVersion清除服务的dynamicVersion。如果输入的localVersion不匹配服务的localVersion,则忽略;如果如果输入的localVersion为空,则直接清除服务的dynamicVersion", response = ResponseEntity.class, httpMethod = "POST") @ResponseBody public ResponseEntity versionClearSync(@PathVariable(value = "serviceId") @ApiParam(value = "服务名", required = true) String serviceId, @RequestBody(required = false) @ApiParam(value = "版本号,指localVersion,可以为空") String version) { return executeVersionClear(serviceId, version, false); } @RequestMapping(path = "/sentinel/update/{serviceId}/{ruleType}", method = RequestMethod.POST) @ApiOperation(value = "更新哨兵规则列表", notes = "哨兵规则类型取值: flow | degrade | authority | system | param-flow", response = ResponseEntity.class, httpMethod = "POST") @ResponseBody public ResponseEntity sentinelUpdate(@PathVariable(value = "serviceId") @ApiParam(value = "服务名", required = true) String serviceId, @PathVariable(value = "ruleType") @ApiParam(value = "哨兵规则类型", required = true) String ruleType, @RequestBody @ApiParam(value = "哨兵规则内容,JSON格式", required = true) String rule) { return executeSentinelUpdate(serviceId, ruleType, rule); } @RequestMapping(path = "/sentinel/clear/{serviceId}/{ruleType}", method = RequestMethod.POST) @ApiOperation(value = "清除哨兵规则列表", notes = "哨兵规则类型取值: flow | degrade | authority | system | param-flow", response = ResponseEntity.class, httpMethod = "POST") @ResponseBody public ResponseEntity sentinelClear(@PathVariable(value = "serviceId") @ApiParam(value = "服务名", required = true) String serviceId, @PathVariable(value = "ruleType") @ApiParam(value = "哨兵规则类型", required = true) String ruleType) { return executeSentinelClear(serviceId, ruleType); } private ResponseEntity executeAuthenticate(UserEntity userEntity) { try { boolean result = authenticationResource.authenticate(userEntity); return ResponseEntity.ok().body(result); } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage()); } } private ResponseEntity getDiscoveryType() { if (discoveryClient instanceof CompositeDiscoveryClient) { CompositeDiscoveryClient compositeDiscoveryClient = (CompositeDiscoveryClient) discoveryClient; List discoveryClients = compositeDiscoveryClient.getDiscoveryClients(); for (DiscoveryClient client : discoveryClients) { String discoveryDescription = client.description(); for (int i = 0; i < DISCOVERY_TYPES.length; i++) { String discoveryType = DISCOVERY_TYPES[i]; if (discoveryDescription.toLowerCase().contains(discoveryType.toLowerCase())) { return ResponseEntity.ok().body(discoveryType); } } } } else { String discoveryDescription = discoveryClient.description(); for (int i = 0; i < DISCOVERY_TYPES.length; i++) { String discoveryType = DISCOVERY_TYPES[i]; if (discoveryDescription.toLowerCase().contains(discoveryType.toLowerCase())) { return ResponseEntity.ok().body(discoveryType); } } } return ResponseEntity.ok().body(DiscoveryConstant.UNKNOWN); } private ResponseEntity getConfigType() { if (configAdapter != null) { String configType = configAdapter.getConfigType(); return ResponseEntity.ok().body(configType); } return ResponseEntity.ok().body(DiscoveryConstant.UNKNOWN); } public List getGroups() { List groups = new ArrayList(); List services = getServices(); for (String service : services) { List instanceEntityList = getInstanceList(service); for (InstanceEntity instance : instanceEntityList) { String plugin = InstanceEntityWrapper.getPlugin(instance); String group = InstanceEntityWrapper.getGroup(instance); if (StringUtils.isNotEmpty(plugin) && !groups.contains(group)) { groups.add(group); } } } return groups; } public List getServices() { return discoveryClient.getServices(); } public List getInstances(String serviceId) { return discoveryClient.getInstances(serviceId); } public List getInstanceList(String service) { List serviceInstances = getInstances(service); List instanceEntityList = new ArrayList(serviceInstances.size()); for (ServiceInstance serviceInstance : serviceInstances) { Map metadata = serviceInstance.getMetadata(); String serviceId = serviceInstance.getServiceId().toLowerCase(); String serviceType = metadata.get(DiscoveryConstant.SPRING_APPLICATION_TYPE); String version = metadata.get(DiscoveryConstant.VERSION); String region = metadata.get(DiscoveryConstant.REGION); String environment = metadata.get(DiscoveryConstant.ENVIRONMENT); String host = serviceInstance.getHost(); int port = serviceInstance.getPort(); InstanceEntity instanceEntity = new InstanceEntity(); instanceEntity.setServiceType(serviceType); instanceEntity.setServiceId(serviceId); instanceEntity.setVersion(version); instanceEntity.setRegion(region); instanceEntity.setEnvironment(environment); instanceEntity.setHost(host); instanceEntity.setPort(port); instanceEntity.setMetadata(metadata); instanceEntityList.add(instanceEntity); } return instanceEntityList; } public Map> getInstanceMap(List groups) { List services = getServices(); Map> instanceMap = new LinkedHashMap>(services.size()); for (String service : services) { List instanceEntityList = getInstanceList(service); if (CollectionUtils.isNotEmpty(groups)) { for (InstanceEntity instance : instanceEntityList) { String plugin = InstanceEntityWrapper.getPlugin(instance); String group = InstanceEntityWrapper.getGroup(instance); if (StringUtils.isNotEmpty(plugin) && groups.contains(group)) { List instanceList = instanceMap.get(service); if (instanceList == null) { instanceList = new ArrayList(); instanceMap.put(service, instanceList); } instanceList.add(instance); } } } else { instanceMap.put(service, instanceEntityList); } } return instanceMap; } private ResponseEntity executeRemoteConfigUpdate(String group, String serviceId, String config) { if (configAdapter == null) { LOG.error("Remote config adapter isn't provided"); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Remote config adapter isn't provided"); } try { boolean result = configAdapter.updateConfig(group, serviceId, config); return ResponseEntity.ok().body(result ? DiscoveryConstant.OK : DiscoveryConstant.NO); } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage()); } } private ResponseEntity executeRemoteConfigClear(String group, String serviceId) { if (configAdapter == null) { LOG.error("Remote config adapter isn't provided"); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Remote config adapter isn't provided"); } try { boolean result = configAdapter.clearConfig(group, serviceId); return ResponseEntity.ok().body(result ? DiscoveryConstant.OK : DiscoveryConstant.NO); } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage()); } } private ResponseEntity executeRemoteConfigView(String group, String serviceId) { if (configAdapter == null) { LOG.error("Remote config adapter isn't provided"); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Remote config adapter isn't provided"); } try { String config = configAdapter.getConfig(group, serviceId); return ResponseEntity.ok().body(config); } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage()); } } private ResponseEntity executeConfigUpdate(String serviceId, String config, boolean async) { List serviceInstances = getInstances(serviceId); ConfigUpdateRestInvoker configUpdateRestInvoker = new ConfigUpdateRestInvoker(serviceInstances, consoleRestTemplate, config, async); return configUpdateRestInvoker.invoke(); } private ResponseEntity executeConfigClear(String serviceId, boolean async) { List serviceInstances = getInstances(serviceId); ConfigClearRestInvoker configClearRestInvoker = new ConfigClearRestInvoker(serviceInstances, consoleRestTemplate, async); return configClearRestInvoker.invoke(); } private ResponseEntity executeVersionUpdate(String serviceId, String version, boolean async) { List serviceInstances = getInstances(serviceId); VersionUpdateRestInvoker versionUpdateRestInvoker = new VersionUpdateRestInvoker(serviceInstances, consoleRestTemplate, version, async); return versionUpdateRestInvoker.invoke(); } private ResponseEntity executeVersionClear(String serviceId, String version, boolean async) { List serviceInstances = getInstances(serviceId); VersionClearRestInvoker versionClearRestInvoker = new VersionClearRestInvoker(serviceInstances, consoleRestTemplate, version, async); return versionClearRestInvoker.invoke(); } private ResponseEntity executeSentinelUpdate(String serviceId, String ruleType, String rule) { List serviceInstances = getInstances(serviceId); SentinelUpdateRestInvoker sentinelUpdateRestInvoker = new SentinelUpdateRestInvoker(serviceInstances, consoleRestTemplate, ruleType, rule); return sentinelUpdateRestInvoker.invoke(); } private ResponseEntity executeSentinelClear(String serviceId, String ruleType) { List serviceInstances = getInstances(serviceId); SentinelClearRestInvoker sentinelClearRestInvoker = new SentinelClearRestInvoker(serviceInstances, consoleRestTemplate, ruleType); return sentinelClearRestInvoker.invoke(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy