dubbo文档优化
This commit is contained in:
@@ -1,44 +1,32 @@
|
||||
package com.zyplayer.doc.dubbo.controller;
|
||||
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.zyplayer.doc.core.annotation.AuthMan;
|
||||
import com.zyplayer.doc.core.json.DocResponseJson;
|
||||
import com.zyplayer.doc.dubbo.controller.param.DubboRequestParam;
|
||||
import com.zyplayer.doc.dubbo.controller.vo.DubboInfoVo;
|
||||
import com.zyplayer.doc.dubbo.controller.vo.NacosServiceInfoVo;
|
||||
import com.zyplayer.doc.dubbo.controller.vo.NacosServiceListVo;
|
||||
import com.zyplayer.doc.dubbo.framework.bean.DubboDocInfo;
|
||||
import com.zyplayer.doc.dubbo.framework.bean.DubboInfo;
|
||||
import com.zyplayer.doc.dubbo.framework.bean.NacosDubboInfo;
|
||||
import com.zyplayer.doc.dubbo.framework.bean.ReferenceConfigHolder;
|
||||
import com.zyplayer.doc.dubbo.framework.constant.DubboDocConst;
|
||||
import com.zyplayer.doc.dubbo.framework.constant.StorageKeys;
|
||||
import com.zyplayer.doc.dubbo.framework.service.ClassLoadService;
|
||||
import com.zyplayer.doc.dubbo.framework.service.MgDubboStorageService;
|
||||
import com.zyplayer.doc.dubbo.framework.service.NacosDocService;
|
||||
import com.zyplayer.doc.dubbo.framework.service.ZookeeperDocService;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.math.NumberUtils;
|
||||
import org.apache.curator.RetryPolicy;
|
||||
import org.apache.curator.framework.CuratorFramework;
|
||||
import org.apache.curator.framework.CuratorFrameworkFactory;
|
||||
import org.apache.curator.retry.ExponentialBackoffRetry;
|
||||
import org.apache.dubbo.common.Constants;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.utils.UrlUtils;
|
||||
import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
|
||||
import org.apache.dubbo.metadata.definition.model.MethodDefinition;
|
||||
import org.apache.dubbo.metadata.identifier.MetadataIdentifier;
|
||||
import org.apache.dubbo.rpc.service.GenericService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URLDecoder;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -56,53 +44,17 @@ import java.util.stream.Collectors;
|
||||
public class DubboController {
|
||||
private static Logger logger = LoggerFactory.getLogger(DubboController.class);
|
||||
|
||||
private final static String DEFAULT_ROOT = "dubbo";
|
||||
private final static String METADATA_NODE_NAME = "service.data";
|
||||
private String root;
|
||||
@Value("${zyplayer.doc.dubbo.doc-lib-path}")
|
||||
private String zyplayerDocDubboLibPath;
|
||||
|
||||
@Value("${zyplayer.doc.dubbo.zookeeper.url:}")
|
||||
private String serviceZookeeperUrl;
|
||||
@Value("${zyplayer.doc.dubbo.zookeeper.metadata-url:}")
|
||||
private String metadataZookeeperUrl;
|
||||
@Value("${zyplayer.doc.dubbo.nacos.url:}")
|
||||
private String nacosUrl;
|
||||
// @Value("${zyplayer.doc.dubbo.nacos.service:}")
|
||||
// private String nacosService;
|
||||
@Resource
|
||||
private MgDubboStorageService mgDubboStorageService;
|
||||
|
||||
private CuratorFramework serverClient;
|
||||
private CuratorFramework metadataClient;
|
||||
|
||||
private void initServerClient() {
|
||||
if (serverClient == null && StringUtils.isNotBlank(serviceZookeeperUrl)) {
|
||||
synchronized (DEFAULT_ROOT) {
|
||||
if (serverClient == null) {
|
||||
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
|
||||
serverClient = CuratorFrameworkFactory.newClient(serviceZookeeperUrl, retryPolicy);
|
||||
serverClient.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initMetadataClient() {
|
||||
if (metadataClient == null && StringUtils.isNotBlank(metadataZookeeperUrl)) {
|
||||
synchronized (DEFAULT_ROOT) {
|
||||
if (metadataClient == null) {
|
||||
URL url = UrlUtils.parseURL(metadataZookeeperUrl, Collections.emptyMap());
|
||||
String group = url.getParameter(Constants.GROUP_KEY, DEFAULT_ROOT);
|
||||
if (!group.startsWith(Constants.PATH_SEPARATOR)) {
|
||||
group = Constants.PATH_SEPARATOR + group;
|
||||
}
|
||||
this.root = group;
|
||||
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
|
||||
metadataClient = CuratorFrameworkFactory.newClient(metadataZookeeperUrl, retryPolicy);
|
||||
metadataClient.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@Resource
|
||||
private ZookeeperDocService zookeeperDocService;
|
||||
@Resource
|
||||
private NacosDocService nacosDocService;
|
||||
@Resource
|
||||
ClassLoadService classLoadService;
|
||||
|
||||
/**
|
||||
* 重新获取所有的服务列表
|
||||
@@ -111,17 +63,17 @@ public class DubboController {
|
||||
* @since 2019年2月10日
|
||||
**/
|
||||
@PostMapping(value = "/reloadService")
|
||||
public DocResponseJson loadService() throws Exception {
|
||||
public DocResponseJson loadService() {
|
||||
List<DubboInfo> providerList;
|
||||
try {
|
||||
if (StringUtils.isBlank(serviceZookeeperUrl)) {
|
||||
if (StringUtils.isBlank(nacosUrl)) {// || StringUtils.isBlank(nacosService)) {
|
||||
if (!zookeeperDocService.isEnable()) {
|
||||
if (!nacosDocService.isEnable()) {
|
||||
return DocResponseJson.warn("zyplayer.doc.dubbo.zookeeper.url、zyplayer.doc.dubbo.nacos.url 参数均未配置");
|
||||
}
|
||||
logger.info("zookeeper参数未配置,使用nacos配置");
|
||||
providerList = this.getDubboInfoByNacos();
|
||||
providerList = nacosDocService.getDubboInfoByNacos();
|
||||
} else {
|
||||
providerList = this.getDubboInfoByZookeeper();
|
||||
providerList = zookeeperDocService.getDubboInfoByZookeeper();
|
||||
}
|
||||
mgDubboStorageService.put(StorageKeys.DUBBO_SERVICE_LIST, JSON.toJSONString(providerList));
|
||||
} catch (Exception e) {
|
||||
@@ -143,6 +95,8 @@ public class DubboController {
|
||||
dubboNodeInfo.setIp(param.getIp());
|
||||
dubboNodeInfo.setPort(param.getPort());
|
||||
dubboNodeInfo.setInterfaceX(param.getService());
|
||||
dubboNodeInfo.setVersion(param.getVersion());
|
||||
dubboNodeInfo.setGroup(param.getGroup());
|
||||
String paramTypeStr = Optional.ofNullable(param.getParamTypes()).orElse("");
|
||||
String paramsStr = Optional.ofNullable(param.getParams()).orElse("");
|
||||
List<String> typeList = JSON.parseArray(paramTypeStr, String.class);
|
||||
@@ -155,7 +109,7 @@ public class DubboController {
|
||||
try {
|
||||
if (typeStr.endsWith("[]")) {
|
||||
String type = typeStr.substring(0, typeStr.length() - 2);
|
||||
Class<?> aClass = Class.forName(type);
|
||||
Class<?> aClass = classLoadService.loadClass(type);
|
||||
List<?> objects = JSON.parseArray(paramStr, aClass);
|
||||
queryTypeList.add(typeStr);
|
||||
queryParamList.add(objects);
|
||||
@@ -164,13 +118,13 @@ public class DubboController {
|
||||
Matcher matcher = pattern.matcher(typeStr);
|
||||
if (matcher.find()) {
|
||||
String group = matcher.group(1);
|
||||
Class<?> aClass = Class.forName(group);
|
||||
Class<?> aClass = classLoadService.loadClass(group);
|
||||
List<?> objects = JSON.parseArray(paramStr, aClass);
|
||||
queryParamList.add(objects);
|
||||
queryTypeList.add("java.util.List");
|
||||
}
|
||||
} else {
|
||||
Class<?> aClass = Class.forName(typeStr);
|
||||
Class<?> aClass = classLoadService.loadClass(typeStr);
|
||||
Object object = JSON.parseObject(paramStr, aClass);
|
||||
queryParamList.add(object);
|
||||
queryTypeList.add(typeStr);
|
||||
@@ -182,13 +136,16 @@ public class DubboController {
|
||||
queryTypeList.add(typeStr);
|
||||
}
|
||||
}
|
||||
GenericService bean = ReferenceConfigHolder.getBean(dubboNodeInfo);
|
||||
try {
|
||||
GenericService bean = ReferenceConfigHolder.getBean(dubboNodeInfo);
|
||||
if (bean == null) {
|
||||
return DocResponseJson.warn("操作失败,获取dubbo服务失败");
|
||||
}
|
||||
Object result = bean.$invoke(param.getMethod(), queryTypeList.toArray(new String[]{}), queryParamList.toArray());
|
||||
return DocResponseJson.ok(result);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return DocResponseJson.warn("请求失败:" + e.getMessage());
|
||||
return DocResponseJson.warn("操作失败," + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,9 +181,9 @@ public class DubboController {
|
||||
**/
|
||||
@PostMapping(value = "/findDocInfo")
|
||||
public DocResponseJson findDocInfo(DubboRequestParam param) {
|
||||
DubboDocInfo definition = this.getDefinitionByJar(param);
|
||||
DubboDocInfo definition = zookeeperDocService.getDefinitionByJar(param);
|
||||
if (definition == null) {
|
||||
definition = this.getDefinitionByMetadata(param);
|
||||
definition = zookeeperDocService.getDefinitionByMetadata(param);
|
||||
}
|
||||
if (definition == null) {
|
||||
return DocResponseJson.warn("未找到指定类,请引入相关包或开启metadata,类名:" + param.getService());
|
||||
@@ -298,173 +255,36 @@ public class DubboController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过nacos方式获取所有服务
|
||||
* 上传文档jar
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2019年2月10日
|
||||
* @since 2020年10月08日
|
||||
**/
|
||||
private List<DubboInfo> getDubboInfoByNacos() {
|
||||
List<DubboInfo> providerList = new LinkedList<>();
|
||||
// 获取所有的服务列表
|
||||
String serviceListStr = HttpUtil.get(nacosUrl + "/v1/ns/catalog/services?withInstances=false&pageNo=1&pageSize=100000");
|
||||
NacosServiceInfoVo nacosServiceInfoVo = JSON.parseObject(serviceListStr, NacosServiceInfoVo.class);
|
||||
if (nacosServiceInfoVo == null || nacosServiceInfoVo.getServiceList().isEmpty()) {
|
||||
return providerList;
|
||||
@PostMapping(value = "/uploadDocJar")
|
||||
public DocResponseJson uploadDocJar(@RequestParam("file") MultipartFile file) {
|
||||
File newFileDir = new File(zyplayerDocDubboLibPath);
|
||||
if (!newFileDir.exists() && !newFileDir.mkdirs()) {
|
||||
return DocResponseJson.warn("创建文件夹失败");
|
||||
}
|
||||
for (NacosServiceListVo service : nacosServiceInfoVo.getServiceList()) {
|
||||
String serviceName = service.getName();
|
||||
String resultStr = HttpUtil.get(nacosUrl + "/v1/ns/instance/list?serviceName=" + serviceName);
|
||||
NacosDubboInfo dubboInstance = JSON.parseObject(resultStr, NacosDubboInfo.class);
|
||||
List<NacosDubboInfo.HostsBean> hosts = dubboInstance.getHosts();
|
||||
DubboInfo dubboInfo = new DubboInfo();
|
||||
List<DubboInfo.DubboNodeInfo> nodeList = new LinkedList<>();
|
||||
for (NacosDubboInfo.HostsBean host : hosts) {
|
||||
DubboInfo.DubboNodeInfo dubboNodeInfo = new DubboInfo.DubboNodeInfo();
|
||||
dubboNodeInfo.setIp(host.getIp());
|
||||
dubboNodeInfo.setPort(host.getPort());
|
||||
dubboNodeInfo.setInterfaceX(host.getMetadata().getInterfaceX());
|
||||
dubboNodeInfo.setMethods(host.getMetadata().getMethods().split(","));
|
||||
dubboNodeInfo.setApplication(host.getMetadata().getApplication());
|
||||
nodeList.add(dubboNodeInfo);
|
||||
}
|
||||
if (serviceName.contains(":")) {
|
||||
serviceName = serviceName.substring(serviceName.indexOf(":") + 1);
|
||||
}
|
||||
dubboInfo.setInterfaceX(serviceName);
|
||||
dubboInfo.setNodeList(nodeList);
|
||||
providerList.add(dubboInfo);
|
||||
String fileSuffix = null;
|
||||
String fileName = file.getOriginalFilename();
|
||||
if (fileName != null) {
|
||||
fileSuffix = fileName.substring(fileName.lastIndexOf("."));
|
||||
}
|
||||
return providerList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过Zookeeper方式获取所有服务
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2019年2月10日
|
||||
**/
|
||||
private List<DubboInfo> getDubboInfoByZookeeper() throws Exception {
|
||||
this.initServerClient();
|
||||
List<String> dubboList = serverClient.getChildren().forPath("/dubbo");
|
||||
if (dubboList == null || dubboList.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
if (!Objects.equals(".jar", fileSuffix)) {
|
||||
return DocResponseJson.warn("仅支持jar后缀的文件格式上传");
|
||||
}
|
||||
List<DubboInfo> providerList = new LinkedList<>();
|
||||
for (String dubboStr : dubboList) {
|
||||
String path = "/dubbo/" + dubboStr + "/providers";
|
||||
if (serverClient.checkExists().forPath(path) == null) {
|
||||
continue;
|
||||
}
|
||||
List<String> providers = serverClient.getChildren().forPath(path);
|
||||
List<DubboInfo.DubboNodeInfo> nodeList = providers.stream().map(val -> {
|
||||
String tempStr = val;
|
||||
try {
|
||||
tempStr = URLDecoder.decode(val, "utf-8");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// IP和端口
|
||||
String ipPort = tempStr.substring(tempStr.indexOf("://") + 3);
|
||||
ipPort = ipPort.substring(0, ipPort.indexOf("/"));
|
||||
String[] ipPortArr = ipPort.split(":");
|
||||
// 参数
|
||||
Map<String, String> paramMap = new HashMap<>();
|
||||
String params = tempStr.substring(tempStr.indexOf("?"));
|
||||
String[] paramsArr = params.split("&");
|
||||
for (String param : paramsArr) {
|
||||
String[] split = param.split("=");
|
||||
paramMap.put(split[0], split[1]);
|
||||
}
|
||||
DubboInfo.DubboNodeInfo dubboNodeInfo = new DubboInfo.DubboNodeInfo();
|
||||
dubboNodeInfo.setIp(ipPortArr[0]);
|
||||
dubboNodeInfo.setPort(NumberUtils.toInt(ipPortArr[1]));
|
||||
dubboNodeInfo.setInterfaceX(paramMap.get("interface"));
|
||||
dubboNodeInfo.setMethods(paramMap.get("methods").split(","));
|
||||
dubboNodeInfo.setApplication(paramMap.get("application"));
|
||||
return dubboNodeInfo;
|
||||
}).collect(Collectors.toList());
|
||||
DubboInfo dubboInfo = new DubboInfo();
|
||||
dubboInfo.setInterfaceX(dubboStr);
|
||||
dubboInfo.setNodeList(nodeList);
|
||||
providerList.add(dubboInfo);
|
||||
}
|
||||
return providerList;
|
||||
}
|
||||
|
||||
private DubboDocInfo getDefinitionByMetadata(DubboRequestParam param) {
|
||||
try {
|
||||
this.initMetadataClient();
|
||||
String path = getNodePath(param.getService(), null, null, param.getApplication());
|
||||
if (metadataClient.checkExists().forPath(path) == null) {
|
||||
return null;
|
||||
}
|
||||
String resultType = null;
|
||||
String metadata = new String(metadataClient.getData().forPath(path));
|
||||
FullServiceDefinition definition = JSON.parseObject(metadata, FullServiceDefinition.class);
|
||||
List<DubboDocInfo.DubboDocParam> paramList = new LinkedList<>();
|
||||
for (MethodDefinition method : definition.getMethods()) {
|
||||
if (Objects.equals(method.getName(), param.getMethod())) {
|
||||
String[] parameterTypes = method.getParameterTypes();
|
||||
resultType = method.getReturnType();
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
DubboDocInfo.DubboDocParam docParam = new DubboDocInfo.DubboDocParam();
|
||||
docParam.setParamType(parameterTypes[i]);
|
||||
docParam.setParamName("arg" + i);
|
||||
paramList.add(docParam);
|
||||
}
|
||||
}
|
||||
}
|
||||
DubboDocInfo dubboDocInfo = new DubboDocInfo();
|
||||
dubboDocInfo.setParams(paramList);
|
||||
dubboDocInfo.setResultType(resultType);
|
||||
return dubboDocInfo;
|
||||
classLoadService.closeClassLoad(() -> {
|
||||
File docJarFile = new File(zyplayerDocDubboLibPath + "/" + DubboDocConst.DUBBO_DOC_LIB_NAME);
|
||||
file.transferTo(docJarFile);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return DocResponseJson.warn("保存文件失败:" + e.getMessage());
|
||||
}
|
||||
return null;
|
||||
return DocResponseJson.ok();
|
||||
}
|
||||
|
||||
private DubboDocInfo getDefinitionByJar(DubboRequestParam param) {
|
||||
String resultType = null;
|
||||
List<DubboDocInfo.DubboDocParam> paramList = new LinkedList<>();
|
||||
try {
|
||||
Class clazz = Class.forName(param.getService());
|
||||
Method[] methods = clazz.getMethods();
|
||||
for (Method method : methods) {
|
||||
String methodName = method.getName();
|
||||
if (methodName.equals(param.getMethod())) {
|
||||
resultType = method.getGenericReturnType().getTypeName();
|
||||
Type[] parameterTypes = method.getGenericParameterTypes();
|
||||
Parameter[] parameters = method.getParameters();
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
DubboDocInfo.DubboDocParam docParam = new DubboDocInfo.DubboDocParam();
|
||||
docParam.setParamName(parameters[i].getName());
|
||||
docParam.setParamType(parameterTypes[i].getTypeName());
|
||||
paramList.add(docParam);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
DubboDocInfo dubboDocInfo = new DubboDocInfo();
|
||||
dubboDocInfo.setParams(paramList);
|
||||
dubboDocInfo.setResultType(resultType);
|
||||
return dubboDocInfo;
|
||||
}
|
||||
|
||||
String toRootDir() {
|
||||
if (root.equals(Constants.PATH_SEPARATOR)) {
|
||||
return root;
|
||||
}
|
||||
return root + Constants.PATH_SEPARATOR;
|
||||
}
|
||||
|
||||
String getNodePath(String serviceInterface, String version, String group, String application) {
|
||||
MetadataIdentifier metadataIdentifier = new MetadataIdentifier(serviceInterface, version, group, Constants.PROVIDER_SIDE, application);
|
||||
return toRootDir() + metadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.PATH) + Constants.PATH_SEPARATOR + METADATA_NODE_NAME;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ public class DubboRequestParam {
|
||||
private String method;
|
||||
private String ip;
|
||||
private Integer port;
|
||||
private String version;
|
||||
private String group;
|
||||
private String paramTypes;
|
||||
private String params;
|
||||
|
||||
@@ -70,4 +72,20 @@ public class DubboRequestParam {
|
||||
public void setApplication(String application) {
|
||||
this.application = application;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public void setGroup(String group) {
|
||||
this.group = group;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ public class DubboDocInfo {
|
||||
private String paramDesc;
|
||||
private Object paramValue;
|
||||
private Integer required;
|
||||
private List<DubboDocParam> params;
|
||||
|
||||
public String getParamName() {
|
||||
return paramName;
|
||||
@@ -65,14 +64,6 @@ public class DubboDocInfo {
|
||||
public void setRequired(Integer required) {
|
||||
this.required = required;
|
||||
}
|
||||
|
||||
public List<DubboDocParam> getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public void setParams(List<DubboDocParam> params) {
|
||||
this.params = params;
|
||||
}
|
||||
}
|
||||
|
||||
public Integer getVersion() {
|
||||
|
||||
@@ -20,6 +20,8 @@ public class DubboInfo {
|
||||
private String interfaceX;
|
||||
private String[] methods;
|
||||
private String application;
|
||||
private String version;
|
||||
private String group;
|
||||
|
||||
public Integer getPort() {
|
||||
return port;
|
||||
@@ -60,6 +62,22 @@ public class DubboInfo {
|
||||
public void setApplication(String application) {
|
||||
this.application = application;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public void setGroup(String group) {
|
||||
this.group = group;
|
||||
}
|
||||
}
|
||||
|
||||
public List<DubboNodeInfo> getNodeList() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.zyplayer.doc.dubbo.framework.bean;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
import org.apache.dubbo.rpc.service.GenericService;
|
||||
@@ -15,24 +16,29 @@ public class ReferenceConfigHolder {
|
||||
private static Map<String, ReferenceConfig> referenceConfigMap = new ConcurrentHashMap<>();
|
||||
|
||||
public static GenericService getBean(DubboInfo.DubboNodeInfo dubboNodeInfo) {
|
||||
String name = dubboNodeInfo.getInterfaceX();
|
||||
String url = "dubbo://" + dubboNodeInfo.getIp() + ":" + dubboNodeInfo.getPort() + "/" + dubboNodeInfo.getInterfaceX();
|
||||
ReferenceConfig referenceConfig = referenceConfigMap.get(url);
|
||||
String url = "dubbo://" + dubboNodeInfo.getIp() + ":" + dubboNodeInfo.getPort();
|
||||
String referenceKey = url + "_" + StringUtils.defaultIfBlank(dubboNodeInfo.getVersion(), "0") + "_" + StringUtils.defaultIfBlank(dubboNodeInfo.getGroup(), "0");
|
||||
ReferenceConfig referenceConfig = referenceConfigMap.get(referenceKey);
|
||||
if (referenceConfig == null) {
|
||||
ApplicationConfig application = new ApplicationConfig();
|
||||
application.setName("zyplayer-doc-consume");
|
||||
// 参考:http://dubbo.apache.org/zh-cn/docs/user/configuration/api.html
|
||||
// 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏
|
||||
referenceConfig = new ReferenceConfig<>();
|
||||
// 如果点对点直连,可以用reference.setUrl()指定目标地址,设置url后将绕过注册中心,
|
||||
// 其中,协议对应provider.setProtocol()的值,端口对应provider.setPort()的值,
|
||||
// 路径对应service.setPath()的值,如果未设置path,缺省path为接口名
|
||||
referenceConfig.setUrl(url);
|
||||
referenceConfig.setInterface(name.substring(name.lastIndexOf(".") + 1));
|
||||
referenceConfig.setGeneric(true);
|
||||
referenceConfig.setApplication(application);
|
||||
referenceConfig.setTimeout(5000);
|
||||
referenceConfigMap.put(url, referenceConfig);
|
||||
synchronized (ReferenceConfigHolder.class) {
|
||||
ApplicationConfig application = new ApplicationConfig();
|
||||
application.setName("zyplayer-doc-consume");
|
||||
// 参考:http://dubbo.apache.org/zh-cn/docs/user/configuration/api.html
|
||||
// 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏
|
||||
referenceConfig = new ReferenceConfig<>();
|
||||
// 如果点对点直连,可以用reference.setUrl()指定目标地址,设置url后将绕过注册中心,
|
||||
// 其中,协议对应provider.setProtocol()的值,端口对应provider.setPort()的值,
|
||||
// 路径对应service.setPath()的值,如果未设置path,缺省path为接口名
|
||||
referenceConfig.setUrl(url);
|
||||
String groupAppend = StringUtils.isNotBlank(dubboNodeInfo.getGroup()) ? dubboNodeInfo.getGroup() + "/" : "";
|
||||
referenceConfig.setInterface(groupAppend + dubboNodeInfo.getInterfaceX());
|
||||
referenceConfig.setGeneric(true);
|
||||
referenceConfig.setApplication(application);
|
||||
referenceConfig.setTimeout(5000);
|
||||
referenceConfig.setVersion(dubboNodeInfo.getVersion());
|
||||
referenceConfig.setGroup(dubboNodeInfo.getGroup());
|
||||
referenceConfigMap.put(referenceKey, referenceConfig);
|
||||
}
|
||||
}
|
||||
// 本项目没有dubbo里面申明的类,快放弃时看源码发现可以设置generic返回一个GenericService对象,通过$invoke去操作具体方法,感觉又打开了一扇大门
|
||||
// 本项目选择的不入侵的方式管理文档,所以文档里面就必须手动加参数,写文档那些了
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.zyplayer.doc.dubbo.framework.constant;
|
||||
|
||||
/**
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年11月08日
|
||||
*/
|
||||
public class DubboDocConst {
|
||||
/**上传的文档jar文件名*/
|
||||
public static final String DUBBO_DOC_LIB_NAME = "zyplayer-doc-dubbo-libs.jar";
|
||||
|
||||
}
|
||||
@@ -1,14 +1,19 @@
|
||||
package com.zyplayer.doc.dubbo.framework.service;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.zyplayer.doc.annotation.DocMethod;
|
||||
import com.zyplayer.doc.annotation.DocParam;
|
||||
import com.zyplayer.doc.core.exception.ConfirmException;
|
||||
import com.zyplayer.doc.dubbo.framework.bean.DubboResponseInfo;
|
||||
import com.zyplayer.doc.dubbo.framework.bean.InterfaceType;
|
||||
import com.zyplayer.doc.dubbo.framework.constant.BaseType;
|
||||
import com.zyplayer.doc.dubbo.framework.constant.DubboDocConst;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.net.JarURLConnection;
|
||||
@@ -18,39 +23,111 @@ import java.util.*;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
/**
|
||||
* 类加载服务
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年11月08日
|
||||
*/
|
||||
@Service
|
||||
public class ClassLoadService {
|
||||
private static Logger logger = LoggerFactory.getLogger(ClassLoadService.class);
|
||||
|
||||
@Value("${zyplayer.doc.dubbo.doc-lib-path}")
|
||||
private String zyplayerDocDubboLibPath;
|
||||
|
||||
private URLClassLoader docClassLoader;
|
||||
|
||||
/**
|
||||
* 获取文档jar类加载器
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年11月08日
|
||||
*/
|
||||
private URLClassLoader getDocClassLoader() throws Exception {
|
||||
if (docClassLoader != null) {
|
||||
return docClassLoader;
|
||||
}
|
||||
if (!FileUtil.isFile(zyplayerDocDubboLibPath + "/" + DubboDocConst.DUBBO_DOC_LIB_NAME)) {
|
||||
throw new ConfirmException("请先上传文档JAR");
|
||||
}
|
||||
synchronized (ClassLoadService.class) {
|
||||
// file:D:/maven/repository/com/zyplayer/dubbo-api/1.0/dubbo-api-1.0.jar
|
||||
URL fileUrl = new URL("file:/" + zyplayerDocDubboLibPath + "/" + DubboDocConst.DUBBO_DOC_LIB_NAME);
|
||||
docClassLoader = new URLClassLoader(new URL[]{fileUrl}, Thread.currentThread().getContextClassLoader());
|
||||
}
|
||||
return docClassLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭类加载器,callback中可对文件进行覆盖上传
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年11月08日
|
||||
*/
|
||||
public void closeClassLoad(ClassLoaderCallback callback) throws Exception {
|
||||
synchronized (ClassLoadService.class) {
|
||||
try {
|
||||
if (docClassLoader != null) {
|
||||
docClassLoader.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("关闭类加载器失败", e);
|
||||
}
|
||||
docClassLoader = null;
|
||||
if (callback != null) {
|
||||
// callback方式,防止刚close,马上又被别人new出来了
|
||||
callback.callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载类
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年11月08日
|
||||
*/
|
||||
public Class<?> loadClass(String serverName) throws Exception {
|
||||
try {
|
||||
return this.getDocClassLoader().loadClass(serverName);
|
||||
} catch (Exception e) {
|
||||
// 失败之后先关闭再去加载一次
|
||||
this.closeClassLoad(null);
|
||||
return this.getDocClassLoader().loadClass(serverName);
|
||||
}
|
||||
}
|
||||
|
||||
// public static void main(String[] args) throws Exception {
|
||||
// String serviceName = "com.zyplayer.dubbo.service.AnnotateService";
|
||||
// String jarGroup = "com.zyplayer";
|
||||
// String jarArtifact = "dubbo-api";
|
||||
// String jarVersion = "1.0";
|
||||
// String basePath = "file:D:/maven/repository";
|
||||
//// String basePath = "http://nexus.dmall.com:8081/nexus/content/groups/public";
|
||||
//// String basePath = "http://nexus.zyplayer.com:8081/nexus/content/groups/public";
|
||||
// new ClassLoadService().loadServerMethod(serviceName, basePath, jarGroup, jarArtifact, jarVersion);
|
||||
// }
|
||||
|
||||
// public static void main(String[] args) throws Exception {
|
||||
// String serviceName = "com.zyplayer.data.service.dubbo.DataIndicatorsService";
|
||||
// String jarGroup = "com.zyplayer.data";
|
||||
// String jarArtifact = "data-api-client";
|
||||
// String jarVersion = "1.0.9.SNAPSHOTS";
|
||||
// String basePath = "http://nexus.zyplayer.com:8081/nexus/content/groups/public";
|
||||
// new ClassLoadService().loadServerMethod(serviceName, basePath, jarGroup, jarArtifact, jarVersion);
|
||||
// }
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String serviceName = "com.dmall.data.service.dubbo.DataIndicatorsService";
|
||||
String jarGroup = "com.dmall.data";
|
||||
String jarArtifact = "data-api-client";
|
||||
String jarVersion = "1.0.9.SNAPSHOTS";
|
||||
String basePath = "http://nexus.dmall.com:8081/nexus/content/groups/public";
|
||||
new ClassLoadService().loadServerMethod(serviceName, basePath, jarGroup, jarArtifact, jarVersion);
|
||||
}
|
||||
|
||||
public void loadServerMethod(String serverName, String basePath, String jarGroup, String jarArtifact, String jarVersion) throws Exception {
|
||||
public void loadServerMethod(String serverName) throws Exception {
|
||||
// jar:file:D:/maven/repository/com/zyplayer/dubbo-api/1.0/dubbo-api-1.0.jar!/
|
||||
String jarPath = jarGroup.replaceAll("\\.", "/") + "/" + jarArtifact + "/" + jarVersion + "/" + jarArtifact + "-" + jarVersion + ".jar";
|
||||
URL jarUrl = new URL("jar:" + basePath + "/" + jarPath + "!/");
|
||||
String docJarFileUrl = "file:/" + zyplayerDocDubboLibPath + "/" + DubboDocConst.DUBBO_DOC_LIB_NAME;
|
||||
URL jarUrl = new URL("jar:" + docJarFileUrl + "!/");
|
||||
JarFile jar = ((JarURLConnection) jarUrl.openConnection()).getJarFile();
|
||||
JarEntry jarEntry = jar.getJarEntry(serverName.replaceAll("\\.", "/") + ".class");
|
||||
if (jarEntry == null) {
|
||||
logger.info("未找到类");
|
||||
return;
|
||||
}
|
||||
URL fileUrl = new URL(basePath + "/" + jarPath);
|
||||
URL fileUrl = new URL(docJarFileUrl);
|
||||
URLClassLoader classLoader = new URLClassLoader(new URL[]{fileUrl}, Thread.currentThread().getContextClassLoader());
|
||||
Class<?> clazz = classLoader.loadClass(serverName);
|
||||
Method[] methods = clazz.getMethods();
|
||||
@@ -220,8 +297,8 @@ public class ClassLoadService {
|
||||
List<DubboResponseInfo> paramList = new LinkedList<>();
|
||||
Field[] fieldArr = clazz.getDeclaredFields();
|
||||
for (Field field : fieldArr) {
|
||||
field.setAccessible(true);
|
||||
try {
|
||||
field.setAccessible(true);
|
||||
paramList.add(this.getInfoByField(classLoader, field, recursion));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.zyplayer.doc.dubbo.framework.service;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月19日
|
||||
*/
|
||||
public interface ClassLoaderCallback {
|
||||
|
||||
/**
|
||||
* 回调
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年10月08日
|
||||
*/
|
||||
void callback() throws Exception;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.zyplayer.doc.dubbo.framework.service;
|
||||
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.zyplayer.doc.dubbo.controller.vo.NacosServiceInfoVo;
|
||||
import com.zyplayer.doc.dubbo.controller.vo.NacosServiceListVo;
|
||||
import com.zyplayer.doc.dubbo.framework.bean.DubboInfo;
|
||||
import com.zyplayer.doc.dubbo.framework.bean.NacosDubboInfo;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* nacos方式加载文档服务
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年11月08日
|
||||
*/
|
||||
@Service
|
||||
public class NacosDocService {
|
||||
|
||||
@Value("${zyplayer.doc.dubbo.nacos.url:}")
|
||||
private String nacosUrl;
|
||||
// @Value("${zyplayer.doc.dubbo.nacos.service:}")
|
||||
// private String nacosService;
|
||||
|
||||
/**
|
||||
* 是否开启nacos文档
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年11月08日
|
||||
*/
|
||||
public boolean isEnable() {
|
||||
return StringUtils.isNotBlank(nacosUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过nacos方式获取所有服务
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2019年2月10日
|
||||
**/
|
||||
public List<DubboInfo> getDubboInfoByNacos() {
|
||||
List<DubboInfo> providerList = new LinkedList<>();
|
||||
// 获取所有的服务列表
|
||||
String serviceListStr = HttpUtil.get(nacosUrl + "/v1/ns/catalog/services?withInstances=false&pageNo=1&pageSize=100000");
|
||||
NacosServiceInfoVo nacosServiceInfoVo = JSON.parseObject(serviceListStr, NacosServiceInfoVo.class);
|
||||
if (nacosServiceInfoVo == null || nacosServiceInfoVo.getServiceList().isEmpty()) {
|
||||
return providerList;
|
||||
}
|
||||
for (NacosServiceListVo service : nacosServiceInfoVo.getServiceList()) {
|
||||
String serviceName = service.getName();
|
||||
String resultStr = HttpUtil.get(nacosUrl + "/v1/ns/instance/list?serviceName=" + serviceName);
|
||||
NacosDubboInfo dubboInstance = JSON.parseObject(resultStr, NacosDubboInfo.class);
|
||||
List<NacosDubboInfo.HostsBean> hosts = dubboInstance.getHosts();
|
||||
DubboInfo dubboInfo = new DubboInfo();
|
||||
List<DubboInfo.DubboNodeInfo> nodeList = new LinkedList<>();
|
||||
for (NacosDubboInfo.HostsBean host : hosts) {
|
||||
DubboInfo.DubboNodeInfo dubboNodeInfo = new DubboInfo.DubboNodeInfo();
|
||||
dubboNodeInfo.setIp(host.getIp());
|
||||
dubboNodeInfo.setPort(host.getPort());
|
||||
dubboNodeInfo.setInterfaceX(host.getMetadata().getInterfaceX());
|
||||
dubboNodeInfo.setMethods(host.getMetadata().getMethods().split(","));
|
||||
dubboNodeInfo.setApplication(host.getMetadata().getApplication());
|
||||
nodeList.add(dubboNodeInfo);
|
||||
}
|
||||
if (serviceName.contains(":")) {
|
||||
serviceName = serviceName.substring(serviceName.indexOf(":") + 1);
|
||||
}
|
||||
dubboInfo.setInterfaceX(serviceName);
|
||||
dubboInfo.setNodeList(nodeList);
|
||||
providerList.add(dubboInfo);
|
||||
}
|
||||
return providerList;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
package com.zyplayer.doc.dubbo.framework.service;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.zyplayer.doc.dubbo.controller.param.DubboRequestParam;
|
||||
import com.zyplayer.doc.dubbo.framework.bean.DubboDocInfo;
|
||||
import com.zyplayer.doc.dubbo.framework.bean.DubboInfo;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.math.NumberUtils;
|
||||
import org.apache.curator.RetryPolicy;
|
||||
import org.apache.curator.framework.CuratorFramework;
|
||||
import org.apache.curator.framework.CuratorFrameworkFactory;
|
||||
import org.apache.curator.retry.ExponentialBackoffRetry;
|
||||
import org.apache.dubbo.common.Constants;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.utils.UrlUtils;
|
||||
import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
|
||||
import org.apache.dubbo.metadata.definition.model.MethodDefinition;
|
||||
import org.apache.dubbo.metadata.identifier.MetadataIdentifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* zookeeper方式加载文档服务
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年11月08日
|
||||
*/
|
||||
@Service
|
||||
public class ZookeeperDocService {
|
||||
|
||||
@Value("${zyplayer.doc.dubbo.zookeeper.url:}")
|
||||
private String serviceZookeeperUrl;
|
||||
@Value("${zyplayer.doc.dubbo.zookeeper.metadata-url:}")
|
||||
private String metadataZookeeperUrl;
|
||||
|
||||
@Resource
|
||||
ClassLoadService classLoadService;
|
||||
|
||||
private CuratorFramework serverClient;
|
||||
private CuratorFramework metadataClient;
|
||||
|
||||
private final static String DEFAULT_ROOT = "dubbo";
|
||||
private final static String METADATA_NODE_NAME = "service.data";
|
||||
private String root;
|
||||
|
||||
/**
|
||||
* zookeeper初始化
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年11月08日
|
||||
*/
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
// 初始化zk注册中心连接
|
||||
if (StringUtils.isNotBlank(serviceZookeeperUrl)) {
|
||||
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
|
||||
serverClient = CuratorFrameworkFactory.newClient(serviceZookeeperUrl, retryPolicy);
|
||||
serverClient.start();
|
||||
}
|
||||
// 初始化zk注册中心元数据信息
|
||||
if (StringUtils.isNotBlank(metadataZookeeperUrl)) {
|
||||
URL url = UrlUtils.parseURL(metadataZookeeperUrl, Collections.emptyMap());
|
||||
String group = url.getParameter(Constants.GROUP_KEY, DEFAULT_ROOT);
|
||||
if (!group.startsWith(Constants.PATH_SEPARATOR)) {
|
||||
group = Constants.PATH_SEPARATOR + group;
|
||||
}
|
||||
this.root = group;
|
||||
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
|
||||
metadataClient = CuratorFrameworkFactory.newClient(metadataZookeeperUrl, retryPolicy);
|
||||
metadataClient.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否启用了zk文档
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年11月08日
|
||||
*/
|
||||
public boolean isEnable() {
|
||||
return StringUtils.isNotBlank(serviceZookeeperUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过Zookeeper方式获取所有服务
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2019年2月10日
|
||||
**/
|
||||
public List<DubboInfo> getDubboInfoByZookeeper() throws Exception {
|
||||
if (serverClient == null) {
|
||||
return null;
|
||||
}
|
||||
List<String> dubboList = serverClient.getChildren().forPath("/dubbo");
|
||||
if (dubboList == null || dubboList.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<DubboInfo> providerList = new LinkedList<>();
|
||||
for (String dubboStr : dubboList) {
|
||||
String path = "/dubbo/" + dubboStr + "/providers";
|
||||
if (serverClient.checkExists().forPath(path) == null) {
|
||||
continue;
|
||||
}
|
||||
List<String> providers = serverClient.getChildren().forPath(path);
|
||||
List<DubboInfo.DubboNodeInfo> nodeList = providers.stream().map(val -> {
|
||||
String tempStr = val;
|
||||
try {
|
||||
tempStr = URLDecoder.decode(val, "utf-8");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// IP和端口
|
||||
String ipPort = tempStr.substring(tempStr.indexOf("://") + 3);
|
||||
ipPort = ipPort.substring(0, ipPort.indexOf("/"));
|
||||
String[] ipPortArr = ipPort.split(":");
|
||||
// 参数
|
||||
Map<String, String> paramMap = new HashMap<>();
|
||||
String params = tempStr.substring(tempStr.indexOf("?") + 1);
|
||||
String[] paramsArr = params.split("&");
|
||||
for (String param : paramsArr) {
|
||||
String[] split = param.split("=");
|
||||
paramMap.put(split[0], split[1]);
|
||||
}
|
||||
DubboInfo.DubboNodeInfo dubboNodeInfo = new DubboInfo.DubboNodeInfo();
|
||||
dubboNodeInfo.setIp(ipPortArr[0]);
|
||||
dubboNodeInfo.setPort(NumberUtils.toInt(ipPortArr[1]));
|
||||
dubboNodeInfo.setInterfaceX(paramMap.get("interface"));
|
||||
dubboNodeInfo.setMethods(paramMap.get("methods").split(","));
|
||||
dubboNodeInfo.setApplication(paramMap.get("application"));
|
||||
dubboNodeInfo.setVersion(paramMap.get("version"));
|
||||
dubboNodeInfo.setGroup(paramMap.get("group"));
|
||||
return dubboNodeInfo;
|
||||
}).collect(Collectors.toList());
|
||||
DubboInfo dubboInfo = new DubboInfo();
|
||||
dubboInfo.setInterfaceX(dubboStr);
|
||||
dubboInfo.setNodeList(nodeList);
|
||||
providerList.add(dubboInfo);
|
||||
}
|
||||
return providerList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过zk中的meta信息获取文档
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年11月08日
|
||||
*/
|
||||
public DubboDocInfo getDefinitionByMetadata(DubboRequestParam param) {
|
||||
if (metadataClient == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
String path = getNodePath(param.getService(), null, null, param.getApplication());
|
||||
if (metadataClient.checkExists().forPath(path) == null) {
|
||||
return null;
|
||||
}
|
||||
String resultType = null;
|
||||
String metadata = new String(metadataClient.getData().forPath(path));
|
||||
FullServiceDefinition definition = JSON.parseObject(metadata, FullServiceDefinition.class);
|
||||
List<DubboDocInfo.DubboDocParam> paramList = new LinkedList<>();
|
||||
for (MethodDefinition method : definition.getMethods()) {
|
||||
if (Objects.equals(method.getName(), param.getMethod())) {
|
||||
String[] parameterTypes = method.getParameterTypes();
|
||||
resultType = method.getReturnType();
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
DubboDocInfo.DubboDocParam docParam = new DubboDocInfo.DubboDocParam();
|
||||
docParam.setParamType(parameterTypes[i]);
|
||||
docParam.setParamName("arg" + i);
|
||||
paramList.add(docParam);
|
||||
}
|
||||
}
|
||||
}
|
||||
DubboDocInfo dubboDocInfo = new DubboDocInfo();
|
||||
dubboDocInfo.setParams(paramList);
|
||||
dubboDocInfo.setResultType(resultType);
|
||||
return dubboDocInfo;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过jar方式获取文档
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年11月08日
|
||||
*/
|
||||
public DubboDocInfo getDefinitionByJar(DubboRequestParam param) {
|
||||
String resultType = null;
|
||||
List<DubboDocInfo.DubboDocParam> paramList = new LinkedList<>();
|
||||
try {
|
||||
Class clazz = classLoadService.loadClass(param.getService());
|
||||
Method[] methods = clazz.getMethods();
|
||||
for (Method method : methods) {
|
||||
String methodName = method.getName();
|
||||
if (methodName.equals(param.getMethod())) {
|
||||
resultType = method.getGenericReturnType().getTypeName();
|
||||
Type[] parameterTypes = method.getGenericParameterTypes();
|
||||
Parameter[] parameters = method.getParameters();
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
DubboDocInfo.DubboDocParam docParam = new DubboDocInfo.DubboDocParam();
|
||||
docParam.setParamName(parameters[i].getName());
|
||||
docParam.setParamType(parameterTypes[i].getTypeName());
|
||||
paramList.add(docParam);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
DubboDocInfo dubboDocInfo = new DubboDocInfo();
|
||||
dubboDocInfo.setParams(paramList);
|
||||
dubboDocInfo.setResultType(resultType);
|
||||
return dubboDocInfo;
|
||||
}
|
||||
|
||||
private String toRootDir() {
|
||||
if (Objects.isNull(root)) {
|
||||
return Constants.PATH_SEPARATOR;
|
||||
}
|
||||
if (Objects.equals(Constants.PATH_SEPARATOR, root)) {
|
||||
return root;
|
||||
}
|
||||
return root + Constants.PATH_SEPARATOR;
|
||||
}
|
||||
|
||||
private String getNodePath(String serviceInterface, String version, String group, String application) {
|
||||
MetadataIdentifier metadataIdentifier = new MetadataIdentifier(serviceInterface, version, group, Constants.PROVIDER_SIDE, application);
|
||||
return toRootDir() + metadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.PATH) + Constants.PATH_SEPARATOR + METADATA_NODE_NAME;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user