I'm writing integration tests for my application that sends messages to RabbitMq. As part of my test config, I'm declaring some RabbitListeners to get these messages.
I know I'm not too far off, because this is working :
@RabbitListener(bindings = @QueueBinding(
value = @Queue(
value = "myQueue",
autoDelete = "true",
exclusive = "false",
durable = "false"),
exchange = @Exchange(
value = "myExchange",
autoDelete = "true",
durable = "true"),
key = "myRoutingKey"))
public void confirmEligibilityMessage(Object eligibilityEvent) {
log.info("received message [{}]", eligibilityEvent);
receivedMessages.add(eligibilityEvent);
}
--> message is received
However, I would like the message to be converted directly to the expected type, so I'm modifying the signature of the method by adding the type of the payload :
public void confirmConsolidationEligibilityMessage(@Payload EligibilityEvent eligibilityEvent)
and I'm getting this issue :"No converter found to convert to.."
Caused by: org.springframework.amqp.support.converter.MessageConversionException: Cannot handle message
... 13 common frames omitted
Caused by: org.springframework.messaging.converter.MessageConversionException: No converter found to convert to class messaging.outgoing.EligibilityEvent, message=GenericMessage [payload={"requestCode":"someRequestCode","isEligible":false}, headers=...
I have tried what is proposed here and made my GlobalEventBusListener implement RabbitListenerConfigurer like this :
public class GlobalEventBusListener implements RabbitListenerConfigurer {
private final List<Object> receivedMessages = new ArrayList<>();
@Override
public void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {
registrar.setMessageHandlerMethodFactory(myHandlerMethodFactory());
}
@Bean
public MessageConverter jackson2Converter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
return converter;
}
@Bean
public DefaultMessageHandlerMethodFactory myHandlerMethodFactory() {
DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
factory.setMessageConverter(jackson2Converter());
return factory;
}
But I still get issues because conversion doesn't happen properly - message is different though..
Caused by: java.lang.IllegalStateException: No suitable resolver for argument [0] [type=messaging.outgoing.EligibilityEvent]
HandlerMethod details:
Controller [mocks.GlobalEventBusListener]
Method [public void mocks.GlobalEventBusListener.confirmEligibilityMessage(messaging.outgoing.EligibilityEvent)]
Any idea of what I could try ? I'm not sure how to investigate further.. Should I log all beans instantiated by Spring Boot and take it from here ? what kind of beans should be here so that it works ? With Spring Boot "magic", I initially thought that simply having a MessageConverter like below in my context would do the trick, but it looks like it's not the case :
@Bean
public MessageConverter jackson2Converter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
return converter;
}
Thanks !!
Thanks to Gary's help and a little bit more reading on the documentation, I was able to fix it. By the way I'm using Spring amqp 1.5.6, ie < 1.6.
amqpTemplate.convertAndSend
method, without converting it myself to Json, headers were set properly, to help the receiver identify the content is Json. -
@Bean
public Jackson2JsonMessageConverter jackson2Converter() {
Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter();
return converter;
}
@Bean
public RabbitListenerContainerFactory rabbitListenerContainerFactory() {
SimpleRabbitListenerContainerFactory simpleRabbitListenerContainerFactory = new SimpleRabbitListenerContainerFactory();
simpleRabbitListenerContainerFactory.setConnectionFactory(connectionFactory());
simpleRabbitListenerContainerFactory.setMessageConverter(jackson2Converter());
return simpleRabbitListenerContainerFactory;
}