I’m currently using Axon 3.2 and I’m facing an issue with the injection of the Metadata value in my subscribing event handlers.
I’ve implemented a message dispatch interceptor as following and added it to the Command Bus.
`
public class AuthenticationInterceptor implements MessageDispatchInterceptor<Message<?>> {
@Override
public BiFunction<Integer, Message<?>, Message<?>> handle(
List<Message<?>> messages) {
return (index, message) -> SecurityContextHolder.getContext().getAuthentication() == null
? message : message
.andMetaData(Collections.singletonMap("username",
SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString()));
}
}
`
I tried to debug and I get the metadata value correctly injected in the Command Handler but it’s always null in the Event Handler method with the following signature :
I checked the domain_event_entry table and it seems that the metadata attached in the Command Dispatch interceptor aren’t persisted and therefore not forwarded to the event handlers.
Ok it seems I found the (obvious) missing part. As a command message and an event message are two separated messages, you have to explicitely tell Axon that you would like to copy the metadata attached to the former to the latter.
The right component for that seems to be the CorrelationDataProvider, and in my case the SimpleCorrelationDataProvider with the header “username”.
If you are using Spring Boot, the easiest way to configure is as following :
` @Configuration
public class AxonConfig {
@Bean()
CorrelationDataProvider correlationDataProviders() {
return new SimpleCorrelationDataProvider(“username”);
}
}
`
The bean will be picked and registered by the Axon auto configuration.
This topic is not really addressed in the official documentation ( correct me if I’m wrong), it might be worth adding a chapter about it.
I’m glad that you managed to resolve the issue. Sorry for the late response, but let me give an explanation regarding message interceptors in AxonFramework. When you registered the MessageInterceptor on command bus, it is applied only to the command messages. During command processing you’re (probably) applying events which are completely different type of messages. If you want to attach a metadata to them, you’d have to register a MessageInterceptor on the event bus. Spring boot autoconfiguration will do that automatically for you.
Thank you for your feedback, it’s really appreciated.
@Milan : That makes sense, but I guess that when it comes to authentication and authorization, it’s better to use the correlation data provider to convey this information from the command side to the read side, instead of assuming that the SecurityContext will be available from an interceptor attached to the Event Bus.
I’m trying to accomplish the same, but cannot get it to work.
I’ve created a MessageDispatchInterceptor that gets some Authentication info from the spring security context and adds it to the metadata. I see this data on the command message. So that part is working.
I’ve also added a CorrelationDataProvider bean to my config, and it’s being invoked (when I debug and set a breakpoint in the CorrelationDataProvider, the code stops there. But in my CorrelationDataProvider, the metaData of the message is always empty.
Do I need to specify all the metadata fields on my @EventHandler annoted methods? Like you I’d like to “transparently” copy over the metadata of the command message to the events being triggered from it.
In my case, I’m using a SimpleCorrelationDataProvider, whose behavior is to copy the metadata from the CommandMessage to the EventMessage for a preconfigured set of metadata keys.
Therefore, when you declare your CorrelationDataProvider bean, you have to configure it by explicitly specifying all the metadata keys you would like to access from the events messages.
In your case, you are attaching some metadata in a MessageDispatchInterceptor, let’s say credentials for example :
To make it work, you have to :
Declare a SimpleCorrelationDataProvider in your Spring configuration and pass “credentials” as a parameter as you would like to copy this metadata from the CommandMessage to the EventMessage.
Add the @MetadataValue(“credentials”) String credentials as a parameter in your @EventHandler annotated methods, this value will be automatically injected by Axon.