| 1 | package edu.ucsb.cs156.frontiers.controllers; | |
| 2 | ||
| 3 | import com.opencsv.bean.StatefulBeanToCsv; | |
| 4 | import com.opencsv.bean.StatefulBeanToCsvBuilder; | |
| 5 | import edu.ucsb.cs156.frontiers.entities.Course; | |
| 6 | import edu.ucsb.cs156.frontiers.entities.DownloadRequest; | |
| 7 | import edu.ucsb.cs156.frontiers.entities.DownloadedCommit; | |
| 8 | import edu.ucsb.cs156.frontiers.entities.Job; | |
| 9 | import edu.ucsb.cs156.frontiers.enums.DownloadRequestType; | |
| 10 | import edu.ucsb.cs156.frontiers.errors.EntityNotFoundException; | |
| 11 | import edu.ucsb.cs156.frontiers.jobs.CommitDownloadRequestJob; | |
| 12 | import edu.ucsb.cs156.frontiers.repositories.CourseRepository; | |
| 13 | import edu.ucsb.cs156.frontiers.repositories.DownloadRequestRepository; | |
| 14 | import edu.ucsb.cs156.frontiers.repositories.DownloadedCommitRepository; | |
| 15 | import edu.ucsb.cs156.frontiers.services.GithubGraphQLService; | |
| 16 | import edu.ucsb.cs156.frontiers.services.jobs.JobService; | |
| 17 | import io.swagger.v3.oas.annotations.Parameter; | |
| 18 | import io.swagger.v3.oas.annotations.tags.Tag; | |
| 19 | import java.io.ByteArrayOutputStream; | |
| 20 | import java.io.OutputStreamWriter; | |
| 21 | import java.time.Instant; | |
| 22 | import java.util.Map; | |
| 23 | import lombok.extern.slf4j.Slf4j; | |
| 24 | import org.springframework.core.io.ByteArrayResource; | |
| 25 | import org.springframework.format.annotation.DateTimeFormat; | |
| 26 | import org.springframework.format.annotation.DateTimeFormat.ISO; | |
| 27 | import org.springframework.http.ContentDisposition; | |
| 28 | import org.springframework.http.HttpHeaders; | |
| 29 | import org.springframework.http.HttpStatus; | |
| 30 | import org.springframework.http.MediaType; | |
| 31 | import org.springframework.http.ResponseEntity; | |
| 32 | import org.springframework.security.access.prepost.PreAuthorize; | |
| 33 | import org.springframework.web.bind.annotation.PathVariable; | |
| 34 | import org.springframework.web.bind.annotation.PostMapping; | |
| 35 | import org.springframework.web.bind.annotation.RequestMapping; | |
| 36 | import org.springframework.web.bind.annotation.RequestParam; | |
| 37 | import org.springframework.web.bind.annotation.RestController; | |
| 38 | ||
| 39 | @RestController | |
| 40 | @RequestMapping("/api/downloads") | |
| 41 | @Tag(name = "Download Management") | |
| 42 | @Slf4j | |
| 43 | public class DownloadRequestController extends ApiController { | |
| 44 | ||
| 45 | private final DownloadedCommitRepository downloadedCommitRepository; | |
| 46 | private final DownloadRequestRepository downloadRequestRepository; | |
| 47 | private final CourseRepository courseRepository; | |
| 48 | private final JobService jobService; | |
| 49 | private final GithubGraphQLService githubGraphQLService; | |
| 50 | ||
| 51 | public DownloadRequestController( | |
| 52 | DownloadedCommitRepository downloadedCommitRepository, | |
| 53 | DownloadRequestRepository downloadRequestRepository, | |
| 54 | CourseRepository courseRepository, | |
| 55 | JobService jobService, | |
| 56 | GithubGraphQLService githubGraphQLService) { | |
| 57 | this.downloadedCommitRepository = downloadedCommitRepository; | |
| 58 | this.downloadRequestRepository = downloadRequestRepository; | |
| 59 | this.courseRepository = courseRepository; | |
| 60 | this.jobService = jobService; | |
| 61 | this.githubGraphQLService = githubGraphQLService; | |
| 62 | } | |
| 63 | ||
| 64 | @PostMapping("/create") | |
| 65 | @PreAuthorize("@CourseSecurity.hasManagePermissions(#root, #courseId)") | |
| 66 | public ResponseEntity<DownloadRequest> createDownloadRequest( | |
| 67 | @Parameter Long courseId, | |
| 68 | @RequestParam String org, | |
| 69 | @RequestParam String repo, | |
| 70 | @RequestParam(required = false) String branch, | |
| 71 | @RequestParam DownloadRequestType type, | |
| 72 | @RequestParam(required = false) @DateTimeFormat(iso = ISO.DATE) Instant startDate, | |
| 73 | @RequestParam(required = false) @DateTimeFormat(iso = ISO.DATE) Instant endDate) { | |
| 74 | ||
| 75 | Course course = | |
| 76 | courseRepository | |
| 77 | .findById(courseId) | |
| 78 |
1
1. lambda$createDownloadRequest$0 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/DownloadRequestController::lambda$createDownloadRequest$0 → KILLED |
.orElseThrow(() -> new EntityNotFoundException(Course.class, courseId)); |
| 79 | DownloadRequest request = | |
| 80 | DownloadRequest.builder() | |
| 81 | .course(course) | |
| 82 | .org(org) | |
| 83 | .repo(repo) | |
| 84 | .downloadType(type) | |
| 85 | .startDate(startDate) | |
| 86 | .endDate(endDate) | |
| 87 | .build(); | |
| 88 | ||
| 89 |
1
1. createDownloadRequest : negated conditional → KILLED |
if (branch != null) { |
| 90 |
1
1. createDownloadRequest : removed call to edu/ucsb/cs156/frontiers/entities/DownloadRequest::setBranch → KILLED |
request.setBranch(branch); |
| 91 | } | |
| 92 | ||
| 93 | request = downloadRequestRepository.save(request); | |
| 94 | ||
| 95 | CommitDownloadRequestJob job = | |
| 96 | CommitDownloadRequestJob.builder() | |
| 97 | .request(request) | |
| 98 | .githubService(githubGraphQLService) | |
| 99 | .build(); | |
| 100 | ||
| 101 | Job startedJob = jobService.runAsJob(job); | |
| 102 | ||
| 103 |
1
1. createDownloadRequest : removed call to edu/ucsb/cs156/frontiers/entities/DownloadRequest::setJob → KILLED |
request.setJob(startedJob); |
| 104 | ||
| 105 |
1
1. createDownloadRequest : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/DownloadRequestController::createDownloadRequest → KILLED |
return ResponseEntity.status(HttpStatus.ACCEPTED).body(downloadRequestRepository.save(request)); |
| 106 | } | |
| 107 | ||
| 108 | @PostMapping("{downloadRequestId}") | |
| 109 | @PreAuthorize("@CourseSecurity.hasDownloadPermissions(#root, #downloadRequestId)") | |
| 110 | public ResponseEntity<Object> getDownload(@PathVariable Long downloadRequestId) throws Exception { | |
| 111 | DownloadRequest request = | |
| 112 | downloadRequestRepository | |
| 113 | .findById(downloadRequestId) | |
| 114 | .orElseThrow( | |
| 115 |
1
1. lambda$getDownload$1 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/DownloadRequestController::lambda$getDownload$1 → KILLED |
() -> new EntityNotFoundException(DownloadRequest.class, downloadRequestId)); |
| 116 | ||
| 117 |
1
1. getDownload : negated conditional → KILLED |
if (request.getJob().getStatus().equals("error")) { |
| 118 | Map<String, String> errorResponse = | |
| 119 | Map.of( | |
| 120 | "message", | |
| 121 | "Download request failed with error; please check the job log for more information."); | |
| 122 |
1
1. getDownload : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/DownloadRequestController::getDownload → KILLED |
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse); |
| 123 | } | |
| 124 | ||
| 125 |
1
1. getDownload : negated conditional → KILLED |
if (!request.getJob().getStatus().equals("complete")) { |
| 126 |
1
1. getDownload : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/DownloadRequestController::getDownload → KILLED |
return ResponseEntity.status(HttpStatus.ACCEPTED) |
| 127 | .body(Map.of("message", "Download request is not complete. Please try again later.")); | |
| 128 | } | |
| 129 | ||
| 130 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |
| 131 | try (OutputStreamWriter writer = new OutputStreamWriter(baos)) { | |
| 132 | StatefulBeanToCsv<DownloadedCommit> csvWriter = | |
| 133 | new StatefulBeanToCsvBuilder<DownloadedCommit>(writer).build(); | |
| 134 |
1
1. getDownload : removed call to com/opencsv/bean/StatefulBeanToCsv::write → KILLED |
csvWriter.write(downloadedCommitRepository.findByRequest(request).iterator()); |
| 135 | } | |
| 136 | ||
| 137 | HttpHeaders headers = new HttpHeaders(); | |
| 138 |
1
1. getDownload : removed call to org/springframework/http/HttpHeaders::setContentType → KILLED |
headers.setContentType(MediaType.parseMediaType("text/csv")); |
| 139 |
1
1. getDownload : removed call to org/springframework/http/HttpHeaders::setContentDisposition → KILLED |
headers.setContentDisposition( |
| 140 | ContentDisposition.builder("attachment") | |
| 141 | .filename(request.getOrg() + "_" + request.getRepo() + ".csv") | |
| 142 | .build()); | |
| 143 | ||
| 144 |
1
1. getDownload : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/DownloadRequestController::getDownload → KILLED |
return ResponseEntity.ok().headers(headers).body(new ByteArrayResource(baos.toByteArray())); |
| 145 | } | |
| 146 | } | |
Mutations | ||
| 78 |
1.1 |
|
| 89 |
1.1 |
|
| 90 |
1.1 |
|
| 103 |
1.1 |
|
| 105 |
1.1 |
|
| 115 |
1.1 |
|
| 117 |
1.1 |
|
| 122 |
1.1 |
|
| 125 |
1.1 |
|
| 126 |
1.1 |
|
| 134 |
1.1 |
|
| 138 |
1.1 |
|
| 139 |
1.1 |
|
| 144 |
1.1 |