/** * Build a master {@link TaskletStep}. * * @return the configured master step * @see RemoteChunkHandlerFactoryBean */ public TaskletStep build() { Assert.notNull(this.inputChannel, "An InputChannel must be provided"); Assert.state(this.outputChannel == null || this.messagingTemplate == null, "You must specify either an outputChannel or a messagingTemplate but not both."); // configure messaging template if (this.messagingTemplate == null) { this.messagingTemplate = new MessagingTemplate(); this.messagingTemplate.setDefaultChannel(this.outputChannel); if (this.logger.isDebugEnabled()) { this.logger.debug("No messagingTemplate was provided, using a default one"); } } // configure item writer ChunkMessageChannelItemWriter<O> chunkMessageChannelItemWriter = new ChunkMessageChannelItemWriter<>(); chunkMessageChannelItemWriter.setMessagingOperations(this.messagingTemplate); chunkMessageChannelItemWriter.setMaxWaitTimeouts(this.maxWaitTimeouts); chunkMessageChannelItemWriter.setThrottleLimit(this.throttleLimit); chunkMessageChannelItemWriter.setReplyChannel(this.inputChannel); super.writer(chunkMessageChannelItemWriter); return super.build(); }
@Test public void testSimulatedRestartWithNoBacklog() throws Exception { factory.setItemReader(new ListItemReader<>(Arrays.asList(StringUtils .commaDelimitedListToStringArray("1,2,3,4,5,6")))); Step step = factory.getObject(); StepExecution stepExecution = getStepExecution(step); // Set up expectation of three messages (chunks) in the backlog stepExecution.getExecutionContext().putInt(ChunkMessageChannelItemWriter.EXPECTED, 6); stepExecution.getExecutionContext().putInt(ChunkMessageChannelItemWriter.ACTUAL, 3); writer.setMaxWaitTimeouts(2); /* * With no backlog we process all the items, but the listener can't * reconcile the expected number of items with the actual. An infinite * loop would be bad, so the best we can do is fail as fast as possible. */ step.execute(stepExecution); assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); assertEquals(ExitStatus.FAILED.getExitCode(), stepExecution.getExitStatus().getExitCode()); String message = stepExecution.getExitStatus().getExitDescription(); assertTrue("Message did not contain 'timed out': " + message, message.toLowerCase().contains("timed out")); assertEquals(0, TestItemWriter.count); assertEquals(0, stepExecution.getReadCount()); }
@Test public void testSimulatedRestartWithBadMessagesFromAnotherJob() throws Exception { factory.setItemReader(new ListItemReader<>(Arrays.asList(StringUtils .commaDelimitedListToStringArray("1,2,3,4,5,6")))); Step step = factory.getObject(); StepExecution stepExecution = getStepExecution(step); // Set up context with two messages (chunks) in the backlog stepExecution.getExecutionContext().putInt(ChunkMessageChannelItemWriter.EXPECTED, 3); stepExecution.getExecutionContext().putInt(ChunkMessageChannelItemWriter.ACTUAL, 2); // Speed up the eventual failure writer.setMaxWaitTimeouts(2); // And make the back log real requests.send(getSimpleMessage("foo", 4321L)); step.execute(stepExecution); assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); assertEquals(ExitStatus.FAILED.getExitCode(), stepExecution.getExitStatus().getExitCode()); String message = stepExecution.getExitStatus().getExitDescription(); assertTrue("Message does not contain 'wrong job': " + message, message.contains("wrong job")); waitForResults(1, 10); assertEquals(1, TestItemWriter.count); assertEquals(0, stepExecution.getReadCount()); }
@Bean public ChunkMessageChannelItemWriter chunkWriter() { ChunkMessageChannelItemWriter chunkWriter = new ChunkMessageChannelItemWriter(); chunkWriter.setMessagingOperations(messageTemplate()); chunkWriter.setReplyChannel(inboundReplies()); chunkWriter.setMaxWaitTimeouts(10); return chunkWriter; }