首页 > 其他分享 >袋鼠云代码检查服务,揭秘高质量代码背后的秘密

袋鼠云代码检查服务,揭秘高质量代码背后的秘密

时间:2023-09-27 16:27:28浏览次数:31  
标签:袋鼠 检查 代码 规则 searchParam SQL com 揭秘

质量是产品的生命线,代码检查是软件开发过程中至关重要的一环,它可以帮助我们发现并纠正潜在的错误,提高软件质量,降低维护成本。

袋鼠云产品中也存在这个问题,由于离线数据开发人员 SQL 水平不一,导致代码书写混乱、SQL 代码运行问题较多。本文将介绍在离线产品中如何利用 SQL 检查规则规范化 SQL 代码,对代码书写问题进行拦截,便于统一管理,用于预防引入需要治理的问题。

通过本文的介绍,我们希望您能够认识到代码检查的重要性,并了解如何通过最佳实践来提高代码质量和开发效率。

何时进行代码规则检查?

SQL 任务在离线产品界面开发完成之后,点击运行的按钮,会先经过代码规则检查,如果代码规则不满足则会提示到用户具体的原因。

file

数据资产模块内置了 5 种代码检查规则,用户可以根据需要选择性开启。

file

开启后在离线项目管理中可以选择使用的代码规则检查项、生效范围和 SQL 任务类型。

file

在离线 SQL 任务中去运行一条 SQL 前会根据选择的规则先进行代码检查,如果代码检查不通过则会反馈给用户,用户可以根据实际需要判断要不要执行该 SQL。

file

在数据资产的代码检查时间中可以看到已经触发的检查历史以及相应的统计数据。

file

如何实现代码检查规则?

在 CodeCheck 包下定义了通用的代码规则检查的接口。

public interface ICheck {
 Result codeCheck(String checkContent, String defaultDb, Integer dataSourceType, Long tenantId, SqlParseInfo sqlParseInfo);
 CodeCheckType getCheckType();
}

分区表查询必须带分区规则为例,会先调用 SQLParser 组件进行 SQL 解析,SQLParseInfo 即为 SQL 解析结果,检查时会先判断 SQL 语句是不是查询语句,如果是则判断查询的表是不是分区表,再判断是否有查询条件,最后判断查询条件中是否包含分区字段来判断是否检查通过。

public class CodeCheckImplType01 extends AbstractCheck {
 private static final Logger LOGGER = LoggerFactory.getLogger(CodeCheckImplType01.class);
 @Autowired
 private DataTableColumnThirdService dataTableColumnThirdService;
 @Autowired
 private DataTableThirdService dataTableThirdService;
 @Override
 public Result codeCheck(String checkContent, String defaultDb, Integer dataSourceType, Long tenantId, SqlParseInfo sqlParseInfo) {
 if (!isQuery(sqlParseInfo.getSqlType())) {
 return Result.buildSuccessResult();
 }
 try {
 MetadataSearchParam searchParam = new MetadataSearchParam();
 searchParam.setDbName(sqlParseInfo.getMainTable().getDb());
 searchParam.setTableName(sqlParseInfo.getMainTable().getName());
 searchParam.setDataSourceType(dataSourceType);
 searchParam.setTenantId(tenantId);
 List<TableDTO> tableDTOS = dataTableThirdService.tableList(searchParam);
 // 获取表信息
 for (TableDTO tableDTO : tableDTOS) {
 List<DataTableColumn> tableColumns = dataTableColumnThirdService.listColumnByTableIds(Lists.newArrayList(tableDTO.getTableId()));
 if (CollectionUtils.isEmpty(tableColumns)) {
 continue;
 }
 List<String> partitionColumnNameList = tableColumns.stream()
 .filter(Objects::nonNull)
 .filter(t -> HavePartitionEnum.have_partition.getPartitionValue().equals(t.getIsPartition()))
 .map(DataTableColumn::getColumnName)
 .collect(Collectors.toList());
 // 非分区表直接返回
 if (CollectionUtils.isEmpty(partitionColumnNameList)) {
 continue;
 }
 if (CollectionUtils.isEmpty(sqlParseInfo.getColumnIdentifierList())) {
 // 没有查询条件则校验失败
 return Result.buildFailedResult(String.format(getCheckType().getCheckResultFormat(), searchParam.getTableName()));
 }
 List<String> columnList = sqlParseInfo.getColumnIdentifierList().stream()
 .filter(c -> StringUtils.equals(c.getDb(), searchParam.getSchemaName()) && StringUtils.equals(c.getTable(), searchParam.getTableName()))
 .map(ColumnIdentifier::getColumn).collect(Collectors.toList());
 boolean disjoint = Collections.disjoint(partitionColumnNameList, columnList);
 if (disjoint) {
 return Result.buildFailedResult(String.format(getCheckType().getCheckResultFormat(), searchParam.getTableName()));
 }
 }
 } catch (Exception e) {
 // 异常情况先通过
 LOGGER.error("code check error, check content: {}, defaultDb: {}, checkType: {}", checkContent, defaultDb, getCheckType().name());
 }
 return Result.buildSuccessResult();
 }
 @Override
 public CodeCheckType getCheckType() {
 return CodeCheckType.TYPE_01;
 }
}

如何自定义代码检查规则?

如果内置的代码检查规则不满足客户的使用场景,客户可以通过上传 jar 的方式自定义代码检查规则。

file

自定义代码检查规则使用 SPI 机制加载用户上传的自定义 jar,并在代码检测时调用 CodeCheck 方法,在资源关闭时调用 close 方法,用户需要将配置文件说明中的 jar 依赖自己的项目中。具体如下:

● 创建一个类实现接口

创建一个类实现接口 com.dtstack.assets.spi.codecheck.ICodeCheckClient 并实现 CodeCheck 和 close 方法,书写相关逻辑代码,如果校验通过需要将 CheckResult 对象中 success 设置为 true,失败时设置 success 字段为 false 并设置校验不通过的理由。

package com.dtstack.assets.spi.codecheck;
import java.util.Map;
public interface ICodeCheckClient {
 /**
 * 代码检查
 *
 * @param checkContent 检查内容
 * @param extMap 扩展配置
 * @return 检查结果
 */
 CheckResult codeCheck(String checkContent, Map<String, Object> extMap);
 /**
 * 释放资源, 调用时需要关闭所使用的资源
 */
 void close();
}

· 入参字段解释

– checkContent 为单条 SQL 信息

– extMap 会设置一些平台的属性,包含任务名称、任务类型等

· 出参字段解释

– success 为是否校验通过,必须设置

– checkResult 为校验结果,校验不通过时不能为空

package com.dtstack.demo;
import com.dtstack.assets.spi.codecheck.CheckResult;
import java.util.Map;
public class CodeCheckImpl implements com.dtstack.assets.spi.codecheck.ICodeCheckClient{
 @Override
 public CheckResult codeCheck(String checkContent, Map<String, Object> extMap) {
 // 代码检查相关逻辑
 CheckResult checkResult = new CheckResult();
 checkResult.setSuccess(false);
 checkResult.setCheckResult("校验不通过的理由");
 return checkResult;
 }
 @Override
 public void close() {
 // 关闭相关资源
 }
}

● 在 resource 目录下创建 META-INF/services 目录

file

● 在 META-INF/services 目录下创建文件

文件名称为 com.dtstack.assets.spi.codecheck.ICodeCheckClient ,文件内容为实现 ICodeCheckClient 接口类的权限定类名。

file

文件名称和内容示例:

file

● 打包当前工程并在数据资产页面注册代码校验规则

不符合条件的 jar 会给出提示。

file
file

如何加载自定义代码规则对应的 jar ?

我们会为上传的每个规则对应的 jar 初始化一个唯一的自定义 classloader,该 classloader 继承 URLClassLoader 并保证子类加载器优先加载。

file

在第一次调用时进行加载并缓存对应的 client。

file

在用户重新上传或者编辑规则后清除旧的 classloader 和加载的 client 并释放资源。

file

《数栈产品白皮书》:https://www.dtstack.com/resources/1004?src=szsm

《数据治理行业实践白皮书》下载地址:https://www.dtstack.com/resources/1001?src=szsm

想了解或咨询更多有关袋鼠云大数据产品、行业解决方案、客户案例的朋友,浏览袋鼠云官网:https://www.dtstack.com/?src=szbky

同时,欢迎对大数据开源项目有兴趣的同学加入「袋鼠云开源框架钉钉技术qun」,交流最新开源技术信息,qun号码:30537511,项目地址:https://github.com/DTStack

标签:袋鼠,检查,代码,规则,searchParam,SQL,com,揭秘
From: https://www.cnblogs.com/DTinsight/p/17732968.html

相关文章

  • Linux0.11代码浅析
    Linux0.11"pulloneselfupbyone'sbootstraps"......
  • Linux2.1.13网络源代码学习(https://qiankunli.github.io/2022/07/04/linux_2_1_13_ne
    简介简介源码目录网络分层数据结构套接字套接字与vfssk_buff结构网络协议栈实现——数据struct和协议structlinux1.2.13接收数据收到数据包的几种情况Socket读取发送数据面向过程/对象/ioc以下来自linux1.2.13源码,算是参见Linux1.0的学习笔记。源码目......
  • 代码检查过程中为什么需要涉及到编译呢?
    本文分享自华为云社区 《代码检查过程中为什么需要涉及到编译呢?》,作者:gentle_zhou。随着大家对软件安全越来越重视,在编码阶段针对源码安全的保障也被各行各业企业研发测试运维团队与个人开发者越来越频繁的被提及,其中静态代码检查SAST工具尤为突出。SAST代码检查服务作为一款可......
  • 揭秘前端滑块验证技术
    大家好,今天我们聊一下现代应用中常见的一种交互验证方式:滑块验证。滑块验证也被称为拼图验证码,是一种用于验证用户是否为人类而不是机器人的常见方法。用户需要完成验证后才能继续往下操作,而机器人通常很难模拟这种人类行为。也因为这样,滑块验证已经成为了网站注册、登录、商品防......
  • PX01如何通过LcdTools读取IC值自动生成初始化代码
    在点屏调试中我们会碰到这种情况,一个已经烧录过全代码的屏在没有获取他的全代码的情况下,怎么从IC里面读取生成初始化代码下到其他屏?LcdTools可以完美解决上述问题,下面举例说明操作过程。首先,我们需要熟悉DriverIC,有哪些寄存器地址,如何进行寄存器读写,我们以ILI9881C为例;ILI988......
  • Visual Studio 2022中粘贴代码会自动变转义字符
    装了VisualStudio2022之后,一直没有正式的项目在跑。最近有新项目,决定试试.net6的新特性。在添加集合时,粘贴”);补充字符串时,发现VS居然自动帮我转了转义字符,比如原文是:varfields=newList<string>();fields.Add("zip我想补充成:fields.Add("zip");结果却变成了:fie......
  • 代码随想录day21 | ● 530.二叉搜索树的最小绝对差 ● 501.二叉搜索树中的众数 ● 2
    530.二叉搜索树的最小绝对差classSolution{private:intresult=INT_MAX;TreeNode*pre=NULL;voidtraversal(TreeNode*cur){if(cur==NULL)return;traversal(cur->left);//左if(pre!=NULL){//中......
  • JVS低代码如何通过逻辑触发变量节点进行表单数据回显?
    使用说明通常业务中会涉及到表单上部分字段填写后通过触发逻辑处理已填写的数据进行回显到表单上,这时我们可以采用业务逻辑来配置对象变量节点进行表单数据回显。对象变量:将自定义字段重新组装新的数据结构,数据结构类型为对象。设计表单入口在表单中配置按钮组件或者是设置组件的网......
  • 携手低代码平台公司,创造高效率办公!
    当前,什么样的平台产品可以实现高效率办公?随着社会化发展程度的推进发展,很多客户朋友希望找到更理想的平台产品,助力企业管理好内部数据,起到链接互通各部门沟通桥梁的作用。低代码开发平台就是其中一种理想的得力助手,可以让企业解放双手,真正让各部门之间的联络和协作关系更和谐,更顺......
  • 面向对象编程的六大原则个人总结(附代码)
    面向对象编程的六大原则个人总结(附代码)目录面向对象编程的六大原则个人总结(附代码)一、什么是单一职责原则?核心思想好处代码示例总结二、什么是里式替换原则?规则代码示例总结三、什么是迪米特法则?核心思想规则代码示例总结四、什么是开闭原则?理解代码示例总结五、什么是依赖倒......