package com.vci.ubcs.omd.repeater;
|
|
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
|
import com.alibaba.cloud.nacos.NacosServiceManager;
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.nacos.api.exception.NacosException;
|
import com.alibaba.nacos.api.naming.NamingService;
|
import com.alibaba.nacos.api.naming.pojo.Instance;
|
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
|
import com.vci.ubcs.common.constant.LauncherConstant;
|
import com.vci.ubcs.omd.dto.BtmAndLinkTypeDdlDTO;
|
import com.vci.ubcs.omd.vo.BtmTypeVO;
|
import com.vci.ubcs.omd.vo.LinkTypeVO;
|
import org.springblade.core.launch.constant.AppConstant;
|
import org.springblade.core.secure.utils.AuthUtil;
|
import org.springblade.core.tool.api.R;
|
import org.springblade.core.tool.utils.StringPool;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.http.*;
|
import org.springframework.stereotype.Component;
|
import org.springframework.util.CollectionUtils;
|
import org.springframework.web.client.HttpClientErrorException;
|
import org.springframework.web.client.RestTemplate;
|
|
import javax.annotation.PostConstruct;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
/**
|
* Description: 领域转发器
|
*
|
* @author LiHang
|
* @date 2023/4/25
|
*/
|
@Component
|
public class DomainRepeater {
|
|
/**
|
* 控制器路径
|
*/
|
public static final String API_PREFIX = "ddl";
|
|
/**
|
* 新增或修改的转发路径名称
|
*/
|
public static final String API_SUBMIT = API_PREFIX + StringPool.SLASH + "submit";
|
|
/**
|
* 表名获取表信息
|
*/
|
public static final String API_GET_TABLE_INFO = API_PREFIX + StringPool.SLASH + "getTableColumnByTableName";
|
|
/**
|
* 获取全部表信息
|
*/
|
public static final String API_GET_ALL_TABLE_INFO = API_PREFIX + StringPool.SLASH + "getAllTableInfo";
|
/**
|
* 获取数据库和业务类型中的不同的地方
|
*/
|
public static final String API_CHECK_DIFFERENT_REFLEX = API_PREFIX + StringPool.SLASH + "checkDifferentAndReflex";
|
|
/**
|
* 用于构建静态服务类
|
*/
|
public static DomainRepeater domainRepeater;
|
/**
|
* Nacos服务列表
|
*/
|
private static NamingService namingService;
|
@Autowired
|
private NacosServiceManager manager;
|
|
@Autowired
|
private NacosDiscoveryProperties properties;
|
|
|
/**
|
* 拿取服务中的所有表信息
|
* @param serviceName 服务名称
|
* @return 返回结果
|
* @throws NacosException 找不到服务时抛出异常
|
*/
|
public static R getFromTable(String serviceName) throws NacosException{
|
ResponseEntity<R> responseEntity = executeGet(getUrl(serviceName, API_GET_ALL_TABLE_INFO), new HashMap<>());
|
if (responseEntity.getStatusCode().equals(HttpStatus.OK)) {
|
R body = Objects.requireNonNull(responseEntity.getBody());
|
return body;
|
}
|
return R.fail(String.valueOf(responseEntity.getStatusCode().value()));
|
}
|
|
@PostConstruct
|
private void init() {
|
domainRepeater = this;
|
namingService = manager.getNamingService(properties.getNacosProperties());
|
}
|
|
/**
|
* 一致性检查
|
* @param ddlDTO 业务类型、链接类型传输对象
|
* @param serviceName 服务名
|
* @return 执行结果,有修改的就会返回。
|
* @throws NacosException nacos查询服务出错时抛出异常
|
*/
|
public static R checkDifferent(BtmAndLinkTypeDdlDTO ddlDTO,String serviceName) throws NacosException {
|
try {
|
String url = getUrl(serviceName, API_CHECK_DIFFERENT_REFLEX);
|
ResponseEntity<R> responseEntity = executePost(url, JSONObject.toJSONString(ddlDTO), null);
|
if (responseEntity.getStatusCode().equals(HttpStatus.OK)) {
|
R body = Objects.requireNonNull(responseEntity.getBody());
|
return body;
|
}
|
return R.fail(String.valueOf(responseEntity.getStatusCode().value()));
|
}catch (HttpClientErrorException e) {
|
if (HttpStatus.NOT_FOUND.equals(e.getStatusCode())) {
|
R fail = R.fail("调用服务失败");
|
fail.setCode(HttpStatus.NOT_FOUND.value());
|
return fail;
|
}
|
} catch (Exception e) {
|
throw new RuntimeException(e);
|
}
|
return R.fail("未知错误");
|
}
|
|
/**
|
* 根据api接口拼接url地址
|
* @param serviceName 服务名
|
* @param api 接口地址
|
* @return url地址
|
* @throws NacosException nacos查询服务出错时抛出异常
|
*/
|
|
public static String getUrl(String serviceName,String api) throws NacosException {
|
Instance service = namingService.selectOneHealthyInstance(AppConstant.APPLICATION_GATEWAY_NAME);
|
return "http://" + service.getIp() + StringPool.COLON + service.getPort() + StringPool.SLASH + serviceName + StringPool.SLASH + api;
|
}
|
|
|
/**
|
* 新增或修改业务类型
|
* @param vo 业务类型传输对象
|
* @param serviceName 服务名
|
* @return 执行结果,有修改的就会返回。
|
*/
|
public static R submitBtmType(String serviceName, BtmTypeVO vo) {
|
try {
|
String url = getUrl(serviceName, API_SUBMIT);
|
BtmAndLinkTypeDdlDTO ddlDTO = new BtmAndLinkTypeDdlDTO();
|
ddlDTO.setBtmTypeList(new ArrayList<>(Collections.singletonList(vo)));
|
ResponseEntity<R> responseEntity = executePost(url, JSONObject.toJSONString(ddlDTO), null);
|
if (responseEntity.getStatusCode().equals(HttpStatus.OK)) {
|
return responseEntity.getBody();
|
}
|
return R.fail(String.valueOf(responseEntity.getStatusCode().value()));
|
} catch (HttpClientErrorException e) {
|
if (HttpStatus.NOT_FOUND.equals(e.getStatusCode())) {
|
R fail = R.fail("调用服务失败");
|
fail.setCode(HttpStatus.NOT_FOUND.value());
|
return fail;
|
}
|
} catch (Exception e) {
|
throw new RuntimeException(e);
|
}
|
return R.fail("未知错误");
|
}
|
|
/**
|
* 新增或修改链接类型
|
* @param vo 业务类型传输对象
|
* @param serviceName 服务名
|
* @return 执行结果,有修改的就会返回。
|
*/
|
public static R submitLinkType(String serviceName, LinkTypeVO vo) {
|
try {
|
String url = getUrl(serviceName, API_SUBMIT);
|
BtmAndLinkTypeDdlDTO ddlDTO = new BtmAndLinkTypeDdlDTO();
|
ddlDTO.setLinkTypeList(new ArrayList<>(Collections.singletonList(vo)));
|
ResponseEntity<R> responseEntity = executePost(url, JSONObject.toJSONString(ddlDTO), null);
|
if (responseEntity.getStatusCode().equals(HttpStatus.OK)) {
|
return responseEntity.getBody();
|
}
|
return R.fail(String.valueOf(responseEntity.getStatusCode().value()));
|
} catch (HttpClientErrorException e) {
|
if (HttpStatus.NOT_FOUND.equals(e.getStatusCode())) {
|
R fail = R.fail("调用服务失败");
|
fail.setCode(HttpStatus.NOT_FOUND.value());
|
return fail;
|
}
|
} catch (Exception e) {
|
throw new RuntimeException(e);
|
}
|
return R.fail("未知错误");
|
}
|
|
/**
|
* 执行httpPost接口
|
*
|
* @param url 地址
|
* @param body 请求体
|
* @param extraHeaders 请求头参数
|
* @return 执行结果
|
*/
|
private static ResponseEntity<R> executePost(String url, String body, Map<String, String> extraHeaders) {
|
RestTemplate restTemplate = new RestTemplate();
|
HttpHeaders httpHeaders = new HttpHeaders();
|
httpHeaders.add("Content-Type", "application/json;charset=UTF-8");
|
httpHeaders.add("Blade-Auth", AuthUtil.getHeader());
|
Optional.ofNullable(extraHeaders).orElseGet(HashMap::new).forEach(httpHeaders::add);
|
HttpEntity<String> request = new HttpEntity<>(body, httpHeaders);
|
return restTemplate.postForEntity(url, request, R.class);
|
}
|
|
/**
|
* 执行httpGet接口
|
*
|
* @param url 地址
|
* @param extraHeaders 请求头参数
|
* @return 执行结果
|
*/
|
private static ResponseEntity<R> executeGet(String url,Map<String, String> extraHeaders) {
|
RestTemplate restTemplate = new RestTemplate();
|
HttpHeaders httpHeaders = new HttpHeaders();
|
httpHeaders.add("Blade-Auth", AuthUtil.getHeader());
|
HttpEntity<String> request = new HttpEntity<>(httpHeaders);
|
if (!CollectionUtils.isEmpty(extraHeaders)){
|
StringBuilder sb = new StringBuilder().append("?");
|
extraHeaders.forEach( (k,v) -> {
|
sb.append(k).append(StringPool.EQUALS).append(v).append(StringPool.AMPERSAND);
|
});
|
String str = sb.toString();
|
if (str.endsWith(StringPool.AMPERSAND)){
|
str = str.substring(0,str.length()-1);
|
}
|
url = url + str;
|
}
|
return restTemplate.exchange(url, HttpMethod.GET,request,R.class,"");
|
}
|
|
/**
|
* 获取所有已注册的服务
|
* @return 不包含默认服务的其他服务
|
* @throws NacosException
|
*/
|
public static List<String> getDomain() throws NacosException {
|
RestTemplate restTemplate = new RestTemplate();
|
String url = "http://" +LauncherConstant.NACOS_DEV_ADDR + "/nacos/v1/ns/service/list?pageNo=1&pageSize=50";
|
String forObject = restTemplate.getForObject(url, String.class);
|
JSONObject jsonObject = JSON.parseObject(forObject);
|
return (List<String>) jsonObject.get("doms");
|
}
|
}
|