【发布时间】:2020-07-24 13:24:21
【问题描述】:
让我们考虑以下用例:
- 一组提供者将数据推送到本地服务器上的相应目录中(例如,P1 将数据推送到 data/P1,P2 推送到 data/P2 等)
- 每个提供者都有自己的生成规则(例如 P1 生成纯 txt 文件,P2 生成档案,P3 生成加密文件等)
- 在服务器上运行的 Spring Boot 应用程序上,每个提供程序都有自己的 Camel 路由,每 10 分钟从相应目录读取一次(例如,R1 读取自(“file:data/P1”),R2 读取自( “文件:数据/P2”), 等)
- 给定的提供者还可以组合规则(例如 P4 生成包含加密数据的档案)
- 根据路径,读取的数据会被相应地处理,以便将纯 txt 文件移动到目标目录(例如 R2 解压缩数据并移动它,R4 解压数据,解密提取结果并移动它等)
一旦实现了更多的路由,很明显大部分代码是重复的并且可以被提取;事实上,由于可以组合规则,每个数据细化都可以看作是一个原子操作,可用于给定的路由。 例如,让我们考虑以下原子操作:
- 解压
- 解密
- 移动
所以,这些路线的外观如下:
R1
from("file:data/P1")
.to("file:destination")
R2
from("file:data/P2")
// UNZIP LOGIC HERE
.to("file:destination")
R3
from("file:data/P3")
// DECRYPT LOGIC HERE
.to("file:destination")
R4
from("file:data/P4")
// UNZIP LOGIC HERE
// DECRYPT LOGIC HERE
.to("file:destination")
由于我想提取通用逻辑,我在这里看到两个主要选项(带有相应的 R4 生成代码):
- 将逻辑提取到自定义组件中
from("file:data/P4")
// FOR EACH FILE
.to("my-custom-component:unzip")
.to("my-custom-component:decrypt")
.to("file:destination")
- 将逻辑提取到更小的路由中
from("file:data/P4")
// FOR EACH FILE
.to("direct:my-unzip-route")
.to("direct:my-decrypt-route")
.to("file:destination")
(当然,这是一个超级简化,但这只是为了给你一个大局。
在这两个选项之间,我更喜欢后者,它可以让我快速重用 Camel EIP(例如 unmarshal().pgp()):
from("file:data/P4")
.to("direct:my-unzip-route")
.to("direct:my-decrypt-route")
.to("file:destination");
from("direct:my-unzip-route")
// LOGIC
.unmarshal().zip()
// MORE LOGIC
;
from("direct:my-decrypt-route")
// LOGIC
.unmarshal().pgp()
// MORE LOGIC
;
第一个问题:由于给定的子路由改变了原始文件集(例如,解压缩可以将一个存档转换为 100 个文件),使用 enrich() 而不是 to()?
第二个问题:我应该在这些子路由之间路由什么?现在,由于为简单起见,这里没有解释实现细节,我正在路由一个文件名的集合,所以,我有一个 from("file:data/P4") from("direct:read-P4") 接收文件名列表作为输入,然后将该列表传播到给定的子路由;每个子路由,从文件名列表开始,应用自己的逻辑,生成新文件并返回带有更新列表的主体(例如,接收 {"test.zip"} 并返回 {"文件 1.txt”、“文件 2.txt”})。 因此,给定的子路由如下所示:
from("direct:...")
// FOR EACH FILE NAME
// APPLY TRANSFORMATION LOGIC TO THE CORRESPONDING FILE
.setBody( // UPDATED LIST OF FILE NAMES )
在没有生产者 EIP 的情况下结束路由是否正确?还是我应该用生成给定新文件的 to() 来结束它?如果是这样,下一个子路由必须从同一个目录再次读取所有数据,这似乎并没有那么优化,因为我已经知道必须考虑哪些文件。
第三个问题:假设让给定的子路由转换数据并返回对应的名称列表是可以的,我应该如何测试呢?不可能模拟结束的生产者,因为我没有与生产者一起完成路线......所以,我必须使用拦截器吗?或者还有什么?
基本上,我提出这个问题是因为我有一组完美的工作路线,但是在创建测试期间,我注意到其中一些是不自然的测试......这很可能是一个结果错误的设计。
【问题讨论】:
标签: apache-camel atomic