How to consume an XML message from RabbitMQ in Spring Boot - spring-boot

My requirement is such that, i will be getting an application/xml message from rabbit mq, which has to be consumed by SpringBoot. I am able to get it as a string, but when I create an entity and try to get the xml as a java object, it throws the following error:
org.springframework.amqp.rabbit.listener.exception.ListenerExecutionFailedException: Listener method could not be invoked with the incoming message
and followed by
Caused by: org.springframework.messaging.converter.MessageConversionException: Cannot convert from [[B] to [com.boot.RabbitListener.Model.XmlEntity] for GenericMessage [payload=byte[4], headers={amqp_receivedDeliveryMode=NON_PERSISTENT, amqp_receivedRoutingKey=jsa.queue1, amqp_deliveryTag=1, amqp_consumerQueue=jsa.queue1, amqp_redelivered=false, id=0afca290-7ee2-36f5-4297-afeacbc451da, amqp_consumerTag=amq.ctag-HZO32UVNiMf9hWo_pAr9Bw, contentType=application/xml, timestamp=1542820548981}]
I am new to SpringBoot and i read some articles in marshler, but i am not sure on how to use it.

Provide a Jackson2XmlMessageConverter as Bean in your configuration as stated in the documentation:
#Bean
public Jackson2XmlMessageConverter xmlMessageConverter() {
return new Jackson2XmlMessageConverter();
}

Related

Spring Kafka failed to resolve className

I am trying to send a data object from one spring service to another service using kafka.
The problem is that kafka is not able to resolve the className and hence is unable to map the consumber's class to the producer's class.
Following is the error message:
Caused by: org.springframework.messaging.converter.MessageConversionException: failed to resolve class name. Caused by: java.lang.ClassNotFoundException
I have tried to map the class using the following property:
For the producer: spring.kafka.producer.properties.spring.json.type.mapping=event:com.ankit.orderservice.event.OrderPlacedEvent
For the consumer: spring.kafka.consumer.properties.spring.json.type.mapping: event:com.ankit.OrderPlacedEvent

NoSuchMethodError when trying to map Kafka binder to input method

The following is prompted in console when trying to launch a spring cloud streams project with the Kafka binder active:
org.springframework.context.ApplicationContextException: Failed to start bean 'inputBindingLifecycle';
Caused by: java.lang.NoSuchMethodError: java.util.List.of(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/List;
My input method goes as follows using Spring Cloud functions:
#Bean
public Function<Message<String>, byte[]> exec() {
return input -> ...
Now, having Kafka in place, my .properties file looks as follows:
spring.cloud.stream.function.bindings.exec-in-0=in
spring.cloud.stream.bindings.in.destination=topic-0
spring.cloud.stream.function.bindings.exec-out-0=out
spring.cloud.stream.bindings.out.destination=topic-1
spring.cloud.stream.bindings.in.binder=kafka
spring.cloud.stream.kafka.bindings.in.consumer.configuration.value.deserializer=org.apache.kafka.common.serialization.StringDeserializer
spring.cloud.stream.bindings.out.binder=kafka
spring.cloud.stream.kafka.bindings.out.producer.configuration.value.serializer=org.apache.kafka.common.serialization.ByteArraySerializer
Am I missing any configs for the input method? Should that method be different for Kafka (already tested this with PubSub and it works)?
The error in your stack trace gives us a clue that you are facing this problem: https://github.com/spring-projects/spring-integration/issues/3761.
So, or upgrade to the latest Spring Cloud Stream: https://spring.io/projects/spring-cloud-stream#learn
Or to the latest Spring Integration: https://spring.io/projects/spring-integration#learn
Or just use Java > 8 !

Throwing exception outside of Flux/Mono reactive pipeline

In my spring JMS listener onMessage method, I am using a reactive pipeline as as below where I receive a JMS message from a queue and transform that to a different format and publishing to another topic. Without the reactive flow, in the case of failure in output publishing, I can throw a runtimeexception for the same message to redeliver from the queue. But by using the below flow of reactive approach, I cannot find a way to throw an exception outside. Can you please help on what should be the approach here for throwing the exception outside to get the message redelivered
public void onMessage(Message message) {
Mono.just(message)
.doOnNext(LoggingUtil::logMessage)
.flatMapIterable(messageTransformer::transformToTriggerEvents)
.doOnNext(LoggingUtil::logTriggerEvent)
.doOnNext(triggerEventPublisher::publish)
.subscribe();
}

IBM MQ ignores JMS ExceptionListener registered by Camel + Spring Boot based app

We develop a microservice based on Apache Camel JMS component and Spring Boot. IBM MQ is used as messaging middleware. There is an issue with exception listener - IBM MQ classes can't find registered exception listener and print it's own stack trace in system out when connection with MQ is broken:
com.ibm.msg.client.jms.internal.JmsProviderExceptionListener
The exception is ignored as no exception listener is registered: '
Message : com.ibm.msg.client.jms.DetailedJMSException: JMSWMQ1107: A problem with this connection has occurred.
An error has occurred with the IBM MQ JMS connection.
Use the linked exception to determine the cause of this error.
org.springframework.jms.connection.CachingConnectionFactory is used for connection setup.
#Bean
protected final ConnectionFactory createMqJmsConnectionFactory() {
MQQueueConnectionFactory mqFactory = new MQQueueConnectionFactory();
// Factory setup
CachingConnectionFactory cachingFactory = new CachingConnectionFactory(mqFactory);
return cachingFactory;
}
CachingConnectionFactory's ancestor implementes javax.jms.ExceptionListener and, as I found on Spring forum, registers itself as exceptionListener. From stack trace I can see that onException() method is invoked after exception, resets connection and writes log.
So we have a situation when IBM MQ ignores CachingConnectionFactory as exception listener. Camel JMS component has exceptionListener endpoint configuration option - I assume, adding of the CachingConnectionFactory here would be redundantly.
Any other settings need to be done in order to register CachingConnectionFactory as exception listener?

JmsTemplate.convertAndSend throws Uncategorized exception occured during JMS processing; javax.jms.JMSException: java.io.InterruptedIOException

I was getting below exception when I tried to send a message to activemq Queue in my mule component using spring jms.
java.io.InterruptedIOException
at org.apache.activemq.transport.WireFormatNegotiator.oneway(WireFormatNegotiator.java:102)
at org.apache.activemq.transport.MutexTransport.oneway(MutexTransport.java:68)
at org.apache.activemq.transport.ResponseCorrelator.asyncRequest(ResponseCorrelator.java:81)
at org.apache.activemq.transport.ResponseCorrelator.request(ResponseCorrelator.java:86)
at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1394)
at org.apache.activemq.ActiveMQConnection.ensureConnectionInfoSent(ActiveMQConnection.java:1510)
at org.apache.activemq.ActiveMQConnection.createSession(ActiveMQConnection.java:325)
at org.springframework.jms.support.JmsAccessor.createSession(JmsAccessor.java:196)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:457)
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:543)
at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:653)
Code :
Using spring jms to send a message to queue. getting exception in the below line.
jmsTemplate.convertAndSend( queueName, jmsEventWrapper.wrapEvent(event), setDelay );
Please help.
Thanks.

Resources