Skip to content

Commit

Permalink
V2.8.0 (#62)
Browse files Browse the repository at this point in the history
* Subscribing improvements.
TypedHttpClient improvements.

* Update UnitTestEx to latest.

* CI .NET 7 support

* try moving the envvar in ci

* Set up database before test

* Fix error.

* Add connection var name

* remove docker build step
  • Loading branch information
chullybun authored Apr 20, 2023
1 parent 9634faa commit 74d4061
Show file tree
Hide file tree
Showing 31 changed files with 237 additions and 95 deletions.
18 changes: 11 additions & 7 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
# options: -m 4g --cpus=2.0

sql:
image: mcr.microsoft.com/mssql/server
image: mcr.microsoft.com/mssql/server:2019-latest
ports:
- 1433:1433
env:
Expand All @@ -36,16 +36,13 @@ jobs:
steps:
- uses: actions/checkout@v2

- name: Set EnvVar for Test
run: |
echo "ConnectionStrings__Database=Data Source=localhost,1433;Initial Catalog=My.Hr;User id=sa;Password=sAPWD23.^0;TrustServerCertificate=true" >> $GITHUB_ENV
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: |
3.1.x
6.0.x
7.0.x
- name: Restore dependencies
run: dotnet restore
Expand All @@ -56,12 +53,19 @@ jobs:
- name: Test
run: dotnet test --filter "(TestCategory!=WithDB)&(TestCategory!=WithCosmos)" --no-build --verbosity normal /p:CollectCoverage=true /p:Exclude="[CoreEx.TestFunction]*" /p:CoverletOutputFormat=lcov /p:CoverletOutput=./coverage/lcov.info

- name: Set EnvVar for Test
run: |
echo "ConnectionStrings__Database=Data Source=localhost,1433;Initial Catalog=My.Hr;User id=sa;Password=sAPWD23.^0;TrustServerCertificate=true" >> $GITHUB_ENV
- name: Create/Migrate DB
run: dotnet run all --project ./samples/My.Hr/My.Hr.Database --connection-varname ConnectionStrings__Database

- name: Test With DB
run: dotnet test --filter TestCategory=WithDB --no-build --verbosity normal /p:CollectCoverage=true /p:Exclude="[CoreEx.TestFunction]*" /p:CoverletOutputFormat=lcov /p:CoverletOutput=./coverage/lcov2.info

- name: Test With Cosmos DB TestCategory=WithCosmos
run: dotnet test --filter Category=WithCosmos --no-build --verbosity normal /p:CollectCoverage=true /p:Exclude="[CoreEx.TestFunction]*" /p:CoverletOutputFormat=lcov /p:CoverletOutput=./coverage/lcov3.info
if: ${{ false }}

- name: Test Docker Build
run: docker-compose -f docker-compose.myHr.yml -f docker-compose.myHr.override.yml build --build-arg LOCAL=true
#- name: Test Docker Build
# run: docker-compose -f docker-compose.myHr.yml -f docker-compose.myHr.override.yml build --build-arg LOCAL=true
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

Represents the **NuGet** versions.

## v2.8.0
- *Enhancement:* Added `CoreEx.EntityFrameworkCore` support for framework `net7.0`.
- *Enhancement:* Updated `ServiceBusSubscriberInvoker` to improve logging, including opportunities to inherit and add further before and after processing logging and/or monitoring.
- *Enhancement:* Updated `ServiceBusOrchestratedSubscriber` to perform a `LogInformation` on success.
- *Enhancement:* The `TypedHttpClientBase<TSelf>` will probe settings by `GetType().Name` to enable settings per implementation type as an overridding configurable option.
- *Fixed:* `HttpResult.CreateExtendedException` passes inner `HttpRequestException` for context.
- *Fixed:* `EventSubscriberOrchestrator.AmbiquousSubscriberHandling` is correctly set to `ErrorHandling.CriticalFailFast` by default.

## v2.7.0
- *Enhancement:* Simplified usage for `TypedHttpClientCore` and `TypedHttpClientBase` such that all parameters with the exception of `HttpClient` default where not specified.
- *Enhancement:* `IServiceCollection` extension methods for `CoreEx.Validation` and `CoreEx.FluentValidation` support option to include/exclude underlying interfaces where performing register using `AddValidator` and `AddValidators`.
Expand Down
2 changes: 1 addition & 1 deletion Common.targets
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>2.7.0</Version>
<Version>2.8.0</Version>
<LangVersion>preview</LangVersion>
<Authors>Avanade</Authors>
<Company>Avanade</Company>
Expand Down
2 changes: 2 additions & 0 deletions CoreEx.sln
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
CODE_OF_CONDUCT.md = CODE_OF_CONDUCT.md
Common.targets = Common.targets
CONTRIBUTING.md = CONTRIBUTING.md
docker-compose.myHr.override.yml = docker-compose.myHr.override.yml
docker-compose.myHr.yml = docker-compose.myHr.yml
LICENCE = LICENCE
nuget-publish.ps1 = nuget-publish.ps1
README.md = README.md
Expand Down
34 changes: 18 additions & 16 deletions samples/My.Hr/My.Hr.Database/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using DbEx.SqlServer.Console;
using System.Reflection;
using DbEx.Migration;
using DbEx.SqlServer.Console;

namespace My.Hr.Database
{
Expand All @@ -13,20 +13,22 @@ public class Program
/// </summary>
/// <param name="args">The startup arguments.</param>
/// <returns>The status code whereby zero indicates success.</returns>
internal static Task<int> Main(string[] args) => RunMigrator("Data Source=.;Initial Catalog=My.HrDb;Integrated Security=True;TrustServerCertificate=true", null, args);
internal static Task<int> Main(string[] args) => new SqlServerMigrationConsole("Data Source=.;Initial Catalog=My.HrDb;Integrated Security=True;TrustServerCertificate=true")
.Configure(c => ConfigureMigrationArgs(c.Args))
.RunAsync(args);

public static Task<int> RunMigrator(string connectionString, Assembly? assembly = null, params string[] args)
=> SqlServerMigrationConsole
.Create<Program>(connectionString)
.Configure(c =>
{
c.Args.AcceptPrompts = true;
c.Args.ConnectionStringEnvironmentVariableName = "My_HrDb";
c.Args.DataParserArgs.RefDataColumnDefaults.TryAdd("IsActive", _ => true);
c.Args.DataParserArgs.RefDataColumnDefaults.TryAdd("SortOrder", i => i);
if (assembly != null)
c.Args.AddAssembly(assembly);
})
.RunAsync(args);
/// <summary>
/// Configure the <see cref="MigrationArgs"/>.
/// </summary>
/// <param name="args">The <see cref="MigrationArgs"/>.</param>
/// <returns>The <see cref="MigrationArgs"/>.</returns>
public static MigrationArgs ConfigureMigrationArgs(MigrationArgs args)
{
args.ConnectionStringEnvironmentVariableName = "My_HrDb";
args.DataParserArgs.RefDataColumnDefaults.TryAdd("IsActive", _ => true);
args.DataParserArgs.RefDataColumnDefaults.TryAdd("SortOrder", i => i);
args.AddAssembly<Program>();
return args;
}
}
}
2 changes: 1 addition & 1 deletion samples/My.Hr/My.Hr.Infra.Tests/My.Hr.Infra.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="UnitTestEx.NUnit" Version="2.1.3" />
<PackageReference Include="UnitTestEx.NUnit" Version="2.2.1" />
</ItemGroup>

<ItemGroup>
Expand Down
10 changes: 7 additions & 3 deletions samples/My.Hr/My.Hr.Infra/Services/DbOperations.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System.Threading.Tasks;
using Dapper;
using DbEx;
using DbEx.Migration;
using DbEx.SqlServer.Migration;
using Microsoft.Data.SqlClient;
using Pulumi;

Expand Down Expand Up @@ -36,13 +39,14 @@ FROM [sys].[database_principals]
});
}

public Task<int> DeployDbSchemaAsync(string connectionString)
public Task<bool> DeployDbSchemaAsync(string connectionString)
{
if (Deployment.Instance.IsDryRun)
// skip in dry run
return Task.FromResult(0);
return Task.FromResult(true);

Log.Info($"Deploying DB schema using {connectionString}");
return Database.Program.RunMigrator(connectionString, assembly: typeof(My.Hr.Database.Program).Assembly, "DeployWithData");
var args = Database.Program.ConfigureMigrationArgs(new MigrationArgs(MigrationCommand.DeployWithData, connectionString));
return new SqlServerMigration(args).MigrateAsync();
}
}
2 changes: 1 addition & 1 deletion samples/My.Hr/My.Hr.Infra/Services/IDbOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ namespace My.Hr.Infra.Services;

public interface IDbOperations
{
Task<int> DeployDbSchemaAsync(string connectionString);
Task<bool> DeployDbSchemaAsync(string connectionString);
void ProvisionUsers(Input<string> connectionString, string groupName);
}
10 changes: 8 additions & 2 deletions samples/My.Hr/My.Hr.UnitTest/EmployeeControllerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
using UnitTestEx.Expectations;
using UnitTestEx.NUnit;
using DbEx;
using Microsoft.Extensions.DependencyInjection;
using My.Hr.Business;
using DbEx.Migration;
using DbEx.SqlServer.Migration;

namespace My.Hr.UnitTest
{
Expand All @@ -28,8 +32,10 @@ public static async Task Init()

using var test = ApiTester.Create<Startup>();
var cs = test.Configuration.GetConnectionString("Database");
if (await Database.Program.RunMigrator(cs, typeof(EmployeeControllerTest).Assembly, MigrationCommand.ResetAndAll.ToString()).ConfigureAwait(false) != 0)
Assert.Fail("Database migration failed.");
var args = Database.Program.ConfigureMigrationArgs(new MigrationArgs(MigrationCommand.ResetAndDatabase, cs)).AddAssembly<EmployeeControllerTest>();
var (Success, Output) = await new SqlServerMigration(args).MigrateAndLogAsync().ConfigureAwait(false);
if (!Success)
Assert.Fail(Output);
}

[Test]
Expand Down
13 changes: 9 additions & 4 deletions samples/My.Hr/My.Hr.UnitTest/EmployeeFunctionTest.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
using CoreEx.Entities;
using CoreEx.Http;
using DbEx;
using Microsoft.Extensions.Configuration;
using DbEx.Migration;
using DbEx.SqlServer.Migration;
using Microsoft.Extensions.DependencyInjection;
using My.Hr.Business;
using My.Hr.Business.Models;
using My.Hr.Functions;
using My.Hr.Functions.Functions;
Expand All @@ -25,9 +28,11 @@ public async Task Init()
HttpConsts.IncludeFieldsQueryStringName = "include-fields";

using var test = FunctionTester.Create<Startup>();
var cs = test.Configuration.GetConnectionString("Database");
if (await Database.Program.RunMigrator(cs, typeof(EmployeeControllerTest).Assembly, MigrationCommand.ResetAndAll.ToString()).ConfigureAwait(false) != 0)
Assert.Fail("Database migration failed.");
var settings = test.Services.GetRequiredService<HrSettings>();
var args = Database.Program.ConfigureMigrationArgs(new MigrationArgs(MigrationCommand.ResetAndDatabase, settings.ConnectionStrings__Database)).AddAssembly<EmployeeControllerTest>();
var (Success, Output) = await new SqlServerMigration(args).MigrateAndLogAsync().ConfigureAwait(false);
if (!Success)
Assert.Fail(Output);
}

[Test]
Expand Down
4 changes: 2 additions & 2 deletions samples/My.Hr/My.Hr.UnitTest/My.Hr.UnitTest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="UnitTestEx" Version="2.1.3" />
<PackageReference Include="UnitTestEx.NUnit" Version="2.1.3" />
<PackageReference Include="UnitTestEx" Version="2.2.1" />
<PackageReference Include="UnitTestEx.NUnit" Version="2.2.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class ServiceBusOrchestratedSubscriber : EventSubscriberBase
/// <param name="logger">The <see cref="ILogger"/>.</param>
/// <param name="eventSubscriberInvoker">The optional <see cref="EventSubscriberInvoker"/>.</param>
/// <param name="serviceBusSubscriberInvoker">The optional <see cref="ServiceBus.ServiceBusSubscriberInvoker"/>.</param>
/// <param name="eventDataConverter">The optional <see cref="IEventDataConverter{ServiceBusReceivedMessage}"/>.</param>
/// <param name="eventDataConverter">The optional <see cref="IEventDataConverter{TMessage}"/>.</param>
/// <param name="eventSerializer">The optional <see cref="IEventSerializer"/>.</param>
public ServiceBusOrchestratedSubscriber(EventSubscriberOrchestrator orchestrator, ExecutionContext executionContext, SettingsBase settings, ILogger<ServiceBusSubscriber> logger, EventSubscriberInvoker? eventSubscriberInvoker = null, ServiceBusSubscriberInvoker? serviceBusSubscriberInvoker = null, IEventDataConverter<ServiceBusReceivedMessage>? eventDataConverter = null, IEventSerializer? eventSerializer = null)
: base(eventDataConverter ?? new ServiceBusReceivedMessageEventDataConverter(eventSerializer ?? new CoreEx.Text.Json.EventDataSerializer()), executionContext, settings, logger, eventSubscriberInvoker)
Expand Down Expand Up @@ -94,7 +94,9 @@ public Task ReceiveAsync(ServiceBusReceivedMessage message, ServiceBusMessageAct
}

// Execute subscriber receive with the event.
await Orchestrator.ReceiveAsync(this, subscriber!, @event, cancellationToken).ConfigureAwait(false);
var success = await Orchestrator.ReceiveAsync(this, subscriber!, @event, cancellationToken).ConfigureAwait(false);
if (success)
Logger.LogInformation("{Type} executed {Subscriber} successfully - Service Bus message '{Message}'.", GetType().Name, subscriber!.GetType().Name, message.MessageId);
}, (message, messageActions), cancellationToken);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ public class ServiceBusReceivedMessageEventDataConverter : IEventDataConverter<S
/// <remarks>This method is not supported; throws a <see cref="NotSupportedException"/>.</remarks>
public Task<ServiceBusReceivedMessage> ConvertToAsync(EventData @event, CancellationToken cancellationToken) => throw new NotSupportedException($"The {nameof(ServiceBusReceivedMessage)} constructor is internal; therefore, can not be instantiated.");

/// <inheritdoc/>
public Task<EventData> ConvertFromMetadataOnlyAsync(ServiceBusReceivedMessage message, CancellationToken cancellationToken)
{
var @event = new EventData();
UpdateMetaDataWhereApplicable(message, @event);
return Task.FromResult(@event);
}

/// <inheritdoc/>
public async Task<EventData> ConvertFromAsync(ServiceBusReceivedMessage message, Type? valueType, CancellationToken cancellationToken)
{
Expand Down Expand Up @@ -65,8 +73,10 @@ public async Task<EventData<T>> ConvertFromAsync<T>(ServiceBusReceivedMessage me
}

/// <summary>
/// Update the metadata from the message where the Id is not null; otherwise, assume deserialized from the body and carry on.
/// Updates the metadata from the <paramref name="message"/> where the <paramref name="event"/> <see cref="EventDataBase.Id"/> is not <c>null</c>; otherwise, assume already updated.
/// </summary>
/// <param name="message">The <see cref="ServiceBusReceivedMessage"/></param>
/// <param name="event">The <see cref="EventData"/>.</param>
private static void UpdateMetaDataWhereApplicable(ServiceBusReceivedMessage message, EventData @event)
{
if (@event.Id is not null)
Expand Down
4 changes: 3 additions & 1 deletion src/CoreEx.Azure/ServiceBus/ServiceBusSubscriber.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace CoreEx.Azure.ServiceBus
/// message identifiers. Where the unhandled <see cref="Exception"/> is <see cref="IExtendedException.IsTransient"/> this will bubble out for the Azure Function runtime/fabric to retry and automatically deadletter; otherwise, it will be
/// immediately deadletted with a reason of <see cref="IExtendedException.ErrorType"/> or <see cref="ErrorType.UnhandledError"/> depending on the exception <see cref="Type"/>.
/// <para>The <see cref="UpdateEventDataWithServiceBusMessage(EventData, ServiceBusReceivedMessage, ServiceBusMessageActions)"/> is invoked after each <see cref="EventData"/> deserialization.</para></remarks>
public class ServiceBusSubscriber : Events.EventSubscriberBase
public class ServiceBusSubscriber : EventSubscriberBase
{
/// <summary>
/// Gets the <see cref="EventDataBase.Internal"/> name to access the <see cref="ServiceBusMessage"/>.
Expand Down Expand Up @@ -93,6 +93,7 @@ public Task ReceiveAsync(ServiceBusReceivedMessage message, ServiceBusMessageAct
// Invoke the actual function logic.
await function(@event!).ConfigureAwait(false);

Logger.LogInformation("{Type} executed successfully - Service Bus message '{Message}'.", GetType().Name, message.MessageId);
}, (message, messageActions), cancellationToken);
}

Expand Down Expand Up @@ -133,6 +134,7 @@ public Task ReceiveAsync<TValue>(ServiceBusReceivedMessage message, ServiceBusMe
// Invoke the actual function logic.
await function(@event!).ConfigureAwait(false);

Logger.LogInformation("{Type} executed successfully - Service Bus message '{Message}'.", GetType().Name, message.MessageId);
}, (message, messageActions), cancellationToken);
}

Expand Down
Loading

0 comments on commit 74d4061

Please sign in to comment.