Skip to content

Commit 3cd2daf

Browse files
committed
Implemented body storage as a separate table
1 parent 2e2de7b commit 3cd2daf

File tree

16 files changed

+1190
-27
lines changed

16 files changed

+1190
-27
lines changed

src/ServiceControl.Persistence.Sql.Core/DbContexts/ServiceControlDbContextBase.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ protected ServiceControlDbContextBase(DbContextOptions options) : base(options)
1818
public DbSet<QueueAddressEntity> QueueAddresses { get; set; }
1919
public DbSet<KnownEndpointEntity> KnownEndpoints { get; set; }
2020
public DbSet<CustomCheckEntity> CustomChecks { get; set; }
21+
public DbSet<MessageBodyEntity> MessageBodies { get; set; }
2122

2223
protected override void OnModelCreating(ModelBuilder modelBuilder)
2324
{
@@ -31,6 +32,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
3132
modelBuilder.ApplyConfiguration(new QueueAddressConfiguration());
3233
modelBuilder.ApplyConfiguration(new KnownEndpointConfiguration());
3334
modelBuilder.ApplyConfiguration(new CustomCheckConfiguration());
35+
modelBuilder.ApplyConfiguration(new MessageBodyConfiguration());
3436

3537
OnModelCreatingProvider(modelBuilder);
3638
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace ServiceControl.Persistence.Sql.Core.Entities;
2+
3+
public class MessageBodyEntity
4+
{
5+
public string Id { get; set; } = null!;
6+
public byte[] Body { get; set; } = null!;
7+
public string ContentType { get; set; } = null!;
8+
public int BodySize { get; set; }
9+
public string? Etag { get; set; }
10+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
namespace ServiceControl.Persistence.Sql.Core.EntityConfigurations;
2+
3+
using Entities;
4+
using Microsoft.EntityFrameworkCore;
5+
using Microsoft.EntityFrameworkCore.Metadata.Builders;
6+
7+
class MessageBodyConfiguration : IEntityTypeConfiguration<MessageBodyEntity>
8+
{
9+
public void Configure(EntityTypeBuilder<MessageBodyEntity> builder)
10+
{
11+
builder.ToTable("MessageBodies");
12+
builder.HasKey(e => e.Id);
13+
builder.Property(e => e.Id).HasMaxLength(200).IsRequired();
14+
builder.Property(e => e.Body).IsRequired();
15+
builder.Property(e => e.ContentType).HasMaxLength(200).IsRequired();
16+
builder.Property(e => e.BodySize).IsRequired();
17+
builder.Property(e => e.Etag).HasMaxLength(100);
18+
}
19+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
namespace ServiceControl.Persistence.Sql.Core.Implementation;
2+
3+
using System;
4+
using System.IO;
5+
using System.Threading.Tasks;
6+
using DbContexts;
7+
using Microsoft.EntityFrameworkCore;
8+
using Microsoft.Extensions.DependencyInjection;
9+
using ServiceControl.Operations.BodyStorage;
10+
11+
public class BodyStorage : IBodyStorage
12+
{
13+
readonly IServiceProvider serviceProvider;
14+
15+
public BodyStorage(IServiceProvider serviceProvider)
16+
{
17+
this.serviceProvider = serviceProvider;
18+
}
19+
20+
public async Task<MessageBodyStreamResult> TryFetch(string bodyId)
21+
{
22+
using var scope = serviceProvider.CreateScope();
23+
var dbContext = scope.ServiceProvider.GetRequiredService<ServiceControlDbContextBase>();
24+
25+
// Try to fetch the body directly by ID
26+
var messageBody = await dbContext.MessageBodies
27+
.AsNoTracking()
28+
.FirstOrDefaultAsync(mb => mb.Id == bodyId);
29+
30+
if (messageBody == null)
31+
{
32+
return new MessageBodyStreamResult { HasResult = false };
33+
}
34+
35+
return new MessageBodyStreamResult
36+
{
37+
HasResult = true,
38+
Stream = new MemoryStream(messageBody.Body),
39+
ContentType = messageBody.ContentType,
40+
BodySize = messageBody.BodySize,
41+
Etag = messageBody.Etag
42+
};
43+
}
44+
}

src/ServiceControl.Persistence.Sql.MySQL/Migrations/20251209023203_AddMessageBodies.Designer.cs

Lines changed: 255 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#nullable disable
2+
3+
namespace ServiceControl.Persistence.Sql.MySQL.Migrations
4+
{
5+
using Microsoft.EntityFrameworkCore.Migrations;
6+
/// <inheritdoc />
7+
public partial class AddMessageBodies : Migration
8+
{
9+
/// <inheritdoc />
10+
protected override void Up(MigrationBuilder migrationBuilder)
11+
{
12+
migrationBuilder.CreateTable(
13+
name: "MessageBodies",
14+
columns: table => new
15+
{
16+
Id = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false)
17+
.Annotation("MySql:CharSet", "utf8mb4"),
18+
Body = table.Column<byte[]>(type: "longblob", nullable: false),
19+
ContentType = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false)
20+
.Annotation("MySql:CharSet", "utf8mb4"),
21+
BodySize = table.Column<int>(type: "int", nullable: false),
22+
Etag = table.Column<string>(type: "varchar(100)", maxLength: 100, nullable: true)
23+
.Annotation("MySql:CharSet", "utf8mb4")
24+
},
25+
constraints: table =>
26+
{
27+
table.PrimaryKey("PK_MessageBodies", x => x.Id);
28+
})
29+
.Annotation("MySql:CharSet", "utf8mb4");
30+
}
31+
32+
/// <inheritdoc />
33+
protected override void Down(MigrationBuilder migrationBuilder)
34+
{
35+
migrationBuilder.DropTable(
36+
name: "MessageBodies");
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)