Apache Camel:文件到BeanIO并根据ID合并beanIO对象 [英] Apache Camel : File to BeanIO and merge beanIO objects based on id

查看:76
本文介绍了Apache Camel:文件到BeanIO并根据ID合并beanIO对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用例来并行读取员工,地址和联系人文件,并将其转换为beanIO对象,然后合并beanIO对象以生成完整的employeeDetails对象.

I have the usecase to read employee, address and contact files in parallel and convert that to beanIO object and merge the beanIO object to produce the complete employeeDetails object.

Emp文件:

1 Foo Engineer
2 Bar AssistantEngineer

Emp联系人文件:

1 8912345678  foo@org.com
2 7812345678    bar@org.com

Emp地址文件:

 1 city1 1234
 2 city2 2345

Exchange中EmployeeDetailsBeanIODataFormat对象中的预期输出:

Expected output in a EmployeeDetailsBeanIODataFormat object in Exchange:

1 Foo Engineer foo@org.com city1 1234
2 Bar AssistantEngineer bar@org.com city2 2345

我有以下路线

from("file://C:/cameltest/employee.txt").to("seda:beanIO");
from("file://C:/cameltest/employeeContact.txt").to("seda:beanIOContact");
from("file://C:/cameltest/employeeAddress.txt").to("seda:beanIOAddress");

每个文件都转换为beanio对象

Each file is converted to beanio object

BeanIODataFormat empFormat = new BeanIODataFormat("beanIO.xml","emp");
BeanIODataFormat empContactFormat = new BeanIODataFormat("beanIO.xml", "empContact");
BeanIODataFormat empAddressFormat = new BeanIODataFormat("beanIO.xml", "empAddress");

from("seda:beanIO").unmarshal(empFormat).log("body - ${body}");        
from("seda:beanIOContact").unmarshal(empContactFormat).log("Contact body ${body}");
from("seda:beanIO").unmarshal(empAddressFormat).log("Address body - ${body}");     

输出正确记录了bean对象.

The output logs the bean objects correctly.

现在,我需要合并对象以形成EmployeeDetails对象.有人可以让我知道该怎么做吗?我已经阅读了,似乎可以使用聚合器来完成这项工作,但是不确定该方法.

Now I need to merge the objects to form EmployeeDetails object. Can someone let me know how to do this? I have read and it seems like Aggregators can be used to do this job, but not sure with the approach.

任何有关此示例的想法都会有所帮助. 欢迎提出建议,是否建议首先根据员工ID合并文件并从中创建对象?在这种情况下,我不想将合并的文件写入磁盘,因为IO会降低性能.

Any idea on this with sample will be helpful. Suggestions are welcome, is it advisable to merge the files first based on employee id and create an object out of it? I dont want to write the merged file into disk in this case as IO will cost the performance.

预先感谢.

推荐答案

解组后,使用拆分器拆分每封邮件

Use a splitter to split each message after the unmarshalling

from("seda:beanIO").unmarshal(empFormat).split(body()).to("seda:aggregate");
from("seda:beanIOContact").unmarshal(empContactFormat).split(body()).to("seda:aggregate");
from("seda:beanIOAddress").unmarshal(empAddressFormat).split(body()).to("seda:aggregate");

然后是聚合器的外观. 详细信息对象作为标头存储在olddExchange中. 最重要的参数如下

And then here is how an aggregator could look like. The details object is stored as a header in the olddExchange. The most important parameters are the following

  1. correlationExpression:simple("$ {body.id}")将所有具有相同id(1或2)的消息相关联
  2. completionSize = 3.每个文件一个.


from("seda:aggregate").aggregate(simple("${body.id}"), (oldExchange,newExchange) -> {
        if (oldExchange == null) {
            EmployeeDetails details = buildDetails(new EmployeeDetails(), newExchange);
            newExchange.getIn().setHeader("details", details);
            return newExchange;
        }
        EmployeeDetails details = oldExchange.getIn().getHeader("details", EmployeeDetails.class);
        buildDetails(details, newExchange);
        oldExchange.getIn().setHeader("details", details);
        return oldExchange;
    }).completionSize(3).log("Details - ${header.details}")

还有

private EmployeeDetails buildDetails(EmployeeDetails details, Exchange newExchange) {
        Object newBody = newExchange.getIn().getBody();
        if (newBody instanceof Employee) {
            details.setId(((Employee) newBody).getId());
            details.setName(((Employee) newBody).getName());
            details.setJob(((Employee) newBody).getJob());
        } else if (newBody instanceof EmployeeContact) {
            details.setEmail(((EmployeeContact) newBody).getEmail());
        } else if (newBody instanceof EmployeeAddress) {
            details.setCity(((EmployeeAddress) newBody).getCity());
            details.setCode(((EmployeeAddress) newBody).getCode());
        }
        return details;
    }

那么结果将是2个细节对象

Then the outcome would be 2 details objects

Details - EmployeeDetails(id=1, name=Foo, job=Engineer, email=foo@org.com, city=city1, code=1234)
Details - EmployeeDetails(id=2, name=Bar, job=AssistantEnginee, email=bar@org.com, city=city2, code=2345)

这篇关于Apache Camel:文件到BeanIO并根据ID合并beanIO对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆