Merge pull request 'feat : portal模块添加注释信息' (#65) from portal into master
Reviewed-on: http://git.feashow.cn/clay/fateverse/pulls/65
This commit is contained in:
@@ -57,6 +57,7 @@ public class PortalController {
|
||||
}
|
||||
|
||||
@ApiOperation("新增接口")
|
||||
@Encrypt
|
||||
@PostMapping
|
||||
@PreAuthorize("@ss.hasPermission('query:portal:add')")
|
||||
public Result<PortalIdWrapper> add(@RequestBody @Validated PortalDto portalDto) {
|
||||
@@ -65,6 +66,7 @@ public class PortalController {
|
||||
}
|
||||
|
||||
@ApiOperation("修改接口")
|
||||
@Encrypt
|
||||
@PutMapping
|
||||
@PreAuthorize("@ss.hasPermission('query:portal:edit')")
|
||||
public Result<PortalIdWrapper> edit(@RequestBody @Validated PortalDto portalDto) {
|
||||
|
||||
@@ -53,10 +53,13 @@ public class PortalDispatchServlet {
|
||||
}
|
||||
|
||||
private void doDispatch(HttpServletRequest request, HttpServletResponse response) {
|
||||
//获取到请求路径
|
||||
String path = request.getServletPath();
|
||||
//获取请求方法
|
||||
String method = request.getMethod();
|
||||
|
||||
//从Redis中获取到当前的方法信息
|
||||
PortalBo portalBo = redisTemplate.opsForValue().get(QueryConstant.PORTAL_KEY + path + ":" + method);
|
||||
//判断是否为空,如果为空则从数据库中查找
|
||||
if (portalBo == null) {
|
||||
Portal portal = portalMapper.selectByPath(path, method);
|
||||
if (portal == null) {
|
||||
@@ -67,10 +70,10 @@ public class PortalDispatchServlet {
|
||||
portalBo = PortalBo.toPortalBo(portal, portalMappings);
|
||||
redisTemplate.opsForValue().set(QueryConstant.PORTAL_KEY + portalBo.getPath() + ":" + portalBo.getRequestMethod(), portalBo);
|
||||
}
|
||||
|
||||
|
||||
//自定义查询编辑查询对象
|
||||
SearchInfo searchInfo = new SearchInfo();
|
||||
List<UniConDto> uniConList = new ArrayList<>();
|
||||
//根据映射关系从request中获取请求参数
|
||||
for (PortalMapping portalMapping : portalBo.getMappings()) {
|
||||
UniConDto uniCon = new UniConDto();
|
||||
String mappingValue = portalMapping.getMappingValue();
|
||||
@@ -86,14 +89,16 @@ public class PortalDispatchServlet {
|
||||
uniConList.add(uniCon);
|
||||
}
|
||||
searchInfo.setList(uniConList);
|
||||
|
||||
//获取当当前接口对应的数据适配器
|
||||
DataAdapter dataAdapter = dataAdapterMapper.selectById(portalBo.getAdapterId());
|
||||
//进行数据适配器的执行逻辑
|
||||
Object result = null;
|
||||
if (portalBo.getState() == 1 || portalBo.getState() == 2) {
|
||||
result = dataAdapterHandler.execute(dataAdapter, portalBo, searchInfo);
|
||||
} else {
|
||||
result = dataAdapterHandler.mockExecute(dataAdapter, portalBo, searchInfo);
|
||||
}
|
||||
//将返回结果放入response
|
||||
ResponseRender.renderString(response, Result.ok(result));
|
||||
}
|
||||
|
||||
|
||||
@@ -51,19 +51,25 @@ public class DispatchSyncService {
|
||||
|
||||
|
||||
public DispatchSyncService(NacosDiscoveryProperties nacosDiscoveryProperties, Environment environment, NacosRegistration nacosRegistration, ThreadPoolTaskExecutor taskExecuteExecutor, DubboServiceBean serviceBean) {
|
||||
//获取当前主机地址
|
||||
this.host = nacosRegistration.getHost();
|
||||
//获取到端口信息的bean
|
||||
this.serviceBean = serviceBean;
|
||||
NacosServiceManager nacosServiceManager = new NacosServiceManager();
|
||||
Properties nacosProperties = nacosDiscoveryProperties.getNacosProperties();
|
||||
//获取dubbo的命名空间
|
||||
String namespace = environment.getProperty("dubbo.registry.parameters.namespace");
|
||||
//获取到当前服务名称
|
||||
this.serviceName = environment.getProperty("dubbo.application.name");
|
||||
nacosProperties.setProperty(PropertyKeyConst.NAMESPACE, namespace);
|
||||
//获取到nacos的管理服务
|
||||
this.namingService = nacosServiceManager.getNamingService(nacosProperties);
|
||||
|
||||
//启动单线程,监听阻塞队列
|
||||
new Thread(() -> {
|
||||
while (true) {
|
||||
try {
|
||||
Runnable take = queue.take();
|
||||
//执行同步任务
|
||||
taskExecuteExecutor.execute(take);
|
||||
} catch (InterruptedException e) {
|
||||
log.info("", e);
|
||||
@@ -80,24 +86,33 @@ public class DispatchSyncService {
|
||||
|
||||
private void syncDispatch(String path, String requestMethod, Boolean publish) {
|
||||
try {
|
||||
//获取nacos中的服务信息
|
||||
List<Instance> allInstances = namingService.getAllInstances(serviceName);
|
||||
for (Instance instance : allInstances) {
|
||||
//判断当前服务是否为本服务
|
||||
if (!(instance.getIp().equals(host) && instance.getPort() == serviceBean.getPort())) {
|
||||
//不是本服务则需要发起同步任务
|
||||
Task task = new Task(instance.getIp(), instance.getPort(), path, publish, requestMethod) {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
//获取云端服务信息
|
||||
List<Instance> allInstances = namingService.getAllInstances(serviceName);
|
||||
//如果没有则不进行同步
|
||||
if (ObjectUtils.isEmpty(allInstances)) {
|
||||
return;
|
||||
}
|
||||
//检查云端实例中是否还存在当前服务,不存在当前任务结束
|
||||
Optional<Instance> optional = allInstances.stream().filter(instance -> this.ip.equals(instance.getIp()) && this.port == instance.getPort()).findAny();
|
||||
if (optional.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Instance instance = optional.get();
|
||||
//指定需要同步服务的ip + port
|
||||
UserSpecifiedAddressUtil.setAddress(new Address(instance.getIp(), instance.getPort(), true));
|
||||
//记录同步状态
|
||||
Boolean state = null;
|
||||
//是否为发布任务
|
||||
if (publish) {
|
||||
log.info("dubboDispatchServletPublish.publish({}, {})", path, requestMethod);
|
||||
state = dubboDispatchServletPublish.publish(path, requestMethod);
|
||||
@@ -105,17 +120,22 @@ public class DispatchSyncService {
|
||||
log.info("dubboDispatchServletPublish.unpublish({}, {})", path, requestMethod);
|
||||
state = dubboDispatchServletPublish.unpublish(path, requestMethod);
|
||||
}
|
||||
//如果为false,则将当前任务重新放入到队列中,等待下一次执行
|
||||
if (state == null || !state) {
|
||||
queue.add(this);
|
||||
}
|
||||
} catch (NacosException e) {
|
||||
log.error("NacosException: {}", e.getMessage());
|
||||
//如果发生异常也是
|
||||
//todo 后续可以添加当前任务报错次数的处理
|
||||
queue.add(this);
|
||||
} finally {
|
||||
//将指定的地址恢复
|
||||
UserSpecifiedAddressUtil.setAddress(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
//像阻塞队列中添加任务
|
||||
queue.add(task);
|
||||
}
|
||||
}
|
||||
@@ -126,15 +146,25 @@ public class DispatchSyncService {
|
||||
|
||||
|
||||
private static abstract class Task implements Runnable {
|
||||
|
||||
/**
|
||||
* 服务ip
|
||||
*/
|
||||
protected final String ip;
|
||||
|
||||
/**
|
||||
* 服务端口
|
||||
*/
|
||||
protected final int port;
|
||||
|
||||
/**
|
||||
* 路径
|
||||
*/
|
||||
protected final String path;
|
||||
|
||||
/**
|
||||
* 是否为发布
|
||||
*/
|
||||
protected final Boolean publish;
|
||||
|
||||
/**
|
||||
* 方法类型
|
||||
*/
|
||||
protected final String requestMethod;
|
||||
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ public class HandlerMethodService implements ApplicationContextAware {
|
||||
|
||||
|
||||
public HandlerMethodService() {
|
||||
//固定PortalDispatchServlet为入口类,其中doDispatch为入口方法
|
||||
Class<PortalDispatchServlet> portalDispatchServletClass = PortalDispatchServlet.class;
|
||||
Method[] declaredMethods = portalDispatchServletClass.getDeclaredMethods();
|
||||
for (Method declaredMethod : declaredMethods) {
|
||||
@@ -65,11 +66,13 @@ public class HandlerMethodService implements ApplicationContextAware {
|
||||
if (mappingMethod == null) {
|
||||
log.error("mappingMethod is null");
|
||||
}
|
||||
//设置权限
|
||||
mappingMethod.setAccessible(Boolean.TRUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
//获取到web mvc的接口存储mapping
|
||||
mapping = (RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping");
|
||||
}
|
||||
|
||||
@@ -95,7 +98,9 @@ public class HandlerMethodService implements ApplicationContextAware {
|
||||
throw new CustomException("path is exist");
|
||||
}
|
||||
mapping.registerMapping(requestMappingInfo, "portalDispatchServlet", mappingMethod);
|
||||
// 判断是否需要发起同步
|
||||
if (sync) {
|
||||
//使用事件监听机制,避免循环注入
|
||||
SpringContextHolder.publishEvent(new DispatchSyncEvent(path, requestMethod.name(), Boolean.TRUE));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,16 +15,33 @@ public interface PortalService {
|
||||
|
||||
/**
|
||||
* 根据id查询
|
||||
*
|
||||
* @param portalId id
|
||||
* @return 结果
|
||||
*/
|
||||
PortalVo searchById(Long portalId);
|
||||
|
||||
|
||||
/**
|
||||
* 查询接口列表
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @return 查询表格结果
|
||||
*/
|
||||
TableDataInfo<SimplePortalVo> searchList(PortalQuery query);
|
||||
|
||||
|
||||
/**
|
||||
* 保存接口信息
|
||||
*
|
||||
* @param portalDto 接口信息
|
||||
* @return 保存完成后接口id和数据适配器id
|
||||
*/
|
||||
PortalIdWrapper save(PortalDto portalDto);
|
||||
|
||||
/**
|
||||
* 修改接口信息
|
||||
*
|
||||
* @param portalDto 接口信息
|
||||
* @return 修改完成后接口id和数据适配器id
|
||||
*/
|
||||
PortalIdWrapper edit(PortalDto portalDto);
|
||||
}
|
||||
|
||||
@@ -133,6 +133,7 @@ public class PortalServiceImpl implements PortalService {
|
||||
adapterIds.add(portal.getAdapterId());
|
||||
}
|
||||
});
|
||||
//映射自定义擦洗名称
|
||||
Map<Long, UniQuery> queryMap = new HashMap<>();
|
||||
if (!ObjectUtils.isEmpty(queryIds)) {
|
||||
List<UniQuery> queryList = queryMapper.selectListByIds(queryIds);
|
||||
@@ -140,6 +141,7 @@ public class PortalServiceImpl implements PortalService {
|
||||
queryMap.put(uniQuery.getId(), uniQuery);
|
||||
}
|
||||
}
|
||||
//映射数据适配器名称
|
||||
Map<Long, String> adapterMap = new HashMap<>();
|
||||
if (!ObjectUtils.isEmpty(adapterIds)) {
|
||||
List<DataAdapter> adapterList = adapterMapper.selectListByIds(adapterIds);
|
||||
@@ -147,6 +149,7 @@ public class PortalServiceImpl implements PortalService {
|
||||
adapterMap.put(adapter.getAdapterId(), adapter.getAdapterName());
|
||||
}
|
||||
}
|
||||
//映射重组
|
||||
return PageUtils.convertDataTable(list, portal -> {
|
||||
SimplePortalVo simplePortalVo = SimplePortalVo.toPortalVo(portal);
|
||||
UniQuery uniQuery = queryMap.getOrDefault(portal.getQueryId(), null);
|
||||
@@ -191,6 +194,7 @@ public class PortalServiceImpl implements PortalService {
|
||||
}
|
||||
portalMappingMapper.insertBatch(mappings);
|
||||
}
|
||||
//发布接口
|
||||
publishPortal(portal, mappings, Boolean.TRUE);
|
||||
return PortalIdWrapper.builder()
|
||||
.portalId(String.valueOf(portal.getPortalId()))
|
||||
@@ -215,12 +219,17 @@ public class PortalServiceImpl implements PortalService {
|
||||
}
|
||||
}
|
||||
PortalBo portalBo = PortalBo.toPortalBo(portal, portalDto.getMappings());
|
||||
//存在接口路径或者请求类型不同则需要重新发布
|
||||
if (!old.getPath().equals(portal.getPath())
|
||||
|| !old.getRequestMethod().equals(portal.getRequestMethod())) {
|
||||
//先卸载接口,需要进行数据同步
|
||||
unpublishPortal(old, true);
|
||||
//注册新的映射
|
||||
methodService.registerMapping(portalBo.getPath(), RequestMethod.valueOf(portalBo.getRequestMethod()), true);
|
||||
}
|
||||
//修改Redis中的数据信息
|
||||
redisTemplate.opsForValue().set(QueryConstant.PORTAL_KEY + portalBo.getPath() + ":" + portalBo.getRequestMethod(), portalBo);
|
||||
//返回接口id和适配器id
|
||||
return PortalIdWrapper.builder()
|
||||
.portalId(String.valueOf(portal.getPortalId()))
|
||||
.adapterId(String.valueOf(portal.getAdapterId()))
|
||||
@@ -254,19 +263,36 @@ public class PortalServiceImpl implements PortalService {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 发布接口
|
||||
*
|
||||
* @param portal 接口信息
|
||||
* @param mappings 映射信息
|
||||
* @param sync 是否同步
|
||||
*/
|
||||
private void publishPortal(Portal portal, List<PortalMapping> mappings, Boolean sync) {
|
||||
PortalBo portalBo = PortalBo.toPortalBo(portal, mappings);
|
||||
redisTemplate.opsForValue().set(QueryConstant.PORTAL_KEY + portalBo.getPath() + ":" + portalBo.getRequestMethod(), portalBo);
|
||||
methodService.registerMapping(portalBo.getPath(), RequestMethod.valueOf(portalBo.getRequestMethod()), sync);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 取消接口映射
|
||||
*
|
||||
* @param portal 接口信息
|
||||
* @param sync 是否同步
|
||||
*/
|
||||
private void unpublishPortal(Portal portal, Boolean sync) {
|
||||
methodService.unregisterMapping(portal.getPath(), RequestMethod.valueOf(portal.getRequestMethod()), sync);
|
||||
redisTemplate.delete(QueryConstant.PORTAL_KEY + portal.getPath() + ":" + portal.getRequestMethod());
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建数据适配器
|
||||
*
|
||||
* @param portalDto 接口dto对象
|
||||
* @param portal 接口信息
|
||||
*/
|
||||
private void createDataAdapter(PortalDto portalDto, Portal portal) {
|
||||
DataAdapterDto dataAdapterDto = portalDto.getDataAdapter();
|
||||
if (ObjectUtils.isEmpty(dataAdapterDto)) {
|
||||
@@ -278,12 +304,19 @@ public class PortalServiceImpl implements PortalService {
|
||||
}
|
||||
dataAdapter.setAdapterName(portal.getPortalName() + "专用数据适配器!");
|
||||
dataAdapter.setCommon(Boolean.FALSE);
|
||||
//初始化对应的数据适配器
|
||||
dataAdapter.init();
|
||||
//插入数据适配器
|
||||
adapterMapper.insert(dataAdapter);
|
||||
//会写数据适配器id
|
||||
portal.setAdapterId(dataAdapter.getAdapterId());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检查接口类型是否正确
|
||||
*
|
||||
* @param portal 接口信息
|
||||
*/
|
||||
private void checkPortalType(Portal portal) {
|
||||
if (PortalEnum.LOCAL.equals(portal.getType())) {
|
||||
if (ObjectUtils.isEmpty(portal.getQueryId())) {
|
||||
|
||||
@@ -13,9 +13,7 @@
|
||||
<if test="uniCon.ucCon == 'GTE'">and ${uniCon.ucKey} >= #{uniCon.ucMock}</if>
|
||||
<if test="uniCon.ucCon == 'LT'">and ${uniCon.ucKey} < #{uniCon.ucMock}</if>
|
||||
<if test="uniCon.ucCon == 'LTE'">and ${uniCon.ucKey} <= #{uniCon.ucMock}</if>
|
||||
<if test="uniCon.ucCon == 'LIKE'">and ${uniCon.ucKey} like concat(concat('%', #{uniCon.ucMock}),
|
||||
'%')
|
||||
</if>
|
||||
<if test="uniCon.ucCon == 'LIKE'">and ${uniCon.ucKey} like concat(concat('%', #{uniCon.ucMock}),'%') </if>
|
||||
</if>
|
||||
<if test="uniCon.ucMock != null and uniCon.ucType != 'input'">
|
||||
<if test="uniCon.ucCon == 'EQ'">and ${uniCon.ucKey} = #{uniCon.ucMock}</if>
|
||||
@@ -24,9 +22,7 @@
|
||||
<if test="uniCon.ucCon == 'GTE'">and ${uniCon.ucKey} >= #{uniCon.ucMock}</if>
|
||||
<if test="uniCon.ucCon == 'LT'">and ${uniCon.ucKey} < #{uniCon.ucMock}</if>
|
||||
<if test="uniCon.ucCon == 'LTE'">and ${uniCon.ucKey} <= #{uniCon.ucMock}</if>
|
||||
<if test="uniCon.ucCon == 'LIKE'">and ${uniCon.ucKey} like concat(concat('%', #{uniCon.ucMock}),
|
||||
'%')
|
||||
</if>
|
||||
<if test="uniCon.ucCon == 'LIKE'">and ${uniCon.ucKey} like concat(concat('%', #{uniCon.ucMock}), '%')</if>
|
||||
<if test="uniCon.ucCon == 'BETWEEN'">and ${uniCon.ucKey} between #{uniCon.begin} and #{uniCon.end}
|
||||
</if>
|
||||
</if>
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
select ut.table_name,utc.comments as table_comment,ut.last_analyzed as update_time
|
||||
from user_tables ut
|
||||
left join user_tab_comments utc on ut.table_name = utc.table_name
|
||||
|
||||
|
||||
|
||||
SELECT * FROM dba_tables dt
|
||||
LEFT JOIN user_tab_comments utc on dt.table_name = utc.table_name
|
||||
WHERE owner = 'FATEVERSE_LOG'
|
||||
|
||||
|
||||
-- 使用CURRENT_SCHEMA函数获取当前模式
|
||||
SELECT CURRENT_SCHEMA() AS current_schema;
|
||||
|
||||
-- 使用CURRENT_USER函数获取当前用户及其默认模式
|
||||
SELECT CURRENT_USER AS current_user;
|
||||
|
||||
|
||||
|
||||
|
||||
SELECT dt.table_name,utc.comments as table_comment FROM dba_tables dt
|
||||
LEFT JOIN user_tab_comments utc on dt.table_name = utc.table_name
|
||||
WHERE owner = 'FATEVERSE_LOG's
|
||||
|
||||
|
||||
|
||||
SELECT * FROM user_tables
|
||||
|
||||
|
||||
select distinct utc.column_name,
|
||||
utc.table_name as remark,
|
||||
CONCAT(CONCAT(CONCAT(lower(utc.data_type),'('), utc.data_length),')') as column_type,
|
||||
utc.data_scale as column_scale,
|
||||
utc.column_id as sort,
|
||||
(case when uc.constraint_type = 'P' then '1' else '0' end) as pk ,
|
||||
ucc.comments as column_comment
|
||||
from user_tab_columns utc
|
||||
inner join user_col_comments ucc on ucc.column_name = utc.column_name and ucc.table_name = utc.table_name
|
||||
left join user_cons_columns uccs on uccs.column_name = utc.column_name
|
||||
left join user_constraints uc on uc.constraint_name = uccs.constraint_name
|
||||
|
||||
|
||||
select ut.table_name,utc.comments as table_comment,ut.last_analyzed as update_time
|
||||
from user_tables ut
|
||||
left join user_tab_comments utc on ut.table_name = utc.table_name
|
||||
|
||||
|
||||
|
||||
select 1 from dual
|
||||
|
||||
|
||||
Reference in New Issue
Block a user