How to get Axon event-identifier from the event-store - axon

Just a short question here...
by using Axon, we know that AggregateLifecycle#apply(Object) will be doing the event-sourced for us which under the hood going to persist our event into our event-store.
With regards to that matter, how to get the event-identifier (not the aggregate identifier) once we call that particular apply method ?
Thanks

Based on your another answer, let me suggest you a way to follow.
The MessageIdentifier as used by AxonFramework (AF) is nothing more than an UUID generated for each Message you create.
Since you only need to reuse that info, you can pretty much get it from the Message while handling it. To make things easier for you, Axon provides a MessageIdentifierParameterResolver meaning you can simply use it in any #MessageHandler of you (of course, I am assuming you are using Spring as well).
Example:
#EventHandler
public void handle(Event eventToBeForwarded, #MessageIdentifier String messageIdentifier) {
// forward the event to another broker using the given `messageIdentifier`
}
Hope that helps you and make things clear!

Related

how to start one flux after completion of another?

how can i start Flux after completion of Flux? Flux doesn't depend on result of Flux.
I thought operation then() should do the work, but it just return mono. So what is the correct operator?
Flux.thenMany is the operator that you need
abstract Flux<Integer> flux1();
abstract Flux<String> flux2();
public Flux<String> flux2AfterFlux1(){
return flux1().thenMany(flux2());
}
My reply is late, so you have probably either figured this out, or moved on. I need to do the same thing, so I seem to have achieved this by using Flux.usingWhen(). I need to obtain IDs from my database that exhibit a certain property. After retrieving these IDs, then I need to get some information about these IDs. Normally, a join would work, but I am using MongoDB, and joins are horrible, so it is better to do separate, sequential queries. So let's say I have a Mongo reactive repository with a method called Flux<String> findInterestingIds(). I have another method in the same repository called Flux<String> findInterestingInformation(String[] interestingIds) that I need to feed the IDs found in the call to the previous method. So this is how I handle it:
Mono<List<String>> interestingIdsMono = myRepo.findInterestingIds()
.collectList();
Flux.usingWhen(interestingIdsMono,
interestingIds -> myRepo.findInterestingInformation(interestingIds),
interestingIds -> Flux.empty().doOnComplete(() -> log.debug("Complete"));
The cleanup function (third parameter) was something that I don't quite yet understand how to use in a good way, so I just logged completion and I do not need to emit anything extra when the flux completes.
ProjectReactor used to have a compose function that is now called transformDeferred, and I had some hopes for that, but I do not quite see how it would apply in this type of situation. At any rate, this is my attempt at it, so feel free to show me a better way!

Where did LoaderService go?

Upgrading AngleSharp from 0.9.6 to 0.9.9 I have this line of code no longer compiling:
return configuration.With(LoaderService(new[] { requester }));
It complains that LoaderService does not exist in the current context. So what happened to LoaderService? Is there a replacement? Does it still exist but just somewhere else?
Good question. Sorry for being late to the party, but even though you may have solved your problem someone else is having a hard time figuring it out.
LoaderService was essentially just a helper to create a loader. But having a service for anything creating a little thing would be overkill and not scale much. Also AngleSharp.Core would need to define all these. So, instead a generic mechanism was introduced, which allows registering such "creator services" via Func<IBrowsingContext, TService>.
However, to solve your piece of code I guess the following line would do the trick:
return configuration.WithDefaultLoader(requesters: requester);
This registers the default loader creator services (one for documents, one for resources inside documents) with the default options (options involve some middleware etc.).
Under the hood (besides some other things) the following is happening:
// just one example, config.Filter is created based on the passed in options
return configuration.With<IDocumentLoader>(ctx => new DocumentLoader(ctx, config.Filter));

Where should I put a logic for querying extra data in CQRS command flow

I'm trying to implement simple DDD/CQRS architecture without event-sourcing for now.
Currently I need to write some code for adding a notification to a document entity (document can have multiple notifications).
I've already created a command NotificationAddCommand, ICommandService and IRepository.
Before inserting new notification through IRepository I have to query current user_id from db using NotificationAddCommand.User_name property.
I'm not sure how to do it right, because I can
Use IQuery from read-flow.
Pass user_name to domain entity and resolve user_id in the repository.
Code:
public class DocumentsCommandService : ICommandService<NotificationAddCommand>
{
private readonly IRepository<Notification, long> _notificationsRepository;
public DocumentsCommandService(
IRepository<Notification, long> notifsRepo)
{
_notificationsRepository = notifsRepo;
}
public void Handle(NotificationAddCommand command)
{
// command.user_id = Resolve(command.user_name) ??
// command.source_secret_id = Resolve(command.source_id, command.source_type) ??
foreach (var receiverId in command.Receivers)
{
var notificationEntity = _notificationsRepository.Get(0);
notificationEntity.TargetId = receiverId;
notificationEntity.Body = command.Text;
_notificationsRepository.Add(notificationEntity);
}
}
}
What if I need more complex logic before inserting? Is it ok to use IQuery or should I create additional services?
The idea of reusing your IQuery somewhat defeats the purpose of CQRS in the sense that your read-side is supposed to be optimized for pulling data for display/query purposes - meaning that it can be denormalized, distributed etc. in any way you deem necessary without being restricted by - or having implications for - the command side (a key example being that it might not be immediately consistent, while your command side obviously needs to be for integrity/validity purposes).
With that in mind, you should look to implement a contract for your write side that will resolve the necessary information for you. Driving from the consumer, that might look like this:
public DocumentsCommandService(IRepository<Notification, long> notifsRepo,
IUserIdResolver userIdResolver)
public interface IUserIdResolver
{
string ByName(string username);
}
With IUserIdResolver implemented as appropriate.
Of course, if both this and the query-side use the same low-level data access implementation (e.g. an immediately-consistent repository) that's fine - what's important is that your architecture is such that if you need to swap out where your read side gets its data for the purposes of, e.g. facilitating a slow offline process, your read and write sides are sufficiently separated that you can swap out where you're reading from without having to untangle reads from the writes.
Ultimately the most important thing is to know why you are making the architectural decisions you're making in your scenario - then you will find it much easier to make these sorts of decisions one way or another.
In a project i'm working i have similar issues. I see 3 options to solve this problem
1) What i did do is make a UserCommandRepository that has a query option. Then you would inject that repository into your service.
Since the few queries i did need were so simplistic (just returning single values) it seemed like a fine tradeoff in my case.
2) Another way of handling it is by forcing the user to just raise a command with the user_id. Then you can let him do the querying.
3) A third option is ask yourself why you need a user_id. If it's to make some relations when querying the data you could also have this handles when querying the data (or when propagating your writeDB to your readDB)

Combine Swinject and Realm

thanks for that Framework. I really like the idea and I'm eager to use it! However, I'm currently trying to get this up and running with an app that uses realm as well. I initially tought, It might be a good idea to create a realmService which I inject to my models and which handles all of the realm write stuff.
Sadly, I can not make my mind up on how to do this properly. The Wether App example is great, but it doesn't cover any realm models. Any hint to point me into the correct direction or something? I tried via constructor and property but I just can't get it to work. I guess, I'm missing something conceptual.
Thanks, I'm eager to learn from you :)
Cheers
I just forked the Weather example app and added Realm in there, using Swinjects DI mechanism. Registering the service component pairs could look like this:
container.register(WeatherFetcher.self) { r in
WeatherFetcher(networking: r.resolve(Networking.self)!)
WeatherFetcher(networking: r.resolve(Networking.self)!,
realm: r.resolve(Realm.self)!)
}
container.register(Realm.Configuration.self) { _ in
// not really necessary if you stick to the defaults everywhere
return Realm.Configuration()
}
container.register(Realm.self) { r in
try! Realm(configuration: r.resolve(Realm.Configuration.self)!)
}

How do I make one of a stub's method call the real method in ASMock?

In flex I want to do something similar to the following
var audioPlayerMock:AudioPlayer = AudioPlayer(mockRepository.createStub(mockRepository.createStub(AudioPlayer));
SetupResult.forCall(audioPlayerMock.play).(CALL_ACTUAL_PLAY_METHOD(WITH_ARGUMENT));
AudioPlayer has a lot of methods that I want stubbed, (so I use mockRepository.creatStub()). But there is one method, play(), that I want to call the actual actual method (super.play(argument) if my thinking is right). I'm not sure how to do this?
I know I can use createDynamic(AudioPlayer) then stub out every other method, but that is a bit tedious.
Cheers
You can use IMethodOptions.callOriginalMethod() to call the actual implementation on a stubbed class:
SetupResult.forCall(authatoPlayerMock.play(null))
.ignoreArguments()
.callOriginalMethod();

Resources