@Override public Job animate(URI animation, Map<String, String> metadata, List<String> arguments) throws AnimateServiceException { Gson gson = new Gson(); List<String> jobArguments = Arrays.asList(animation.toString(), gson.toJson(metadata), gson.toJson(arguments)); try { logger.debug("Create animate service job"); return serviceRegistry.createJob(JOB_TYPE, OPERATION, jobArguments, jobLoad); } catch (ServiceRegistryException e) { throw new AnimateServiceException(e); } }
/** * {@inheritDoc} * * @see org.opencastproject.job.api.JobProducer#acceptJob(org.opencastproject.job.api.Job) */ @Override public void acceptJob(final Job job) throws ServiceRegistryException { final Job runningJob; try { job.setStatus(Job.Status.RUNNING); runningJob = getServiceRegistry().updateJob(job); } catch (NotFoundException e) { throw new IllegalStateException(e); } executor.submit(new JobRunner(runningJob, getServiceRegistry().getCurrentJob())); }
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); }
/** * 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 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; } }
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); } }
maxload = getServiceRegistry().getMaxLoadOnNode(getServiceRegistry().getRegistryHostname()); } catch (NotFoundException e) { throw new ServiceRegistryException(e); float currentLoad = getServiceRegistry().getOwnLoad(); logger.debug("{} Current load on this host: {}, job's load: {}, job's status: {}, max load: {}", Thread.currentThread().getId(), currentLoad, job.getJobLoad(), job.getStatus().name(),
@GET @Path("count") @Produces(MediaType.TEXT_PLAIN) @RestQuery(name = "count", description = "Returns the number of jobs matching the query parameters as plain text.", returnDescription = "The number of matching jobs", restParameters = { @RestParameter(name = "serviceType", isRequired = false, type = Type.STRING, description = "The service type identifier"), @RestParameter(name = "status", isRequired = false, type = Type.STRING, description = "The job status"), @RestParameter(name = "host", isRequired = false, type = Type.STRING, description = "The host executing the job"), @RestParameter(name = "operation", isRequired = false, type = Type.STRING, description = "The job's operation") }, reponses = { @RestResponse(responseCode = SC_OK, description = "Job count returned.") }) public long count(@QueryParam("serviceType") String serviceType, @QueryParam("status") Job.Status status, @QueryParam("host") String host, @QueryParam("operation") String operation) { try { if (isNotBlank(host) && isNotBlank(operation)) { if (isBlank(serviceType)) throw new WebApplicationException(Response.serverError().entity("Service type must not be null").build()); return serviceRegistry.count(serviceType, host, operation, status); } else if (isNotBlank(host)) { if (isBlank(serviceType)) throw new WebApplicationException(Response.serverError().entity("Service type must not be null").build()); return serviceRegistry.countByHost(serviceType, host, status); } else if (isNotBlank(operation)) { if (isBlank(serviceType)) throw new WebApplicationException(Response.serverError().entity("Service type must not be null").build()); return serviceRegistry.countByOperation(serviceType, operation, status); } else { return serviceRegistry.count(serviceType, status); } } catch (ServiceRegistryException e) { throw new WebApplicationException(e); } }
Float jobLoad = Float.parseFloat(request.getParameter("jobLoad")); job = ((ServiceRegistryJpaImpl) serviceRegistry).createJob(host, jobType, operation, arguments, payload, start, serviceRegistry.getCurrentJob(), jobLoad); } else { job = ((ServiceRegistryJpaImpl) serviceRegistry).createJob(host, jobType, operation, arguments, payload, start, serviceRegistry.getCurrentJob());
@GET @Path("maxload") @Produces(MediaType.TEXT_XML) @RestQuery(name = "maxload", description = "Returns the maximum load that servers in this service registry can execute concurrently. " + "If there is only one server in this service registry this will be the maximum load that one server is able to handle at one time. " + "If it is a distributed install across many servers then this number will be the maximum load the cluster can process concurrently.", returnDescription = "The maximum load of the cluster or server", restParameters = { @RestParameter(name = "host", isRequired = false, type = Type.STRING, description = "The host you want to know the maximum load for.") }, reponses = { @RestResponse(responseCode = SC_OK, description = "Maximum load for the cluster.") }) public Response getMaxLoadOnNode(@QueryParam("host") String host) throws NotFoundException { try { if (StringUtils.isEmpty(host)) { return Response.ok(serviceRegistry.getMaxLoads()).build(); } else { SystemLoad systemLoad = new SystemLoad(); systemLoad.addNodeLoad(serviceRegistry.getMaxLoadOnNode(host)); return Response.ok(systemLoad).build(); } } catch (ServiceRegistryException e) { throw new WebApplicationException(e); } }
/** Shorthand for {@link #getServiceRegistry()}.incident() */ public Incidents incident() { return getServiceRegistry().incident(); }
public static float getConfiguredLoadValue(@SuppressWarnings("rawtypes") Dictionary bundleProperties, String configKey, Float defaultValue, ServiceRegistry registry) { String jobLoad = StringUtils.trimToNull((String) bundleProperties.get(configKey)); float loadValue = defaultValue; if (jobLoad != null) { try { loadValue = Float.parseFloat(jobLoad); if (loadValue < 0) { logger.warn("Load value for key {} set to less than 0, defaulting to 0", configKey); loadValue = 0.0f; } logger.info("Set load for key {} to {}", configKey, loadValue); } catch (NumberFormatException e) { logger.warn("Can not set job loads to {}. {} must be a float", jobLoad, configKey); loadValue = defaultValue; logger.info("Set load for key {} to default of {}", configKey, loadValue); } } else { logger.info("No job load configuration found for key {}, load to default of {}", configKey, loadValue); } try { checkJobFitsCluster(loadValue, configKey, registry.getHostRegistrations()); } catch (ServiceRegistryException e) { logger.warn("Unable to verify that {} will run on this cluster due to load of {}", configKey, loadValue); } return loadValue; }
@GET @Path("available.xml") @Produces(MediaType.TEXT_XML) @RestQuery(name = "availableasxml", description = "Lists available services by service type identifier, ordered by load.", returnDescription = "The services list as XML", restParameters = { @RestParameter(name = "serviceType", isRequired = false, type = Type.STRING, description = "The service type identifier") }, reponses = { @RestResponse(responseCode = SC_OK, description = "Returned the available services."), @RestResponse(responseCode = SC_BAD_REQUEST, description = "No service type specified, bad request.") }) public Response getAvailableServicesAsXml(@QueryParam("serviceType") String serviceType) { if (isBlank(serviceType)) throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity("Service type must be specified") .build()); JaxbServiceRegistrationList registrations = new JaxbServiceRegistrationList(); try { for (ServiceRegistration reg : serviceRegistry.getServiceRegistrationsByLoad(serviceType)) { registrations.add(new JaxbServiceRegistration(reg)); } return Response.ok(registrations).build(); } catch (ServiceRegistryException e) { throw new WebApplicationException(e); } }
@GET @Path("ownload") @Produces(MediaType.TEXT_PLAIN) @RestQuery(name = "ownload", description = "Returns the current load on this service registry's node.", returnDescription = "The current load across the cluster", restParameters = {}, reponses = { @RestResponse(responseCode = SC_OK, description = "Current load for the cluster.") }) public Response getOwnLoad() { try { return Response.ok(serviceRegistry.getOwnLoad()).build(); } catch (ServiceRegistryException e) { throw new WebApplicationException(e); } }
/** * {@inheritDoc} * * @see org.opencastproject.job.api.JobProducer#countJobs(org.opencastproject.job.api.Job.Status) */ @Override public long countJobs(Status status) throws ServiceRegistryException { if (status == null) throw new IllegalArgumentException("Status must not be null"); return getServiceRegistry().count(getJobType(), status); }
/** * 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); } }
@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; }
httpUriRequest.setHeader(SecurityConstants.AUTHORIZATION_HEADER, "true"); if (serviceRegistry != null && serviceRegistry.getCurrentJob() != null) { httpUriRequest.setHeader(CURRENT_JOB_HEADER, Long.toString(serviceRegistry.getCurrentJob().getId()));
@Override public WorkflowOperationResult start(WorkflowInstance wi, JobContext ctx) throws WorkflowOperationException { final WorkflowOperationInstance woi = wi.getCurrentOperation(); final int code = option(woi.getConfiguration(OPT_CODE)).bind(Strings.toInt).getOrElse(1); final Severity severity = option(woi.getConfiguration(OPT_SEVERITY)).bind(parseEnum(Severity.FAILURE)).getOrElse(Severity.INFO); final List<Tuple<String, String>> details = Arrays.stream(ArrayUtils.nullToEmpty( StringUtils.split(woi.getConfiguration(OPT_DETAILS), ";"))) .map((opt) -> opt.split("=")) .filter((t) -> t.length == 2) .map((x) -> Tuple.tuple(x[0], x[1])) .collect(Collectors.toList()); final Map<String, String> params = Arrays.stream(ArrayUtils.nullToEmpty( StringUtils.split(woi.getConfiguration(OPT_PARAMS), ";"))) .map((opt) -> opt.split("=")) .filter((t) -> t.length == 2) .collect(Collectors.toMap(x -> x[0], x -> x[1])); log.info("Create nop job"); final Job job = nopService.nop(); log.info("Log a dummy incident with code %d", code); serviceRegistry.incident().record(job, severity, code, params, details); if (!waitForStatus(job).isSuccess()) { throw new WorkflowOperationException("Job did not complete successfully"); } else { return createResult(WorkflowOperationResult.Action.CONTINUE); } }
@GET @Path("hosts.xml") @Produces(MediaType.TEXT_XML) @RestQuery(name = "hostsasxml", description = "Returns a host registraton or list of available host registrations as XML.", returnDescription = "The host list as XML", reponses = { @RestResponse(responseCode = SC_OK, description = "Returned the available hosts.") }) public JaxbHostRegistrationList getHostsAsXml() throws NotFoundException { JaxbHostRegistrationList registrations = new JaxbHostRegistrationList(); try { for (HostRegistration reg : serviceRegistry.getHostRegistrations()) registrations.add(new JaxbHostRegistration(reg)); return registrations; } catch (ServiceRegistryException e) { throw new WebApplicationException(e); } }