Saga Event processing Query

Hi,

I’m facing issues related to Saga configuration with clustered-event bus (with amqp-rabbit).

Issue 1:
Any SagaEventHandler configured after the first type (in this case com.test.EventHandler1) is not consuming the events.They are remaining in the rabbit-queues with status ‘ready’.

If i switch com.test.EventHandler2 with com.test.EventHandler1 then com.test.EventHandler2 gets triggered.

Not sure if there is any mistake in the below configuration.

Spring-config below
`
<axon:saga-manager id=“sagaManager” event-bus=“eventBus” saga-repository=“sagaMongoRepository”>
<axon:async transaction-manager=“transactionManager”/>
axon:types
com.test.EventHandler1,
com.test.EventHandler2
</axon:types>
</axon:saga-manager>



`

EventHandlers
`
package com.test
@Component
public class EventHandler1 extends AbstractAnnotatedSaga {

@StartSaga
@SagaEventHandler(associationProperty = “sagaIdentifier”)
@Transactional
public void handleEvent1(Event event, @Timestamp DateTime time) { …}
}
package com.test

@Component
public class EventHandler2 extends AbstractAnnotatedSaga {

@StartSaga
@SagaEventHandler(associationProperty = “sagaIdentifier”)
@Transactional
public void handleEvent2(Event event, @Timestamp DateTime time) { …}
}

`

Issue2:

The eventlistener is throwing below exception when persisting the saga in MongoDB.

`
[WARN] org.axonframework.saga.annotation.AsyncAnnotatedSagaManager$LoggingExceptionHandler - A fatal exception occurred while processing an Event for a Saga. Processing will continue with the next Event
org.axonframework.serializer.SerializationException: An exception occurred writing serialized data to the output stream
at org.axonframework.serializer.JavaSerializer.serialize(JavaSerializer.java:72) ~[axon-core-2.3.2.jar:2.3.2]
at org.axonframework.saga.repository.mongo.SagaEntry.(SagaEntry.java:65) ~[axon-mongo-2.3.2.jar:2.3.2]
at org.axonframework.saga.repository.mongo.MongoSagaRepository.storeSaga(MongoSagaRepository.java:117) ~[axon-mongo-2.3.2.jar:2.3.2]
at org.axonframework.saga.repository.AbstractSagaRepository.add(AbstractSagaRepository.java:51) ~[axon-core-2.3.2.jar:2.3.2]
at org.axonframework.saga.annotation.AsyncSagaEventProcessor.persistProcessedSagas(AsyncSagaEventProcessor.java:219) ~[axon-core-2.3.2.jar:2.3.2]
at org.axonframework.saga.annotation.AsyncSagaEventProcessor.doProcessEvent(AsyncSagaEventProcessor.java:147) ~[axon-core-2.3.2.jar:2.3.2]
at org.axonframework.saga.annotation.AsyncSagaEventProcessor.onEvent(AsyncSagaEventProcessor.java:118) ~[axon-core-2.3.2.jar:2.3.2]
at org.axonframework.saga.annotation.AsyncSagaEventProcessor.onEvent(AsyncSagaEventProcessor.java:49) ~[axon-core-2.3.2.jar:2.3.2]
at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:133) ~[disruptor-3.2.0.jar:na]
at org.axonframework.saga.annotation.AsyncAnnotatedSagaManager$StartDetectingRunnable.run(AsyncAnnotatedSagaManager.java:481) [axon-core-2.3.2.jar:2.3.2]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_25]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_25]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_25]
Caused by: java.io.NotSerializableException: org.axonframework.eventhandling.ClusteringEventBus

`

Let me know if you need more information.

Thanks,
Jebu.

Both the issues are apparently configuration issues. Just posting on this thread for future reference:

Issue1 (Any SagaEventHandler configured after the first type is not consuming the events)
SagaManager is essentially an EventListener and hence while subscribing it is wired to a single cluster which by default is using the first axon-type.

Fix: For 2 clusters, configuring 2 separate SagaManagers with corresponding axon-types resolves this.

Issue2 (The eventlistener is throwing below exception when persisting the saga in MongoDB.)

  • For persistent saga, missed marking the resources as ‘transient’.
  • Axon was trying to persist the Eventbus which was injected by spring-resource injector (which is definitely not what i wanted).

Fix: Marked the injected resources as ‘transient’

Thanks,
Jebu.

Hi,

thanks for posting the solution.
The first issue looks weird though. It should be perfectly fine to use multiple saga types in the same Saga Manager.
Which Axon version do you use?

Cheers,
Allard

Allard,

Thanks for your reply.

Axon version: 2.3.2 / Rabit MQ 3.4.3/Spring AMQP-1.2.1

Actually, I have a follow-up question on the persistence of SAGA in MongoDB.

Scenario 1 (Resource-Injector for Event Chaining within Sagas)

Pseudo code below:

`
transient eventBus
transient repository

@StartSaga
@SagaEventHandler(order-key)
EH1 (OrderCreatedEvent)
{
//do processing
eventBus.publish(OrderSaveEvent)
}

@EndSaga
@SagaEventHandler(order-key)
EH2 (OrderSavedEvent)
{
repository.save()
}

@Resource
setEventBus(){}
@Resource
setRepository(){}
`

We are seeing the ‘ResourceInjector’ is working only for the first event and the second event (OrderSaved) is failing with ‘NullPtrException’ as the ‘repository’ is not injected.

Scenario 2 (Reprocess of event for which Saga is Open)

The same behavior appears when the second time a new OrderCreatedEvent repeats(say reprocessed) when the persisted-saga (which is still open) is deserialized. This also doesn’t have the resources injected. Is this by-design or is there a mis-configuration.

Relevant Spring config below:
`
<axon:saga-manager id=“sagaManager” event-bus=“eventBus” saga-repository=“sagaMongoRepository”
resource-injector=“sagaInjector”>
<axon:async transaction-manager=“transactionManager”/>
axon:types
com.mycompany.myapp.event.saga.OrderCreatedSaga
</axon:types>
</axon:saga-manager>




`

Thanks,
Jebu.

Which repository are you injecting? I don’t see a repository defined in your Spring context (other than the Saga one, which you should never have to inject).

You don’t have to specify the resoucre injector, as the Spring one is the default when using the element.

Cheers,

Allard

Not clear on your question. The Saga has 2 attributes (eventBus, repository - JPA repo). Both are injected via @Autowired. Now, both the resources are available for the first event (based event triggered). But both the attributes are null when subsequent events are fired from the base-event (scenario 1) OR existing Saga is processed (scenario 2)

Just to clarify, is there any convention/config required by the resource-injector to inject the resources every time the Saga is invoked?

Thanks,
Jebu.

Hi,

I was misguided by the code. My bad.
The problem is in the configuration: your repository needs to (also) have a link to the resource injector.

So putting a
inside your …</…> should solve the issue.

Cheers,

Allard

Fantastic! This works a charm. Thanks for pointing out.