Compare commits
17 Commits
f9a73fbe0c
...
3da16ba640
| Author | SHA1 | Date | |
|---|---|---|---|
| 3da16ba640 | |||
| 71a0220c3f | |||
| f53603083a | |||
| 92e7d44d3b | |||
| f8211e9e9d | |||
| 1782844543 | |||
| 2aa7cabcbd | |||
| 28f35101f9 | |||
| f8c5502905 | |||
| 961b87de3d | |||
| 6b036f4f91 | |||
| 46b7ae29cd | |||
| 84e403f411 | |||
| 3b77345aee | |||
| 6d04a4afd1 | |||
| 1f250d55b0 | |||
| c422de445d |
@@ -3,7 +3,8 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using ReC.API.Extensions;
|
||||
using ReC.API.Models;
|
||||
using ReC.Application.RecActions.Commands;
|
||||
using ReC.Application.RecActions.Queries;
|
||||
using ReC.Application.RecActionViews.Commands;
|
||||
using ReC.Application.RecActionViews.Queries;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace ReC.API.Controllers;
|
||||
@@ -22,7 +23,7 @@ public class RecActionController(IMediator mediator, IConfiguration config) : Co
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
public async Task<IActionResult> Invoke([FromRoute] int profileId, CancellationToken cancel)
|
||||
{
|
||||
await mediator.InvokeBatchRecAction(profileId, cancel);
|
||||
await mediator.InvokeBatchRecActionView(profileId, cancel);
|
||||
return Accepted();
|
||||
}
|
||||
|
||||
@@ -35,7 +36,7 @@ public class RecActionController(IMediator mediator, IConfiguration config) : Co
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
public async Task<IActionResult> Invoke(CancellationToken cancel)
|
||||
{
|
||||
await mediator.InvokeBatchRecAction(config.GetFakeProfileId(), cancel);
|
||||
await mediator.InvokeBatchRecActionView(config.GetFakeProfileId(), cancel);
|
||||
return Accepted();
|
||||
}
|
||||
|
||||
@@ -48,7 +49,7 @@ public class RecActionController(IMediator mediator, IConfiguration config) : Co
|
||||
/// <returns>A list of RecActions for the specified profile.</returns>
|
||||
[HttpGet]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> Get([FromQuery] ReadRecActionQuery query, CancellationToken cancel) => Ok(await mediator.Send(query, cancel));
|
||||
public async Task<IActionResult> Get([FromQuery] ReadRecActionViewQuery query, CancellationToken cancel) => Ok(await mediator.Send(query, cancel));
|
||||
|
||||
/// <summary>
|
||||
/// Gets all RecActions for a fake/test profile.
|
||||
@@ -58,7 +59,7 @@ public class RecActionController(IMediator mediator, IConfiguration config) : Co
|
||||
/// <returns>A list of RecActions for the fake profile.</returns>
|
||||
[HttpGet("fake")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> Get(CancellationToken cancel, [FromQuery] bool invoked = false) => Ok(await mediator.Send(new ReadRecActionQuery()
|
||||
public async Task<IActionResult> Get(CancellationToken cancel, [FromQuery] bool invoked = false) => Ok(await mediator.Send(new ReadRecActionViewQuery()
|
||||
{
|
||||
ProfileId = config.GetFakeProfileId(),
|
||||
Invoked = invoked
|
||||
|
||||
@@ -6,7 +6,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
namespace ReC.Application.Common.Behaviors;
|
||||
|
||||
public class BodyQueryBehavior<TRequest, TResponse>(IRecDbContext dbContext) : IPipelineBehavior<TRequest, TResponse>
|
||||
where TRequest : RecActionDto
|
||||
where TRequest : RecActionViewDto
|
||||
where TResponse : notnull
|
||||
{
|
||||
public async Task<TResponse> Handle(TRequest action, RequestHandlerDelegate<TResponse> next, CancellationToken cancel)
|
||||
|
||||
@@ -8,7 +8,7 @@ using System.Text.Json;
|
||||
namespace ReC.Application.Common.Behaviors;
|
||||
|
||||
public class HeaderQueryBehavior<TRequest, TResponse>(IRecDbContext dbContext, ILogger<HeaderQueryBehavior<TRequest, TResponse>>? logger = null) : IPipelineBehavior<TRequest, TResponse>
|
||||
where TRequest : RecActionDto
|
||||
where TRequest : RecActionViewDto
|
||||
where TResponse : notnull
|
||||
{
|
||||
public async Task<TResponse> Handle(TRequest action, RequestHandlerDelegate<TResponse> next, CancellationToken cancel)
|
||||
|
||||
32
src/ReC.Application/Common/Dto/ConnectionDto.cs
Normal file
32
src/ReC.Application/Common/Dto/ConnectionDto.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
namespace ReC.Application.Common.Dto;
|
||||
|
||||
public record ConnectionDto
|
||||
{
|
||||
public short? Id { get; set; }
|
||||
|
||||
public string? Bezeichnung { get; set; }
|
||||
|
||||
public string? SqlProvider { get; set; }
|
||||
|
||||
public string? Server { get; set; }
|
||||
|
||||
public string? Datenbank { get; set; }
|
||||
|
||||
public string? Username { get; set; }
|
||||
|
||||
public string? Password { get; set; }
|
||||
|
||||
public string? Bemerkung { get; set; }
|
||||
|
||||
public bool? Aktiv { get; set; }
|
||||
|
||||
public string? ErstelltWer { get; set; }
|
||||
|
||||
public DateTime? ErstelltWann { get; set; }
|
||||
|
||||
public string? GeandertWer { get; set; }
|
||||
|
||||
public DateTime? GeaendertWann { get; set; }
|
||||
|
||||
public bool? SysConnection { get; set; }
|
||||
}
|
||||
@@ -6,7 +6,15 @@ public class DtoMappingProfile : AutoMapper.Profile
|
||||
{
|
||||
public DtoMappingProfile()
|
||||
{
|
||||
CreateMap<RecActionView, RecActionDto>();
|
||||
CreateMap<RecActionView, RecActionViewDto>();
|
||||
CreateMap<OutRes, OutResDto>();
|
||||
|
||||
|
||||
CreateMap<Connection, ConnectionDto>();
|
||||
CreateMap<EndpointAuth, EndpointAuthDto>();
|
||||
CreateMap<Endpoint, EndpointDto>();
|
||||
CreateMap<EndpointParam, EndpointParamDto>();
|
||||
CreateMap<Profile, ProfileDto>();
|
||||
CreateMap<RecAction, RecActionDto>();
|
||||
}
|
||||
}
|
||||
|
||||
40
src/ReC.Application/Common/Dto/EndpointAuthDto.cs
Normal file
40
src/ReC.Application/Common/Dto/EndpointAuthDto.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using ReC.Domain.Constants;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Application.Common.Dto;
|
||||
|
||||
[Table("TBREC_CFG_ENDPOINT_AUTH")]
|
||||
public record EndpointAuthDto
|
||||
{
|
||||
public long? Id { get; set; }
|
||||
|
||||
public bool? Active { get; set; }
|
||||
|
||||
public string? Description { get; set; }
|
||||
|
||||
public EndpointAuthType? Type { get; set; }
|
||||
|
||||
public string? ApiKey { get; set; }
|
||||
|
||||
public string? ApiValue { get; set; }
|
||||
|
||||
public ApiKeyLocation? ApiKeyAddTo { get; set; }
|
||||
|
||||
public string? Token { get; set; }
|
||||
|
||||
public string? Username { get; set; }
|
||||
|
||||
public string? Password { get; set; }
|
||||
|
||||
public string? Domain { get; set; }
|
||||
|
||||
public string? Workstation { get; set; }
|
||||
|
||||
public string? AddedWho { get; set; }
|
||||
|
||||
public DateTime? AddedWhen { get; set; }
|
||||
|
||||
public string? ChangedWho { get; set; }
|
||||
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
}
|
||||
22
src/ReC.Application/Common/Dto/EndpointDto.cs
Normal file
22
src/ReC.Application/Common/Dto/EndpointDto.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Application.Common.Dto;
|
||||
|
||||
public record EndpointDto
|
||||
{
|
||||
public long Id { get; set; }
|
||||
|
||||
public bool? Active { get; set; }
|
||||
|
||||
public string? Description { get; set; }
|
||||
|
||||
public string? Uri { get; set; }
|
||||
|
||||
public string? AddedWho { get; set; }
|
||||
|
||||
public DateTime? AddedWhen { get; set; }
|
||||
|
||||
public string? ChangedWho { get; set; }
|
||||
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
}
|
||||
33
src/ReC.Application/Common/Dto/EndpointParamDto.cs
Normal file
33
src/ReC.Application/Common/Dto/EndpointParamDto.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Application.Common.Dto;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the TBREC_CFG_ENDPOINT_PARAMS table.
|
||||
/// All properties are nullable to provide flexibility on the database side,
|
||||
/// preventing breaking changes if columns are altered to be nullable in production.
|
||||
/// </summary>
|
||||
public record EndpointParamDto
|
||||
{
|
||||
public long? Id { get; set; }
|
||||
|
||||
public bool? Active { get; set; }
|
||||
|
||||
public string? Description { get; set; }
|
||||
|
||||
public short? GroupId { get; set; }
|
||||
|
||||
public byte? Sequence { get; set; }
|
||||
|
||||
public string? Key { get; set; }
|
||||
|
||||
public string? Value { get; set; }
|
||||
|
||||
public string? AddedWho { get; set; }
|
||||
|
||||
public DateTime? AddedWhen { get; set; }
|
||||
|
||||
public string? ChangedWho { get; set; }
|
||||
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
}
|
||||
31
src/ReC.Application/Common/Dto/ProfileDto.cs
Normal file
31
src/ReC.Application/Common/Dto/ProfileDto.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Application.Common.Dto;
|
||||
|
||||
[Table("TBREC_CFG_PROFILE", Schema = "dbo")]
|
||||
public record ProfileDto
|
||||
{
|
||||
public long Id { get; set; }
|
||||
|
||||
public bool? Active { get; set; }
|
||||
|
||||
public string? Type { get; set; }
|
||||
|
||||
public string? Mandantor { get; set; }
|
||||
|
||||
public string? Name { get; set; }
|
||||
|
||||
public string? Description { get; set; }
|
||||
|
||||
public string? LogLevel { get; set; }
|
||||
|
||||
public string? Language { get; set; }
|
||||
|
||||
public string? AddedWho { get; set; }
|
||||
|
||||
public DateTime? AddedWhen { get; set; }
|
||||
|
||||
public string? ChangedWho { get; set; }
|
||||
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
}
|
||||
@@ -1,78 +1,54 @@
|
||||
namespace ReC.Application.Common.Dto;
|
||||
using ReC.Domain.Constants;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Application.Common.Dto;
|
||||
|
||||
[Table("TBREC_CFG_ACTION")]
|
||||
public record RecActionDto
|
||||
{
|
||||
public required long Id { get; init; }
|
||||
public long? Id { get; set; }
|
||||
|
||||
public long? ProfileId { get; init; }
|
||||
public long? ProfileId { get; set; }
|
||||
|
||||
public string? ProfileName { get; init; }
|
||||
public ProfileDto? Profile { get; set; }
|
||||
|
||||
public string? ProfileType { get; init; }
|
||||
public bool? Active { get; set; }
|
||||
|
||||
public byte? ProfileSequence { get; init; }
|
||||
public byte? Sequence { get; set; }
|
||||
|
||||
public long? EndpointId { get; init; }
|
||||
public long? EndpointId { get; set; }
|
||||
|
||||
public string? EndpointUri { get; init; }
|
||||
public EndpointDto? Endpoint { get; set; }
|
||||
|
||||
public long? EndpointAuthId { get; init; }
|
||||
public long? EndpointAuthId { get; set; }
|
||||
|
||||
public string? EndpointAuthType { get; init; }
|
||||
public EndpointAuthDto? EndpointAuth { get; set; }
|
||||
|
||||
public string? EndpointAuthApiKey { get; init; }
|
||||
public short? EndpointParamsId { get; set; }
|
||||
|
||||
public string? EndpointAuthApiValue { get; init; }
|
||||
public short? SqlConnectionId { get; set; }
|
||||
|
||||
public string? EndpointAuthApiKeyAddTo { get; init; }
|
||||
public ConnectionDto? SqlConnection { get; set; }
|
||||
|
||||
public string? EndpointAuthToken { get; init; }
|
||||
public string? Type { get; set; }
|
||||
|
||||
public string? EndpointAuthUsername { get; init; }
|
||||
public string? PreprocessingQuery { get; set; }
|
||||
|
||||
public string? EndpointAuthPassword { get; init; }
|
||||
public string? HeaderQuery { get; set; }
|
||||
|
||||
public string? EndpointAuthDomain { get; init; }
|
||||
public string? BodyQuery { get; set; }
|
||||
|
||||
public string? EndpointAuthWorkstation { get; init; }
|
||||
public string? PostprocessingQuery { get; set; }
|
||||
|
||||
public short? EndpointParamsId { get; init; }
|
||||
public ErrorAction? ErrorAction { get; set; }
|
||||
|
||||
public short? SqlConnectionId { get; init; }
|
||||
public string? AddedWho { get; set; }
|
||||
|
||||
public string? SqlConnectionServer { get; init; }
|
||||
public DateTime? AddedWhen { get; set; }
|
||||
|
||||
public string? SqlConnectionDb { get; init; }
|
||||
public string? ChangedWho { get; set; }
|
||||
|
||||
public string? SqlConnectionUsername { get; init; }
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
|
||||
public string? SqlConnectionPassword { get; init; }
|
||||
|
||||
public string? RestType { get; init; }
|
||||
|
||||
public string? PreprocessingQuery { get; init; }
|
||||
|
||||
public string? HeaderQuery { get; init; }
|
||||
|
||||
public Dictionary<string, string>? Headers { get; set; }
|
||||
|
||||
public string? BodyQuery { get; init; }
|
||||
|
||||
public string? Body { get; set; }
|
||||
|
||||
public string? PostprocessingQuery { get; init; }
|
||||
|
||||
public string? ErrorAction { get; init; }
|
||||
|
||||
public UriBuilder ToEndpointUriBuilder()
|
||||
{
|
||||
var builder = EndpointUri is null ? new UriBuilder() : new UriBuilder(EndpointUri);
|
||||
|
||||
builder.Port = -1;
|
||||
|
||||
if (ProfileType is not null)
|
||||
builder.Scheme = ProfileType;
|
||||
|
||||
return builder;
|
||||
}
|
||||
public OutResDto? OutRes { get; set; }
|
||||
}
|
||||
80
src/ReC.Application/Common/Dto/RecActionViewDto.cs
Normal file
80
src/ReC.Application/Common/Dto/RecActionViewDto.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using ReC.Domain.Constants;
|
||||
|
||||
namespace ReC.Application.Common.Dto;
|
||||
|
||||
public record RecActionViewDto
|
||||
{
|
||||
public required long Id { get; init; }
|
||||
|
||||
public long? ProfileId { get; init; }
|
||||
|
||||
public string? ProfileName { get; init; }
|
||||
|
||||
public string? ProfileType { get; init; }
|
||||
|
||||
public byte? ProfileSequence { get; init; }
|
||||
|
||||
public long? EndpointId { get; init; }
|
||||
|
||||
public string? EndpointUri { get; init; }
|
||||
|
||||
public long? EndpointAuthId { get; init; }
|
||||
|
||||
public EndpointAuthType? EndpointAuthType { get; init; }
|
||||
|
||||
public string? EndpointAuthApiKey { get; init; }
|
||||
|
||||
public string? EndpointAuthApiValue { get; init; }
|
||||
|
||||
public ApiKeyLocation? EndpointAuthApiKeyAddTo { get; init; }
|
||||
|
||||
public string? EndpointAuthToken { get; init; }
|
||||
|
||||
public string? EndpointAuthUsername { get; init; }
|
||||
|
||||
public string? EndpointAuthPassword { get; init; }
|
||||
|
||||
public string? EndpointAuthDomain { get; init; }
|
||||
|
||||
public string? EndpointAuthWorkstation { get; init; }
|
||||
|
||||
public short? EndpointParamsId { get; init; }
|
||||
|
||||
public short? SqlConnectionId { get; init; }
|
||||
|
||||
public string? SqlConnectionServer { get; init; }
|
||||
|
||||
public string? SqlConnectionDb { get; init; }
|
||||
|
||||
public string? SqlConnectionUsername { get; init; }
|
||||
|
||||
public string? SqlConnectionPassword { get; init; }
|
||||
|
||||
public string? RestType { get; init; }
|
||||
|
||||
public string? PreprocessingQuery { get; init; }
|
||||
|
||||
public string? HeaderQuery { get; init; }
|
||||
|
||||
public Dictionary<string, string>? Headers { get; set; }
|
||||
|
||||
public string? BodyQuery { get; init; }
|
||||
|
||||
public string? Body { get; set; }
|
||||
|
||||
public string? PostprocessingQuery { get; init; }
|
||||
|
||||
public ErrorAction ErrorAction { get; init; }
|
||||
|
||||
public UriBuilder ToEndpointUriBuilder()
|
||||
{
|
||||
var builder = EndpointUri is null ? new UriBuilder() : new UriBuilder(EndpointUri);
|
||||
|
||||
builder.Port = -1;
|
||||
|
||||
if (ProfileType is not null)
|
||||
builder.Scheme = ProfileType;
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
@@ -5,15 +5,25 @@ namespace ReC.Application.Common.Interfaces;
|
||||
|
||||
public interface IRecDbContext
|
||||
{
|
||||
public DbSet<EndpointParam> EndpointParams { get; }
|
||||
public DbSet<EndpointParam> EndpointParams { get; set; }
|
||||
|
||||
public DbSet<RecActionView> Actions { get; }
|
||||
public DbSet<RecActionView> RecActionViews { get; set; }
|
||||
|
||||
public DbSet<OutRes> OutRes { get; }
|
||||
public DbSet<OutRes> OutRes { get; set; }
|
||||
|
||||
public DbSet<HeaderQueryResult> HeaderQueryResults { get; }
|
||||
public DbSet<HeaderQueryResult> HeaderQueryResults { get; set; }
|
||||
|
||||
public DbSet<BodyQueryResult> BodyQueryResults { get; }
|
||||
public DbSet<BodyQueryResult> BodyQueryResults { get; set; }
|
||||
|
||||
public DbSet<ConnectionDto> Connections { get; set; }
|
||||
|
||||
public DbSet<EndpointDto> Endpoints { get; set; }
|
||||
|
||||
public DbSet<EndpointAuthDto> EndpointAuths { get; set; }
|
||||
|
||||
public DbSet<ProfileDto> Profiles { get; set; }
|
||||
|
||||
public DbSet<RecActionDto> RecActions { get; set; }
|
||||
|
||||
public Task<int> SaveChangesAsync(CancellationToken cancel = default);
|
||||
}
|
||||
@@ -5,14 +5,14 @@ using ReC.Domain.Entities;
|
||||
|
||||
namespace ReC.Application.Endpoints.Commands;
|
||||
|
||||
public class ObtainEndpointCommand : IRequest<Endpoint>
|
||||
public class ObtainEndpointCommand : IRequest<EndpointDto>
|
||||
{
|
||||
public string Uri { get; init; } = null!;
|
||||
}
|
||||
|
||||
public class ObtainEndpointCommandHandler(IRepository<Endpoint> repo) : IRequestHandler<ObtainEndpointCommand, Endpoint>
|
||||
public class ObtainEndpointCommandHandler(IRepository<EndpointDto> repo) : IRequestHandler<ObtainEndpointCommand, EndpointDto>
|
||||
{
|
||||
public async Task<Endpoint> Handle(ObtainEndpointCommand request, CancellationToken cancel)
|
||||
public async Task<EndpointDto> Handle(ObtainEndpointCommand request, CancellationToken cancel)
|
||||
{
|
||||
var endpoint = await repo.Where(e => e.Uri == request.Uri).FirstOrDefaultAsync(cancel);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ public class MappingProfile : AutoMapper.Profile
|
||||
{
|
||||
public MappingProfile()
|
||||
{
|
||||
CreateMap<ObtainEndpointCommand, Endpoint>()
|
||||
CreateMap<ObtainEndpointCommand, EndpointDto>()
|
||||
.ForMember(e => e.Active, exp => exp.MapFrom(cmd => true))
|
||||
.ForMember(e => e.AddedWhen, exp => exp.MapFrom(cmd => DateTime.UtcNow))
|
||||
.ForMember(e => e.AddedWho, exp => exp.MapFrom(cmd => "ReC.API"));
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
using MediatR;
|
||||
using ReC.Application.RecActionViews.Queries;
|
||||
using ReC.Domain.Constants;
|
||||
|
||||
namespace ReC.Application.RecActionViews.Commands;
|
||||
|
||||
public record InvokeBatchRecActionViewsCommand : ReadRecActionQueryBase, IRequest;
|
||||
|
||||
public static class InvokeBatchRecActionViewsCommandExtensions
|
||||
{
|
||||
public static Task InvokeBatchRecActionView(this ISender sender, long profileId, CancellationToken cancel = default)
|
||||
=> sender.Send(new InvokeBatchRecActionViewsCommand { ProfileId = profileId }, cancel);
|
||||
}
|
||||
|
||||
public class InvokeRecActionViewsCommandHandler(ISender sender) : IRequestHandler<InvokeBatchRecActionViewsCommand>
|
||||
{
|
||||
public async Task Handle(InvokeBatchRecActionViewsCommand request, CancellationToken cancel)
|
||||
{
|
||||
var actions = await sender.Send(request.ToReadQuery(q => q.Invoked = false), cancel);
|
||||
|
||||
foreach (var action in actions)
|
||||
{
|
||||
var ok = await sender.Send(action.ToInvokeCommand(), cancel);
|
||||
if (!ok)
|
||||
switch (action.ErrorAction)
|
||||
{
|
||||
case ErrorAction.Continue:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,30 +5,31 @@ using ReC.Application.Common.Constants;
|
||||
using ReC.Application.Common.Dto;
|
||||
using ReC.Application.Common.Exceptions;
|
||||
using ReC.Application.OutResults.Commands;
|
||||
using ReC.Domain.Constants;
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace ReC.Application.RecActions.Commands;
|
||||
namespace ReC.Application.RecActionViews.Commands;
|
||||
|
||||
public record InvokeRecActionCommand : IRequest<bool>
|
||||
public record InvokeRecActionViewCommand : IRequest<bool>
|
||||
{
|
||||
public RecActionDto Action { get; set; } = null!;
|
||||
public RecActionViewDto Action { get; set; } = null!;
|
||||
}
|
||||
|
||||
public static class InvokeRecActionCommandExtensions
|
||||
public static class InvokeRecActionViewCommandExtensions
|
||||
{
|
||||
public static InvokeRecActionCommand ToInvokeCommand(this RecActionDto dto) => new() { Action = dto };
|
||||
public static InvokeRecActionViewCommand ToInvokeCommand(this RecActionViewDto dto) => new() { Action = dto };
|
||||
}
|
||||
|
||||
public class InvokeRecActionCommandHandler(
|
||||
public class InvokeRecActionViewCommandHandler(
|
||||
ISender sender,
|
||||
IHttpClientFactory clientFactory,
|
||||
IConfiguration? config = null
|
||||
) : IRequestHandler<InvokeRecActionCommand, bool>
|
||||
) : IRequestHandler<InvokeRecActionViewCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(InvokeRecActionCommand request, CancellationToken cancel)
|
||||
public async Task<bool> Handle(InvokeRecActionViewCommand request, CancellationToken cancel)
|
||||
{
|
||||
var action = request.Action;
|
||||
|
||||
@@ -57,35 +58,42 @@ public class InvokeRecActionCommandHandler(
|
||||
|
||||
switch (action.EndpointAuthType)
|
||||
{
|
||||
case "No Auth":
|
||||
case EndpointAuthType.NoAuth:
|
||||
break;
|
||||
|
||||
case "API Key":
|
||||
case EndpointAuthType.ApiKey:
|
||||
if (action.EndpointAuthApiKey is string apiKey && action.EndpointAuthApiValue is string apiValue)
|
||||
{
|
||||
if (action.EndpointAuthApiKeyAddTo == "Header")
|
||||
switch (action.EndpointAuthApiKeyAddTo)
|
||||
{
|
||||
httpReq.Headers.Add(apiKey, apiValue);
|
||||
}
|
||||
else // Defaults to Query String
|
||||
{
|
||||
var uriBuilder = new UriBuilder(httpReq.RequestUri!);
|
||||
var query = System.Web.HttpUtility.ParseQueryString(uriBuilder.Query);
|
||||
query[apiKey] = apiValue;
|
||||
uriBuilder.Query = query.ToString();
|
||||
httpReq.RequestUri = uriBuilder.Uri;
|
||||
case ApiKeyLocation.Header:
|
||||
httpReq.Headers.Add(apiKey, apiValue);
|
||||
break;
|
||||
case ApiKeyLocation.Query:
|
||||
var uriBuilder = new UriBuilder(httpReq.RequestUri!);
|
||||
var query = System.Web.HttpUtility.ParseQueryString(uriBuilder.Query);
|
||||
query[apiKey] = apiValue;
|
||||
uriBuilder.Query = query.ToString();
|
||||
httpReq.RequestUri = uriBuilder.Uri;
|
||||
break;
|
||||
default:
|
||||
throw new DataIntegrityException(
|
||||
$"The API key location '{action.EndpointAuthApiKeyAddTo}' is not supported. " +
|
||||
$"ProfileId: {action.ProfileId}, " +
|
||||
$"Id: {action.Id}"
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "Bearer Token":
|
||||
case "JWT Bearer":
|
||||
case "OAuth 2.0": // OAuth 2.0 uses Bearer tokens for authenticated requests
|
||||
case EndpointAuthType.BearerToken:
|
||||
case EndpointAuthType.JwtBearer:
|
||||
case EndpointAuthType.OAuth2:
|
||||
if (action.EndpointAuthToken is string authToken)
|
||||
httpReq.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
|
||||
break;
|
||||
|
||||
case "Basic Auth":
|
||||
case EndpointAuthType.BasicAuth:
|
||||
if (action.EndpointAuthUsername is string authUsername && action.EndpointAuthPassword is string authPassword)
|
||||
{
|
||||
var basicAuth = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{authUsername}:{authPassword}"));
|
||||
@@ -93,7 +101,7 @@ public class InvokeRecActionCommandHandler(
|
||||
}
|
||||
break;
|
||||
|
||||
case "NTLM Auth":
|
||||
case EndpointAuthType.NtlmAuth:
|
||||
if (!string.IsNullOrWhiteSpace(action.EndpointAuthUsername))
|
||||
{
|
||||
var credentials = new NetworkCredential(
|
||||
@@ -105,9 +113,9 @@ public class InvokeRecActionCommandHandler(
|
||||
}
|
||||
break;
|
||||
|
||||
case "Digest Auth":
|
||||
case "OAuth 1.0":
|
||||
case "AWS Signature":
|
||||
case EndpointAuthType.DigestAuth:
|
||||
case EndpointAuthType.OAuth1:
|
||||
case EndpointAuthType.AwsSignature:
|
||||
// These authentication methods require more complex implementations,
|
||||
// often involving multi-step handshakes or specialized libraries.
|
||||
// They are left as placeholders for future implementation.
|
||||
@@ -8,7 +8,7 @@ public class MappingProfile : AutoMapper.Profile
|
||||
{
|
||||
public MappingProfile()
|
||||
{
|
||||
CreateMap<CreateRecActionCommand, RecAction>()
|
||||
CreateMap<CreateRecActionCommand, RecActionDto>()
|
||||
.ForMember(e => e.Active, exp => exp.MapFrom(cmd => true))
|
||||
.ForMember(e => e.AddedWhen, exp => exp.MapFrom(cmd => DateTime.UtcNow))
|
||||
.ForMember(e => e.AddedWho, exp => exp.MapFrom(cmd => "ReC.API"));
|
||||
@@ -6,32 +6,32 @@ using Microsoft.EntityFrameworkCore;
|
||||
using DigitalData.Core.Exceptions;
|
||||
using ReC.Application.Common.Dto;
|
||||
|
||||
namespace ReC.Application.RecActions.Queries;
|
||||
namespace ReC.Application.RecActionViews.Queries;
|
||||
|
||||
public record ReadRecActionQueryBase
|
||||
{
|
||||
public long ProfileId { get; init; }
|
||||
|
||||
public ReadRecActionQuery ToReadQuery(Action<ReadRecActionQuery> modify)
|
||||
public ReadRecActionViewQuery ToReadQuery(Action<ReadRecActionViewQuery> modify)
|
||||
{
|
||||
ReadRecActionQuery query = new(this);
|
||||
ReadRecActionViewQuery query = new(this);
|
||||
modify(query);
|
||||
return query;
|
||||
}
|
||||
}
|
||||
|
||||
public record ReadRecActionQuery : ReadRecActionQueryBase, IRequest<IEnumerable<RecActionDto>>
|
||||
public record ReadRecActionViewQuery : ReadRecActionQueryBase, IRequest<IEnumerable<RecActionViewDto>>
|
||||
{
|
||||
public ReadRecActionQuery(ReadRecActionQueryBase root) : base(root) { }
|
||||
public ReadRecActionViewQuery(ReadRecActionQueryBase root) : base(root) { }
|
||||
|
||||
public bool? Invoked { get; set; } = null;
|
||||
|
||||
public ReadRecActionQuery() { }
|
||||
public ReadRecActionViewQuery() { }
|
||||
}
|
||||
|
||||
public class ReadRecActionQueryHandler(IRepository<RecActionView> repo, IMapper mapper) : IRequestHandler<ReadRecActionQuery, IEnumerable<RecActionDto>>
|
||||
public class ReadRecActionViewQueryHandler(IRepository<RecActionView> repo, IMapper mapper) : IRequestHandler<ReadRecActionViewQuery, IEnumerable<RecActionViewDto>>
|
||||
{
|
||||
public async Task<IEnumerable<RecActionDto>> Handle(ReadRecActionQuery request, CancellationToken cancel)
|
||||
public async Task<IEnumerable<RecActionViewDto>> Handle(ReadRecActionViewQuery request, CancellationToken cancel)
|
||||
{
|
||||
var query = repo.Where(act => act.ProfileId == request.ProfileId);
|
||||
|
||||
@@ -43,6 +43,6 @@ public class ReadRecActionQueryHandler(IRepository<RecActionView> repo, IMapper
|
||||
if (actions.Count == 0)
|
||||
throw new NotFoundException($"No actions found for the profile {request.ProfileId}.");
|
||||
|
||||
return mapper.Map<IEnumerable<RecActionDto>>(actions);
|
||||
return mapper.Map<IEnumerable<RecActionViewDto>>(actions);
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ public record CreateRecActionCommand : IRequest
|
||||
public long? EndpointAuthId { get; set; }
|
||||
}
|
||||
|
||||
public class CreateRecActionCommandHandler(ISender sender, IRepository<RecAction> repo) : IRequestHandler<CreateRecActionCommand>
|
||||
public class CreateRecActionCommandHandler(ISender sender, IRepository<RecActionDto> repo) : IRequestHandler<CreateRecActionCommand>
|
||||
{
|
||||
public async Task Handle(CreateRecActionCommand request, CancellationToken cancel)
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ public class DeleteRecActionsCommand : IRequest
|
||||
public required long ProfileId { get; init; }
|
||||
}
|
||||
|
||||
public class DeleteRecActionsCommandHandler(IRepository<RecAction> repo) : IRequestHandler<DeleteRecActionsCommand>
|
||||
public class DeleteRecActionsCommandHandler(IRepository<RecActionDto> repo) : IRequestHandler<DeleteRecActionsCommand>
|
||||
{
|
||||
public async Task Handle(DeleteRecActionsCommand request, CancellationToken cancel)
|
||||
{
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
using MediatR;
|
||||
using ReC.Application.RecActions.Queries;
|
||||
|
||||
namespace ReC.Application.RecActions.Commands;
|
||||
|
||||
public record InvokeBatchRecActionsCommand : ReadRecActionQueryBase, IRequest;
|
||||
|
||||
public static class InvokeBatchRecActionsCommandExtensions
|
||||
{
|
||||
public static Task InvokeBatchRecAction(this ISender sender, long profileId, CancellationToken cancel = default)
|
||||
=> sender.Send(new InvokeBatchRecActionsCommand { ProfileId = profileId }, cancel);
|
||||
}
|
||||
|
||||
public class InvokeRecActionsCommandHandler(ISender sender) : IRequestHandler<InvokeBatchRecActionsCommand>
|
||||
{
|
||||
public async Task Handle(InvokeBatchRecActionsCommand request, CancellationToken cancel)
|
||||
{
|
||||
var actions = await sender.Send(request.ToReadQuery(q => q.Invoked = false), cancel);
|
||||
|
||||
foreach (var action in actions)
|
||||
{
|
||||
var ok = await sender.Send(action.ToInvokeCommand(), cancel);
|
||||
if (!ok)
|
||||
switch (action.ErrorAction?.ToLowerInvariant())
|
||||
{
|
||||
case "continue":
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
7
src/ReC.Domain/Constants/ApiKeyLocation.cs
Normal file
7
src/ReC.Domain/Constants/ApiKeyLocation.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace ReC.Domain.Constants;
|
||||
|
||||
public enum ApiKeyLocation
|
||||
{
|
||||
Header = 0,
|
||||
Query = 1
|
||||
}
|
||||
15
src/ReC.Domain/Constants/EndpointAuthType.cs
Normal file
15
src/ReC.Domain/Constants/EndpointAuthType.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
namespace ReC.Domain.Constants;
|
||||
|
||||
public enum EndpointAuthType
|
||||
{
|
||||
NoAuth = 0,
|
||||
ApiKey = 1,
|
||||
BearerToken = 2,
|
||||
JwtBearer = 3,
|
||||
BasicAuth = 4,
|
||||
DigestAuth = 5,
|
||||
OAuth1 = 6,
|
||||
OAuth2 = 7,
|
||||
AwsSignature = 8,
|
||||
NtlmAuth = 9
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
namespace ReC.Domain.Entities;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Domain.Entities;
|
||||
|
||||
[Table("TBDD_CONNECTION")]
|
||||
public class Connection
|
||||
{
|
||||
public short? Id { get; set; }
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
namespace ReC.Domain.Entities;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Domain.Entities;
|
||||
|
||||
[Table("TBREC_CFG_ENDPOINT")]
|
||||
public class Endpoint
|
||||
{
|
||||
public long Id { get; set; }
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using ReC.Domain.Constants;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Domain.Entities;
|
||||
|
||||
[Table("TBREC_CFG_ENDPOINT_AUTH")]
|
||||
public class EndpointAuth
|
||||
{
|
||||
public long? Id { get; set; }
|
||||
@@ -11,13 +12,13 @@ public class EndpointAuth
|
||||
|
||||
public string? Description { get; set; }
|
||||
|
||||
public string? Type { get; set; }
|
||||
public EndpointAuthType? Type { get; set; }
|
||||
|
||||
public string? ApiKey { get; set; }
|
||||
|
||||
public string? ApiValue { get; set; }
|
||||
|
||||
public string? ApiKeyAddTo { get; set; }
|
||||
public ApiKeyLocation? ApiKeyAddTo { get; set; }
|
||||
|
||||
public string? Token { get; set; }
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
namespace ReC.Domain.Entities;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Domain.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the TBREC_CFG_ENDPOINT_PARAMS table.
|
||||
/// All properties are nullable to provide flexibility on the database side,
|
||||
/// preventing breaking changes if columns are altered to be nullable in production.
|
||||
/// </summary>
|
||||
[Table("TBREC_CFG_ENDPOINT_PARAMS", Schema = "dbo")]
|
||||
public class EndpointParam
|
||||
{
|
||||
public long? Id { get; set; }
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
namespace ReC.Domain.Entities;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Domain.Entities;
|
||||
|
||||
[Table("TBREC_OUT_RESULT", Schema = "dbo")]
|
||||
public class OutRes
|
||||
{
|
||||
public long? Id { get; set; }
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
namespace ReC.Domain.Entities;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Domain.Entities;
|
||||
|
||||
[Table("TBREC_CFG_PROFILE", Schema = "dbo")]
|
||||
public class Profile
|
||||
{
|
||||
public long Id { get; set; }
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using ReC.Domain.Constants;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Domain.Entities;
|
||||
|
||||
[Table("TBREC_CFG_ACTION")]
|
||||
public class RecAction
|
||||
{
|
||||
public long? Id { get; set; }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using ReC.Domain.Constants;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Domain.Entities;
|
||||
@@ -11,14 +11,17 @@ namespace ReC.Domain.Entities;
|
||||
/// runtime mapping errors and ensures the application can handle schema changes without
|
||||
/// requiring immediate code updates.
|
||||
/// </summary>
|
||||
[Table("VWREC_ACTION", Schema = "dbo")]
|
||||
public class RecActionView
|
||||
{
|
||||
public required long Id { get; set; }
|
||||
|
||||
[ForeignKey("Id")]
|
||||
public RecAction? Root { get; set; }
|
||||
|
||||
public long? ProfileId { get; set; }
|
||||
|
||||
[ForeignKey("ProfileId")]
|
||||
public Profile? Profile { get; set; }
|
||||
|
||||
public string? ProfileName { get; set; }
|
||||
@@ -29,6 +32,9 @@ public class RecActionView
|
||||
|
||||
public long? EndpointId { get; set; }
|
||||
|
||||
[ForeignKey("EndpointId")]
|
||||
public Endpoint? Endpoint { get; set; }
|
||||
|
||||
public string? EndpointUri { get; set; }
|
||||
|
||||
public long? EndpointAuthId { get; set; }
|
||||
@@ -36,13 +42,13 @@ public class RecActionView
|
||||
[ForeignKey("EndpointAuthId")]
|
||||
public EndpointAuth? EndpointAuth { get; set; }
|
||||
|
||||
public string? EndpointAuthType { get; set; }
|
||||
public EndpointAuthType? EndpointAuthType { get; set; }
|
||||
|
||||
public string? EndpointAuthApiKey { get; set; }
|
||||
|
||||
public string? EndpointAuthApiValue { get; set; }
|
||||
|
||||
public string? EndpointAuthApiKeyAddTo { get; set; }
|
||||
public ApiKeyLocation? EndpointAuthApiKeyAddTo { get; set; }
|
||||
|
||||
public string? EndpointAuthToken { get; set; }
|
||||
|
||||
@@ -58,6 +64,9 @@ public class RecActionView
|
||||
|
||||
public short? SqlConnectionId { get; set; }
|
||||
|
||||
[ForeignKey("SqlConnectionId")]
|
||||
public Connection? SqlConnection { get; set; }
|
||||
|
||||
public string? SqlConnectionServer { get; set; }
|
||||
|
||||
public string? SqlConnectionDb { get; set; }
|
||||
|
||||
@@ -8,7 +8,7 @@ public class RecDbContext(DbContextOptions<RecDbContext> options) : DbContext(op
|
||||
{
|
||||
public DbSet<EndpointParam> EndpointParams { get; set; }
|
||||
|
||||
public DbSet<RecActionView> Actions { get; set; }
|
||||
public DbSet<RecActionView> RecActionViews { get; set; }
|
||||
|
||||
public DbSet<OutRes> OutRes { get; set; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user