I'm using spring-jms with azure's servicebus. I'm trying to use selector to distinguish between message types, but I can't get it working. This is my code.
@Component
@Slf4j
public class MessageTestRunner implements CommandLineRunner {
private static final String QUEUE_NAME = "lva-test-queue";
private static final String PING_SELECTOR = "selector = 'PING'";
private static final String PONG_SELECTOR = "selector = 'PONG'";
private static final String SB_SCHEDULED_ENQUEUE_HEADER = "x-opt-scheduled-enqueue-time";
private final JmsTemplate jmsTemplate;
public MessageTestRunner(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
@Override
public void run(String... args) throws Exception {
jmsTemplate.convertAndSend(QUEUE_NAME, ping(), m -> {
m.setStringProperty("selector", "PING");
return m;
});
jmsTemplate.convertAndSend(QUEUE_NAME, pong(), m -> {
m.setStringProperty("selector", "PONG");
return m;
});
}
private PingMessage ping() {
final PingMessage msg = new PingMessage();
msg.setAt(ZonedDateTime.now());
return msg;
}
private PongMessage pong() {
final PongMessage msg = new PongMessage();
msg.setAt(ZonedDateTime.now());
return msg;
}
@JmsListener(destination = QUEUE_NAME, selector = PING_SELECTOR, containerFactory = JMS_FACTORY_NAME)
public void handle(PingMessage message) {
log.debug("Handling ping message [{}]", message);
}
@JmsListener(destination = QUEUE_NAME, selector = PONG_SELECTOR, containerFactory = JMS_FACTORY_NAME)
public void handle(PongMessage message) {
log.debug("Handling pong message [{}]", message);
}
}
and this is the exception which I get
org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Listener method could not be invoked with incoming message
Endpoint handler details:
Method [public void com.example.MessageTestRunner.handle(com.example.data.model.PingMessage)]
Bean [com.example.MessageTestRunner@7aae1170]
; nested exception is org.springframework.messaging.converter.MessageConversionException: Cannot convert from [com.example.data.model.PongMessage] to [com.example.data.model.PingMessage] for org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage@72eb85b7, failedMessage=org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage@72eb85b7
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:118) ~[spring-jms-5.3.10.jar:5.3.10]
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:77) ~[spring-jms-5.3.10.jar:5.3.10]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:736) ~[spring-jms-5.3.10.jar:5.3.10]
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:696) ~[spring-jms-5.3.10.jar:5.3.10]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:674) ~[spring-jms-5.3.10.jar:5.3.10]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:318) ~[spring-jms-5.3.10.jar:5.3.10]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:257) ~[spring-jms-5.3.10.jar:5.3.10]
Is there some configuration/... which should I change to enable selector?
EDIT: The problem seems to be when I disable sending of PONG message, then PONG handler is receiving also PING messages and I can see the error in logs. However I would expect that PING message is never sent to PONG handler as there is selector that won't allow that.
EDIT2: Seems like selector is supported only in service bus premium tier which supports JMS 2.0 (link)
So the issue is with service bus itself. We are using service bus in standard tier which doesn't support selector. More details here and here