|
|
|
@ -4,6 +4,7 @@ import cn.hutool.core.util.RandomUtil;
|
|
|
|
|
import net.educoder.ecsonar.dao.*;
|
|
|
|
|
import net.educoder.ecsonar.exception.BusinessException;
|
|
|
|
|
import net.educoder.ecsonar.model.*;
|
|
|
|
|
import net.educoder.ecsonar.model.api.Quality;
|
|
|
|
|
import net.educoder.ecsonar.model.api.QualityInspect;
|
|
|
|
|
import net.educoder.ecsonar.model.api.QualityInspectIsCompleted;
|
|
|
|
|
import net.educoder.ecsonar.model.api.QualityInspectResultData;
|
|
|
|
@ -11,6 +12,7 @@ import net.educoder.ecsonar.model.dto.*;
|
|
|
|
|
import net.educoder.ecsonar.model.vo.*;
|
|
|
|
|
import net.educoder.ecsonar.task.GraduationProjectQualityInspectRunnable;
|
|
|
|
|
import net.educoder.ecsonar.utils.IdUtils;
|
|
|
|
|
import net.educoder.ecsonar.utils.SystemUtil;
|
|
|
|
|
import org.apache.commons.collections4.CollectionUtils;
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
@ -19,6 +21,8 @@ import org.springframework.beans.factory.annotation.Qualifier;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
|
|
import java.math.RoundingMode;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.concurrent.ExecutorService;
|
|
|
|
|
|
|
|
|
@ -33,10 +37,10 @@ public class GraduationProjectQualityInspectService {
|
|
|
|
|
private static final Logger LOGGER = LoggerFactory.getLogger(GraduationProjectQualityInspectService.class);
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private GraduationProjectTaskInfoDao taskInfoDao;
|
|
|
|
|
private GraduationProjectTaskInfoDao graduationProjectTaskInfoDao;
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private GraduationProjectTaskInfoDetailDao taskInfoDetailDao;
|
|
|
|
|
private GraduationProjectTaskInfoDetailDao graduationProjectTaskInfoDetailDao;
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private DbOperateService dbOperateService;
|
|
|
|
@ -77,7 +81,7 @@ public class GraduationProjectQualityInspectService {
|
|
|
|
|
taskInfo.setId(IdUtils.nextStrId());
|
|
|
|
|
taskInfo.setPeopleNumber(qualityInspectVOList.size());
|
|
|
|
|
|
|
|
|
|
taskInfoDao.insertTaskInfo(taskInfo);
|
|
|
|
|
graduationProjectTaskInfoDao.insertTaskInfo(taskInfo);
|
|
|
|
|
LOGGER.info("taskId:{}, {}个人提交了代码", taskInfo.getId(), qualityInspectVOList.size());
|
|
|
|
|
|
|
|
|
|
for (GraduationProjectQualityInspectVO qualityInspectVO : qualityInspectVOList) {
|
|
|
|
@ -92,7 +96,7 @@ public class GraduationProjectQualityInspectService {
|
|
|
|
|
graduationProjectTaskInfoDetail.setGitUrl(qualityInspectVO.getGitUrl());
|
|
|
|
|
graduationProjectTaskInfoDetail.setLanguage(qualityInspectVO.getLanguage());
|
|
|
|
|
|
|
|
|
|
taskInfoDetailDao.insertTaskInfoDetail(graduationProjectTaskInfoDetail);
|
|
|
|
|
graduationProjectTaskInfoDetailDao.insertTaskInfoDetail(graduationProjectTaskInfoDetail);
|
|
|
|
|
|
|
|
|
|
// 提交一个sonar扫描任务
|
|
|
|
|
GraduationProjectQualityInspectRunnable runnable = new GraduationProjectQualityInspectRunnable(taskInfo.getId(),
|
|
|
|
@ -108,31 +112,147 @@ public class GraduationProjectQualityInspectService {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public RollPage<QualityInspectResultData> qualityInspectResultQuery(Integer pageNum, Integer pageSize, String taskId) {
|
|
|
|
|
RollPage<QualityInspectResultData> rollPage = new RollPage();
|
|
|
|
|
public RollPage<QualityInspectResultData> qualityInspectResultQuery(GraduationQualityInspectResultQueryVO queryVO) {
|
|
|
|
|
int pageSize = queryVO.getPageSize();
|
|
|
|
|
int pageNum = queryVO.getPageNumber();
|
|
|
|
|
|
|
|
|
|
RollPage<QualityInspectResultData> rollPage = new RollPage<>();
|
|
|
|
|
rollPage.setCurrentPage(pageNum);
|
|
|
|
|
rollPage.setPageSize(pageSize);
|
|
|
|
|
|
|
|
|
|
int offset = (queryVO.getPageNumber() - 1) * queryVO.getPageSize();
|
|
|
|
|
Integer totalCount = graduationProjectTaskInfoDetailDao.
|
|
|
|
|
selectGraduationProjectTaskInfoDetailPageCount(queryVO.getTaskId(), pageSize, offset);
|
|
|
|
|
rollPage.setRecordSum(totalCount);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (totalCount == null || totalCount == 0) {
|
|
|
|
|
rollPage.setRecordList(new ArrayList<>());
|
|
|
|
|
} else {
|
|
|
|
|
List<GraduationProjectTaskInfoDetail> taskInfoDetails = graduationProjectTaskInfoDetailDao.
|
|
|
|
|
selectGraduationProjectTaskInfoDetailPageList(queryVO.getTaskId(), pageSize, offset);
|
|
|
|
|
|
|
|
|
|
List<QualityInspectResultData> resultDataList = new ArrayList<>(taskInfoDetails.size());
|
|
|
|
|
rollPage.setRecordList(resultDataList);
|
|
|
|
|
|
|
|
|
|
// 组装数据
|
|
|
|
|
for (GraduationProjectTaskInfoDetail taskInfoDetail : taskInfoDetails) {
|
|
|
|
|
QualityInspectResultData resultData = new QualityInspectResultData();
|
|
|
|
|
resultData.setName(taskInfoDetail.getName());
|
|
|
|
|
resultData.setStudentId(taskInfoDetail.getStudentId());
|
|
|
|
|
resultData.setUserId(taskInfoDetail.getUserId());
|
|
|
|
|
|
|
|
|
|
Metrics metrics = reportService.getMetrics(taskInfoDetail.getProjectName());
|
|
|
|
|
|
|
|
|
|
resultData.setDiscern(!metrics.getBugs().equals("-"));
|
|
|
|
|
resultData.setBug(new Quality(metrics.getBlock_bugs(), metrics.getMajor_bugs(), metrics.getMinor_bugs(), metrics.getCritical_bugs(), metrics.getBugs()));
|
|
|
|
|
resultData.setVulnerability(new Quality(metrics.getBlock_violations(), metrics.getMajor_violations(), metrics.getMinor_violations(), metrics.getCritical_violations(), metrics.getViolations()));
|
|
|
|
|
resultData.setCodeSmall(new Quality(metrics.getBlock_code_smells(), metrics.getMajor_code_smells(), metrics.getMinor_code_smells(), metrics.getCritical_code_smells(), metrics.getCode_smells()));
|
|
|
|
|
|
|
|
|
|
resultData.setComplexity(metrics.getComplexity());
|
|
|
|
|
resultData.setTotalRowNumber(metrics.getLines());
|
|
|
|
|
|
|
|
|
|
resultDataList.add(resultData);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int maxBugNumber = resultDataList.stream().mapToInt((QualityInspectResultData resultData) -> {
|
|
|
|
|
Quality bug = resultData.getBug();
|
|
|
|
|
return bug.getMinor() + bug.getBlocker() + bug.getMajor() + bug.getCritical();
|
|
|
|
|
}).max().getAsInt();
|
|
|
|
|
|
|
|
|
|
int maxVulnerabilityNumber = resultDataList.stream().mapToInt((QualityInspectResultData resultData) -> {
|
|
|
|
|
Quality vulnerability = resultData.getVulnerability();
|
|
|
|
|
return vulnerability.getMinor() + vulnerability.getBlocker() + vulnerability.getMajor() + vulnerability.getCritical();
|
|
|
|
|
}).max().getAsInt();
|
|
|
|
|
|
|
|
|
|
int maxCodeSmallNumber = resultDataList.stream().mapToInt((QualityInspectResultData resultData) -> {
|
|
|
|
|
Quality codeSmall = resultData.getCodeSmall();
|
|
|
|
|
return codeSmall.getMinor() + codeSmall.getBlocker() + codeSmall.getMajor() + codeSmall.getCritical();
|
|
|
|
|
}).max().getAsInt();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 计算得分
|
|
|
|
|
for (QualityInspectResultData resultData : resultDataList) {
|
|
|
|
|
BigDecimal finalScore = calcQualityScore(resultData, queryVO.getBugRate(), maxBugNumber,
|
|
|
|
|
queryVO.getVulnerabilityRate(), maxVulnerabilityNumber,
|
|
|
|
|
queryVO.getCodeSmallRate(), maxCodeSmallNumber);
|
|
|
|
|
resultData.setQualityScore(finalScore);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rollPage;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public QualityInspectIsCompleted qualityInspectIsCompleted(String taskId) {
|
|
|
|
|
return null;
|
|
|
|
|
GraduationProjectTaskInfo graduationProjectTaskInfo = graduationProjectTaskInfoDao.selectById(taskId);
|
|
|
|
|
if (graduationProjectTaskInfo == null) {
|
|
|
|
|
throw new BusinessException(2, "任务id不存在");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (graduationProjectTaskInfo.getStatus() == 1) {
|
|
|
|
|
return new QualityInspectIsCompleted(taskId, graduationProjectTaskInfo.getStatus());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Integer taskNumber = graduationProjectTaskInfoDetailDao.selectCountByTaskId(graduationProjectTaskInfo.getId());
|
|
|
|
|
int completed = graduationProjectTaskInfo.getPeopleNumber().equals(taskNumber) ? 1 : 0;
|
|
|
|
|
|
|
|
|
|
// 数据库未更新状态,但sonar任务已经全部执行完,更新task_info状态
|
|
|
|
|
if (graduationProjectTaskInfo.getStatus() == 0 && completed == 1) {
|
|
|
|
|
graduationProjectTaskInfoDao.updateTaskInfoStatus(graduationProjectTaskInfo.getId(), 1);
|
|
|
|
|
|
|
|
|
|
// 并且删除文件 /tmp/$taskId
|
|
|
|
|
String command = String.format("rm -rf /tmp/%s", taskId);
|
|
|
|
|
SystemUtil.executeAndGetExitStatus(command);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new QualityInspectIsCompleted(taskId, completed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 阻断 严重 主要 次要
|
|
|
|
|
* 10 5 3 1
|
|
|
|
|
* 代码质量分 =50*(x-a)/x + 30*(y-b)/y + 20*(z-c)/c
|
|
|
|
|
* 1、缺陷最大值为x,实际值为a。
|
|
|
|
|
* 2、漏洞最大值为y,实际值为b。
|
|
|
|
|
* 3、代码规范性最大值为z,实际值为c。
|
|
|
|
|
* (具体占比需要根据老师配置的比例进行计算)
|
|
|
|
|
*
|
|
|
|
|
* @param resultData
|
|
|
|
|
* @return
|
|
|
|
|
* @param resultData 用户数据
|
|
|
|
|
* @param bugRate bug得分占比率
|
|
|
|
|
* @param maxBugNumber 最大bug数
|
|
|
|
|
* @param vulnerabilityRate 漏洞得分占比率
|
|
|
|
|
* @param maxVulnerabilityNumber 最大漏洞数量
|
|
|
|
|
* @param codeSmallRate 代码规范得分占比
|
|
|
|
|
* @param maxCodeSmallNumber 最大代码规范数量
|
|
|
|
|
* @return score
|
|
|
|
|
*/
|
|
|
|
|
private BigDecimal calcQualityScore(QualityInspectResultData resultData) {
|
|
|
|
|
private BigDecimal calcQualityScore(QualityInspectResultData resultData,
|
|
|
|
|
int bugRate,
|
|
|
|
|
int maxBugNumber,
|
|
|
|
|
int vulnerabilityRate,
|
|
|
|
|
int maxVulnerabilityNumber,
|
|
|
|
|
int codeSmallRate,
|
|
|
|
|
int maxCodeSmallNumber) {
|
|
|
|
|
if (resultData.getTotalRowNumber() <= 0) {
|
|
|
|
|
return BigDecimal.ZERO;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
Quality bug = resultData.getBug();
|
|
|
|
|
BigDecimal bugScore = BigDecimal.valueOf(bugRate)
|
|
|
|
|
.multiply(BigDecimal.valueOf(maxBugNumber - (bug.getBlocker() + bug.getCritical() + bug.getMajor() + bug.getMinor())))
|
|
|
|
|
.divide(BigDecimal.valueOf(maxBugNumber), 2, RoundingMode.HALF_UP);
|
|
|
|
|
|
|
|
|
|
Quality vulnerability = resultData.getVulnerability();
|
|
|
|
|
BigDecimal vulnerabilityScore = BigDecimal.valueOf(vulnerabilityRate)
|
|
|
|
|
.multiply(BigDecimal.valueOf(maxVulnerabilityNumber - (vulnerability.getBlocker() + vulnerability.getCritical() + vulnerability.getMajor() + vulnerability.getMinor())))
|
|
|
|
|
.divide(BigDecimal.valueOf(maxVulnerabilityNumber), 2, RoundingMode.HALF_UP);
|
|
|
|
|
|
|
|
|
|
Quality codeSmall = resultData.getCodeSmall();
|
|
|
|
|
BigDecimal codeSmallScore = BigDecimal.valueOf(codeSmallRate)
|
|
|
|
|
.multiply(BigDecimal.valueOf(maxCodeSmallNumber - (codeSmall.getBlocker() + codeSmall.getCritical() + codeSmall.getMajor() + codeSmall.getMinor())))
|
|
|
|
|
.divide(BigDecimal.valueOf(maxCodeSmallNumber), 2, RoundingMode.HALF_UP);
|
|
|
|
|
|
|
|
|
|
BigDecimal score = bugScore.add(vulnerabilityScore).add(codeSmallScore);
|
|
|
|
|
return score;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|