/** * 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); } }
/** * Creates {@code ExecutionContext} which defines the context for executing the finalizing step of * the job. If the step exists, it must be part of a job, therefore the {@code Job} entity is * being set as part of the context. * * @param stepId The unique identifier of the step. Must not be {@code null}. * @return The context for monitoring the finalizing step of the job, or {@code null} if no such * step. */ public static ExecutionContext createFinalizingContext(Guid stepId) { ExecutionContext context = null; try { Step step = JobRepositoryFactory.getJobRepository().getStep(stepId); if (step != null && step.getParentStepId() != null) { context = new ExecutionContext(); Step executionStep = JobRepositoryFactory.getJobRepository().getStep(step.getParentStepId()); // indicates if a step is monitored at Job level or as an inner step Guid parentStepId = executionStep.getParentStepId(); if (parentStepId == null) { context.setExecutionMethod(ExecutionMethod.AsJob); context.setJob(JobRepositoryFactory.getJobRepository().getJobWithSteps(step.getJobId())); } else { context.setExecutionMethod(ExecutionMethod.AsStep); Step parentStep = JobRepositoryFactory.getJobRepository().getStep(parentStepId); parentStep.setSteps( DbFacade.getInstance().getStepDao().getStepsByParentStepId(parentStep.getId())); context.setStep(parentStep); } context.setMonitored(true); } } catch (Exception e) { log.error(e); } return context; }
/** * Updates the step with the id in the external system in which the describe task runs. * * @param step The step which represents the external task * @param externalId The id of the task in the external system * @param systemType The type of the system */ public static void updateStepExternalId( Step step, Guid externalId, ExternalSystemType systemType) { if (step != null) { step.getExternalSystem().setId(externalId); step.getExternalSystem().setType(systemType); try { JobRepositoryFactory.getJobRepository().updateStep(step); } catch (Exception e) { log.errorFormat( "Failed to save step {0}, {1} for system-type {2} with id {3}", step.getId(), step.getStepType().name(), systemType.name(), externalId, e); } } }
/** * Finalizes a {@code Step} execution which represents a VDSM task. In case of a failure status, * the job will not be marked as failed at this stage, but via executing the {@code * CommandBase.endAction} with the proper status by {@code the AsyncTaskManager}. * * @param stepId A unique identifier of the step to finalize. * @param exitStatus The status which the step should be ended with. */ public static void endTaskStep(Guid stepId, JobExecutionStatus exitStatus) { try { if (stepId != null) { Step step = JobRepositoryFactory.getJobRepository().getStep(stepId); if (step != null) { step.markStepEnded(exitStatus); JobRepositoryFactory.getJobRepository().updateStep(step); } } } catch (Exception e) { log.errorFormat("Failed to terminate step {0} with status {1}", stepId, exitStatus, 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 Step addSubStep(Step parentStep, StepEnum stepName, String description) { Step step = null; if (parentStep != null) { if (description == null) { description = ExecutionMessageDirector.getInstance().getStepMessage(stepName); } step = parentStep.addStep(stepName, description); try { JobRepositoryFactory.getJobRepository().saveStep(step); } catch (Exception e) { log.errorFormat( "Failed to save new step {0} for step {1}, {2}.", stepName.name(), parentStep.getId(), parentStep.getStepType().name(), e); parentStep.getSteps().remove(step); step = null; } } return step; }
/** * 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; }
/** * Finalizes Job with VDSM tasks, as this case requires verification that no other steps are * running in order to close the entire Job * * @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 endTaskJob(ExecutionContext context, boolean exitStatus) { if (context == null) { return; } try { if (context.getExecutionMethod() == ExecutionMethod.AsJob && context.getJob() != null) { endJob(context, exitStatus); } else { Step parentStep = context.getStep(); if (context.getExecutionMethod() == ExecutionMethod.AsStep && parentStep != null) { Step finalizingStep = parentStep.getStep(StepEnum.FINALIZING); if (finalizingStep != null) { finalizingStep.markStepEnded(exitStatus); JobRepositoryFactory.getJobRepository().updateStep(finalizingStep); } parentStep.markStepEnded(exitStatus); JobRepositoryFactory.getJobRepository().updateStep(parentStep); List<Step> steps = DbFacade.getInstance().getStepDao().getStepsByJobId(parentStep.getJobId()); boolean hasChildStepsRunning = false; for (Step step : steps) { if (step.getStatus() == JobExecutionStatus.STARTED && step.getParentStepId() != null) { hasChildStepsRunning = true; break; } } if (!hasChildStepsRunning) { endJob( exitStatus, JobRepositoryFactory.getJobRepository().getJob(parentStep.getJobId())); } } } } catch (RuntimeException e) { log.error(e); } }
@Override protected boolean canDoAction() { boolean retValue = true; step = getStepDao().get(getParameters().getId()); if (step == null) { retValue = false; addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_NO_STEP); } else if (!step.isExternal()) { retValue = false; addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_NOT_EXTERNAL); } else { job = getJobDao().get(step.getJobId()); if (job == null) { retValue = false; addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_NO_JOB); } if (!retValue) { addCanDoActionMessage(VdcBllMessages.VAR__ACTION__END); addCanDoActionMessage(VdcBllMessages.VAR__TYPE__EXTERNAL_STEP); } } return retValue; }
/** * 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; }
/** * Gets a list of {@link Step} entities ordered by: * <li>parent step id, preceded by nulls * <li>step number * * @param steps * @return a collection of the steps. */ private List<Step> buildStepsTree(List<Step> steps) { List<Step> jobDirectSteps = new ArrayList<Step>(); // a map of parent step id and a list of child-steps Map<NGuid, List<Step>> parentStepMap = new HashMap<NGuid, List<Step>>(); for (Step step : steps) { if (step.getParentStepId() == null) { jobDirectSteps.add(step); } else { MultiValueMapUtils.addToMap(step.getParentStepId(), step, parentStepMap); } } for (Step step : steps) { step.setSteps(parentStepMap.get(step.getId())); } return jobDirectSteps; }
/** * Adds a {@link Step} entity by the provided context as a child step of a given parent step. 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 parentStep The parent step which the new step will be added as its child. * @param newStepName 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 addSubStep( ExecutionContext context, Step parentStep, StepEnum newStepName, String description, boolean isExternal) { Step step = null; if (context == null || parentStep == null) { return null; } try { if (context.isMonitored()) { if (description == null) { description = ExecutionMessageDirector.getInstance().getStepMessage(newStepName); } if (context.getExecutionMethod() == ExecutionMethod.AsJob) { if (DbFacade.getInstance().getStepDao().exists(parentStep.getId())) { if (parentStep.getJobId().equals(context.getJob().getId())) { step = parentStep.addStep(newStepName, description); } } } else if (context.getExecutionMethod() == ExecutionMethod.AsStep) { step = parentStep.addStep(newStepName, description); } } if (step != null) { step.setExternal(isExternal); JobRepositoryFactory.getJobRepository().saveStep(step); } } catch (Exception e) { log.error(e); } return step; }