kamaladafrica / axon-cdi

Axon Framework CDI Integration
Apache License 2.0
6 stars 1 forks source link

Configurer #5

Closed dcdh closed 6 years ago

dcdh commented 7 years ago

Hello Alessio, Here is a new version of axon-cdi using the configurer to set up Axon.

dcdh commented 7 years ago

Here are some information about the implementation.

Observers are used to discover beans like AggregateRoot, Saga, CommandHandler and EventHandler beans. AfterBeanDiscovery is used to validate beans scoped, setup Axon using the Configurer and produce CDI beans if some of them are missing AfterDeploymentValidation is used to start every Axon components.

The entrypoint (ExecutionContext) contains a list of Agggregates, Sagas and Handlers having same execution context. (Cf. AggregateRootBeanInfo isSameContext methods). Each ExecutionContext will used a Configurer and next a Configuration to setup Axon and CDI beans.

AfterBeanDiscovery

-Beans scoped validation

Axon components (like CommandBus, CommandGateway, EventStore...) must be ApplicationScoped. When a CommandGateway is injected in an application this reference must refer to a configurer one which can handle command events and not a new reference of CommandGateway. However it is preferable for some other beans like Aggregates, Sagas, CommandHandlers and EventHandlers to be dependant scoped. A decorator is used to validate each Beans. If one scope is wrong an exception is raised and the application stopped.

-Axon Configurer

The configuration of Axon has changed in version 3.x. Now a Configurer is present to setup each component. A decorator is used to setup each component depending of beans Produces. Also, note that I have used proxies because Components in Configurer need the reference of Bean which cannot be retrieved in the AfterBeanDiscovery phase. Each proxy made a call to CDI to retrieve the reference of the Bean. This call is not made in the Configurer. The Configurer just want to know if a reference is present.

-Produce CDI beans

At this point a Configuration is build from the Configurer. The Configuration will used references (proxies) previously defined in the Configurer. If Component have not be registered default one will be created by the Configuration. A decorator is used to check if Axon beans are presents or not and create CDI beans if needed. I have also used decorators for each CDI beans.

AfterDeploymentValidation

Each configuration are started. Objects in proxies are retrieved.

kamaladafrica commented 7 years ago

I don't think that axon components should be application scoped. Suppose we have to develop a multitenant application. For some reasons, we have to choose a schema for each tenant strategy (actually two schemas for tenant, one for event and one for the query part) and a schema (two) for global operations (tenant registration, for example). So we can have an application scoped command gateway, but we need to choose the right eventstore at "request" time and depending from aggregate to update. (Those were the requirements of the application that led to the creation of this project)

Can those requirements be fulfilled by this approach?

dcdh commented 7 years ago

Some Axon components must be application scoped to avoid side effects. A command bus must be unique on a CQRS architecture to ensure that a same aggregate is not impacted several times at a same time to avoid locking failure. The DisruptorCommandBus is a good implementation for an unique instance CommandBus with a fast througput. Regarding CommandGateway, it is only a facade holding a reference of a CommandBus. It purpose is to give methods to send command. So CommandGateway should follow the scope of the CommandBus. If scale horizontaly (by adding machines) must be used a distributed CommandBus and a distributed EventBus should be used. Axon provides some Spring projects (axon-distributed-commandbus-jgroups, axon-distributed-commandbus-springcloud, axon-amqp) and they can be used as an example for porting theses concepts to JEE.

Curently I have not work on distributing an Axon application. Distributing an application is far more complicated as it have to be splitted in differents parts (api, impl) and I don't even speak about separing the production with blue, green environnements and also events replaying... So I've just translate a simple, single jvm application in CDI like they do with SpringAxonAutoConfigurer using Configurer and Configuration. Regarding EventBus, no matter the number of EventBus bean declared they used the method findComponent which will return the first bean found even if multiple are presents. Also, the configurer (method configureEventStore) can't handle multiple EventStore. To respond to your question you can't choose the right event store but you can choose the right CommandGateway associated with the aggregate in the command handler.

Moreover, regarding projections (aka query part) I've don't have a good visibiliy yet on how Axon works regarding event handlers and infrastructure. I mean that an event can be handled by a jpa infrastructure, a mongo infrastructure, a solr infrastructure, a CMIS infrastructure together. Maybe that I Will have to make an event handler for each infrastructure to separate transactions. But how the token store will handle each event handler ? Globally an all event handler or separatly on each handler ?

To resume, I've just analysed what was Configurer inputs and Configuration outputs and make everythings work. My next step is to make a test in a wildfly swarm application with JPA, Mongo, CMIS and Solr to understand how projections (aka query part) work in Axon.