How to get list of registered consumers in MassTransit? - masstransit

is there a way how to get list of all registered consumers? Right now I need to write a test, that make sure, that all required queues has registered consumers. That is unfortunately impossible or at least I don't know a way.
My test should cover that scenario, when you forget to register one and it's quite hard to find out, unless you're using request/response scenario, when it throw a timeout exception.
And Moq is not helping that much, because mostly it is generic methods (like AddConsumer) with constraints which is quite a problem when verifying certain method was called with specific parameters. I can replace it with calling non-generic, but that I would like to use as last resort.
Thank you

After the container is configured, you could use the IServiceCollection directly to check if registrations exist.
Assert.That(services.Any(x => x.ServiceType == typeof(SomeConsumer));
Do that for each consumer.

Related

Authorization of commands in Axon

Up until now I have been handling authorization in the CommandHandlers.
An example is I have an aggregate "Team" containing a list of managers (AggregateIdentifier from a User). All command handlers in the Team aggregate then verify the user executing the command is manager of the team.
The userId is injected as metadata in a CommandHandlerInterceptor based on the SecurityContext.
My main concern is, when I use sagas, it becomes an additional overhead to maintain the user context across the commands issued against different aggregates. Aside from that, the manager association can expire in the period the saga is running and subsequent failing commands, leading to an incomplete state which also needs to be handled with some rollback functionality.
Is it better to do the authorization in my controller layer to avoid the additional overhead or should I see it more as good practice to let my CommandHandlers decide whether the command is valid for the aggregate?
Authorization to perform certain operations/commands is something which I'd argue isn't domain specific logic. Instead, it is more a form of cross cutting concern which you need throughout your application. Thus, placing it in the #CommandHandler annotated method is not the ideal place in my head. However, placing it close by makes a lot of sense.
You have pointed out you are already using a CommandHandlerInterceptor to populate the Spring SecurityContext, thus I am assuming you are using a CommandDispatchInterceptor to populate the command's MetaData with information when you send a command out. This is a great use of the interceptor logic indeed, so I'd keep that in place. This however set's the information, it doesn't validate it.
To that end, you could build your own Handler Enhancer, which validates security metadata on a command. You could even build a dedicated annotation you'd add next to the #CommandHandler annotation, which describes the required roles. That way, the method still portrays what roles you need for the given command, but the actual validation can be done in this Handler Enhancer for you.
Now, let's circle back to your question:
Is it better to do the authorization in my controller layer to avoid the additional overhead or should I see it more as good practice to let my CommandHandlers decide whether the command is valid for the aggregate?
I think it's fine to do it in the aggregate, potentially making it cleaner through use of a Handler Enhancer. When it comes to your concern in the Saga, well, I think you should see that separate. The Saga handles events, facts that something has happened. Ignoring that fact because somebody whom initiated the operations which led to this fact doesn't have the rights doesn't resolve the point that it still has happened. Added, you are indeed not guaranteed on the timing of the Saga at all. Maybe your Saga deals with historical events, meaning it is completely out of scope.
If possible within your system, I would regard any command the Saga wants to publish as being sent by a "system user". The Saga is not something your users (which have specific roles) will directly influence; it is all indirect. The Saga is internal to your system, hence it is the system describing the intent to perform an operation.
That's my two cents to the situation, hope this helps you out #Vincent!

Flux Dispatcher - View actions vs. Server Actions

Is there any reason, other than semantics, to create different dispatch methods for view and server actions? All tutorials and examples I’ve seen (most notably this) ignore the source constant entirely when listening to dispatched payloads in favor of switching on the payload's action type.
I suppose there is a reason why this pattern is pervasive in flux examples, but I have yet to see a concrete example as to why this is useful. Presumably one could add an additional if or switch on the payload source to determine whether to act in stores, but no examples I've seen consider this constant at all. Any thoughts on this would be much appreciated.
Yes, this was cruft/cargo-culting that came over from a particular Flux project at Facebook, but there is no real reason to do this. If you do need to differentiate between server and view actions, you can just give them different types, or have another property of the action itself to help differentiate them.
When I get time, I plan to rewrite all the examples and documentation to reflect this.

What is the difference between Consumes.For, Consumes.Selected, Consumes.All and Consumes.Context in MassTransit?

I've started looking at MassTransit and am writing the classes that will handle the messages. When I implement the interface from Consumes<T> I get four options: All, Selected, For<T> and Context. What is the difference between the four and when should them be used?
All just gives you all the messages to consume. Context is All but you also get the Context<TMessage> if you need it. Selected allows you to accept or reject messages before it gets to your consumer. For<T> is primarily for Sagas, I don't think there's a good use case for it outside of that.
Starting off, just using All is likely the right answer.

Should exceptions be defined in use cases?

Say you have a use case called 'schedule meeting.' Defined in the spec, meetings can only be scheduled for the current time or the future. In the Use Case should it include the flow where "if the date/time given is in the past, a message box will show 'meeting time cannot be in the past'"?
Like I said, it's defined in the spec that the date/time cannot be in the past, but in the use case definition, should it be defined there as well?
The business work flows should not be technical if they can be avoided.
Saying something like 'The User shall see an Error under these conditions..." is ok, but it is up to the developers to define how to implement that. Exceptions might be a good way, but the business stake holders should be indifferent to the implementation details.
I'm glad that I found this old thread! I've just read the wiki entry for use-case exceptions, and it threw up some problems for me.
Let me just say that, as I understand a use case to be properly used, you should not make a past-date meeting an exception.
A use case expresses a requirement, in this case, to schedule a meeting. Dealing with invalid meeting requests actually is a part of the scheduling process, and not an exception to it.
The requirement exists, without exception, as does the use case. Invalid dates are a detail item. Think of your use case as a more general, table of contents.
If you are modelling iteratively, you will 'discover' and manage the requirement to reject invalid meeting requests, as you elaborate your model/document.
,
I'm glad that I found this old thread! I've just read the wiki entry for use-case exceptions, and it threw up some problems for me.
Let me just say that, as I understand a use case to be properly used, you should not make a past-date meeting an exception.
A use case expresses a requirement, in this case, to schedule a meeting. Dealing with invalid meeting requests actually is a part of the scheduling process, and not an exception to it.
The requirement exists, without exception, as does the use case. Invalid dates are a detail item. Think of your use case as a more general, table of contents.
If you are modelling iteratively, you will 'discover' and manage the requirement to reject invalid meeting requests, as you elaborate your model/document.
Put even more succinctly, you have described a schedule meeting function. A UML use case should not be used for functional-driven development.

TDD and Service (class what do something but nothing returns back)

I'm trying to follow TDD (i'm newbee) during development of Service class which builds tasks passed by Service clients. The built objects are then passed to other systems. In other words this service takes tasks but returns nothing as a result - it passes built tasks to other Services.
So I'm wondering how can I write test for it because there is nothing to assert.
I'm thinking about using mocks to track interactions inside the service but I'm a little bit afraid of using mocks because I will be tied up with internal implementarion of the service.
Thanks all of you in advance!
There's no problem using mocks for this, since you are effectively going to be mocking the external interface of the components that are used internally in the component. This is really what mocking is intended for, and sound like a perfect match for your use case.
When doing TDD it should also allow you to get those quick turnaround cycles that are considered good practice, since you can just create mocks of those external services. These mocks will easily allow you to write another failing test.
You can consider breaking it up in a couple classes. One responsible to build the list of tasks that will be executed, and the other responsible to execute the list of tasks it is handed. This way you can directly test the code that build the lists of tasks.
That said, I want to add a sample I posted on another question, regarding how I view the TDD process when external systems are involved.
Lets say you have to check whether
some given logic sends an email, logs
the info on a file, saves data on the
database, and calls a web service (not
all at once I know, but you start
adding tests for each of those). On
each test you don't want to hit the
external systems, what you really want
to test is if the logic will make the
calls to those systems that you are
expecting it to do. So when you write
a test that checks that an email is
sent when you create an user, what you
test is if the logic calls the
dependency that does that. Notice that
you can write these tests and the
related logic, without actually having
to implement the code that sends the
email (and then having to access the
external system to know what was sent
...). This will help you focus on the
task at hand and help you get a
decoupled system. It will also make it
simple to test what is being sent to
those systems.
Not sure what language you're using so in psuedo-code it could be something like this:
when_service_is_passed_tasks
before_each_test
mockClients = CreateMocks of 3 TaskClients
tasks = GetThreeTasks()
myService = new TaskRouter(mockClients)
sends_all_to_the_appropriate_clients
tasks = GetThreeTasks()
myService.RouteTaks(tasks)
Assert mockClients[0].AcceptTask(tasks[0]) was called
Assert mockClients[1].AcceptTask(tasks[1]) was called
Assert mockClients[2].AcceptTask(tasks[2]) was called
if_one_routing_fails_all_fail
tasks = GetTasksWhereOneIsFailing()
myService.RouteTaks(tasks)
Assert mockClients[0].AcceptTask(*) was not called
Assert mockClients[1].AcceptTask(*) was not called
Assert mockClients[2].AcceptTask(*) was not called

Resources