Skip to content

Commit e6e3841

Browse files
committed
#392 Host.Outbox.PostgreSql
Signed-off-by: Richard Pringle <richardpringle@gmail.com>
1 parent 54e6785 commit e6e3841

File tree

57 files changed

+2907
-180
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+2907
-180
lines changed

docs/plugin_outbox.md

Lines changed: 93 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,16 @@ Please read the [Introduction](intro.md) before reading this provider documentat
55
- [Introduction](#introduction)
66
- [Configuration](#configuration)
77
- [Entity Framework](#entity-framework)
8-
- [SQL Connection](#sql-connection)
8+
- [PostgreSQL](#postgresql)
9+
- [SQL Server](#sql-server)
10+
- [Direct Connection](#direct-connection)
11+
- [PostgreSQL](#postgresql-1)
12+
- [SQL Server](#sql-server-1)
913
- [Options](#options)
1014
- [UseOutbox for Producers](#useoutbox-for-producers)
1115
- [Transactions for Consumers](#transactions-for-consumers)
1216
- [UseTransactionScope](#usetransactionscope)
17+
- [UsePostgreSqlTransaction](#usepostgresqltransaction)
1318
- [UseSqlTransaction](#usesqltransaction)
1419
- [How it works](#how-it-works)
1520
- [Clean up](#clean-up)
@@ -18,16 +23,29 @@ Please read the [Introduction](intro.md) before reading this provider documentat
1823
## Introduction
1924

2025
The [`Host.Outbox`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox) introduces [Transactional Outbox](https://microservices.io/patterns/data/transactional-outbox.html) pattern to the SlimMessageBus.
21-
It comes in two flavors:
2226

27+
PostgreSQL
28+
- [`Host.Outbox.PostgreSql`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.PostgreSql) as integration with the [Npgsql](https://www.npgsql.org/) client
29+
- [`Host.Outbox.PostgreSql.DbContext`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.PostgreSql.DbContext) as integration with Entity Framework Core using Npgsql
30+
31+
SQL server
2332
- [`Host.Outbox.Sql`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.Sql) as integration with the System.Data.Sql client (MSSQL)
24-
- [`Host.Outbox.Sql.DbContext`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.Sql.DbContext) as integration with Entity Framework Core
33+
- [`Host.Outbox.Sql.DbContext`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.Sql.DbContext) as integration with Entity Framework Core using System.Data.Sql
2534

2635
Outbox plugin can work in combination with any transport provider.
2736

2837
## Configuration
2938

3039
### Entity Framework
40+
#### PostgreSQL
41+
42+
> Required: [`SlimMessageBus.Host.Outbox.PostgreSql.DbContext`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.PostgreSql.DbContext)
43+
44+
```cs
45+
using SlimMessageBus.Host.Outbox.PostgreSql.DbContext;
46+
```
47+
48+
#### SQL Server
3149

3250
> Required: [`SlimMessageBus.Host.Outbox.Sql.DbContext`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.Sql.DbContext)
3351
@@ -40,7 +58,7 @@ Consider the following example (from [Samples](../src/Samples/Sample.OutboxWebAp
4058
- `services.AddOutboxUsingDbContext<CustomerContext>(...)` is used to add the [Outbox.DbContext](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.Sql.DbContext) plugin to the container.
4159
- `CustomerContext` is the application specific Entity Framework `DbContext`.
4260
- `CustomerCreatedEvent` is produced on the `AzureSB` child bus, the bus will deliver these events via outbox - see `.UseOutbox()`
43-
- `CreateCustomerCommand` is consumed on the `Memory` child bus, each command is wrapped in an SQL transaction - see `UseSqlTransaction()`
61+
- `CreateCustomerCommand` is consumed on the `Memory` child bus, each command is wrapped in an SQL transaction - see `UsePostgreSqlTransaction()` / `UseSqlTransaction()`
4462

4563
Startup setup:
4664

@@ -52,9 +70,20 @@ builder.Services.AddSlimMessageBus(mbb =>
5270
.AddChildBus("Memory", mbb =>
5371
{
5472
mbb.WithProviderMemory()
55-
.AutoDeclareFrom(Assembly.GetExecutingAssembly(), consumerTypeFilter: t => t.Name.EndsWith("CommandHandler"))
56-
//.UseTransactionScope(messageTypeFilter: t => t.Name.EndsWith("Command")) // Consumers/Handlers will be wrapped in a TransactionScope
57-
.UseSqlTransaction(messageTypeFilter: t => t.Name.EndsWith("Command")); // Consumers/Handlers will be wrapped in a SqlTransaction ending with Command
73+
.AutoDeclareFrom(Assembly.GetExecutingAssembly(), consumerTypeFilter: t => t.Name.EndsWith("CommandHandler"));
74+
//.UseTransactionScope(messageTypeFilter: t => t.Name.EndsWith("Command")) // Consumers/Handlers will be wrapped in a TransactionScope
75+
//.UseSqlTransaction(messageTypeFilter: t => t.Name.EndsWith("Command")); // Consumers/Handlers will be wrapped in a SqlTransaction ending with Command
76+
77+
switch (dbProvider)
78+
{
79+
case DbProvider.SqlServer:
80+
mbb.UseSqlTransaction(messageTypeFilter: t => t.Name.EndsWith("Command")); // Consumers/Handlers will be wrapped in a SqlTransaction ending with Command
81+
break;
82+
83+
case DbProvider.PostgreSql:
84+
mbb.UsePostgreSqlTransaction(messageTypeFilter: t => t.Name.EndsWith("Command")); // Consumers/Handlers will be wrapped in a SqlTransaction ending with Command
85+
break;
86+
}
5887
})
5988
.AddChildBus("AzureSB", mbb =>
6089
{
@@ -81,20 +110,40 @@ builder.Services.AddSlimMessageBus(mbb =>
81110
// x.UseOutbox();
82111
})
83112
// All outgoing messages from this bus will go out via an outbox
84-
.UseOutbox(/* messageTypeFilter: t => t.Name.EndsWith("Command") */); // Additionaly, can apply filter do determine messages that should go out via outbox
113+
.UseOutbox(/* messageTypeFilter: t => t.Name.EndsWith("Command") */); // Additionally, can apply filter do determine messages that should go out via outbox
85114
})
86115
.AddServicesFromAssembly(Assembly.GetExecutingAssembly())
87116
.AddJsonSerializer()
88-
.AddAspNet()
89-
.AddOutboxUsingDbContext<CustomerContext>(opts =>
90-
{
91-
opts.PollBatchSize = 100;
92-
opts.PollIdleSleep = TimeSpan.FromSeconds(10);
93-
opts.MessageCleanup.Interval = TimeSpan.FromSeconds(10);
94-
opts.MessageCleanup.Age = TimeSpan.FromMinutes(1);
95-
//opts.SqlSettings.TransactionIsolationLevel = System.Data.IsolationLevel.RepeatableRead;
96-
//opts.SqlSettings.Dialect = SqlDialect.SqlServer;
97-
});
117+
.AddAspNet();
118+
119+
switch (dbProvider)
120+
{
121+
case DbProvider.SqlServer:
122+
SlimMessageBus.Host.Outbox.Sql.DbContext.MessageBusBuilderExtensions.AddOutboxUsingDbContext<CustomerContext>(mbb, opts =>
123+
{
124+
opts.PollBatchSize = 500;
125+
opts.PollIdleSleep = TimeSpan.FromSeconds(10);
126+
opts.MessageCleanup.Interval = TimeSpan.FromSeconds(10);
127+
opts.MessageCleanup.Age = TimeSpan.FromMinutes(1);
128+
//opts.SqlSettings.TransactionIsolationLevel = System.Data.IsolationLevel.RepeatableRead;
129+
//opts.SqlSettings.Dialect = SqlDialect.SqlServer;
130+
});
131+
132+
break;
133+
134+
case DbProvider.PostgreSql:
135+
SlimMessageBus.Host.Outbox.PostgreSql.DbContext.MessageBusBuilderExtensions.AddOutboxUsingDbContext<CustomerContext>(mbb, opts =>
136+
{
137+
opts.PollBatchSize = 500;
138+
opts.PollIdleSleep = TimeSpan.FromSeconds(10);
139+
opts.MessageCleanup.Interval = TimeSpan.FromSeconds(10);
140+
opts.MessageCleanup.Age = TimeSpan.FromMinutes(1);
141+
//opts.SqlSettings.TransactionIsolationLevel = System.Data.IsolationLevel.RepeatableRead;
142+
//opts.SqlSettings.Dialect = SqlDialect.SqlServer;
143+
});
144+
145+
break;
146+
}
98147
});
99148
```
100149

@@ -119,7 +168,16 @@ public record CreateCustomerCommandHandler(IMessageBus Bus, CustomerContext Cust
119168
}
120169
```
121170

122-
### SQL Connection
171+
### Direct Connection
172+
#### PostgreSQL
173+
174+
> Required: [`SlimMessageBus.Host.Outbox.PostgreSql`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.PostgreSql)
175+
176+
```cs
177+
using SlimMessageBus.Host.Outbox.PostgreSql;
178+
```
179+
180+
#### SQL Server
123181

124182
> Required: [`SlimMessageBus.Host.Outbox.Sql`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.Sql)
125183
@@ -129,7 +187,7 @@ using SlimMessageBus.Host.Outbox.Sql;
129187

130188
Consider the following example:
131189

132-
- `services.AddMessageBusOutboxUsingSql(...)` is used to add the [Outbox.Sql](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.Sql) plugin to the container.
190+
- `services.AddOutboxUsingSql(...)` is used to add the [Outbox.Sql](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.Sql) plugin to the container.
133191
- `SqlConnection` is registered in the container
134192

135193
```cs
@@ -181,6 +239,20 @@ using SlimMessageBus.Host.Outbox;
181239

182240
When applied on the (child) bus level then all consumers (or handlers) will inherit that option.
183241

242+
#### UsePostgreSqlTransaction
243+
244+
> Required: [`SlimMessageBus.Host.Outbox.PostgreSql`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.PostgreSql) or [`SlimMessageBus.Host.Outbox.PostgreSql.DbContext`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.PostgreSql.DbContext)
245+
246+
```cs
247+
using SlimMessageBus.Host.Outbox.PostgreSql;
248+
```
249+
250+
`.UsePostgreSqlTransaction()` can be used on consumers (or handlers) declaration to force the consumer to start a `PostgreSqlTransaction` prior the message `OnHandle` and to complete that transaction after it. Any exception raised by the consumer would cause the transaction to be rolled back.
251+
252+
When applied on the (child) bus level then all consumers (or handlers) will inherit that option.
253+
254+
`PostgreSqlTransaction`-s are created off the associated `NpgsqlConnection`.
255+
184256
#### UseSqlTransaction
185257

186258
> Required: [`SlimMessageBus.Host.Outbox.Sql`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.Sql) or [`SlimMessageBus.Host.Outbox.Sql.DbContext`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.Sql.DbContext)
@@ -204,7 +276,7 @@ When applied on the (child) bus level then all consumers (or handlers) will inhe
204276
- When a message is sent via a bus or producer marked with `.UseOutbox()` then such message will be inserted into the `Outbox` table.
205277
It is important that message publish happens in the context of an transaction to ensure consistency.
206278

207-
- When the message publication happens in the context of a consumer (or handler) of another message, the `.UseTransactionScope()`, `.UseSqlTransaction()` can be used to start a transaction.
279+
- When the message publication happens in the context of a consumer (or handler) of another message, the `.UseTransactionScope()`, `.UseSqlTransaction()` or `.UseSqlTransaction()` can be used to start a transaction.
208280

209281
- The transaction can be managed by the application, starting it either explicitly using `DbContext.Database.BeginTransactionAsync()` or creating a `TransactionScope()`.
210282

docs/plugin_outbox.t.md

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,16 @@ Please read the [Introduction](intro.md) before reading this provider documentat
55
- [Introduction](#introduction)
66
- [Configuration](#configuration)
77
- [Entity Framework](#entity-framework)
8-
- [SQL Connection](#sql-connection)
8+
- [PostgreSQL](#postgresql)
9+
- [SQL Server](#sql-server)
10+
- [Direct Connection](#direct-connection)
11+
- [PostgreSQL](#postgresql-1)
12+
- [SQL Server](#sql-server-1)
913
- [Options](#options)
1014
- [UseOutbox for Producers](#useoutbox-for-producers)
1115
- [Transactions for Consumers](#transactions-for-consumers)
1216
- [UseTransactionScope](#usetransactionscope)
17+
- [UsePostgreSqlTransaction](#usepostgresqltransaction)
1318
- [UseSqlTransaction](#usesqltransaction)
1419
- [How it works](#how-it-works)
1520
- [Clean up](#clean-up)
@@ -18,16 +23,29 @@ Please read the [Introduction](intro.md) before reading this provider documentat
1823
## Introduction
1924

2025
The [`Host.Outbox`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox) introduces [Transactional Outbox](https://microservices.io/patterns/data/transactional-outbox.html) pattern to the SlimMessageBus.
21-
It comes in two flavors:
2226

27+
PostgreSQL
28+
- [`Host.Outbox.PostgreSql`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.PostgreSql) as integration with the [Npgsql](https://www.npgsql.org/) client
29+
- [`Host.Outbox.PostgreSql.DbContext`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.PostgreSql.DbContext) as integration with Entity Framework Core using Npgsql
30+
31+
SQL server
2332
- [`Host.Outbox.Sql`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.Sql) as integration with the System.Data.Sql client (MSSQL)
24-
- [`Host.Outbox.Sql.DbContext`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.Sql.DbContext) as integration with Entity Framework Core
33+
- [`Host.Outbox.Sql.DbContext`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.Sql.DbContext) as integration with Entity Framework Core using System.Data.Sql
2534

2635
Outbox plugin can work in combination with any transport provider.
2736

2837
## Configuration
2938

3039
### Entity Framework
40+
#### PostgreSQL
41+
42+
> Required: [`SlimMessageBus.Host.Outbox.PostgreSql.DbContext`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.PostgreSql.DbContext)
43+
44+
```cs
45+
using SlimMessageBus.Host.Outbox.PostgreSql.DbContext;
46+
```
47+
48+
#### SQL Server
3149

3250
> Required: [`SlimMessageBus.Host.Outbox.Sql.DbContext`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.Sql.DbContext)
3351
@@ -40,7 +58,7 @@ Consider the following example (from [Samples](../src/Samples/Sample.OutboxWebAp
4058
- `services.AddOutboxUsingDbContext<CustomerContext>(...)` is used to add the [Outbox.DbContext](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.Sql.DbContext) plugin to the container.
4159
- `CustomerContext` is the application specific Entity Framework `DbContext`.
4260
- `CustomerCreatedEvent` is produced on the `AzureSB` child bus, the bus will deliver these events via outbox - see `.UseOutbox()`
43-
- `CreateCustomerCommand` is consumed on the `Memory` child bus, each command is wrapped in an SQL transaction - see `UseSqlTransaction()`
61+
- `CreateCustomerCommand` is consumed on the `Memory` child bus, each command is wrapped in an SQL transaction - see `UsePostgreSqlTransaction()` / `UseSqlTransaction()`
4462

4563
Startup setup:
4664

@@ -50,7 +68,16 @@ Command handler:
5068

5169
@[:cs](../src/Samples/Sample.OutboxWebApi/Application/CreateCustomerCommandHandler.cs,Handler)
5270

53-
### SQL Connection
71+
### Direct Connection
72+
#### PostgreSQL
73+
74+
> Required: [`SlimMessageBus.Host.Outbox.PostgreSql`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.PostgreSql)
75+
76+
```cs
77+
using SlimMessageBus.Host.Outbox.PostgreSql;
78+
```
79+
80+
#### SQL Server
5481

5582
> Required: [`SlimMessageBus.Host.Outbox.Sql`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.Sql)
5683
@@ -60,7 +87,7 @@ using SlimMessageBus.Host.Outbox.Sql;
6087

6188
Consider the following example:
6289

63-
- `services.AddMessageBusOutboxUsingSql(...)` is used to add the [Outbox.Sql](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.Sql) plugin to the container.
90+
- `services.AddOutboxUsingSql(...)` is used to add the [Outbox.Sql](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.Sql) plugin to the container.
6491
- `SqlConnection` is registered in the container
6592

6693
```cs
@@ -112,6 +139,20 @@ using SlimMessageBus.Host.Outbox;
112139

113140
When applied on the (child) bus level then all consumers (or handlers) will inherit that option.
114141

142+
#### UsePostgreSqlTransaction
143+
144+
> Required: [`SlimMessageBus.Host.Outbox.PostgreSql`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.PostgreSql) or [`SlimMessageBus.Host.Outbox.PostgreSql.DbContext`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.PostgreSql.DbContext)
145+
146+
```cs
147+
using SlimMessageBus.Host.Outbox.PostgreSql;
148+
```
149+
150+
`.UsePostgreSqlTransaction()` can be used on consumers (or handlers) declaration to force the consumer to start a `PostgreSqlTransaction` prior the message `OnHandle` and to complete that transaction after it. Any exception raised by the consumer would cause the transaction to be rolled back.
151+
152+
When applied on the (child) bus level then all consumers (or handlers) will inherit that option.
153+
154+
`PostgreSqlTransaction`-s are created off the associated `NpgsqlConnection`.
155+
115156
#### UseSqlTransaction
116157

117158
> Required: [`SlimMessageBus.Host.Outbox.Sql`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.Sql) or [`SlimMessageBus.Host.Outbox.Sql.DbContext`](https://www.nuget.org/packages/SlimMessageBus.Host.Outbox.Sql.DbContext)
@@ -135,7 +176,7 @@ When applied on the (child) bus level then all consumers (or handlers) will inhe
135176
- When a message is sent via a bus or producer marked with `.UseOutbox()` then such message will be inserted into the `Outbox` table.
136177
It is important that message publish happens in the context of an transaction to ensure consistency.
137178

138-
- When the message publication happens in the context of a consumer (or handler) of another message, the `.UseTransactionScope()`, `.UseSqlTransaction()` can be used to start a transaction.
179+
- When the message publication happens in the context of a consumer (or handler) of another message, the `.UseTransactionScope()`, `.UseSqlTransaction()` or `.UseSqlTransaction()` can be used to start a transaction.
139180

140181
- The transaction can be managed by the application, starting it either explicitly using `DbContext.Database.BeginTransactionAsync()` or creating a `TransactionScope()`.
141182

src/Infrastructure/docker-compose.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ services:
3434
networks:
3535
- slim
3636

37+
psqldb:
38+
container_name: slim.psql
39+
image: postgres:17.4
40+
environment:
41+
- POSTGRES_USER=postgres
42+
- POSTGRES_PASSWORD=SecretP@55word
43+
ports:
44+
- 5432:5432
45+
networks:
46+
- slim
47+
3748
rabbitmq:
3849
container_name: slim.rabbitmq
3950
image: rabbitmq:3.12.14-management-alpine
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace Sample.OutboxWebApi;
2+
3+
public enum DbProvider
4+
{
5+
PostgreSql,
6+
SqlServer
7+
}

src/Samples/Sample.OutboxWebApi/Migrations/20230105224220_InitialCreate.Designer.cs

Lines changed: 0 additions & 49 deletions
This file was deleted.

0 commit comments

Comments
 (0)