I want to send commands between two bounded contexts. I am using Axon Server as an event store and message handler. From what I read so far, Axon Server should automatically register as a distributed command bus. However, I get a NoCommandHandlerFoundException whenever I send a command using the command gateway.
In each service, I have identical classes for the command. I only use String and UUID as attribute data types. The packages in which the classes are located are identical as well.
Alright that clears it up a lot more for me, thanks!
The AxonServerCommandBus, used by the CommandGateway to send commands, is currently only connected to one context (let’s call it A). However, you want the command to be handled in context B.
You can supply a TargetContextResolver to the AxonServerCommandBus to resolve the context it has to send commands to. By default this resolves to context A. Writing one that resolves this command to context B should do the trick for you.
It should look like this:
@Configuration
public class AxonServerConfiguration {
@Bean
public TargetContextResolver<CommandMessage<?>> targetContextResolver() {
return message -> {
if(message.getCommandName().startsWith("de.tailord.workdutyplanning.api")) {
return "Context B";
}
return "Context A";
};
}
}
This bean is automatically picked up by the AxonServerAutoConfiguration
I had to rename the configuration class because it conflicted with a bean in the axon starter package. I also needed to add a TargetContextResolver for query messages.
After this, my bounded contexts can finally talk to each other
What is the reasoning behind the target context resolver? I imagine, that an additional target context parameter for the command gateway would be more intuitive. I don’t like that every command has to be resolved now with this redundant check 99% of the time. The only argument I can think of is location transparency but to me, this is also violated with this custom resolver that looks at the package and sets the context. I would like it to be more explicit when dispatching the command and not in some configuration bean.
As for the reasoning behind this, I think it has to do with legacy. Axon Framework has been around longer than Axon Server, and multi-context is something that came into being much later. It’s actually implementation-specific for the DistributedCommandBus, so that might also be the reason it’s not part of the generic CommandBus or CommandGateway interfaces.
Having said that, we are always looking for improvements and we will start working on Axon 5 in the near future. It would be great if you could suggest this here: Axon Framework 5 suggestions - #11 by Gerard