/** * Add flows to the split, in addition to the current state already present in the parent builder. * * @param flows more flows to add to the split * @return the parent builder */ public FlowBuilder<Q> add(Flow... flows) { Collection<Flow> list = new ArrayList<>(Arrays.asList(flows)); String name = "split" + (parent.splitCounter++); int counter = 0; State one = parent.currentState; Flow flow = null; if (!(one == null || one instanceof FlowState)) { FlowBuilder<Flow> stateBuilder = new FlowBuilder<>(name + "_" + (counter++)); stateBuilder.currentState = one; flow = stateBuilder.build(); } else if (one instanceof FlowState && parent.states.size() == 1) { list.add(((FlowState) one).getFlows().iterator().next()); } if (flow != null) { list.add(flow); } State next = parent.createState(list, executor); parent.currentState = next; return parent; }
@Test public void testBuildSplit_BATCH_2282() throws Exception { Flow flow1 = new FlowBuilder<Flow>("subflow1").from(step1).end(); Flow flow2 = new FlowBuilder<Flow>("subflow2").from(step2).end(); Flow splitFlow = new FlowBuilder<Flow>("splitflow").split(new SimpleAsyncTaskExecutor()).add(flow1, flow2).build(); FlowJobBuilder builder = new JobBuilder("flow").repository(jobRepository).start(splitFlow).end(); builder.preventRestart().build().execute(execution); assertEquals(BatchStatus.COMPLETED, execution.getStatus()); assertEquals(2, execution.getStepExecutions().size()); }
@Test public void testBuildSplitUsingStartAndAdd_BATCH_2346() throws Exception { Flow subflow1 = new FlowBuilder<Flow>("subflow1").from(step2).end(); Flow subflow2 = new FlowBuilder<Flow>("subflow2").from(step3).end(); Flow splitflow = new FlowBuilder<Flow>("splitflow").start(subflow1).split(new SimpleAsyncTaskExecutor()) .add(subflow2).build(); FlowJobBuilder builder = new JobBuilder("flow").repository(jobRepository).start(splitflow).end(); builder.preventRestart().build().execute(execution); assertEquals(BatchStatus.COMPLETED, execution.getStatus()); assertEquals(2, execution.getStepExecutions().size()); }
@Bean public Flow flow() { return new FlowBuilder<Flow>("flow") .start(stepBuilderFactory.get("flow.step1") .tasklet(new Tasklet() { @Override public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { return RepeatStatus.FINISHED; } }).build() ).next(stepBuilderFactory.get("flow.step2") .tasklet(new Tasklet() { @Override public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { return RepeatStatus.FINISHED; } }).build() ).build(); }
@Test public void testBuildSingleFlow() throws Exception { Flow flow = new FlowBuilder<Flow>("subflow").from(step1).next(step2).build(); FlowJobBuilder builder = new JobBuilder("flow").repository(jobRepository).start(flow).end().preventRestart(); builder.build().execute(execution); assertEquals(BatchStatus.COMPLETED, execution.getStatus()); assertEquals(2, execution.getStepExecutions().size()); }
@Test public void testBuildSplit() throws Exception { Flow flow = new FlowBuilder<Flow>("subflow").from(step1).end(); SimpleJobBuilder builder = new JobBuilder("flow").repository(jobRepository).start(step2); builder.split(new SimpleAsyncTaskExecutor()).add(flow).end(); builder.preventRestart().build().execute(execution); assertEquals(BatchStatus.COMPLETED, execution.getStatus()); assertEquals(2, execution.getStepExecutions().size()); }
@Test public void test() throws Exception { FlowBuilder<Flow> builder = new FlowBuilder<>("flow"); JobRepository jobRepository = new MapJobRepositoryFactoryBean().getObject(); JobExecution execution = jobRepository.createJobExecution("foo", new JobParameters()); builder.start(new StepSupport("step") { @Override public void execute(StepExecution stepExecution) throws JobInterruptedException, UnexpectedJobExecutionException { } }).end().start(new JobFlowExecutor(jobRepository, new SimpleStepHandler(jobRepository), execution)); }
@Test public void testBuildSubflow() throws Exception { Flow flow = new FlowBuilder<Flow>("subflow").from(step1).end(); JobFlowBuilder builder = new JobBuilder("flow").repository(jobRepository).start(flow); builder.on("COMPLETED").to(step2); builder.end().preventRestart().build().execute(execution); assertEquals(BatchStatus.COMPLETED, execution.getStatus()); assertEquals(2, execution.getStepExecutions().size()); }
@Bean public Job concurrentJob() { Flow splitFlow = new FlowBuilder<Flow>("splitflow").split(new SimpleAsyncTaskExecutor()).add(flow(), flow(), flow(), flow(), flow(), flow(), flow()).build(); return jobBuilderFactory.get("concurrentJob") .start(firstStep()) .next(stepBuilderFactory.get("splitFlowStep") .flow(splitFlow) .build()) .next(lastStep()) .build(); }
private Flow handleFlowForSegment(Deque<Flow> resultFlowDeque) { FlowBuilder<Flow> localTaskAppFlowBuilder = new FlowBuilder<>("Flow" + UUID.randomUUID().toString()); if(!resultFlowDeque.isEmpty()) { localTaskAppFlowBuilder.start(resultFlowDeque.pop()); } while (!resultFlowDeque.isEmpty()) { localTaskAppFlowBuilder.next(resultFlowDeque.pop()); } return localTaskAppFlowBuilder.end(); }
public ComposedRunnerJobFactory(ComposedTaskProperties properties) { this.composedTaskProperties = properties; Assert.notNull(properties.getGraph(), "The DSL must not be null"); this.dsl = properties.getGraph(); this.incrementInstanceEnabled = properties.isIncrementInstanceEnabled(); this.flowBuilder = new FlowBuilder<>(UUID.randomUUID().toString()); }
/** * Add flows to the split, in addition to the current state already present in the parent builder. * * @param flows more flows to add to the split * @return the parent builder */ public FlowBuilder<Q> add(Flow... flows) { Collection<Flow> list = new ArrayList<Flow>(Arrays.asList(flows)); String name = "split" + (parent.splitCounter++); int counter = 0; State one = parent.currentState; Flow flow = null; if (!(one == null || one instanceof FlowState)) { FlowBuilder<Flow> stateBuilder = new FlowBuilder<Flow>(name + "_" + (counter++)); stateBuilder.currentState = one; flow = stateBuilder.build(); } else if (one instanceof FlowState && parent.states.size() == 1) { list.add(((FlowState) one).getFlows().iterator().next()); } if (flow != null) { list.add(flow); } State next = parent.createState(list, executor); parent.currentState = next; return parent; }
private Flow getTaskAppFlow(TaskAppNode taskApp) { String beanName = getBeanName(taskApp); Step currentStep = this.context.getBean(beanName, Step.class); return new FlowBuilder<Flow>(beanName).from(currentStep).end(); } }
private Flow processSplitNode(Deque<LabelledTaskNode> visitorDeque, SplitNode splitNode) { Deque<Flow> flows = new LinkedList<>(); //For each node in the split process it as a DSL flow. for (LabelledTaskNode taskNode : splitNode.getSeries()) { Deque<Flow> resultFlowDeque = new LinkedList<>(); flows.addAll(processSplitFlow(taskNode, resultFlowDeque)); } removeProcessedNodes(visitorDeque, splitNode); Flow nestedSplitFlow = new FlowBuilder.SplitBuilder<>( new FlowBuilder<Flow>("Split" + UUID.randomUUID().toString()), taskExecutor) .add(flows.toArray(new Flow[flows.size()])) .build(); FlowBuilder<Flow> taskAppFlowBuilder = new FlowBuilder<>("Flow" + UUID.randomUUID().toString()); if (this.hasNestedSplit) { this.splitFlows = flows.size(); int threadCorePoolSize = this.composedTaskProperties.getSplitThreadCorePoolSize(); Assert.isTrue(threadCorePoolSize >= this.splitFlows, "Split thread core pool size " + threadCorePoolSize + " should be equal or greater " + "than the depth of split flows " + (this.splitFlows +1) + "." + " Try setting the composed task property `splitThreadCorePoolSize`"); } return taskAppFlowBuilder.start(nestedSplitFlow).end(); }
@Bean public Flow flow1() { return new FlowBuilder<Flow>("flow1") .start(stepBuilderFactory.get("step1") .tasklet(tasklet()).build()) .build(); }
@Bean public Flow foo() { FlowBuilder<Flow> flowBuilder = new FlowBuilder<>("foo"); flowBuilder.start(step1()) .next(step2()) .end(); return flowBuilder.build(); }
@Bean public Flow bar() { FlowBuilder<Flow> flowBuilder = new FlowBuilder<>("bar"); flowBuilder.start(step1()) .next(step2()) .end(); return flowBuilder.build(); } }
private void handleTransition(Deque<Flow> resultFlowDeque, TaskAppNode taskAppNode) { String beanName = getBeanName(taskAppNode); Step currentStep = this.context.getBean(beanName, Step.class); FlowBuilder<Flow> builder = new FlowBuilder<Flow>(beanName) .from(currentStep); boolean wildCardPresent = false; for (TransitionNode transitionNode : taskAppNode.getTransitions()) { String transitionBeanName = getBeanName(transitionNode); wildCardPresent = transitionNode.getStatusToCheck().equals(WILD_CARD); Step transitionStep = this.context.getBean(transitionBeanName, Step.class); builder.on(transitionNode.getStatusToCheck()).to(transitionStep) .from(currentStep); } if (wildCardPresent && !resultFlowDeque.isEmpty()) { throw new IllegalStateException( "Invalid flow following '*' specifier."); } else { //if there are nodes are in the execution Deque. Make sure that //they are processed as a target of the wildcard instead of the //whole transition. if (!resultFlowDeque.isEmpty()) { builder.on(WILD_CARD).to(handleFlowForSegment(resultFlowDeque)).from(currentStep); } } resultFlowDeque.push(builder.end()); }
@Bean public Job splitJob(@Qualifier("foo") Flow foo, @Qualifier("foo") Flow bar) { FlowBuilder<Flow> flowBuilder = new FlowBuilder<>("split"); Flow flow = flowBuilder.split(new SimpleAsyncTaskExecutor()) .add(foo, bar) .end(); return jobBuilderFactory.get("splitJob") .start(myStep1()) .next(myStep2()) .on("COMPLETED").to(flow) .end() .build(); } }
@Bean public Flow flow2() { return new FlowBuilder<Flow>("flow2") .start(stepBuilderFactory.get("step2") .tasklet(tasklet()).build()) .next(stepBuilderFactory.get("step3") .tasklet(tasklet()).build()) .build(); }