Immutable commands using immutables.github.io

Hello,

I am trying to use Axon with https://immutables.github.io/.
I am having trouble using it with commands.
immutables allows me to easily check preconditions on command beans and of course easily generate immutable commands.

I have a command named MyCommand which is an interface:

@Value.Immutable public interface MyCommand{ String id(); }

immutables automatically generates a concrete final class named ImmutableMyCommand.

I have a spring component defining a method handling MyCommand :

`
@Component
public MyCommandHandler{

@CommandHandler
public void handle(MyCommand command){

}

}

`

When I test my code, the method handling MyCommand is never found by the CommandBus since the handler subcribred to “MyCommand” and not “ImmutableMyCommand”.

Could we add an annotation to Axon to force it to map the command interface to its unique implementation?
Is it a bad practice to handle the interface and not the implementation in the CommandHandler?

Regards.

Or can we just add a payload interface to Axon allowing only to force the command name?

Hi Réda,

by default, the name of the command in a CommandMessage is the fully qualified class name of the payload of that message. Also by default, the name of the command a handler is subscribed to, is the FQ ClassName of the expected payload.

When sending, your commandName will be mypackage.ImmutableMyCommand. The handler is subscribed to mypackage.MyCommand.

So either you should dispatch a CommandMessage with an explicitly set commandName (MyCommand), or alternatively specify a command name on your @CommandHandler annotation, being “mypackage.ImmutableMyCommand”.

Currently, the CommandGateway doesn’t allow for Command names to be explicitly defined.

Cheers,

Allard

Hi Allard,

I am using version 2.4.6.
While @CommandHandler is mapped to a FQ classname String, @EventSouringHandler is mapped to a FQ class.
Don’t you think @CommandHandler should be mapped to a FQ class?

Also don’t you think that GenericCommandMessage should be able to check for the payload type to determine the Command FQ target?

Would you accept the 2 following PRs?
1 - Add a commandClass attribute to @CommandHandler
2 - Add an interface that would be implemented by a CommandMessage payload to fix the command name by altering GenericCommandMessage like this:

public GenericCommandMessage(T payload, Map<String, ?> newMetaData) {
   String commandName = payload.getClass().getName();
   if (CommandPayload.class.isInstance(command)) {

      commandName = ((CommandPayload) command).getCommandName();
  }
    this(commandName, payload, newMetaData);
}

Hi Reda,

a solution I think would be nice for this situation (and certain similar ones) is where commands are annotated with an @Command annotation. This annotation would be @Inherited and have a String name() attribute. The default being “”, which would force Axon to use the FQCN instead. Just as it would use when the annotation is not present on the class at all.

The GenericCommandMessage.asCommandMessage() method could use this technique to resolve the command name for any payload. Proxies are implementations of another class, so if that other class has the @Command annotation, the @Inherited will make sure the generated proxy is considered annotated as well.

As far as I can tell, this solution is completely backwards compatible.

Cheers,

Allard