***strong text***I want to use 2 aws outbound adaptor in a single integration flow. One is outbound S3 adaptor and one outbound SQS adaptor. I have to move file from smb share to S3 bucket then use the transformer and then use the SQS adaptor to send transformed message to SQS queue. I can achieve this with 2 integration flow but I want to achieve this with only one integration flow. If I add both outbound adaptor part of one flow only one of them is working
1 Answers
That’s true, two Outbound channel Adapters can’t work one after another. Just because one-way component doesn’t return anything to send as a payload into the output channel.
You might need to make yourself familiar with the publish-subscribe
pattern: https://www.enterpriseintegrationpatterns.com/patterns/messaging/PublishSubscribeChannel.html.
In the IntegrationFlow
you just need to configure a publishSubscribeChannel
with two subscribers as sub-flows for your different Channel Adapters.
See docs for more info: https://docs.spring.io/spring-integration/docs/5.1.7.RELEASE/reference/html/#java-dsl-subflows
UPDATE
Since you already have an .enrichHeaders(h->h.header("bucketName”,”mybucket”))
before publishSubscribeChannel()
, it is a fact that this one is going to be available for both subscribers downstream.
To make access into it from the s3MessageHandler
, you must configure it like this:
public MessageHandler s3MessageHandler() {
S3MessageHandler handler = new S3MessageHandler(amazonS3,
new FunctionExpression<>(m -> m.getHeaders().get(”mybucket”)));
return handler;
}
To make access to that header for your next SQS subscriber part, you need to change your transform()
method signature to accept the whole Message<>
, so you get access to headers again for building some custom message for SQS.

- 113,505
- 11
- 91
- 118
-
Well, the best way is to store that information in headers before sending to the `publishSubscribeChannel`. So, S3 Outbound Channel adapter would use them to store remote file and SQS channel adapter would reuse the same information for its goals. – Artem Bilan Sep 05 '19 at 18:00
-
Any chances to share what you have so far? What is bad in having `bucketExpression` and `keyExpression` configured on the `S3MessageHandler` ? – Artem Bilan Sep 05 '19 at 18:36
-
Please, edit your question. That code snippet is not readable in the comments. – Artem Bilan Sep 05 '19 at 18:41
-
??? I said: *edit your question*, not *my answer*. Please, be careful and respectful. You also need to keep in mind that we have our job to do as well. So, our time helping here is valuable. Thanks for understanding. Please, post as a *code* also, not a picture. It will be helpful in copy/pasting and editing. – Artem Bilan Sep 05 '19 at 18:49
-
No, it's still unreadable. What is wrong with editing your own question? Where is an S3 channel adapter? What does your `transform(m)` do? A lot of questions because of your won code. I'm not sure how to help you from here... Sorry – Artem Bilan Sep 05 '19 at 18:54
-
In what place? Expression or your `transform()`? How does exception look? – Artem Bilan Sep 05 '19 at 19:23
-
Try this, please: `new FunctionExpression
>(m -> m.getHeaders().get(”mybucket”))` – Artem Bilan Sep 05 '19 at 19:35 -
Yes, you can get all of that info in your transformer, as long as arg type is `Message>`. See headers in debug mode. And also I guess that your `payload` is `File`, so you can simply get access its name. – Artem Bilan Sep 05 '19 at 19:37
-
You can't do `.setHeader("id", generate())`. Essentially you can't modify this header at all: it is generated by the Framework. – Artem Bilan Sep 05 '19 at 20:14
-
Try `.transform(Message.class, m -> transform(m))` instead. – Artem Bilan Sep 05 '19 at 20:15
-
You know, it's getting too far from the original request in the SO topic. Let's consider to stop the discussion here! Feel free to raise you questions though! – Artem Bilan Sep 05 '19 at 20:16