From a44912ac8715680c0372184f410957f26b3f4354 Mon Sep 17 00:00:00 2001 From: masiton Date: Sat, 5 Jul 2025 17:07:53 +0200 Subject: [PATCH] payloadLifespan/payloadLifetime and other name variants unified to Time To Live naming. --- Directory.Packages.props | 3 +- README.md | 6 +- .../MessengerApi.Configuration.csproj | 1 + .../Model/MessengerConfiguration.cs | 6 +- .../Constants.EnvironmentVariables.cs | 2 +- .../Entities/Message.cs | 2 +- .../MessengerApi.Db.Contracts.csproj | 1 + .../MessengerApi.Db.Npg.Migrator.csproj | 5 + .../MessengerApi.Db.Npg.csproj | 5 +- ...20250705145537_RenameTtlColumn.Designer.cs | 123 +++++++++++++++++ .../20250705145537_RenameTtlColumn.cs | 28 ++++ .../MessengerNpgDbContextModelSnapshot.cs | 6 +- .../MessengerApi.Db.Sql.Migrator.csproj | 4 + .../MessengerApi.Db.Sql.csproj | 3 +- ...ortenPayloadLifespanColumnName.Designer.cs | 125 ++++++++++++++++++ ...145221_ShortenPayloadLifespanColumnName.cs | 28 ++++ ...0705145452_RenameTtlColumnName.Designer.cs | 125 ++++++++++++++++++ .../20250705145452_RenameTtlColumnName.cs | 28 ++++ .../MessengerSqlDbContextModelSnapshot.cs | 6 +- code/MessengerApi.Db/MessengerDbContext.cs | 2 +- .../Repositories/MessageRepository.cs | 2 +- .../Handlers/Endpoint/SendEndpointHandler.cs | 4 +- code/MessengerApi/Models/Http/SendRequest.cs | 2 +- code/MessengerApi/Program.cs | 2 +- .../Properties/launchSettings.json | 2 +- 25 files changed, 496 insertions(+), 25 deletions(-) create mode 100644 code/MessengerApi.Db.Npg/Migrations/20250705145537_RenameTtlColumn.Designer.cs create mode 100644 code/MessengerApi.Db.Npg/Migrations/20250705145537_RenameTtlColumn.cs create mode 100644 code/MessengerApi.Db.Sql/Migrations/20250705145221_ShortenPayloadLifespanColumnName.Designer.cs create mode 100644 code/MessengerApi.Db.Sql/Migrations/20250705145221_ShortenPayloadLifespanColumnName.cs create mode 100644 code/MessengerApi.Db.Sql/Migrations/20250705145452_RenameTtlColumnName.Designer.cs create mode 100644 code/MessengerApi.Db.Sql/Migrations/20250705145452_RenameTtlColumnName.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index d7f66d9..5a1df6d 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -3,9 +3,10 @@ + + - diff --git a/README.md b/README.md index 641f808..ce8e1cf 100644 --- a/README.md +++ b/README.md @@ -49,9 +49,9 @@ Additional tunables, with their sustainable default values: - `QUERY_RATE_PER_MINUTE: 100` - Sets maximum allowed client query rate per minute for all endpoints. Anonymous users share same limit pool. - If send rate is exceeded, client receives a `HTTP 429` with explanation. -- `DEFAULT_MESSAGE_LIFETIME_IN_MINUTES: 1` +- `DEFAULT_MESSAGE_TIME_TO_LIVE_IN_SECONDS: 60` - Message will wait for delivery for set amount of time. After the time passes, a call to `/receive` will not consider it for delivery anymore. - - Override this in message content by setting _optional_ `lifespanInSeconds` value inside the request. + - Override this in message content by setting _optional_ `timeToLiveInSeconds` value inside the request. - There will be no indication to the sender or to client that there was a missed message. Once it's gone, it's gone. - `HOUSEKEEPING_ENABLED: true` - Turns on housekeeping job that periodically removes stale, delivered and/or acknowledged messages. You can tune this further, see below. By default, it only removes messages that are 2 hours old, regardless of their delivery or acknowledgement state. @@ -106,7 +106,7 @@ Request: "payloadType": "STATUS", "payload": "{\n \"system\": \"OK\",\n}", "toUserId": "46b882b7-4b96-4fa2-ba1b-4955a9500c36", - "lifespanInSeconds": "3600" + "timeToLiveInSeconds": "3600" } Response: diff --git a/code/MessengerApi.Configuration/MessengerApi.Configuration.csproj b/code/MessengerApi.Configuration/MessengerApi.Configuration.csproj index ef83a76..a98a8dc 100644 --- a/code/MessengerApi.Configuration/MessengerApi.Configuration.csproj +++ b/code/MessengerApi.Configuration/MessengerApi.Configuration.csproj @@ -4,6 +4,7 @@ net9.0 enable disable + true diff --git a/code/MessengerApi.Configuration/Model/MessengerConfiguration.cs b/code/MessengerApi.Configuration/Model/MessengerConfiguration.cs index df1e7e3..a8881be 100644 --- a/code/MessengerApi.Configuration/Model/MessengerConfiguration.cs +++ b/code/MessengerApi.Configuration/Model/MessengerConfiguration.cs @@ -31,7 +31,7 @@ namespace MessengerApi.Configuration.Model /// /// Message lifetime unless set differently in message body. /// - public int DefaultMessageLifetimeInMinutes { get; set; } + public int DefaultMessageTimeToLiveInSeconds { get; set; } /// /// If true, messages are periodically wiped to free up space. @@ -72,7 +72,7 @@ namespace MessengerApi.Configuration.Model this.Origins = origins ?? []; this.Proxies = []; this.RateLimitPerMinute = 120; - this.DefaultMessageLifetimeInMinutes = 1; + this.DefaultMessageTimeToLiveInSeconds = 60; this.HousekeepingEnabled = true; this.HousekeepingMessageAgeInMinutes = 120; this.HousekeepingMessageState = HousekeepingMessageStates.None; @@ -85,7 +85,7 @@ namespace MessengerApi.Configuration.Model { Populate(config, Env.PROXIES, x => this.Proxies = ProxiesParser.Parse(x)); Populate(config, Env.QUERY_RATE_PER_MINUTE, x => this.RateLimitPerMinute = x); - Populate(config, Env.DEFAULT_MESSAGE_LIFETIME_IN_MINUTES, x => this.DefaultMessageLifetimeInMinutes = x); + Populate(config, Env.DEFAULT_MESSAGE_TIME_TO_LIVE_IN_SECONDS, x => this.DefaultMessageTimeToLiveInSeconds = x); Populate(config, Env.HOUSEKEEPING_ENABLED, x => this.HousekeepingEnabled = x); Populate(config, Env.HOUSEKEEPING_MESSAGE_AGE_IN_MINUTES, x => this.HousekeepingMessageAgeInMinutes = x); Populate(config, Env.HOUSEKEEPING_MESSAGE_STATE, x => this.HousekeepingMessageState = HousekeepingMessageStateParser.Parse(x)); diff --git a/code/MessengerApi.Configuration/Sources/Environment/Constants.EnvironmentVariables.cs b/code/MessengerApi.Configuration/Sources/Environment/Constants.EnvironmentVariables.cs index db1fc53..8934a38 100644 --- a/code/MessengerApi.Configuration/Sources/Environment/Constants.EnvironmentVariables.cs +++ b/code/MessengerApi.Configuration/Sources/Environment/Constants.EnvironmentVariables.cs @@ -10,7 +10,7 @@ public const string CORS_ORIGINS = nameof(CORS_ORIGINS); public const string PROXIES = nameof(PROXIES); public const string QUERY_RATE_PER_MINUTE = nameof(QUERY_RATE_PER_MINUTE); - public const string DEFAULT_MESSAGE_LIFETIME_IN_MINUTES = nameof(DEFAULT_MESSAGE_LIFETIME_IN_MINUTES); + public const string DEFAULT_MESSAGE_TIME_TO_LIVE_IN_SECONDS = nameof(DEFAULT_MESSAGE_TIME_TO_LIVE_IN_SECONDS); public const string HOUSEKEEPING_ENABLED = nameof(HOUSEKEEPING_ENABLED); public const string HOUSEKEEPING_MESSAGE_AGE_IN_MINUTES = nameof(HOUSEKEEPING_MESSAGE_AGE_IN_MINUTES); public const string HOUSEKEEPING_MESSAGE_STATE = nameof(HOUSEKEEPING_MESSAGE_STATE); diff --git a/code/MessengerApi.Db.Contracts/Entities/Message.cs b/code/MessengerApi.Db.Contracts/Entities/Message.cs index aa8b9a9..063f222 100644 --- a/code/MessengerApi.Db.Contracts/Entities/Message.cs +++ b/code/MessengerApi.Db.Contracts/Entities/Message.cs @@ -20,6 +20,6 @@ namespace MessengerApi.Db.Entities public string Payload { get; set; } - public int? PayloadLifespanInSeconds { get; set; } + public int? TimeToLiveInSeconds { get; set; } } } \ No newline at end of file diff --git a/code/MessengerApi.Db.Contracts/MessengerApi.Db.Contracts.csproj b/code/MessengerApi.Db.Contracts/MessengerApi.Db.Contracts.csproj index ef83a76..a98a8dc 100644 --- a/code/MessengerApi.Db.Contracts/MessengerApi.Db.Contracts.csproj +++ b/code/MessengerApi.Db.Contracts/MessengerApi.Db.Contracts.csproj @@ -4,6 +4,7 @@ net9.0 enable disable + true diff --git a/code/MessengerApi.Db.Npg.Migrator/MessengerApi.Db.Npg.Migrator.csproj b/code/MessengerApi.Db.Npg.Migrator/MessengerApi.Db.Npg.Migrator.csproj index cd92fc0..21631db 100644 --- a/code/MessengerApi.Db.Npg.Migrator/MessengerApi.Db.Npg.Migrator.csproj +++ b/code/MessengerApi.Db.Npg.Migrator/MessengerApi.Db.Npg.Migrator.csproj @@ -8,10 +8,15 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/code/MessengerApi.Db.Npg/MessengerApi.Db.Npg.csproj b/code/MessengerApi.Db.Npg/MessengerApi.Db.Npg.csproj index e6f0e7b..0250679 100644 --- a/code/MessengerApi.Db.Npg/MessengerApi.Db.Npg.csproj +++ b/code/MessengerApi.Db.Npg/MessengerApi.Db.Npg.csproj @@ -3,11 +3,12 @@ net9.0 enable - enable + disable + true - + diff --git a/code/MessengerApi.Db.Npg/Migrations/20250705145537_RenameTtlColumn.Designer.cs b/code/MessengerApi.Db.Npg/Migrations/20250705145537_RenameTtlColumn.Designer.cs new file mode 100644 index 0000000..0e1b528 --- /dev/null +++ b/code/MessengerApi.Db.Npg/Migrations/20250705145537_RenameTtlColumn.Designer.cs @@ -0,0 +1,123 @@ +// +using System; +using MessengerApi.Db.Npg; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace MessengerApi.Db.Npg.Migrations +{ + [DbContext(typeof(MessengerNpgDbContext))] + [Migration("20250705145537_RenameTtlColumn")] + partial class RenameTtlColumn + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.6") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("MessengerApi.Db.Entities.Message", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedUtc") + .HasColumnType("timestamp with time zone"); + + b.Property("FromId") + .HasColumnType("uuid"); + + b.Property("IsAcknowledged") + .HasColumnType("boolean"); + + b.Property("IsDelivered") + .HasColumnType("boolean"); + + b.Property("Payload") + .HasColumnType("text"); + + b.Property("PayloadType") + .HasColumnType("text"); + + b.Property("TimeToLiveInSeconds") + .HasColumnType("integer"); + + b.Property("ToId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ToId", "IsDelivered"); + + b.ToTable("Messages"); + }); + + modelBuilder.Entity("MessengerApi.Db.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ApiKey") + .HasColumnType("uuid"); + + b.Property("IsEnabled") + .HasColumnType("boolean"); + + b.Property("Name") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("MessengerApi.Db.Entities.UserRoute", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("FromId") + .HasColumnType("uuid"); + + b.Property("ToId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("FromId"); + + b.HasIndex("ToId"); + + b.ToTable("UserRoutes"); + }); + + modelBuilder.Entity("MessengerApi.Db.Entities.UserRoute", b => + { + b.HasOne("MessengerApi.Db.Entities.User", "From") + .WithMany() + .HasForeignKey("FromId"); + + b.HasOne("MessengerApi.Db.Entities.User", "To") + .WithMany() + .HasForeignKey("ToId"); + + b.Navigation("From"); + + b.Navigation("To"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/code/MessengerApi.Db.Npg/Migrations/20250705145537_RenameTtlColumn.cs b/code/MessengerApi.Db.Npg/Migrations/20250705145537_RenameTtlColumn.cs new file mode 100644 index 0000000..53ae1ca --- /dev/null +++ b/code/MessengerApi.Db.Npg/Migrations/20250705145537_RenameTtlColumn.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace MessengerApi.Db.Npg.Migrations +{ + /// + public partial class RenameTtlColumn : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.RenameColumn( + name: "PayloadLifespanInSeconds", + table: "Messages", + newName: "TimeToLiveInSeconds"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.RenameColumn( + name: "TimeToLiveInSeconds", + table: "Messages", + newName: "PayloadLifespanInSeconds"); + } + } +} diff --git a/code/MessengerApi.Db.Npg/Migrations/MessengerNpgDbContextModelSnapshot.cs b/code/MessengerApi.Db.Npg/Migrations/MessengerNpgDbContextModelSnapshot.cs index 66307cb..70d6458 100644 --- a/code/MessengerApi.Db.Npg/Migrations/MessengerNpgDbContextModelSnapshot.cs +++ b/code/MessengerApi.Db.Npg/Migrations/MessengerNpgDbContextModelSnapshot.cs @@ -43,12 +43,12 @@ namespace MessengerApi.Db.Npg.Migrations b.Property("Payload") .HasColumnType("text"); - b.Property("PayloadLifespanInSeconds") - .HasColumnType("integer"); - b.Property("PayloadType") .HasColumnType("text"); + b.Property("TimeToLiveInSeconds") + .HasColumnType("integer"); + b.Property("ToId") .HasColumnType("uuid"); diff --git a/code/MessengerApi.Db.Sql.Migrator/MessengerApi.Db.Sql.Migrator.csproj b/code/MessengerApi.Db.Sql.Migrator/MessengerApi.Db.Sql.Migrator.csproj index dc203c9..ffb9e82 100644 --- a/code/MessengerApi.Db.Sql.Migrator/MessengerApi.Db.Sql.Migrator.csproj +++ b/code/MessengerApi.Db.Sql.Migrator/MessengerApi.Db.Sql.Migrator.csproj @@ -13,6 +13,10 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/code/MessengerApi.Db.Sql/MessengerApi.Db.Sql.csproj b/code/MessengerApi.Db.Sql/MessengerApi.Db.Sql.csproj index 0372cd2..dc3792e 100644 --- a/code/MessengerApi.Db.Sql/MessengerApi.Db.Sql.csproj +++ b/code/MessengerApi.Db.Sql/MessengerApi.Db.Sql.csproj @@ -4,10 +4,11 @@ net9.0 enable enable + true - + diff --git a/code/MessengerApi.Db.Sql/Migrations/20250705145221_ShortenPayloadLifespanColumnName.Designer.cs b/code/MessengerApi.Db.Sql/Migrations/20250705145221_ShortenPayloadLifespanColumnName.Designer.cs new file mode 100644 index 0000000..2a94b25 --- /dev/null +++ b/code/MessengerApi.Db.Sql/Migrations/20250705145221_ShortenPayloadLifespanColumnName.Designer.cs @@ -0,0 +1,125 @@ +// +using System; +using MessengerApi.Db.Sql; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace MessengerApi.Db.Sql.Migrations +{ + [DbContext(typeof(MessengerSqlDbContext))] + [Migration("20250705145221_ShortenPayloadLifespanColumnName")] + partial class ShortenPayloadLifespanColumnName + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.6") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("MessengerApi.Db.Entities.Message", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedUtc") + .HasColumnType("datetime2"); + + b.Property("FromId") + .HasColumnType("uniqueidentifier"); + + b.Property("IsAcknowledged") + .HasColumnType("bit"); + + b.Property("IsDelivered") + .HasColumnType("bit"); + + b.Property("LifespanInSeconds") + .HasColumnType("int"); + + b.Property("Payload") + .HasColumnType("nvarchar(max)"); + + b.Property("PayloadType") + .HasColumnType("nvarchar(max)"); + + b.Property("ToId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ToId", "IsDelivered"); + + SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("ToId", "IsDelivered"), false); + + b.ToTable("Messages"); + }); + + modelBuilder.Entity("MessengerApi.Db.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ApiKey") + .HasColumnType("uniqueidentifier"); + + b.Property("IsEnabled") + .HasColumnType("bit"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("MessengerApi.Db.Entities.UserRoute", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("FromId") + .HasColumnType("uniqueidentifier"); + + b.Property("ToId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("FromId"); + + b.HasIndex("ToId"); + + b.ToTable("UserRoutes"); + }); + + modelBuilder.Entity("MessengerApi.Db.Entities.UserRoute", b => + { + b.HasOne("MessengerApi.Db.Entities.User", "From") + .WithMany() + .HasForeignKey("FromId"); + + b.HasOne("MessengerApi.Db.Entities.User", "To") + .WithMany() + .HasForeignKey("ToId"); + + b.Navigation("From"); + + b.Navigation("To"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/code/MessengerApi.Db.Sql/Migrations/20250705145221_ShortenPayloadLifespanColumnName.cs b/code/MessengerApi.Db.Sql/Migrations/20250705145221_ShortenPayloadLifespanColumnName.cs new file mode 100644 index 0000000..c69f8f6 --- /dev/null +++ b/code/MessengerApi.Db.Sql/Migrations/20250705145221_ShortenPayloadLifespanColumnName.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace MessengerApi.Db.Sql.Migrations +{ + /// + public partial class ShortenPayloadLifespanColumnName : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.RenameColumn( + name: "PayloadLifespanInSeconds", + table: "Messages", + newName: "LifespanInSeconds"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.RenameColumn( + name: "LifespanInSeconds", + table: "Messages", + newName: "PayloadLifespanInSeconds"); + } + } +} diff --git a/code/MessengerApi.Db.Sql/Migrations/20250705145452_RenameTtlColumnName.Designer.cs b/code/MessengerApi.Db.Sql/Migrations/20250705145452_RenameTtlColumnName.Designer.cs new file mode 100644 index 0000000..e4ac520 --- /dev/null +++ b/code/MessengerApi.Db.Sql/Migrations/20250705145452_RenameTtlColumnName.Designer.cs @@ -0,0 +1,125 @@ +// +using System; +using MessengerApi.Db.Sql; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace MessengerApi.Db.Sql.Migrations +{ + [DbContext(typeof(MessengerSqlDbContext))] + [Migration("20250705145452_RenameTtlColumnName")] + partial class RenameTtlColumnName + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.6") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("MessengerApi.Db.Entities.Message", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedUtc") + .HasColumnType("datetime2"); + + b.Property("FromId") + .HasColumnType("uniqueidentifier"); + + b.Property("IsAcknowledged") + .HasColumnType("bit"); + + b.Property("IsDelivered") + .HasColumnType("bit"); + + b.Property("Payload") + .HasColumnType("nvarchar(max)"); + + b.Property("PayloadType") + .HasColumnType("nvarchar(max)"); + + b.Property("TimeToLiveInSeconds") + .HasColumnType("int"); + + b.Property("ToId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ToId", "IsDelivered"); + + SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("ToId", "IsDelivered"), false); + + b.ToTable("Messages"); + }); + + modelBuilder.Entity("MessengerApi.Db.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ApiKey") + .HasColumnType("uniqueidentifier"); + + b.Property("IsEnabled") + .HasColumnType("bit"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("MessengerApi.Db.Entities.UserRoute", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("FromId") + .HasColumnType("uniqueidentifier"); + + b.Property("ToId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("FromId"); + + b.HasIndex("ToId"); + + b.ToTable("UserRoutes"); + }); + + modelBuilder.Entity("MessengerApi.Db.Entities.UserRoute", b => + { + b.HasOne("MessengerApi.Db.Entities.User", "From") + .WithMany() + .HasForeignKey("FromId"); + + b.HasOne("MessengerApi.Db.Entities.User", "To") + .WithMany() + .HasForeignKey("ToId"); + + b.Navigation("From"); + + b.Navigation("To"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/code/MessengerApi.Db.Sql/Migrations/20250705145452_RenameTtlColumnName.cs b/code/MessengerApi.Db.Sql/Migrations/20250705145452_RenameTtlColumnName.cs new file mode 100644 index 0000000..d9dc6f8 --- /dev/null +++ b/code/MessengerApi.Db.Sql/Migrations/20250705145452_RenameTtlColumnName.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace MessengerApi.Db.Sql.Migrations +{ + /// + public partial class RenameTtlColumnName : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.RenameColumn( + name: "LifespanInSeconds", + table: "Messages", + newName: "TimeToLiveInSeconds"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.RenameColumn( + name: "TimeToLiveInSeconds", + table: "Messages", + newName: "LifespanInSeconds"); + } + } +} diff --git a/code/MessengerApi.Db.Sql/Migrations/MessengerSqlDbContextModelSnapshot.cs b/code/MessengerApi.Db.Sql/Migrations/MessengerSqlDbContextModelSnapshot.cs index 6faf21c..139a7bb 100644 --- a/code/MessengerApi.Db.Sql/Migrations/MessengerSqlDbContextModelSnapshot.cs +++ b/code/MessengerApi.Db.Sql/Migrations/MessengerSqlDbContextModelSnapshot.cs @@ -43,12 +43,12 @@ namespace MessengerApi.Db.Sql.Migrations b.Property("Payload") .HasColumnType("nvarchar(max)"); - b.Property("PayloadLifespanInSeconds") - .HasColumnType("int"); - b.Property("PayloadType") .HasColumnType("nvarchar(max)"); + b.Property("TimeToLiveInSeconds") + .HasColumnType("int"); + b.Property("ToId") .HasColumnType("uniqueidentifier"); diff --git a/code/MessengerApi.Db/MessengerDbContext.cs b/code/MessengerApi.Db/MessengerDbContext.cs index 9c598b1..c3eb1f5 100644 --- a/code/MessengerApi.Db/MessengerDbContext.cs +++ b/code/MessengerApi.Db/MessengerDbContext.cs @@ -19,7 +19,7 @@ namespace MessengerApi.Db modelBuilder.Entity().HasKey(e => e.Id); modelBuilder.Entity().HasKey(e => e.Id); modelBuilder.Entity().Property(e => e.CreatedUtc).HasConversion(); - modelBuilder.Entity().Property(e => e.PayloadLifespanInSeconds).IsRequired(); + modelBuilder.Entity().Property(e => e.TimeToLiveInSeconds).IsRequired(); modelBuilder.Entity().HasKey(e => e.Id); } } diff --git a/code/MessengerApi.Db/Repositories/MessageRepository.cs b/code/MessengerApi.Db/Repositories/MessageRepository.cs index bd305a1..9cce229 100644 --- a/code/MessengerApi.Db/Repositories/MessageRepository.cs +++ b/code/MessengerApi.Db/Repositories/MessageRepository.cs @@ -16,7 +16,7 @@ namespace MessengerApi.Db.Repositories return this.db .Where(x => x.ToId == user.Id && x.IsDelivered == false) - .Where(x => x.PayloadLifespanInSeconds == null || x.CreatedUtc.AddSeconds(x.PayloadLifespanInSeconds.Value) >= timestamp) + .Where(x => x.TimeToLiveInSeconds == null || x.CreatedUtc.AddSeconds(x.TimeToLiveInSeconds.Value) >= timestamp) .OrderBy(x => x.CreatedUtc); } } diff --git a/code/MessengerApi/Handlers/Endpoint/SendEndpointHandler.cs b/code/MessengerApi/Handlers/Endpoint/SendEndpointHandler.cs index f6e786a..b852356 100644 --- a/code/MessengerApi/Handlers/Endpoint/SendEndpointHandler.cs +++ b/code/MessengerApi/Handlers/Endpoint/SendEndpointHandler.cs @@ -32,7 +32,7 @@ namespace MessengerApi.Handlers.Endpoint Guid? toUserId, string payload, string payloadType, - int? payloadLifespanInSeconds) + int? timeToLiveInSeconds) { // Authorize. var targetRecipientId = toUserId.HasValue @@ -50,7 +50,7 @@ namespace MessengerApi.Handlers.Endpoint ToId = targetRecipientId, Payload = payload, PayloadType = payloadType, - PayloadLifespanInSeconds = payloadLifespanInSeconds ?? (this.configuration.DefaultMessageLifetimeInMinutes * 60) + TimeToLiveInSeconds = timeToLiveInSeconds ?? (this.configuration.DefaultMessageTimeToLiveInSeconds) }; this.unitOfWork.Messages.Add(message); diff --git a/code/MessengerApi/Models/Http/SendRequest.cs b/code/MessengerApi/Models/Http/SendRequest.cs index 42896d1..35e3a9b 100644 --- a/code/MessengerApi/Models/Http/SendRequest.cs +++ b/code/MessengerApi/Models/Http/SendRequest.cs @@ -8,6 +8,6 @@ public string PayloadType { get; set; } - public int? PayloadLifetimeInSeconds { get; set; } + public int? TimeToLiveInSeconds { get; set; } } } \ No newline at end of file diff --git a/code/MessengerApi/Program.cs b/code/MessengerApi/Program.cs index 7cbaf15..585a45d 100644 --- a/code/MessengerApi/Program.cs +++ b/code/MessengerApi/Program.cs @@ -184,7 +184,7 @@ namespace MessengerApi.Api { try { - var response = await handler.SendMessage(request.ToUserId, request.Payload, request.PayloadType, request.PayloadLifetimeInSeconds); + var response = await handler.SendMessage(request.ToUserId, request.Payload, request.PayloadType, request.TimeToLiveInSeconds); await unitOfWork.SaveChanges(); return Results.Json(response.Id); } diff --git a/code/MessengerApi/Properties/launchSettings.json b/code/MessengerApi/Properties/launchSettings.json index 1f55cdd..96f79f2 100644 --- a/code/MessengerApi/Properties/launchSettings.json +++ b/code/MessengerApi/Properties/launchSettings.json @@ -10,7 +10,7 @@ "CORS_ORIGINS": "", "PROXIES": "", "QUERY_RATE_PER_MINUTE": "100", - "DEFAULT_MESSAGE_LIFETIME_IN_MINUTES": "60", + "DEFAULT_MESSAGE_TIME_TO_LIVE_IN_SECONDS": "60", "HOUSEKEEPING_ENABLED": "False", "LOGGING_VERBOSITY": "Trace" },