✔ 이 예제는 여러 Slave Step 들이 하나의 Writer를 공유하는 과정에서 Thread Safe 하도록 구성되어 있다.
<job id="partitionJob" restartable="true" xmlns="http://www.springframework.org/schema/batch"> <step id="step"> <partition step="step1" partitioner="partitioner"> <handler grid-size="4" task-executor="taskExecutor" /> </partition> </step> </job>
<bean id="partitioner" class="org.springframework.batch.core.partition.support.MultiResourcePartitioner"> <property name="resources" value="classpath:egovframework/data/input/delimited*.csv" /> </bean>
<step id="step1" xmlns="http://www.springframework.org/schema/batch"> <tasklet transaction-manager="transactionManager"> <chunk writer="itemWriterPartition" reader="itemReader commit-interval="3" /> </tasklet> </step>
<bean id="itemReader" scope="step" autowire-candidate="false" parent="itemReaderParent"> <property name="resource" value="#{stepExecutionContext[fileName]}" /> </bean> <bean id="itemWriterPartition" class="egovframework.brte.sample.example.support.EgovPartitionFlatFileItemWriter"> <property name="resource" value="file:./target/test-outputs/partition/file/delimitedOneFile.csv" /> ... </bean>
스프링에서 제공하는 MultiResourcePartitioner 를 사용하며 입력리소스의 수(입력파일 수)만큼 Context를 생성하고 출력위치를 셋팅하는 역할을 한다.(Context 생성으로 여러 Slave Step들을 사용할 수 있게 됨)
✔ 이 예제에서 는 File 파티셔닝 예제에서 사용하는 MultiResourcePartitioner와 동일하므로 해당부분을 참고한다.
EgovPartitionFlatFileItemWriter는 file 파티셔닝에서 Slave Step들이 하나의 Writer를 공유해 하나의 타겟파일에 데이터를 Write 하도록 구성했다.
✔ scope = “step” 설정 해제 : 여러 Slave Step에서 하나의 EgovPartitionFlatFileItemWriter만 생기기 위함
✔ JunitTest 클래스의 구조는 배치실행환경 예제 Junit Test 설명을 참고한다.
✔ assertEquals(“COMPLETED”, jobExecution.getExitStatus().getExitCode()) : 배치수행결과가 COMPLETED 인지 확인한다.
✔ 데이터처리 결과를 확인하기 위해, 배치수행과 개별적으로 여러 입력파일의 데이터 합과 단일 출력파일의 데이터 합을 비교하여 정상수행여부를 판단한다.
@Test public void testUpdateCredit() throws Exception { ... open(inputReader); List<CustomerCredit> inputs = new ArrayList<CustomerCredit>(getCredits(inputReader)); close(inputReader); JobExecution jobExecution = jobLauncherTestUtils.launchJob(); assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus()); @SuppressWarnings("unchecked") ItemReader<CustomerCredit> outputReader = (ItemReader<CustomerCredit>) applicationContext.getBean("outputTestReader"); open(outputReader); List<CustomerCredit> outputs = new ArrayList<CustomerCredit>(getCredits(outputReader)); close(outputReader); // inputFile 과 outputFile 에 포함된 line 수 비교 assertEquals(inputs.size(), outputs.size()); // inputFile 과 outputFile 에 포함된 모든 credit 의 합을 비교 int inputCredit=0; int outputCredit=0; //input 파일들에서 Credit 의 합 inputs.iterator(); for (int i = 0; i < inputs.size(); i++) { inputCredit += inputs.get(i).getCredit().intValue(); } //output 파일들에서 Credit 의 합 for (int j = 0; j < outputs.size(); j++) { outputCredit += outputs.get(j).getCredit().intValue(); } assertEquals(inputCredit, outputCredit); }
수행방법은 JunitTest 실행을 참고한다.