agave-jobs/jobs-core/src/main/java/org/iplantc/service/jobs/callbacks/JobCallbackManager.java
/**
     * Handles custom runtime {@link Job} job events thrown from running jobs 
     * as POST requests. The requests contain a JSON object which gets propagated 
     * to any notifications sent to the user.
     *  
     * @param callback
     * @param customRuntimeJsonBody
     * @return the updated job
     * @throws JobCallbackException
     * @throws ObjectNotFoundException
     * @throws FileNotFoundException
     * @throws JobException
     */
Handles custom runtime  Job job events thrown from running jobs
as POST requests. The requests contain a JSON object which gets propagated
to any notifications sent to the user.


Handles custom runtime Job job events thrown from running jobs as POST requests . The requests contain a JSON object which gets propagated to any notifications sent to the user .
public Job processCustomRuntimeEvent(JobCallback callback, JsonNode customRuntimeJsonBody) 
    throws JobCallbackException, ObjectNotFoundException, FileNotFoundException, JobException
    {
    	if (callback == null) {
            throw new JobCallbackException("Callback cannot be null.");
        }
        Job job = callback.getJob();
        if (job == null) {
            throw new ObjectNotFoundException(null, "No job found with given id");
        } 
        else if (!job.isVisible()) {
            throw new JobCallbackException("Failed to process callback. Job has already been deleted.");
        }
        else if (!job.isRunning()) {
            throw new JobCallbackException("Job " + job.getUuid() + " is not running.");
        }
        else {
            TenancyHelper.setCurrentEndUser(job.getOwner());
            TenancyHelper.setCurrentTenantId(job.getTenantId());
            JobStatusType status = callback.getStatus();
            if (customRuntimeJsonBody == null) {
            	throw new JobCallbackException("Empty JSON callback content found.");
            }
            else if (StringUtils.length(customRuntimeJsonBody.toString()) > 5120) {
            	throw new JobCallbackException("Message content exceeds the maximum " +
        				"callback message size of 10KB");
    	    }
            else if (status == HEARTBEAT) 
            {
                log.debug("Job " + job.getUuid() + 
                		" received custom runtime event notification for job " + 
                		callback.getJob().getUuid());
                if (!customRuntimeJsonBody.isObject()) {
                	throw new JobCallbackException("Callback content is not a valid JSON object.");
                }
                else if (!customRuntimeJsonBody.hasNonNull("CUSTOM_USER_JOB_EVENT_NAME")) {
                	throw new JobCallbackException("Malformed JSON callback content found.");
                }
                else {
                	String customEventName = customRuntimeJsonBody.get("CUSTOM_USER_JOB_EVENT_NAME").asText();
                	if (isReservedEventName(customEventName)) {
                		throw new JobCallbackException("Illegal runtime event name. " + customEventName + 
                				" is reserved for internally generated events.");
                	}
                	else {
	                	JobEvent event = new JobEvent(customEventName, 
	                			"A custom runtime " + customEventName + " event was received for job " + 
	                					job.getUuid(), job.getOwner());
	                	event.setJob(job);
		                job.getEvents().add(event);
		                JobDao.persist(job);
		                JobEventProcessor eventProcessor;
						try {
							eventProcessor = new JobEventProcessor(event);
							eventProcessor.processJobRuntimeCallbackEvent(customRuntimeJsonBody);
							return job;
						} 
						catch (JobEventProcessingException e) {
							throw new JobCallbackException(e.getMessage(), e);
						}
                	}
                }
            }
            else {
            	throw new FileNotFoundException("Illegal job callback reqeust.");
            }
        }
    }
public Job processCustomRuntimeEvent ( JobCallback callback , JsonNode customRuntimeJsonBody ) throws JobCallbackException , ObjectNotFoundException , FileNotFoundException , JobException { if ( callback == null ) { throw new JobCallbackException ( "Callback cannot be null." ) ; } Job job = callback . getJob ( ) ; if ( job == null ) { throw new ObjectNotFoundException ( null , "No job found with given id" ) ; } else if ( ! job . isVisible ( ) ) { throw new JobCallbackException ( "Failed to process callback. Job has already been deleted." ) ; } else if ( ! job . isRunning ( ) ) { throw new JobCallbackException ( "Job " + job . getUuid ( ) + " is not running." ) ; } else { TenancyHelper . setCurrentEndUser ( job . getOwner ( ) ) ; TenancyHelper . setCurrentTenantId ( job . getTenantId ( ) ) ; JobStatusType status = callback . getStatus ( ) ; if ( customRuntimeJsonBody == null ) { throw new JobCallbackException ( "Empty JSON callback content found." ) ; } else if ( StringUtils . length ( customRuntimeJsonBody . toString ( ) ) > 5120 ) { throw new JobCallbackException ( "Message content exceeds the maximum " + "callback message size of 10KB" ) ; } else if ( status == HEARTBEAT ) { log . debug ( "Job " + job . getUuid ( ) + " received custom runtime event notification for job " + callback . getJob ( ) . getUuid ( ) ) ; if ( ! customRuntimeJsonBody . isObject ( ) ) { throw new JobCallbackException ( "Callback content is not a valid JSON object." ) ; } else if ( ! customRuntimeJsonBody . hasNonNull ( "CUSTOM_USER_JOB_EVENT_NAME" ) ) { throw new JobCallbackException ( "Malformed JSON callback content found." ) ; } else { String customEventName = customRuntimeJsonBody . get ( "CUSTOM_USER_JOB_EVENT_NAME" ) . asText ( ) ; if ( isReservedEventName ( customEventName ) ) { throw new JobCallbackException ( "Illegal runtime event name. " + customEventName + " is reserved for internally generated events." ) ; } else { JobEvent event = new JobEvent ( customEventName , "A custom runtime " + customEventName + " event was received for job " + job . getUuid ( ) , job . getOwner ( ) ) ; event . setJob ( job ) ; job . getEvents ( ) . add ( event ) ; JobDao . persist ( job ) ; JobEventProcessor eventProcessor ; try { eventProcessor = new JobEventProcessor ( event ) ; eventProcessor . processJobRuntimeCallbackEvent ( customRuntimeJsonBody ) ; return job ; } catch ( JobEventProcessingException e ) { throw new JobCallbackException ( e . getMessage ( ) , e ) ; } } } } else { throw new FileNotFoundException ( "Illegal job callback reqeust." ) ; } } }
Handles custom runtime {@link Job} job events thrown from running jobs
 as POST requests.
Handles custom runtime { @link Job } job events thrown from running jobs as POST requests .
// unknown job. no callback will be thrown // deleted jobs have their runtime callbacks disabled // runtime callbacks are only valid on running jobs // job is running and valid // we're not processing empty messages. they can use heartbeats for that // verify file size does not exceed 5120 characters, ie. 10KB // heartbeats need to set an event, but they do not update the job status. // response should be a json ojbect // malformed json. no event was in body // seems like valid json. process the event as a custom runtime event on the job