Package org.springframework.batch.core.step.builder

Source Code of org.springframework.batch.core.step.builder.PartitionStepBuilder

/*
* Copyright 2006-2011 the original author or authors.
*
* 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 org.springframework.batch.core.step.builder;

import org.springframework.batch.core.Step;
import org.springframework.batch.core.partition.PartitionHandler;
import org.springframework.batch.core.partition.StepExecutionSplitter;
import org.springframework.batch.core.partition.support.PartitionStep;
import org.springframework.batch.core.partition.support.Partitioner;
import org.springframework.batch.core.partition.support.SimpleStepExecutionSplitter;
import org.springframework.batch.core.partition.support.StepExecutionAggregator;
import org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler;
import org.springframework.core.task.SyncTaskExecutor;
import org.springframework.core.task.TaskExecutor;

/**
* Step builder for {@link PartitionStep} instances. A partition step executes the same step (possibly remotely)
* multiple times with different input parameters (in the form of execution context). Useful for parallelization.
*
* @author Dave Syer
*
* @since 2.2
*/
public class PartitionStepBuilder extends StepBuilderHelper<PartitionStepBuilder> {

  private TaskExecutor taskExecutor;

  private Partitioner partitioner;

  private static final int DEFAULT_GRID_SIZE = 6;

  private Step step;

  private PartitionHandler partitionHandler;

  private int gridSize = DEFAULT_GRID_SIZE;

  private StepExecutionSplitter splitter;

  private StepExecutionAggregator aggregator;

  private String stepName;

  /**
   * Create a new builder initialized with any properties in the parent. The parent is copied, so it can be re-used.
   *
   * @param parent a parent helper containing common step properties
   */
  public PartitionStepBuilder(StepBuilderHelper<?> parent) {
    super(parent);
  }

  /**
   * Add a partitioner which can be used to create a {@link StepExecutionSplitter}. Use either this or an explicit
   * {@link #splitter(StepExecutionSplitter)} but not both.
   *
   * @param slaveStepName the name of the slave step (used to construct step execution names)
   * @param partitioner a partitioner to use
   * @return this for fluent chaining
   */
  public PartitionStepBuilder partitioner(String slaveStepName, Partitioner partitioner) {
    this.stepName = slaveStepName;
    this.partitioner = partitioner;
    return this;
  }

  /**
   * Provide an actual step instance to execute in parallel. If an explicit
   * {@link #partitionHandler(PartitionHandler)} is provided, the step is optional and is only used to extract
   * configuration data (name and other basic properties of a step).
   *
   * @param step a step to execute in parallel
   * @return this for fluent chaining
   */
  public PartitionStepBuilder step(Step step) {
    this.step = step;
    return this;
  }

  /**
   * Provide a task executor to use when constructing a {@link PartitionHandler} from the {@link #step(Step)}. Mainly
   * used for running a step locally in parallel, but can be used to execute remotely if the step is remote. Not used
   * if an explicit {@link #partitionHandler(PartitionHandler)} is provided.
   *
   * @param taskExecutor a task executor to use when executing steps in parallel
   * @return this for fluent chaining
   */
  public PartitionStepBuilder taskExecutor(TaskExecutor taskExecutor) {
    this.taskExecutor = taskExecutor;
    return this;
  }

  /**
   * Provide an explicit partition handler that will carry out the work of the partition step. The partition handler
   * is the main SPI for adapting a partition step to a specific distributed computation environment. Optional if you
   * only need local or remote processing through the Step interface.
   *
   * @see #step(Step) for setting up a default handler that works with a local or remote Step
   *
   * @param partitionHandler a partition handler
   * @return this for fluent chaining
   */
  public PartitionStepBuilder partitionHandler(PartitionHandler partitionHandler) {
    this.partitionHandler = partitionHandler;
    return this;
  }

  /**
   * A hint to the {@link #splitter(StepExecutionSplitter)} about how many step executions are required. If running
   * locally or remotely through a {@link #taskExecutor(TaskExecutor)} determines precisely the number of step
   * execution sin the first attempt at a partition step execution.
   *
   * @param gridSize the grid size
   * @return this for fluent chaining
   */
  public PartitionStepBuilder gridSize(int gridSize) {
    this.gridSize = gridSize;
    return this;
  }

  /**
   * Provide an explicit {@link StepExecutionSplitter} instead of having one build from the
   * {@link #partitioner(String, Partitioner)}. USeful if you need more control over the splitting.
   *
   * @param splitter a step execution splitter
   * @return this for fluent chaining
   */
  public PartitionStepBuilder splitter(StepExecutionSplitter splitter) {
    this.splitter = splitter;
    return this;
  }

  /**
   * Provide a step execution aggregator for aggregating partitioned step executions into a single result for the
   * {@link PartitionStep} itself.  Default is a simple implementation that works in most cases.
   *
   * @param aggregator a step execution aggregator
   * @return this for fluent chaining
   */
  public PartitionStepBuilder aggregator(StepExecutionAggregator aggregator) {
    this.aggregator = aggregator;
    return this;
  }

  public Step build() {
    PartitionStep step = new PartitionStep();
    step.setName(getName());
    super.enhance(step);

    if (partitionHandler != null) {
      step.setPartitionHandler(partitionHandler);
    }
    else {
      TaskExecutorPartitionHandler partitionHandler = new TaskExecutorPartitionHandler();
      partitionHandler.setStep(this.step);
      if (taskExecutor == null) {
        taskExecutor = new SyncTaskExecutor();
      }
      partitionHandler.setGridSize(gridSize);
      partitionHandler.setTaskExecutor(taskExecutor);
      step.setPartitionHandler(partitionHandler);
    }

    if (splitter != null) {
      step.setStepExecutionSplitter(splitter);
    }
    else {

      boolean allowStartIfComplete = isAllowStartIfComplete();
      String name = stepName;
      if (this.step != null) {
        try {
          allowStartIfComplete = this.step.isAllowStartIfComplete();
          name = this.step.getName();
        }
        catch (Exception e) {
          logger.info("Ignored exception from step asking for name and allowStartIfComplete flag. "
              + "Using default from enclosing PartitionStep (" + name + "," + allowStartIfComplete + ").");
        }
      }
      SimpleStepExecutionSplitter splitter = new SimpleStepExecutionSplitter();
      splitter.setPartitioner(partitioner);
      splitter.setJobRepository(getJobRepository());
      splitter.setAllowStartIfComplete(allowStartIfComplete);
      splitter.setStepName(name);
      this.splitter = splitter;
      step.setStepExecutionSplitter(splitter);

    }

    if (aggregator != null) {
      step.setStepExecutionAggregator(aggregator);
    }

    try {
      step.afterPropertiesSet();
    }
    catch (Exception e) {
      throw new StepBuilderException(e);
    }

    return step;

  }

  protected TaskExecutor getTaskExecutor() {
    return taskExecutor;
  }

  protected Partitioner getPartitioner() {
    return partitioner;
  }

  protected Step getStep() {
    return step;
  }

  protected PartitionHandler getPartitionHandler() {
    return partitionHandler;
  }

  protected int getGridSize() {
    return gridSize;
  }

  protected StepExecutionSplitter getSplitter() {
    return splitter;
  }

  protected StepExecutionAggregator getAggregator() {
    return aggregator;
  }

  protected String getStepName() {
    return stepName;
  }
}
TOP

Related Classes of org.springframework.batch.core.step.builder.PartitionStepBuilder

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.