Compare commits
4 Commits
refactor/r
...
bugfix/raw
| Author | SHA1 | Date | |
|---|---|---|---|
| 761fd208e5 | |||
| d149cbea3a | |||
| bb2dd4d63b | |||
| 4bde1d090f |
@@ -10,9 +10,9 @@
|
|||||||
<Product>ReC.API</Product>
|
<Product>ReC.API</Product>
|
||||||
<PackageIcon>Assets\icon.ico</PackageIcon>
|
<PackageIcon>Assets\icon.ico</PackageIcon>
|
||||||
<PackageTags>digital data rest-caller rec api</PackageTags>
|
<PackageTags>digital data rest-caller rec api</PackageTags>
|
||||||
<Version>2.2.0-beta</Version>
|
<Version>2.2.1-beta</Version>
|
||||||
<AssemblyVersion>2.2.0.0</AssemblyVersion>
|
<AssemblyVersion>2.2.1.0</AssemblyVersion>
|
||||||
<FileVersion>2.2.0.0</FileVersion>
|
<FileVersion>2.2.1.0</FileVersion>
|
||||||
<InformationalVersion>2.2.0-beta</InformationalVersion>
|
<InformationalVersion>2.2.0-beta</InformationalVersion>
|
||||||
<Copyright>Copyright © 2025 Digital Data GmbH. All rights reserved.</Copyright>
|
<Copyright>Copyright © 2025 Digital Data GmbH. All rights reserved.</Copyright>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
|
|||||||
@@ -1,23 +1,54 @@
|
|||||||
using MediatR;
|
using MediatR;
|
||||||
using ReC.Application.Common.Dto;
|
|
||||||
using ReC.Application.Common.Interfaces;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using ReC.Application.Common.Dto;
|
||||||
|
using ReC.Application.Common.Exceptions;
|
||||||
|
using ReC.Application.Common.Interfaces;
|
||||||
|
|
||||||
namespace ReC.Application.Common.Behaviors.Action;
|
namespace ReC.Application.Common.Behaviors.Action;
|
||||||
|
|
||||||
public class BodyQueryBehavior<TRequest, TResponse>(IRecDbContext dbContext) : IPipelineBehavior<TRequest, TResponse>
|
public class BodyQueryBehavior<TRequest, TResponse>(IRecDbContext dbContext) : IPipelineBehavior<TRequest, TResponse>
|
||||||
where TRequest : RecActionViewDto
|
where TRequest : notnull
|
||||||
where TResponse : notnull
|
where TResponse : IEnumerable<RecActionViewDto>
|
||||||
{
|
{
|
||||||
public async Task<TResponse> Handle(TRequest action, RequestHandlerDelegate<TResponse> next, CancellationToken cancel)
|
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancel)
|
||||||
{
|
{
|
||||||
if (action.BodyQuery is null)
|
var actions = await next(cancel);
|
||||||
return await next(cancel);
|
|
||||||
|
|
||||||
var result = await dbContext.BodyQueryResults.FromSqlRaw(action.BodyQuery).SingleOrDefaultAsync(cancel);
|
foreach (var action in actions)
|
||||||
|
await SetBody(action, cancel);
|
||||||
|
|
||||||
action.Body = result?.RawBody;
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
return await next(cancel);
|
private async Task SetBody(RecActionViewDto action, CancellationToken cancel)
|
||||||
|
{
|
||||||
|
if (action.BodyQuery is not string bodyQuery)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await using var command = dbContext.Database.GetDbConnection().CreateCommand();
|
||||||
|
command.CommandText = bodyQuery;
|
||||||
|
|
||||||
|
await dbContext.Database.OpenConnectionAsync(cancel);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
object? scalar;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
scalar = await command.ExecuteScalarAsync(cancel);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new DataIntegrityException(
|
||||||
|
$"Body query execution failed. The stored SQL may be malformed. ActionId: {action.Id}, ProfileId: {action.ProfileId}, Error: {ex.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
action.Body = scalar as string
|
||||||
|
?? throw new DataIntegrityException(
|
||||||
|
$"Body query returned no result or a null value. ActionId: {action.Id}, ProfileId: {action.ProfileId}");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
await dbContext.Database.CloseConnectionAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,43 +1,61 @@
|
|||||||
using MediatR;
|
using MediatR;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using ReC.Application.Common.Dto;
|
using ReC.Application.Common.Dto;
|
||||||
|
using ReC.Application.Common.Exceptions;
|
||||||
using ReC.Application.Common.Interfaces;
|
using ReC.Application.Common.Interfaces;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace ReC.Application.Common.Behaviors.Action;
|
namespace ReC.Application.Common.Behaviors.Action;
|
||||||
|
|
||||||
public class HeaderQueryBehavior<TRequest, TResponse>(IRecDbContext dbContext, ILogger<HeaderQueryBehavior<TRequest, TResponse>>? logger = null) : IPipelineBehavior<TRequest, TResponse>
|
public class HeaderQueryBehavior<TRequest, TResponse>(IRecDbContext dbContext) : IPipelineBehavior<TRequest, TResponse>
|
||||||
where TRequest : RecActionViewDto
|
where TRequest : notnull
|
||||||
where TResponse : notnull
|
where TResponse : IEnumerable<RecActionViewDto>
|
||||||
{
|
{
|
||||||
public async Task<TResponse> Handle(TRequest action, RequestHandlerDelegate<TResponse> next, CancellationToken cancel)
|
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancel)
|
||||||
{
|
{
|
||||||
if (action.HeaderQuery is null)
|
var actions = await next(cancel);
|
||||||
return await next(cancel);
|
|
||||||
|
|
||||||
var result = await dbContext.HeaderQueryResults.FromSqlRaw(action.HeaderQuery).SingleOrDefaultAsync(cancel);
|
foreach (var action in actions)
|
||||||
|
await SetHeader(action, cancel);
|
||||||
|
|
||||||
if (result?.RawHeader is null)
|
return actions;
|
||||||
{
|
|
||||||
logger?.LogWarning("Header query did not return a result or returned a null REQUEST_HEADER. Profile ID: {ProfileId}, Action ID: {Id}", action.ProfileId, action.Id);
|
|
||||||
|
|
||||||
return await next(cancel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var headerDict = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(result.RawHeader);
|
private async Task SetHeader(RecActionViewDto action, CancellationToken cancel)
|
||||||
|
|
||||||
if(headerDict is null)
|
|
||||||
{
|
{
|
||||||
logger?.LogWarning(
|
if (action.HeaderQuery is not string headerQuery)
|
||||||
"Header JSON deserialization returned null. RawHeader: {RawHeader}, ProfileId: {ProfileId}, Id: {Id}",
|
return;
|
||||||
result.RawHeader, action.ProfileId, action.Id);
|
|
||||||
|
|
||||||
return await next(cancel);
|
await using var command = dbContext.Database.GetDbConnection().CreateCommand();
|
||||||
|
command.CommandText = headerQuery;
|
||||||
|
|
||||||
|
await dbContext.Database.OpenConnectionAsync(cancel);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
object? scalar;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
scalar = await command.ExecuteScalarAsync(cancel);
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new DataIntegrityException(
|
||||||
|
$"Header query execution failed. The stored SQL may be malformed. ActionId: {action.Id}, ProfileId: {action.ProfileId}, Error: {ex.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scalar is not string rawHeader)
|
||||||
|
throw new DataIntegrityException(
|
||||||
|
$"Header query returned no result or a null value. ActionId: {action.Id}, ProfileId: {action.ProfileId}");
|
||||||
|
|
||||||
|
var headerDict = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(rawHeader)
|
||||||
|
?? throw new DataIntegrityException(
|
||||||
|
$"Header query returned invalid JSON. ActionId: {action.Id}, ProfileId: {action.ProfileId}");
|
||||||
|
|
||||||
action.Headers = headerDict.ToDictionary(header => header.Key, kvp => kvp.Value.ToString());
|
action.Headers = headerDict.ToDictionary(header => header.Key, kvp => kvp.Value.ToString());
|
||||||
|
}
|
||||||
return await next(cancel);
|
finally
|
||||||
|
{
|
||||||
|
await dbContext.Database.CloseConnectionAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user