0

I have below code that works with spring cloud stream 3. Now I upgraded to spring cloud stream 4. EnableBinding and Source are both removed. I have read many posts regarding the deprecation of these and I know I should probably use a functional method like Supplier to replace Source. But I still don't know how to use Supplier in this example since rabbitmq container will keep running and output() will be called whenever a message is received whereas Supplier is just to define a single method and return a single value. Can anyone provide a complete code in new way not just some snippets or generic documentations?

@EnableBinding(Source.class)
public class App {
    
    @Autowired
    private Source source;

    @EventListener(ApplicationReadyEvent.class)
    public void start(ApplicationReadyEvent e) {
        
        SimpleMessageListenerContainer rabbitContainer = new SimpleMessageListenerContainer(connectionFactory);
        rabbitContainer.setMessageListener((message) -> {
            source.output().send(MessageBuilder.withPayload(message.getBody()).build(), 5000);
        })
        rabbitContainer.start();
    }
}

My 2nd attempt.

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

@Component
public class App {
    
    @Autowired
    private StreamBridge streamBridge;

    @EventListener(ApplicationReadyEvent.class)
    public void start(ApplicationReadyEvent e) {
        
        SimpleMessageListenerContainer rabbitContainer = new SimpleMessageListenerContainer(connectionFactory);
        rabbitContainer.setMessageListener((message) -> {
            streamBridge.send("output", MessageBuilder.withPayload(message.getBody()).build());
        })
        rabbitContainer.start();
    }
}

user3908406
  • 1,416
  • 1
  • 18
  • 32

1 Answers1

2

See the documentation.

Use a StreamBridge to send arbitrary output to a binding.

That said, this is not good practice...

    @EventListener(ApplicationReadyEvent.class)
    public void start(ApplicationReadyEvent e) {
        
        SimpleMessageListenerContainer rabbitContainer = new SimpleMessageListenerContainer(connectionFactory);
        rabbitContainer.setMessageListener((message) -> {
            source.output().send(MessageBuilder.withPayload(message.getBody()).build(), 5000);
        })
        rabbitContainer.start();
    }

The container needs to be managed by Spring (i.e. a Spring Bean) to get all its functionality (e.g. event publication).

You can define the container as a @Bean; it will be started during the context refresh; it is not necessary to start it manually. If you still want to do so, set its autoStartup property to false and start it whenever you want.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Thank you! can you confirm instead of doing `source.output().send()` I should do `streamBridge.send("output", MessageBuilder.withPayload(message.getBody()).build());`. ? and how do I pass the `5000` timeout? – user3908406 Jan 11 '23 at 20:06
  • You can build a message, or just send the body and the framework will create the message. There is no timeout; the timeout in this context is meaningless (even with the old style); it only applies to message channels that can block (such as a bounded `QueueChannel` which is full and can't accept more messages). Output bindings always use `SubscribableChannel` which can't time out. – Gary Russell Jan 11 '23 at 20:18
  • Thanks! I just tried this idea and added to my question. I'm getting error `No beans of 'StreamBridge' type found.`, any idea? – user3908406 Jan 11 '23 at 21:03
  • Doesn't make any sense as long as you have proper dependencies set up; there will always be a `StreamBridge` bean. I created a similar app this morning with no problems. Debug logging of context initialization should help. If you can't figure it out, post an [MCRE](https://stackoverflow.com/help/minimal-reproducible-example) someplace. You also need to fix that listener container usage as I described. – Gary Russell Jan 11 '23 at 21:29
  • I actually just found out it is just my Intellij complaining, when I actually run the code it worked. Thanks! – user3908406 Jan 11 '23 at 21:30