using DigitalData.Core.Abstraction.Application.Repository; using DigitalData.Core.Exceptions; using MediatR; using Microsoft.Data.SqlClient; using Microsoft.Extensions.Options; using ReC.Application.Common.Exceptions; using ReC.Application.Common.Options; using ReC.Application.EndpointAuth.Commands; using ReC.Application.EndpointParams.Commands; using ReC.Application.Endpoints.Commands; using ReC.Application.Profile.Commands; using ReC.Application.RecActions.Commands; using ReC.Application.Results.Commands; using System.Data; namespace ReC.Application.Common.Procedures.InsertProcedure; public record InsertObjectProcedure : IRequest { /// /// Target entity: ACTION, ENDPOINT, ENDPOINT_AUTH, ENDPOINT_PARAMS, PROFILE, RESULT /// public string Entity { get; set; } = null!; //TODO: update to set in authentication middleware or similar, and remove from procedure properties internal string? AddedWho { get; private set; } = "ReC.API"; public InsertActionCommand? Action { get; set; } public InsertEndpointCommand? Endpoint { get; set; } public InsertEndpointAuthCommand? EndpointAuth { get; set; } public InsertProfileCommand? Profile { get; set; } public InsertResultCommand? Result { get; set; } public InsertEndpointParamsCommand? EndpointParams { get; set; } } public class InsertObjectProcedureHandler(IRepository repo, IOptionsMonitor sqlExOpt) : IRequestHandler { public async Task Handle(InsertObjectProcedure request, CancellationToken cancel) { var sp = new StoredProcedureBuilder("[dbo].[PRREC_INSERT_OBJECT]") .Add("pENTITY", request.Entity) .Add("pADDED_WHO", request.AddedWho) .Add("pADDED_WHEN", DateTime.UtcNow) .Add("pACTION_PROFILE_ID", request.Action?.ProfileId) .Add("pACTION_ACTIVE", request.Action?.Active) .Add("pACTION_SEQUENCE", request.Action?.Sequence, SqlDbType.TinyInt) .Add("pACTION_ENDPOINT_ID", request.Action?.EndpointId) .Add("pACTION_ENDPOINT_AUTH_ID", request.Action?.EndpointAuthId) .Add("pACTION_ENDPOINT_PARAMS_ID", request.Action?.EndpointParamsId, SqlDbType.SmallInt) .Add("pACTION_SQL_CONNECTION_ID", request.Action?.SqlConnectionId, SqlDbType.SmallInt) .Add("pACTION_TYPE_ID", request.Action?.TypeId is not null ? (byte)request.Action.TypeId : null, SqlDbType.TinyInt) .Add("pACTION_PRE_SQL", request.Action?.PreSql) .Add("pACTION_HEADER_SQL", request.Action?.HeaderSql) .Add("pACTION_BODY_SQL", request.Action?.BodySql) .Add("pACTION_POST_SQL", request.Action?.PostSql) .Add("pACTION_ERROR_ACTION_ID", request.Action?.ErrorActionId, SqlDbType.TinyInt) .Add("pENDPOINT_ACTIVE", request.Endpoint?.Active) .Add("pENDPOINT_DESCRIPTION", request.Endpoint?.Description) .Add("pENDPOINT_URI", request.Endpoint?.Uri) .Add("pENDPOINT_AUTH_ACTIVE", request.EndpointAuth?.Active) .Add("pENDPOINT_AUTH_DESCRIPTION", request.EndpointAuth?.Description) .Add("pENDPOINT_AUTH_TYPE_ID", request.EndpointAuth?.TypeId, SqlDbType.TinyInt) .Add("pENDPOINT_AUTH_API_KEY", request.EndpointAuth?.ApiKey) .Add("pENDPOINT_AUTH_API_VALUE", request.EndpointAuth?.ApiValue) .Add("pENDPOINT_AUTH_API_KEY_ADD_TO_ID", request.EndpointAuth?.ApiKeyAddToId) .Add("pENDPOINT_AUTH_TOKEN", request.EndpointAuth?.Token) .Add("pENDPOINT_AUTH_USERNAME", request.EndpointAuth?.Username) .Add("pENDPOINT_AUTH_PASSWORD", request.EndpointAuth?.Password) .Add("pENDPOINT_AUTH_DOMAIN", request.EndpointAuth?.Domain) .Add("pENDPOINT_AUTH_WORKSTATION", request.EndpointAuth?.Workstation) .Add("pPROFILE_ACTIVE", request.Profile?.Active) .Add("pPROFILE_TYPE_ID", request.Profile?.TypeId, SqlDbType.TinyInt) .Add("pPROFILE_MANDANTOR", request.Profile?.Mandantor) .Add("pPROFILE_NAME", request.Profile?.Name) .Add("pPROFILE_DESCRIPTION", request.Profile?.Description) .Add("pPROFILE_LOG_LEVEL_ID", request.Profile?.LogLevelId, SqlDbType.TinyInt) .Add("pPROFILE_LANGUAGE_ID", request.Profile?.LanguageId, SqlDbType.SmallInt) .Add("pRESULT_ACTION_ID", request.Result?.ActionId) .Add("pRESULT_STATUS_ID", request.Result?.Status, SqlDbType.SmallInt) .Add("pRESULT_TYPE_ID", request.Result?.Type is not null ? (byte)request.Result.Type : null, SqlDbType.TinyInt) .Add("pRESULT_HEADER", request.Result?.Header) .Add("pRESULT_BODY", request.Result?.Body) .Add("pRESULT_INFO", request.Result?.Info) .Add("pRESULT_INFO_DETAIL", request.Result?.InfoDetail) .Add("pRESULT_ERROR", request.Result?.Error) .Add("pRESULT_REFERENCE1", request.Result?.Reference1) .Add("pRESULT_REFERENCE2", request.Result?.Reference2) .Add("pRESULT_REFERENCE3", request.Result?.Reference3) .Add("pRESULT_REFERENCE4", request.Result?.Reference4) .Add("pRESULT_REFERENCE5", request.Result?.Reference5) .Add("pENDPOINT_PARAMS_ACTIVE", request.EndpointParams?.Active) .Add("pENDPOINT_PARAMS_DESCRIPTION", request.EndpointParams?.Description) .Add("pENDPOINT_PARAMS_GROUP_ID", request.EndpointParams?.GroupId, SqlDbType.SmallInt) .Add("pENDPOINT_PARAMS_SEQUENCE", request.EndpointParams?.Sequence, SqlDbType.TinyInt) .Add("pENDPOINT_PARAMS_KEY", request.EndpointParams?.Key) .Add("pENDPOINT_PARAMS_VALUE", request.EndpointParams?.Value) .AddOutput("oGUID", SqlDbType.BigInt); try { await repo.ExecuteQueryRawAsync(sp.BuildSql(), sp.BuildParameters(), cancel); } catch (SqlException ex) { if (sqlExOpt.CurrentValue.BadRequestSqlExceptionNumbers.Contains(ex.Number)) throw new BadRequestException(ex.Message, ex); else throw; } var guidParam = sp.GetParameter("oGUID"); 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."); } }