diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b68001..baa579d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.0.3] - 2026-06-20 + +### Changed +- Consolidated source into a single `MaksIT.HAMode` project and assembly; removed internal multi-project packaging shell and manual DLL bundling. +- Namespaces are unchanged (`MaksIT.HAMode.Abstractions`, `MaksIT.HAMode.PostgreSql`, etc.) so consumers can upgrade without code changes. + ## [1.0.2] - 2026-06-20 ### Changed diff --git a/README.md b/README.md index 1a3e19a..97310bc 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Reusable high-availability runtime coordination library for MaksIT services. ## Packages -- `MaksIT.HAMode` (single NuGet package) +- `MaksIT.HAMode` (single NuGet package, single assembly) - `MaksIT.HAMode.Extensions.ServiceCollectionExtensions` - `MaksIT.HAMode.Abstractions` namespace: - `IRuntimeInstanceId` diff --git a/assets/badges/coverage-branches.svg b/assets/badges/coverage-branches.svg index 27013c9..e7bba28 100644 --- a/assets/badges/coverage-branches.svg +++ b/assets/badges/coverage-branches.svg @@ -1,5 +1,5 @@ - - Branch Coverage: 37.3% + + Branch Coverage: 43.6% @@ -9,13 +9,13 @@ - + Branch Coverage - - 37.3% + + 43.6% diff --git a/assets/badges/coverage-lines.svg b/assets/badges/coverage-lines.svg index 32742a9..4da9aa7 100644 --- a/assets/badges/coverage-lines.svg +++ b/assets/badges/coverage-lines.svg @@ -1,5 +1,5 @@ - - Line Coverage: 41.1% + + Line Coverage: 55.7% @@ -15,7 +15,7 @@ Line Coverage - - 41.1% + + 55.7% diff --git a/assets/badges/coverage-methods.svg b/assets/badges/coverage-methods.svg index 5ff67e9..9c11943 100644 --- a/assets/badges/coverage-methods.svg +++ b/assets/badges/coverage-methods.svg @@ -1,5 +1,5 @@ - - Method Coverage: 60.9% + + Method Coverage: 76.1% @@ -15,7 +15,7 @@ Method Coverage - - 60.9% + + 76.1% diff --git a/src/MaksIT.HAMode.Abstractions/MaksIT.HAMode.Abstractions.csproj b/src/MaksIT.HAMode.Abstractions/MaksIT.HAMode.Abstractions.csproj deleted file mode 100644 index fda7c6b..0000000 --- a/src/MaksIT.HAMode.Abstractions/MaksIT.HAMode.Abstractions.csproj +++ /dev/null @@ -1,46 +0,0 @@ - - - - net10.0 - enable - enable - false - $(MSBuildProjectName.Replace(" ", "_")) - true - $(NoWarn);CS1591 - - MaksIT.HAMode.Abstractions - 0.1.0 - Maksym Sadovnychyy - MAKS-IT - MaksIT.HAMode - Copyright © Maksym Sadovnychyy (MAKS-IT) - Shared high-availability abstractions for MaksIT services, including runtime instance identity and lease coordination contracts. - dotnet;ha;high-availability;runtime;lease;coordination;postgresql;kubernetes - https://github.com/MAKS-IT-COM/maksit-hamode - https://github.com/MAKS-IT-COM/maksit-hamode - git - README.md - LICENSE.md - See CHANGELOG.md in the package and repository releases. - false - true - true - true - snupkg - true - true - - - - - - - - - - - - - - diff --git a/src/MaksIT.HAMode.Etcd/MaksIT.HAMode.Etcd.csproj b/src/MaksIT.HAMode.Etcd/MaksIT.HAMode.Etcd.csproj deleted file mode 100644 index a27cc0a..0000000 --- a/src/MaksIT.HAMode.Etcd/MaksIT.HAMode.Etcd.csproj +++ /dev/null @@ -1,52 +0,0 @@ - - - - net10.0 - enable - enable - false - $(MSBuildProjectName.Replace(" ", "_")) - true - $(NoWarn);CS1591 - - MaksIT.HAMode.Etcd - 0.1.0 - Maksym Sadovnychyy - MAKS-IT - MaksIT.HAMode - Copyright © Maksym Sadovnychyy (MAKS-IT) - etcd runtime lease implementation for MaksIT HA mode, using transactions and lease-backed keys. - dotnet;ha;high-availability;runtime;lease;coordination;etcd;grpc;kubernetes - https://github.com/MAKS-IT-COM/maksit-hamode - https://github.com/MAKS-IT-COM/maksit-hamode - git - README.md - LICENSE.md - See CHANGELOG.md in the package and repository releases. - false - true - true - true - snupkg - true - true - - - - - - - - - - - - - - - - - - - - diff --git a/src/MaksIT.HAMode.PostgreSql/MaksIT.HAMode.PostgreSql.csproj b/src/MaksIT.HAMode.PostgreSql/MaksIT.HAMode.PostgreSql.csproj deleted file mode 100644 index dcba7a2..0000000 --- a/src/MaksIT.HAMode.PostgreSql/MaksIT.HAMode.PostgreSql.csproj +++ /dev/null @@ -1,51 +0,0 @@ - - - - net10.0 - enable - enable - false - $(MSBuildProjectName.Replace(" ", "_")) - true - $(NoWarn);CS1591 - - MaksIT.HAMode.PostgreSql - 0.1.0 - Maksym Sadovnychyy - MAKS-IT - MaksIT.HAMode - Copyright © Maksym Sadovnychyy (MAKS-IT) - PostgreSQL runtime lease implementation for MaksIT HA mode, based on app_runtime_leases coordination table. - dotnet;ha;high-availability;runtime;lease;coordination;postgresql;npgsql;kubernetes - https://github.com/MAKS-IT-COM/maksit-hamode - https://github.com/MAKS-IT-COM/maksit-hamode - git - README.md - LICENSE.md - See CHANGELOG.md in the package and repository releases. - false - true - true - true - snupkg - true - true - - - - - - - - - - - - - - - - - - - diff --git a/src/MaksIT.HAMode.Redis/MaksIT.HAMode.Redis.csproj b/src/MaksIT.HAMode.Redis/MaksIT.HAMode.Redis.csproj deleted file mode 100644 index 05f2923..0000000 --- a/src/MaksIT.HAMode.Redis/MaksIT.HAMode.Redis.csproj +++ /dev/null @@ -1,51 +0,0 @@ - - - - net10.0 - enable - enable - false - $(MSBuildProjectName.Replace(" ", "_")) - true - $(NoWarn);CS1591 - - MaksIT.HAMode.Redis - 0.1.0 - Maksym Sadovnychyy - MAKS-IT - MaksIT.HAMode - Copyright © Maksym Sadovnychyy (MAKS-IT) - Redis runtime lease implementation for MaksIT HA mode, using atomic Lua scripts and TTL-bound keys. - dotnet;ha;high-availability;runtime;lease;coordination;redis;stackexchange-redis;kubernetes - https://github.com/MAKS-IT-COM/maksit-hamode - https://github.com/MAKS-IT-COM/maksit-hamode - git - README.md - LICENSE.md - See CHANGELOG.md in the package and repository releases. - false - true - true - true - snupkg - true - true - - - - - - - - - - - - - - - - - - - diff --git a/src/MaksIT.HAMode.Tests/MaksIT.HAMode.Tests.csproj b/src/MaksIT.HAMode.Tests/MaksIT.HAMode.Tests.csproj index 6516ca4..f70fbf7 100644 --- a/src/MaksIT.HAMode.Tests/MaksIT.HAMode.Tests.csproj +++ b/src/MaksIT.HAMode.Tests/MaksIT.HAMode.Tests.csproj @@ -13,8 +13,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all @@ -24,10 +24,6 @@ - - - - diff --git a/src/MaksIT.HAMode.Tests/RuntimeLeaseServiceValidationTests.cs b/src/MaksIT.HAMode.Tests/RuntimeLeaseServiceValidationTests.cs index 9434d1a..7d7d425 100644 --- a/src/MaksIT.HAMode.Tests/RuntimeLeaseServiceValidationTests.cs +++ b/src/MaksIT.HAMode.Tests/RuntimeLeaseServiceValidationTests.cs @@ -1,8 +1,10 @@ using MaksIT.HAMode.Etcd; using MaksIT.HAMode.PostgreSql; using MaksIT.HAMode.Redis; +using dotnet_etcd; using Microsoft.Extensions.Logging.Abstractions; using Npgsql; +using StackExchange.Redis; using System.Net; namespace MaksIT.HAMode.Tests; @@ -153,6 +155,33 @@ public sealed class RuntimeLeaseServiceValidationTests { Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode); } + [Fact] + public async Task Redis_TryAcquire_WithSharedMultiplexer_AllowsEmptyConfiguration() { + var multiplexer = ConnectionMultiplexer.Connect("127.0.0.1:63999,abortConnect=false,connectTimeout=1"); + var service = new RuntimeLeaseServiceRedis( + new TestRedisProvider { Configuration = "" }, + NullLogger.Instance, + multiplexer); + + var result = await service.TryAcquireAsync("lease", "holder", PositiveTtl, TestContext.Current.CancellationToken); + + Assert.NotEqual(HttpStatusCode.BadRequest, result.StatusCode); + await service.DisposeAsync(); + } + + [Fact] + public async Task Etcd_TryAcquire_WithSharedClient_AllowsEmptyEndpoints() { + var client = new EtcdClient("http://127.0.0.1:2379"); + var service = new RuntimeLeaseServiceEtcd( + new TestEtcdProvider { Endpoints = "" }, + NullLogger.Instance, + client); + + var result = await service.TryAcquireAsync("lease", "holder", PositiveTtl, TestContext.Current.CancellationToken); + + Assert.NotEqual(HttpStatusCode.BadRequest, result.StatusCode); + } + [Fact] public async Task Etcd_TryAcquire_MissingKeyPrefix_ReturnsBadRequest() { var service = new RuntimeLeaseServiceEtcd( diff --git a/src/MaksIT.HAMode.Tests/ServiceCollectionExtensionsTests.cs b/src/MaksIT.HAMode.Tests/ServiceCollectionExtensionsTests.cs index 156d897..47321f8 100644 --- a/src/MaksIT.HAMode.Tests/ServiceCollectionExtensionsTests.cs +++ b/src/MaksIT.HAMode.Tests/ServiceCollectionExtensionsTests.cs @@ -20,6 +20,94 @@ public sealed class ServiceCollectionExtensionsTests { var instanceId = provider.GetRequiredService(); Assert.IsType(instanceId); + Assert.Same(typeof(RuntimeInstanceIdProvider).Assembly, instanceId.GetType().Assembly); + } + + [Fact] + public void AddHAModePostgreSqlLease_WithGenericProvider_RegistersLeaseServiceOnly() { + var services = new ServiceCollection() + .AddLogging() + .AddHAModePostgreSqlLease(); + + var provider = services.BuildServiceProvider(); + + Assert.IsType(provider.GetRequiredService()); + Assert.IsType(provider.GetRequiredService()); + Assert.Throws(() => provider.GetRequiredService()); + } + + [Fact] + public void AddHAModeRedisLease_WithGenericProvider_RegistersLeaseServiceOnly() { + var services = new ServiceCollection() + .AddLogging() + .AddHAModeRedisLease(); + + var provider = services.BuildServiceProvider(); + + Assert.IsType(provider.GetRequiredService()); + Assert.IsType(provider.GetRequiredService()); + Assert.Throws(() => provider.GetRequiredService()); + } + + [Fact] + public void AddHAModeEtcdLease_WithGenericProvider_RegistersLeaseServiceOnly() { + var services = new ServiceCollection() + .AddLogging() + .AddHAModeEtcdLease(); + + var provider = services.BuildServiceProvider(); + + Assert.IsType(provider.GetRequiredService()); + Assert.IsType(provider.GetRequiredService()); + Assert.Throws(() => provider.GetRequiredService()); + } + + [Fact] + public void AddHAModePostgreSqlLease_WithSharedDataSource_RegistersLeaseServiceOnly() { + var configuration = new TestPgProvider(); + var dataSource = NpgsqlDataSource.Create("Host=127.0.0.1;Port=5432;Database=hamode;Username=hamode;Password=hamode"); + var services = new ServiceCollection() + .AddLogging() + .AddHAModePostgreSqlLease(configuration, dataSource); + + var provider = services.BuildServiceProvider(); + + Assert.Same(configuration, provider.GetRequiredService()); + Assert.Same(dataSource, provider.GetRequiredService()); + Assert.IsType(provider.GetRequiredService()); + Assert.Throws(() => provider.GetRequiredService()); + } + + [Fact] + public void AddHAModeRedisLease_WithSharedMultiplexer_RegistersLeaseServiceOnly() { + var configuration = new TestRedisProvider(); + var multiplexer = ConnectionMultiplexer.Connect("127.0.0.1:63999,abortConnect=false,connectTimeout=1"); + var services = new ServiceCollection() + .AddLogging() + .AddHAModeRedisLease(configuration, multiplexer); + + var provider = services.BuildServiceProvider(); + + Assert.Same(configuration, provider.GetRequiredService()); + Assert.Same(multiplexer, provider.GetRequiredService()); + Assert.IsType(provider.GetRequiredService()); + Assert.Throws(() => provider.GetRequiredService()); + } + + [Fact] + public void AddHAModeEtcdLease_WithSharedClient_RegistersLeaseServiceOnly() { + var configuration = new TestEtcdProvider(); + var client = new EtcdClient("http://127.0.0.1:2379"); + var services = new ServiceCollection() + .AddLogging() + .AddHAModeEtcdLease(configuration, client); + + var provider = services.BuildServiceProvider(); + + Assert.Same(configuration, provider.GetRequiredService()); + Assert.Same(client, provider.GetRequiredService()); + Assert.IsType(provider.GetRequiredService()); + Assert.Throws(() => provider.GetRequiredService()); } [Fact] diff --git a/src/MaksIT.HAMode.slnx b/src/MaksIT.HAMode.slnx index c551d6e..5a4f28d 100644 --- a/src/MaksIT.HAMode.slnx +++ b/src/MaksIT.HAMode.slnx @@ -1,8 +1,4 @@ - - - - - + diff --git a/src/MaksIT.HAMode.Abstractions/IRuntimeInstanceId.cs b/src/MaksIT.HAMode/Abstractions/IRuntimeInstanceId.cs similarity index 100% rename from src/MaksIT.HAMode.Abstractions/IRuntimeInstanceId.cs rename to src/MaksIT.HAMode/Abstractions/IRuntimeInstanceId.cs diff --git a/src/MaksIT.HAMode.Abstractions/IRuntimeLeaseConnectionProvider.cs b/src/MaksIT.HAMode/Abstractions/IRuntimeLeaseConnectionProvider.cs similarity index 100% rename from src/MaksIT.HAMode.Abstractions/IRuntimeLeaseConnectionProvider.cs rename to src/MaksIT.HAMode/Abstractions/IRuntimeLeaseConnectionProvider.cs diff --git a/src/MaksIT.HAMode.Abstractions/IRuntimeLeaseConnectionStringProvider.cs b/src/MaksIT.HAMode/Abstractions/IRuntimeLeaseConnectionStringProvider.cs similarity index 100% rename from src/MaksIT.HAMode.Abstractions/IRuntimeLeaseConnectionStringProvider.cs rename to src/MaksIT.HAMode/Abstractions/IRuntimeLeaseConnectionStringProvider.cs diff --git a/src/MaksIT.HAMode.Abstractions/IRuntimeLeaseEtcdConnectionProvider.cs b/src/MaksIT.HAMode/Abstractions/IRuntimeLeaseEtcdConnectionProvider.cs similarity index 100% rename from src/MaksIT.HAMode.Abstractions/IRuntimeLeaseEtcdConnectionProvider.cs rename to src/MaksIT.HAMode/Abstractions/IRuntimeLeaseEtcdConnectionProvider.cs diff --git a/src/MaksIT.HAMode.Abstractions/IRuntimeLeaseRedisConnectionProvider.cs b/src/MaksIT.HAMode/Abstractions/IRuntimeLeaseRedisConnectionProvider.cs similarity index 100% rename from src/MaksIT.HAMode.Abstractions/IRuntimeLeaseRedisConnectionProvider.cs rename to src/MaksIT.HAMode/Abstractions/IRuntimeLeaseRedisConnectionProvider.cs diff --git a/src/MaksIT.HAMode.Abstractions/IRuntimeLeaseService.cs b/src/MaksIT.HAMode/Abstractions/IRuntimeLeaseService.cs similarity index 100% rename from src/MaksIT.HAMode.Abstractions/IRuntimeLeaseService.cs rename to src/MaksIT.HAMode/Abstractions/IRuntimeLeaseService.cs diff --git a/src/MaksIT.HAMode.Abstractions/RuntimeInstanceIdProvider.cs b/src/MaksIT.HAMode/Abstractions/RuntimeInstanceIdProvider.cs similarity index 100% rename from src/MaksIT.HAMode.Abstractions/RuntimeInstanceIdProvider.cs rename to src/MaksIT.HAMode/Abstractions/RuntimeInstanceIdProvider.cs diff --git a/src/MaksIT.HAMode.Etcd/RuntimeLeaseServiceEtcd.cs b/src/MaksIT.HAMode/Etcd/RuntimeLeaseServiceEtcd.cs similarity index 100% rename from src/MaksIT.HAMode.Etcd/RuntimeLeaseServiceEtcd.cs rename to src/MaksIT.HAMode/Etcd/RuntimeLeaseServiceEtcd.cs diff --git a/src/MaksIT.HAMode/MaksIT.HAMode.csproj b/src/MaksIT.HAMode/MaksIT.HAMode.csproj index 768e760..a7b5d3e 100644 --- a/src/MaksIT.HAMode/MaksIT.HAMode.csproj +++ b/src/MaksIT.HAMode/MaksIT.HAMode.csproj @@ -6,10 +6,9 @@ enable true $(NoWarn);CS1591 - true MaksIT.HAMode - 1.0.2 + 1.0.3 Maksym Sadovnychyy MAKS-IT MaksIT.HAMode @@ -31,17 +30,11 @@ true - - - - - - - + diff --git a/src/MaksIT.HAMode.PostgreSql/RuntimeLeaseServiceNpgsql.cs b/src/MaksIT.HAMode/PostgreSql/RuntimeLeaseServiceNpgsql.cs similarity index 100% rename from src/MaksIT.HAMode.PostgreSql/RuntimeLeaseServiceNpgsql.cs rename to src/MaksIT.HAMode/PostgreSql/RuntimeLeaseServiceNpgsql.cs diff --git a/src/MaksIT.HAMode.Redis/RuntimeLeaseServiceRedis.cs b/src/MaksIT.HAMode/Redis/RuntimeLeaseServiceRedis.cs similarity index 100% rename from src/MaksIT.HAMode.Redis/RuntimeLeaseServiceRedis.cs rename to src/MaksIT.HAMode/Redis/RuntimeLeaseServiceRedis.cs