Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions samples/multi-tenant/ravendb/Raven_10/Receiver/Receiver.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net9.0;net8.0</TargetFrameworks>
<OutputType>Exe</OutputType>
<LangVersion>12.0</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NServiceBus.Extensions.Hosting" Version="3.*" />
<PackageReference Include="NServiceBus.RavenDB" Version="10.*" />
<PackageReference Include="RavenDB.Client" Version="6.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\Shared.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
<TargetFrameworks>net9.0;net8.0</TargetFrameworks>
<OutputType>Exe</OutputType>
<LangVersion>12.0</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NServiceBus.Extensions.Hosting" Version="3.0.1" />
<PackageReference Include="NServiceBus.Extensions.Hosting" Version="3.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\Shared.csproj" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<PropertyGroup>
<TargetFrameworks>net9.0;net8.0</TargetFrameworks>
<LangVersion>12.0</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NServiceBus" Version="9.*" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using NServiceBus;
using Microsoft.Extensions.Logging;

public class OrderLifecycleSaga(ILogger<OrderLifecycleSaga> logger) :
Saga<OrderLifecycleSagaData>,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using NServiceBus;

public class OrderLifecycleSagaData :
public class OrderLifecycleSagaData :
ContainSagaData
{
public string OrderId { get; set; }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using NServiceBus;

public class OrderSubmittedHandler(ILogger<OrderSubmittedHandler> logger) :
IHandleMessages<OrderSubmitted>
Expand Down
99 changes: 99 additions & 0 deletions samples/multi-tenant/ravendb/Raven_11/Receiver/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using Microsoft.Extensions.Hosting;
using Raven.Client.Documents;
using Raven.Client.Documents.Operations;
using Raven.Client.Exceptions;
using Raven.Client.Exceptions.Database;
using Raven.Client.ServerWide;
using Raven.Client.ServerWide.Operations;

Console.Title = "Receiver";
var builder = Host.CreateApplicationBuilder(args);

var endpointConfiguration = new EndpointConfiguration("Samples.MultiTenant.Receiver");

using var documentStore = new DocumentStore
{
Urls = new[] { "http://localhost:8080" },
Database = "MultiTenantSamples",
};

documentStore.Initialize();
await CreateDatabase(documentStore);
await CreateTenantDatabase(documentStore, "A");
await CreateTenantDatabase(documentStore, "B");

var persistence = endpointConfiguration.UsePersistence<RavenDBPersistence>();
persistence.SetDefaultDocumentStore(documentStore);

var transport = new LearningTransport
{
TransportTransactionMode = TransportTransactionMode.ReceiveOnly
};
endpointConfiguration.UseTransport(transport);
endpointConfiguration.UseSerialization<SystemJsonSerializer>();

var outbox = endpointConfiguration.EnableOutbox();

#region DetermineDatabase

persistence.SetMessageToDatabaseMappingConvention(headers =>
{
return headers.TryGetValue("tenant_id", out var tenantId)
? $"MultiTenantSamples-{tenantId}"
: "MultiTenantSamples";
});

#endregion

var pipeline = endpointConfiguration.Pipeline;

pipeline.Register(new StoreTenantIdBehavior(), "Stores tenant ID in the session");
pipeline.Register(new PropagateTenantIdBehavior(), "Propagates tenant ID to outgoing messages");

builder.UseNServiceBus(endpointConfiguration);
await builder.Build().RunAsync();

static async Task CreateDatabase(IDocumentStore documentStore)
{
try
{
await documentStore.Maintenance.ForDatabase(documentStore.Database).SendAsync(new GetStatisticsOperation());
}
catch (DatabaseDoesNotExistException)
{
try
{
await documentStore.Maintenance.Server.SendAsync(new CreateDatabaseOperation(new DatabaseRecord(documentStore.Database)));
}
catch (ConcurrencyException)
{
// This exception is thrown if the database already exists.
// We can safely ignore it, as our goal is simply to ensure it exists.
}
}
}

static async Task CreateTenantDatabase(DocumentStore documentStore, string tenant)
{
#region CreateDatabase

var id = $"MultiTenantSamples-{tenant}";
try
{
await documentStore.Maintenance.ForDatabase(id).SendAsync(new GetStatisticsOperation());
}
catch (DatabaseDoesNotExistException)
{
try
{
await documentStore.Maintenance.Server.SendAsync(new CreateDatabaseOperation(new DatabaseRecord(id)));
}
catch (ConcurrencyException)
{
// This exception is thrown if the database already exists.
// We can safely ignore it, as our goal is simply to ensure it exists.
}
}

#endregion
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
using System;
using System.Threading.Tasks;
using NServiceBus.Pipeline;

public class PropagateTenantIdBehavior :
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NServiceBus.Extensions.Hosting" Version="4.0.0-alpha.1" />
<PackageReference Include="NServiceBus.RavenDB" Version="10.0.0-alpha.1" />
<PackageReference Include="RavenDB.Client" Version="5.*" />
<PackageReference Include="NServiceBus.Extensions.Hosting" Version="4.0.0-alpha.2" />
<PackageReference Include="NServiceBus.RavenDB" Version="11.0.0-alpha.1" />
<PackageReference Include="RavenDB.Client" Version="6.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\Shared.csproj" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
using System;
using System.Threading.Tasks;
using NServiceBus.Pipeline;

public class StoreTenantIdBehavior :
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using NServiceBus;
using Microsoft.Extensions.Logging;

public class OrderAcceptedHandler(ILogger<OrderAcceptedHandler> logger) :
IHandleMessages<OrderAccepted>
{
Expand Down
65 changes: 65 additions & 0 deletions samples/multi-tenant/ravendb/Raven_11/Sender/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

Console.Title = "Sender";

// Configure the NServiceBus endpoint
var endpointConfiguration = new EndpointConfiguration("Samples.MultiTenant.Sender");
endpointConfiguration.UseTransport(new LearningTransport());
endpointConfiguration.UseSerialization<SystemJsonSerializer>();
endpointConfiguration.EnableInstallers();

var builder = Host.CreateApplicationBuilder(args);
builder.UseNServiceBus(endpointConfiguration);

var host = builder.Build();

await host.StartAsync();

// Get the required services
var messageSession = host.Services.GetRequiredService<IMessageSession>();
// Register a cancellation token to gracefully handle application shutdown
var ct = host.Services.GetRequiredService<IHostApplicationLifetime>().ApplicationStopping;

Console.WriteLine("Press A or B to publish a message (A and B are tenant IDs). Press Ctrl+C to shut down.");

// Wait for user input to publish messages
while (!ct.IsCancellationRequested)
{
if (!Console.KeyAvailable)
{
// If no key is pressed, wait for a short time before checking again
await Task.Delay(100, CancellationToken.None);
continue;
}

var input = Console.ReadKey();
Console.WriteLine();

var inputKey = char.ToUpperInvariant(input.KeyChar);
if (inputKey is 'A' or 'B')
{
// Send a message to the specified tenant
var message = new OrderSubmitted
{
OrderId = GenerateOrderId(),
Value = GenerateOrderValue()
};

var options = new PublishOptions();
options.SetHeader("tenant_id", inputKey.ToString());

await messageSession.Publish(message, options);
}
else
{
Console.WriteLine($"[{inputKey}] is not a valid tenant identifier.");
}
}

// Wait for the host to stop gracefully
await host.StopAsync();

static string GenerateOrderId() => Guid.NewGuid().ToString("N")[..6].ToUpperInvariant();

static int GenerateOrderValue(int max = 100) => Random.Shared.Next(max);
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NServiceBus.Extensions.Hosting" Version="4.0.0-alpha.1" />
<PackageReference Include="NServiceBus.Extensions.Hosting" Version="4.0.0-alpha.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\Shared.csproj" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using NServiceBus;

public class OrderAccepted :
public class OrderAccepted :
IMessage
{
public string OrderId { get; set; }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using NServiceBus;

public class OrderSubmitted :
public class OrderSubmitted :
IEvent
{
public string OrderId { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NServiceBus" Version="10.0.0-alpha.1" />
<PackageReference Include="NServiceBus" Version="10.0.0-alpha.3" />
</ItemGroup>
</Project>
27 changes: 27 additions & 0 deletions samples/multi-tenant/ravendb/Raven_9/MultiTenant.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29728.190
MinimumVisualStudioVersion = 15.0.26730.12
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sender", "Sender\Sender.csproj", "{B58159EB-9EFD-443F-A80E-8C90B0AF1907}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Receiver", "Receiver\Receiver.csproj", "{1EEC6A8C-DB3C-4F20-93CE-5004BF16AD7F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "Shared\Shared.csproj", "{BF92D39E-42F6-44E9-8F7F-819993235621}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B58159EB-9EFD-443F-A80E-8C90B0AF1907}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B58159EB-9EFD-443F-A80E-8C90B0AF1907}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1EEC6A8C-DB3C-4F20-93CE-5004BF16AD7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1EEC6A8C-DB3C-4F20-93CE-5004BF16AD7F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF92D39E-42F6-44E9-8F7F-819993235621}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BF92D39E-42F6-44E9-8F7F-819993235621}.Debug|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
5 changes: 5 additions & 0 deletions samples/multi-tenant/ravendb/Raven_9/Receiver/Order.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
public class Order
{
public string Id { get; set; }
public decimal Value { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Microsoft.Extensions.Logging;

public class OrderLifecycleSaga(ILogger<OrderLifecycleSaga> logger) :
Saga<OrderLifecycleSagaData>,
IAmStartedByMessages<OrderSubmitted>,
IHandleTimeouts<OrderTimeout>
{

public async Task Handle(OrderSubmitted message, IMessageHandlerContext context)
{
Data.OrderId = message.OrderId;

await RequestTimeout<OrderTimeout>(context, TimeSpan.FromSeconds(5));
}

public Task Timeout(OrderTimeout state, IMessageHandlerContext context)
{
logger.LogInformation("Order {OrderId} has timed out", Data.OrderId);
return Task.CompletedTask;
}

protected override void ConfigureHowToFindSaga(SagaPropertyMapper<OrderLifecycleSagaData> mapper)
{
mapper.MapSaga(saga => saga.OrderId)
.ToMessage<OrderSubmitted>(m => m.OrderId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
public class OrderLifecycleSagaData :
ContainSagaData
{
public string OrderId { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Microsoft.Extensions.Logging;

public class OrderSubmittedHandler(ILogger<OrderSubmittedHandler> logger) :
IHandleMessages<OrderSubmitted>
{
public async Task Handle(OrderSubmitted message, IMessageHandlerContext context)
{
logger.LogInformation("Order {OrderId} worth {Value} submitted", message.OrderId, message.Value);

var order = new Order
{
Id = message.OrderId,
Value = message.Value
};
var session = context.SynchronizedStorageSession.RavenSession();

await session.StoreAsync(order, context.CancellationToken);

var orderAccepted = new OrderAccepted
{
OrderId = message.OrderId,
};
await context.Reply(orderAccepted);
}
}
3 changes: 3 additions & 0 deletions samples/multi-tenant/ravendb/Raven_9/Receiver/OrderTimeout.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
public class OrderTimeout
{
}
Loading
Loading