简体   繁体   English

如何使用Apache Camel读取文件,如何使用Spring批处理文件,读取每一行并将其路由回Apache Camel

[英]How to read file using Apache Camel, process the file using Spring batch, read each line and route it back through Apache Camel

Would like to know how to pass the JAXBElement to a Camel route, which processed from each line of the batch file read through Spring batch loaded through Camel Route. 想知道如何将JAXBElement传递到Camel路由,该过程从通过Camel Route加载的Spring批处理读取的批处理文件的每一行进行处理。

Code snippets given below uses a customerWriter method to call JMSTemplate to write the message to a Queue. 下面给出的代码段使用customerWriter方法调用JMSTemplate将消息写入队列。 Instead I need to route the message to another Camel route. 相反,我需要将消息路由到另一条骆驼路由。

Current: CamelRoute -> ReadFile -> Spring Batch -> Process Each line -> Queue 当前: CamelRoute-> ReadFile-> Spring Batch->处理每一行->队列

Expected: CamelRoute -> ReadFile -> Spring Batch -> Process Each line -> Camel Route 预期: CamelRoute-> ReadFile-> Spring Batch->处理每一行-> Camel Route

Camel Route to read the file: 骆驼路线读取文件:

@Override
public void configure()  {

    String fromUri = batchLoadPath + "?" + batchFileOptions;
    from(fromUri).process(new Processor() {
        public void process(Exchange msg)  {
            File file = msg.getIn().getBody(File.class);
            String fileName = file.getAbsolutePath();

            try {
                JobParameters jobParameters = new JobParametersBuilder().addString("input.file.name", fileName).addDate("dateTime", new Date()).toJobParameters();
                jobLauncher.run(importCustomerJob, jobParameters);
            } catch (Exception e) {
                log.error(Process file encountered error:" + e.getMessage(), e);
            }
        }

    })
    .to("log:EndBatch");

Batch Config: 批量配置:

@Bean
public JmsItemWriter<String> customerWriter() {
    JmsItemWriter<String> writer = new JmsItemWriter<String>();
    writer.setJmsTemplate(jmsTemplate);
    return writer;
}

public Job importCustomerJob(JobCompletionNotificationListener listener, JobBuilderFactory jobBuilderFactory, Step step1) {
    JobBuilder builder = jobBuilderFactory.get("importCustomerJob");
    builder.incrementer(new RunIdIncrementer());
    builder.listener(listener);
    JobFlowBuilder jfb = builder.flow(step1);
    jfb.end();
    Job job = jfb.build().build();
    return job;
}

@Bean
public Step step1(StepBuilderFactory stepBuilderFactory) {
    // Read chunk of 10 records and writing those as messages to queue
    return stepBuilderFactory.get("step1")
            .<Customer, String>chunk(10)
            .reader(customerReader())
            .faultTolerant()
            .skipPolicy(fileVerificationSkipper())
            .processor(customerItemProcessor())
            .writer(customerWriter())
            .listener(customerReader())
            .build();
}

Batch Processor: 批处理机:

public class CustomerItemProcessor implements ItemProcessor<Customer, String> {
    @Autowired
    JaxbUtil jaxbUtil;

    public String process(Customer item) throws Exception {
        // Mapping code goes here
        JAXBElement<CustomerX> mobj = customerFactory.createCustomerX(cp);
        return jaxbUtil.objectToXml(mobj);
    }
}

Well, from a Camel point of view, to call another Camel route you simply add a .to() statement. 好吧,从骆驼的角度来看,要调用另一条骆驼路线,您只需添加.to()语句。 For example to call an in-memory route synchronously, you can use direct: . 例如,要同步调用内存中的路由,可以使用direct:

from(fromUri).process(new Processor() {
    public void process(Exchange msg)  {
        ... your processor impl
    }
})
.to("direct:yourOtherRoute")
.to("log:EndBatch"); 

from("direct:yourOtherRoute")
...

To pass the result of the processor to the next route, the processor must set this result into the Exchange Body. 要将处理器的结果传递到下一条路由,处理器必须将此结果设置到Exchange正文中。

Thanks for your suggestions @Burki and @Roman Vottner. 感谢您的建议@Burki和@Roman Vottner。 Here's the code which I modified and it worked. 这是我修改并起作用的代码。

Solution: 解:

Added a writer method in Batch Config and called it instead of JMSWriter Batch Config中添加了writer方法,并调用了它而不是JMSWriter

@Bean
public CamelItemWriter<String> customerCamelWriter() {
    ProducerTemplate producerTemplate = camelContext.createProducerTemplate();
    CamelItemWriter<String> writer = new CamelItemWriter<String>(producerTemplate, "direct:process");
    return writer;
}

@Bean
public Step step1(StepBuilderFactory stepBuilderFactory) {
    // Read chunk of 10 records and writing those as messages to CAS.TRF.MDM queue
    return stepBuilderFactory.get("step1")
            .<Customer, String>chunk(10)
            .reader(customerReader())
            .faultTolerant()
            .skipPolicy(fileVerificationSkipper())
            .processor(customerItemProcessor())
            .writer(customerCamelWriter())
            .listener(customerReader())
            .build();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM