Compare commits

...

3 Commits

@ -0,0 +1,116 @@
package net.educoder.ecsonar.controller;
import net.educoder.ecsonar.model.RollPage;
import net.educoder.ecsonar.model.api.QualityInspect;
import net.educoder.ecsonar.model.api.QualityInspectIsCompleted;
import net.educoder.ecsonar.model.api.QualityInspectResultData;
import net.educoder.ecsonar.model.dto.AnalyseDetailDTO;
import net.educoder.ecsonar.model.dto.AnalyseDetailListDTO;
import net.educoder.ecsonar.model.dto.CodeDetailDTO;
import net.educoder.ecsonar.model.dto.ProblemAnalysisDTO;
import net.educoder.ecsonar.model.vo.*;
import net.educoder.ecsonar.services.GraduationProjectQualityInspectService;
import net.educoder.ecsonar.services.QualityInspectService;
import net.educoder.ecsonar.utils.ResponseResult;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
/**
* @Author: youys
* @Date: 2023/8/30
* @Description:
*/
@RestController
@RequestMapping("/graduation/project")
public class GraduationProjectController {
@Resource
private GraduationProjectQualityInspectService graduationProjectQualityInspect;
@Resource
private QualityInspectService qualityInspectService;
/**
*
*
* @param qualityInspectVOList
* @return
*/
@PostMapping("/qualityInspect")
public ResponseResult graduationQualityInspect(@RequestBody List<GraduationProjectQualityInspectVO> qualityInspectVOList) {
QualityInspect qualityInspect = graduationProjectQualityInspect.graduationProjectQualityInspect(qualityInspectVOList);
return ResponseResult.success(qualityInspect);
}
/**
*
*
* @param graduationQualityInspectResultQueryVO
* @return
*/
@PostMapping(value = "qualityInspectResultQuery")
public ResponseResult graduationQualityInspectResultQuery(@RequestBody GraduationQualityInspectResultQueryVO graduationQualityInspectResultQueryVO) {
QualityInspectIsCompleted isCompleted = graduationProjectQualityInspect.qualityInspectIsCompleted(graduationQualityInspectResultQueryVO.getTaskId());
if (isCompleted.getCompleted() != 1) {
return ResponseResult.error("质量检测正在处理中");
}
RollPage<QualityInspectResultData> result = graduationProjectQualityInspect.qualityInspectResultQuery(graduationQualityInspectResultQueryVO);
return ResponseResult.success(result);
}
/**
*
*
* @return
*/
@GetMapping("/analyseDetail")
public ResponseResult<AnalyseDetailDTO> analyseDetail(@RequestParam("taskDetailId") String taskDetailId) {
AnalyseDetailDTO analyseDetailDTO = graduationProjectQualityInspect.getAnalyseDetail(taskDetailId);
return ResponseResult.success(analyseDetailDTO);
}
/**
*
*
* @return
*/
@GetMapping("/analyseDetailList")
public ResponseResult analyseDetailList(@Valid GraduationProjectAnalyseDetailListVO analyseDetailListVO) {
RollPage<AnalyseDetailListDTO> rollPage = graduationProjectQualityInspect.getAnalyseDetailList(analyseDetailListVO);
return ResponseResult.success(rollPage);
}
/**
*
*
* @return
*/
@GetMapping("/problemAnalysis")
public ResponseResult problemAnalysis(@RequestParam Integer ruleId) {
ProblemAnalysisDTO problemAnalysis = qualityInspectService.getProblemAnalysis(ruleId);
return ResponseResult.success(problemAnalysis);
}
/**
*
*
* @return
*/
@GetMapping("/codeDetail")
public ResponseResult<CodeDetailDTO> codeDetail(@Valid CodeDetailVO codeDetailVO) {
CodeDetailDTO codeDetail = qualityInspectService.getCodeDetail(codeDetailVO);
return ResponseResult.success(codeDetail);
}
}

@ -0,0 +1,27 @@
package net.educoder.ecsonar.dao;
import net.educoder.ecsonar.model.GraduationProjectTaskInfo;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
/**
* @Author: youys
* @Date: 2023/8/31
* @Description: dao
*/
public interface GraduationProjectTaskInfoDao {
@Insert("insert into graduation_project_task_info(id,people_number) values(#{id},#{peopleNumber} )")
void insertTaskInfo(GraduationProjectTaskInfo taskInfo);
@Update("update graduation_project_task_info set status=#{status},update_time=current_timestamp where id=#{id}")
void updateTaskInfoStatus(@Param("id") String id, @Param("status") Integer status);
@Select("select id,status,people_number peopleNumber,create_time createTime,update_time updateTime " +
"from graduation_project_task_info where id=#{id}")
GraduationProjectTaskInfo selectById(String id);
}

@ -0,0 +1,87 @@
package net.educoder.ecsonar.dao;
import net.educoder.ecsonar.model.GraduationProjectTaskInfoDetail;
import net.educoder.ecsonar.model.TaskInfoDetail;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
/**
* @Author: youys
* @Date: 2023/8/31
* @Description: dao
*/
public interface GraduationProjectTaskInfoDetailDao {
/**
*
*
* @param taskInfoDetail
*/
@Insert("insert into graduation_project_task_info_detail(id,task_id,project_name,language,student_id,user_id,name,git_url) " +
"values(#{id},#{taskId},#{projectName},#{language},#{studentId},#{userId} ,#{name},#{gitUrl})")
void insertTaskInfoDetail(GraduationProjectTaskInfoDetail taskInfoDetail);
/**
*
*
* @param id
* @param status
*/
@Update("update graduation_project_task_info_detail " +
"set status=#{status},update_time=current_timestamp where id=#{id}")
void updateGraduationProjectTaskInfoDetailStatus(@Param("id") String id, @Param("status") Integer status);
/**
* taskIdsonar
*
* @param taskId
* @return
*/
@Select("select count(1) from graduation_project_task_info_detail " +
"where task_id=#{taskId} and status != 0")
Integer selectCountByTaskId(@Param("taskId") String taskId);
/**
* idTaskInfoDetail
*
* @param id
* @return
*/
@Select("select id,task_id taskId,project_name projectName,language,student_id studentId,user_id " +
"userId,name,git_url gitUrl,status,create_time createTime,update_time updateTime " +
"from graduation_project_task_info_detail where id=#{id}")
GraduationProjectTaskInfoDetail selectById(String id);
/**
* count
*
* @param taskId
* @param pageSize
* @param offset
* @return
*/
@Select("select count(1) from graduation_project_task_info_detail " +
"where task_id=#{taskId} limit #{pageSize} offset #{offset}")
Integer selectGraduationProjectTaskInfoDetailPageCount(@Param("taskId") String taskId,
@Param("pageSize") Integer pageSize,
@Param("offset") Integer offset);
/**
*
*
* @param taskId
* @param pageSize
* @param position
* @return
*/
@Select("select id,task_id taskId,project_name projectName,language,student_id studentId,user_id userId," +
"name,git_url gitUrl,status,create_time createTime,update_time updateTime " +
"from graduation_project_task_info_detail where task_id=#{taskId} limit #{pageSize} offset #{position}")
List<GraduationProjectTaskInfoDetail> selectGraduationProjectTaskInfoDetailPageList(@Param("taskId") String taskId,
@Param("pageSize") Integer pageSize,
@Param("position") Integer position);
}

@ -0,0 +1,61 @@
package net.educoder.ecsonar.model;
import java.util.Date;
/**
* @Author: youys
* @Date: 2023/8/31
* @Description:
*/
public class GraduationProjectTaskInfo {
private String id;
/**
* 0 1
*/
private Integer status;
private Integer peopleNumber;
private Date createTime;
private Date updateTime;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Integer getPeopleNumber() {
return peopleNumber;
}
public void setPeopleNumber(Integer peopleNumber) {
this.peopleNumber = peopleNumber;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}

@ -0,0 +1,139 @@
package net.educoder.ecsonar.model;
import java.util.Date;
/**
* @Author: youys
* @Date: 2023/8/31
* @Description:
*/
public class GraduationProjectTaskInfoDetail {
private String id;
/**
* id
*/
private String taskId;
/**
*
*/
private String projectName;
/**
*
*/
private String language;
/**
*
*/
private String studentId;
/**
* id
*/
private Long userId;
/**
* git
*/
private String gitUrl;
/**
*
*/
private String name;
/**
* 0 1 -1
*/
private Integer status;
private Date createTime;
private Date updateTime;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
public String getStudentId() {
return studentId;
}
public void setStudentId(String studentId) {
this.studentId = studentId;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public String getGitUrl() {
return gitUrl;
}
public void setGitUrl(String gitUrl) {
this.gitUrl = gitUrl;
}
}

@ -5,7 +5,7 @@ import java.math.BigDecimal;
/**
* @Author: youys
* @Date: 2022/1/17
* @Description:
* @Description:
*/
public class QualityInspectResultData {
@ -62,6 +62,11 @@ public class QualityInspectResultData {
*/
private BigDecimal qualityScore;
/**
* id
*/
private String taskDetailId;
public String getMentor() {
return mentor;
}
@ -149,4 +154,12 @@ public class QualityInspectResultData {
public void setQualityScore(BigDecimal qualityScore) {
this.qualityScore = qualityScore;
}
public String getTaskDetailId() {
return taskDetailId;
}
public void setTaskDetailId(String taskDetailId) {
this.taskDetailId = taskDetailId;
}
}

@ -2,6 +2,9 @@ package net.educoder.ecsonar.model.vo;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* @Author: youys
* @Date: 2022/9/27
@ -11,7 +14,12 @@ import lombok.Data;
public class CodeDetailVO {
@NotBlank(message = "uuid不能为空")
private String uuid;
@NotNull(message = "ruleId不能为空")
private Integer ruleId;
@NotNull(message = "issueId不能为空")
private Long issueId;
}

@ -0,0 +1,33 @@
package net.educoder.ecsonar.model.vo;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* @Author: youys
* @Date: 2022/12/20
* @Description:
*/
@Data
public class GraduationProjectAnalyseDetailListVO extends PageVO {
/**
*
* 1
* 2 bug
* 3
*/
private Integer type;
/**
*
* all
*/
private Integer degree;
@NotBlank(message = "作业id不能为空")
private String taskDetailId;
}

@ -0,0 +1,33 @@
package net.educoder.ecsonar.model.vo;
import lombok.Data;
/**
* @Author: youys
* @Date: 2023/8/30
* @Description:
*/
@Data
public class GraduationProjectQualityInspectVO {
/**
*
*/
private String language;
/**
* id
*/
private Long userId;
/**
* git
*/
private String gitUrl;
/**
*
*/
private String studentId;
/**
*
*/
private String name;
}

@ -0,0 +1,34 @@
package net.educoder.ecsonar.model.vo;
import lombok.Data;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
/**
* @Author: youys
* @Date: 2023/9/1
* @Description:
*/
@Data
public class GraduationQualityInspectResultQueryVO extends PageVO{
@NotBlank(message = "任务id不能为空")
private String taskId;
@Min(value = 1, message = "最小值为1")
@Max(value = 100, message = "最大值为100")
private Integer bugRate;
@Min(value = 1, message = "最小值为1")
@Max(value = 100, message = "最大值为100")
private Integer vulnerabilityRate;
@Min(value = 1, message = "最小值为1")
@Max(value = 100, message = "最大值为100")
private Integer codeSmallRate;
}

@ -4,10 +4,13 @@ import net.educoder.ecsonar.config.DynamicDataSourceConfig;
import net.educoder.ecsonar.config.DynamicDataSourceContextHolder;
import net.educoder.ecsonar.dao.*;
import net.educoder.ecsonar.model.GameCodes;
import net.educoder.ecsonar.model.GraduationProjectTaskInfoDetail;
import net.educoder.ecsonar.model.Project;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @Author: youys
* @Date: 2021/12/31
@ -32,6 +35,9 @@ public class DbOperateService {
@Autowired
private CloudTaskInfoDetailDao cloudTaskInfoDetailDao;
@Resource
private GraduationProjectTaskInfoDetailDao graduationProjectTaskInfoDetailDao;
/**
* idcode
*
@ -64,6 +70,10 @@ public class DbOperateService {
taskInfoDetailDao.updateTaskInfoDetailStatus(id, status);
}
public void updateGraduationProjectTaskInfoDetail(String id, Integer status) {
graduationProjectTaskInfoDetailDao.updateGraduationProjectTaskInfoDetailStatus(id, status);
}
public void updateCloudTaskInfoDetail(String id, Integer status) {
cloudTaskInfoDetailDao.updateCloudTaskInfoDetailStatus(id, status);
}

@ -0,0 +1,375 @@
package net.educoder.ecsonar.services;
import cn.hutool.core.util.RandomUtil;
import com.google.protobuf.InvalidProtocolBufferException;
import net.educoder.ecsonar.dao.*;
import net.educoder.ecsonar.enums.AnalyseTypeEnum;
import net.educoder.ecsonar.enums.DegreeEnum;
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;
import net.educoder.ecsonar.model.dto.*;
import net.educoder.ecsonar.model.vo.*;
import net.educoder.ecsonar.protobuf.DbIssues;
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;
import org.springframework.beans.factory.annotation.Autowired;
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;
/**
* @Author: youys
* @Date: 2023/8/31
* @Description: service
*/
@Service
public class GraduationProjectQualityInspectService {
private static final Logger LOGGER = LoggerFactory.getLogger(GraduationProjectQualityInspectService.class);
@Autowired
private GraduationProjectTaskInfoDao graduationProjectTaskInfoDao;
@Autowired
private GraduationProjectTaskInfoDetailDao graduationProjectTaskInfoDetailDao;
@Autowired
private DbOperateService dbOperateService;
@Autowired
private SonarService sonarService;
@Autowired
private ReportService reportService;
@Autowired
private IssuesDao issuesDao;
@Autowired
private ProjectDao projectDao;
@Autowired
@Qualifier("sonarScannerPool")
private ExecutorService sonarScannerPool;
@Autowired
@Qualifier("sonarQueryResultPool")
private ExecutorService sonarQueryResultPool;
public QualityInspect graduationProjectQualityInspect(List<GraduationProjectQualityInspectVO> qualityInspectVOList) {
if (CollectionUtils.isEmpty(qualityInspectVOList)) {
throw new BusinessException(2, "用户数据不能为空");
}
GraduationProjectTaskInfo taskInfo = new GraduationProjectTaskInfo();
taskInfo.setId(IdUtils.nextStrId());
taskInfo.setPeopleNumber(qualityInspectVOList.size());
graduationProjectTaskInfoDao.insertTaskInfo(taskInfo);
LOGGER.info("taskId:{}, {}个人提交了代码", taskInfo.getId(), qualityInspectVOList.size());
for (GraduationProjectQualityInspectVO qualityInspectVO : qualityInspectVOList) {
GraduationProjectTaskInfoDetail graduationProjectTaskInfoDetail = new GraduationProjectTaskInfoDetail();
graduationProjectTaskInfoDetail.setId(IdUtils.nextStrId());
graduationProjectTaskInfoDetail.setTaskId(taskInfo.getId());
graduationProjectTaskInfoDetail.setProjectName(String.format("%s-%s", qualityInspectVO.getStudentId(), RandomUtil.randomString(8)));
graduationProjectTaskInfoDetail.setName(qualityInspectVO.getName());
graduationProjectTaskInfoDetail.setStudentId(qualityInspectVO.getStudentId());
graduationProjectTaskInfoDetail.setUserId(qualityInspectVO.getUserId());
graduationProjectTaskInfoDetail.setGitUrl(qualityInspectVO.getGitUrl());
graduationProjectTaskInfoDetail.setLanguage(qualityInspectVO.getLanguage());
graduationProjectTaskInfoDetailDao.insertTaskInfoDetail(graduationProjectTaskInfoDetail);
// 提交一个sonar扫描任务
GraduationProjectQualityInspectRunnable runnable = new GraduationProjectQualityInspectRunnable(taskInfo.getId(),
qualityInspectVO.getLanguage(), graduationProjectTaskInfoDetail, sonarQueryResultPool);
runnable.setDbOperateService(dbOperateService);
runnable.setSonarService(sonarService);
// 提交任务
sonarScannerPool.execute(runnable);
}
// 提交之后返回taskId
return new QualityInspect(taskInfo.getId());
}
public RollPage<QualityInspectResultData> qualityInspectResultQuery(GraduationQualityInspectResultQueryVO queryVO) {
int pageSize = queryVO.getPageSize();
int pageNum = queryVO.getCurrentPage();
RollPage<QualityInspectResultData> rollPage = new RollPage<>();
rollPage.setCurrentPage(pageNum);
rollPage.setPageSize(pageSize);
int offset = (pageNum - 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());
resultData.setTaskDetailId(taskInfoDetail.getId());
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) {
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);
}
/**
* =50*(x-a)/x + 30*(y-b)/y + 20*(z-c)/c
* 1xa
* 2yb
* 3zc
*
*
* @param resultData
* @param bugRate bug
* @param maxBugNumber bug
* @param vulnerabilityRate
* @param maxVulnerabilityNumber
* @param codeSmallRate
* @param maxCodeSmallNumber
* @return score
*/
private BigDecimal calcQualityScore(QualityInspectResultData resultData,
int bugRate,
int maxBugNumber,
int vulnerabilityRate,
int maxVulnerabilityNumber,
int codeSmallRate,
int maxCodeSmallNumber) {
if (resultData.getTotalRowNumber() <= 0) {
return BigDecimal.ZERO;
}
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;
}
/**
*
*
* @param taskDetailId
* @return
*/
public AnalyseDetailDTO getAnalyseDetail(String taskDetailId) {
// 作业id+学号
GraduationProjectTaskInfoDetail graduationProjectTaskInfoDetail = graduationProjectTaskInfoDetailDao.selectById(taskDetailId);
if (graduationProjectTaskInfoDetail == null) {
throw new BusinessException(-1, "找不到分析记录");
}
Project project = projectDao.findByName(graduationProjectTaskInfoDetail.getProjectName());
if (project == null) {
throw new BusinessException(-1, String.format("找不到分析记录detailId:%s", taskDetailId));
}
DegreeDTO codeSmall = issuesDao.queryDegree(project.getProject_uuid(), AnalyseTypeEnum.CodeSmell.getType(), AnalyseTypeEnum.CodeSmell.getMetricId());
DegreeDTO bug = issuesDao.queryDegree(project.getProject_uuid(), AnalyseTypeEnum.BUG.getType(), AnalyseTypeEnum.BUG.getMetricId());
DegreeDTO vulnerability = issuesDao.queryDegree(project.getProject_uuid(), AnalyseTypeEnum.Vulnerability.getType(), AnalyseTypeEnum.Vulnerability.getMetricId());
AnalyseDetailDTO analyseDetail = new AnalyseDetailDTO();
analyseDetail.setBug(bug == null ? new DegreeDTO() : bug);
analyseDetail.setVulnerability(vulnerability == null ? new DegreeDTO() : vulnerability);
analyseDetail.setCodeSmall(codeSmall == null ? new DegreeDTO() : codeSmall);
return analyseDetail;
}
/**
*
*
* @param analyseDetailListVO
* @return
*/
public RollPage<AnalyseDetailListDTO> getAnalyseDetailList(GraduationProjectAnalyseDetailListVO analyseDetailListVO) {
RollPage<AnalyseDetailListDTO> rollPage = new RollPage<>();
if (analyseDetailListVO.getCurrentPage() <= 0) {
analyseDetailListVO.setCurrentPage(1);
}
if (analyseDetailListVO.getPageSize() >= 10000) {
analyseDetailListVO.setPageSize(10000);
}
rollPage.setCurrentPage(analyseDetailListVO.getCurrentPage());
rollPage.setPageSize(analyseDetailListVO.getPageSize());
// 作业id+学号
GraduationProjectTaskInfoDetail graduationProjectTaskInfoDetail = graduationProjectTaskInfoDetailDao.selectById(analyseDetailListVO.getTaskDetailId());
if (graduationProjectTaskInfoDetail == null) {
throw new BusinessException(-1, String.format("找不到分析记录detailId:%s", analyseDetailListVO.getTaskDetailId()));
}
Project project = projectDao.findByName(graduationProjectTaskInfoDetail.getProjectName());
if (project == null) {
throw new BusinessException(-1, String.format("找不到分析记录detailId:%s", analyseDetailListVO.getTaskDetailId()));
}
// 分析类型
AnalyseTypeEnum analyseTypeEnum = AnalyseTypeEnum.getAnalyseTypeEnum(analyseDetailListVO.getType());
// 严重程度
DegreeEnum degreeEnum = DegreeEnum.getDegreeEnum(analyseDetailListVO.getDegree());
String severity = null;
if (degreeEnum != DegreeEnum.All) {
severity = degreeEnum.getValue();
}
Integer pageIssuesCount = issuesDao.getPageIssuesCount(project.getProject_uuid(), analyseTypeEnum.getType(), severity);
rollPage.setRecordSum(pageIssuesCount);
if (pageIssuesCount > 0) {
int start = (analyseDetailListVO.getCurrentPage() - 1) * analyseDetailListVO.getPageSize();
List<Issues> pageIssues = issuesDao.getPageIssues(project.getProject_uuid(), analyseTypeEnum.getType(), severity, start, analyseDetailListVO.getPageSize());
processPageIssues(pageIssues, rollPage);
} else {
rollPage.setRecordList(new ArrayList(0));
}
return rollPage;
}
private void processPageIssues(List<Issues> pageIssues, RollPage<AnalyseDetailListDTO> rollPage) {
List<AnalyseDetailListDTO> analyseDetailLists = new ArrayList<>(pageIssues.size());
for (Issues pageIssue : pageIssues) {
AnalyseDetailListDTO detailListDTO = new AnalyseDetailListDTO();
analyseDetailLists.add(detailListDTO);
detailListDTO.setName(pageIssue.getName());
detailListDTO.setDescription(pageIssue.getMessage());
detailListDTO.setIssueId(pageIssue.getId());
detailListDTO.setUuid(pageIssue.getUuid());
detailListDTO.setRuleId(pageIssue.getRuleId());
detailListDTO.setFilePath(pageIssue.getPath());
detailListDTO.setLanguage(pageIssue.getLanguage());
detailListDTO.setLevel(DegreeEnum.getDegreeEnumByValue(pageIssue.getSeverity()).getDesc());
try {
DbIssues.Locations locations = DbIssues.Locations.parseFrom(pageIssue.getLocations());
detailListDTO.setRowNumber(locations.getTextRange().getStartLine());
} catch (InvalidProtocolBufferException e) {
detailListDTO.setRowNumber(0);
LOGGER.error("Fail to read ISSUES.LOCATIONS [KEE=%s]", e);
}
}
rollPage.setRecordList(analyseDetailLists);
}
}

@ -180,6 +180,8 @@ public class SonarService {
if (consumer != null) {
log.info("语言:{},projectName:{},path:{}找到了consumer", language, sonarScannerParam.getProjectKey(),sonarScannerParam.getProjectPath());
consumer.accept(sonarScannerParam);
}else{
sonar(sonarScannerParam.getProjectPath(), sonarScannerParam.getProjectKey());
}
}

@ -0,0 +1,120 @@
package net.educoder.ecsonar.task;
import com.alibaba.fastjson.JSONObject;
import net.educoder.ecsonar.constant.Constant;
import net.educoder.ecsonar.model.GraduationProjectTaskInfoDetail;
import net.educoder.ecsonar.model.SonarScannerParam;
import net.educoder.ecsonar.services.DbOperateService;
import net.educoder.ecsonar.services.SonarService;
import net.educoder.ecsonar.utils.SystemUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
/**
* @Author: youys
* @Date: 2023/8/31
* @Description:
*/
public class GraduationProjectQualityInspectRunnable implements Runnable {
private static final Logger LOGGER = LoggerFactory.getLogger(GraduationProjectQualityInspectRunnable.class);
private String taskId;
public String language;
private ExecutorService queryResultPool;
private GraduationProjectTaskInfoDetail taskInfoDetail;
private DbOperateService dbOperateService;
private SonarService sonarService;
private static final String SUCCESS = "SUCCESS";
public GraduationProjectQualityInspectRunnable(String taskId, String language,
GraduationProjectTaskInfoDetail taskInfoDetail,
ExecutorService queryResultPool) {
this.taskId = taskId;
this.language = language;
this.taskInfoDetail = taskInfoDetail;
this.queryResultPool = queryResultPool;
}
@Override
public void run() {
String projectName = taskInfoDetail.getProjectName();
String path = String.format("/tmp/%s/%s/", taskId, projectName);
// 需要先git clone 到某个目录下面
SystemUtil.ExecuteResp executeResp = gitClone(path, taskInfoDetail.getGitUrl());
if (executeResp.getStatus() != 0) {
LOGGER.warn("projectName:{} git clone失败", taskInfoDetail.getProjectName());
return;
}
// 写完所有文件开始用sonar进行质量分析
SonarScannerParam param = new SonarScannerParam(projectName, path);
if (Constant.C.equalsIgnoreCase(language) || Constant.CXX.equalsIgnoreCase(language)) {
String resultPath = String.format("/tmp/%s", taskId);
File f = new File(resultPath);
if (!f.exists()) {
f.mkdirs();
}
param.setCppCheckReportPath(resultPath + String.format("/%s-result.xml", projectName));
}
// 调用sonar服务
LOGGER.info("taskId:{}, projectName:{}, detailId:{} 开始调用sonar分析,语言:{}", taskId, projectName, taskInfoDetail.getId(), language);
// sonarUrl 启动多个,随机一个
sonarService.sonar(language, param);
// 提交一个查结果的任务
GraduationProjectQueryResultRunnable queryResultRunnable = new GraduationProjectQueryResultRunnable(projectName, taskInfoDetail.getId(), dbOperateService);
LOGGER.info("taskId:{}, projectName:{}, detailId:{} 提交了查询结果的任务", taskId, projectName, taskInfoDetail.getId());
Future<String> submit = queryResultPool.submit(queryResultRunnable);
String status;
try {
status = submit.get();
} catch (Exception e) {
LOGGER.error("GraduationProjectQueryResultRunnable is Exception", e);
status = "FAILED";
}
dbOperateService.updateGraduationProjectTaskInfoDetail(taskInfoDetail.getId(), SUCCESS.equals(status) ? 1 : -1);
}
public void setDbOperateService(DbOperateService dbOperateService) {
this.dbOperateService = dbOperateService;
}
public void setSonarService(SonarService sonarService) {
this.sonarService = sonarService;
}
/**
*
*
* @param path
* @param gitUrl
* @return
*/
private SystemUtil.ExecuteResp gitClone(String path, String gitUrl) {
String command = StringUtils.join("rm -rf ", path, " && mkdir -p ", path, " && cd ", path, " && git clone ", gitUrl);
LOGGER.info("git clonecommand:{}", command);
SystemUtil.ExecuteResp executeResp = SystemUtil.executeAndGetExitStatus(command);
LOGGER.info("git clone结果:{}", JSONObject.toJSONString(executeResp));
return executeResp;
}
}

@ -0,0 +1,44 @@
package net.educoder.ecsonar.task;
import net.educoder.ecsonar.services.DbOperateService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.Callable;
/**
* @Author: youys
* @Date: 2023/8/31
* @Description:
*/
public class GraduationProjectQueryResultRunnable implements Callable<String> {
private static final Logger LOGGER = LoggerFactory.getLogger(GraduationProjectQueryResultRunnable.class);
private String projectName;
private String detailId;
private DbOperateService dbOperateService;
public GraduationProjectQueryResultRunnable(String projectName, String detailId, DbOperateService dbOperateService) {
this.projectName = projectName;
this.detailId = detailId;
this.dbOperateService = dbOperateService;
}
@Override
public String call() throws Exception {
int count = 0;
String status;
while ((status = dbOperateService.queryCeActivityStatus(projectName)) == null && count++ <= 60) {
LOGGER.info("detailId:[{}],sonar还未执行完,次数:{}", detailId, count);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
}
// 查询
LOGGER.info("detailId:[{}], 查询sonar执行状态[{}]", detailId, status);
return status;
}
}

@ -22,7 +22,7 @@ import java.util.concurrent.ExecutorService;
/**
* @Author: youys
* @Date: 2022/1/18
* @Description:
* @Description:
*/
public class QualityInspectRunnable implements Runnable {

@ -7,7 +7,7 @@ import org.slf4j.LoggerFactory;
/**
* @Author: youys
* @Date: 2022/1/18
* @Description:
* @Description:
*/
public class SonarQueryResultRunnable implements Runnable {

@ -6,9 +6,9 @@
spring.datasource.initSize=20
#spring.datasource.master.url=jdbc:postgresql://127.0.0.1:5432/sonar7.7
spring.datasource.master.url=jdbc:postgresql://117.50.14.123:5432/sonar
spring.datasource.master.username=sonar
spring.datasource.master.password=sonar
spring.datasource.master.url=jdbc:postgresql://121.40.224.66:45432/sonar
spring.datasource.master.username=postgres
spring.datasource.master.password=Edu_postgresql
spring.datasource.master.driverClassName=org.postgresql.Driver
@ -43,9 +43,9 @@ zip.save.path=/tmp/
#excel.template.path=/Users/guange/work/java/ecsonar/src/main/resources/template.xlsx
excel.template.path=template.xlsx
sonar.url=http://127.0.0.1:9000
#sonar.url=http://117.50.14.123:9000
# token令牌
#sonar.url=http://127.0.0.1:9000
sonar.url=http://121.40.224.66:49000
# token
sonar.token=0253a518e824a976ea2f11aec17938cb0f8c0495
extract.path=/usr/local/bin/unar

Loading…
Cancel
Save