JobResource { @ApiOperation( value = "cancels the job associated with the specified job ID", response = AsyncJobStatusDTO.class) @ApiResponses({ @ApiResponse(code = 400, message = ""), @ApiResponse(code = 404, message = "") }) @DELETE @Path("/{job_id}") @Produces(MediaType.APPLICATION_JSON) @Transactional public AsyncJobStatusDTO cancelJob( @PathParam("job_id") @Verify(AsyncJobStatus.class) String jobId) { if (jobId == null || jobId.isEmpty()) { String errmsg = this.i18n.tr("Job ID is null or empty"); throw new BadRequestException(errmsg); } try { AsyncJobStatus status = this.jobManager.cancelJob(jobId); if (status == null) { String errmsg = this.i18n.tr("No job status found associated with the given job ID: {0}", jobId); throw new NotFoundException(errmsg); } return this.translator.translate(status, AsyncJobStatusDTO.class); } catch (IllegalStateException e) { String errmsg = this.i18n.tr("Job {0} is already in a terminal state or otherwise cannot be " + "canceled at this time", jobId); throw new BadRequestException(errmsg, e); } } @Inject  JobResource(Configuration config, I18n i18n, ModelTranslator translator, JobManager jobManager,
        AsyncJobStatusCurator jobCurator, OwnerCurator ownerCurator); @ApiOperation( value = "fetches the status of the job scheduler for this Candlepin node", response = SchedulerStatusDTO.class) @ApiResponses({ @ApiResponse(code = 400, message = ""), @ApiResponse(code = 404, message = "") }) @GET @Path("/scheduler") @Produces(MediaType.APPLICATION_JSON) @Transactional SchedulerStatusDTO getSchedulerStatus(); @ApiOperation( value = "enables or disables the job scheduler for this Candlepin node", response = SchedulerStatusDTO.class) @ApiResponses({ @ApiResponse(code = 400, message = ""), @ApiResponse(code = 404, message = "") }) @POST @Path("/scheduler") @Produces(MediaType.APPLICATION_JSON) @Transactional SchedulerStatusDTO setSchedulerStatus(
        @QueryParam("running") @DefaultValue("true") boolean running); @ApiOperation( value = "fetches a set of job statuses matching the given filter options", response = AsyncJobStatusDTO.class, responseContainer = "set") @ApiResponses({ @ApiResponse(code = 400, message = ""), @ApiResponse(code = 404, message = "") }) @GET @Path("/") @Produces(MediaType.APPLICATION_JSON) @Transactional Stream<AsyncJobStatusDTO> listJobStatuses(
        @QueryParam("id") Set<String> ids,
        @QueryParam("key") Set<String> keys,
        @QueryParam("state") Set<String> states,
        @QueryParam("owner") Set<String> ownerKeys,
        @QueryParam("principal") Set<String> principals,
        @QueryParam("origin") Set<String> origins,
        @QueryParam("executor") Set<String> executors,
        @QueryParam("after") @DateFormat Date after,
        @QueryParam("before") @DateFormat Date before); @ApiOperation( value = "fetches the job status associated with the specified job ID", response = AsyncJobStatusDTO.class) @ApiResponses({ @ApiResponse(code = 400, message = ""), @ApiResponse(code = 404, message = "") }) @GET @Path("/{job_id}") @Produces(MediaType.APPLICATION_JSON) @Transactional AsyncJobStatusDTO getJobStatus(
        @PathParam("job_id") @Verify(AsyncJobStatus.class) String jobId); @ApiOperation( value = "cancels the job associated with the specified job ID", response = AsyncJobStatusDTO.class) @ApiResponses({ @ApiResponse(code = 400, message = ""), @ApiResponse(code = 404, message = "") }) @DELETE @Path("/{job_id}") @Produces(MediaType.APPLICATION_JSON) @Transactional AsyncJobStatusDTO cancelJob(
        @PathParam("job_id") @Verify(AsyncJobStatus.class) String jobId); @ApiOperation( value = "cleans up terminal jobs matching the provided criteria", response = AsyncJobStatusDTO.class) @ApiResponses({ @ApiResponse(code = 400, message = ""), @ApiResponse(code = 404, message = "") }) @DELETE @Path("/") @Produces(MediaType.APPLICATION_JSON) @Transactional int cleanupTerminalJobs(
        @QueryParam("id") Set<String> ids,
        @QueryParam("key") Set<String> keys,
        @QueryParam("state") Set<String> states,
        @QueryParam("owner") Set<String> ownerKeys,
        @QueryParam("principal") Set<String> principals,
        @QueryParam("origin") Set<String> origins,
        @QueryParam("executor") Set<String> executors,
        @QueryParam("after") @DateFormat Date after,
        @QueryParam("before") @DateFormat Date before,
        @QueryParam("force") @DefaultValue("false") boolean force); @ApiOperation( value = "schedules a job using the specified key and job properties", response = AsyncJobStatusDTO.class) @ApiResponses({ @ApiResponse(code = 400, message = ""), @ApiResponse(code = 404, message = "") }) @POST @Path("schedule/{job_key}") @Produces(MediaType.APPLICATION_JSON) @Transactional AsyncJobStatusDTO scheduleJob(
        @PathParam("job_key") String jobKey);  }
@Test public void testCancelJob() { String jobId = "test_job_id"; AsyncJobStatus status = mock(AsyncJobStatus.class); doReturn(jobId).when(status).getId(); doReturn(status).when(this.jobManager).cancelJob(eq(jobId)); JobResource resource = this.buildJobResource(); AsyncJobStatusDTO output = resource.cancelJob(jobId); assertNotNull(output); assertEquals(jobId, output.getId()); verify(this.jobManager, times(1)).cancelJob(eq(jobId)); }
@Test public void testCancelJobWithBadId() { String jobId = "bad_job_id"; JobResource resource = this.buildJobResource(); assertThrows(NotFoundException.class, () -> resource.cancelJob(jobId)); }
@Test public void testCancelJobInTerminalState() { String jobId = "test_job_id"; doThrow(new IllegalStateException()).when(this.jobManager).cancelJob(eq(jobId)); JobResource resource = this.buildJobResource(); assertThrows(BadRequestException.class, () -> resource.cancelJob(jobId)); }