Adding new field to domainevent entry table to store api gateway header details in event store domainevententry table

Hello all,

How to to customize/add new field to domain event entry table to track audit history of consumer or application id from gateway api in axon spring boot applications?

Any generic way to set new field values for all events in framework level instead of adding the header details to each event?

Any generic ways to store request header related data from api in a new custom field in domain event entry table and how to send it from command gateway? Is there any documentation already exists for this?

Thanks in advance

Hi there Angela!

Axon Framework supports what you’re asking for, in the form of MetaData. Any message (command, event, query) in Axon Framework can carry MetaData and can be provided with their respective dispatch mechanisms (CommandGateway, AggregateLifecycle, etc).
It is briefly described in the reference guide section about Message anatomy.

MetaData added to events will be stored to the DomainEventEntry table, in the respective column, serialized to the format configured for that (Most of the time XML or JSON). This way the information can be audited.

MetaData added to command will not be copied to Event MetaData automatically. For this you will need a CorrelationDataProvider, which is responsible for relating commands to events.

So, to summarize, you will need to implement the following:

  • Add the MetaData that you want in the events to the Command
  • Add a CorrelationDataProvider to copy that MetaData to the events
  • Add the CorrelationDataProvider to your configuration

If there are any questions left, please let me know. I hope this helps!

Hello Morlack,
Thanks for the reply. Can we use some message dispatch interceptors so that to pass metadata directly from rest controller class without passing as metadata parameter. Is it possible to define metadata in rest controller class with MetaData metadata = MetaData.with(“consumerappname”,“test”); and to use @metadatavalue in eventhandlers. Then how it is dispatched from rest controller command classes to events without passing as parameters in command handlers?

Hi Angela,

Yes, a MessageDispatchInterceptor registered to your commandBus will be able to add Metadata. The following could be used as an example:

public class UserAddingInterceptor implements MessageDispatchInterceptor<CommandMessage<?>> {
    @Override
    public BiFunction<Integer, CommandMessage<?>, CommandMessage<?>> handle(List<? extends CommandMessage<?>> list) {
        return (i, m) -> m.andMetaData(Map.of("user", "name"));
    }
}

The @MetaDataValue can be used in all handlers of Axon Framework to get a certain MetaData property, such as the user one added above here.
The CorrelationDataProvider I described in my previous will automatically copy the command metadata to the event.

1 Like

Hello Morlack,

Thanks for the quick reply. Tried the interceptor code. In above example
Instead of hard coded vale like “value” is it possible to get some header values from request of restcontoller class directly in UserAddingInterceptor ."With hardcoded value of Map.of(“user”, “name”) I am able to add metadata of name value.
Getting the header value related to headers instead of hardcoded value for key üser directly in interceptor is the hardest part now. Looking for a solution to get request header values or some variables in restcontroller in interceptor instead of adding metadata to every command. Thanks in advance

Hi Angela,

that should be possible making it a bean and injecting the authorization context. But it all depends on the exact library combination of your system an how it is configured. I would suggest looking it up in the Spring documenation. But if it’s Spring Boot (or something alike) I can point you in the right direction:

RequestContextHolder.getRequestAttributes()

This will hold the HTTP request attributes if there is a HTTP call. Perhaps this works for you, since you should have access to the headers there.

1 Like

Hi Morlack,

Thanks for the response. Implementing Metadata and dataproviders able to apply the metadata value for all events commands. Thanks once again for the suggestions.

Hi @angela,

Just to add to what @Morlack told you, on Axon Framework 4.5.8 we introduced some utility methods on the CommandGateway that could help with this!

Have a look at this PR: Allow insertion of `MetaData` on the `CommandGateway`'s API by smcvb · Pull Request #2085 · AxonFramework/AxonFramework · GitHub

KR,

@Morlack , @lfgcampos Thanks for the responses. We have implementedadding metadta using interceptors and it is working fine. Any idea to view metadata from postgres pgadmin using queries. The data is stored as bytea (binary data) and not able to view or read from pgadmin for postgres. Thanks in advance.

Hey Angela,

This sounds like Postgres TOAST at work. Postgres stores a pointer to the actual data (which is an ID). There are queries available to extract the data, but there are downsides to TOAST. For example, there is an upper limit on how many TOAST objects can be stored because it can run out of IDs.

A colleague recently created a blog on this, and I think reading that will explain it much better than I can. I bet this approach can be applied for metadata columns as well. Good luck!