Configure Rebus routing (endpoint) in code and not in app.config - rebus

I would like to use #rebus in OneWayClientMode and at the same time configure the endpoint addresses in code and not via app.config.
Is this possible? I can find no trace of it in the fluent configuration.

Basically, you have two options: 1) route messages explicitly when you send them, and 2) implement your own routing logic using `IDetermineMessageOwnership´
The first option is pretty easy, and it is pretty explicit - you can simply go bus.Advanced.Routing.Send(destination, message) whenever you send a message. You should of course take care to not hardcode the destination too many times which could lead to problems later on :)
The second options is also easy, but it is slightly more implicit - you can implement the IDetermineMessageOwnership interface which is basically a way to map a message type to an endpoint, and then make Rebus use it like this:
Configure.With(...)
.(...)
.MessageOwnership(m => m.Use(myImplementation))
.(...)
Unless I was going to do only one or two bus.Sends, I would go for the latter option :) happy routing!

I'd like to give a more explicit example of option 2, because I had to search through the examples to find out how to type in "myImplementation", and it is really quite simple. Suppose you want a queue identified by sWorkerId to receive all messages, this is what you do:
Configure.With(...
.MessageOwnership(o => o.Use(new RebusConfig(sWorkerId)))
.CreateBus()
.Start(RebusConfig.NumberOfWorkers)
RebusConfig implements IDetermineMessageOwnership as:
public class RebusConfig : IDetermineMessageOwnership
{
private string m_sWorkerRoleEndpoint;
public RebusConfig(string sWorkerRoleEndpointId)
{
m_sWorkerRoleEndpoint = sWorkerRoleEndpointId;
}
public string GetEndpointFor(Type messageType)
{
return m_sWorkerRoleEndpoint;
}
}
Hope this helps ...

Related

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

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!

Discouraged Class Usage PHPCS

Let's say I have these classes:
Old_Class
New_Class
If this exists ->something(new Old_Class()) or Old_Class::staticMethod() or $oldClass->methodCall() I want a code sniff to warn "Old_Class usage found, recommend using New_Class instead".
I found this sniff Generic.PHP.ForbiddenFunctions but it only seems to catch built-in php functions is_array, is_null, etc.
Do I need to write a custom sniff for this?
If so, what token should I added to the register() function to catch on?
I couldn't use a built-in one. I had to write one using T_STRING.
public function register()
{
return [
T_STRING,
];
}
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
if ($tokens[$stackPtr]['content'] === 'Old_Class') {
$error = 'Old_Class usage found, consider using New_Class instead.';
$phpcsFile->addWarning($error, $stackPtr);
}
}
I know this is a fairly old question, but there are two possible solutions I'm aware of:
The Slevomat coding standard for Codesniffer includes a sniff to report usage of any of an array of forbidden classes
Static analysis tools are another approach for this. If you mark a class with the #deprecated annotation, I know from personal experience that Psalm will flag it with the DeprecatedClass issue, and if you can't fix them all at once, you can add them to the baseline, which will suppress the issue, but keep track of it, so you can still use Psalm in continuous integration and not break on existing issues. I believe PHPStan has similar functionality.

Chaining Handlers with MediatR

We are using MediatR to implement a "Pipeline" for our dotnet core WebAPI backend, trying to follow the CQRS principle.
I can't decide if I should try to implement a IPipelineBehavior chain, or if it is better to construct a new Request and call MediatR.Send from within my Handler method (for the request).
The scenario is essentially this:
User requests an action to be executed, i.e. Delete something
We have to check if that something is being used by someone else
We have to mark that something as deleted in the database
We have to actually delete the files from the file system.
Option 1 is what we have now: A DeleteRequest which is handled by one class, wherein the Handler checks if it is being used, marks it as deleted, and then sends a new TaskStartRequest with the parameters to Delete.
Option 2 is what I'm considering: A DeleteRequest which implements the marker interfaces IRequireCheck, IStartTask, with a pipeline which runs:
IPipelineBehavior<IRequireCheck> first to check if the something is being used,
IPipelineBehavior<DeleteRequest> to mark the something as deleted in database and
IPipelineBehavior<IStartTask> to start the Task.
I haven't fully figured out what Option 2 would look like, but this is the general idea.
I guess I'm mainly wondering if it is code smell to call MediatR.Send(TRequest2) within a Handler for a TRequest1.
If those are the options you're set on going with - I say Option 2. Sending requests from inside existing Mediatr handlers can be seen as a code smell. You're hiding side effects and breaking the Single Responsibility Principle. You're also coupling your requests together and you should try to avoid situations where you can't send one type of request before another.
However, I think there might be an alternative. If a delete request can't happen without the validation and marking beforehand you may be able to leverage a preprocessor (example here) for your TaskStartRequest. That way you can have a single request that does everything you need. This even mirrors your pipeline example by simply leveraging the existing Mediatr patterns.
Is there any need to break the tasks into multiple Handlers? Maybe I am missing the point in mediatr. Wouldn't this suffice?
public async Task<Result<IFailure,ISuccess>> Handle(DeleteRequest request)
{
var thing = await this.repo.GetById(request.Id);
if (thing.IsBeignUsed())
{
return Failure.BeignUsed();
}
var deleted = await this.repo.Delete(request.Id);
return deleted ? new Success(request.Id) : Failure.DbError();
}

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)

Getting the right syntax for SignalR server to call client

I'm putting together a very basic sort of "hello world" app with SignalR, with the minor caveat that it's self-hosted, which introduces an additional wrinkle or two. Basically, I'm trying to figure out the right way to call methods on my client(s) from the server.
On my client, for instance, I've got a method that looks like this:
roomHub.onEcho = function (msg) {
console.log("onEcho called: " + msg);
};
And I can call it successfully from my server-side hub like so:
public class RoomHub : Hub
{
public void Echo(string echo)
{
Clients.onEcho(echo);
}
}
And it works, but of course, it calls all the clients, not just one. And in the various samples I've seen online (e.g., https://github.com/SignalR/SignalR/blob/master/samples/Microsoft.AspNet.SignalR.Hosting.AspNet.Samples/Hubs/Benchmark/HubBench.cs, I see all sorts of commands that make it look like I should be able to specify who gets called, e.g.:
public void Echo(string echo)
{
Clients.Caller.onEcho(echo);
Clients.Caller(Context.ConnectionId).onEcho(echo);
Clients.All.onEcho(echo);
}
But I can't get any of the above syntaxes to work. For Clients.All.onEcho() and Clients.Caller.onEcho(), absolutely nothing happens. For Clients.Caller(Context.ConnectionId).onEcho(), Firebug tells me that it's actually trying to call a Caller() method on my JavaScript roomHub instance, which of course isn't there.
Here's the weird bit, though. If I look at the Hub class, I can see why none of these work - because the Hub constructor overrides a bunch of the properties of its "Clients" object with NullClientProxies:
protected Hub()
{
Clients = new HubConnectionContext();
Clients.All = new NullClientProxy();
Clients.Others = new NullClientProxy();
Clients.Caller = new NullClientProxy();
}
But I'm kinda mystified as to why it does that - or why the samples seem to work anyway - or what the expected approach should be.
Any thoughts? What am I doing wrong here?
We've been updating docs recently so you've probably seen lots of inconsistent data around the place. The latest version of SignalR is 1.0 alpha2 ( http://weblogs.asp.net/davidfowler/archive/2012/11/11/microsoft-asp-net-signalr.aspx ). All of the documentation has been updated to show the new syntax so if you're using an older version, please upgrade. Check out the wiki for examples https://github.com/SignalR/SignalR/wiki/Hubs

Resources