首页 > 解决方案 > 尝试使用 Apache Camel 将文件上传到 Amazon S3 时出现“缺少 AWS S3 密钥标头”错误

问题描述

我正在尝试使用 Apache Camel 将 csv 文件从本地目录上传到 AWS S3。

参考此处找到的文档(https://camel.apache.org/staging/components/latest/aws-s3-component.html),我尝试创建一个像这样的简单路由(我当然删除了密钥和其他标识信息并用 [FAKE_INFO] 替换它们):

from("file:fileName=${in.headers[fileName]}")
  .to("aws-s3://[BUCKET]?accessKey=[ACCESS_KEY]&secretKey=RAW([SECRET_KEY])&region=US_EAST_2&prefix=TEST.csv");

这会导致以下错误:

错误:java.lang.IllegalArgumentException:AWS S3 Key 标头缺少 apache camel

在网上搜索了一下后,我删除了传递的前缀,而是插入了一个 .setHeader 来路由,如下所示:

from("file:fileName=${in.headers[fileName]}")
  .setHeader(S3Constants.KEY, simple("TEST.csv"))
  .to("aws-s3://[BUCKET]?accessKey=[ACCESS_KEY]&secretKey=RAW([SECRET_KEY])&region=US_EAST_2");

这很好用,只要我愿意在 setHeader 之后对所有内容进行硬编码。但是,对于我的特定用例,我需要从交换标头传递项目以提供密钥、存储桶名称和文件名(此路由由多个文件使用,这些文件根据交换标头中收到的不同标准转到不同的存储桶)。由于某种原因,一旦使用 setHeader 设置 S3Constants.KEY,我就无法再访问任何交换标头 - 事实上,我什至无法从交换标头分配 S3Constants.KEY 值。如您所见,from 部分中的文件名是通过交换标头分配的,我在那里没有遇到任何问题,所以我知道它们正在被接收到路由中。

关于如何修改此路由的任何想法,以便它允许我在没有 S3Constants 的情况下上传文件并在适当的情况下使用交换标头?

标签: javaamazon-s3apache-camel

解决方案


不确定我的理解是否正确,但在我看来

  • 题主的问题已经解决了
  • 您唯一的问题是您想要动态的静态目标地址

要定义动态目标地址,有一个“动态到

.toD(...)

您可以在这样的动态目标地址中使用例如简单的表达式

.toD("aws-s3://${in.header.bucket}?region=${in.header.region}&...")

有关更多详细信息,请参阅Camel Docs(“动态到”部分)。

顺便说一句:您写的是“交换标头”。不要将Exchange 属性邮件标头混淆!

  • Exchange 属性仅在 Exchange 包装器上,因此在 Camel 路由完成处理后随 Exchange 丢失。
  • 消息头在消息本身上,因此即使在将消息路由到队列或任何端点之后,它们也会保留在消息上。这也意味着标头必须是可序列化的。
  • 您必须以不同方式访问这两种类型。例如,在 Simple 中,您从入站消息中获取标头,${in.header.myHeader}而使用 Exchange 属性获取${exchangeProperty.myProperty}

推荐阅读