AxonFramework / AxonFramework

Framework for Evolutionary Message-Driven Microservices on the JVM
https://axoniq.io/
Apache License 2.0
3.3k stars 788 forks source link

Granular Axon Starter "use case" selection #1256

Open jangalinski opened 4 years ago

jangalinski commented 4 years ago

This is somewhat related to #1247 ... In my microservice project, I have apps that only want to use the querygateway for direct queries to the server or the eventgateway to build custom projections.

I want to keep using the spring autoconfiguration so the apps using these features don't have to do custom context configuration. But using the spring-starter, I get all features at once. So my app also gets a command gateway and (and this hurts) wants to build a JpaSagaStore although it will never handle any sagas itself (this happens because the JpaAutoConfiguration becomes active if my project uses jpa - which it does, for its own persistence).

I solved this by excluding the JpaAutoConfiguration, but it would be great if there was a way to enable features via properties or profiles ... My idea would be, that no features are active by default (or at most the query gateway) and I enable command and eventgateway explicitely.

smcvb commented 4 years ago

Hi Jan, interesting suggestion you come up with. To be honest, I am not entirely sold at the moment for the idea.

So, would you mind elaborating why excluding an auto-config class in the SpringBootApplication annotation is more work then defining what to enable/disable in a property file? Maybe if I see it in a different light it makes more sense to include.

jangalinski commented 4 years ago

I am currently "modularizing" the axon-starter by "UseCase" (or "OperationMode") in my project.

So far, I identified the following ("I" is the application using axon):

Query-Only

Event Tracking

Event Subscribing

CommandHandling

Full-Axon

Currently, when I use the axon-starter, the autoconfiguration is grouped by technology. If I have JPA, I get SagaStore and TokenStore ... so I am always in "Full" OperationMode.

I want to give apps that connect to the server the choice which role they want to take. I also want to limit what certain applications can do ... if I need a sophisticated saga to collect events and gather information before creating a command, no other app should just publish that command directly.

So I need an autoconfiguration, that is more detailed and allows me to select the stuff I need, based on profiles and "modes".

As I said: I am building this right now, as we wrap the axon starter in a project wide starter-lib with the features above, so if you are intersted and this is a valid use case maybe we can discuss this offline?

zambrovski commented 4 years ago

Very strong vote for this approach from my side.

I can just report from my experience. We designed taskpool to have multiple components seprated by the buses, which allowed to introduce different deployment scenarios. Our first implementation excluded the autoconfiguration(s) by default and then added them individually, resulting in a huge stack of different Axon-specific annotations on configuration classes. Refactoring of this code is not doable and mistakes are very probable, especially during later operation / migration to further versions.

I think it would be a great idea not only introduce the modularized starter, but also materialize the use case modes in describing it by example. I could contribute a virtual comprehensive example description and provide the description of the modes as a part of architectural description / kind of patterns.

smcvb commented 4 years ago

Awesome, thanks for the feedback @jangalinski and @zambrovski. Do think I am "sold" now at least ;-) I'll see what we can do in regards to prioritization to introduce this "ease of use" feature.

Would be great if this idea does not only withhold itself to the Spring Boot module to be honest, as Spring Boot is not the only solution out there of course. Any thoughts/suggestions on that matter?

jangalinski commented 4 years ago

As mentioned, I am currently building such modularization so I would be willing to help implementing it.

For the "no spring boot" use case: you did an "ok" job (I still have some minor design flaws in mind) splitting up the axon-core lib into dedicated libs (messaging, eventsourcing, ...) so that's fine for me. The problem is, that you merged them all back together again for the spring auto-configuration/starter.

smcvb commented 4 years ago

If with an ok job and design flaws you are pointing towards an even more fine grained modularization of the framework, then I can state that wont happen for Axon 4 due to backwards compatibility. If that's a wrong assumption on my part, I very much like to hear what your intentions are with both arguments.

jangalinski commented 4 years ago

Steven, I apologize for the choice of words. I was in a hurry and the German/English barrier hit. Now you repeat them, they sound much harsher then intended. I will take a few moments to prepare my thoughts on this and come back to you with my ideas for improvements.

zambrovski commented 3 years ago

To wake up this issue this year, if you do the Axon configuration via builders, you can decide which parts to include and use and which are not required in this operation mode. Since you are configuring the framework anyway, you can match the exact mode you need. So I think on that level it is not "ok", but a pretty good solution.

If you are using SpringBoot, the defaults seem a little funny, because they assume a monolithic application. Don't get me wrong, this is a perfect choice and everyone should start there, but if you get distributed in a way @jangalinski describes above, this default is not very helpful. If you switch the AutoConfiguration off, you end up on the level of Axon Framework without SpringBoot.

The propose is to have a common understanding on the Operation Modes. If we get them sorted, we can think of different conditional configurations activating certain Axon features. And for every given Operation Mode, you will start only the features it includes. By not "starting" the feature, one would provide an unusable component, which is stopping the misuse (like a dummy command bus throwing UnsupportedOperationException if you try to use it...

smcvb commented 3 years ago

Thanks for the insights @zambrovski; as always much appreciated. Although times are still busy, I do feel work in this could be growing nearer from our team. But as always I am not here to give any timing related promises... All I can promise is that once work would start from our end, we will update this ticket accordingly.

smcvb commented 1 year ago

We do not envision having sufficient time to work on this before our intended release of 4.8.0. Added, we aim to direct our attention to the following major release. Due to this, it is unclear at this stage when the issue will be resolved.