|
| 1 | +package com.amazonaws.gurureviewercli.util; |
| 2 | + |
| 3 | +import java.io.IOException; |
| 4 | +import java.nio.file.Path; |
| 5 | +import java.util.ArrayList; |
| 6 | +import java.util.Collection; |
| 7 | +import java.util.stream.Collectors; |
| 8 | + |
| 9 | +import com.fasterxml.jackson.annotation.JsonInclude; |
| 10 | +import com.fasterxml.jackson.databind.DeserializationFeature; |
| 11 | +import com.fasterxml.jackson.databind.SerializationFeature; |
| 12 | +import com.fasterxml.jackson.databind.json.JsonMapper; |
| 13 | +import lombok.val; |
| 14 | +import software.amazon.awssdk.services.codegurureviewer.model.RecommendationSummary; |
| 15 | +import software.amazon.awssdk.services.codegurureviewer.model.Severity; |
| 16 | + |
| 17 | +import com.amazonaws.gurureviewercli.model.ScanMetaData; |
| 18 | +import com.amazonaws.gurureviewercli.model.bitbucket.CodeInsightsAnnotation; |
| 19 | +import com.amazonaws.gurureviewercli.model.bitbucket.CodeInsightsReport; |
| 20 | + |
| 21 | +/** |
| 22 | + * Export Report and Annotations file for BitBucket CodeInsights. |
| 23 | + */ |
| 24 | +public final class CodeInsightExport { |
| 25 | + private static final String REPORT_FILE_NAME = "report.json"; |
| 26 | + private static final String ANNOTATIONS_FILE_NAME = "annotations.json"; |
| 27 | + |
| 28 | + private static final JsonMapper JSON_MAPPER = |
| 29 | + JsonMapper.builder() |
| 30 | + .serializationInclusion(JsonInclude.Include.NON_ABSENT) |
| 31 | + .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) |
| 32 | + .disable(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS) |
| 33 | + .disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE) |
| 34 | + .enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE) |
| 35 | + .build(); |
| 36 | + |
| 37 | + public static void report(final Collection<RecommendationSummary> recommendations, |
| 38 | + final ScanMetaData scanMetaData, |
| 39 | + final Path outputDir) throws IOException { |
| 40 | + val reportTitle = "CodeGuru Reviewer report"; |
| 41 | + val url = String.format("https://console.aws.amazon.com/codeguru/reviewer?region=%s#/codereviews/details/%s", |
| 42 | + scanMetaData.getRegion(), scanMetaData.getCodeReviewArn()); |
| 43 | + val report = CodeInsightsReport.builder() |
| 44 | + .title(reportTitle) |
| 45 | + .reporter("CodeGuru Reviewer CLI") |
| 46 | + .details(String.format("CodeGuru Reviewer reported %d recommendations", |
| 47 | + recommendations.size())) |
| 48 | + .result(recommendations.isEmpty() ? "PASSED" : "FAILED") |
| 49 | + .link(url) |
| 50 | + .data(new ArrayList<>()) |
| 51 | + .build(); |
| 52 | + |
| 53 | + val annotations = recommendations.stream().map(r -> convert(r, reportTitle)) |
| 54 | + .collect(Collectors.toList()); |
| 55 | + |
| 56 | + JSON_MAPPER.writeValue(outputDir.resolve(REPORT_FILE_NAME).toFile(), report); |
| 57 | + JSON_MAPPER.writeValue(outputDir.resolve(ANNOTATIONS_FILE_NAME).toFile(), annotations); |
| 58 | + } |
| 59 | + |
| 60 | + private static CodeInsightsAnnotation convert(final RecommendationSummary recommendation, |
| 61 | + final String reportTitle) { |
| 62 | + String description = recommendation.recommendationCategoryAsString(); |
| 63 | + if (recommendation.ruleMetadata() != null) { |
| 64 | + description = recommendation.ruleMetadata().shortDescription(); |
| 65 | + } |
| 66 | + |
| 67 | + return CodeInsightsAnnotation.builder() |
| 68 | + .title(reportTitle) |
| 69 | + .externalId(recommendation.recommendationId()) |
| 70 | + .path(recommendation.filePath()) |
| 71 | + .line(recommendation.startLine()) |
| 72 | + .summary(description) |
| 73 | + .annotationType("Vulnerability".toUpperCase()) |
| 74 | + .severity(convertSeverity(recommendation.severity())) |
| 75 | + .build(); |
| 76 | + } |
| 77 | + |
| 78 | + private static String convertSeverity(Severity guruSeverity) { |
| 79 | + if (guruSeverity != null) { |
| 80 | + return guruSeverity.toString().toUpperCase(); // Bitbucket uses the same severity levels as CodeGuru. |
| 81 | + } |
| 82 | + return "Unknown"; |
| 83 | + } |
| 84 | + |
| 85 | +} |
0 commit comments