Package com.vmware.bdd.service.job

Source Code of com.vmware.bdd.service.job.SubJobStep

/***************************************************************************
* Copyright (c) 2012-2014 VMware, Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
***************************************************************************/
package com.vmware.bdd.service.job;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.step.AbstractStep;
import org.springframework.batch.core.step.job.JobParametersExtractor;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.util.Assert;

/**
* @author Jarred Li
* @version 0.9
* @since 0.9
*
*/
public class SubJobStep extends AbstractStep {
   private static final Logger logger = Logger.getLogger(SubJobStep.class);
   private static String subJobParametersKey = "subJobParameters";

   private Job job;
   private JobLauncher jobLauncher;
   private JobParametersExtractor jobParametersExtractor =
         new SubJobParametersExtractor();
   private JobExecutionStatusHolder jobExecutionStatusHolder;
   private JobExecutionStatusHolder mainJobExecutionStatusHolder;

   @Override
   public void afterPropertiesSet() throws Exception {
      super.afterPropertiesSet();
      Assert.state(jobLauncher != null, "A JobLauncher must be provided");
      Assert.state(job != null, "A Job must be provided");
   }

   /**
    * The {@link Job} to delegate to in this step.
    *
    * @param job
    *           a {@link Job}
    */
   public void setJob(Job job) {
      this.job = job;
   }

   /**
    * A {@link JobLauncher} is required to be able to run the enclosed
    * {@link Job}.
    *
    * @param jobLauncher
    *           the {@link JobLauncher} to set
    */
   public void setJobLauncher(JobLauncher jobLauncher) {
      this.jobLauncher = jobLauncher;
   }

   /**
    * The {@link JobParametersExtractor} is used to extract
    * {@link JobParametersExtractor} from the {@link StepExecution} to run the
    * {@link Job}. By default an instance will be provided that simply copies
    * the {@link JobParameters} from the parent job.
    *
    * @param jobParametersExtractor
    *           the {@link JobParametersExtractor} to set
    */
   public void setJobParametersExtractor(
         JobParametersExtractor jobParametersExtractor) {
      this.jobParametersExtractor = jobParametersExtractor;
   }

   /**
    * @return the jobExecutionStatusHolder
    */
   public JobExecutionStatusHolder getJobExecutionStatusHolder() {
      return jobExecutionStatusHolder;
   }

   /**
    * @param jobExecutionStatusHolder
    *           the jobExecutionStatusHolder to set
    */
   public void setJobExecutionStatusHolder(
         JobExecutionStatusHolder jobExecutionStatusHolder) {
      this.jobExecutionStatusHolder = jobExecutionStatusHolder;
   }

   /**
    * @return the mainJobExecutionStatusHolder
    */
   public JobExecutionStatusHolder getMainJobExecutionStatusHolder() {
      return mainJobExecutionStatusHolder;
   }

   /**
    * @param mainJobExecutionStatusHolder
    *           the mainJobExecutionStatusHolder to set
    */
   public void setMainJobExecutionStatusHolder(
         JobExecutionStatusHolder mainJobExecutionStatusHolder) {
      this.mainJobExecutionStatusHolder = mainJobExecutionStatusHolder;
   }

   /**
    * Execute the job provided by delegating to the {@link JobLauncher} to
    * prevent duplicate executions. The job parameters will be generated by the
    * {@link JobParametersExtractor} provided (if any), otherwise empty. On a
    * restart, the job parameters will be the same as the last (failed)
    * execution.
    *
    * @see AbstractStep#doExecute(StepExecution)
    */
   @Override
   protected void doExecute(StepExecution stepExecution) throws Exception {

      ExecutionContext executionContext = stepExecution.getExecutionContext();

      JobParameters jobParameters;
      if (executionContext.containsKey(subJobParametersKey)) {
         jobParameters =
               (JobParameters) executionContext.get(subJobParametersKey);
      } else {
         jobParameters =
               jobParametersExtractor.getJobParameters(job, stepExecution);
         executionContext.put(subJobParametersKey, jobParameters);
      }

      JobExecution subJobExecution = jobLauncher.run(job, jobParameters);
      //Wait for job completion
      while (true) {
         if (subJobExecution.getStatus().isRunning()) {
            double subJobProgress =
                  jobExecutionStatusHolder.getCurrentProgress(subJobExecution
                        .getId());
            mainJobExecutionStatusHolder.setCurrentStepProgress(stepExecution
                  .getJobExecution().getId(), subJobProgress);
            Thread.sleep(3000);
         } else {
            break;
         }
      }

      String nodeName = null;
      if (subJobExecution.getJobInstance().getJobParameters().getParameters()
            .containsKey(JobConstants.SUB_JOB_NODE_NAME)) {
         nodeName =
               subJobExecution.getJobInstance().getJobParameters()
                     .getString(JobConstants.SUB_JOB_NODE_NAME);
      } else {
         String stepName = stepExecution.getStepName();
         nodeName = stepName.substring(stepName.lastIndexOf("-") + 1);
      }
      ExecutionContext mainJobExecutionContext =
            stepExecution.getJobExecution().getExecutionContext();
      updateExecutionStatus(subJobExecution, nodeName, mainJobExecutionContext);
   }

   /**
    * update sub job status into main job's execution context for reporting
    *
    * @param subJobExecution
    *           sub job execution
    * @param nodeName
    *           node name of sub job
    * @param mainJobExecutionContext
    *           main job execution context
    */
   private void updateExecutionStatus(JobExecution subJobExecution,
         String nodeName, ExecutionContext mainJobExecutionContext) {
      String rollbackStr =
            (String) subJobExecution.getExecutionContext().get(
                  JobConstants.SUB_JOB_FAIL_FLAG);
      boolean rollback = false;
      if (rollbackStr != null) {
         rollback = Boolean.parseBoolean(rollbackStr);
      }
      if (subJobExecution.getStatus().isUnsuccessful() || rollback) {
         Object errorMessageO =
               subJobExecution.getExecutionContext().get(
                     JobConstants.CURRENT_ERROR_MESSAGE);
         String errorMessage = null;
         if (errorMessageO != null) {
            errorMessage = (String)errorMessageO;
         }
         Object failedObj =
               mainJobExecutionContext.get(JobConstants.SUB_JOB_NODES_FAIL);
         List<NodeOperationStatus> failedNodes = null;
         if (failedObj == null) {
            failedNodes = new ArrayList<NodeOperationStatus>();
         } else {
            failedNodes = (ArrayList<NodeOperationStatus>) failedObj;
         }
         NodeOperationStatus failedSubJob =
               new NodeOperationStatus(nodeName, false, errorMessage);
         failedNodes.add(failedSubJob);
         mainJobExecutionContext.put(JobConstants.SUB_JOB_NODES_FAIL,
               failedNodes);
      } else {
         Object succeededObj =
               mainJobExecutionContext.get(JobConstants.SUB_JOB_NODES_SUCCEED);
         List<NodeOperationStatus> succeededNodes = null;
         if (succeededObj == null) {
            succeededNodes = new ArrayList<NodeOperationStatus>();
         } else {
            succeededNodes = (ArrayList<NodeOperationStatus>) succeededObj;
         }
         NodeOperationStatus succeededSubJob = new NodeOperationStatus(nodeName);
         succeededNodes.add(succeededSubJob);
         mainJobExecutionContext.put(JobConstants.SUB_JOB_NODES_SUCCEED,
               succeededNodes);
      }
   }
}
TOP

Related Classes of com.vmware.bdd.service.job.SubJobStep

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.