Can a subsystem add a property with a computed value to every JMS message?
bernd.koecke Dec 15, 2015 8:31 AMHello,
first my motivation for this feature: In the old days we had an application running on an application server cluster, but now we have small services running on a number of nodes. And calling these services in some order builds a business transaction. If something happens we have to look into the log files of all services. We use ELK to have all log events at one place. But we need a unique id attached to the business transaction to correlate the log events of one call chain.
I'm building a subsystem for WildFly 10 to provide this feature. If a call reaches our server and no id is attached, the subsystem creates a UUID, attaches it and send it behind the scenes to other servers. After creation the id is part of the invocation and logging context and is send to Elasticsearch with every log event. It is not necessary to write code in EJBs for handling this id. Because the EJB3 subsystem has a very fine grained structure, I got it working for EJBs with local, remote and asynchronous calls. I hope I will get it working for REST and SOAP calls, CDI and EJB interceptors, too.
At the moment I try to get it working for JMS (2.0) implemented by the messaging-activemq subsystem in WildFly 10 but I got stuck. I would like to add a property to each JMS message which is send, from an EJB. But at that moment when I inject a connection factory or a JMSContext and send a message, I'm leaving the EJB container and I can't find a way of adding some kind of interceptor to the messaging subsystem. I tried the following so far:
My first idea was sub classing and using the delegator pattern for the connection factory and JMS context.. But because of final classes and methods together with the JMSProducers convenience methods, e.g send(destination, map), I don't think that this can work.
I found the "outgoing-interceptors" in the messaging subsystem configuration and I added one, but its called to late. The invocation context with my tracking id is a ThreadLocal and this kind of interceptor is called after a thread change and so I don't have access to my context and id any more.
There is an instance of ActiveMQs ChannelImpl called from the right thread when a message is sent and it has a currently empty interceptor list, but I can't find a way of adding my interceptor. Maybe I can add one with some dirty hacks, but I'm searching for a solution which doesn't break in the next messaging subsystem version.
Does anybody know a way of adding some kind of interceptor to the messaging subsystem which is in the call chain of the EJB container thread (named e.g. "EJB default - <num>") before a message is sent? Or maybe a completely different solution for adding a property to JMS messages?
Thanks a lot for your help! Regards
Bernd