Compare commits
234 Commits
feat/clien
...
cbd86de3e8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cbd86de3e8 | ||
|
|
a5160b35dd | ||
|
|
60e1627494 | ||
|
|
b9f08bc21c | ||
|
|
758616c95e | ||
|
|
7376b49e38 | ||
|
|
b65c354ef0 | ||
|
|
38258a98c1 | ||
|
|
7666708ab5 | ||
|
|
d3b67bc429 | ||
|
|
97f992aef5 | ||
|
|
cc6f93ae1c | ||
|
|
402990bd3c | ||
|
|
43cdef4910 | ||
|
|
348a55fc60 | ||
|
|
719bc9c941 | ||
|
|
37381af042 | ||
|
|
34fe996d91 | ||
|
|
252fc10243 | ||
|
|
c8a9245b54 | ||
|
|
c56bcc198e | ||
|
|
538abec212 | ||
|
|
19666e649d | ||
|
|
1df9235036 | ||
| dd9c1c7ca2 | |||
| f9cc735318 | |||
| 2a8eb3c0ad | |||
| 7a4cdb3d1f | |||
| 453b6d1813 | |||
| bd2b5ff62f | |||
| 849de7a204 | |||
| c7423fb6fd | |||
| ad51e4b1eb | |||
| df2ebe0cc2 | |||
| 5c06f287ab | |||
| c3e3a0377d | |||
| cf34a54170 | |||
| 16f48f125b | |||
| e3faa2f570 | |||
| 0d30b5ff87 | |||
| 563375f6e3 | |||
| 3864b0f68b | |||
| 35e03269e7 | |||
| 8b212d541e | |||
| dd4cecc15d | |||
| 0dedb506e1 | |||
| 24f146ca26 | |||
| 2692553865 | |||
| d90c2fab96 | |||
| 854e36e71f | |||
| 1d31f2aff9 | |||
| 11206cf84f | |||
| b48ebd8e88 | |||
| 12d17e0808 | |||
| 1dee3180d5 | |||
| bd4046a6c1 | |||
| af6f94c1ed | |||
| 7bfb56b664 | |||
| 1a6eced316 | |||
| c82749bcbf | |||
| e8fa149532 | |||
| aaa7beb92a | |||
| 5cce52ec27 | |||
| 3f36f048b2 | |||
| 92e8d9e778 | |||
| 2d04670fef | |||
| c0085b4c18 | |||
| 59ea5e3e67 | |||
| a9f2c4c2f7 | |||
| 001f4bf2c5 | |||
| bfe6c12ee0 | |||
| e1260e49f0 | |||
| 8b86eca838 | |||
| fb12cb6c98 | |||
| 2635bfb223 | |||
| 5245cd04ff | |||
| 9d5334e7dc | |||
| e5bb61376a | |||
| d3aa8c715b | |||
| 6720e66b23 | |||
| 71470fc21d | |||
| 9191ec4179 | |||
| e0d83c0a14 | |||
| 03bcfb6fc9 | |||
| 284ced6059 | |||
| 88c6e6d214 | |||
| 6263848a0a | |||
| 83f173fdc4 | |||
| 7c687c0541 | |||
| 48e9812224 | |||
| 1199c61ae8 | |||
| a55b51e504 | |||
| 752f781f54 | |||
| 9b800dce20 | |||
| 0fa1a418de | |||
| cc54539aba | |||
| ac4c4cb69a | |||
| 73ccb9e43b | |||
| b6ab59ae4a | |||
| 868e11ff62 | |||
| 38d819adac | |||
| 9b3bb925f9 | |||
| a92d57d9cf | |||
| 39fcee2b50 | |||
| d0597e28e8 | |||
| d8d77652ac | |||
| 62612897bd | |||
| 99c50fb348 | |||
| 8aaf11f39d | |||
| 152189fefd | |||
| 5a4b8427be | |||
| e4a644a636 | |||
| 25c6c41b26 | |||
| c672a10c97 | |||
| 1e21218f31 | |||
| 68e7ee54f9 | |||
| 2a749267b3 | |||
| edc1de2034 | |||
| ae79a60605 | |||
| 6b8286a386 | |||
| 1fabc29e4f | |||
| 56fb34d987 | |||
| 47ddde239e | |||
| 5a4d2d8553 | |||
| 4e209e29fc | |||
| 78aaea67e6 | |||
| 98261f4e21 | |||
| aab8174500 | |||
| fb6d6af12b | |||
| f82f4d2c65 | |||
| 90ee3f6a5d | |||
| a24ec1ab3e | |||
| b8c30d520e | |||
| f69f323542 | |||
| 3621820060 | |||
| 0e0f27c124 | |||
| 5404530785 | |||
| 289b6109e4 | |||
| 679c065aaa | |||
| a02cac8778 | |||
| 42fd176fad | |||
| e529027587 | |||
| cc2adab5e5 | |||
| a0233fd876 | |||
| 0afe9870c0 | |||
| 784b4b1f05 | |||
| 1634b4b7b1 | |||
| 576b2d59d9 | |||
| 3da16ba640 | |||
| 71a0220c3f | |||
| f53603083a | |||
| 92e7d44d3b | |||
| f8211e9e9d | |||
| 1782844543 | |||
| 2aa7cabcbd | |||
| 28f35101f9 | |||
| f8c5502905 | |||
| 961b87de3d | |||
| 6b036f4f91 | |||
| 46b7ae29cd | |||
| 84e403f411 | |||
| 3b77345aee | |||
| 6d04a4afd1 | |||
| 1f250d55b0 | |||
| c422de445d | |||
| f9a73fbe0c | |||
| 282ce3a0b7 | |||
| 26f2da1313 | |||
| bc700e2cd2 | |||
| ea5389df85 | |||
| 87e1bb9187 | |||
| 68cc919bad | |||
| 374365d250 | |||
| 8c79b3a156 | |||
| 0583d07f26 | |||
| fd7744e94e | |||
| a5aac1d0ec | |||
| 165152b7cf | |||
| f1f9e8d791 | |||
| 35171add0c | |||
| 030dcf8b58 | |||
| 71411d4027 | |||
| da1b05347e | |||
| d932fb522c | |||
| 134a808633 | |||
|
|
00efb14f2c | ||
| fe40cd001f | |||
| f96b73bf38 | |||
| c8f3b29329 | |||
| 07fca00344 | |||
| e4aec494c8 | |||
| 009bb623b5 | |||
| f8e7f8c974 | |||
| 959b56c4bb | |||
| 5a56125444 | |||
| 48039b8fd5 | |||
| 31d1d9d171 | |||
| 1419455b36 | |||
| a6111cdc66 | |||
| 3caa6b9bd3 | |||
| fb08a45c57 | |||
| 0588ba33d8 | |||
| 535fdbb7b4 | |||
| 4206a962ff | |||
| ae059e4416 | |||
| d771dbbc9e | |||
| 73ffaaab08 | |||
| b79fcf936b | |||
| 674c14dd7c | |||
| b326e7e1b3 | |||
| 3f8ba7d76c | |||
| 13346b610a | |||
| 8bc9b85049 | |||
| 141e77f315 | |||
| f9a4d93495 | |||
| 79f771b3ea | |||
| 8738c15804 | |||
| 70c07c9595 | |||
| 96fe9c99da | |||
| 1e62a70866 | |||
| f4aa0b5965 | |||
| 1700fe978d | |||
| 37c88812e1 | |||
| 34efb662ec | |||
| dcbff90ed8 | |||
| 404a1c4793 | |||
| 1cdd28738a | |||
| 45c7259ce8 | |||
| 6d9985051e | |||
| b9f5a3f10c | |||
| 243cc97aa2 | |||
| bb43bfa064 | |||
| b4966585ae | |||
| ae548d530f |
33
src/ReC.API/Controllers/CommonController.cs
Normal file
33
src/ReC.API/Controllers/CommonController.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using ReC.Application.Common.Procedures.DeleteProcedure;
|
||||
using ReC.Application.Common.Procedures.InsertProcedure;
|
||||
using ReC.Application.Common.Procedures.UpdateProcedure;
|
||||
|
||||
namespace ReC.API.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class CommonController(IMediator mediator) : ControllerBase
|
||||
{
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> CreateObject([FromBody] InsertObjectProcedure procedure, CancellationToken cancel)
|
||||
{
|
||||
var id = await mediator.Send(procedure, cancel);
|
||||
return StatusCode(StatusCodes.Status201Created, id);
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
public async Task<IActionResult> UpdateObject([FromBody] UpdateObjectProcedure procedure, CancellationToken cancel)
|
||||
{
|
||||
var result = await mediator.Send(procedure, cancel);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
public async Task<IActionResult> DeleteObject([FromBody] DeleteObjectProcedure procedure, CancellationToken cancel)
|
||||
{
|
||||
var result = await mediator.Send(procedure, cancel);
|
||||
return Ok(result);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using ReC.API.Extensions;
|
||||
using ReC.API.Models;
|
||||
using ReC.Application.OutResults.Commands;
|
||||
using ReC.Application.OutResults.Queries;
|
||||
|
||||
namespace ReC.API.Controllers;
|
||||
@@ -17,7 +19,7 @@ public class OutResController(IMediator mediator, IConfiguration config) : Contr
|
||||
/// <returns>A list of output results matching the query.</returns>
|
||||
[HttpGet]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> Get([FromQuery] ReadOutResQuery query, CancellationToken cancel) => Ok(await mediator.Send(query, cancel));
|
||||
public async Task<IActionResult> Get([FromQuery] ReadResultViewQuery query, CancellationToken cancel) => Ok(await mediator.Send(query, cancel));
|
||||
|
||||
/// <summary>
|
||||
/// Gets output results for a fake/test profile.
|
||||
@@ -26,7 +28,7 @@ public class OutResController(IMediator mediator, IConfiguration config) : Contr
|
||||
/// <returns>A list of output results for the fake profile.</returns>
|
||||
[HttpGet("fake")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> Get(CancellationToken cancel) => Ok(await mediator.Send(new ReadOutResQuery()
|
||||
public async Task<IActionResult> Get(CancellationToken cancel) => Ok(await mediator.Send(new ReadResultViewQuery()
|
||||
{
|
||||
ProfileId = config.GetFakeProfileId()
|
||||
}, cancel));
|
||||
@@ -36,13 +38,13 @@ public class OutResController(IMediator mediator, IConfiguration config) : Contr
|
||||
/// </summary>
|
||||
/// <param name="actionId">The ID of the action to retrieve the result for.</param>
|
||||
/// <param name="cancel">A token to cancel the operation.</param>
|
||||
/// <param name="resultType">Specifies which part of the result to return (Full, Header, or Body).</param>
|
||||
/// <param name="resultType">Specifies which part of the result to return (Full, OnlyHeader, or OnlyBody).</param>
|
||||
/// <returns>The requested output result or a part of it (header/body).</returns>
|
||||
[HttpGet("fake/{actionId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> Get([FromRoute] long actionId, CancellationToken cancel, ResultType resultType = ResultType.Full)
|
||||
{
|
||||
var res = (await mediator.Send(new ReadOutResQuery()
|
||||
var res = (await mediator.Send(new ReadResultViewQuery()
|
||||
{
|
||||
ProfileId = config.GetFakeProfileId(),
|
||||
ActionId = actionId
|
||||
@@ -50,28 +52,39 @@ public class OutResController(IMediator mediator, IConfiguration config) : Contr
|
||||
|
||||
return resultType switch
|
||||
{
|
||||
ResultType.Body => res.Body is null ? Ok(new object { }) : Ok(res.Body.JsonToDynamic()),
|
||||
ResultType.Header => res.Header is null ? Ok(new object { }) : Ok(res.Header.JsonToDynamic()),
|
||||
ResultType.OnlyBody => res.Body is null ? NotFound() : Ok(res.Body.JsonToDynamic()),
|
||||
ResultType.OnlyHeader => res.Header is null ? NotFound() : Ok(res.Header.JsonToDynamic()),
|
||||
_ => Ok(res),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes output results based on the provided criteria.
|
||||
/// </summary>
|
||||
/// <param name="command">The command containing the deletion criteria, such as ActionId or ProfileId.</param>
|
||||
/// <param name="cancel">A token to cancel the operation.</param>
|
||||
/// <returns>An empty response indicating success.</returns>
|
||||
[HttpDelete]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[Obsolete("Use the related procedure or view.")]
|
||||
public async Task<IActionResult> Delete([FromQuery] DeleteOutResCommand command, CancellationToken cancel)
|
||||
{
|
||||
await mediator.Send(command, cancel);
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the type of result to be returned from an output result query.
|
||||
/// </summary>
|
||||
public enum ResultType
|
||||
{
|
||||
/// <summary>
|
||||
/// Return the full result object.
|
||||
/// Deletes all output results for a fake/test profile.
|
||||
/// </summary>
|
||||
Full,
|
||||
/// <summary>
|
||||
/// Return only the header part of the result.
|
||||
/// </summary>
|
||||
Header,
|
||||
/// <summary>
|
||||
/// Return only the body part of the result.
|
||||
/// </summary>
|
||||
Body
|
||||
}
|
||||
/// <param name="cancel">A token to cancel the operation.</param>
|
||||
/// <returns>An empty response indicating success.</returns>
|
||||
[HttpDelete("fake")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[Obsolete("Use the related procedure or view.")]
|
||||
public async Task<IActionResult> Delete(CancellationToken cancel)
|
||||
{
|
||||
await mediator.Send(new DeleteOutResCommand() { ProfileId = config.GetFakeProfileId() }, cancel);
|
||||
return NoContent();
|
||||
}
|
||||
}
|
||||
16
src/ReC.API/Controllers/ProfileController.cs
Normal file
16
src/ReC.API/Controllers/ProfileController.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using ReC.Application.Profile.Queries;
|
||||
|
||||
namespace ReC.API.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class ProfileController(IMediator mediator) : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> GetProfile([FromQuery] ReadProfileViewQuery query, CancellationToken cancel)
|
||||
{
|
||||
return Ok(await mediator.Send(query, cancel));
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using ReC.API.Extensions;
|
||||
using ReC.API.Models;
|
||||
using ReC.Application.Common.Procedures.InsertProcedure;
|
||||
using ReC.Application.RecActions.Commands;
|
||||
using ReC.Application.RecActions.Queries;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace ReC.API.Controllers;
|
||||
|
||||
@@ -18,11 +17,11 @@ public class RecActionController(IMediator mediator, IConfiguration config) : Co
|
||||
/// <param name="profileId">The ID of the profile.</param>
|
||||
/// <param name="cancel">A token to cancel the operation.</param>
|
||||
/// <returns>An HTTP 202 Accepted response indicating the process has been started.</returns>
|
||||
[HttpPost("invoke/{cmd}")]
|
||||
[HttpPost("invoke/{profileId}")]
|
||||
[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 +34,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();
|
||||
}
|
||||
|
||||
@@ -43,12 +42,12 @@ public class RecActionController(IMediator mediator, IConfiguration config) : Co
|
||||
/// <summary>
|
||||
/// Gets all RecActions for a given profile.
|
||||
/// </summary>
|
||||
/// <param name="profileId">The ID of the profile.</param>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="cancel">A token to cancel the operation.</param>
|
||||
/// <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 +57,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
|
||||
@@ -72,49 +71,11 @@ public class RecActionController(IMediator mediator, IConfiguration config) : Co
|
||||
/// <returns>An HTTP 201 Created response.</returns>
|
||||
[HttpPost]
|
||||
[ProducesResponseType(StatusCodes.Status201Created)]
|
||||
public async Task<IActionResult> CreateAction([FromBody] CreateRecActionCommand command, CancellationToken cancel)
|
||||
public async Task<IActionResult> CreateAction([FromBody] InsertActionProcedure command, CancellationToken cancel)
|
||||
{
|
||||
await mediator.Send(command, cancel);
|
||||
await mediator.ExecuteInsertProcedure(command, config["AddedWho"], cancel);
|
||||
|
||||
return CreatedAtAction(nameof(CreateAction), null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new fake RecAction for testing purposes.
|
||||
/// </summary>
|
||||
/// <param name="cancel">A token to cancel the operation.</param>
|
||||
/// <param name="request">The optional request body and header for the fake action.</param>
|
||||
/// <param name="endpointUri">The target endpoint URI.</param>
|
||||
/// <param name="endpointPath">The optional path to append to the endpoint URI.</param>
|
||||
/// <param name="type">The HTTP method type (e.g., GET, POST).</param>
|
||||
/// <returns>An HTTP 201 Created response.</returns>
|
||||
[HttpPost("fake")]
|
||||
[ProducesResponseType(StatusCodes.Status201Created)]
|
||||
public async Task<IActionResult> CreateFakeAction(
|
||||
CancellationToken cancel,
|
||||
[FromBody] FakeRequest? request = null,
|
||||
[FromQuery] string endpointUri = "https://jsonplaceholder.typicode.com/posts",
|
||||
[FromQuery] string? endpointPath = "1",
|
||||
[FromQuery] string type = "GET")
|
||||
{
|
||||
if (endpointPath is not null)
|
||||
endpointUri = new Uri(new Uri(endpointUri.TrimEnd('/') + "/"), endpointPath.TrimStart('/')).ToString();
|
||||
|
||||
var bodyJson = request?.Body is not null ? JsonSerializer.Serialize(request.Body, options: new() { WriteIndented = false }) : null;
|
||||
var headerJson = request?.Header is not null ? JsonSerializer.Serialize(request.Header, options: new() { WriteIndented = false }) : null;
|
||||
|
||||
await mediator.Send(new CreateRecActionCommand()
|
||||
{
|
||||
ProfileId = config.GetFakeProfileId(),
|
||||
EndpointUri = endpointUri,
|
||||
Type = type,
|
||||
BodyQuery = $@"SELECT '{bodyJson ?? "NULL"}' AS REQUEST_BODY;",
|
||||
HeaderQuery = headerJson is not null ? $@"SELECT '{headerJson}' AS REQUEST_HEADER;" : null,
|
||||
Active = true,
|
||||
EndpointAuthId = 4
|
||||
}, cancel);
|
||||
|
||||
return CreatedAtAction(nameof(CreateFakeAction), null);
|
||||
return StatusCode(StatusCodes.Status201Created);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -125,6 +86,7 @@ public class RecActionController(IMediator mediator, IConfiguration config) : Co
|
||||
/// <returns>An HTTP 204 No Content response upon successful deletion.</returns>
|
||||
[HttpDelete]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[Obsolete("Use the related procedure.")]
|
||||
public async Task<IActionResult> Delete([FromQuery] DeleteRecActionsCommand cmd, CancellationToken cancel)
|
||||
{
|
||||
await mediator.Send(cmd, cancel);
|
||||
@@ -138,6 +100,7 @@ public class RecActionController(IMediator mediator, IConfiguration config) : Co
|
||||
/// <returns>An HTTP 204 No Content response upon successful deletion.</returns>
|
||||
[HttpDelete("fake")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[Obsolete("Use the related procedure.")]
|
||||
public async Task<IActionResult> Delete(CancellationToken cancel)
|
||||
{
|
||||
await mediator.Send(new DeleteRecActionsCommand()
|
||||
|
||||
49
src/ReC.API/Controllers/ResultViewController.cs
Normal file
49
src/ReC.API/Controllers/ResultViewController.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using ReC.API.Extensions;
|
||||
using ReC.API.Models;
|
||||
using ReC.Application.Common.Procedures.InsertProcedure;
|
||||
using ReC.Application.OutResults.Queries;
|
||||
|
||||
namespace ReC.API.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class ResultViewController(IMediator mediator, IConfiguration config) : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> Get([FromQuery] ReadResultViewQuery query, CancellationToken cancel) => Ok(await mediator.Send(query, cancel));
|
||||
|
||||
[HttpGet("fake")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> Get(CancellationToken cancel) => Ok(await mediator.Send(new ReadResultViewQuery()
|
||||
{
|
||||
ProfileId = config.GetFakeProfileId()
|
||||
}, cancel));
|
||||
|
||||
[HttpGet("fake/{actionId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> Get([FromRoute] long actionId, CancellationToken cancel, ResultType resultType = ResultType.Full)
|
||||
{
|
||||
var res = (await mediator.Send(new ReadResultViewQuery()
|
||||
{
|
||||
ProfileId = config.GetFakeProfileId(),
|
||||
ActionId = actionId
|
||||
}, cancel)).First();
|
||||
|
||||
return resultType switch
|
||||
{
|
||||
ResultType.OnlyBody => res.Body is null ? NotFound() : Ok(res.Body.JsonToDynamic()),
|
||||
ResultType.OnlyHeader => res.Header is null ? NotFound() : Ok(res.Header.JsonToDynamic()),
|
||||
_ => Ok(res),
|
||||
};
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> Create([FromBody] InsertResultProcedure procedure, CancellationToken cancel)
|
||||
{
|
||||
await mediator.Send(procedure, cancel);
|
||||
return CreatedAtAction(nameof(Get), new { actionId = procedure.ActionId }, procedure);
|
||||
}
|
||||
}
|
||||
18
src/ReC.API/Middleware/AuthScopedFilter.cs
Normal file
18
src/ReC.API/Middleware/AuthScopedFilter.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using ReC.Application.Common.Interfaces;
|
||||
|
||||
namespace ReC.API.Middleware;
|
||||
|
||||
public class AuthScopedFilter(IConfiguration config) : IAsyncActionFilter
|
||||
{
|
||||
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
||||
{
|
||||
if (context.ActionArguments.TryGetValue("command", out var command) && command is IAuthScoped authScopedCommand)
|
||||
{
|
||||
var addedWho = config["AddedWho"] ?? throw new InvalidOperationException("The required 'AddedWho' configuration is missing. Please contact a system administrator.");
|
||||
authScopedCommand.Scope.AddedWho = addedWho;
|
||||
}
|
||||
|
||||
await next();
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,7 @@ public class ExceptionHandlingMiddleware
|
||||
context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||
details = new()
|
||||
{
|
||||
Title = "Bad Request",
|
||||
Title = "Bad Procedure",
|
||||
Detail = badRequestEx.Message
|
||||
};
|
||||
break;
|
||||
@@ -106,6 +106,57 @@ public class ExceptionHandlingMiddleware
|
||||
};
|
||||
break;
|
||||
|
||||
case InsertObjectFailedException insertFailedEx:
|
||||
logger.LogError(
|
||||
insertFailedEx,
|
||||
"Insert operation failed during request processing. {procedure}",
|
||||
JsonSerializer.Serialize(
|
||||
insertFailedEx.Procedure,
|
||||
options: new() { WriteIndented = true }
|
||||
));
|
||||
|
||||
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||
details = new()
|
||||
{
|
||||
Title = "Insert Operation Failed",
|
||||
Detail = insertFailedEx.Message
|
||||
};
|
||||
break;
|
||||
|
||||
case UpdateObjectFailedException updateFailedEx:
|
||||
logger.LogError(
|
||||
updateFailedEx,
|
||||
"Update operation failed during request processing. {procedure}",
|
||||
JsonSerializer.Serialize(
|
||||
updateFailedEx.Procedure,
|
||||
options: new() { WriteIndented = true }
|
||||
));
|
||||
|
||||
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||
details = new()
|
||||
{
|
||||
Title = "Update Operation Failed",
|
||||
Detail = updateFailedEx.Message
|
||||
};
|
||||
break;
|
||||
|
||||
case DeleteObjectFailedException deleteFailedEx:
|
||||
logger.LogError(
|
||||
deleteFailedEx,
|
||||
"Delete operation failed during request processing. {procedure}",
|
||||
JsonSerializer.Serialize(
|
||||
deleteFailedEx.Procedure,
|
||||
options: new() { WriteIndented = true }
|
||||
));
|
||||
|
||||
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||
details = new()
|
||||
{
|
||||
Title = "Delete Operation Failed",
|
||||
Detail = deleteFailedEx.Message
|
||||
};
|
||||
break;
|
||||
|
||||
default:
|
||||
logger.LogError(exception, "Unhandled exception occurred.");
|
||||
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||
@@ -120,4 +171,4 @@ public class ExceptionHandlingMiddleware
|
||||
if (details is not null)
|
||||
await context.Response.WriteAsJsonAsync(details);
|
||||
}
|
||||
}
|
||||
}
|
||||
17
src/ReC.API/Models/ResultType.cs
Normal file
17
src/ReC.API/Models/ResultType.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace ReC.API.Models;
|
||||
|
||||
public enum ResultType
|
||||
{
|
||||
/// <summary>
|
||||
/// Return the full result object.
|
||||
/// </summary>
|
||||
Full,
|
||||
/// <summary>
|
||||
/// Return only the header part of the result.
|
||||
/// </summary>
|
||||
OnlyHeader,
|
||||
/// <summary>
|
||||
/// Return only the body part of the result.
|
||||
/// </summary>
|
||||
OnlyBody
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
using Microsoft.AspNetCore.Rewrite;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NLog;
|
||||
using NLog.Web;
|
||||
using ReC.API.Middleware;
|
||||
using ReC.Application;
|
||||
using ReC.Infrastructure;
|
||||
using System.Reflection;
|
||||
using LogLevel = Microsoft.Extensions.Logging.LogLevel;
|
||||
|
||||
var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
|
||||
@@ -23,6 +25,13 @@ try
|
||||
|
||||
var config = builder.Configuration;
|
||||
|
||||
Directory
|
||||
.GetFiles(builder.Environment.ContentRootPath, "appsettings.*.json", SearchOption.TopDirectoryOnly)
|
||||
.Where(file => Path.GetFileName(file) != $"appsettings.Development.json")
|
||||
.Where(file => Path.GetFileName(file) != $"appsettings.migration.json")
|
||||
.ToList()
|
||||
.ForEach(file => config.AddJsonFile(file, true, true));
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddRecServices(options =>
|
||||
{
|
||||
@@ -45,10 +54,18 @@ try
|
||||
});
|
||||
});
|
||||
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddControllers(options =>
|
||||
{
|
||||
options.Filters.Add<AuthScopedFilter>();
|
||||
});
|
||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen();
|
||||
builder.Services.AddSwaggerGen(c =>
|
||||
{
|
||||
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
||||
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
|
||||
c.IncludeXmlComments(xmlPath);
|
||||
});
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
@@ -57,10 +74,13 @@ try
|
||||
#pragma warning restore CS0618
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
if (app.Environment.IsDevelopment() || config.GetValue<bool>("UseSwagger"))
|
||||
{
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
|
||||
var rewriteOptions = new RewriteOptions().AddRedirect("^$", "swagger");
|
||||
app.UseRewriter(rewriteOptions);
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
@@ -10,13 +10,15 @@
|
||||
<Product>ReC.API</Product>
|
||||
<PackageIcon>Assets\icon.ico</PackageIcon>
|
||||
<PackageTags>digital data rest-caller rec api</PackageTags>
|
||||
<Version>1.0.0-beta</Version>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
<FileVersion>1.0.0.0</FileVersion>
|
||||
<InformationalVersion>1.0.0-beta</InformationalVersion>
|
||||
<Version>1.0.3-beta</Version>
|
||||
<AssemblyVersion>1.0.3.0</AssemblyVersion>
|
||||
<FileVersion>1.0.3.0</FileVersion>
|
||||
<InformationalVersion>1.0.3-beta</InformationalVersion>
|
||||
<Copyright>Copyright © 2025 Digital Data GmbH. All rights reserved.</Copyright>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<NoWarn>$(NoWarn);1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.11" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
|
||||
|
||||
59
src/ReC.API/appsettings.Logging.json
Normal file
59
src/ReC.API/appsettings.Logging.json
Normal file
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"NLog": {
|
||||
"throwConfigExceptions": true,
|
||||
"variables": {
|
||||
"logDirectory": "E:\\LogFiles\\Digital Data\\Rec.API",
|
||||
"logFileNamePrefix": "${shortdate}.Rec.API"
|
||||
},
|
||||
"targets": {
|
||||
"infoLogs": {
|
||||
"type": "File",
|
||||
"fileName": "${logDirectory}\\${logFileNamePrefix}-Info.log",
|
||||
"maxArchiveDays": 30
|
||||
},
|
||||
"warningLogs": {
|
||||
"type": "File",
|
||||
"fileName": "${logDirectory}\\${logFileNamePrefix}-Warning.log",
|
||||
"maxArchiveDays": 30
|
||||
},
|
||||
"errorLogs": {
|
||||
"type": "File",
|
||||
"fileName": "${logDirectory}\\${logFileNamePrefix}-Error.log",
|
||||
"maxArchiveDays": 30
|
||||
},
|
||||
"criticalLogs": {
|
||||
"type": "File",
|
||||
"fileName": "${logDirectory}\\${logFileNamePrefix}-Critical.log",
|
||||
"maxArchiveDays": 30
|
||||
}
|
||||
},
|
||||
"rules": [
|
||||
{
|
||||
"logger": "*",
|
||||
"level": "Info",
|
||||
"writeTo": "infoLogs"
|
||||
},
|
||||
{
|
||||
"logger": "*",
|
||||
"level": "Warn",
|
||||
"writeTo": "warningLogs"
|
||||
},
|
||||
{
|
||||
"logger": "*",
|
||||
"level": "Error",
|
||||
"writeTo": "errorLogs"
|
||||
},
|
||||
{
|
||||
"logger": "*",
|
||||
"level": "Fatal",
|
||||
"writeTo": "criticalLogs"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,5 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"UseSwagger": true,
|
||||
"ConnectionStrings": {
|
||||
"Default": "Server=SDD-VMP04-SQL19\\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=dd;Encrypt=false;TrustServerCertificate=True;"
|
||||
},
|
||||
@@ -14,56 +9,5 @@
|
||||
"MaxConcurrentInvocations": 5
|
||||
},
|
||||
"AddedWho": "ReC.API",
|
||||
"FakeProfileId": 2,
|
||||
"NLog": {
|
||||
"throwConfigExceptions": true,
|
||||
"variables": {
|
||||
"logDirectory": "E:\\LogFiles\\Digital Data\\Rec.API",
|
||||
"logFileNamePrefix": "${shortdate}.Rec.API"
|
||||
},
|
||||
"targets": {
|
||||
"infoLogs": {
|
||||
"type": "File",
|
||||
"fileName": "${logDirectory}\\${logFileNamePrefix}-Info.log",
|
||||
"maxArchiveDays": 30
|
||||
},
|
||||
"warningLogs": {
|
||||
"type": "File",
|
||||
"fileName": "${logDirectory}\\${logFileNamePrefix}-Warning.log",
|
||||
"maxArchiveDays": 30
|
||||
},
|
||||
"errorLogs": {
|
||||
"type": "File",
|
||||
"fileName": "${logDirectory}\\${logFileNamePrefix}-Error.log",
|
||||
"maxArchiveDays": 30
|
||||
},
|
||||
"criticalLogs": {
|
||||
"type": "File",
|
||||
"fileName": "${logDirectory}\\${logFileNamePrefix}-Critical.log",
|
||||
"maxArchiveDays": 30
|
||||
}
|
||||
},
|
||||
"rules": [
|
||||
{
|
||||
"logger": "*",
|
||||
"level": "Info",
|
||||
"writeTo": "infoLogs"
|
||||
},
|
||||
{
|
||||
"logger": "*",
|
||||
"level": "Warn",
|
||||
"writeTo": "warningLogs"
|
||||
},
|
||||
{
|
||||
"logger": "*",
|
||||
"level": "Error",
|
||||
"writeTo": "errorLogs"
|
||||
},
|
||||
{
|
||||
"logger": "*",
|
||||
"level": "Fatal",
|
||||
"writeTo": "criticalLogs"
|
||||
}
|
||||
]
|
||||
}
|
||||
"FakeProfileId": 2
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -1,30 +1,29 @@
|
||||
using FluentValidation;
|
||||
using MediatR;
|
||||
|
||||
namespace ReC.Application.Common.Behaviors
|
||||
namespace ReC.Application.Common.Behaviors;
|
||||
|
||||
public class ValidationBehavior<TRequest, TResponse>(IEnumerable<IValidator<TRequest>> validators) : IPipelineBehavior<TRequest, TResponse>
|
||||
where TRequest : notnull
|
||||
{
|
||||
public class ValidationBehavior<TRequest, TResponse>(IEnumerable<IValidator<TRequest>> validators) : IPipelineBehavior<TRequest, TResponse>
|
||||
where TRequest : notnull
|
||||
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancel)
|
||||
{
|
||||
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancel)
|
||||
if (validators.Any())
|
||||
{
|
||||
if (validators.Any())
|
||||
{
|
||||
var context = new ValidationContext<TRequest>(request);
|
||||
var context = new ValidationContext<TRequest>(request);
|
||||
|
||||
var validationResults = await Task.WhenAll(
|
||||
validators.Select(v =>
|
||||
v.ValidateAsync(context, cancel)));
|
||||
var validationResults = await Task.WhenAll(
|
||||
validators.Select(v =>
|
||||
v.ValidateAsync(context, cancel)));
|
||||
|
||||
var failures = validationResults
|
||||
.SelectMany(r => r.Errors)
|
||||
.Where(f => f != null)
|
||||
.ToList();
|
||||
var failures = validationResults
|
||||
.SelectMany(r => r.Errors)
|
||||
.Where(f => f != null)
|
||||
.ToList();
|
||||
|
||||
if (failures.Count != 0)
|
||||
throw new ValidationException(failures);
|
||||
}
|
||||
return await next(cancel);
|
||||
if (failures.Count != 0)
|
||||
throw new ValidationException(failures);
|
||||
}
|
||||
return await next(cancel);
|
||||
}
|
||||
}
|
||||
6
src/ReC.Application/Common/Constants/Http.cs
Normal file
6
src/ReC.Application/Common/Constants/Http.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace ReC.Application.Common.Constants;
|
||||
|
||||
public static class Http
|
||||
{
|
||||
public static readonly string ClientName = "HttpClient-" + Guid.NewGuid().ToString();
|
||||
}
|
||||
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; }
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using ReC.Domain.Entities;
|
||||
using ReC.Domain.Views;
|
||||
|
||||
namespace ReC.Application.Common.Dto;
|
||||
|
||||
@@ -6,7 +7,18 @@ 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<Domain.Entities.Profile, ProfileDto>();
|
||||
CreateMap<RecAction, RecActionDto>();
|
||||
|
||||
CreateMap<ResultView, ResultViewDto>();
|
||||
CreateMap<ProfileView, ProfileViewDto>();
|
||||
}
|
||||
}
|
||||
|
||||
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; }
|
||||
}
|
||||
42
src/ReC.Application/Common/Dto/ProfileViewDto.cs
Normal file
42
src/ReC.Application/Common/Dto/ProfileViewDto.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
namespace ReC.Application.Common.Dto;
|
||||
|
||||
public class ProfileViewDto
|
||||
{
|
||||
public long Id { get; init; }
|
||||
|
||||
public IEnumerable<RecActionViewDto>? RecActions { get; set; }
|
||||
|
||||
public bool Active { get; init; }
|
||||
|
||||
public byte TypeId { get; init; }
|
||||
|
||||
public string? Type { get; init; }
|
||||
|
||||
public string? Mandantor { get; init; }
|
||||
|
||||
public string? ProfileName { get; init; }
|
||||
|
||||
public string? Description { get; init; }
|
||||
|
||||
public byte LogLevelId { get; init; }
|
||||
|
||||
public string? LogLevel { get; init; }
|
||||
|
||||
public short LanguageId { get; init; }
|
||||
|
||||
public string? Language { get; init; }
|
||||
|
||||
public string? AddedWho { get; init; }
|
||||
|
||||
public DateTime AddedWhen { get; init; }
|
||||
|
||||
public string? ChangedWho { get; init; }
|
||||
|
||||
public DateTime? ChangedWhen { get; init; }
|
||||
|
||||
public DateTime? FirstRun { get; init; }
|
||||
|
||||
public DateTime? LastRun { get; init; }
|
||||
|
||||
public string? LastResult { get; init; }
|
||||
}
|
||||
@@ -1,76 +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 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; }
|
||||
}
|
||||
88
src/ReC.Application/Common/Dto/RecActionViewDto.cs
Normal file
88
src/ReC.Application/Common/Dto/RecActionViewDto.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
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 ProfileType? ProfileType { get; init; }
|
||||
|
||||
public byte? Sequence { get; init; }
|
||||
|
||||
public long? EndpointId { get; init; }
|
||||
|
||||
public string? EndpointUri { get; init; }
|
||||
|
||||
public long? EndpointAuthId { get; init; }
|
||||
|
||||
public EndpointAuthType? EndpointAuthType { get; init; }
|
||||
|
||||
public string? EndpointAuthTypeName { get; init; }
|
||||
|
||||
public string? EndpointAuthApiKey { get; init; }
|
||||
|
||||
public string? EndpointAuthApiValue { get; init; }
|
||||
|
||||
public ApiKeyLocation? EndpointAuthApiKeyAddTo { get; init; }
|
||||
|
||||
public string? EndpointAuthApiKeyAddToName { 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 RestType? RestType { get; init; }
|
||||
|
||||
public string? RestTypeName { 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 string? ErrorActionName { get; init; }
|
||||
|
||||
public UriBuilder ToEndpointUriBuilder()
|
||||
{
|
||||
var builder = EndpointUri is null ? new UriBuilder() : new UriBuilder(EndpointUri);
|
||||
|
||||
builder.Port = -1;
|
||||
|
||||
if (ProfileType is ProfileType type)
|
||||
builder.Scheme = type.ToUriBuilderScheme();
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
34
src/ReC.Application/Common/Dto/ResultViewDto.cs
Normal file
34
src/ReC.Application/Common/Dto/ResultViewDto.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
namespace ReC.Application.Common.Dto;
|
||||
|
||||
public record ResultViewDto
|
||||
{
|
||||
public long Id { get; init; }
|
||||
|
||||
public OutResDto? Root { get; init; }
|
||||
|
||||
public long? ActionId { get; init; }
|
||||
|
||||
public RecActionViewDto? Action { get; init; }
|
||||
|
||||
public long? ProfileId { get; init; }
|
||||
|
||||
public ProfileViewDto? Profile { get; init; }
|
||||
|
||||
public string? ProfileName { get; init; }
|
||||
|
||||
public short? StatusCode { get; init; }
|
||||
|
||||
public string? StatusName { get; init; }
|
||||
|
||||
public string? Header { get; init; }
|
||||
|
||||
public string? Body { get; init; }
|
||||
|
||||
public string? AddedWho { get; init; }
|
||||
|
||||
public DateTime? AddedWhen { get; init; }
|
||||
|
||||
public string? ChangedWho { get; init; }
|
||||
|
||||
public DateTime? ChangedWhen { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using ReC.Application.Common.Procedures.DeleteProcedure;
|
||||
|
||||
namespace ReC.Application.Common.Exceptions;
|
||||
|
||||
public class DeleteObjectFailedException : Exception
|
||||
{
|
||||
public DeleteObjectProcedure Procedure { get; }
|
||||
|
||||
public DeleteObjectFailedException(DeleteObjectProcedure procedure) : base()
|
||||
{
|
||||
Procedure = procedure;
|
||||
}
|
||||
|
||||
public DeleteObjectFailedException(DeleteObjectProcedure procedure, string? message) : base(message)
|
||||
{
|
||||
Procedure = procedure;
|
||||
}
|
||||
|
||||
public DeleteObjectFailedException(DeleteObjectProcedure procedure, string? message, Exception? innerException) : base(message, innerException)
|
||||
{
|
||||
Procedure = procedure;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using ReC.Application.Common.Procedures.InsertProcedure;
|
||||
|
||||
namespace ReC.Application.Common.Exceptions;
|
||||
|
||||
public class InsertObjectFailedException : Exception
|
||||
{
|
||||
public InsertObjectProcedure Procedure { get; }
|
||||
|
||||
public InsertObjectFailedException(InsertObjectProcedure procedure) : base()
|
||||
{
|
||||
Procedure = procedure;
|
||||
}
|
||||
|
||||
public InsertObjectFailedException(InsertObjectProcedure procedure, string? message) : base(message)
|
||||
{
|
||||
Procedure = procedure;
|
||||
}
|
||||
|
||||
public InsertObjectFailedException(InsertObjectProcedure procedure, string? message, Exception? innerException) : base(message, innerException)
|
||||
{
|
||||
Procedure = procedure;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using ReC.Application.Common.Procedures.UpdateProcedure;
|
||||
|
||||
namespace ReC.Application.Common.Exceptions;
|
||||
|
||||
public class UpdateObjectFailedException : Exception
|
||||
{
|
||||
public UpdateObjectProcedure Procedure { get; }
|
||||
|
||||
public UpdateObjectFailedException(UpdateObjectProcedure procedure) : base()
|
||||
{
|
||||
Procedure = procedure;
|
||||
}
|
||||
|
||||
public UpdateObjectFailedException(UpdateObjectProcedure procedure, string? message) : base(message)
|
||||
{
|
||||
Procedure = procedure;
|
||||
}
|
||||
|
||||
public UpdateObjectFailedException(UpdateObjectProcedure procedure, string? message, Exception? innerException) : base(message, innerException)
|
||||
{
|
||||
Procedure = procedure;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,28 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using ReC.Domain.Constants;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace ReC.Application.Common;
|
||||
|
||||
public static class HttpExtensions
|
||||
{
|
||||
private static readonly Dictionary<string, HttpMethod> _methods = new(StringComparer.OrdinalIgnoreCase)
|
||||
private static readonly Dictionary<RestType, HttpMethod> _methods = new()
|
||||
{
|
||||
["GET"] = HttpMethod.Get,
|
||||
["POST"] = HttpMethod.Post,
|
||||
["PUT"] = HttpMethod.Put,
|
||||
["DELETE"] = HttpMethod.Delete,
|
||||
["PATCH"] = HttpMethod.Patch,
|
||||
["HEAD"] = HttpMethod.Head,
|
||||
["OPTIONS"] = HttpMethod.Options,
|
||||
["TRACE"] = HttpMethod.Trace,
|
||||
["CONNECT"] = HttpMethod.Connect
|
||||
[RestType.Get] = HttpMethod.Get,
|
||||
[RestType.Post] = HttpMethod.Post,
|
||||
[RestType.Put] = HttpMethod.Put,
|
||||
[RestType.Delete] = HttpMethod.Delete,
|
||||
[RestType.Patch] = HttpMethod.Patch,
|
||||
[RestType.Head] = HttpMethod.Head,
|
||||
[RestType.Options] = HttpMethod.Options,
|
||||
[RestType.Trace] = HttpMethod.Trace,
|
||||
[RestType.Connect] = HttpMethod.Connect
|
||||
};
|
||||
|
||||
public static HttpMethod ToHttpMethod(this string method) => _methods.TryGetValue(method, out var httpMethod)
|
||||
? httpMethod
|
||||
: new HttpMethod(method);
|
||||
public static HttpMethod ToHttpMethod(this RestType method) => !method.IsValid()
|
||||
? throw new ArgumentOutOfRangeException(nameof(method), $"The RestType value '{method}' is not valid.")
|
||||
: _methods.TryGetValue(method, out var httpMethod)
|
||||
? httpMethod
|
||||
: new HttpMethod(method.ToHttpMethodName());
|
||||
|
||||
public static HttpRequestMessage ToHttpRequestMessage(this HttpMethod method, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri)
|
||||
=> new(method, requestUri);
|
||||
|
||||
13
src/ReC.Application/Common/Interfaces/IAuthScoped.cs
Normal file
13
src/ReC.Application/Common/Interfaces/IAuthScoped.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ReC.Application.Common.Interfaces;
|
||||
|
||||
public record AuthScope
|
||||
{
|
||||
public string? AddedWho { get; set; }
|
||||
}
|
||||
|
||||
public interface IAuthScoped : IScoped<AuthScope>
|
||||
{
|
||||
public string? AddedWho => Scope.AddedWho;
|
||||
}
|
||||
@@ -1,19 +1,46 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ReC.Domain.Entities;
|
||||
using ReC.Domain.QueryOutput;
|
||||
using ReC.Domain.Views;
|
||||
|
||||
namespace ReC.Application.Common.Interfaces;
|
||||
|
||||
public interface IRecDbContext
|
||||
{
|
||||
public DbSet<EndpointParam> EndpointParams { get; }
|
||||
#region DbSets
|
||||
[Obsolete("Use Views instead.")]
|
||||
public DbSet<EndpointParam> EndpointParams { get; set; }
|
||||
|
||||
public DbSet<RecActionView> Actions { get; }
|
||||
public DbSet<RecActionView> RecActionViews { get; set; }
|
||||
|
||||
public DbSet<OutRes> OutRes { get; }
|
||||
public DbSet<ProfileView> ProfileViews { get; set; }
|
||||
|
||||
public DbSet<HeaderQueryResult> HeaderQueryResults { get; }
|
||||
public DbSet<ResultView> RecResultViews { get; set; }
|
||||
|
||||
public DbSet<BodyQueryResult> BodyQueryResults { get; }
|
||||
[Obsolete("Use Views instead.")]
|
||||
public DbSet<OutRes> OutRes { get; set; }
|
||||
|
||||
public DbSet<HeaderQueryResult> HeaderQueryResults { get; set; }
|
||||
|
||||
public DbSet<BodyQueryResult> BodyQueryResults { get; set; }
|
||||
|
||||
[Obsolete("Use Views instead.")]
|
||||
public DbSet<Connection> Connections { get; set; }
|
||||
|
||||
[Obsolete("Use Views instead.")]
|
||||
public DbSet<Endpoint> Endpoints { get; set; }
|
||||
|
||||
[Obsolete("Use Views instead.")]
|
||||
public DbSet<EndpointAuth> EndpointAuths { get; set; }
|
||||
|
||||
[Obsolete("Use Views instead.")]
|
||||
public DbSet<Domain.Entities.Profile> Profiles { get; set; }
|
||||
|
||||
[Obsolete("Use Views instead.")]
|
||||
public DbSet<RecAction> RecActions { get; set; }
|
||||
|
||||
public DbSet<InsertObjectResult> RecResults { get; set; }
|
||||
#endregion DbSets
|
||||
|
||||
public Task<int> SaveChangesAsync(CancellationToken cancel = default);
|
||||
}
|
||||
10
src/ReC.Application/Common/Interfaces/IScoped.cs
Normal file
10
src/ReC.Application/Common/Interfaces/IScoped.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using MediatR;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ReC.Application.Common.Interfaces;
|
||||
|
||||
public interface IScoped<TScope> where TScope : notnull
|
||||
{
|
||||
[JsonIgnore]
|
||||
public TScope Scope { get; }
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
namespace ReC.Application.Common.Procedures.DeleteProcedure;
|
||||
|
||||
public record DeleteActionProcedure : IDeleteProcedure
|
||||
{
|
||||
/// <summary>
|
||||
/// Start GUID/ID (inclusive)
|
||||
/// </summary>
|
||||
public long Start { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// End GUID/ID (inclusive). If 0, will be set to Start value.
|
||||
/// </summary>
|
||||
public long End { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, delete even if dependent RESULT data exists
|
||||
/// </summary>
|
||||
public bool Force { get; set; }
|
||||
|
||||
public DeleteObjectProcedure ToObjectProcedure()
|
||||
{
|
||||
return new DeleteObjectProcedure
|
||||
{
|
||||
Entity = "ACTION",
|
||||
Start = Start,
|
||||
End = End,
|
||||
Force = Force
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
namespace ReC.Application.Common.Procedures.DeleteProcedure;
|
||||
|
||||
public record DeleteEndpointAuthProcedure : IDeleteProcedure
|
||||
{
|
||||
/// <summary>
|
||||
/// Start GUID/ID (inclusive)
|
||||
/// </summary>
|
||||
public long Start { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// End GUID/ID (inclusive). If 0, will be set to Start value.
|
||||
/// </summary>
|
||||
public long End { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, delete even if dependent ACTION data exists
|
||||
/// </summary>
|
||||
public bool Force { get; set; }
|
||||
|
||||
public DeleteObjectProcedure ToObjectProcedure()
|
||||
{
|
||||
return new DeleteObjectProcedure
|
||||
{
|
||||
Entity = "ENDPOINT_AUTH",
|
||||
Start = Start,
|
||||
End = End,
|
||||
Force = Force
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
namespace ReC.Application.Common.Procedures.DeleteProcedure;
|
||||
|
||||
public record DeleteEndpointParamsProcedure : IDeleteProcedure
|
||||
{
|
||||
/// <summary>
|
||||
/// Start GUID/ID (inclusive)
|
||||
/// </summary>
|
||||
public long Start { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// End GUID/ID (inclusive). If 0, will be set to Start value.
|
||||
/// </summary>
|
||||
public long End { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, delete even if dependent ACTION data exists
|
||||
/// </summary>
|
||||
public bool Force { get; set; }
|
||||
|
||||
public DeleteObjectProcedure ToObjectProcedure()
|
||||
{
|
||||
return new DeleteObjectProcedure
|
||||
{
|
||||
Entity = "ENDPOINT_PARAMS",
|
||||
Start = Start,
|
||||
End = End,
|
||||
Force = Force
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
namespace ReC.Application.Common.Procedures.DeleteProcedure;
|
||||
|
||||
public record DeleteEndpointProcedure : IDeleteProcedure
|
||||
{
|
||||
/// <summary>
|
||||
/// Start GUID/ID (inclusive)
|
||||
/// </summary>
|
||||
public long Start { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// End GUID/ID (inclusive). If 0, will be set to Start value.
|
||||
/// </summary>
|
||||
public long End { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, delete even if dependent ACTION data exists
|
||||
/// </summary>
|
||||
public bool Force { get; set; }
|
||||
|
||||
public DeleteObjectProcedure ToObjectProcedure()
|
||||
{
|
||||
return new DeleteObjectProcedure
|
||||
{
|
||||
Entity = "ENDPOINT",
|
||||
Start = Start,
|
||||
End = End,
|
||||
Force = Force
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using MediatR;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using ReC.Application.Common.Exceptions;
|
||||
|
||||
namespace ReC.Application.Common.Procedures.DeleteProcedure;
|
||||
|
||||
public record DeleteObjectProcedure : IRequest<int>
|
||||
{
|
||||
/// <summary>
|
||||
/// Target entity: ACTION, ENDPOINT, ENDPOINT_AUTH, ENDPOINT_PARAMS, PROFILE, RESULT
|
||||
/// </summary>
|
||||
public string Entity { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Start GUID/ID (inclusive)
|
||||
/// </summary>
|
||||
public long Start { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// End GUID/ID (inclusive). If 0, will be set to Start value.
|
||||
/// </summary>
|
||||
public long End { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, delete even if dependent data exists
|
||||
/// </summary>
|
||||
public bool Force { get; set; }
|
||||
}
|
||||
|
||||
public static class DeleteObjectProcedureExtensions
|
||||
{
|
||||
public static Task<int> ExecuteDeleteProcedure(this ISender sender, IDeleteProcedure procedure, CancellationToken cancel = default)
|
||||
{
|
||||
return sender.Send(procedure.ToObjectProcedure(), cancel);
|
||||
}
|
||||
|
||||
public static Task<int> ExecuteDeleteProcedure(this ISender sender, string entity, long start, long end = 0, bool force = false, CancellationToken cancel = default)
|
||||
{
|
||||
return sender.Send(new DeleteObjectProcedure
|
||||
{
|
||||
Entity = entity,
|
||||
Start = start,
|
||||
End = end,
|
||||
Force = force
|
||||
}, cancel);
|
||||
}
|
||||
}
|
||||
|
||||
public class DeleteObjectProcedureHandler(IRepository repo) : IRequestHandler<DeleteObjectProcedure, int>
|
||||
{
|
||||
public async Task<int> Handle(DeleteObjectProcedure request, CancellationToken cancel)
|
||||
{
|
||||
var parameters = new[]
|
||||
{
|
||||
new SqlParameter("@pENTITY", request.Entity ?? (object)DBNull.Value),
|
||||
new SqlParameter("@pSTART", request.Start.ToString()),
|
||||
new SqlParameter("@pEND", request.End.ToString()),
|
||||
new SqlParameter("@pFORCE", (object?)request.Force ?? DBNull.Value)
|
||||
};
|
||||
|
||||
var result = await repo.ExecuteQueryRawAsync(
|
||||
"EXEC @RC = [dbo].[PRREC_DELETE_OBJECT] " +
|
||||
"@pENTITY, @pSTART, @pEND, @pFORCE; " +
|
||||
"SELECT @RC;",
|
||||
parameters,
|
||||
cancel);
|
||||
|
||||
// The stored procedure returns 0 on success, error codes > 0 on failure
|
||||
if (result > 0)
|
||||
{
|
||||
throw new DeleteObjectFailedException(request, $"DeleteObject stored procedure failed with error code: {result}");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
namespace ReC.Application.Common.Procedures.DeleteProcedure;
|
||||
|
||||
public record DeleteProfileProcedure : IDeleteProcedure
|
||||
{
|
||||
/// <summary>
|
||||
/// Start GUID/ID (inclusive)
|
||||
/// </summary>
|
||||
public long Start { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// End GUID/ID (inclusive). If 0, will be set to Start value.
|
||||
/// </summary>
|
||||
public long End { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, delete even if dependent ACTION data exists
|
||||
/// </summary>
|
||||
public bool Force { get; set; }
|
||||
|
||||
public DeleteObjectProcedure ToObjectProcedure()
|
||||
{
|
||||
return new DeleteObjectProcedure
|
||||
{
|
||||
Entity = "PROFILE",
|
||||
Start = Start,
|
||||
End = End,
|
||||
Force = Force
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
namespace ReC.Application.Common.Procedures.DeleteProcedure;
|
||||
|
||||
public record DeleteResultProcedure : IDeleteProcedure
|
||||
{
|
||||
/// <summary>
|
||||
/// Start GUID/ID (inclusive)
|
||||
/// </summary>
|
||||
public long Start { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// End GUID/ID (inclusive). If 0, will be set to Start value.
|
||||
/// </summary>
|
||||
public long End { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Force parameter (not used for RESULT entity as it has no dependencies)
|
||||
/// </summary>
|
||||
public bool Force { get; set; }
|
||||
|
||||
public DeleteObjectProcedure ToObjectProcedure()
|
||||
{
|
||||
return new DeleteObjectProcedure
|
||||
{
|
||||
Entity = "RESULT",
|
||||
Start = Start,
|
||||
End = End,
|
||||
Force = Force
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace ReC.Application.Common.Procedures.DeleteProcedure;
|
||||
|
||||
public interface IDeleteProcedure
|
||||
{
|
||||
public DeleteObjectProcedure ToObjectProcedure();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace ReC.Application.Common.Procedures.InsertProcedure;
|
||||
|
||||
public interface IInsertProcedure
|
||||
{
|
||||
public InsertObjectProcedure ToObjectProcedure(string? addedWho = null);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
namespace ReC.Application.Common.Procedures.InsertProcedure;
|
||||
|
||||
public record InsertActionProcedure : IInsertProcedure
|
||||
{
|
||||
public long? ProfileId { get; set; }
|
||||
public bool? Active { get; set; }
|
||||
public byte? Sequence { get; set; }
|
||||
public long? EndpointId { get; set; }
|
||||
public long? EndpointAuthId { get; set; }
|
||||
public short? EndpointParamsId { get; set; }
|
||||
public short? SqlConnectionId { get; set; }
|
||||
public byte? TypeId { get; set; }
|
||||
public string? PreSql { get; set; }
|
||||
public string? HeaderSql { get; set; }
|
||||
public string? BodySql { get; set; }
|
||||
public string? PostSql { get; set; }
|
||||
public byte? ErrorActionId { get; set; }
|
||||
|
||||
public InsertObjectProcedure ToObjectProcedure(string? addedWho = null)
|
||||
{
|
||||
return new InsertObjectProcedure
|
||||
{
|
||||
Entity = "ACTION",
|
||||
Action = this
|
||||
}.AddedBy(addedWho);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
namespace ReC.Application.Common.Procedures.InsertProcedure;
|
||||
|
||||
public record InsertEndpointAuthProcedure : IInsertProcedure
|
||||
{
|
||||
public bool? Active { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public byte? TypeId { get; set; }
|
||||
public string? ApiKey { get; set; }
|
||||
public string? ApiValue { get; set; }
|
||||
public bool? ApiKeyAddToId { 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 InsertObjectProcedure ToObjectProcedure(string? addedWho = null)
|
||||
{
|
||||
return new InsertObjectProcedure
|
||||
{
|
||||
Entity = "ENDPOINT_AUTH",
|
||||
EndpointAuth = this
|
||||
}.AddedBy(addedWho);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
namespace ReC.Application.Common.Procedures.InsertProcedure;
|
||||
|
||||
public record InsertEndpointParamsProcedure : IInsertProcedure
|
||||
{
|
||||
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 InsertObjectProcedure ToObjectProcedure(string? addedWho = null)
|
||||
{
|
||||
return new InsertObjectProcedure
|
||||
{
|
||||
Entity = "ENDPOINT_PARAMS",
|
||||
EndpointParams = this
|
||||
}.AddedBy(addedWho);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace ReC.Application.Common.Procedures.InsertProcedure;
|
||||
|
||||
public record InsertEndpointProcedure : IInsertProcedure
|
||||
{
|
||||
public bool? Active { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public string? Uri { get; set; }
|
||||
|
||||
public InsertObjectProcedure ToObjectProcedure(string? addedWho = null)
|
||||
{
|
||||
return new InsertObjectProcedure
|
||||
{
|
||||
Entity = "ENDPOINT",
|
||||
Endpoint = this
|
||||
}.AddedBy(addedWho);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using MediatR;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using ReC.Application.Common.Exceptions;
|
||||
|
||||
namespace ReC.Application.Common.Procedures.InsertProcedure;
|
||||
|
||||
public record InsertObjectProcedure : IRequest<long>
|
||||
{
|
||||
/// <summary>
|
||||
/// Target entity: ACTION, ENDPOINT, ENDPOINT_AUTH, ENDPOINT_PARAMS, PROFILE, RESULT
|
||||
/// </summary>
|
||||
public string Entity { get; set; } = null!;
|
||||
|
||||
internal string? AddedWho { get; private set; }
|
||||
|
||||
public InsertObjectProcedure AddedBy(string? addedWho = null)
|
||||
{
|
||||
AddedWho = addedWho ?? "ReC.API";
|
||||
return this;
|
||||
}
|
||||
|
||||
public InsertActionProcedure Action { get; set; } = new();
|
||||
public InsertEndpointProcedure Endpoint { get; set; } = new();
|
||||
public InsertEndpointAuthProcedure EndpointAuth { get; set; } = new();
|
||||
public InsertProfileProcedure Profile { get; set; } = new();
|
||||
public InsertResultProcedure Result { get; set; } = new();
|
||||
public InsertEndpointParamsProcedure EndpointParams { get; set; } = new();
|
||||
}
|
||||
|
||||
public static class InsertObjectProcedureExtensions
|
||||
{
|
||||
public static Task<long> ExecuteInsertProcedure(this ISender sender, IInsertProcedure procedure, string? addedWho = null, CancellationToken cancel = default)
|
||||
{
|
||||
return sender.Send(procedure.ToObjectProcedure(addedWho ?? "Rec.API"), cancel);
|
||||
}
|
||||
}
|
||||
|
||||
public class InsertObjectProcedureHandler(IRepository repo) : IRequestHandler<InsertObjectProcedure, long>
|
||||
{
|
||||
public async Task<long> Handle(InsertObjectProcedure request, CancellationToken cancel)
|
||||
{
|
||||
var parameters = new[]
|
||||
{
|
||||
new SqlParameter("@pENTITY", request.Entity ?? (object)DBNull.Value),
|
||||
|
||||
new SqlParameter("@pADDED_WHO", (object?)request.AddedWho ?? DBNull.Value),
|
||||
new SqlParameter("@pADDED_WHEN", (object?)DateTime.UtcNow ?? DBNull.Value),
|
||||
|
||||
new SqlParameter("@pACTION_PROFILE_ID", (object?)request.Action.ProfileId ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_ACTIVE", (object?)request.Action.Active ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_SEQUENCE", (object?)request.Action.Sequence ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_ENDPOINT_ID", (object?)request.Action.EndpointId ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_ENDPOINT_AUTH_ID", (object?)request.Action.EndpointAuthId ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_ENDPOINT_PARAMS_ID", (object?)request.Action.EndpointParamsId ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_SQL_CONNECTION_ID", (object?)request.Action.SqlConnectionId ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_TYPE_ID", (object?)request.Action.TypeId ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_PRE_SQL", (object?)request.Action.PreSql ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_HEADER_SQL", (object?)request.Action.HeaderSql ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_BODY_SQL", (object?)request.Action.BodySql ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_POST_SQL", (object?)request.Action.PostSql ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_ERROR_ACTION_ID", (object?)request.Action.ErrorActionId ?? DBNull.Value),
|
||||
|
||||
new SqlParameter("@pENDPOINT_ACTIVE", (object?)request.Endpoint.Active ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_DESCRIPTION", (object?)request.Endpoint.Description ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_URI", (object?)request.Endpoint.Uri ?? DBNull.Value),
|
||||
|
||||
new SqlParameter("@pENDPOINT_AUTH_ACTIVE", (object?)request.EndpointAuth.Active ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_AUTH_DESCRIPTION", (object?)request.EndpointAuth.Description ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_AUTH_TYPE_ID", (object?)request.EndpointAuth.TypeId ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_AUTH_API_KEY", (object?)request.EndpointAuth.ApiKey ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_AUTH_API_VALUE", (object?)request.EndpointAuth.ApiValue ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_AUTH_API_KEY_ADD_TO_ID", (object?)request.EndpointAuth.ApiKeyAddToId ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_AUTH_TOKEN", (object?)request.EndpointAuth.Token ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_AUTH_USERNAME", (object?)request.EndpointAuth.Username ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_AUTH_PASSWORD", (object?)request.EndpointAuth.Password ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_AUTH_DOMAIN", (object?)request.EndpointAuth.Domain ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_AUTH_WORKSTATION", (object?)request.EndpointAuth.Workstation ?? DBNull.Value),
|
||||
|
||||
new SqlParameter("@pPROFILE_ACTIVE", (object?)request.Profile.Active ?? DBNull.Value),
|
||||
new SqlParameter("@pPROFILE_TYPE_ID", (object?)request.Profile.TypeId ?? DBNull.Value),
|
||||
new SqlParameter("@pPROFILE_MANDANTOR", (object?)request.Profile.Mandantor ?? DBNull.Value),
|
||||
new SqlParameter("@pPROFILE_NAME", (object?)request.Profile.Name ?? DBNull.Value),
|
||||
new SqlParameter("@pPROFILE_DESCRIPTION", (object?)request.Profile.Description ?? DBNull.Value),
|
||||
new SqlParameter("@pPROFILE_LOG_LEVEL_ID", (object?)request.Profile.LogLevelId ?? DBNull.Value),
|
||||
new SqlParameter("@pPROFILE_LANGUAGE_ID", (object?)request.Profile.LanguageId ?? DBNull.Value),
|
||||
|
||||
new SqlParameter("@pRESULT_ACTION_ID", (object?)request.Result.ActionId ?? DBNull.Value),
|
||||
new SqlParameter("@pRESULT_STATUS_ID", (object?)request.Result.StatusId ?? DBNull.Value),
|
||||
new SqlParameter("@pRESULT_HEADER", (object?)request.Result.Header ?? DBNull.Value),
|
||||
new SqlParameter("@pRESULT_BODY", (object?)request.Result.Body ?? DBNull.Value),
|
||||
|
||||
new SqlParameter("@pENDPOINT_PARAMS_ACTIVE", (object?)request.EndpointParams.Active ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_PARAMS_DESCRIPTION", (object?)request.EndpointParams.Description ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_PARAMS_GROUP_ID", (object?)request.EndpointParams.GroupId ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_PARAMS_SEQUENCE", (object?)request.EndpointParams.Sequence ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_PARAMS_KEY", (object?)request.EndpointParams.Key ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_PARAMS_VALUE", (object?)request.EndpointParams.Value ?? DBNull.Value),
|
||||
|
||||
new SqlParameter
|
||||
{
|
||||
ParameterName = "@oGUID",
|
||||
SqlDbType = System.Data.SqlDbType.BigInt,
|
||||
Direction = System.Data.ParameterDirection.Output
|
||||
}
|
||||
};
|
||||
|
||||
await repo.ExecuteQueryRawAsync(
|
||||
"EXEC [dbo].[PRREC_INSERT_OBJECT] " +
|
||||
"@pENTITY, @pADDED_WHO, @pADDED_WHEN, " +
|
||||
"@pACTION_PROFILE_ID, @pACTION_ACTIVE, @pACTION_SEQUENCE, @pACTION_ENDPOINT_ID, @pACTION_ENDPOINT_AUTH_ID, @pACTION_ENDPOINT_PARAMS_ID, @pACTION_SQL_CONNECTION_ID, @pACTION_TYPE_ID, @pACTION_PRE_SQL, @pACTION_HEADER_SQL, @pACTION_BODY_SQL, @pACTION_POST_SQL, @pACTION_ERROR_ACTION_ID, " +
|
||||
"@pENDPOINT_ACTIVE, @pENDPOINT_DESCRIPTION, @pENDPOINT_URI, " +
|
||||
"@pENDPOINT_AUTH_ACTIVE, @pENDPOINT_AUTH_DESCRIPTION, @pENDPOINT_AUTH_TYPE_ID, @pENDPOINT_AUTH_API_KEY, @pENDPOINT_AUTH_API_VALUE, @pENDPOINT_AUTH_API_KEY_ADD_TO_ID, @pENDPOINT_AUTH_TOKEN, @pENDPOINT_AUTH_USERNAME, @pENDPOINT_AUTH_PASSWORD, @pENDPOINT_AUTH_DOMAIN, @pENDPOINT_AUTH_WORKSTATION, " +
|
||||
"@pPROFILE_ACTIVE, @pPROFILE_TYPE_ID, @pPROFILE_MANDANTOR, @pPROFILE_NAME, @pPROFILE_DESCRIPTION, @pPROFILE_LOG_LEVEL_ID, @pPROFILE_LANGUAGE_ID, " +
|
||||
"@pRESULT_ACTION_ID, @pRESULT_STATUS_ID, @pRESULT_HEADER, @pRESULT_BODY, " +
|
||||
"@pENDPOINT_PARAMS_ACTIVE, @pENDPOINT_PARAMS_DESCRIPTION, @pENDPOINT_PARAMS_GROUP_ID, @pENDPOINT_PARAMS_SEQUENCE, @pENDPOINT_PARAMS_KEY, @pENDPOINT_PARAMS_VALUE, " +
|
||||
"@oGUID OUTPUT",
|
||||
parameters,
|
||||
cancel);
|
||||
|
||||
var guidParam = parameters.Last();
|
||||
|
||||
if (guidParam.Value != DBNull.Value)
|
||||
if (guidParam.Value is long longValue)
|
||||
return longValue;
|
||||
else if (long.TryParse(guidParam.Value.ToString(), out var guid))
|
||||
return guid;
|
||||
|
||||
throw new InsertObjectFailedException(request, "InsertObject stored procedure did not return a valid identifier.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
namespace ReC.Application.Common.Procedures.InsertProcedure;
|
||||
|
||||
public record InsertProfileProcedure : IInsertProcedure
|
||||
{
|
||||
public bool? Active { get; set; }
|
||||
public byte? TypeId { get; set; }
|
||||
public string? Mandantor { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public byte? LogLevelId { get; set; }
|
||||
public short? LanguageId { get; set; }
|
||||
|
||||
public InsertObjectProcedure ToObjectProcedure(string? addedWho = null)
|
||||
{
|
||||
return new InsertObjectProcedure
|
||||
{
|
||||
Entity = "PROFILE",
|
||||
Profile = this
|
||||
}.AddedBy(addedWho);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace ReC.Application.Common.Procedures.InsertProcedure;
|
||||
|
||||
public record InsertResultProcedure : IInsertProcedure
|
||||
{
|
||||
public long? ActionId { get; set; }
|
||||
public short? StatusId { get; set; }
|
||||
public string? Header { get; set; }
|
||||
public string? Body { get; set; }
|
||||
|
||||
public InsertObjectProcedure ToObjectProcedure(string? addedWho = null)
|
||||
{
|
||||
return new InsertObjectProcedure
|
||||
{
|
||||
Entity = "RESULT",
|
||||
Result = this
|
||||
}.AddedBy(addedWho ?? "Rec.API");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace ReC.Application.Common.Procedures.UpdateProcedure;
|
||||
|
||||
public interface IUpdateProcedure
|
||||
{
|
||||
public UpdateObjectProcedure ToObjectProcedure(long guid, string? changedWho = null);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
namespace ReC.Application.Common.Procedures.UpdateProcedure;
|
||||
|
||||
public record UpdateActionProcedure : IUpdateProcedure
|
||||
{
|
||||
public long? ProfileId { get; set; }
|
||||
public bool? Active { get; set; }
|
||||
public byte? Sequence { get; set; }
|
||||
public long? EndpointId { get; set; }
|
||||
public long? EndpointAuthId { get; set; }
|
||||
public short? EndpointParamsId { get; set; }
|
||||
public short? SqlConnectionId { get; set; }
|
||||
public byte? TypeId { get; set; }
|
||||
public string? PreSql { get; set; }
|
||||
public string? HeaderSql { get; set; }
|
||||
public string? BodySql { get; set; }
|
||||
public string? PostSql { get; set; }
|
||||
public byte? ErrorActionId { get; set; }
|
||||
|
||||
public UpdateObjectProcedure ToObjectProcedure(long guid, string? changedWho = null)
|
||||
{
|
||||
return new UpdateObjectProcedure
|
||||
{
|
||||
Entity = "ACTION",
|
||||
Guid = guid,
|
||||
Action = this
|
||||
}.ChangedBy(changedWho);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
namespace ReC.Application.Common.Procedures.UpdateProcedure;
|
||||
|
||||
public record UpdateEndpointAuthProcedure : IUpdateProcedure
|
||||
{
|
||||
public bool? Active { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public byte? TypeId { get; set; }
|
||||
public string? ApiKey { get; set; }
|
||||
public string? ApiValue { get; set; }
|
||||
public bool? ApiKeyAddToId { 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 UpdateObjectProcedure ToObjectProcedure(long guid, string? changedWho = null)
|
||||
{
|
||||
return new UpdateObjectProcedure
|
||||
{
|
||||
Entity = "ENDPOINT_AUTH",
|
||||
Guid = guid,
|
||||
EndpointAuth = this
|
||||
}.ChangedBy(changedWho);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
namespace ReC.Application.Common.Procedures.UpdateProcedure;
|
||||
|
||||
public record UpdateEndpointParamsProcedure : IUpdateProcedure
|
||||
{
|
||||
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 UpdateObjectProcedure ToObjectProcedure(long guid, string? changedWho = null)
|
||||
{
|
||||
return new UpdateObjectProcedure
|
||||
{
|
||||
Entity = "ENDPOINT_PARAMS",
|
||||
Guid = guid,
|
||||
EndpointParams = this
|
||||
}.ChangedBy(changedWho);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace ReC.Application.Common.Procedures.UpdateProcedure;
|
||||
|
||||
public record UpdateEndpointProcedure : IUpdateProcedure
|
||||
{
|
||||
public bool? Active { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public string? Uri { get; set; }
|
||||
|
||||
public UpdateObjectProcedure ToObjectProcedure(long guid, string? changedWho = null)
|
||||
{
|
||||
return new UpdateObjectProcedure
|
||||
{
|
||||
Entity = "ENDPOINT",
|
||||
Guid = guid,
|
||||
Endpoint = this
|
||||
}.ChangedBy(changedWho);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using MediatR;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using ReC.Application.Common.Exceptions;
|
||||
|
||||
namespace ReC.Application.Common.Procedures.UpdateProcedure;
|
||||
|
||||
public record UpdateObjectProcedure : IRequest<int>
|
||||
{
|
||||
/// <summary>
|
||||
/// Target entity: ACTION, ENDPOINT, ENDPOINT_AUTH, ENDPOINT_PARAMS, PROFILE, RESULT
|
||||
/// </summary>
|
||||
public string Entity { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Target GUID to update (required)
|
||||
/// </summary>
|
||||
public long Guid { get; set; }
|
||||
|
||||
internal string? ChangedWho { get; private set; }
|
||||
|
||||
public UpdateObjectProcedure ChangedBy(string? changedWho = null)
|
||||
{
|
||||
ChangedWho = changedWho ?? "ReC.API";
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateActionProcedure Action { get; set; } = new();
|
||||
public UpdateEndpointProcedure Endpoint { get; set; } = new();
|
||||
public UpdateEndpointAuthProcedure EndpointAuth { get; set; } = new();
|
||||
public UpdateProfileProcedure Profile { get; set; } = new();
|
||||
public UpdateResultProcedure Result { get; set; } = new();
|
||||
public UpdateEndpointParamsProcedure EndpointParams { get; set; } = new();
|
||||
}
|
||||
|
||||
public static class UpdateObjectProcedureExtensions
|
||||
{
|
||||
public static Task<int> ExecuteUpdateProcedure(this ISender sender, IUpdateProcedure procedure, long guid, string? changedWho = null, CancellationToken cancel = default)
|
||||
{
|
||||
return sender.Send(procedure.ToObjectProcedure(guid, changedWho ?? "ReC.API"), cancel);
|
||||
}
|
||||
}
|
||||
|
||||
public class UpdateObjectProcedureHandler(IRepository repo) : IRequestHandler<UpdateObjectProcedure, int>
|
||||
{
|
||||
public async Task<int> Handle(UpdateObjectProcedure request, CancellationToken cancel)
|
||||
{
|
||||
var parameters = new[]
|
||||
{
|
||||
new SqlParameter("@pENTITY", request.Entity ?? (object)DBNull.Value),
|
||||
new SqlParameter("@pGUID", (object?)request.Guid ?? DBNull.Value),
|
||||
|
||||
new SqlParameter("@pCHANGED_WHO", (object?)request.ChangedWho ?? DBNull.Value),
|
||||
new SqlParameter("@pCHANGED_WHEN", (object?)DateTime.UtcNow ?? DBNull.Value),
|
||||
|
||||
new SqlParameter("@pACTION_PROFILE_ID", (object?)request.Action.ProfileId ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_ACTIVE", (object?)request.Action.Active ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_SEQUENCE", (object?)request.Action.Sequence ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_ENDPOINT_ID", (object?)request.Action.EndpointId ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_ENDPOINT_AUTH_ID", (object?)request.Action.EndpointAuthId ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_ENDPOINT_PARAMS_ID", (object?)request.Action.EndpointParamsId ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_SQL_CONNECTION_ID", (object?)request.Action.SqlConnectionId ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_TYPE_ID", (object?)request.Action.TypeId ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_PRE_SQL", (object?)request.Action.PreSql ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_HEADER_SQL", (object?)request.Action.HeaderSql ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_BODY_SQL", (object?)request.Action.BodySql ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_POST_SQL", (object?)request.Action.PostSql ?? DBNull.Value),
|
||||
new SqlParameter("@pACTION_ERROR_ACTION_ID", (object?)request.Action.ErrorActionId ?? DBNull.Value),
|
||||
|
||||
new SqlParameter("@pENDPOINT_ACTIVE", (object?)request.Endpoint.Active ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_DESCRIPTION", (object?)request.Endpoint.Description ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_URI", (object?)request.Endpoint.Uri ?? DBNull.Value),
|
||||
|
||||
new SqlParameter("@pENDPOINT_AUTH_ACTIVE", (object?)request.EndpointAuth.Active ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_AUTH_DESCRIPTION", (object?)request.EndpointAuth.Description ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_AUTH_TYPE_ID", (object?)request.EndpointAuth.TypeId ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_AUTH_API_KEY", (object?)request.EndpointAuth.ApiKey ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_AUTH_API_VALUE", (object?)request.EndpointAuth.ApiValue ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_AUTH_API_KEY_ADD_TO_ID", (object?)request.EndpointAuth.ApiKeyAddToId ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_AUTH_TOKEN", (object?)request.EndpointAuth.Token ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_AUTH_USERNAME", (object?)request.EndpointAuth.Username ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_AUTH_PASSWORD", (object?)request.EndpointAuth.Password ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_AUTH_DOMAIN", (object?)request.EndpointAuth.Domain ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_AUTH_WORKSTATION", (object?)request.EndpointAuth.Workstation ?? DBNull.Value),
|
||||
|
||||
new SqlParameter("@pENDPOINT_PARAMS_ACTIVE", (object?)request.EndpointParams.Active ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_PARAMS_DESCRIPTION", (object?)request.EndpointParams.Description ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_PARAMS_GROUP_ID", (object?)request.EndpointParams.GroupId ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_PARAMS_SEQUENCE", (object?)request.EndpointParams.Sequence ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_PARAMS_KEY", (object?)request.EndpointParams.Key ?? DBNull.Value),
|
||||
new SqlParameter("@pENDPOINT_PARAMS_VALUE", (object?)request.EndpointParams.Value ?? DBNull.Value),
|
||||
|
||||
new SqlParameter("@pPROFILE_ACTIVE", (object?)request.Profile.Active ?? DBNull.Value),
|
||||
new SqlParameter("@pPROFILE_TYPE_ID", (object?)request.Profile.TypeId ?? DBNull.Value),
|
||||
new SqlParameter("@pPROFILE_MANDANTOR", (object?)request.Profile.Mandantor ?? DBNull.Value),
|
||||
new SqlParameter("@pPROFILE_NAME", (object?)request.Profile.Name ?? DBNull.Value),
|
||||
new SqlParameter("@pPROFILE_DESCRIPTION", (object?)request.Profile.Description ?? DBNull.Value),
|
||||
new SqlParameter("@pPROFILE_LOG_LEVEL_ID", (object?)request.Profile.LogLevelId ?? DBNull.Value),
|
||||
new SqlParameter("@pPROFILE_LANGUAGE_ID", (object?)request.Profile.LanguageId ?? DBNull.Value),
|
||||
new SqlParameter("@pPROFILE_FIRST_RUN", (object?)request.Profile.FirstRun ?? DBNull.Value),
|
||||
new SqlParameter("@pPROFILE_LAST_RUN", (object?)request.Profile.LastRun ?? DBNull.Value),
|
||||
new SqlParameter("@pPROFILE_LAST_RESULT", (object?)request.Profile.LastResult ?? DBNull.Value),
|
||||
|
||||
new SqlParameter("@pRESULT_ACTION_ID", (object?)request.Result.ActionId ?? DBNull.Value),
|
||||
new SqlParameter("@pRESULT_STATUS_ID", (object?)request.Result.StatusId ?? DBNull.Value),
|
||||
new SqlParameter("@pRESULT_HEADER", (object?)request.Result.Header ?? DBNull.Value),
|
||||
new SqlParameter("@pRESULT_BODY", (object?)request.Result.Body ?? DBNull.Value)
|
||||
};
|
||||
|
||||
var result = await repo.ExecuteQueryRawAsync(
|
||||
"EXEC @RC = [dbo].[PRREC_UPDATE_OBJECT] " +
|
||||
"@pENTITY, @pGUID, @pCHANGED_WHO, @pCHANGED_WHEN, " +
|
||||
"@pACTION_PROFILE_ID, @pACTION_ACTIVE, @pACTION_SEQUENCE, @pACTION_ENDPOINT_ID, @pACTION_ENDPOINT_AUTH_ID, @pACTION_ENDPOINT_PARAMS_ID, @pACTION_SQL_CONNECTION_ID, @pACTION_TYPE_ID, @pACTION_PRE_SQL, @pACTION_HEADER_SQL, @pACTION_BODY_SQL, @pACTION_POST_SQL, @pACTION_ERROR_ACTION_ID, " +
|
||||
"@pENDPOINT_ACTIVE, @pENDPOINT_DESCRIPTION, @pENDPOINT_URI, " +
|
||||
"@pENDPOINT_AUTH_ACTIVE, @pENDPOINT_AUTH_DESCRIPTION, @pENDPOINT_AUTH_TYPE_ID, @pENDPOINT_AUTH_API_KEY, @pENDPOINT_AUTH_API_VALUE, @pENDPOINT_AUTH_API_KEY_ADD_TO_ID, @pENDPOINT_AUTH_TOKEN, @pENDPOINT_AUTH_USERNAME, @pENDPOINT_AUTH_PASSWORD, @pENDPOINT_AUTH_DOMAIN, @pENDPOINT_AUTH_WORKSTATION, " +
|
||||
"@pENDPOINT_PARAMS_ACTIVE, @pENDPOINT_PARAMS_DESCRIPTION, @pENDPOINT_PARAMS_GROUP_ID, @pENDPOINT_PARAMS_SEQUENCE, @pENDPOINT_PARAMS_KEY, @pENDPOINT_PARAMS_VALUE, " +
|
||||
"@pPROFILE_ACTIVE, @pPROFILE_TYPE_ID, @pPROFILE_MANDANTOR, @pPROFILE_NAME, @pPROFILE_DESCRIPTION, @pPROFILE_LOG_LEVEL_ID, @pPROFILE_LANGUAGE_ID, @pPROFILE_FIRST_RUN, @pPROFILE_LAST_RUN, @pPROFILE_LAST_RESULT, " +
|
||||
"@pRESULT_ACTION_ID, @pRESULT_STATUS_ID, @pRESULT_HEADER, @pRESULT_BODY; " +
|
||||
"SELECT @RC;",
|
||||
parameters,
|
||||
cancel);
|
||||
|
||||
// The stored procedure returns 0 on success, error codes > 0 on failure
|
||||
if (result > 0)
|
||||
{
|
||||
throw new UpdateObjectFailedException(request, $"UpdateObject stored procedure failed with error code: {result}");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
namespace ReC.Application.Common.Procedures.UpdateProcedure;
|
||||
|
||||
public record UpdateProfileProcedure : IUpdateProcedure
|
||||
{
|
||||
public bool? Active { get; set; }
|
||||
public byte? TypeId { get; set; }
|
||||
public string? Mandantor { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public byte? LogLevelId { get; set; }
|
||||
public short? LanguageId { get; set; }
|
||||
public DateTime? FirstRun { get; set; }
|
||||
public DateTime? LastRun { get; set; }
|
||||
public string? LastResult { get; set; }
|
||||
|
||||
public UpdateObjectProcedure ToObjectProcedure(long guid, string? changedWho = null)
|
||||
{
|
||||
return new UpdateObjectProcedure
|
||||
{
|
||||
Entity = "PROFILE",
|
||||
Guid = guid,
|
||||
Profile = this
|
||||
}.ChangedBy(changedWho);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace ReC.Application.Common.Procedures.UpdateProcedure;
|
||||
|
||||
public record UpdateResultProcedure : IUpdateProcedure
|
||||
{
|
||||
public long? ActionId { get; set; }
|
||||
public short? StatusId { get; set; }
|
||||
public string? Header { get; set; }
|
||||
public string? Body { get; set; }
|
||||
|
||||
public UpdateObjectProcedure ToObjectProcedure(long guid, string? changedWho = null)
|
||||
{
|
||||
return new UpdateObjectProcedure
|
||||
{
|
||||
Entity = "RESULT",
|
||||
Guid = guid,
|
||||
Result = this
|
||||
}.ChangedBy(changedWho);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using FluentValidation;
|
||||
using ReC.Application.Common.Interfaces;
|
||||
|
||||
namespace ReC.Application.Common.Validations;
|
||||
|
||||
public class AuthScopedValidator : AbstractValidator<IAuthScoped>
|
||||
{
|
||||
public AuthScopedValidator()
|
||||
{
|
||||
RuleFor(x => x.AddedWho)
|
||||
.NotEmpty()
|
||||
.WithMessage("The 'AddedWho' field is required. A missing value may indicate an API configuration issue. Please contact your system administrator for assistance.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
using FluentValidation;
|
||||
using ReC.Application.Common.Procedures.InsertProcedure;
|
||||
|
||||
namespace ReC.Application.Common.Validations;
|
||||
|
||||
public class InsertObjectProcedureValidator : AbstractValidator<InsertObjectProcedure>
|
||||
{
|
||||
public InsertObjectProcedureValidator()
|
||||
{
|
||||
// ENTITY must be one of the allowed values
|
||||
RuleFor(x => x.Entity)
|
||||
.NotEmpty()
|
||||
.Must(e => e is "ACTION" or "ENDPOINT" or "ENDPOINT_AUTH" or "ENDPOINT_PARAMS" or "PROFILE" or "RESULT")
|
||||
.WithMessage("ENTITY must be one of: ACTION, ENDPOINT, ENDPOINT_AUTH, ENDPOINT_PARAMS, PROFILE, RESULT.");
|
||||
|
||||
// ACTION validation
|
||||
When(x => x.Entity == "ACTION", () =>
|
||||
{
|
||||
RuleFor(x => x.Action.ProfileId)
|
||||
.NotNull()
|
||||
.WithMessage("ACTION requires ActionProfileId (maps to @pACTION_PROFILE_ID).");
|
||||
|
||||
RuleFor(x => x.Action.EndpointId)
|
||||
.NotNull()
|
||||
.WithMessage("ACTION requires ActionEndpointId (maps to @pACTION_ENDPOINT_ID).");
|
||||
});
|
||||
|
||||
// ENDPOINT validation
|
||||
When(x => x.Entity == "ENDPOINT", () =>
|
||||
{
|
||||
RuleFor(x => x.Endpoint.Uri)
|
||||
.NotEmpty()
|
||||
.WithMessage("ENDPOINT requires EndpointUri (maps to @pENDPOINT_URI).")
|
||||
.MaximumLength(2000);
|
||||
});
|
||||
|
||||
// PROFILE validation
|
||||
When(x => x.Entity == "PROFILE", () =>
|
||||
{
|
||||
RuleFor(x => x.Profile.Name)
|
||||
.NotEmpty()
|
||||
.WithMessage("PROFILE requires ProfileName (maps to @pPROFILE_NAME).")
|
||||
.MaximumLength(50);
|
||||
|
||||
RuleFor(x => x.Profile.Mandantor)
|
||||
.MaximumLength(50)
|
||||
.When(x => x.Profile.Mandantor != null);
|
||||
|
||||
RuleFor(x => x.Profile.Description)
|
||||
.MaximumLength(250)
|
||||
.When(x => x.Profile.Description != null);
|
||||
});
|
||||
|
||||
// RESULT validation
|
||||
When(x => x.Entity == "RESULT", () =>
|
||||
{
|
||||
RuleFor(x => x.Result.ActionId)
|
||||
.NotNull()
|
||||
.WithMessage("RESULT requires ResultActionId (maps to @pRESULT_ACTION_ID).");
|
||||
|
||||
RuleFor(x => x.Result.StatusId)
|
||||
.NotNull()
|
||||
.WithMessage("RESULT requires ResultStatusId (maps to @pRESULT_STATUS_ID).");
|
||||
});
|
||||
|
||||
// ENDPOINT_PARAMS validation
|
||||
When(x => x.Entity == "ENDPOINT_PARAMS", () =>
|
||||
{
|
||||
RuleFor(x => x.EndpointParams.GroupId)
|
||||
.NotNull()
|
||||
.WithMessage("ENDPOINT_PARAMS requires EndpointParamsGroupId (maps to @pENDPOINT_PARAMS_GROUP_ID).");
|
||||
});
|
||||
|
||||
// Simple length guards for some string fields (optional but cheap)
|
||||
RuleFor(x => x.AddedWho)
|
||||
.MaximumLength(50)
|
||||
.When(x => x.AddedWho != null);
|
||||
|
||||
RuleFor(x => x.Endpoint.Description)
|
||||
.MaximumLength(250)
|
||||
.When(x => x.Endpoint.Description != null);
|
||||
|
||||
RuleFor(x => x.EndpointAuth.Description)
|
||||
.MaximumLength(250)
|
||||
.When(x => x.EndpointAuth.Description != null);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
using MediatR;
|
||||
using FluentValidation;
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ReC.Application.Common.Behaviors;
|
||||
using ReC.Application.Common.Constants;
|
||||
using ReC.Application.Common.Options;
|
||||
using System.Reflection;
|
||||
using FluentValidation;
|
||||
|
||||
namespace ReC.Application;
|
||||
|
||||
@@ -35,7 +36,11 @@ public static class DependencyInjection
|
||||
cfg.LicenseKey = configOpt.LuckyPennySoftwareLicenseKey;
|
||||
});
|
||||
|
||||
services.AddHttpClient();
|
||||
services.AddHttpClient(Http.ClientName)
|
||||
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
|
||||
{
|
||||
UseDefaultCredentials = false
|
||||
});
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
@@ -1,25 +1,29 @@
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using AutoMapper;
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ReC.Application.Common.Dto;
|
||||
using ReC.Domain.Entities;
|
||||
|
||||
namespace ReC.Application.Endpoints.Commands;
|
||||
|
||||
public class ObtainEndpointCommand : IRequest<Endpoint>
|
||||
[Obsolete("Use the related procedure or view.")]
|
||||
public class ObtainEndpointCommand : IRequest<EndpointDto>
|
||||
{
|
||||
public string Uri { get; init; } = null!;
|
||||
}
|
||||
|
||||
public class ObtainEndpointCommandHandler(IRepository<Endpoint> repo) : IRequestHandler<ObtainEndpointCommand, Endpoint>
|
||||
[Obsolete("Use the related procedure or view.")]
|
||||
public class ObtainEndpointCommandHandler(IRepository<Endpoint> repo, IMapper mapper) : 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);
|
||||
|
||||
if (endpoint is not null)
|
||||
return endpoint;
|
||||
return mapper.Map<EndpointDto>(endpoint);
|
||||
|
||||
endpoint = await repo.CreateAsync(request, cancel);
|
||||
return endpoint;
|
||||
return mapper.Map<EndpointDto>(endpoint);
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,15 @@
|
||||
using ReC.Application.Endpoints.Commands;
|
||||
using ReC.Domain.Entities;
|
||||
using ReC.Application.Common.Dto;
|
||||
|
||||
namespace ReC.Application.Endpoints;
|
||||
|
||||
// TODO: update to inject AddedWho from the current host/user contex
|
||||
public class MappingProfile : AutoMapper.Profile
|
||||
{
|
||||
[Obsolete("Use the related procedure or view.")]
|
||||
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"));
|
||||
|
||||
@@ -4,10 +4,15 @@ using ReC.Domain.Entities;
|
||||
|
||||
namespace ReC.Application.OutResults.Commands;
|
||||
|
||||
[Obsolete("Use the related procedure or view.")]
|
||||
public class CreateOutResCommand : IRequest
|
||||
{
|
||||
public required long ActionId { get; set; }
|
||||
|
||||
public short? Status { get; set; }
|
||||
|
||||
public string? Message { get; set; }
|
||||
|
||||
public string? Header { get; set; }
|
||||
|
||||
public string? Body { get; set; }
|
||||
@@ -15,6 +20,7 @@ public class CreateOutResCommand : IRequest
|
||||
public string? AddedWho { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete("Use the related procedure or view.")]
|
||||
public class CreateOutResCommandHandler(IRepository<OutRes> repo) : IRequestHandler<CreateOutResCommand>
|
||||
{
|
||||
public Task Handle(CreateOutResCommand request, CancellationToken cancel)
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using MediatR;
|
||||
using ReC.Application.Common.Interfaces;
|
||||
using ReC.Domain.Views;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ReC.Application.OutResults.Commands;
|
||||
|
||||
[Obsolete("Use the related procedure or view.")]
|
||||
public class CreateResultViewCommand : IAuthScoped, IRequest
|
||||
{
|
||||
public required long ActionId { get; set; }
|
||||
|
||||
public required short StatusCode { get; set; }
|
||||
|
||||
public string? Header { get; set; }
|
||||
|
||||
public string? Body { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public AuthScope Scope { get; } = new();
|
||||
}
|
||||
|
||||
[Obsolete("Use the related procedure or view.")]
|
||||
public class CreateResultViewCommandHandler(IRepository<ResultView> repo) : IRequestHandler<CreateResultViewCommand>
|
||||
{
|
||||
public Task Handle(CreateResultViewCommand request, CancellationToken cancel) => repo.CreateAsync(request, cancel);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using MediatR;
|
||||
using ReC.Domain.Entities;
|
||||
|
||||
namespace ReC.Application.OutResults.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the command to delete output results based on specified criteria.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Deletion can be performed by providing either an <see cref="ActionId"/> or a <see cref="ProfileId"/>.
|
||||
/// At least one of these properties must be set for the operation to proceed.
|
||||
/// </remarks>
|
||||
[Obsolete("Use the related procedure or view.")]
|
||||
public record DeleteOutResCommand : IRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the unique identifier for the action whose output results should be deleted.
|
||||
/// </summary>
|
||||
public long? ActionId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique identifier for the profile whose associated action's output results should be deleted.
|
||||
/// </summary>
|
||||
public long? ProfileId { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the execution of the <see cref="DeleteOutResCommand"/>.
|
||||
/// </summary>
|
||||
[Obsolete("Use the related procedure or view.")]
|
||||
public class DeleteOutResCommandHandler(IRepository<OutRes> repo) : IRequestHandler<DeleteOutResCommand>
|
||||
{
|
||||
/// <summary>
|
||||
/// Processes the delete command by removing matching <see cref="OutRes"/> entities from the repository.
|
||||
/// </summary>
|
||||
/// <param name="request">The command containing the deletion criteria.</param>
|
||||
/// <param name="cancel">A cancellation token that can be used to cancel the work.</param>
|
||||
/// <returns>A task that represents the asynchronous delete operation.</returns>
|
||||
/// <remarks>
|
||||
/// The handler deletes records where <c>OutRes.ActionId</c> matches <see cref="DeleteOutResCommand.ActionId"/>
|
||||
/// or where the associated <c>Action.ProfileId</c> matches <see cref="DeleteOutResCommand.ProfileId"/>.
|
||||
/// </remarks>
|
||||
public Task Handle(DeleteOutResCommand request, CancellationToken cancel)
|
||||
{
|
||||
return repo.DeleteAsync(x => x.ActionId == request.ActionId || x.Action!.ProfileId == request.ProfileId, cancel);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using FluentValidation;
|
||||
|
||||
namespace ReC.Application.OutResults.Commands;
|
||||
|
||||
[Obsolete("Use the related procedure or view.")]
|
||||
public class DeleteOutResCommandValidator : AbstractValidator<DeleteOutResCommand>
|
||||
{
|
||||
public DeleteOutResCommandValidator()
|
||||
{
|
||||
RuleFor(x => x)
|
||||
.Must(x => x.ActionId.HasValue || x.ProfileId.HasValue)
|
||||
.WithMessage("At least one of ActionId or ProfileId must be provided.")
|
||||
.WithName("Identifier");
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,20 @@
|
||||
using ReC.Application.OutResults.Commands;
|
||||
using ReC.Domain.Entities;
|
||||
using ReC.Domain.Views;
|
||||
|
||||
namespace ReC.Application.OutResults;
|
||||
|
||||
// TODO: update to inject AddedWho from the current host/user contex
|
||||
public class MappingProfiles : AutoMapper.Profile
|
||||
{
|
||||
[Obsolete("Use the related procedure or view.")]
|
||||
public MappingProfiles()
|
||||
{
|
||||
CreateMap<CreateOutResCommand, OutRes>()
|
||||
.ForMember(e => e.AddedWhen, exp => exp.MapFrom(cmd => DateTime.UtcNow))
|
||||
.ForMember(e => e.AddedWho, exp => exp.MapFrom(cmd => "ReC.API"));
|
||||
|
||||
CreateMap<CreateResultViewCommand, ResultView>()
|
||||
.ForMember(e => e.AddedWhen, exp => exp.MapFrom(cmd => DateTime.UtcNow));
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ using ReC.Domain.Entities;
|
||||
|
||||
namespace ReC.Application.OutResults.Queries;
|
||||
|
||||
[Obsolete("Use the related procedure or view.")]
|
||||
public record ReadOutResQuery : IRequest<IEnumerable<OutResDto>>
|
||||
{
|
||||
public long? ProfileId { get; init; }
|
||||
@@ -15,6 +16,7 @@ public record ReadOutResQuery : IRequest<IEnumerable<OutResDto>>
|
||||
public long? ActionId { get; init; }
|
||||
}
|
||||
|
||||
[Obsolete("Use the related procedure or view.")]
|
||||
public class ReadOutResHandler(IRepository<OutRes> repo, IMapper mapper) : IRequestHandler<ReadOutResQuery, IEnumerable<OutResDto>>
|
||||
{
|
||||
public async Task<IEnumerable<OutResDto>> Handle(ReadOutResQuery request, CancellationToken cancel)
|
||||
|
||||
@@ -2,6 +2,7 @@ using FluentValidation;
|
||||
|
||||
namespace ReC.Application.OutResults.Queries;
|
||||
|
||||
[Obsolete("Use the related procedure or view.")]
|
||||
public class ReadOutResQueryValidator : AbstractValidator<ReadOutResQuery>
|
||||
{
|
||||
public ReadOutResQueryValidator()
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
using AutoMapper;
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using DigitalData.Core.Exceptions;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ReC.Application.Common.Dto;
|
||||
using ReC.Domain.Views;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace ReC.Application.OutResults.Queries;
|
||||
|
||||
public record ReadResultViewQuery : IRequest<IEnumerable<ResultViewDto>>
|
||||
{
|
||||
public long? Id { get; init; } = null;
|
||||
|
||||
public long? ActionId { get; init; } = null;
|
||||
|
||||
public long? ProfileId { get; init; } = null;
|
||||
}
|
||||
|
||||
public class ReadResultViewQueryHandler(IRepository<ResultView> repo, IMapper mapper) : IRequestHandler<ReadResultViewQuery, IEnumerable<ResultViewDto>>
|
||||
{
|
||||
public async Task<IEnumerable<ResultViewDto>> Handle(ReadResultViewQuery request, CancellationToken cancel)
|
||||
{
|
||||
var q = repo.Query;
|
||||
|
||||
if(request.Id is long id)
|
||||
q = q.Where(rv => rv.Id == id);
|
||||
|
||||
if(request.ActionId is long actionId)
|
||||
q = q.Where(rv => rv.ActionId == actionId);
|
||||
|
||||
if(request.ProfileId is long profileId)
|
||||
q = q.Where(rv => rv.ProfileId == profileId);
|
||||
|
||||
var entities = await q.ToListAsync(cancel);
|
||||
|
||||
if (entities.Count == 0)
|
||||
throw new NotFoundException($"No result views found for the given criteria. Criteria: {
|
||||
JsonSerializer.Serialize(request, options: new()
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
WriteIndented = true
|
||||
})}"
|
||||
);
|
||||
|
||||
return mapper.Map<IEnumerable<ResultViewDto>>(entities);
|
||||
}
|
||||
}
|
||||
36
src/ReC.Application/Profile/Queries/ReadProfileViewQuery.cs
Normal file
36
src/ReC.Application/Profile/Queries/ReadProfileViewQuery.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using AutoMapper;
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using DigitalData.Core.Exceptions;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ReC.Application.Common.Dto;
|
||||
using ReC.Domain.Views;
|
||||
|
||||
namespace ReC.Application.Profile.Queries;
|
||||
|
||||
public record ReadProfileViewQuery : IRequest<IEnumerable<ProfileViewDto>>
|
||||
{
|
||||
public long? Id { get; init; } = null;
|
||||
|
||||
public bool IncludeActions { get; init; } = true;
|
||||
}
|
||||
|
||||
public class ReadProfileViewQueryHandler(IRepository<ProfileView> repo, IMapper mapper)
|
||||
: IRequestHandler<ReadProfileViewQuery, IEnumerable<ProfileViewDto>>
|
||||
{
|
||||
public async Task<IEnumerable<ProfileViewDto>> Handle(ReadProfileViewQuery request, CancellationToken cancel)
|
||||
{
|
||||
var query = request.IncludeActions
|
||||
? repo.Query.Include(p => p.Actions)
|
||||
: repo.Query;
|
||||
|
||||
if (request.Id is long id)
|
||||
query = query.Where(p => p.Id == id);
|
||||
|
||||
var profiles = await query.ToListAsync(cancel);
|
||||
|
||||
return profiles is null || profiles.Count == 0
|
||||
? throw new NotFoundException($"Profile {request.Id} not found.")
|
||||
: mapper.Map<IEnumerable<ProfileViewDto>>(profiles);
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper" Version="15.1.0" />
|
||||
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.5.0" />
|
||||
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.6.0" />
|
||||
<PackageReference Include="DigitalData.Core.Application" Version="3.4.0" />
|
||||
<PackageReference Include="DigitalData.Core.Exceptions" Version="1.1.0" />
|
||||
<PackageReference Include="FluentValidation" Version="12.1.0" />
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using DigitalData.Core.Exceptions;
|
||||
using MediatR;
|
||||
using ReC.Application.Endpoints.Commands;
|
||||
using ReC.Domain.Entities;
|
||||
using ReC.Application.Endpoints.Commands;
|
||||
|
||||
namespace ReC.Application.RecActions.Commands;
|
||||
|
||||
[Obsolete("Use the related procedure or view.")]
|
||||
public record CreateRecActionCommand : IRequest
|
||||
{
|
||||
public long ProfileId { get; init; }
|
||||
@@ -27,6 +28,7 @@ public record CreateRecActionCommand : IRequest
|
||||
public long? EndpointAuthId { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete("Use the related procedure or view.")]
|
||||
public class CreateRecActionCommandHandler(ISender sender, IRepository<RecAction> repo) : IRequestHandler<CreateRecActionCommand>
|
||||
{
|
||||
public async Task Handle(CreateRecActionCommand request, CancellationToken cancel)
|
||||
|
||||
@@ -6,11 +6,13 @@ using ReC.Domain.Entities;
|
||||
|
||||
namespace ReC.Application.RecActions.Commands;
|
||||
|
||||
[Obsolete("Use the related procedure or view.")]
|
||||
public class DeleteRecActionsCommand : IRequest
|
||||
{
|
||||
public required long ProfileId { get; init; }
|
||||
}
|
||||
|
||||
[Obsolete("Use the related procedure or view.")]
|
||||
public class DeleteRecActionsCommandHandler(IRepository<RecAction> repo) : IRequestHandler<DeleteRecActionsCommand>
|
||||
{
|
||||
public async Task Handle(DeleteRecActionsCommand request, CancellationToken cancel)
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
using MediatR;
|
||||
using ReC.Application.RecActions.Queries;
|
||||
using ReC.Domain.Constants;
|
||||
|
||||
namespace ReC.Application.RecActions.Commands;
|
||||
|
||||
public record InvokeBatchRecActionViewsCommand : IRequest
|
||||
{
|
||||
public long ProfileId { get; init; }
|
||||
}
|
||||
|
||||
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(new ReadRecActionViewQuery() { ProfileId = request.ProfileId, 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
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, IServiceScopeFactory scopeFactory, IHttpClientFactory clientFactory, ILogger<InvokeRecActionsCommandHandler>? logger = null) : IRequestHandler<InvokeBatchRecActionsCommand>
|
||||
{
|
||||
public async Task Handle(InvokeBatchRecActionsCommand request, CancellationToken cancel)
|
||||
{
|
||||
var actions = await sender.Send(request.ToReadQuery(q => q.Invoked = false), cancel);
|
||||
|
||||
var http = clientFactory.CreateClient();
|
||||
|
||||
using var semaphore = new SemaphoreSlim(5);
|
||||
|
||||
var tasks = actions.Select(async action =>
|
||||
{
|
||||
await semaphore.WaitAsync(cancel);
|
||||
try
|
||||
{
|
||||
using var scope = scopeFactory.CreateScope();
|
||||
var sender = scope.ServiceProvider.GetRequiredService<ISender>();
|
||||
await sender.Send(action.ToInvokeCommand(), cancel);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
logger?.LogError(
|
||||
ex,
|
||||
"Error invoking Rec action. ProfileId: {ProfileId}, Id: {Id}",
|
||||
action.ProfileId,
|
||||
action.Id
|
||||
);
|
||||
}
|
||||
finally
|
||||
{
|
||||
semaphore.Release();
|
||||
}
|
||||
});
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using ReC.Application.Common;
|
||||
using ReC.Application.Common.Dto;
|
||||
using ReC.Application.Common.Exceptions;
|
||||
using ReC.Application.OutResults.Commands;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace ReC.Application.RecActions.Commands;
|
||||
|
||||
public record InvokeRecActionCommand : IRequest
|
||||
{
|
||||
public RecActionDto Action { get; set; } = null!;
|
||||
}
|
||||
|
||||
public static class InvokeRecActionCommandExtensions
|
||||
{
|
||||
public static InvokeRecActionCommand ToInvokeCommand(this RecActionDto dto) => new() { Action = dto };
|
||||
}
|
||||
|
||||
public class InvokeRecActionCommandHandler(
|
||||
ISender sender,
|
||||
IHttpClientFactory clientFactory,
|
||||
IConfiguration? config = null
|
||||
) : IRequestHandler<InvokeRecActionCommand>
|
||||
{
|
||||
public async Task Handle(InvokeRecActionCommand request, CancellationToken cancel)
|
||||
{
|
||||
var action = request.Action;
|
||||
using var http = clientFactory.CreateClient();
|
||||
|
||||
if (action.RestType is null)
|
||||
throw new DataIntegrityException(
|
||||
$"Rec action could not be invoked because the RestType value is null. " +
|
||||
$"ProfileId: {action.ProfileId}, " +
|
||||
$"Id: {action.Id}"
|
||||
);
|
||||
|
||||
using var httpReq = action.RestType
|
||||
.ToHttpMethod()
|
||||
.ToHttpRequestMessage(action.EndpointUri);
|
||||
|
||||
if(action.Body is not null)
|
||||
{
|
||||
using var reqBody = new StringContent(action.Body);
|
||||
httpReq.Content = reqBody;
|
||||
}
|
||||
|
||||
if (action.Headers is not null)
|
||||
foreach (var header in action.Headers)
|
||||
httpReq.Headers.Add(header.Key, header.Value);
|
||||
|
||||
using var response = await http.SendAsync(httpReq, cancel);
|
||||
var resBody = await response.Content.ReadAsStringAsync(cancel);
|
||||
var resHeaders = response.Headers.ToDictionary();
|
||||
|
||||
await sender.Send(new CreateOutResCommand
|
||||
{
|
||||
ActionId = action.Id,
|
||||
Header = JsonSerializer.Serialize(resHeaders, options: new() { WriteIndented = false }),
|
||||
Body = resBody,
|
||||
AddedWho = config?["AddedWho"]
|
||||
}, cancel);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using ReC.Application.Common;
|
||||
using ReC.Application.Common.Constants;
|
||||
using ReC.Application.Common.Dto;
|
||||
using ReC.Application.Common.Exceptions;
|
||||
using ReC.Application.Common.Procedures.InsertProcedure;
|
||||
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;
|
||||
|
||||
public record InvokeRecActionViewCommand : IRequest<bool>
|
||||
{
|
||||
public RecActionViewDto Action { get; set; } = null!;
|
||||
}
|
||||
|
||||
public static class InvokeRecActionViewCommandExtensions
|
||||
{
|
||||
public static InvokeRecActionViewCommand ToInvokeCommand(this RecActionViewDto dto) => new() { Action = dto };
|
||||
}
|
||||
|
||||
public class InvokeRecActionViewCommandHandler(
|
||||
ISender sender,
|
||||
IHttpClientFactory clientFactory,
|
||||
IConfiguration? config = null
|
||||
) : IRequestHandler<InvokeRecActionViewCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(InvokeRecActionViewCommand request, CancellationToken cancel)
|
||||
{
|
||||
var action = request.Action;
|
||||
|
||||
using var http = clientFactory.CreateClient(Http.ClientName);
|
||||
|
||||
if (action.RestType is not RestType restType)
|
||||
throw new DataIntegrityException(
|
||||
$"Rec action could not be invoked because the RestType value is null. " +
|
||||
$"ProfileId: {action.ProfileId}, " +
|
||||
$"Id: {action.Id}"
|
||||
);
|
||||
|
||||
using var httpReq = restType
|
||||
.ToHttpMethod()
|
||||
.ToHttpRequestMessage(action.EndpointUri);
|
||||
|
||||
if (action.Body is not null)
|
||||
{
|
||||
using var reqBody = new StringContent(action.Body);
|
||||
httpReq.Content = reqBody;
|
||||
}
|
||||
|
||||
if (action.Headers is not null)
|
||||
foreach (var header in action.Headers)
|
||||
httpReq.Headers.Add(header.Key, header.Value);
|
||||
|
||||
switch (action.EndpointAuthType)
|
||||
{
|
||||
case EndpointAuthType.NoAuth:
|
||||
break;
|
||||
|
||||
case EndpointAuthType.ApiKey:
|
||||
if (action.EndpointAuthApiKey is string apiKey && action.EndpointAuthApiValue is string apiValue)
|
||||
{
|
||||
switch (action.EndpointAuthApiKeyAddTo)
|
||||
{
|
||||
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 EndpointAuthType.BearerToken:
|
||||
case EndpointAuthType.JwtBearer:
|
||||
case EndpointAuthType.OAuth2:
|
||||
if (action.EndpointAuthToken is string authToken)
|
||||
httpReq.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
|
||||
break;
|
||||
|
||||
case EndpointAuthType.BasicAuth:
|
||||
if (action.EndpointAuthUsername is string authUsername && action.EndpointAuthPassword is string authPassword)
|
||||
{
|
||||
var basicAuth = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{authUsername}:{authPassword}"));
|
||||
httpReq.Headers.Authorization = new AuthenticationHeaderValue("Basic", basicAuth);
|
||||
}
|
||||
break;
|
||||
|
||||
case EndpointAuthType.NtlmAuth:
|
||||
if (!string.IsNullOrWhiteSpace(action.EndpointAuthUsername))
|
||||
{
|
||||
var credentials = new NetworkCredential(
|
||||
action.EndpointAuthUsername,
|
||||
action.EndpointAuthPassword,
|
||||
action.EndpointAuthDomain);
|
||||
var credentialCache = new CredentialCache { { httpReq.RequestUri!, "NTLM", credentials } };
|
||||
httpReq.Options.Set(new HttpRequestOptionsKey<CredentialCache>("Credentials"), credentialCache);
|
||||
}
|
||||
break;
|
||||
|
||||
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.
|
||||
default:
|
||||
throw new NotImplementedException(
|
||||
$"The authentication type '{action.EndpointAuthType}' is not supported yet. " +
|
||||
$"ProfileId: {action.ProfileId}, " +
|
||||
$"Id: {action.Id}"
|
||||
);
|
||||
}
|
||||
|
||||
using var response = await http.SendAsync(httpReq, cancel);
|
||||
var resBody = await response.Content.ReadAsStringAsync(cancel);
|
||||
var resHeaders = response.Headers.ToDictionary();
|
||||
|
||||
var statusCode = (short)response.StatusCode;
|
||||
|
||||
await sender.ExecuteInsertProcedure(new InsertResultProcedure()
|
||||
{
|
||||
StatusId = statusCode,
|
||||
ActionId = action.Id,
|
||||
Header = JsonSerializer.Serialize(resHeaders, options: new() { WriteIndented = false }),
|
||||
Body = resBody
|
||||
}, config?["AddedWho"], cancel);
|
||||
|
||||
return response.IsSuccessStatusCode;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,15 @@
|
||||
using ReC.Application.RecActions.Commands;
|
||||
using ReC.Domain.Entities;
|
||||
using ReC.Application.Common.Dto;
|
||||
using ReC.Application.RecActions.Commands;
|
||||
|
||||
namespace ReC.Application.RecActions;
|
||||
|
||||
// TODO: update to inject AddedWho from the current host/user contex
|
||||
public class MappingProfile : AutoMapper.Profile
|
||||
{
|
||||
[Obsolete("Use the related procedure or view.")]
|
||||
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"));
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
using MediatR;
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using ReC.Domain.Entities;
|
||||
using AutoMapper;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using DigitalData.Core.Exceptions;
|
||||
using ReC.Application.Common.Dto;
|
||||
|
||||
namespace ReC.Application.RecActions.Queries;
|
||||
|
||||
public record ReadRecActionQueryBase
|
||||
{
|
||||
public long ProfileId { get; init; }
|
||||
|
||||
public ReadRecActionQuery ToReadQuery(Action<ReadRecActionQuery> modify)
|
||||
{
|
||||
ReadRecActionQuery query = new(this);
|
||||
modify(query);
|
||||
return query;
|
||||
}
|
||||
}
|
||||
|
||||
public record ReadRecActionQuery : ReadRecActionQueryBase, IRequest<IEnumerable<RecActionDto>>
|
||||
{
|
||||
public ReadRecActionQuery(ReadRecActionQueryBase root) : base(root) { }
|
||||
|
||||
public bool? Invoked { get; set; } = null;
|
||||
|
||||
public ReadRecActionQuery() { }
|
||||
}
|
||||
|
||||
public class ReadRecActionQueryHandler(IRepository<RecActionView> repo, IMapper mapper) : IRequestHandler<ReadRecActionQuery, IEnumerable<RecActionDto>>
|
||||
{
|
||||
public async Task<IEnumerable<RecActionDto>> Handle(ReadRecActionQuery request, CancellationToken cancel)
|
||||
{
|
||||
var query = repo.Where(act => act.ProfileId == request.ProfileId);
|
||||
|
||||
if (request.Invoked is bool invoked)
|
||||
query = invoked ? query.Where(act => act.Root!.OutRes != null) : query.Where(act => act.Root!.OutRes == null);
|
||||
|
||||
var actions = await query.ToListAsync(cancel);
|
||||
|
||||
if(actions.Count == 0)
|
||||
throw new NotFoundException($"No actions found for the profile {request.ProfileId}.");
|
||||
|
||||
return mapper.Map<IEnumerable<RecActionDto>>(actions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using MediatR;
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using AutoMapper;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using DigitalData.Core.Exceptions;
|
||||
using ReC.Application.Common.Dto;
|
||||
using ReC.Domain.Views;
|
||||
|
||||
namespace ReC.Application.RecActions.Queries;
|
||||
|
||||
public record ReadRecActionViewQuery : IRequest<IEnumerable<RecActionViewDto>>
|
||||
{
|
||||
public long? ProfileId { get; init; } = null;
|
||||
|
||||
public bool? Invoked { get; set; } = null;
|
||||
}
|
||||
|
||||
public class ReadRecActionViewQueryHandler(IRepository<RecActionView> repo, IMapper mapper) : IRequestHandler<ReadRecActionViewQuery, IEnumerable<RecActionViewDto>>
|
||||
{
|
||||
public async Task<IEnumerable<RecActionViewDto>> Handle(ReadRecActionViewQuery request, CancellationToken cancel)
|
||||
{
|
||||
var query = repo.Query;
|
||||
|
||||
if (request.ProfileId is long profileId)
|
||||
query = repo.Where(act => act.ProfileId == profileId);
|
||||
|
||||
if (request.Invoked is bool invoked)
|
||||
query = invoked
|
||||
? query.Where(act => act.Results!.Any())
|
||||
: query.Where(act => !act.Results!.Any());
|
||||
|
||||
var actions = await query.ToListAsync(cancel);
|
||||
|
||||
if (actions.Count == 0)
|
||||
throw new NotFoundException($"No actions found for the profile {request.ProfileId}.");
|
||||
|
||||
return mapper.Map<IEnumerable<RecActionViewDto>>(actions);
|
||||
}
|
||||
}
|
||||
6
src/ReC.Domain/Attributes/MustConfiguredAttribute.cs
Normal file
6
src/ReC.Domain/Attributes/MustConfiguredAttribute.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace ReC.Domain.Attributes;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class MustConfiguredAttribute : Attribute
|
||||
{
|
||||
}
|
||||
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 : byte
|
||||
{
|
||||
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 : byte
|
||||
{
|
||||
NoAuth = 0,
|
||||
ApiKey = 1,
|
||||
BearerToken = 2,
|
||||
JwtBearer = 3,
|
||||
BasicAuth = 4,
|
||||
DigestAuth = 5,
|
||||
OAuth1 = 6,
|
||||
OAuth2 = 7,
|
||||
AwsSignature = 8,
|
||||
NtlmAuth = 9
|
||||
}
|
||||
7
src/ReC.Domain/Constants/ErrorAction.cs
Normal file
7
src/ReC.Domain/Constants/ErrorAction.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace ReC.Domain.Constants;
|
||||
|
||||
public enum ErrorAction : byte
|
||||
{
|
||||
Stop = 0,
|
||||
Continue = 1,
|
||||
}
|
||||
12
src/ReC.Domain/Constants/ProfileType.cs
Normal file
12
src/ReC.Domain/Constants/ProfileType.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace ReC.Domain.Constants;
|
||||
|
||||
public enum ProfileType : byte
|
||||
{
|
||||
Http = 1,
|
||||
Https = 2
|
||||
}
|
||||
|
||||
public static class ProfileTypeExtensions
|
||||
{
|
||||
public static string ToUriBuilderScheme(this ProfileType profileType) => profileType.ToString().ToLower();
|
||||
}
|
||||
28
src/ReC.Domain/Constants/RestType.cs
Normal file
28
src/ReC.Domain/Constants/RestType.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
namespace ReC.Domain.Constants;
|
||||
|
||||
public enum RestType : byte
|
||||
{
|
||||
None = 0,
|
||||
Get = 1,
|
||||
Post = 2,
|
||||
Put = 3,
|
||||
Patch = 4,
|
||||
Delete = 5,
|
||||
Head = 6,
|
||||
Options = 7,
|
||||
Connect = 8,
|
||||
Trace = 9,
|
||||
}
|
||||
|
||||
public static class RestTypeExtensions
|
||||
{
|
||||
public static string ToHttpMethodName(this RestType restType)
|
||||
{
|
||||
return restType.ToString().ToUpper();
|
||||
}
|
||||
|
||||
public static bool IsValid(this RestType restType)
|
||||
{
|
||||
return restType != RestType.None;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Domain.Entities;
|
||||
|
||||
public class BodyQueryResult
|
||||
{
|
||||
[Column("REQUEST_BODY")]
|
||||
public string? RawBody { get; init; }
|
||||
}
|
||||
@@ -1,52 +1,36 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Domain.Entities;
|
||||
|
||||
[Obsolete("Use Views instead.")]
|
||||
[Table("TBDD_CONNECTION")]
|
||||
public class Connection
|
||||
{
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Column("GUID")]
|
||||
public short? Id { get; set; }
|
||||
|
||||
[Column("BEZEICHNUNG")]
|
||||
public string? Bezeichnung { get; set; }
|
||||
|
||||
[Column("SQL_PROVIDER")]
|
||||
public string? SqlProvider { get; set; }
|
||||
|
||||
[Column("SERVER")]
|
||||
public string? Server { get; set; }
|
||||
|
||||
[Column("DATENBANK")]
|
||||
public string? Datenbank { get; set; }
|
||||
|
||||
[Column("USERNAME")]
|
||||
public string? Username { get; set; }
|
||||
|
||||
[Column("PASSWORD")]
|
||||
public string? Password { get; set; }
|
||||
|
||||
[Column("BEMERKUNG")]
|
||||
public string? Bemerkung { get; set; }
|
||||
|
||||
[Column("AKTIV")]
|
||||
public bool? Aktiv { get; set; }
|
||||
|
||||
[Column("ERSTELLTWER")]
|
||||
public string? ErstelltWer { get; set; }
|
||||
|
||||
[Column("ERSTELLTWANN")]
|
||||
public DateTime? ErstelltWann { get; set; }
|
||||
|
||||
[Column("GEANDERTWER")]
|
||||
public string? GeandertWer { get; set; }
|
||||
|
||||
[Column("GEAENDERTWANN")]
|
||||
public DateTime? GeaendertWann { get; set; }
|
||||
|
||||
[Column("SYS_CONNECTION")]
|
||||
public bool? SysConnection { get; set; }
|
||||
}
|
||||
@@ -1,34 +1,24 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Domain.Entities;
|
||||
|
||||
[Obsolete("Use Views instead.")]
|
||||
[Table("TBREC_CFG_ENDPOINT")]
|
||||
public class Endpoint
|
||||
{
|
||||
[Key]
|
||||
[Column("GUID")]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long Id { get; set; }
|
||||
|
||||
[Column("ACTIVE")]
|
||||
public bool? Active { get; set; }
|
||||
|
||||
[Column("DESCRIPTION")]
|
||||
public string? Description { get; set; }
|
||||
|
||||
[Column("URI")]
|
||||
public string? Uri { get; set; }
|
||||
|
||||
[Column("ADDED_WHO")]
|
||||
public string? AddedWho { get; set; }
|
||||
|
||||
[Column("ADDED_WHEN")]
|
||||
public DateTime? AddedWhen { get; set; }
|
||||
|
||||
[Column("CHANGED_WHO")]
|
||||
public string? ChangedWho { get; set; }
|
||||
|
||||
[Column("CHANGED_WHEN")]
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
}
|
||||
@@ -1,58 +1,41 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using ReC.Domain.Constants;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Domain.Entities;
|
||||
|
||||
[Obsolete("Use Views instead.")]
|
||||
[Table("TBREC_CFG_ENDPOINT_AUTH")]
|
||||
public class EndpointAuth
|
||||
{
|
||||
[Key]
|
||||
[Column("GUID")]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long? Id { get; set; }
|
||||
|
||||
[Column("ACTIVE")]
|
||||
public bool? Active { get; set; }
|
||||
|
||||
[Column("DESCRIPTION")]
|
||||
public string? Description { get; set; }
|
||||
|
||||
[Column("TYPE")]
|
||||
public string? Type { get; set; }
|
||||
public EndpointAuthType? Type { get; set; }
|
||||
|
||||
[Column("API_KEY")]
|
||||
public string? ApiKey { get; set; }
|
||||
|
||||
[Column("API_VALUE")]
|
||||
public string? ApiValue { get; set; }
|
||||
|
||||
[Column("API_KEY_ADD_TO")]
|
||||
public string? ApiKeyAddTo { get; set; }
|
||||
public ApiKeyLocation? ApiKeyAddTo { get; set; }
|
||||
|
||||
[Column("TOKEN")]
|
||||
public string? Token { get; set; }
|
||||
|
||||
[Column("USERNAME")]
|
||||
public string? Username { get; set; }
|
||||
|
||||
[Column("PASSWORD")]
|
||||
public string? Password { get; set; }
|
||||
|
||||
[Column("DOMAIN")]
|
||||
public string? Domain { get; set; }
|
||||
|
||||
[Column("WORKSTATION")]
|
||||
public string? Workstation { get; set; }
|
||||
|
||||
[Column("ADDED_WHO")]
|
||||
public string? AddedWho { get; set; }
|
||||
|
||||
[Column("ADDED_WHEN")]
|
||||
public DateTime? AddedWhen { get; set; }
|
||||
|
||||
[Column("CHANGED_WHO")]
|
||||
public string? ChangedWho { get; set; }
|
||||
|
||||
[Column("CHANGED_WHEN")]
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Domain.Entities;
|
||||
|
||||
@@ -8,40 +7,29 @@ namespace ReC.Domain.Entities;
|
||||
/// All properties are nullable to provide flexibility on the database side,
|
||||
/// preventing breaking changes if columns are altered to be nullable in production.
|
||||
/// </summary>
|
||||
[Obsolete("Use Views instead.")]
|
||||
[Table("TBREC_CFG_ENDPOINT_PARAMS", Schema = "dbo")]
|
||||
public class EndpointParam
|
||||
{
|
||||
[Key]
|
||||
[Column("GUID")]
|
||||
public long? Id { get; set; }
|
||||
|
||||
[Column("ACTIVE")]
|
||||
public bool? Active { get; set; }
|
||||
|
||||
[Column("DESCRIPTION")]
|
||||
public string? Description { get; set; }
|
||||
|
||||
[Column("GROUP_ID")]
|
||||
public short? GroupId { get; set; }
|
||||
|
||||
[Column("SEQUENCE")]
|
||||
public byte? Sequence { get; set; }
|
||||
|
||||
[Column("KEY")]
|
||||
public string? Key { get; set; }
|
||||
|
||||
[Column("VALUE")]
|
||||
public string? Value { get; set; }
|
||||
|
||||
[Column("ADDED_WHO")]
|
||||
public string? AddedWho { get; set; }
|
||||
|
||||
[Column("ADDED_WHEN")]
|
||||
public DateTime? AddedWhen { get; set; }
|
||||
|
||||
[Column("CHANGED_WHO")]
|
||||
public string? ChangedWho { get; set; }
|
||||
|
||||
[Column("CHANGED_WHEN")]
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Domain.Entities;
|
||||
|
||||
public class HeaderQueryResult
|
||||
{
|
||||
[Column("REQUEST_HEADER")]
|
||||
public string? RawHeader { get; init; }
|
||||
}
|
||||
@@ -1,37 +1,28 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Domain.Entities;
|
||||
|
||||
[Obsolete("Use Views instead.")]
|
||||
[Table("TBREC_OUT_RESULT", Schema = "dbo")]
|
||||
public class OutRes
|
||||
{
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Column("GUID")]
|
||||
public long? Id { get; set; }
|
||||
|
||||
[Column("ACTION_ID")]
|
||||
public long? ActionId { get; set; }
|
||||
|
||||
[ForeignKey("ActionId")]
|
||||
public RecAction? Action { get; set; }
|
||||
|
||||
[Column("RESULT_HEADER")]
|
||||
public short? Status { get; set; }
|
||||
|
||||
public string? Header { get; set; }
|
||||
|
||||
[Column("RESULT_BODY")]
|
||||
public string? Body { get; set; }
|
||||
|
||||
[Column("ADDED_WHO")]
|
||||
public string? AddedWho { get; set; }
|
||||
|
||||
[Column("ADDED_WHEN")]
|
||||
public DateTime? AddedWhen { get; set; }
|
||||
|
||||
[Column("CHANGED_WHO")]
|
||||
public string? ChangedWho { get; set; }
|
||||
|
||||
[Column("CHANGED_WHEN")]
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,46 +1,32 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Domain.Entities;
|
||||
|
||||
[Obsolete("Use Views instead.")]
|
||||
[Table("TBREC_CFG_PROFILE", Schema = "dbo")]
|
||||
public class Profile
|
||||
{
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Column("GUID")]
|
||||
public long Id { get; set; }
|
||||
|
||||
[Column("ACTIVE")]
|
||||
public bool? Active { get; set; }
|
||||
|
||||
[Column("TYPE")]
|
||||
public string? Type { get; set; }
|
||||
|
||||
[Column("MANDANTOR")]
|
||||
public string? Mandantor { get; set; }
|
||||
|
||||
[Column("PROFILE_NAME")]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[Column("DESCRIPTION")]
|
||||
public string? Description { get; set; }
|
||||
|
||||
[Column("LOG_LEVEL")]
|
||||
public string? LogLevel { get; set; }
|
||||
|
||||
[Column("LANGUAGE")]
|
||||
public string? Language { get; set; }
|
||||
|
||||
[Column("ADDED_WHO")]
|
||||
public string? AddedWho { get; set; }
|
||||
|
||||
[Column("ADDED_WHEN")]
|
||||
public DateTime? AddedWhen { get; set; }
|
||||
|
||||
[Column("CHANGED_WHO")]
|
||||
public string? ChangedWho { get; set; }
|
||||
|
||||
[Column("CHANGED_WHEN")]
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
}
|
||||
@@ -1,73 +1,54 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using ReC.Domain.Constants;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Domain.Entities;
|
||||
|
||||
[Obsolete("Use Views instead.")]
|
||||
[Table("TBREC_CFG_ACTION")]
|
||||
public class RecAction
|
||||
{
|
||||
[Key]
|
||||
[Column("GUID")]
|
||||
public long? Id { get; set; }
|
||||
|
||||
[Column("PROFILE_ID")]
|
||||
public long? ProfileId { get; set; }
|
||||
|
||||
[ForeignKey("ProfileId")]
|
||||
public Profile? Profile { get; set; }
|
||||
|
||||
[Column("ACTIVE")]
|
||||
public bool? Active { get; set; }
|
||||
|
||||
[Column("SEQUENCE")]
|
||||
public byte? Sequence { get; set; }
|
||||
|
||||
[Column("ENDPOINT_ID")]
|
||||
public long? EndpointId { get; set; }
|
||||
|
||||
[ForeignKey("EndpointId")]
|
||||
public Endpoint? Endpoint { get; set; }
|
||||
|
||||
[Column("ENDPOINT_AUTH_ID")]
|
||||
public long? EndpointAuthId { get; set; }
|
||||
|
||||
[ForeignKey("EndpointAuthId")]
|
||||
public EndpointAuth? EndpointAuth { get; set; }
|
||||
|
||||
[Column("ENDPOINT_PARAMS_ID")]
|
||||
public short? EndpointParamsId { get; set; }
|
||||
|
||||
[Column("SQL_CONNECTION_ID")]
|
||||
public short? SqlConnectionId { get; set; }
|
||||
|
||||
[ForeignKey("SqlConnectionId")]
|
||||
public Connection? SqlConnection { get; set; }
|
||||
|
||||
[Column("TYPE")]
|
||||
public string? Type { get; set; }
|
||||
|
||||
[Column("PREPROCESSING_QUERY")]
|
||||
public string? PreprocessingQuery { get; set; }
|
||||
|
||||
[Column("HEADER_QUERY")]
|
||||
public string? HeaderQuery { get; set; }
|
||||
|
||||
[Column("BODY_QUERY")]
|
||||
public string? BodyQuery { get; set; }
|
||||
|
||||
[Column("POSTPROCESSING_QUERY")]
|
||||
public string? PostprocessingQuery { get; set; }
|
||||
|
||||
[Column("ADDED_WHO")]
|
||||
public ErrorAction? ErrorAction { get; set; }
|
||||
|
||||
public string? AddedWho { get; set; }
|
||||
|
||||
[Column("ADDED_WHEN")]
|
||||
public DateTime? AddedWhen { get; set; }
|
||||
|
||||
[Column("CHANGED_WHO")]
|
||||
public string? ChangedWho { get; set; }
|
||||
|
||||
[Column("CHANGED_WHEN")]
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
|
||||
public OutRes? OutRes { get; set; }
|
||||
|
||||
6
src/ReC.Domain/QueryOutput/BodyQueryResult.cs.cs
Normal file
6
src/ReC.Domain/QueryOutput/BodyQueryResult.cs.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace ReC.Domain.QueryOutput;
|
||||
|
||||
public class BodyQueryResult
|
||||
{
|
||||
public string? RawBody { get; init; }
|
||||
}
|
||||
6
src/ReC.Domain/QueryOutput/HeaderQueryResult.cs
Normal file
6
src/ReC.Domain/QueryOutput/HeaderQueryResult.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace ReC.Domain.QueryOutput;
|
||||
|
||||
public class HeaderQueryResult
|
||||
{
|
||||
public string? RawHeader { get; init; }
|
||||
}
|
||||
8
src/ReC.Domain/QueryOutput/InsertObjectResult.cs
Normal file
8
src/ReC.Domain/QueryOutput/InsertObjectResult.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Domain.QueryOutput;
|
||||
|
||||
public class InsertObjectResult
|
||||
{
|
||||
public required long NewObjectId { get; set; }
|
||||
}
|
||||
46
src/ReC.Domain/Views/ProfileView.cs
Normal file
46
src/ReC.Domain/Views/ProfileView.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using ReC.Domain.Constants;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ReC.Domain.Views;
|
||||
|
||||
[Table("VWREC_PROFILE", Schema = "dbo")]
|
||||
public record ProfileView
|
||||
{
|
||||
public virtual IEnumerable<RecActionView>? Actions { get; init; }
|
||||
|
||||
public long Id { get; init; }
|
||||
|
||||
public bool Active { get; init; }
|
||||
|
||||
public ProfileType TypeId { get; init; }
|
||||
|
||||
public string? Type { get; init; }
|
||||
|
||||
public string? Mandantor { get; init; }
|
||||
|
||||
public string? ProfileName { get; init; }
|
||||
|
||||
public string? Description { get; init; }
|
||||
|
||||
public byte LogLevelId { get; init; }
|
||||
|
||||
public string? LogLevel { get; init; }
|
||||
|
||||
public short LanguageId { get; init; }
|
||||
|
||||
public string? Language { get; init; }
|
||||
|
||||
public string? AddedWho { get; init; }
|
||||
|
||||
public DateTime AddedWhen { get; init; }
|
||||
|
||||
public string? ChangedWho { get; init; }
|
||||
|
||||
public DateTime? ChangedWhen { get; init; }
|
||||
|
||||
public DateTime? FirstRun { get; init; }
|
||||
|
||||
public DateTime? LastRun { get; init; }
|
||||
|
||||
public string? LastResult { get; init; }
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user