Skip to content

Commit

Permalink
V3.3.0 (#74)
Browse files Browse the repository at this point in the history
* Add tracing to `InvokerBaseT`.
Add new `InvokeArgs`.

* InvokerBaseT2 updates.
Roll out more invokers (tracing)

* Add InvokeArgs to InvokerBaseT

* InvokerBaseT2 InvokeArgs implementation

* Add invoker to other long-running to get tracking.

* Finalizing tweaks.

* DbEx latest.

* Adjust the version.

* AppInsights usage configurable.
  • Loading branch information
chullybun authored Aug 8, 2023
1 parent 9b42694 commit 5d7e1ae
Show file tree
Hide file tree
Showing 55 changed files with 1,271 additions and 672 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

Represents the **NuGet** versions.

## v3.3.0
- *Enhancement:* [Distributed tracing](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/distributed-tracing-instrumentation-walkthroughs#best-practices) has been added via the `InvokerBase` set of classes throughout `CoreEx` to ensure coverage and consistency of implementation. A new `InvokeArgs` has been added to house the [`ActivitySource`](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.activitysource) instance; this also provides for further extension opportunities limiting future potential breaking changes.

## v3.2.0
- *Enhancement:* Added `ServiceBusReceiverActions` as a means to encapsulate the `ServiceBusReceivedMessage` and `ServiceBusReceiver` as a `ServiceBusMessageActions` equivalent to enable both the `ServiceBusSubscriber` and `ServiceBusOrchestratedSubscriber` to be leveraged outside of native Azure Functions.
- *Enhancement:* Added support for [claim-check pattern](https://learn.microsoft.com/en-us/azure/architecture/patterns/claim-check) for large messages. `EventData.Value` serialization to be stored as an attachment in the likes of blob storage and then referenced (claim-check) from the actual message. A new `IAttachmentStorage` encapsulates the attachment behavior with the `IEventSerializer` implementations referencing as applicable; whereby separating this behavior from the `IEventSender` enabling greater consistency and reuse. Added `BlobAttachmentStorage` and `BlobSasAttachmentStorage` to support Azure blob storage.
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>3.2.0</Version>
<Version>3.3.0</Version>
<LangVersion>preview</LangVersion>
<Authors>Avanade</Authors>
<Company>Avanade</Company>
Expand Down
1 change: 1 addition & 0 deletions samples/My.Hr/My.Hr.Api/My.Hr.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

<ItemGroup>
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
<PackageReference Include="Azure.Monitor.OpenTelemetry.AspNetCore" Version="1.0.0-beta.5" />
</ItemGroup>

<ItemGroup>
Expand Down
10 changes: 10 additions & 0 deletions samples/My.Hr/My.Hr.Api/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
using CoreEx.DataBase.HealthChecks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Azure.Monitor.OpenTelemetry.AspNetCore;
using OpenTelemetry.Instrumentation.AspNetCore;
using OpenTelemetry.Trace;

namespace My.Hr.Api;

Expand Down Expand Up @@ -56,6 +59,13 @@ public void ConfigureServices(IServiceCollection services)

services.AddControllers();

if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("APPLICATIONINSIGHTS_CONNECTION_STRING")))
{
services.AddOpenTelemetry().UseAzureMonitor();
services.Configure<AspNetCoreInstrumentationOptions>(options => options.RecordException = true);
services.ConfigureOpenTelemetryTracerProvider((sp, builder) => builder.AddSource("CoreEx.*"));
}

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
services.AddEndpointsApiExplorer();
services.AddSwaggerGen(options =>
Expand Down
2 changes: 1 addition & 1 deletion samples/My.Hr/My.Hr.Database/My.Hr.Database.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="DbEx.SqlServer" Version="2.3.4" />
<PackageReference Include="DbEx.SqlServer" Version="2.3.6" />
<PackageReference Include="Microsoft.Tye.Extensions.Configuration" Version="0.10.0-alpha.21420.1" />
</ItemGroup>

Expand Down
24 changes: 12 additions & 12 deletions src/CoreEx.AspNetCore/WebApis/WebApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public Task<IActionResult> RunAsync(HttpRequest request, Func<WebApiParam, Task<
/// <returns>The resulting <see cref="IActionResult"/>.</returns>
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
/// <remarks>This is, and must be, used by all methods that process an <see cref="HttpRequest"/> to ensure that the standardized before and after, success and error, handling occurs as required.</remarks>
public new Task<IActionResult> RunAsync(HttpRequest request, Func<WebApiParam, CancellationToken, Task<IActionResult>> function, OperationType operationType = OperationType.Unspecified, CancellationToken cancellationToken = default)
public Task<IActionResult> RunAsync(HttpRequest request, Func<WebApiParam, CancellationToken, Task<IActionResult>> function, OperationType operationType = OperationType.Unspecified, CancellationToken cancellationToken = default)
=> base.RunAsync(request, function, operationType, cancellationToken);

/// <summary>
Expand Down Expand Up @@ -109,7 +109,7 @@ public async Task<IActionResult> RunAsync<TValue>(HttpRequest request, Func<WebA
return await CreateActionResultFromExceptionAsync(this, request.HttpContext, vr.ValidationException!, Settings, Logger, OnUnhandledExceptionAsync, cancellationToken).ConfigureAwait(false);

return await function(new WebApiParam<TValue>(wap, vr.Value), ct).ConfigureAwait(false);
}, operationType, cancellationToken).ConfigureAwait(false);
}, operationType, cancellationToken, nameof(RunAsync)).ConfigureAwait(false);
}

#region GetAsync
Expand Down Expand Up @@ -155,7 +155,7 @@ public async Task<IActionResult> GetAsync<TResult>(HttpRequest request, Func<Web
{
var result = await function(wap, ct).ConfigureAwait(false);
return ValueContentResult.CreateResult(result, statusCode, alternateStatusCode, JsonSerializer, wap.RequestOptions, checkForNotModified: true, location: null);
}, operationType, cancellationToken).ConfigureAwait(false);
}, operationType, cancellationToken, nameof(GetAsync)).ConfigureAwait(false);
}

#endregion
Expand Down Expand Up @@ -199,7 +199,7 @@ public async Task<IActionResult> PostAsync(HttpRequest request, Func<WebApiParam
{
await function(wap, ct).ConfigureAwait(false);
return new ExtendedStatusCodeResult(statusCode) { Location = locationUri?.Invoke() };
}, operationType, cancellationToken).ConfigureAwait(false);
}, operationType, cancellationToken, nameof(PostAsync)).ConfigureAwait(false);
}

/// <summary>
Expand Down Expand Up @@ -293,7 +293,7 @@ private async Task<IActionResult> PostInternalAsync<TValue>(HttpRequest request,

await function(wapv!, ct).ConfigureAwait(false);
return new ExtendedStatusCodeResult(statusCode) { Location = locationUri?.Invoke() };
}, operationType, cancellationToken).ConfigureAwait(false);
}, operationType, cancellationToken, nameof(PostAsync)).ConfigureAwait(false);
}

/// <summary>
Expand Down Expand Up @@ -339,7 +339,7 @@ public async Task<IActionResult> PostAsync<TResult>(HttpRequest request, Func<We
{
var result = await function(wap, ct).ConfigureAwait(false);
return ValueContentResult.CreateResult(result, statusCode, alternateStatusCode, JsonSerializer, wap.RequestOptions, checkForNotModified: false, location: locationUri?.Invoke(result));
}, operationType, cancellationToken).ConfigureAwait(false);
}, operationType, cancellationToken, nameof(PostAsync)).ConfigureAwait(false);
}

/// <summary>
Expand Down Expand Up @@ -441,7 +441,7 @@ private async Task<IActionResult> PostInternalAsync<TValue, TResult>(HttpRequest

var result = await function(wapv!, ct).ConfigureAwait(false);
return ValueContentResult.CreateResult(result, statusCode, alternateStatusCode, JsonSerializer, wap.RequestOptions, checkForNotModified: false, location: locationUri?.Invoke(result));
}, operationType, cancellationToken).ConfigureAwait(false);
}, operationType, cancellationToken, nameof(PostAsync)).ConfigureAwait(false);
}

#endregion
Expand Down Expand Up @@ -535,7 +535,7 @@ private async Task<IActionResult> PutInternalAsync<TValue>(HttpRequest request,

await function(wapv!, ct).ConfigureAwait(false);
return new ExtendedStatusCodeResult(statusCode);
}, operationType, cancellationToken).ConfigureAwait(false);
}, operationType, cancellationToken, nameof(PutAsync)).ConfigureAwait(false);
}

/// <summary>
Expand Down Expand Up @@ -633,7 +633,7 @@ public async Task<IActionResult> PutInternalAsync<TValue, TResult>(HttpRequest r

var result = await function(wapv!, ct).ConfigureAwait(false);
return ValueContentResult.CreateResult(result, statusCode, alternateStatusCode, JsonSerializer, wap.RequestOptions, checkForNotModified: false, location: null);
}, operationType, cancellationToken).ConfigureAwait(false);
}, operationType, cancellationToken, nameof(PutAsync)).ConfigureAwait(false);
}

/// <summary>
Expand Down Expand Up @@ -737,7 +737,7 @@ private async Task<IActionResult> PutInternalAsync<TValue>(HttpRequest request,
// Update the value.
var result = await put(wapv!, ct).ConfigureAwait(false);
return ValueContentResult.CreateResult(result, statusCode, null, JsonSerializer, wap.RequestOptions, checkForNotModified: false, location: null);
}, operationType, cancellationToken).ConfigureAwait(false);
}, operationType, cancellationToken, nameof(PutAsync)).ConfigureAwait(false);
}

/// <summary>
Expand Down Expand Up @@ -809,7 +809,7 @@ public async Task<IActionResult> DeleteAsync(HttpRequest request, Func<WebApiPar
catch (NotFoundException) when (ConvertNotfoundToDefaultStatusCodeOnDelete) { /* Return default status code. */ }

return new ExtendedStatusCodeResult(statusCode);
}, operationType, cancellationToken).ConfigureAwait(false);
}, operationType, cancellationToken, nameof(DeleteAsync)).ConfigureAwait(false);
}

#endregion
Expand Down Expand Up @@ -908,7 +908,7 @@ public async Task<IActionResult> PatchAsync<TValue>(HttpRequest request, Func<We
}

return ValueContentResult.CreateResult(Value, statusCode, null, JsonSerializer, wap.RequestOptions, checkForNotModified: false, location: null);
}, operationType, cancellationToken).ConfigureAwait(false);
}, operationType, cancellationToken, nameof(PatchAsync)).ConfigureAwait(false);
}

#endregion
Expand Down
8 changes: 5 additions & 3 deletions src/CoreEx.AspNetCore/WebApis/WebApiBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@
using System.Collections.Generic;
using System.Net;
using System.Net.Mime;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;

namespace CoreEx.AspNetCore.WebApis
{
/// <summary>
/// Provides the base Web API execution encapsulation to <see cref="RunAsync(HttpRequest, Func{WebApiParam, CancellationToken, Task{IActionResult}}, OperationType, CancellationToken)"/> the underlying logic in a consistent manner.
/// Provides the base Web API execution encapsulation to <see cref="RunAsync"/> the underlying logic in a consistent manner.
/// </summary>
public abstract class WebApiBase
{
Expand Down Expand Up @@ -93,8 +94,9 @@ public virtual IEnumerable<string> GetCorrelationIdNames()
/// <param name="operationType">The <see cref="OperationType"/>.</param>
/// <returns>The resulting <see cref="IActionResult"/>.</returns>
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
/// <param name="memberName">The calling member name (uses <see cref="CallerMemberNameAttribute"/> to default).</param>
/// <remarks>This is, and must be, used by all methods that process an <see cref="HttpRequest"/> to ensure that the standardized before and after, success and error, handling occurs as required.</remarks>
protected async Task<IActionResult> RunAsync(HttpRequest request, Func<WebApiParam, CancellationToken, Task<IActionResult>> function, OperationType operationType = OperationType.Unspecified, CancellationToken cancellationToken = default)
protected async Task<IActionResult> RunAsync(HttpRequest request, Func<WebApiParam, CancellationToken, Task<IActionResult>> function, OperationType operationType = OperationType.Unspecified, CancellationToken cancellationToken = default, [CallerMemberName] string? memberName = null)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
Expand All @@ -105,7 +107,7 @@ protected async Task<IActionResult> RunAsync(HttpRequest request, Func<WebApiPar
// Invoke the "actual" function via the pluggable invoker.
ExecutionContext.OperationType = operationType;
var wap = new WebApiParam(this, new WebApiRequestOptions(request), operationType);
return await Invoker.InvokeAsync(this, wap, (w, ct) => function(w, ct), wap, cancellationToken).ConfigureAwait(false);
return await Invoker.InvokeAsync(this, wap, (_, w, ct) => function(w, ct), wap, cancellationToken, memberName).ConfigureAwait(false);
}

/// <summary>
Expand Down
8 changes: 4 additions & 4 deletions src/CoreEx.AspNetCore/WebApis/WebApiInvoker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
namespace CoreEx.AspNetCore.WebApis
{
/// <summary>
/// Provides pluggable invocation orchestration, logging and exception handling for <see cref="WebApiBase.RunAsync(Microsoft.AspNetCore.Http.HttpRequest, Func{WebApiParam, CancellationToken, Task{Microsoft.AspNetCore.Mvc.IActionResult}}, OperationType, CancellationToken)"/>.
/// Provides pluggable invocation orchestration, logging and exception handling for <see cref="WebApiBase.RunAsync"/>.
/// </summary>
public class WebApiInvoker : InvokerBase<WebApiBase, WebApiParam>
{
Expand All @@ -30,10 +30,10 @@ public class WebApiInvoker : InvokerBase<WebApiBase, WebApiParam>
public bool CatchAndHandleExceptions { get; set; } = true;

/// <inheritdoc/>
protected override TResult OnInvoke<TResult>(WebApiBase invoker, Func<TResult> func, WebApiParam? args) => throw new NotSupportedException();
protected override TResult OnInvoke<TResult>(InvokeArgs invokeArgs, WebApiBase invoker, Func<InvokeArgs, TResult> func, WebApiParam? args) => throw new NotSupportedException();

/// <inheritdoc/>
protected async override Task<TResult> OnInvokeAsync<TResult>(WebApiBase owner, Func<CancellationToken, Task<TResult>> func, WebApiParam? param, CancellationToken cancellationToken)
protected async override Task<TResult> OnInvokeAsync<TResult>(InvokeArgs invokeArgs, WebApiBase owner, Func<InvokeArgs, CancellationToken, Task<TResult>> func, WebApiParam? param, CancellationToken cancellationToken)
{
if (param == null)
throw new ArgumentNullException(nameof(param));
Expand All @@ -58,7 +58,7 @@ protected async override Task<TResult> OnInvokeAsync<TResult>(WebApiBase owner,

try
{
var ar = await func(cancellationToken).ConfigureAwait(false);
var ar = await func(invokeArgs, cancellationToken).ConfigureAwait(false);
owner.Logger.LogDebug("WebApi stopped; completed.");
return ar;
}
Expand Down
8 changes: 4 additions & 4 deletions src/CoreEx.AspNetCore/WebApis/WebApiPublisher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ private async Task<IActionResult> PublishInternalAsync<TValue>(HttpRequest reque
await EventPublisher.SendAsync(cancellationToken).ConfigureAwait(false);

return new ExtendedStatusCodeResult(statusCode);
}, operationType, cancellationToken).ConfigureAwait(false);
}, operationType, cancellationToken, nameof(PublishAsync)).ConfigureAwait(false);
}

/// <summary>
Expand Down Expand Up @@ -200,7 +200,7 @@ private async Task<IActionResult> PublishInternalAsync<TColl, TItem>(HttpRequest
await EventPublisher.SendAsync(ct).ConfigureAwait(false);

return new ExtendedStatusCodeResult(statusCode);
}, operationType, cancellationToken).ConfigureAwait(false);
}, operationType, cancellationToken, nameof(PublishAsync)).ConfigureAwait(false);
}

#endregion
Expand Down Expand Up @@ -280,7 +280,7 @@ private async Task<IActionResult> PublishWithResultInternalAsync<TValue>(HttpReq
await EventPublisher.SendAsync(cancellationToken).ConfigureAwait(false);

return new ExtendedStatusCodeResult(statusCode);
}, operationType, cancellationToken).ConfigureAwait(false);
}, operationType, cancellationToken, nameof(PublishWithResultAsync)).ConfigureAwait(false);
}

/// <summary>
Expand Down Expand Up @@ -374,7 +374,7 @@ private async Task<IActionResult> PublishWithResultInternalAsync<TColl, TItem>(H
await EventPublisher.SendAsync(ct).ConfigureAwait(false);

return new ExtendedStatusCodeResult(statusCode);
}, operationType, cancellationToken).ConfigureAwait(false);
}, operationType, cancellationToken, nameof(PublishWithResultAsync)).ConfigureAwait(false);
}

#endregion
Expand Down
Loading

0 comments on commit 5d7e1ae

Please sign in to comment.