From f1f96d08cd99862d33361adcfd6d9a65894a2b69 Mon Sep 17 00:00:00 2001 From: HopeLi <1278288511@qq.com> Date: Wed, 11 Jun 2025 15:12:30 +0800 Subject: [PATCH] =?UTF-8?q?0611=20ljc=20=20=20report=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cd/casic/ci/api/ReportController.java | 13 +- .../dto/resp/report/ImageLayerInfo.java | 43 ++++++ .../process/dto/resp/report/ReportResp.java | 1 - .../dto/resp/report/ReportTaskResp.java | 130 ++++++++++++++++++ .../process/service/report/ReportService.java | 3 + .../report/impl/ReportServiceImpl.java | 109 +++++++++++++++ 6 files changed, 294 insertions(+), 5 deletions(-) create mode 100644 modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/dto/resp/report/ImageLayerInfo.java create mode 100644 modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/dto/resp/report/ReportTaskResp.java diff --git a/modules/module-ci-process-api/src/main/java/cd/casic/ci/api/ReportController.java b/modules/module-ci-process-api/src/main/java/cd/casic/ci/api/ReportController.java index 55c4fe30..d09e6dbc 100644 --- a/modules/module-ci-process-api/src/main/java/cd/casic/ci/api/ReportController.java +++ b/modules/module-ci-process-api/src/main/java/cd/casic/ci/api/ReportController.java @@ -4,6 +4,7 @@ package cd.casic.ci.api; import cd.casic.ci.process.dto.req.report.ReportAssetTaskReq; import cd.casic.ci.process.dto.req.report.ReportDeleteReq; import cd.casic.ci.process.dto.resp.report.ReportResp; +import cd.casic.ci.process.dto.resp.report.ReportTaskResp; import cd.casic.ci.process.process.dataObject.base.BaseIdPageReq; import cd.casic.ci.process.process.dataObject.base.BaseIdReq; import cd.casic.ci.process.process.service.report.ReportService; @@ -14,10 +15,7 @@ import jakarta.annotation.security.PermitAll; import jakarta.validation.Valid; import org.jetbrains.annotations.NotNull; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.security.KeyManagementException; import java.security.KeyStoreException; @@ -71,4 +69,11 @@ public class ReportController { return CommonResult.success(reportResp); } + + @GetMapping(path = "/findByScaTaskId") + public CommonResult findByScaTaskId(@RequestParam @NotNull String taskId) throws Exception { + ReportTaskResp taskResp = reportService.findByScaTaskId(taskId); + return CommonResult.success(taskResp); + } + } diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/dto/resp/report/ImageLayerInfo.java b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/dto/resp/report/ImageLayerInfo.java new file mode 100644 index 00000000..4a75980b --- /dev/null +++ b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/dto/resp/report/ImageLayerInfo.java @@ -0,0 +1,43 @@ +package cd.casic.ci.process.dto.resp.report; + +import lombok.Data; + +/** + * @author HopeLi + * @version v1.0 + * @ClassName ImageLayerInfo + * @Date: 2025/6/11 10:51 + * @Description: + */ +@Data +public class ImageLayerInfo { + /** + * 是否为基础层 + * 示例值: ""(空字符串表示非基础层) + */ + private String basicLayer; + + /** + * 安装命令 + * 示例值: "COPY . /home/ # buildkit" + */ + private String command; + + /** + * 是否为指令安装 + * 示例值: true + */ + private Boolean commandInstall; + + /** + * 所属镜像层 ID + * 示例值: "1" + */ + private String layerId; + + /** + * 层级序列号 + * 示例值: 7 + */ + private Integer layerIndex; +} diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/dto/resp/report/ReportResp.java b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/dto/resp/report/ReportResp.java index a52b46db..3675fcf4 100644 --- a/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/dto/resp/report/ReportResp.java +++ b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/dto/resp/report/ReportResp.java @@ -81,6 +81,5 @@ public class ReportResp { private Integer fail; private Integer success; - private Integer code; } diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/dto/resp/report/ReportTaskResp.java b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/dto/resp/report/ReportTaskResp.java new file mode 100644 index 00000000..3e3510c1 --- /dev/null +++ b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/dto/resp/report/ReportTaskResp.java @@ -0,0 +1,130 @@ +package cd.casic.ci.process.dto.resp.report; + +import lombok.Data; + +import java.util.List; + +/** + * @author HopeLi + * @version v1.0 + * @ClassName ReportTaskResp + * @Date: 2025/6/11 10:47 + * @Description: + */ +@Data +public class ReportTaskResp { + /** 应用id */ + private Integer applicationId; + + /** 已审计组件数 */ + private Integer componentAuditNum; + + /** 黑名单组件数 */ + private Integer componentBlackNum; + + /** 高风险组件数 */ + private Integer componentHighNum; + + /** 低风险组件数 */ + private Integer componentLowNum; + + /** 中风险组件数 */ + private Integer componentMediumNum; + + /** 无漏洞组件数 */ + private Integer componentNormalNum; + + /** 组件数 */ + private Integer componentNum; + + /** 恶意组件数 */ + private Integer componentPoisonNum; + + /** 严重组件数 */ + private Integer componentSeriousNum; + + /** 未审计组件数量 */ + private Integer componentUnAuditNum; + + /** 白名单组件数 */ + private Integer componentWhiteNum; + + /** 检测结束时间 */ + private String detectEndTime; + + /** 检测开始时间 */ + private String detectStartTime; + + /** 检测时长 */ + private String detectTime; + + /** 镜像分层信息 */ + private List imageLayerInfos; + + /** 已审计许可证数量 */ + private Integer licenseAuditNum; + + /** 黑名单许可证数量 */ + private Integer licenseBlackNum; + + /** 高风险许可证数量 */ + private Integer licenseHighNum; + + /** 低风险许可证数量 */ + private Integer licenseLowNum; + + /** 中风险许可证数量 */ + private Integer licenseMediumNum; + + /** 许可证数 */ + private Integer licenseNum; + + /** 未审计许可证数量 */ + private Integer licenseUnAuditNum; + + /** 白名单许可证数量 */ + private Integer licenseWhiteNum; + + /** 项目id */ + private Integer projectId; + + /** + * 状态 + * 0-未审计 1-未检测 2-排队中 3-检测中 4-检测暂停 5-检测完成 6-检测超时 7-手动停止 8-检测异常 9-已删除 10-拉取中 11-停止中 12-下载中 + */ + private Integer status; + + /** 任务id */ + private Integer taskId; + + /** 已审计漏洞数量 */ + private Integer vulAuditNum; + + /** 黑名单漏洞数量 */ + private Integer vulBlackNum; + + /** 高风险漏洞数量 */ + private Integer vulHighNum; + + /** 低风险漏洞数量 */ + private Integer vulLowNum; + + /** 中风险漏洞数量 */ + private Integer vulMediumNum; + + /** 漏洞数 */ + private Integer vulNum; + + /** 严重漏洞数量 */ + private Integer vulSeriousNum; + + /** 未审计漏洞数量 */ + private Integer vulUnAuditNum; + + /** 白名单漏洞数量 */ + private Integer vulWhiteNum; + + //xm-trace-id + private String xmTraceId; + +} diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/process/service/report/ReportService.java b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/process/service/report/ReportService.java index 0fc207e4..1f6aab7d 100644 --- a/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/process/service/report/ReportService.java +++ b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/process/service/report/ReportService.java @@ -3,6 +3,7 @@ package cd.casic.ci.process.process.service.report; import cd.casic.ci.process.dto.req.report.ReportAssetTaskReq; import cd.casic.ci.process.dto.req.report.ReportDeleteReq; import cd.casic.ci.process.dto.resp.report.ReportResp; +import cd.casic.ci.process.dto.resp.report.ReportTaskResp; import cd.casic.ci.process.process.dataObject.base.BaseIdPageReq; import cd.casic.ci.process.process.dataObject.base.BaseIdReq; import cd.casic.framework.commons.pojo.PageResult; @@ -28,4 +29,6 @@ public interface ReportService{ ResponseEntity downLoadReport(@Valid BaseIdReq req) throws Exception; ReportResp assetReportTask(@Valid ReportAssetTaskReq req) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException; + + ReportTaskResp findByScaTaskId(String taskId) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException; } diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/process/service/report/impl/ReportServiceImpl.java b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/process/service/report/impl/ReportServiceImpl.java index a6e7b6ca..aa1f9bfb 100644 --- a/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/process/service/report/impl/ReportServiceImpl.java +++ b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/process/service/report/impl/ReportServiceImpl.java @@ -2,7 +2,9 @@ package cd.casic.ci.process.process.service.report.impl; import cd.casic.ci.process.dto.req.report.ReportAssetTaskReq; import cd.casic.ci.process.dto.req.report.ReportDeleteReq; +import cd.casic.ci.process.dto.resp.report.ImageLayerInfo; import cd.casic.ci.process.dto.resp.report.ReportResp; +import cd.casic.ci.process.dto.resp.report.ReportTaskResp; import cd.casic.ci.process.engine.context.ConstantContextHolder; import cd.casic.ci.process.process.dataObject.base.BaseIdPageReq; import cd.casic.ci.process.process.dataObject.base.BaseIdReq; @@ -18,6 +20,7 @@ import org.springframework.http.converter.ByteArrayHttpMessageConverter; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; import java.security.KeyManagementException; import java.security.KeyStoreException; @@ -161,6 +164,44 @@ public class ReportServiceImpl implements ReportService { } } + @Override + public ReportTaskResp findByScaTaskId(String taskId) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException { + RestTemplate restTemplate = getRestTemplateWithoutSANCheck(); + String reportFindTaskUrl = ConstantContextHolder.getScaIp() + "/openapi/v1/task"; + + // 构建带有查询参数的 URL + UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(reportFindTaskUrl).queryParam("taskId", taskId); + + String urlWithParams = builder.toUriString(); + + HttpHeaders headers = createHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + + HttpEntity requestEntity = new HttpEntity<>(headers); + + log.info("根据taskId查询报告接口(GET): " + urlWithParams); + ResponseEntity jsonObjectResponseEntity = restTemplate.exchange(urlWithParams, HttpMethod.GET,requestEntity,JSONObject.class); + + if (ObjectUtils.isEmpty(jsonObjectResponseEntity.getBody())){ + throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"查询报告失败"); + } + + JSONObject response = jsonObjectResponseEntity.getBody(); + + String message = response.getString("message"); + if ("success".equals(message)) { + ReportTaskResp taskResp = new ReportTaskResp(); + log.info("===============根据taskId查询报告接口成功================="); + JSONObject data = response.getJSONObject("data"); + setFindReportTaskResp(data, response.getString("xmTraceId"), taskResp); + return taskResp; + } else { + log.error("===============根据taskId查询报告接口失败================="); + throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "根据taskId查询报告失败"); + } + } + + private HttpHeaders createHeaders() { HttpHeaders headers = new HttpHeaders(); @@ -261,6 +302,74 @@ public class ReportServiceImpl implements ReportService { } + private void setFindReportTaskResp(JSONObject data, String xmTraceId, ReportTaskResp taskResp) { + if (data == null) { + throw new IllegalArgumentException("data 不能为空"); + } + + taskResp.setApplicationId(data.getInteger("applicationId")); + taskResp.setComponentAuditNum(data.getInteger("componentAuditNum")); + taskResp.setComponentBlackNum(data.getInteger("componentBlackNum")); + taskResp.setComponentHighNum(data.getInteger("componentHighNum")); + taskResp.setComponentLowNum(data.getInteger("componentLowNum")); + taskResp.setComponentMediumNum(data.getInteger("componentMediumNum")); + taskResp.setComponentNormalNum(data.getInteger("componentNormalNum")); + taskResp.setComponentNum(data.getInteger("componentNum")); + taskResp.setComponentPoisonNum(data.getInteger("componentPoisonNum")); + taskResp.setComponentSeriousNum(data.getInteger("componentSeriousNum")); + taskResp.setComponentUnAuditNum(data.getInteger("componentUnAuditNum")); + taskResp.setComponentWhiteNum(data.getInteger("componentWhiteNum")); + + taskResp.setDetectEndTime(data.getString("detectEndTime")); + taskResp.setDetectStartTime(data.getString("detectStartTime")); + taskResp.setDetectTime(data.getString("detectTime")); + + // 镜像分层信息:解析 JSONArray 到 List + JSONArray imageLayerArray = data.getJSONArray("imageLayerInfos"); + List imageLayerInfos = new ArrayList<>(); + if (imageLayerArray != null && !imageLayerArray.isEmpty()) { + for (int i = 0; i < imageLayerArray.size(); i++) { + JSONObject layerObj = imageLayerArray.getJSONObject(i); + ImageLayerInfo layerInfo = new ImageLayerInfo(); + + layerInfo.setBasicLayer(layerObj.getString("basicLayer")); + layerInfo.setCommand(layerObj.getString("command")); + layerInfo.setCommandInstall(layerObj.getBoolean("commandInstall")); + layerInfo.setLayerId(layerObj.getString("layerId")); + layerInfo.setLayerIndex(layerObj.getInteger("layerIndex")); + + imageLayerInfos.add(layerInfo); + } + } + taskResp.setImageLayerInfos(imageLayerInfos); + + taskResp.setLicenseAuditNum(data.getInteger("licenseAuditNum")); + taskResp.setLicenseBlackNum(data.getInteger("licenseBlackNum")); + taskResp.setLicenseHighNum(data.getInteger("licenseHighNum")); + taskResp.setLicenseLowNum(data.getInteger("licenseLowNum")); + taskResp.setLicenseMediumNum(data.getInteger("licenseMediumNum")); + taskResp.setLicenseNum(data.getInteger("licenseNum")); + taskResp.setLicenseUnAuditNum(data.getInteger("licenseUnAuditNum")); + taskResp.setLicenseWhiteNum(data.getInteger("licenseWhiteNum")); + + taskResp.setProjectId(data.getInteger("projectId")); + taskResp.setStatus(data.getInteger("status")); + taskResp.setTaskId(data.getInteger("taskId")); + + taskResp.setVulAuditNum(data.getInteger("vulAuditNum")); + taskResp.setVulBlackNum(data.getInteger("vulBlackNum")); + taskResp.setVulHighNum(data.getInteger("vulHighNum")); + taskResp.setVulLowNum(data.getInteger("vulLowNum")); + taskResp.setVulMediumNum(data.getInteger("vulMediumNum")); + taskResp.setVulNum(data.getInteger("vulNum")); + taskResp.setVulSeriousNum(data.getInteger("vulSeriousNum")); + taskResp.setVulUnAuditNum(data.getInteger("vulUnAuditNum")); + taskResp.setVulWhiteNum(data.getInteger("vulWhiteNum")); + + taskResp.setXmTraceId(xmTraceId); + } + + public enum FileType { // 文档类 XLSX("xlsx", "Excel", new byte[]{0x50, 0x4B, 0x03, 0x04}),