JobsController.java

1
package edu.ucsb.cs.scaffold.controller;
2
3
import edu.ucsb.cs.scaffold.entity.Course;
4
import edu.ucsb.cs.scaffold.errors.EntityNotFoundException;
5
import edu.ucsb.cs.scaffold.jobs.ReadPLColorsJob;
6
import edu.ucsb.cs.scaffold.jobs.RotatePatKeysJob;
7
import edu.ucsb.cs.scaffold.jobs.SyncCourseWithPlRepoJob;
8
import edu.ucsb.cs.scaffold.jobs.SyncCourseWithPlRepoJobFactory;
9
import edu.ucsb.cs.scaffold.jobs.UpdateAllJob;
10
import edu.ucsb.cs.scaffold.repository.CourseRepository;
11
import edu.ucsb.cs.scaffold.repository.PatCredentialRepository;
12
import edu.ucsb.cs.scaffold.repository.PlColorRepository;
13
import edu.ucsb.cs.scaffold.services.GithubService;
14
import edu.ucsb.cs.scaffold.services.PatEncryptionService;
15
import edu.ucsb.cs.scaffold.services.UpdateUserService;
16
import edu.ucsb.cs156.jobs.entities.Job;
17
import edu.ucsb.cs156.jobs.repositories.JobsRepository;
18
import edu.ucsb.cs156.jobs.services.JobService;
19
import io.swagger.v3.oas.annotations.Operation;
20
import io.swagger.v3.oas.annotations.Parameter;
21
import io.swagger.v3.oas.annotations.tags.Tag;
22
import lombok.extern.slf4j.Slf4j;
23
import org.springframework.beans.factory.annotation.Autowired;
24
import org.springframework.security.access.prepost.PreAuthorize;
25
import org.springframework.web.bind.annotation.GetMapping;
26
import org.springframework.web.bind.annotation.PostMapping;
27
import org.springframework.web.bind.annotation.RequestMapping;
28
import org.springframework.web.bind.annotation.RequestParam;
29
import org.springframework.web.bind.annotation.RestController;
30
31
/**
32
 * Launch endpoints for this app's concrete jobs, plus the course-scoped jobs listing (which uses
33
 * this app's CourseSecurity rule). The generic admin endpoints (list all / paginated / logs /
34
 * delete) come from the lib-jobs library's own controller.
35
 */
36
@Tag(name = "Jobs")
37
@RequestMapping("/api/jobs")
38
@RestController
39
@Slf4j
40
public class JobsController extends ApiController {
41
  @Autowired private JobsRepository jobsRepository;
42
43
  @Autowired private JobService jobService;
44
45
  @Autowired private UpdateUserService updateUserService;
46
47
  @Autowired private CourseRepository courseRepository;
48
  @Autowired private PatEncryptionService patEncryptionService;
49
  @Autowired private PatCredentialRepository patCredentialRepository;
50
  @Autowired private SyncCourseWithPlRepoJobFactory syncCourseWithPlRepoJobFactory;
51
  @Autowired private GithubService githubService;
52
  @Autowired private PlColorRepository plColorRepository;
53
54
  @Operation(summary = "Launch UpdateAll job")
55
  @PreAuthorize("hasRole('ROLE_ADMIN')")
56
  @PostMapping("/launch/updateAll")
57
  public Job launchUpdateAllJob() {
58
59
    UpdateAllJob job = UpdateAllJob.builder().updateUserService(updateUserService).build();
60 1 1. launchUpdateAllJob : replaced return value with null for edu/ucsb/cs/scaffold/controller/JobsController::launchUpdateAllJob → KILLED
    return jobService.runAsJob(job);
61
  }
62
63
  @Operation(
64
      summary =
65
          "Launch RotatePatKeys job (re-encrypt stored PATs under the current PAT_ENCRYPTION_KEY)")
66
  @PreAuthorize("hasRole('ROLE_ADMIN')")
67
  @PostMapping("/launch/rotatePatKeys")
68
  public Job launchRotatePatKeysJob() {
69
70
    RotatePatKeysJob job =
71
        RotatePatKeysJob.builder()
72
            .patEncryptionService(patEncryptionService)
73
            .patCredentialRepository(patCredentialRepository)
74
            .build();
75 1 1. launchRotatePatKeysJob : replaced return value with null for edu/ucsb/cs/scaffold/controller/JobsController::launchRotatePatKeysJob → KILLED
    return jobService.runAsJob(job);
76
  }
77
78
  @Operation(
79
      summary =
80
          "Launch SyncCourseWithPlRepo job (sync the course's questions and assessments from"
81
              + " GitHub and PrairieLearn, using the launching user's PATs)")
82
  @PreAuthorize("@CourseSecurity.hasManagePermissions(#root, #courseId)")
83
  @PostMapping("/launch/syncCourseWithPlRepo")
84
  public Job launchSyncCourseWithPlRepoJob(
85
      @Parameter(name = "courseId") @RequestParam Long courseId) {
86
87
    Course course =
88
        courseRepository
89
            .findById(courseId)
90 1 1. lambda$launchSyncCourseWithPlRepoJob$0 : replaced return value with null for edu/ucsb/cs/scaffold/controller/JobsController::lambda$launchSyncCourseWithPlRepoJob$0 → KILLED
            .orElseThrow(() -> new EntityNotFoundException(Course.class, courseId));
91
    SyncCourseWithPlRepoJob job =
92
        syncCourseWithPlRepoJobFactory.create(getCurrentUser().getUser().getId(), course);
93 1 1. launchSyncCourseWithPlRepoJob : replaced return value with null for edu/ucsb/cs/scaffold/controller/JobsController::launchSyncCourseWithPlRepoJob → KILLED
    return jobService.runAsJob(job);
94
  }
95
96
  @Operation(
97
      summary =
98
          "Launch ReadPLColors job (read PrairieLearn's badge colors from GitHub and update the"
99
              + " pl_color table, using the launching admin's GitHub PAT)")
100
  @PreAuthorize("hasRole('ROLE_ADMIN')")
101
  @PostMapping("/launch/readPLColors")
102
  public Job launchReadPLColorsJob() {
103
104
    ReadPLColorsJob job =
105
        ReadPLColorsJob.builder()
106
            .userId(getCurrentUser().getUser().getId())
107
            .patCredentialRepository(patCredentialRepository)
108
            .patEncryptionService(patEncryptionService)
109
            .githubService(githubService)
110
            .plColorRepository(plColorRepository)
111
            .build();
112 1 1. launchReadPLColorsJob : replaced return value with null for edu/ucsb/cs/scaffold/controller/JobsController::launchReadPLColorsJob → KILLED
    return jobService.runAsJob(job);
113
  }
114
115
  @Operation(summary = "List jobs by courseId")
116
  @PreAuthorize("@CourseSecurity.hasManagePermissions(#root, #courseId)")
117
  @GetMapping("/course")
118
  public Iterable<Job> jobsByCourse(@Parameter(name = "courseId") @RequestParam Long courseId) {
119 1 1. jobsByCourse : replaced return value with Collections.emptyList for edu/ucsb/cs/scaffold/controller/JobsController::jobsByCourse → KILLED
    return jobsRepository.findByScopeTypeAndScopeIdOrderByIdDesc("course", courseId);
120
  }
121
}

Mutations

60

1.1
Location : launchUpdateAllJob
Killed by : edu.ucsb.cs.scaffold.controller.JobsControllerJobsTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.controller.JobsControllerJobsTests]/[method:admin_can_launch_updateAll_job()]
replaced return value with null for edu/ucsb/cs/scaffold/controller/JobsController::launchUpdateAllJob → KILLED

75

1.1
Location : launchRotatePatKeysJob
Killed by : edu.ucsb.cs.scaffold.controller.JobsControllerJobsTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.controller.JobsControllerJobsTests]/[method:admin_can_launch_rotatePatKeys_job()]
replaced return value with null for edu/ucsb/cs/scaffold/controller/JobsController::launchRotatePatKeysJob → KILLED

90

1.1
Location : lambda$launchSyncCourseWithPlRepoJob$0
Killed by : edu.ucsb.cs.scaffold.controller.JobsControllerJobsTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.controller.JobsControllerJobsTests]/[method:launching_syncCourseWithPlRepo_for_a_missing_course_returns_404()]
replaced return value with null for edu/ucsb/cs/scaffold/controller/JobsController::lambda$launchSyncCourseWithPlRepoJob$0 → KILLED

93

1.1
Location : launchSyncCourseWithPlRepoJob
Killed by : edu.ucsb.cs.scaffold.controller.JobsControllerJobsTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.controller.JobsControllerJobsTests]/[method:instructor_with_course_permissions_can_launch_syncCourseWithPlRepo_job()]
replaced return value with null for edu/ucsb/cs/scaffold/controller/JobsController::launchSyncCourseWithPlRepoJob → KILLED

112

1.1
Location : launchReadPLColorsJob
Killed by : edu.ucsb.cs.scaffold.controller.JobsControllerJobsTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.controller.JobsControllerJobsTests]/[method:admin_can_launch_readPLColors_job()]
replaced return value with null for edu/ucsb/cs/scaffold/controller/JobsController::launchReadPLColorsJob → KILLED

119

1.1
Location : jobsByCourse
Killed by : edu.ucsb.cs.scaffold.controller.JobsControllerJobsTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.controller.JobsControllerJobsTests]/[method:admin_can_get_jobs_by_course()]
replaced return value with Collections.emptyList for edu/ucsb/cs/scaffold/controller/JobsController::jobsByCourse → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0