Simon Online

2024-10-12

Fast Endpoints Listen Port

In order to set the listening port for Fast Endpoints you can use the same mechanism as a regular ASP.NET application. This invovles setting the Urls setting in the appsettings.json file. My file looks like this:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "Urls": "http://0.0.0.0:8080",
  "AllowedHosts": "*"
}
2024-09-15

Update outdated Nuget packages

If you’re using Visual Studio Code to develop C# applications, you might need to update outdated Nuget packages. You can do that without having to do each one individually on the command line using dotnet outdated

Install it with

dotnet tool install --global dotnet-outdated

Then you can run it in the root of your project to list the packages which will be updated with

dotnet outdated

Then, if you’re happy, run it again with

dotnet outdated -u

to actually get everything updated.

2024-09-14

NServiceBus Kata 6 - When things go wrong

So far in this series things have been going pretty well. We’ve looked at sending messages, publishing messages, switching transports, long running processes, and timeouts. But what happens when things go wrong? In this kata we’re going to look at how to handle errors in NServiceBus.

Read More

2024-09-09

NServiceBus Kata 5 - Timeouts

In the previous kata we looked at sagas which are a way to coordinate long running processes. In this kata we’re going to look at another tool in the NServiceBus toolbox: timeouts. Timeouts are a way to schedule a message to be sent at some point in the future. This is a powerful tool for building out complex processes.

Read More

2024-09-02

NServiceBus Kata 4 - Long Running Processes

We now have a pretty solid way to send messages, publish messages and we’ve got those messages flowing over a reliable transport mechanism. Sending and publishing individual messages only gets us so far. We often need a way to coordinate complex processes which involve multiple services. For this NServiceBus has the concept of sagas which some might call process managers.

Read More

2024-09-01

NServiceBus Kata 3 - Switching transports

In the previous article we looked at publishing messages and the one before that sending messages. But in both cases we cheated a little bit: we used the LearningTransport. This is effectively just a directory on disk. It cannot be used as real world transport. Let’s change out this transport for something more production ready.

Read More

2024-08-31

NServiceBus Kata 2

In the previous kata we sent a message from one application to another. This is a common pattern in messaging systems. In this kata we’re going to look at a different pattern: publishing a message.

Read More

2024-08-30

NServiceBus Kata 1

Exciting times for me, I get to help out on an NServiceBus project! It’s been way too long since I did anything with NServiceBus but I’m back, baby! Most of the team has never used NServiceBus before so I thought it would be a good idea to do a little kata to get them up to speed. I’ll probably do 2 or 3 of these and if they help my team they might as well help you, too.

The Problem

Our goal is to very simply demonstrate reliable messaging. If you’re communicating between two processes on different machines a usual approach is to send a message using HTTP. Problem is that sometimes the other end isn’t reachable. Could be that the service is down, could be that the network is down or it could be that the remote location was hit by a meteor. HTTP won’t help us in this case - what we want is a reliable protocol which will save the message somewhere safe and deliver it when the endpoint does show up.

For this we use a message queue. There are approximately 9 billion different messaging technologies out there but we’re going to use NServiceBus. NServiceBus is a .NET library which wraps up a lot of the complexity of messaging. It is built to be able to use a variety of transport such as RabbitMQ and Azure Service Bus.

We want to make use of NServiceBus and a few C# applications to demonstrate reliable messaging.

The Kata

I like cake but I feel bad about eating it because it’s not good for me. So in this kata you need to command me to eat cake. I can’t refuse a command to eat cake so I can’t possibly feel bad about it.

Create a sender application which sends a message to a receiver application. The receiver application should be able to receive the message and write it to the console. The sender application should be able to send the message and then exit. The receiver application should be able to start up and receive the message even if the sender application isn’t running.

Now go do it!

Useful resources:

My Solution

  1. Create a new directory for the project

    mkdir kata1
    cd kata1
    
  2. Create a new console project for the sender

    dotnet new console -o sender
    
  3. Create a new console project for the receiver

    dotnet new console -o receiver
    
  4. Create a new class library for the messages

    dotnet new classlib -o messages
    
  5. Add a reference to the messages project in the sender and receiver projects

    dotnet add sender reference ../messages
    dotnet add receiver reference ../messages
    
  6. Add a reference to NServiceBus in all the projects

    dotnet add sender package NServiceBus
    dotnet add receiver package NServiceBus
    dotnet add messages package NServiceBus
    
  7. Create a new class in the messages project (and remove Class1.cs)

namespace messages;

using NServiceBus;

public class EatCake: ICommand
{
    public int NumberOfCakes { get; set; }
    public string Flavour { get; set; } = "Chocolate";
}
  1. Update Program.cs in the sender project to send a message
using messages;
using NServiceBus;

Console.Title = "NServiceBusKata - Sender";

var endpointConfiguration = new EndpointConfiguration("NServiceBusKataSender");

// Choose JSON to serialize and deserialize messages
endpointConfiguration.UseSerialization<SystemJsonSerializer>();

var transport = endpointConfiguration.UseTransport<LearningTransport>();

var endpointInstance = await Endpoint.Start(endpointConfiguration);

await endpointInstance.Send("NServiceBusKataReceiver", new EatCake{
    Flavour = "Coconut",
    NumberOfCakes = 2 //don't be greedy
});

await endpointInstance.Stop();
  1. Update Program.cs in the receiver project to be an endpoint
using NServiceBus;

Console.Title = "NServiceBusKata - Reciever";

var endpointConfiguration = new EndpointConfiguration("NServiceBusKataReceiver");

// Choose JSON to serialize and deserialize messages
endpointConfiguration.UseSerialization<SystemJsonSerializer>();

var transport = endpointConfiguration.UseTransport<LearningTransport>();

var endpointInstance = await Endpoint.Start(endpointConfiguration);

Console.WriteLine("Press Enter to exit...");
Console.ReadLine();

await endpointInstance.Stop();
  1. Add a message handler to the receiver project
using messages;

public class EatCakeHandler :
    IHandleMessages<EatCake>
{
    public Task Handle(EatCake message, IMessageHandlerContext context)
    {
        Console.WriteLine($"Cake eaten, NumberOfCakes = {message.NumberOfCakes}; Flavour = {message.Flavour}");
        return Task.CompletedTask;
    }
}

Things to try now:

  1. Run the sender project - it will send a message but the receiver won’t be running so nothing will happen
  2. Run the receiver project - it will start listening for messages and find the message which was left for it
  3. Run the sender project again - it will send a message and the receiver will pick it up and write to the console

This demonstrates reliable messaging with NServiceBus

2024-07-31

Plinko Diagram

One of my team members mentioned that they envision the process flow of our code as a Plinko board. If you’ve never watched The Price is Right, a Plinko board is a vertical board with pegs that a contestant drops a disc down. The disc bounces off the pegs and lands in a slot at the bottom. The slots have different values and the contestant wins the value of the slot the disc lands in.

I just loved this mental model. Each peg in the board is an fork in the code and a different path can be taken from that point on. It’s basically an execution tree but with a fun visual that’s easy to explain to people.

flowchart TB
    A --> B & C
    B --> D & E
    C --> F & G
2024-05-24

Setting Container Cors Rules in Azure

This week I’m busy upgrading some legacy code to the latest version of the Azure SDKs. This code is so old it was using packages like WindowsAzure.Storage. Over the years this library has evolved significantly and is now part of the Azure.Storage.Blobs package. What this code I was updating was doing was setting the CORS rules on a blob container. These days I think I would solve this problem using Terraform and set the blob properties directly on the container. But since I was already in the code I figured I would just update it there.

So what we want is to allow anybody to link into these and download them with a GET

using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
...
var bsp = new BlobServiceProperties { HourMetrics = null, MinuteMetrics = null, Logging = null };
bsp.Cors.Add(new BlobCorsRule
{
    AllowedHeaders =  "*",
    AllowedMethods = "GET",
    AllowedOrigins = "*",
    ExposedHeaders = "*",
    MaxAgeInSeconds = 60 * 30 // 30 minutes
});

// from a nifty little T4 template
var connectionString = new ConnectionStrings().StorageConnectionString;
BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);
blobServiceClient.SetProperties(bsp);

Again, in hindsight I feel like these rules are overly permissive and I would probably want to lock them down a bit more.