/** * Sets the current job on the new thread * * @param httpRequest * the HTTP request * @param httpResponse * the HTTP response * @throws IOException * if the error response was not able to be sent */ private void setCurrentJob(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException { String currentJobId = httpRequest.getHeader(CURRENT_JOB_HEADER); try { if (StringUtils.isNotBlank(currentJobId)) { Job currentJob = serviceRegistry.getJob(Long.parseLong(currentJobId)); serviceRegistry.setCurrentJob(currentJob); } } catch (Exception e) { logger.error("Unable to set the current job {}: {}", currentJobId, e); httpResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Was not able to set the current job id {} to the service registry" + currentJobId); } }
private Job findJob(long jobId) throws NotFoundException, IncidentServiceException { try { return getServiceRegistry().getJob(jobId); } catch (NotFoundException e) { logger.info("Job with Id {} does not exist", jobId); throw e; } catch (ServiceRegistryException e) { logger.error("Could not retrieve job {}: {}", jobId, e.getMessage()); throw new IncidentServiceException(e); } }
/** * Record an incident for a given job caused by an uncatched exception. This method is intended to record incidents by * the job system itself, e.g. the job dispatcher. Please note that an incident will <em>only</em> be recorded if none * of severity {@link org.opencastproject.job.api.Incident.Severity#FAILURE} has already been recorded by the job or * one of its child jobs. If no job with the given job id exists nothing happens. */ public void unhandledException(long jobId, Severity severity, Throwable t) { try { unhandledException(sr.getJob(jobId), severity, t); } catch (NotFoundException ignore) { } catch (ServiceRegistryException e) { logException(e); } }
@GET @Path("job/{id}.json") @Produces(MediaType.APPLICATION_JSON) @RestQuery(name = "jobasjson", description = "Returns a job as JSON.", returnDescription = "The job as JSON", pathParameters = { @RestParameter(name = "id", isRequired = true, type = Type.STRING, description = "The job identifier") }, reponses = { @RestResponse(responseCode = SC_OK, description = "Job found."), @RestResponse(responseCode = SC_NOT_FOUND, description = "No job with that identifier exists.") }) public JaxbJob getJobAsJson(@PathParam("id") long id) throws NotFoundException { try { return new JaxbJob(serviceRegistry.getJob(id)); } catch (ServiceRegistryException e) { throw new WebApplicationException(e); } }
job = getServiceRegistry().getJob(jobId); } catch (NotFoundException e) { logger.warn("Unable to find dispatched job {}", jobId);
/** * Get the latest state of a job. Does not modify the <code>job</code> parameter. * * @return the updated job or none, if it cannot be found */ public static Opt<Job> update(ServiceRegistry reg, Job job) throws ServiceRegistryException { try { return Opt.some(reg.getJob(job.getId())); } catch (NotFoundException e) { return Opt.none(); } }
private void handleFailedProcessing(final Throwable t) throws Exception { if (t instanceof JobCanceledException) { logger.info(t.getMessage()); } else { Job jobAfterProcessing = getServiceRegistry().getJob(jobId); jobAfterProcessing.setStatus(Status.FAILED); jobAfterProcessing = getServiceRegistry().updateJob(jobAfterProcessing); getServiceRegistry().incident().unhandledException(jobAfterProcessing, Severity.FAILURE, t); logger.error("Error handling operation '{}': {}", jobAfterProcessing.getOperation(), getStackTrace(t)); if (t instanceof ServiceRegistryException) throw (ServiceRegistryException) t; } }
final Job processedJob = serviceRegistry.getJob(job.getId()); final Job.Status jobStatus = processedJob.getStatus(); switch (jobStatus) {
private void wakeWaiterJob() { if (this.waiterJobId.isSome()) { try { final Job waiter = serviceRegistry.getJob(waiterJobId.get()); waiter.setStatus(Job.Status.RUNNING); for (Job j : jobs) { Job updatedJob = this.serviceRegistry.getJob(j.getId()); updatedJob.removeBlockingJobId(); // FYI not updating local j in jobs collection this.serviceRegistry.updateJob(updatedJob); } waiter.removeBlockedJobsIds(); this.serviceRegistry.updateJob(waiter); } catch (ServiceRegistryException e) { logger.warn("Unable to put {} into a waiting state, this may cause a deadlock: {}", waiterJobId, e.getMessage()); } catch (NotFoundException e) { logger.warn("Unable to put {} into a waiting state, job not found by the service registry. This may cause a deadlock: {}", waiterJobId, e.getMessage()); } } else { logger.debug("No waiting job set, unable to put waiting job into waiting state"); } }
@Override public Incident storeIncident(Job job, Date timestamp, String code, Incident.Severity severity, Map<String, String> descriptionParameters, List<Tuple<String, String>> details) throws IncidentServiceException, IllegalStateException { try { job = getServiceRegistry().getJob(job.getId()); final IncidentDto dto = getPenv().tx( Queries.persist(IncidentDto.mk(job.getId(), timestamp, code, severity, descriptionParameters, details))); return toIncident(job, dto); } catch (NotFoundException e) { throw new IllegalStateException("Can't create incident for not-existing job"); } catch (Exception e) { logger.error("Could not store job incident: {}", e.getMessage()); throw new IncidentServiceException(e); } }
private void handleSuccessfulProcessing(final String payload) throws Exception { // The job may gets updated internally during processing. It therefore needs to be reload from the service // registry in order to prevent inconsistencies. final Job jobAfterProcessing = getServiceRegistry().getJob(jobId); jobAfterProcessing.setPayload(payload); jobAfterProcessing.setStatus(Status.FINISHED); getServiceRegistry().updateJob(jobAfterProcessing); }
private void suspendWaiterJob() { if (this.waiterJobId.isSome()) { try { final Job waiter = serviceRegistry.getJob(waiterJobId.get()); waiter.setStatus(Job.Status.WAITING); List<Long> blockedForJobs = new LinkedList<Long>(); for (Job j : jobs) { try { if (setBlockerJob(j, waiter)) { blockedForJobs.add(j.getId()); } } catch (OptimisticLockException e) { // Try again, this happens if the job finishes before we get here // If the same exception happens again then we're in a very weird state if (setBlockerJob(j, waiter)) { blockedForJobs.add(j.getId()); } } } waiter.setBlockedJobIds(blockedForJobs); this.serviceRegistry.updateJob(waiter); } catch (ServiceRegistryException e) { logger.warn("Unable to put {} into a waiting state, this may cause a deadlock: {}", waiterJobId, e.getMessage()); } catch (NotFoundException e) { logger.warn("Unable to put {} into a waiting state, job not found by the service registry. This may cause a deadlock: {}", waiterJobId, e.getMessage()); } } else { logger.debug("No waiting job set, unable to put waiting job into waiting state"); } }
/** * Sets j's blocking job ID (ie, the job which it is blocking) to waiter's ID * @param j * The job doing the blocking * @param waiter * The job blocking, waiting for its child to finish * @return * True if j is an active job and has been successfully updated, false if it is not an active job * @throws ServiceRegistryException * @throws NotFoundException */ private boolean setBlockerJob(Job j, Job waiter) throws ServiceRegistryException, NotFoundException { Job blockerJob = this.serviceRegistry.getJob(j.getId()); if (j.getStatus().isActive()) { blockerJob.setBlockingJobId(waiter.getId()); // FYI not updating local j in jobs collection this.serviceRegistry.updateJob(blockerJob); return true; } else { return false; } }
@Override public IncidentTree getIncidentsOfJob(long jobId, boolean cascade) throws NotFoundException, IncidentServiceException { List<Incident> incidents = getIncidentsOfJob(jobId); List<IncidentTree> childIncidents = new ArrayList<IncidentTree>(); try { Job job = getServiceRegistry().getJob(jobId); if (cascade && !"START_WORKFLOW".equals(job.getOperation())) { childIncidents = getChildIncidents(jobId); } else if (cascade && "START_WORKFLOW".equals(job.getOperation())) { for (WorkflowOperationInstance operation : getWorkflowService().getWorkflowById(jobId).getOperations()) { if (operation.getState().equals(OperationState.INSTANTIATED)) continue; IncidentTree operationResult = getIncidentsOfJob(operation.getId(), true); if (hasIncidents(Collections.list(operationResult))) childIncidents.add(operationResult); } } return new IncidentTreeImpl(incidents, childIncidents); } catch (NotFoundException ignore) { // Workflow deleted return new IncidentTreeImpl(incidents, childIncidents); } catch (Exception e) { logger.error("Error loading child jobs of {}: {}", jobId); throw new IncidentServiceException(e); } }
@Override public Void call() throws Exception { final SecurityService securityService = getSecurityService(); final ServiceRegistry serviceRegistry = getServiceRegistry(); final Job jobBeforeProcessing = serviceRegistry.getJob(jobId); if (currentJobId.isSome()) serviceRegistry.setCurrentJob(serviceRegistry.getJob(currentJobId.get())); final Organization organization = getOrganizationDirectoryService() .getOrganization(jobBeforeProcessing.getOrganization()); securityService.setOrganization(organization); final User user = getUserDirectoryService().loadUser(jobBeforeProcessing.getCreator()); securityService.setUser(user); try { final String payload = process(jobBeforeProcessing); handleSuccessfulProcessing(payload); } catch (Throwable t) { handleFailedProcessing(t); } finally { serviceRegistry.setCurrentJob(null); securityService.setUser(null); securityService.setOrganization(null); } return null; }