/** * Finalizes a {@code Job} execution by a given context in which the job was performed and by the * exit status of the step. If the {@code Job} execution continues beyond the scope of the * command, the {@code Job.isAsyncJob()} should be set to {@code true}. If {@code * ExecutionMethod.AsStep} is defined, the current active step can end the running {@code Job} by * setting the {@ExecutionContext.shouldEndJob()} to {@code true}. * * @param executionContext The context of the execution which defines how the job should be ended * @param exitStatus Indicates if the execution described by the job ended successfully or not. */ public static void endJob(ExecutionContext context, boolean exitStatus) { if (context == null) { return; } Job job = context.getJob(); try { if (context.isMonitored()) { if (context.getExecutionMethod() == ExecutionMethod.AsJob && job != null) { if (context.shouldEndJob() || !(job.isAsyncJob() && exitStatus)) { context.setCompleted(true); endJob(exitStatus, job); } } else { Step step = context.getStep(); if (context.getExecutionMethod() == ExecutionMethod.AsStep && step != null) { if (context.shouldEndJob()) { if (job == null) { job = JobRepositoryFactory.getJobRepository().getJob(step.getJobId()); } if (job != null) { context.setCompleted(true); endJob(exitStatus, job); } } } } } } catch (Exception e) { log.error(e); } }
/** * Prepares the monitoring objects for the command by the default behavior: * * <ul> * <li>{@link ExecutionContext} determines how the command should be monitored. By default, * non-internal commands will be associated with {@code Job} to represent the command * execution. Internal commands will not be monitored by default, therefore the {@code * ExecutionContext} is created as non-monitored context. * <li>{@link Job} is created for monitored actions * </ul> * * @param command The created instance of the command (can't be <code>null</code>). * @param actionType The action type of the command * @param runAsInternal Indicates if the command should be run as internal action or not * @param hasCorrelationId Indicates if the current command was executed under a correlation-ID */ public static void prepareCommandForMonitoring( CommandBase<?> command, VdcActionType actionType, boolean runAsInternal) { ExecutionContext context = command.getExecutionContext(); if (context == null) { context = new ExecutionContext(); } try { boolean isMonitored = shouldMonitorCommand(actionType, runAsInternal); // A monitored job is created for monitored external flows if (isMonitored || context.isJobRequired()) { Job job = getJob(command, actionType); context.setExecutionMethod(ExecutionMethod.AsJob); context.setJob(job); command.setExecutionContext(context); command.setJobId(job.getId()); context.setMonitored(true); } } catch (Exception e) { log.errorFormat( "Failed to prepare command of type {0} for monitoring due to error {1}", actionType.name(), ExceptionUtils.getMessage(e), e); } }
/** * Finalizes a {@code Step} execution by a given context in which the step was performed and by * the exit status of the step. * * @param context The context in which the {@code Step} was executed. * @param step The step to finalize. * @param exitStatus Indicates if the execution described by the step ended successfully or not. */ public static void endStep(ExecutionContext context, Step step, boolean exitStatus) { if (context == null) { return; } if (context.isMonitored()) { Job job = context.getJob(); try { if (step != null) { step.markStepEnded(exitStatus); JobRepositoryFactory.getJobRepository().updateStep(step); } if (context.getExecutionMethod() == ExecutionMethod.AsJob && job != null && !exitStatus) { // step failure will cause the job to be marked as failed context.setCompleted(true); job.markJobEnded(false); JobRepositoryFactory.getJobRepository().updateCompletedJobAndSteps(job); } else { Step parentStep = context.getStep(); if (context.getExecutionMethod() == ExecutionMethod.AsStep && parentStep != null) { context.setCompleted(true); if (!exitStatus) { job.markJobEnded(false); JobRepositoryFactory.getJobRepository().updateCompletedJobAndSteps(job); } } } } catch (Exception e) { log.error(e); } } }
private static void endJob(boolean exitStatus, Job job) { job.markJobEnded(exitStatus); try { JobRepositoryFactory.getJobRepository().updateCompletedJobAndSteps(job); } catch (Exception e) { log.errorFormat("Failed to end Job {0}, {1}", job.getId(), job.getActionType().name(), e); } }
/** * Mark the Job as an Async Job which should be terminated by external process to the current * command scope. * * @param executionContext The context which describe the running job. * @param isAsync indicates if the job should be ended by current action */ public static void setAsyncJob(ExecutionContext executionContext, boolean isAsync) { if (executionContext == null) { return; } Job job = executionContext.getJob(); if (executionContext.getExecutionMethod() == ExecutionMethod.AsJob && job != null) { job.setIsAsyncJob(isAsync); } }
@Override public Job getJob(final Guid jobId) { Job job = jobDao.get(jobId); if (job != null) { Map<Guid, VdcObjectType> jobSubjectEntity = jobSubjectEntityDao.getJobSubjectEntityByJobId(jobId); job.setJobSubjectEntities(jobSubjectEntity); } return job; }
@Override public List<Job> getJobsByEntityAndAction(Guid entityId, VdcActionType actionType) { List<Job> jobList = new ArrayList<Job>(); List<Guid> jobIdsList = jobSubjectEntityDao.getJobIdByEntityId(entityId); for (Guid jobId : jobIdsList) { Job job = jobDao.get(jobId); if (job != null && job.getActionType() == actionType) { jobList.add(job); } } return jobList; }
/** * Updates Job for the same entity for a specific action as completed with a given exit status. * * @param entityId The entity to search for its jobs * @param actionType The action type to search for * @param status The exist status to be set for the job */ public static void updateSpecificActionJobCompleted( Guid entityId, VdcActionType actionType, boolean status) { try { List<Job> jobs = JobRepositoryFactory.getJobRepository().getJobsByEntityAndAction(entityId, actionType); for (Job job : jobs) { if (job.getStatus() == JobExecutionStatus.STARTED) job.markJobEnded(status); JobRepositoryFactory.getJobRepository().updateCompletedJobAndSteps(job); } } catch (RuntimeException e) { log.error(e); } }
@Override public Job getJobWithSteps(final Guid jobId) { Job job = jobDao.get(jobId); if (job != null) { Map<Guid, VdcObjectType> jobSubjectEntity = jobSubjectEntityDao.getJobSubjectEntityByJobId(jobId); job.setJobSubjectEntities(jobSubjectEntity); List<Step> steps = stepDao.getStepsByJobId(jobId); if (!steps.isEmpty()) { job.setSteps(buildStepsTree(steps)); } } return job; }
/** * Method should be called when finalizing the command. The execution step is being ended with * success and the finalization step is started. * * @param executionContext The context of the job * @return A created instance of the Finalizing step */ public static Step startFinalizingStep(ExecutionContext executionContext) { if (executionContext == null) { return null; } Step step = null; try { if (executionContext.getExecutionMethod() == ExecutionMethod.AsJob) { Job job = executionContext.getJob(); if (job != null) { Step executingStep = job.getStep(StepEnum.EXECUTING); Step finalizingStep = job.addStep( StepEnum.FINALIZING, ExecutionMessageDirector.getInstance().getStepMessage(StepEnum.FINALIZING)); if (executingStep != null) { executingStep.markStepEnded(true); JobRepositoryFactory.getJobRepository() .updateExistingStepAndSaveNewStep(executingStep, finalizingStep); } else { JobRepositoryFactory.getJobRepository().saveStep(finalizingStep); } } } else if (executionContext.getExecutionMethod() == ExecutionMethod.AsStep) { Step parentStep = executionContext.getStep(); if (parentStep != null) { Step executingStep = parentStep.getStep(StepEnum.EXECUTING); Step finalizingStep = parentStep.addStep( StepEnum.FINALIZING, ExecutionMessageDirector.getInstance().getStepMessage(StepEnum.FINALIZING)); if (executingStep != null) { executingStep.markStepEnded(true); JobRepositoryFactory.getJobRepository() .updateExistingStepAndSaveNewStep(executingStep, finalizingStep); } else { JobRepositoryFactory.getJobRepository().saveStep(finalizingStep); } } } } catch (Exception e) { log.error(e); } return step; }
/** * Creates and returns an instance of {@link Job} entity. * * @param actionType The action type the job entity represents. * @param command The {@code CommandBase} instance which the job entity describes. * @return An initialized {@code Job} instance. */ public static Job createJob(VdcActionType actionType, CommandBase<?> command) { Job job = new Job(); job.setId(Guid.newGuid()); job.setActionType(actionType); job.setDescription( ExecutionMessageDirector.resolveJobMessage(actionType, command.getJobMessageProperties())); job.setJobSubjectEntities(getSubjectEntities(command.getPermissionCheckSubjects())); job.setOwnerId(command.getUserId()); job.setStatus(JobExecutionStatus.STARTED); job.setStartTime(new Date()); job.setCorrelationId(command.getCorrelationId()); return job; }
/** * Adds a {@link Step} entity by the provided context. A {@link Step} will not be created if * {@code ExecutionContext.isMonitored()} returns false. * * @param context The context of the execution which defines visibility and execution method. * @param stepName The name of the step. * @param description A presentation name for the step. If not provided, the presentation name is * resolved by the {@code stepName}. * @param isExternal Indicates if the step is invoked by a plug-in * @return */ public static Step addStep( ExecutionContext context, StepEnum stepName, String description, boolean isExternal) { if (context == null) { return null; } Step step = null; if (context.isMonitored()) { if (description == null) { description = ExecutionMessageDirector.getInstance().getStepMessage(stepName); } try { Job job = context.getJob(); if (context.getExecutionMethod() == ExecutionMethod.AsJob && job != null) { step = job.addStep(stepName, description); try { step.setExternal(isExternal); JobRepositoryFactory.getJobRepository().saveStep(step); } catch (Exception e) { log.errorFormat( "Failed to save new step {0} for job {1}, {2}.", stepName.name(), job.getId(), job.getActionType().name(), e); job.getSteps().remove(step); step = null; } } else { Step contextStep = context.getStep(); if (context.getExecutionMethod() == ExecutionMethod.AsStep && contextStep != null) { step = addSubStep(contextStep, stepName, description); step.setExternal(isExternal); } } } catch (Exception e) { log.error(e); } } return step; }