We are using axon framework version 3.4.2 and found a bug inside our code. The bug relates to a missing event which was not published. The solution is to fix the code but this would not fix the event store and views.
My question is how would one fix this? We thought of appending the events to the event store (we use a JDBC event store), but without the correct data, the new events would not be processed. The best would be to do it in the application by publishing the event in axon and let axon handle all the details, but this is a once-off, correcting action.
Is there any way of "injecting" a once-off event into axon?
The comment which Matt shared is conceptually what you should do.
Thus, to resolve the issue you unintendedly introduced, you should produce a compensation action, aka a command. This command will be handled in your command model, will validate the model's state and publish the desired event.
Added, I am assuming this event of your should originate from an Aggregate, correct?
In Axon terms, that means you want to publish a domain event rather than a regular event.
Although you can publish events on the EventBus or store in the EventStore directly, it is rather complicated to make those domain events through that process.
Thus, as I started off with and what Matt Freeman commented on your question, a compensating action would be the way to go, with or without Axon.
Last note, know that Axon 4.2 is already out for some time now. Although Axon 3 will still under go bug fixes, none of these have occurred in the last year. Simply put, there is no active development on Axon 3. Migrating to a more recent version would thus be beneficial for your project.
Related
As a follow-up to Axon Event Published Multiple Times Over Eventbus, when using an EmbeddedEventStore and publishing a command that will attempt to create an instance of an aggregate that already exists, Axon is not throwing an exception indicating the instance exists (or constraint violation), as is on the contrary, when using Axon's JPA event store. Is this the expected behavior? If so, why?
Recently our community filed a similar issue to our repo that I am going refer here.
Essentially the JPA or JDBC implementation are responsible for catching this kind of exceptions and translating them to something the Framework understands.
If that occurs, you should see an AggregateStreamCreationException dispatched, indicating that it failed and why it failed. If this is not happening I recommend you looking into your PersistenceExceptionResolver.
If you still see this happening after checking what I shared, this is likely a bug and in this case, feel free to open it on our repo as such.
I am using Axon 3.1.1 and wanted to know,
How can I get a list of eventprocessor in my configuration file,
I went through the springAmQPmessageSource file but still not sure how to exactly do it.
So that I can pass my event to appropriate eventhandler on Query side.
List<Consumer<List<? extends EventMessage<?>>>> eventProcessors = new CopyOnWriteArrayList<>();
Updated
I was retrieving message from kafka topic and wanted to wire them to specific eventhandler but since I am not able to get evenprocessors, I am not able to do that.
Can you please tell me how to do it, if I am using Axon 3.0.5
If you're using the SpringAmqpMessageSource, you will not need to retrieve the list of eventProcessors you've shared, as Axon will automatically subscribe all the event handling components to it for you.
Subsequently, the events the Message Source receives will automatically be pushed to all the listeners in your query side.
As this is all covered as Axon infrastructure under the hood, there is no one-off way to pull them out of it for your own use (other than potentially wiring them yourself).
Hence, you shouldn't have to do this yourself.
But, maybe I'm missing an obvious point here.
Could you elaborate a little more why you need the list of handlers in the first place?
According to CQRS à la Greg Young, event handlers (and the downstream event denormalizers) react on incoming events that were published before by the event publisher.
Now lets suppose that at runtime we want to add a new event denormalizer: Basically, this is easy, but it needs to get to its data to the current state.
What is the best way to do this?
Should I send an out-of-order request to the event store and ask for all previously emitted events?
Or is there a better way to do this?
You can fetch and replay all (required) events against the new handler. This can be done in a separate process since what you essentially want is to get the persisted view models into the proper state.
Have a look at Rinat Abdullin's Lokad.CQRS sample project for a production example. Especially the SaaS.Engine.StartupProjectionRebuilder might be an interesting source even though it's rather complex.
One can also build the projections so that they remember what event they saw last. Then on any startup, they ask for this event and all forward. Re-starting an old projection and building a new one then become roughly the same thing.
If you embrace bounded context complex integration you may need to drop the entire read model and rebuild it.
Getting into CQRS and I understand that you have commands (app layer) and events (from the domain).
In the simple case where events are to update the read model, do read model updates fail? If there is no "bug" then I cannot see them failing and as I am using EventStore, I know there is a commit flag which will retry failures.
So my question is do I have to do anything in addition to EventStore to handle failures?
Coming from a world where you do everything in one transaction and now things are done separately is worrying me.
Of course there may be cases where a published event will fail in the read models.
You have to make sure you can detect that and solve it.
The nice thing is that you can replay all the events again and again so you have the chance not only to fix the error. You can also test the fix by replaying every single event if you want.
I use NServiceBus as my publishing mechanism which allows me to use an error queue. Using my other logging tools together with the error queue I can easily determine what happened since I have the error log and the actual message that caused the error in the first place.
I am trying to wrap my head around Saga's using Jonathan Olivers EventStore and CommonDomain. I understand how Aggregates are working with the CommonDomain/EventStore but I am stuck on grasping Saga usage. I have read both of Jonathan's Saga's with Event Sourcing Part I & II but sill lost in actual implementation
1) More of observation, when persisting the saga the EventStore is utilizing the Headers to persist the Saga and Commands that need to be sent out and it looks like the Payload is storing the Event that triggered the Saga to "wake up". Wondering reasons for this. Would we never want to store individual commands vs having them all in the header?
1) It seems like the Event that triggered the Saga gets replayed multiple times since the "Transition" method in SagaBase always re-adds the event to uncommitted collection. (Unlike ARs that have an internal Apply method vs public Domain method). Maybe I am not using the Transition method properly
2) Typically the bus that you use with the EventStore will publish Events (I implemented IPublishMessages). If I need my Saga to publish a command there does not seem to be a Send option. Do I need to parse the Headers to grab the commands myself?
I am thinking I am using the CommonDomain / EventStore incorrectly as working with Aggregates was easy but Saga's seem "incomplete" to me. I am assuming its because I am not doing it correctly. Still very new to CQRS. Does anyone have a working example of Saga's using J Olivers Common Domain / Event Store? I think that would clear things up considerably.
[EDIT]
I think I figured it out but would like some input. Saga's really should not be publishing events. They send out commands. Thus on the publish side of things for the EventStore (IPublishMessages) I should first be checking the type of message (AggregateType vs SagaType) For AggregateTypes I can publish Events but for SagaTypes only publish the commands (found in Header). This eliminates the same event (say OrderSubmittedEvent) that triggers the creation of the Saga to not publish it again when persisting the saga.
The commands are put in the headers to be sent on the bus. The EventStore is concerned with the storage of events so the events that caused saga transitions are persisted. Later, when the saga is loaded from the event stream, the events will be passed to the saga's transition method to bring it to the current state.
The transition method serves a dual purpose in the saga implementation. Transition is called to handle incoming messages and to load the saga from peristence. In SagaEventStoreRepository.BuildSaga ClearUncomittedEvents and ClearUndispatchedMessages are called on the saga after the current state is built up thus avoiding duplicate event and command processing.
I haven't personally done this but I would use a separate EventStore instance for my sagas. This would allow for the usage of a separate IPublishMessages implementation to take the commands from the event headers and send them.