云脑代码质量分析

dev
youys 2 years ago
parent 9cba668ba3
commit e8790e9f09

@ -63,6 +63,12 @@
<version>5.7.19</version> <version>5.7.19</version>
</dependency> </dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-http</artifactId>
<version>5.7.19</version>
</dependency>
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId> <artifactId>fastjson</artifactId>

@ -19,4 +19,10 @@ public class Constant {
public static final List<String> language = Arrays.asList(JAVA, C, CXX, PYTHON); public static final List<String> language = Arrays.asList(JAVA, C, CXX, PYTHON);
public static final String SUCCESS = "SUCCESS"; public static final String SUCCESS = "SUCCESS";
public static final String BUG = "BUG";
public static final String VULNERABILITY = "VULNERABILITY";
public static final String CODE_SMELL = "CODE_SMELL";
public static final String SECURITY_HOTSPOT = "SECURITY_HOTSPOT";
} }

@ -3,7 +3,7 @@ package net.educoder.ecsonar.controller;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import net.educoder.ecsonar.model.api.QualityInspect; import net.educoder.ecsonar.model.api.QualityInspect;
import net.educoder.ecsonar.model.api.QualityInspectIsCompleted; import net.educoder.ecsonar.model.api.QualityInspectIsCompleted;
import net.educoder.ecsonar.model.vo.CloudBrainQualityInspectVO; import net.educoder.ecsonar.model.vo.*;
import net.educoder.ecsonar.services.CloudBrainService; import net.educoder.ecsonar.services.CloudBrainService;
import net.educoder.ecsonar.utils.ResponseResult; import net.educoder.ecsonar.utils.ResponseResult;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
@ -12,7 +12,9 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* @Author: youys * @Author: youys
@ -28,10 +30,16 @@ public class CloudBrainController {
@Autowired @Autowired
private CloudBrainService cloudBrainService; private CloudBrainService cloudBrainService;
/**
*
*
* @param cloudBrainQualityInspectVO
* @return
*/
@PostMapping("/cloudQualityInspect") @PostMapping("/cloudQualityInspect")
public ResponseResult cloudQualityInspect(@RequestBody List<CloudBrainQualityInspectVO> cloudBrainQualityInspectVO) { public ResponseResult cloudQualityInspect(@RequestBody List<CloudBrainQualityInspectVO> cloudBrainQualityInspectVO) {
logger.info("cloudQualityInspect请求参数:{}", JSONObject.toJSONString(cloudBrainQualityInspectVO)); logger.info("cloudQualityInspect请求参数:{}", JSONObject.toJSONString(cloudBrainQualityInspectVO));
if(CollectionUtils.isEmpty(cloudBrainQualityInspectVO)){ if (CollectionUtils.isEmpty(cloudBrainQualityInspectVO)) {
ResponseResult.error("参数不能为空"); ResponseResult.error("参数不能为空");
} }
QualityInspect qualityInspect = cloudBrainService.startQualityInspect(cloudBrainQualityInspectVO); QualityInspect qualityInspect = cloudBrainService.startQualityInspect(cloudBrainQualityInspectVO);
@ -40,13 +48,45 @@ public class CloudBrainController {
/** /**
* *
*
* @param taskId * @param taskId
* @return * @return
*/ */
@GetMapping(value = "/cloudQualityInspectIsCompleted/{taskId}") @GetMapping(value = "/cloudQualityInspectResult")
public ResponseResult<QualityInspectIsCompleted> cloudQualityInspectIsCompleted(@PathVariable String taskId){ public ResponseResult<CloudQualityInspectResultVO> cloudQualityInspectResult(@RequestParam String taskId) {
QualityInspectIsCompleted result = cloudBrainService.cloudQualityInspectIsCompleted(taskId); CloudQualityInspectResultVO result = cloudBrainService.cloudQualityInspectResult(taskId);
return ResponseResult.success(result);
}
/**
* issues
*
* @param searchVO
* @return
*/
@GetMapping(value = "/issues/search")
public ResponseResult<IssuesVO> issuesSearch(IssuesSearchVO searchVO) {
List<IssuesVO> result = cloudBrainService.issuesSearch(searchVO);
return ResponseResult.success(result);
}
/**
*
*
* @param component
* @return
*/
@GetMapping(value = "/getSourceCode")
public ResponseResult<Map> getSourceCode(@RequestParam String component) {
List<SourceCodeVO> sources = cloudBrainService.getSourceCode(component);
Map<String, Object> result = new HashMap<>(2);
result.put("sources", sources);
return ResponseResult.success(result); return ResponseResult.success(result);
} }

@ -34,6 +34,6 @@ public interface CloudTaskInfoDao {
* @param id * @param id
* @param status * @param status
*/ */
@Update("update cloud_task_info set status=#{status} where id=#{id}") @Update("update cloud_task_info set status=#{status},update_time=current_timestamp where id=#{id}")
void updateCloudTaskInfoStatus(@Param("id") String id, @Param("status") Integer status); void updateCloudTaskInfoStatus(@Param("id") String id, @Param("status") Integer status);
} }

@ -6,6 +6,8 @@ import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update; import org.apache.ibatis.annotations.Update;
import java.util.List;
/** /**
* @Author: youys * @Author: youys
* @Date: 2022/1/18 * @Date: 2022/1/18
@ -31,6 +33,20 @@ public interface CloudTaskInfoDetailDao {
void updateCloudTaskInfoDetailStatus(@Param("id") String id, @Param("status") Integer status); void updateCloudTaskInfoDetailStatus(@Param("id") String id, @Param("status") Integer status);
/**
*
* @param taskId
* @return
*/
@Select("select count(1) from cloud_task_info_detail where task_id=#{taskId} and status=1") @Select("select count(1) from cloud_task_info_detail where task_id=#{taskId} and status=1")
Integer selectCountByTaskId(String taskId); Integer selectCountByTaskId(String taskId);
/**
* projectNames
* @param taskId
* @return
*/
@Select("select project_name from cloud_task_info_detail where task_id=#{taskId} and status=1")
List<String> selectProjectNamesByTaskId(String taskId);
} }

@ -1,5 +1,6 @@
package net.educoder.ecsonar.dao; package net.educoder.ecsonar.dao;
import net.educoder.ecsonar.model.IssuesMetrics;
import net.educoder.ecsonar.model.Metrics; import net.educoder.ecsonar.model.Metrics;
import net.educoder.ecsonar.model.Project; import net.educoder.ecsonar.model.Project;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
@ -48,4 +49,13 @@ public interface ProjectDao {
"(SELECT COALESCE(count(*),0) minor_violations FROM issues where project_uuid=#{projectUuid} and status='OPEN' and issue_type=3 and severity='MINOR')," + "(SELECT COALESCE(count(*),0) minor_violations FROM issues where project_uuid=#{projectUuid} and status='OPEN' and issue_type=3 and severity='MINOR')," +
"(select text_value violations from project_measures where component_uuid = #{projectUuid} and metric_id = 93 order by id desc limit 1)") "(select text_value violations from project_measures where component_uuid = #{projectUuid} and metric_id = 93 order by id desc limit 1)")
Metrics selectMetricsByProjectUuid(String projectUuid); Metrics selectMetricsByProjectUuid(String projectUuid);
@Select("select (select count(1) from issues where project_uuid=#{projectUuid} and issue_type=1) vulnerability," +
"(select count(1) from issues where project_uuid=#{projectUuid} and issue_type=2) bugs," +
"(select count(1) from issues where project_uuid=#{projectUuid} and issue_type=3) codeSmell," +
"(select value from project_measures pm where component_uuid=#{projectUuid} and metric_id=3) codeLines")
IssuesMetrics selectIssuesMetrics(String projectUuid);
} }

@ -0,0 +1,46 @@
package net.educoder.ecsonar.model;
/**
* @Author: youys
* @Date: 2022/7/6
* @Description:
*/
public class IssuesMetrics {
private Integer bugs;
private Integer vulnerability;
private Integer codeSmell;
private Integer codeLines;
public Integer getBugs() {
return bugs;
}
public void setBugs(Integer bugs) {
this.bugs = bugs;
}
public Integer getVulnerability() {
return vulnerability;
}
public void setVulnerability(Integer vulnerability) {
this.vulnerability = vulnerability;
}
public Integer getCodeSmell() {
return codeSmell;
}
public void setCodeSmell(Integer codeSmell) {
this.codeSmell = codeSmell;
}
public Integer getCodeLines() {
return codeLines;
}
public void setCodeLines(Integer codeLines) {
this.codeLines = codeLines;
}
}

@ -0,0 +1,81 @@
package net.educoder.ecsonar.model.vo;
/**
* @Author: youys
* @Date: 2022/7/6
* @Description:
*/
public class CloudQualityInspectMetricsVO {
private String taskId;
private String projectName;
/**
* bug
*/
private Integer bugs;
/**¬
*
*/
private Integer vulnerability;
/**
*
*/
private Integer codeSmell;
/**
*
*/
private Integer codeLines;
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
public Integer getBugs() {
return bugs;
}
public void setBugs(Integer bugs) {
this.bugs = bugs;
}
public Integer getVulnerability() {
return vulnerability;
}
public void setVulnerability(Integer vulnerability) {
this.vulnerability = vulnerability;
}
public Integer getCodeLines() {
return codeLines;
}
public void setCodeLines(Integer codeLines) {
this.codeLines = codeLines;
}
public Integer getCodeSmell() {
return codeSmell;
}
public void setCodeSmell(Integer codeSmell) {
this.codeSmell = codeSmell;
}
}

@ -0,0 +1,43 @@
package net.educoder.ecsonar.model.vo;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: youys
* @Date: 2022/7/6
* @Description:
*/
public class CloudQualityInspectResultVO {
private String taskId;
private Integer completed;
private List<CloudQualityInspectMetricsVO> metricsVOList = new ArrayList<>(0);
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
public Integer getCompleted() {
return completed;
}
public void setCompleted(Integer completed) {
this.completed = completed;
}
public List<CloudQualityInspectMetricsVO> getMetricsVOList() {
return metricsVOList;
}
public void setMetricsVOList(List<CloudQualityInspectMetricsVO> metricsVOList) {
this.metricsVOList = metricsVOList;
}
}

@ -0,0 +1,37 @@
package net.educoder.ecsonar.model.vo;
/**
* @Author: youys
* @Date: 2022/7/6
* @Description:
*/
public class IssuesSearchVO {
private String taskId;
private String projectName;
private String type;
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 getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}

@ -0,0 +1,55 @@
package net.educoder.ecsonar.model.vo;
/**
* @Author: youys
* @Date: 2022/7/6
* @Description:
*/
public class IssuesVO {
private String component;
private String message;
private String status;
private String severity;
private Integer line;
public String getComponent() {
return component;
}
public void setComponent(String component) {
this.component = component;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getSeverity() {
return severity;
}
public void setSeverity(String severity) {
this.severity = severity;
}
public Integer getLine() {
return line;
}
public void setLine(Integer line) {
this.line = line;
}
}

@ -0,0 +1,28 @@
package net.educoder.ecsonar.model.vo;
/**
* @Author: youys
* @Date: 2022/7/6
* @Description:
*/
public class SourceCodeVO {
private String code;
private Integer line;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Integer getLine() {
return line;
}
public void setLine(Integer line) {
this.line = line;
}
}

@ -1,23 +1,29 @@
package net.educoder.ecsonar.services; package net.educoder.ecsonar.services;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import net.educoder.ecsonar.dao.CloudTaskInfoDao; import net.educoder.ecsonar.dao.CloudTaskInfoDao;
import net.educoder.ecsonar.dao.CloudTaskInfoDetailDao; import net.educoder.ecsonar.dao.CloudTaskInfoDetailDao;
import net.educoder.ecsonar.dao.ProjectDao;
import net.educoder.ecsonar.exception.BusinessException; import net.educoder.ecsonar.exception.BusinessException;
import net.educoder.ecsonar.model.CloudTaskInfo; import net.educoder.ecsonar.model.CloudTaskInfo;
import net.educoder.ecsonar.model.CloudTaskInfoDetail; import net.educoder.ecsonar.model.CloudTaskInfoDetail;
import net.educoder.ecsonar.model.IssuesMetrics;
import net.educoder.ecsonar.model.Project;
import net.educoder.ecsonar.model.api.QualityInspect; import net.educoder.ecsonar.model.api.QualityInspect;
import net.educoder.ecsonar.model.api.QualityInspectIsCompleted; import net.educoder.ecsonar.model.api.QualityInspectIsCompleted;
import net.educoder.ecsonar.model.vo.CloudBrainQualityInspectVO; import net.educoder.ecsonar.model.vo.*;
import net.educoder.ecsonar.task.CloudBrainQualityInspectRunnable; import net.educoder.ecsonar.task.CloudBrainQualityInspectRunnable;
import net.educoder.ecsonar.utils.IdUtils; import net.educoder.ecsonar.utils.IdUtils;
import net.educoder.ecsonar.utils.SystemUtil; import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
@ -41,6 +47,9 @@ public class CloudBrainService {
@Autowired @Autowired
private DbOperateService dbOperateService; private DbOperateService dbOperateService;
@Autowired
private ProjectDao projectDao;
@Autowired @Autowired
@Qualifier("sonarScannerPool") @Qualifier("sonarScannerPool")
private ExecutorService sonarScannerPool; private ExecutorService sonarScannerPool;
@ -49,6 +58,9 @@ public class CloudBrainService {
@Qualifier("sonarQueryResultPool") @Qualifier("sonarQueryResultPool")
private ExecutorService sonarQueryResultPool; private ExecutorService sonarQueryResultPool;
@Value("${sonar.host}")
private String sonarHost;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public QualityInspect startQualityInspect(List<CloudBrainQualityInspectVO> cloudBrainQualityInspectVO) { public QualityInspect startQualityInspect(List<CloudBrainQualityInspectVO> cloudBrainQualityInspectVO) {
@ -108,4 +120,130 @@ public class CloudBrainService {
QualityInspectIsCompleted qualityInspectIsCompleted = new QualityInspectIsCompleted(taskId, completed); QualityInspectIsCompleted qualityInspectIsCompleted = new QualityInspectIsCompleted(taskId, completed);
return qualityInspectIsCompleted; return qualityInspectIsCompleted;
} }
public CloudQualityInspectResultVO cloudQualityInspectResult(String taskId) {
QualityInspectIsCompleted qualityInspectIsCompleted = cloudQualityInspectIsCompleted(taskId);
CloudQualityInspectResultVO resultVO = new CloudQualityInspectResultVO();
resultVO.setTaskId(taskId);
resultVO.setCompleted(qualityInspectIsCompleted.getCompleted());
if (qualityInspectIsCompleted.getCompleted() == 0) {
return resultVO;
}
CloudTaskInfo cloudTaskInfo = cloudTaskInfoDao.queryById(taskId);
if (cloudTaskInfo == null) {
return resultVO;
}
List<String> projectNames = cloudTaskInfoDetailDao.selectProjectNamesByTaskId(taskId);
List<CloudQualityInspectMetricsVO> metricsVOList = new ArrayList<>(projectNames.size());
for (String projectName : projectNames) {
Project project = projectDao.findByName(projectName);
IssuesMetrics issuesMetrics = projectDao.selectIssuesMetrics(project.getProject_uuid());
CloudQualityInspectMetricsVO metricsVO = new CloudQualityInspectMetricsVO();
metricsVO.setProjectName(projectName);
metricsVO.setBugs(issuesMetrics.getBugs());
metricsVO.setVulnerability(issuesMetrics.getVulnerability());
metricsVO.setCodeSmell(issuesMetrics.getCodeSmell());
metricsVO.setCodeLines(issuesMetrics.getCodeLines());
metricsVOList.add(metricsVO);
}
resultVO.setMetricsVOList(metricsVOList);
return resultVO;
}
/**
* issues
* @param searchVO
* @return
*/
public List<IssuesVO> issuesSearch(IssuesSearchVO searchVO) {
List<IssuesVO> issues = doGetIssues(searchVO.getProjectName(), searchVO.getType());
return issues;
}
/**
*
* @param component
* @return
*/
public List<SourceCodeVO> getSourceCode(String component) {
return doGetSourceCode(component);
}
/**
* issues
*
* @param projectName
* @param types
* @return
*/
private List<IssuesVO> doGetIssues(String projectName, String types) {
StringBuilder sb = new StringBuilder();
sb.append("/api/issues/search?componentKeys=").append(projectName)
.append("&s=FILE_LINE&resolved=false&types=").append(types)
.append("&ps=500&organization=default-organization&facets=severities%2Ctypes&additionalFields=_all");
String url = sonarHost + sb.toString();
String result = HttpUtil.get(url);
if (StringUtils.isEmpty(result)) {
return new ArrayList<>(0);
}
JSONArray issuesArray = JSONObject.parseObject(result).getJSONArray("issues");
List<IssuesVO> issuesVOS = new ArrayList<>(issuesArray.size());
for (Object o : issuesArray) {
JSONObject issueObj = (JSONObject) o;
IssuesVO vo = new IssuesVO();
vo.setComponent(issueObj.getString("component"));
vo.setLine(issueObj.getInteger("line"));
vo.setMessage(issueObj.getString("message"));
vo.setSeverity(issueObj.getString("severity"));
vo.setStatus(issueObj.getString("status"));
issuesVOS.add(vo);
}
return issuesVOS;
}
private List<SourceCodeVO> doGetSourceCode(String component) {
StringBuilder sb = new StringBuilder();
sb.append("/api/sources/lines?key=").append(component)
.append("&from=1&to=50100");
String url = sonarHost + sb.toString();
String result = HttpUtil.get(url);
if (StringUtils.isEmpty(result)) {
return new ArrayList<>(0);
}
JSONArray sourcesArrays = JSONObject.parseObject(result).getJSONArray("sources");
List<SourceCodeVO> sourceCodeVOS = new ArrayList<>(sourcesArrays.size());
for (Object o : sourcesArrays) {
JSONObject issueObj = (JSONObject) o;
SourceCodeVO vo = new SourceCodeVO();
vo.setCode(issueObj.getString("code"));
vo.setLine(issueObj.getInteger("line"));
sourceCodeVOS.add(vo);
}
return sourceCodeVOS;
}
} }

@ -56,4 +56,6 @@ last.run.id=0
skip.checked=true skip.checked=true
server.port=8081 server.port=8081
sonar.host=http://localhost:9000
Loading…
Cancel
Save