Multi upcasting in Axon 3.1.1 : possible regression ?

120 views
Skip to first unread message

Nicolas Terendij

unread,
Feb 15, 2018, 4:36:23 AM2/15/18
to Axon Framework Users
Hello,

we are using axon in production and we have a potential regression concerning upcasting when upgrading to Axon 3.1.1.

With Axon 3.1 we have an upcaster spring bean that upcasts from one event to three events and it works perfectly :

@Component
public class MyUpcaster extends EventMultiUpcaster {
private static SimpleSerializedType targetType = new SimpleSerializedType("my.events.Event", "1");

@Override
protected boolean canUpcast(final IntermediateEventRepresentation ir) {
return ir.getType().equals(targetType);
}

@Override
protected Stream<IntermediateEventRepresentation> doUpcast(final IntermediateEventRepresentation ir) {
return Stream.of(
ir.upcastPayload(
new SimpleSerializedType("my.events.Event", "2"), JsonNode.class, jsonNode -> jsonNode),

ir.upcastPayload(
new SimpleSerializedType("my.events.OtherEvent1", "1"), JsonNode.class, jsonNode -> jsonNode),

ir.upcastPayload(
new SimpleSerializedType("my.events.OtherEvent2", "1"), JsonNode.class, jsonNode -> jsonNode)
);
}
}

The following handlers are called

@Aggregate(type = "myAggregate")
public class MyAggregate {
...

@EventSourcingHandler
public void on(final my.events.Event event){
OK PASS INTO HANDLER
}

@EventSourcingHandler
public void on(final my.events.OtherEvent1 event){
OK PASS INTO HANDLER
}

@EventSourcingHandler
public void on(final my.events.OtherEvent2 event){
OK PASS INTO HANDLER
}
}

When upgrading from axon 3.1 to 3.1.1, only  the first handler is called

@Aggregate(type = "myAggregate")
public class MyAggregate {
...

@EventSourcingHandler
public void on(final my.events.Event event){
OK PASS INTO HANDLER
}

@EventSourcingHandler
public void on(final my.events.OtherEvent1 event){
KO DO NOT PASS INTO HANDLER
}

@EventSourcingHandler
public void on(final my.events.OtherEvent2 event){
KO DO NOT PASS INTO HANDLER
}
}

Thanks to unit tests and ConcatenatingDomainEventStream.java javadoc we have found a workaround.
We have to set an incremented sequence number in each IntermediateEventRepresentation

@Component
public class MyUpcaster extends EventMultiUpcaster {
private static SimpleSerializedType targetType = new SimpleSerializedType("my.events.Event", "1");

@Override
protected boolean canUpcast(final IntermediateEventRepresentation ir) {
return ir.getType().equals(targetType);
}

@Override
protected Stream<IntermediateEventRepresentation> doUpcast(final IntermediateEventRepresentation firstRepresentation) {

//first representation sequence number is equal to zero (in our case)
GenericDomainEventMessage<my.events.OtherEvent1> secondEventMessage = new GenericDomainEventMessage<>(
firstRepresentation.getAggregateType().get(), firstRepresentation.getAggregateIdentifier().get(), firstRepresentation.getSequenceNumber().get()+1L, new my.events.OtherEvent1());

EventData<?> secondEventData = new DomainEventEntry(secondEventMessage, serializer);

InitialEventRepresentation secondRepresentation =
new InitialEventRepresentation(secondEventData, serializer);

GenericDomainEventMessage<my.events.OtherEvent2> thirdEventMessage = new GenericDomainEventMessage<>(
firstRepresentation.getAggregateType().get(), firstRepresentation.getAggregateIdentifier().get(), firstRepresentation.getSequenceNumber().get()+2L, new my.events.OtherEvent2());

EventData<?> thirdEventData = new DomainEventEntry(thirdEventMessage, serializer);

InitialEventRepresentation thirdRepresentation =
new InitialEventRepresentation(thirdEventData, serializer);

return Stream.of(
firstRepresentation.upcastPayload(
new SimpleSerializedType("my.events.Event", "2"), JsonNode.class, jsonNode -> jsonNode),

secondRepresentation.upcastPayload(
new SimpleSerializedType("my.events.OtherEvent1", "1"), JsonNode.class, jsonNode -> jsonNode),

thirdRepresentation.upcastPayload(
new SimpleSerializedType("my.events.OtherEvent2", "1"), JsonNode.class, jsonNode -> jsonNode)
);
}

And Now all handlers are called again

@Aggregate(type = "myAggregate")
public class MyAggregate {
...

@EventSourcingHandler
public void on(final my.events.Event event) {
OK PASS INTO HANDLER
}

@EventSourcingHandler
public void on(final my.events.OtherEvent1 event) {
OK PASS INTO HANDLER
}

@EventSourcingHandler
public void on(final my.events.OtherEvent2 event) {
OK PASS INTO HANDLER
}

Questions :
Is it a side effect since 3.1.1 ? or the new behaviour ?
Are we doing something wrong ?

Many thanks.

Nicolas

Richard Capraro

unread,
Feb 19, 2018, 11:08:23 AM2/19/18
to Axon Framework Users
+1

Steven van Beelen

unread,
Feb 22, 2018, 4:14:49 AM2/22/18
to axonfr...@googlegroups.com
Hi Nicolas, Richard,

Sorry for the long wait, this required some discussion over here to figure it out.
First off, you should not have to adjust the sequence id when upcasting your events, also in the scenario where you're using an `EventMultiUpcaster`.
The `ConcatenatingDomainEventStream` should be able to coop with this scenario and leave any events in the initial event stream with reoccuring sequence ids.
Only when it starts reading form the following stream should it ignore sequence ids it has already encountered.
I've just created this issue as documentation for the problem and will be trying to solve it today.

It's slated for 3.1.3, which we're trying to release this week.
So, stay tuned!

Cheers,
Steven

On Mon, Feb 19, 2018 at 5:08 PM Richard Capraro <richard...@gmail.com> wrote:
+1

--
You received this message because you are subscribed to the Google Groups "Axon Framework Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to axonframewor...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Richard Capraro

unread,
Feb 22, 2018, 8:08:21 AM2/22/18
to Axon Framework Users
Hi Steven,
thank you very much for this answer !

We will surely use the new 3.1.3 version as soon as it is released.

Cheers,

Richard (and Nicolas :-))

Steven van Beelen

unread,
Feb 26, 2018, 3:58:31 AM2/26/18
to axonfr...@googlegroups.com
Hi Nicolas, Richard,

The issue is resolved and merged to 3.1.3, which is now available for download.

Cheers,
Steven

--

Nicolas Terendij

unread,
Mar 9, 2018, 10:09:26 AM3/9/18
to Axon Framework Users
Hello,

with 3.1.3 it works again !! Good job :) 

Many thanks.

Nicolas & Richard

Steven van Beelen

unread,
Mar 11, 2018, 11:31:44 AM3/11/18
to axonfr...@googlegroups.com
Hi Nicolas and Richard,

Great to hear that solved it for you guys! :)

Cheers,
Steven

--
Reply all
Reply to author
Forward
0 new messages