JobService.java

1
package edu.ucsb.cs156.frontiers.services.jobs;
2
3
import edu.ucsb.cs156.frontiers.entities.Job;
4
import edu.ucsb.cs156.frontiers.repositories.JobsRepository;
5
import edu.ucsb.cs156.frontiers.services.CurrentUserService;
6
import lombok.extern.slf4j.Slf4j;
7
import org.springframework.beans.factory.annotation.Autowired;
8
import org.springframework.context.annotation.Lazy;
9
import org.springframework.scheduling.annotation.Async;
10
import org.springframework.stereotype.Service;
11
import org.springframework.transaction.support.TransactionTemplate;
12
13
@Service
14
@Slf4j
15
public class JobService {
16
  @Autowired private JobsRepository jobsRepository;
17
18
  @Autowired private CurrentUserService currentUserService;
19
20
  @Autowired private JobContextFactory contextFactory;
21
22
  /*
23
   * This is a self-referential bean to allow for async method calls within the same class.
24
   */
25
  @Lazy @Autowired private JobService self;
26
  @Autowired private TransactionTemplate transactionTemplate;
27
28
  public Job runAsJob(JobContextConsumer jobFunction) {
29
    String jobName = jobFunction.getClass().getName().replace("edu.ucsb.cs156.frontiers.jobs.", "");
30
31
    Job job =
32
        Job.builder()
33
            .createdBy(currentUserService.getUser())
34
            .status("running")
35
            .jobName(jobName)
36
            .course(jobFunction.getCourse())
37
            .build();
38
39
    log.info("Starting job: {}, jobName={}", job.getId(), job.getJobName());
40
41
    jobsRepository.save(job);
42 1 1. runAsJob : removed call to edu/ucsb/cs156/frontiers/services/jobs/JobService::runJobAsync → KILLED
    self.runJobAsync(job, jobFunction);
43
44 1 1. runAsJob : replaced return value with null for edu/ucsb/cs156/frontiers/services/jobs/JobService::runAsJob → KILLED
    return job;
45
  }
46
47
  /**
48
   * Runs a job asynchronously.
49
   *
50
   * <p>This method uses a TransactionTemplate because outside of the Spring context, you cannot
51
   * delete entities that are unmanaged by Hibernate. Using the transactionTemplate lambda keeps the
52
   * database session open and allows Hibernate to maintain it's knowledge of the object graph (i.e.
53
   * the entities)
54
   *
55
   * <p>To learn more, read about Hibernate and the concept of a Spring Context.
56
   *
57
   * <p>Note that using the transactionTemplate lambda means that if there is an unhandled
58
   * exception, either every database transactions succeeds, or all of them are rolled back.
59
   *
60
   * <p>However, the job entity metadata will still be saved.
61
   *
62
   * @param job metadata entity about the job
63
   * @param jobFunction runnable job function
64
   */
65
  @Async
66
  public void runJobAsync(Job job, JobContextConsumer jobFunction) {
67
    JobContext context = contextFactory.createContext(job);
68
69
    try {
70 1 1. runJobAsync : removed call to org/springframework/transaction/support/TransactionTemplate::executeWithoutResult → KILLED
      transactionTemplate.executeWithoutResult(
71
          status -> {
72
            try {
73
              jobFunction.accept(context);
74
              /*lambdas cannot throw checked exceptions
75
              have to repackage as a runtime exception
76
              to catch outside transactional boundary*/
77
            } catch (Exception e) {
78
              throw new RuntimeException(e);
79
            }
80
          });
81
    } catch (Exception e) {
82 1 1. runJobAsync : removed call to edu/ucsb/cs156/frontiers/entities/Job::setStatus → KILLED
      job.setStatus("error");
83
      context.log(e.getMessage());
84
      return;
85
    }
86
87 1 1. runJobAsync : removed call to edu/ucsb/cs156/frontiers/entities/Job::setStatus → KILLED
    job.setStatus("complete");
88
    jobsRepository.save(job);
89
  }
90
91
  public String getJobLogs(Long jobId) {
92
    Job job =
93
        jobsRepository
94
            .findById(jobId)
95 1 1. lambda$getJobLogs$1 : replaced return value with null for edu/ucsb/cs156/frontiers/services/jobs/JobService::lambda$getJobLogs$1 → KILLED
            .orElseThrow(() -> new IllegalArgumentException("Job not found"));
96
97
    String log = job.getLog();
98 1 1. getJobLogs : negated conditional → KILLED
    return log != null ? log : "";
99
  }
100
}

Mutations

42

1.1
Location : runAsJob
Killed by : edu.ucsb.cs156.frontiers.services.JobServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.services.JobServiceTests]/[method:runAsJob_fires_correctly()]
removed call to edu/ucsb/cs156/frontiers/services/jobs/JobService::runJobAsync → KILLED

44

1.1
Location : runAsJob
Killed by : edu.ucsb.cs156.frontiers.services.JobServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.services.JobServiceTests]/[method:runAsJob_fires_correctly()]
replaced return value with null for edu/ucsb/cs156/frontiers/services/jobs/JobService::runAsJob → KILLED

70

1.1
Location : runJobAsync
Killed by : edu.ucsb.cs156.frontiers.services.JobServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.services.JobServiceTests]/[method:runAsyncJob_fires_correctly()]
removed call to org/springframework/transaction/support/TransactionTemplate::executeWithoutResult → KILLED

82

1.1
Location : runJobAsync
Killed by : edu.ucsb.cs156.frontiers.services.JobServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.services.JobServiceTests]/[method:runAsyncJob_handles_error()]
removed call to edu/ucsb/cs156/frontiers/entities/Job::setStatus → KILLED

87

1.1
Location : runJobAsync
Killed by : edu.ucsb.cs156.frontiers.services.JobServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.services.JobServiceTests]/[method:runAsyncJob_fires_correctly()]
removed call to edu/ucsb/cs156/frontiers/entities/Job::setStatus → KILLED

95

1.1
Location : lambda$getJobLogs$1
Killed by : edu.ucsb.cs156.frontiers.services.JobServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.services.JobServiceTests]/[method:test_getJobLogs_job_not_found()]
replaced return value with null for edu/ucsb/cs156/frontiers/services/jobs/JobService::lambda$getJobLogs$1 → KILLED

98

1.1
Location : getJobLogs
Killed by : edu.ucsb.cs156.frontiers.services.JobServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.services.JobServiceTests]/[method:test_getJobLogs_with_null_log()]
negated conditional → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0