Skip to content

Commit ad1d06c

Browse files
authored
Add NServiceBus 10 RavenDB Persistence sample (#7730)
* Refactored input loop service * Added NServiceBus 10 RavenDB Persistence sample
1 parent 593dacd commit ad1d06c

20 files changed

+332
-51
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<LangVersion>preview</LangVersion>
5+
<TargetFramework>net10.0</TargetFramework>
6+
</PropertyGroup>
7+
<ItemGroup>
8+
<PackageReference Include="NServiceBus.Extensions.Hosting" Version="4.0.0-alpha.2" />
9+
</ItemGroup>
10+
11+
<ItemGroup>
12+
<ProjectReference Include="..\Shared\Shared.csproj" />
13+
</ItemGroup>
14+
</Project>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System.Threading.Tasks;
2+
using Microsoft.Extensions.Logging;
3+
using NServiceBus;
4+
5+
public class OrderCompletedHandler(ILogger<OrderCompletedHandler> logger) :
6+
IHandleMessages<OrderCompleted>
7+
{
8+
public Task Handle(OrderCompleted message, IMessageHandlerContext context)
9+
{
10+
logger.LogInformation("Received OrderCompleted for OrderId {OrderId}", message.OrderId);
11+
return Task.CompletedTask;
12+
}
13+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using System;
2+
using Microsoft.Extensions.DependencyInjection;
3+
using Microsoft.Extensions.Hosting;
4+
using NServiceBus;
5+
6+
Console.Title = "Client";
7+
8+
var builder = Host.CreateApplicationBuilder(args);
9+
10+
var endpointConfiguration = new EndpointConfiguration("Samples.RavenDB.Client");
11+
12+
endpointConfiguration.UseSerialization<SystemJsonSerializer>();
13+
endpointConfiguration.UseTransport(new LearningTransport());
14+
15+
Console.WriteLine("Press 'enter' to send a StartOrder messages");
16+
builder.UseNServiceBus(endpointConfiguration);
17+
18+
var host = builder.Build();
19+
await host.StartAsync();
20+
21+
var messageSession = host.Services.GetRequiredService<IMessageSession>();
22+
23+
while (true)
24+
{
25+
var key = Console.ReadKey();
26+
Console.WriteLine();
27+
28+
if (key.Key != ConsoleKey.Enter)
29+
{
30+
break;
31+
}
32+
33+
var orderId = Guid.NewGuid();
34+
var startOrder = new StartOrder
35+
{
36+
OrderId = orderId
37+
};
38+
await messageSession.Send("Samples.RavenDB.Server", startOrder);
39+
Console.WriteLine($"StartOrder Message sent with OrderId {orderId}");
40+
}
41+
42+
await host.StopAsync();
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.29728.190
5+
MinimumVisualStudioVersion = 15.0.26730.12
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Server", "Server\Server.csproj", "{48F718EE-6C45-41BA-80EC-81BF34D4A623}"
7+
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "Shared\Shared.csproj", "{DD438DB2-9C03-4BC0-BA52-BB7A35098458}"
9+
EndProject
10+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "Client\Client.csproj", "{2FE71442-7F81-428E-B945-D564850D6564}"
11+
EndProject
12+
Global
13+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
14+
Debug|Any CPU = Debug|Any CPU
15+
EndGlobalSection
16+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
17+
{48F718EE-6C45-41BA-80EC-81BF34D4A623}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
18+
{48F718EE-6C45-41BA-80EC-81BF34D4A623}.Debug|Any CPU.Build.0 = Debug|Any CPU
19+
{DD438DB2-9C03-4BC0-BA52-BB7A35098458}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
20+
{DD438DB2-9C03-4BC0-BA52-BB7A35098458}.Debug|Any CPU.Build.0 = Debug|Any CPU
21+
{2FE71442-7F81-428E-B945-D564850D6564}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22+
{2FE71442-7F81-428E-B945-D564850D6564}.Debug|Any CPU.Build.0 = Debug|Any CPU
23+
EndGlobalSection
24+
GlobalSection(SolutionProperties) = preSolution
25+
HideSolutionNode = FALSE
26+
EndGlobalSection
27+
EndGlobal
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
public class CompleteOrder
2+
{
3+
public string OrderDescription { get; set; }
4+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
using Microsoft.Extensions.Logging;
4+
using NServiceBus;
5+
#region thesaga
6+
7+
public class OrderSaga(ILogger<OrderSaga> logger) :
8+
Saga<OrderSagaData>,
9+
IAmStartedByMessages<StartOrder>,
10+
IHandleTimeouts<CompleteOrder>
11+
{
12+
protected override void ConfigureHowToFindSaga(SagaPropertyMapper<OrderSagaData> mapper)
13+
{
14+
mapper.MapSaga(sagaData => sagaData.OrderId)
15+
.ToMessage<StartOrder>(message => message.OrderId);
16+
}
17+
18+
public Task Handle(StartOrder message, IMessageHandlerContext context)
19+
{
20+
var orderDescription = $"The saga for order {message.OrderId}";
21+
Data.OrderDescription = orderDescription;
22+
23+
logger.LogInformation("Received StartOrder message {OrderId}. Starting Saga", Data.OrderId);
24+
25+
var shipOrder = new ShipOrder
26+
{
27+
OrderId = message.OrderId
28+
};
29+
30+
31+
logger.LogInformation("Order will complete in 5 seconds");
32+
var timeoutData = new CompleteOrder
33+
{
34+
OrderDescription = orderDescription
35+
};
36+
37+
return Task.WhenAll(
38+
context.SendLocal(shipOrder),
39+
RequestTimeout(context, TimeSpan.FromSeconds(5), timeoutData)
40+
);
41+
}
42+
43+
public Task Timeout(CompleteOrder state, IMessageHandlerContext context)
44+
{
45+
logger.LogInformation("Saga with OrderId {OrderId} completed", Data.OrderId);
46+
var orderCompleted = new OrderCompleted
47+
{
48+
OrderId = Data.OrderId
49+
};
50+
MarkAsComplete();
51+
return context.Publish(orderCompleted);
52+
}
53+
}
54+
55+
#endregion
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System;
2+
using NServiceBus;
3+
4+
#region sagadata
5+
6+
public class OrderSagaData :
7+
ContainSagaData
8+
{
9+
public Guid OrderId { get; set; }
10+
public string OrderDescription { get; set; }
11+
}
12+
#endregion
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
using System;
2+
3+
public class OrderShipped
4+
{
5+
public Guid OrderId { get; set; }
6+
public DateTime ShippingDate { get; set; }
7+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
using Microsoft.Extensions.Hosting;
4+
using NServiceBus;
5+
using Raven.Client.Documents;
6+
using Raven.Client.Exceptions;
7+
using Raven.Client.ServerWide;
8+
using Raven.Client.ServerWide.Operations;
9+
10+
11+
Console.Title = "Server";
12+
13+
var builder = Host.CreateApplicationBuilder(args);
14+
15+
#region Config
16+
17+
var endpointConfiguration = new EndpointConfiguration("Samples.RavenDB.Server");
18+
using var documentStore = new DocumentStore
19+
{
20+
Urls = ["http://localhost:8080"],
21+
Database = "RavenSimpleSample",
22+
};
23+
24+
documentStore.Initialize();
25+
26+
var persistence = endpointConfiguration.UsePersistence<RavenDBPersistence>();
27+
persistence.SetDefaultDocumentStore(documentStore);
28+
29+
#endregion
30+
31+
var outbox = endpointConfiguration.EnableOutbox();
32+
outbox.SetTimeToKeepDeduplicationData(TimeSpan.FromMinutes(5));
33+
34+
var transport = new LearningTransport
35+
{
36+
TransportTransactionMode = TransportTransactionMode.ReceiveOnly
37+
};
38+
endpointConfiguration.UseSerialization<SystemJsonSerializer>();
39+
endpointConfiguration.UseTransport(transport);
40+
41+
await EnsureDatabaseExists(documentStore);
42+
43+
Console.WriteLine("Starting...");
44+
45+
builder.UseNServiceBus(endpointConfiguration);
46+
await builder.Build().RunAsync();
47+
48+
static async Task EnsureDatabaseExists(DocumentStore documentStore)
49+
{
50+
// create the database
51+
try
52+
{
53+
await documentStore.Maintenance.Server.SendAsync(new CreateDatabaseOperation(new DatabaseRecord(documentStore.Database)));
54+
}
55+
catch (ConcurrencyException)
56+
{
57+
// intentionally ignored
58+
}
59+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<LangVersion>preview</LangVersion>
5+
<TargetFramework>net10.0</TargetFramework>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<ProjectReference Include="..\Shared\Shared.csproj" />
10+
</ItemGroup>
11+
12+
<ItemGroup>
13+
<PackageReference Include="NServiceBus.Extensions.Hosting" Version="4.0.0-alpha.2" />
14+
<PackageReference Include="NServiceBus.RavenDB" Version="10.0.0-alpha.2" />
15+
<PackageReference Include="RavenDB.Client" Version="5.*" />
16+
</ItemGroup>
17+
</Project>

0 commit comments

Comments
 (0)