Improved Case Automation POST body conext and other minor issues:
* Pushed Case Workflow Display HTML rendering logic down into a controller for improved security and consistent tokenisation of the Jube token format against context. Included a migration to update the default demo entry to use proper tokenisation. Updated the repository to support fetching CaseWorkflowDisplay with appropriate security. * Implemented improved tokenisation of the EntityAnalysisModelInstanceEntryPayload model via a common extension method on EntityAnalysisModelInstanceEntryPayload, used consistently across the system for serialisation and storage. * Included a migration to update the tokenisation format for full CaseWorkflowDisplay support. * Fixed an issue where CaseWorkflowFilter was incorrectly filtering on CaseWorkflowStatus.Guid instead of CaseWorkflowStatus.Name, causing the GUID to be returned rather than the display name on the template/demo model. (The remainder was fixed in GitHub issue #6.) Included a migration with a corrective SQL statement. * Fixed an issue where tokens were not being stored alongside CaseWorkflowFilter definition configuration. It now behaves identically to CaseSearch. Note: migrating missing tokens is not feasible as it requires JS-side parsing via JQueryBuilder. * Reduced the size of the CaseWorkflowForm invocation to include only the required fields given the new POST body context being rendered server side. Improved API serialisation by using a dictionary for form payload keys and values. * Consolidated JSON serialisation settings into DI and updated usages throughout. * Updated EntityAnalysisModelInstanceEntryPayload write serialisers to handle deserialisation, which is required to support tokenisation of new Case Automation POST bodies. * Created an extension method on the EntityAnalysisModelInstanceEntryPayload to centralise tokenisation of strings across Activation and Case Automation on a consistent basis. Simplified Case Notification and Case HTTP dispatch by removing tokenisation logic from those classes. * Removed a redundant field from the CaseWorkflowFormEntry POCO (database left unchanged for now). * Fixed a bug in Case session SQL rebuilding where the rebuild date was not being correctly checked for null or default value, which caused a failure in the last migration. * Made minor modifications to the Create Case process and method signature to skip serialisation when the payload object required for tokenisation is already available on the thread (e.g. during synchronous reprocessing). * Updated Case Workflow Macro processing to fetch the archive payload for the case from the database, improving security of that invocation endpoint. * Removed what appeared to be a duplicate EntityAnalysisModelInstanceEntryPayload model introduced during refactoring. * Fixed a but in Case Worfkflow Display Role assigment owing to volatile Guid in its update.
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
/* Copyright (C) 2022-present Jube Holdings Limited.
|
||||
*
|
||||
* This file is part of Jube™ software.
|
||||
*
|
||||
* Jube™ is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* Jube™ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License along with Jube™. If not,
|
||||
* see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Jube.App.Controllers.Helper
|
||||
{
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Code;
|
||||
using Data.Context;
|
||||
using Data.Repository;
|
||||
using Dto;
|
||||
using DynamicEnvironment;
|
||||
using Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
using Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload.Extensions;
|
||||
using Engine.Helpers;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[Produces("application/json")]
|
||||
[Authorize]
|
||||
public class CaseWorkflowDisplayExecutionController : Controller
|
||||
{
|
||||
private readonly DbContext dbContext;
|
||||
private readonly JsonSerializationHelper jsonSerializationHelper;
|
||||
private readonly PermissionValidation permissionValidation;
|
||||
private readonly CaseRepository repositoryCase;
|
||||
private readonly CaseWorkflowDisplayRepository repositoryCaseWorkflowDisplay;
|
||||
private readonly CaseWorkflowStatusRepository repositoryCaseWorkflowStatus;
|
||||
private readonly string userName;
|
||||
|
||||
public CaseWorkflowDisplayExecutionController(
|
||||
DynamicEnvironment dynamicEnvironment, IHttpContextAccessor httpContextAccessor,
|
||||
JsonSerializationHelper jsonSerializationHelper)
|
||||
{
|
||||
if (httpContextAccessor.HttpContext?.User.Identity != null)
|
||||
{
|
||||
userName = httpContextAccessor.HttpContext.User.Identity.Name;
|
||||
}
|
||||
|
||||
dbContext =
|
||||
DataConnectionDbContext.GetDbContextDataConnection(dynamicEnvironment.AppSettings("ConnectionString"));
|
||||
|
||||
repositoryCase = new CaseRepository(dbContext, userName);
|
||||
repositoryCaseWorkflowDisplay = new CaseWorkflowDisplayRepository(dbContext, userName);
|
||||
repositoryCaseWorkflowStatus = new CaseWorkflowStatusRepository(dbContext, userName);
|
||||
|
||||
permissionValidation = new PermissionValidation(dbContext, userName);
|
||||
this.jsonSerializationHelper = jsonSerializationHelper;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
dbContext.Close();
|
||||
dbContext.Dispose();
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<string>> ExecuteAsync([FromBody] CaseWorkflowDisplayExecutionDto model, CancellationToken token = default)
|
||||
{
|
||||
if (!permissionValidation.Validate(new[]
|
||||
{
|
||||
1
|
||||
}))
|
||||
{
|
||||
return Forbid();
|
||||
}
|
||||
|
||||
var existingCase = await repositoryCase.GetByIdActiveOnlyAsync(model.CaseId, token);
|
||||
|
||||
if (existingCase == null)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var caseWorkflowDisplay = await repositoryCaseWorkflowDisplay.GetByIdActiveOnlyAsync(model.CaseWorkflowDisplayId, token);
|
||||
|
||||
if (caseWorkflowDisplay == null)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var caseWorkflowStatus = await repositoryCaseWorkflowStatus.GetByGuidAsync(existingCase.CaseWorkflowStatusGuid, token);
|
||||
|
||||
if (caseWorkflowStatus == null)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var payload = JsonConvert.DeserializeObject<EntityAnalysisModelInstanceEntryPayload>(existingCase.Json, jsonSerializationHelper.DefaultJsonSerializerSettingsSettings);
|
||||
var replacedHtml = payload.ReplaceTokens(caseWorkflowDisplay.Html);
|
||||
|
||||
return Ok(replacedHtml);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,19 +13,23 @@
|
||||
|
||||
namespace Jube.App.Controllers.Helper
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Case;
|
||||
using Code;
|
||||
using Data.Context;
|
||||
using Data.Poco;
|
||||
using Data.Repository;
|
||||
using Dto;
|
||||
using DynamicEnvironment;
|
||||
using Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
using Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload.Extensions;
|
||||
using Engine.Helpers;
|
||||
using log4net;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
@@ -35,24 +39,34 @@ namespace Jube.App.Controllers.Helper
|
||||
{
|
||||
private readonly DbContext dbContext;
|
||||
private readonly DynamicEnvironment dynamicEnvironment;
|
||||
private readonly JsonSerializationHelper jsonSerializationHelper;
|
||||
private readonly ILog log;
|
||||
private readonly PermissionValidation permissionValidation;
|
||||
private readonly CaseRepository repositoryCase;
|
||||
private readonly CaseWorkflowMacroRepository repositoryCaseWorkflowMacro;
|
||||
private readonly CaseWorkflowStatusRepository repositoryCaseWorkflowStatus;
|
||||
private readonly string userName;
|
||||
|
||||
public CaseWorkflowMacroExecutionController(ILog log,
|
||||
DynamicEnvironment dynamicEnvironment, IHttpContextAccessor httpContextAccessor)
|
||||
DynamicEnvironment dynamicEnvironment, IHttpContextAccessor httpContextAccessor, JsonSerializationHelper jsonSerializationHelper)
|
||||
{
|
||||
if (httpContextAccessor.HttpContext?.User.Identity != null)
|
||||
{
|
||||
userName = httpContextAccessor.HttpContext.User.Identity.Name;
|
||||
}
|
||||
|
||||
dbContext =
|
||||
DataConnectionDbContext.GetDbContextDataConnection(dynamicEnvironment.AppSettings("ConnectionString"));
|
||||
|
||||
this.log = log;
|
||||
this.dynamicEnvironment = dynamicEnvironment;
|
||||
|
||||
dbContext =
|
||||
DataConnectionDbContext.GetDbContextDataConnection(this.dynamicEnvironment.AppSettings("ConnectionString"));
|
||||
repositoryCase = new CaseRepository(dbContext, userName);
|
||||
repositoryCaseWorkflowMacro = new CaseWorkflowMacroRepository(dbContext, userName);
|
||||
repositoryCaseWorkflowStatus = new CaseWorkflowStatusRepository(dbContext, userName);
|
||||
|
||||
permissionValidation = new PermissionValidation(dbContext, userName);
|
||||
this.jsonSerializationHelper = jsonSerializationHelper;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
@@ -77,53 +91,74 @@ namespace Jube.App.Controllers.Helper
|
||||
return Forbid();
|
||||
}
|
||||
|
||||
if (model.Payload == null)
|
||||
var existingCase = await repositoryCase.GetByIdActiveOnlyAsync(model.CaseId, token);
|
||||
|
||||
if (existingCase == null)
|
||||
{
|
||||
return Ok(model);
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var jObject = JObject.Parse(model.Payload);
|
||||
var caseWorkflowMacro = await repositoryCaseWorkflowMacro.GetByIdActiveOnlyAsync(model.CaseWorkflowMacroId, token);
|
||||
|
||||
var values = new Dictionary<string, string>();
|
||||
foreach (var (key, value) in jObject)
|
||||
if (caseWorkflowMacro == null)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
values.Add(key, value.ToString());
|
||||
}
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var caseWorkflowMacroRepository = new CaseWorkflowMacroRepository(dbContext, userName);
|
||||
var caseWorkflowStatus = await repositoryCaseWorkflowStatus.GetByGuidAsync(existingCase.CaseWorkflowStatusGuid, token);
|
||||
|
||||
var caseWorkflowMacro = await caseWorkflowMacroRepository.GetByIdActiveOnlyAsync(model.CaseWorkflowMacroId, token);
|
||||
|
||||
if (caseWorkflowMacro.EnableNotification != 1 && caseWorkflowMacro.EnableHttpEndpoint != 1)
|
||||
if (caseWorkflowStatus == null)
|
||||
{
|
||||
return Ok(model);
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var context = JsonConvert.DeserializeObject<EntityAnalysisModelInstanceEntryPayload>(existingCase.Json, jsonSerializationHelper.DefaultJsonSerializerSettingsSettings);
|
||||
|
||||
if (caseWorkflowMacro.EnableNotification == 1)
|
||||
{
|
||||
var notification = new Notification(log, dynamicEnvironment);
|
||||
var notificationSubject = context.ReplaceTokens(caseWorkflowMacro.NotificationSubject);
|
||||
var notificationDestination = context.ReplaceTokens(caseWorkflowMacro.NotificationDestination);
|
||||
var notificationBody = context.ReplaceTokens(caseWorkflowMacro.NotificationBody);
|
||||
|
||||
await notification.SendAsync(caseWorkflowMacro.NotificationTypeId ?? 1,
|
||||
caseWorkflowMacro.NotificationDestination,
|
||||
caseWorkflowMacro.NotificationSubject,
|
||||
caseWorkflowMacro.NotificationBody, values, token);
|
||||
notificationDestination,
|
||||
notificationSubject,
|
||||
notificationBody, token);
|
||||
}
|
||||
|
||||
if (caseWorkflowMacro.EnableHttpEndpoint != 1)
|
||||
if (caseWorkflowMacro.EnableHttpEndpoint == 1)
|
||||
{
|
||||
return Ok(model);
|
||||
}
|
||||
var endpoint = context.ReplaceTokens(caseWorkflowMacro.HttpEndpoint);
|
||||
|
||||
if (caseWorkflowMacro.HttpEndpointTypeId != null)
|
||||
{
|
||||
await SendHttpEndpoint.SendAsync(caseWorkflowMacro.HttpEndpoint,
|
||||
caseWorkflowMacro.HttpEndpointTypeId.Value
|
||||
, values);
|
||||
if (caseWorkflowMacro.HttpEndpointTypeId == 1)
|
||||
{
|
||||
await SendHttpEndpoint.PostAsync(endpoint, PreparePostBodyString(model, existingCase, context, caseWorkflowStatus, caseWorkflowMacro), log);
|
||||
}
|
||||
else
|
||||
{
|
||||
await SendHttpEndpoint.GetAsync(endpoint, log);
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(model);
|
||||
}
|
||||
|
||||
private string PreparePostBodyString(CaseWorkflowMacroExecutionDto model, Case existingCase, EntityAnalysisModelInstanceEntryPayload payload, CaseWorkflowStatus caseWorkflowStatus, CaseWorkflowMacro caseWorkflowMacro)
|
||||
{
|
||||
var jObject = JObject.FromObject(model, jsonSerializationHelper.ArchiveJsonSerializer);
|
||||
jObject["caseWorkflowMacroName"] = caseWorkflowMacro.Name;
|
||||
|
||||
var caseJObject = JObject.FromObject(existingCase, jsonSerializationHelper.ArchiveJsonSerializer);
|
||||
caseJObject.Remove("json");
|
||||
jObject["case"] = caseJObject;
|
||||
|
||||
caseJObject["caseWorkflowStatus"] = caseWorkflowStatus.Name;
|
||||
|
||||
var payloadJObject = JObject.FromObject(payload, jsonSerializationHelper.ArchiveJsonSerializer);
|
||||
caseJObject["payload"] = payloadJObject;
|
||||
|
||||
return jObject.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,12 +28,16 @@ namespace Jube.App.Controllers.Repository
|
||||
using Data.Repository;
|
||||
using Dto;
|
||||
using DynamicEnvironment;
|
||||
using Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
using Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload.Extensions;
|
||||
using Engine.Helpers;
|
||||
using FluentValidation;
|
||||
using FluentValidation.Results;
|
||||
using log4net;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Validators;
|
||||
|
||||
@@ -44,6 +48,7 @@ namespace Jube.App.Controllers.Repository
|
||||
{
|
||||
private readonly DbContext dbContext;
|
||||
private readonly DynamicEnvironment dynamicEnvironment;
|
||||
private readonly JsonSerializationHelper jsonSerializationHelper;
|
||||
private readonly ILog log;
|
||||
private readonly IMapper mapper;
|
||||
private readonly PermissionValidation permissionValidation;
|
||||
@@ -53,7 +58,7 @@ namespace Jube.App.Controllers.Repository
|
||||
private readonly IValidator<CaseDto> validator;
|
||||
|
||||
public CaseController(ILog log, DynamicEnvironment dynamicEnvironment
|
||||
, IHttpContextAccessor httpContextAccessor)
|
||||
, IHttpContextAccessor httpContextAccessor, JsonSerializationHelper jsonSerializationHelper)
|
||||
{
|
||||
if (httpContextAccessor.HttpContext?.User.Identity != null)
|
||||
{
|
||||
@@ -64,6 +69,7 @@ namespace Jube.App.Controllers.Repository
|
||||
|
||||
dbContext =
|
||||
DataConnectionDbContext.GetDbContextDataConnection(dynamicEnvironment.AppSettings("ConnectionString"));
|
||||
|
||||
permissionValidation = new PermissionValidation(dbContext, userName);
|
||||
|
||||
var config = new MapperConfiguration(cfg =>
|
||||
@@ -77,6 +83,7 @@ namespace Jube.App.Controllers.Repository
|
||||
repositoryCaseEvent = new CaseEventRepository(dbContext, userName);
|
||||
validator = new CaseDtoValidator();
|
||||
this.dynamicEnvironment = dynamicEnvironment;
|
||||
this.jsonSerializationHelper = jsonSerializationHelper;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
@@ -366,7 +373,7 @@ namespace Jube.App.Controllers.Repository
|
||||
{
|
||||
var caseWorkflowStatusRepository = new CaseWorkflowStatusRepository(dbContext, userName);
|
||||
var caseWorkflowStatuses = await caseWorkflowStatusRepository.GetByCasesWorkflowGuidActiveOnlyAsync(existing.CaseWorkflowGuid, token);
|
||||
var caseWorkflowStatus = caseWorkflowStatuses.FirstOrDefault(f => f.Guid == existing.CaseWorkflowStatusGuid);
|
||||
var caseWorkflowStatus = caseWorkflowStatuses.FirstOrDefault(f => f.Guid == model.CaseWorkflowStatusGuid);
|
||||
|
||||
if (caseWorkflowStatus == null)
|
||||
{
|
||||
@@ -388,36 +395,35 @@ namespace Jube.App.Controllers.Repository
|
||||
|
||||
if (model.Payload != null)
|
||||
{
|
||||
var jObject = JObject.Parse(model.Payload);
|
||||
|
||||
var values = new Dictionary<string, string>();
|
||||
foreach (var (key, value) in jObject)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
values.Add(key, value.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
if (caseWorkflowStatus.EnableNotification == 1 ||
|
||||
caseWorkflowStatus.EnableHttpEndpoint == 1)
|
||||
{
|
||||
var payload = JsonConvert.DeserializeObject<EntityAnalysisModelInstanceEntryPayload>(existing.Json, jsonSerializationHelper.DefaultJsonSerializerSettingsSettings);
|
||||
|
||||
if (caseWorkflowStatus.EnableNotification == 1)
|
||||
{
|
||||
var notification = new Notification(log, dynamicEnvironment);
|
||||
var notificationSubject = payload.ReplaceTokens(caseWorkflowStatus.NotificationSubject);
|
||||
var notificationDestination = payload.ReplaceTokens(caseWorkflowStatus.NotificationDestination);
|
||||
var notificationBody = payload.ReplaceTokens(caseWorkflowStatus.NotificationBody);
|
||||
|
||||
await notification.SendAsync(caseWorkflowStatus.NotificationTypeId ?? 1,
|
||||
caseWorkflowStatus.NotificationDestination,
|
||||
caseWorkflowStatus.NotificationSubject,
|
||||
caseWorkflowStatus.NotificationBody, values, token);
|
||||
notificationDestination,
|
||||
notificationSubject,
|
||||
notificationBody, token);
|
||||
}
|
||||
|
||||
if (caseWorkflowStatus.EnableHttpEndpoint == 1)
|
||||
{
|
||||
if (caseWorkflowStatus.HttpEndpointTypeId != null)
|
||||
var endpoint = payload.ReplaceTokens(caseWorkflowStatus.HttpEndpoint);
|
||||
|
||||
if (caseWorkflowStatus.HttpEndpointTypeId == 1)
|
||||
{
|
||||
await SendHttpEndpoint.SendAsync(caseWorkflowStatus.HttpEndpoint,
|
||||
caseWorkflowStatus.HttpEndpointTypeId.Value
|
||||
, values);
|
||||
await SendHttpEndpoint.PostAsync(endpoint, PreparePostBodyString(existing, payload, caseWorkflowStatus), log);
|
||||
}
|
||||
else
|
||||
{
|
||||
await SendHttpEndpoint.GetAsync(endpoint, log);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -460,5 +466,17 @@ namespace Jube.App.Controllers.Repository
|
||||
return StatusCode(500);
|
||||
}
|
||||
}
|
||||
|
||||
private string PreparePostBodyString(Case existing, EntityAnalysisModelInstanceEntryPayload payload, CaseWorkflowStatus caseWorkflowStatus)
|
||||
{
|
||||
var caseJObject = JObject.FromObject(existing, jsonSerializationHelper.ArchiveJsonSerializer);
|
||||
caseJObject["caseWorkflowStatusName"] = caseWorkflowStatus.Name;
|
||||
|
||||
var payloadJObject = JObject.FromObject(payload, jsonSerializationHelper.ArchiveJsonSerializer);
|
||||
caseJObject.Remove("json");
|
||||
caseJObject["payload"] = payloadJObject;
|
||||
|
||||
return caseJObject.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,11 +25,15 @@ namespace Jube.App.Controllers.Repository
|
||||
using Data.Repository;
|
||||
using Dto;
|
||||
using DynamicEnvironment;
|
||||
using Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
using Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload.Extensions;
|
||||
using Engine.Helpers;
|
||||
using FluentValidation;
|
||||
using log4net;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Validators;
|
||||
|
||||
@@ -40,16 +44,20 @@ namespace Jube.App.Controllers.Repository
|
||||
{
|
||||
private readonly DbContext dbContext;
|
||||
private readonly DynamicEnvironment dynamicEnvironment;
|
||||
private readonly JsonSerializationHelper jsonSerializationHelper;
|
||||
private readonly ILog log;
|
||||
private readonly IMapper mapper;
|
||||
private readonly PermissionValidation permissionValidation;
|
||||
private readonly CaseNoteRepository repository;
|
||||
private readonly CaseRepository repositoryCase;
|
||||
private readonly CaseNoteRepository repositoryCaseNote;
|
||||
private readonly CaseWorkflowActionRepository repositoryCaseWorkflowAction;
|
||||
private readonly CaseWorkflowStatusRepository repositoryCaseWorkflowStatus;
|
||||
private readonly string userName;
|
||||
private readonly IValidator<CaseNoteDto> validator;
|
||||
|
||||
public CaseNoteController(ILog log,
|
||||
DynamicEnvironment dynamicEnvironment
|
||||
, IHttpContextAccessor httpContextAccessor)
|
||||
, IHttpContextAccessor httpContextAccessor, JsonSerializationHelper jsonSerializationHelper)
|
||||
{
|
||||
if (httpContextAccessor.HttpContext?.User.Identity != null)
|
||||
{
|
||||
@@ -69,9 +77,13 @@ namespace Jube.App.Controllers.Repository
|
||||
});
|
||||
|
||||
mapper = new Mapper(config);
|
||||
repository = new CaseNoteRepository(dbContext, userName);
|
||||
repositoryCaseNote = new CaseNoteRepository(dbContext, userName);
|
||||
repositoryCase = new CaseRepository(dbContext, userName);
|
||||
repositoryCaseWorkflowAction = new CaseWorkflowActionRepository(dbContext, userName);
|
||||
repositoryCaseWorkflowStatus = new CaseWorkflowStatusRepository(dbContext, userName);
|
||||
validator = new CaseNoteDtoValidator();
|
||||
this.dynamicEnvironment = dynamicEnvironment;
|
||||
this.jsonSerializationHelper = jsonSerializationHelper;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
@@ -100,56 +112,86 @@ namespace Jube.App.Controllers.Repository
|
||||
|
||||
if (!results.IsValid)
|
||||
{
|
||||
return Ok(await repository.InsertAsync(mapper.Map<CaseNote>(model), token));
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var jObject = JObject.Parse(model.Payload);
|
||||
var existingCase = await repositoryCase.GetByIdActiveOnlyAsync(model.CaseId, token);
|
||||
|
||||
var values = new Dictionary<string, string>();
|
||||
foreach (var (key, value) in jObject)
|
||||
if (existingCase == null)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
values.Add(key, value.ToString());
|
||||
}
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var caseWorkflowActionRepository = new CaseWorkflowActionRepository(dbContext, userName);
|
||||
|
||||
var caseWorkflowAction = await caseWorkflowActionRepository.GetByIdActiveOnlyAsync(model.ActionId, token);
|
||||
var caseWorkflowAction = await repositoryCaseWorkflowAction.GetByIdActiveOnlyAsync(model.ActionId, token);
|
||||
|
||||
if (caseWorkflowAction == null)
|
||||
{
|
||||
return Forbid();
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var caseWorkflowStatus = await repositoryCaseWorkflowStatus.GetByGuidAsync(existingCase.CaseWorkflowStatusGuid, token);
|
||||
|
||||
if (caseWorkflowStatus == null)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var caseNote = await repositoryCaseNote.InsertAsync(mapper.Map<CaseNote>(model), token);
|
||||
|
||||
if (caseWorkflowAction.EnableNotification != 1 && caseWorkflowAction.EnableHttpEndpoint != 1)
|
||||
{
|
||||
return Ok(await repository.InsertAsync(mapper.Map<CaseNote>(model), token));
|
||||
return Ok(caseNote);
|
||||
}
|
||||
|
||||
var payload = JsonConvert.DeserializeObject<EntityAnalysisModelInstanceEntryPayload>(existingCase.Json, jsonSerializationHelper.DefaultJsonSerializerSettingsSettings);
|
||||
|
||||
if (caseWorkflowAction.EnableNotification == 1)
|
||||
{
|
||||
var notification = new Notification(log, dynamicEnvironment);
|
||||
var notificationSubject = payload.ReplaceTokens(caseWorkflowAction.NotificationSubject);
|
||||
var notificationDestination = payload.ReplaceTokens(caseWorkflowAction.NotificationDestination);
|
||||
var notificationBody = payload.ReplaceTokens(caseWorkflowAction.NotificationBody);
|
||||
|
||||
await notification.SendAsync(caseWorkflowAction.NotificationTypeId ?? 1,
|
||||
caseWorkflowAction.NotificationDestination,
|
||||
caseWorkflowAction.NotificationSubject,
|
||||
caseWorkflowAction.NotificationBody, values, token);
|
||||
notificationDestination,
|
||||
notificationSubject,
|
||||
notificationBody, token);
|
||||
}
|
||||
|
||||
if (caseWorkflowAction.EnableHttpEndpoint != 1)
|
||||
{
|
||||
return Ok(await repository.InsertAsync(mapper.Map<CaseNote>(model), token));
|
||||
return Ok(await repositoryCaseNote.InsertAsync(caseNote, token));
|
||||
}
|
||||
|
||||
if (caseWorkflowAction.HttpEndpointTypeId != null)
|
||||
var endpoint = payload.ReplaceTokens(caseWorkflowAction.HttpEndpoint);
|
||||
|
||||
if (caseWorkflowAction.HttpEndpointTypeId == 1)
|
||||
{
|
||||
await SendHttpEndpoint.SendAsync(caseWorkflowAction.HttpEndpoint,
|
||||
caseWorkflowAction.HttpEndpointTypeId.Value
|
||||
, values);
|
||||
await SendHttpEndpoint.PostAsync(endpoint, PreparePostBodyString(caseNote, existingCase, caseWorkflowStatus, caseWorkflowAction, payload), log);
|
||||
}
|
||||
else
|
||||
{
|
||||
await SendHttpEndpoint.GetAsync(endpoint, log);
|
||||
}
|
||||
|
||||
return Ok(await repository.InsertAsync(mapper.Map<CaseNote>(model), token));
|
||||
return Ok(caseNote);
|
||||
}
|
||||
|
||||
private string PreparePostBodyString(CaseNote caseNote, Case existingCase, CaseWorkflowStatus caseWorkflowStatus, CaseWorkflowAction caseWorkflowAction, EntityAnalysisModelInstanceEntryPayload payload)
|
||||
{
|
||||
var jObject = JObject.FromObject(caseNote, jsonSerializationHelper.ArchiveJsonSerializer);
|
||||
jObject["caseWorkflowActionName"] = caseWorkflowAction.Name;
|
||||
|
||||
var caseJObject = JObject.FromObject(existingCase, jsonSerializationHelper.ArchiveJsonSerializer);
|
||||
caseJObject.Remove("json");
|
||||
jObject["case"] = caseJObject;
|
||||
|
||||
caseJObject["caseWorkflowStatus"] = caseWorkflowStatus.Name;
|
||||
|
||||
var payloadJObject = JObject.FromObject(payload, jsonSerializationHelper.ArchiveJsonSerializer);
|
||||
caseJObject["payload"] = payloadJObject;
|
||||
|
||||
return jObject.ToString();
|
||||
}
|
||||
|
||||
[HttpGet("ByCaseKeyValue")]
|
||||
@@ -165,7 +207,7 @@ namespace Jube.App.Controllers.Repository
|
||||
return Forbid();
|
||||
}
|
||||
|
||||
return Ok(mapper.Map<List<CaseNote>>(await repository.GetByCaseKeyValueAsync(key, value, token)));
|
||||
return Ok(mapper.Map<List<CaseNote>>(await repositoryCaseNote.GetByCaseKeyValueAsync(key, value, token)));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -26,12 +26,16 @@ namespace Jube.App.Controllers.Repository
|
||||
using Data.Repository;
|
||||
using Dto;
|
||||
using DynamicEnvironment;
|
||||
using Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
using Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload.Extensions;
|
||||
using Engine.Helpers;
|
||||
using FluentValidation;
|
||||
using FluentValidation.Results;
|
||||
using log4net;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Validators;
|
||||
|
||||
@@ -42,15 +46,18 @@ namespace Jube.App.Controllers.Repository
|
||||
{
|
||||
private readonly DbContext dbContext;
|
||||
private readonly DynamicEnvironment dynamicEnvironment;
|
||||
private readonly JsonSerializationHelper jsonSerializationHelper;
|
||||
private readonly ILog log;
|
||||
private readonly IMapper mapper;
|
||||
private readonly PermissionValidation permissionValidation;
|
||||
private readonly CaseWorkflowFormEntryRepository repository;
|
||||
private readonly CaseWorkflowFormRepository repositoryCaseWorkflowForm;
|
||||
private readonly CaseWorkflowFormEntryRepository repositoryCaseWorkflowFormEntry;
|
||||
private readonly CaseWorkflowStatusRepository repositoryCaseWorkflowStatus;
|
||||
private readonly string userName;
|
||||
private readonly IValidator<CaseWorkflowFormEntryDto> validator;
|
||||
|
||||
public CaseWorkflowFormEntryController(ILog log,
|
||||
DynamicEnvironment dynamicEnvironment, IHttpContextAccessor httpContextAccessor)
|
||||
DynamicEnvironment dynamicEnvironment, IHttpContextAccessor httpContextAccessor, JsonSerializationHelper jsonSerializationHelper)
|
||||
{
|
||||
if (httpContextAccessor.HttpContext?.User.Identity != null)
|
||||
{
|
||||
@@ -70,7 +77,10 @@ namespace Jube.App.Controllers.Repository
|
||||
});
|
||||
|
||||
mapper = new Mapper(config);
|
||||
repository = new CaseWorkflowFormEntryRepository(dbContext, userName);
|
||||
repositoryCaseWorkflowFormEntry = new CaseWorkflowFormEntryRepository(dbContext, userName);
|
||||
repositoryCaseWorkflowStatus = new CaseWorkflowStatusRepository(dbContext, userName);
|
||||
repositoryCaseWorkflowForm = new CaseWorkflowFormRepository(dbContext, userName);
|
||||
this.jsonSerializationHelper = jsonSerializationHelper;
|
||||
validator = new CaseWorkflowFormEntryDtoValidator();
|
||||
this.dynamicEnvironment = dynamicEnvironment;
|
||||
}
|
||||
@@ -111,38 +121,38 @@ namespace Jube.App.Controllers.Repository
|
||||
var repositoryCase = new CaseRepository(dbContext, userName);
|
||||
var existingCase = await repositoryCase.GetByIdActiveOnlyAsync(model.CaseId, token);
|
||||
|
||||
if (existingCase == null)
|
||||
if (existingCase == null || model.Payload == null)
|
||||
{
|
||||
return Forbid();
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var entry = await repository.InsertAsync(mapper.Map<CaseWorkflowFormEntry>(model), token);
|
||||
var caseWorkflowStatus = await repositoryCaseWorkflowStatus.GetByGuidAsync(existingCase.CaseWorkflowStatusGuid, token);
|
||||
|
||||
if (model.Payload == null)
|
||||
if (caseWorkflowStatus == null)
|
||||
{
|
||||
return Ok(entry);
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var caseWorkflowForm = await repositoryCaseWorkflowForm.GetByIdAsync(model.CaseWorkflowFormId, token);
|
||||
|
||||
if (caseWorkflowForm == null)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var caseWorkflowEntry = mapper.Map<CaseWorkflowFormEntry>(model);
|
||||
var entry = await repositoryCaseWorkflowFormEntry.InsertAsync(caseWorkflowEntry, token);
|
||||
|
||||
var repositoryCaseWorkflowFormEntryValue =
|
||||
new CaseWorkflowFormEntryValueRepository(dbContext, userName);
|
||||
|
||||
var jObject = JObject.Parse(model.Payload);
|
||||
|
||||
var values = new Dictionary<string, string>();
|
||||
foreach (var (key, value) in jObject)
|
||||
foreach (var (key, value) in model.Payload)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
values.Add(key, value.ToString());
|
||||
|
||||
if (key == "CaseKey")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var caseWorkflowFormEntryValue = new CaseWorkflowFormEntryValue
|
||||
{
|
||||
CaseWorkflowFormEntryId = entry.Id,
|
||||
@@ -153,34 +163,37 @@ namespace Jube.App.Controllers.Repository
|
||||
await repositoryCaseWorkflowFormEntryValue.InsertAsync(caseWorkflowFormEntryValue, token);
|
||||
}
|
||||
|
||||
var caseWorkflowFormRepository = new CaseWorkflowFormRepository(dbContext, userName);
|
||||
|
||||
var caseWorkflowForm = await caseWorkflowFormRepository.GetByIdAsync(model.CaseWorkflowFormId, token);
|
||||
|
||||
if (caseWorkflowForm.EnableNotification != 1 && caseWorkflowForm.EnableHttpEndpoint != 1)
|
||||
{
|
||||
return Ok(entry);
|
||||
}
|
||||
|
||||
var archivePayload = JsonConvert.DeserializeObject<EntityAnalysisModelInstanceEntryPayload>(existingCase.Json, jsonSerializationHelper.DefaultJsonSerializerSettingsSettings);
|
||||
|
||||
if (caseWorkflowForm.EnableNotification == 1)
|
||||
{
|
||||
var notification = new Notification(log, dynamicEnvironment);
|
||||
var notificationSubject = archivePayload.ReplaceTokens(caseWorkflowForm.NotificationSubject);
|
||||
var notificationDestination = archivePayload.ReplaceTokens(caseWorkflowForm.NotificationDestination);
|
||||
var notificationBody = archivePayload.ReplaceTokens(caseWorkflowForm.NotificationBody);
|
||||
|
||||
await notification.SendAsync(caseWorkflowForm.NotificationTypeId ?? 1,
|
||||
caseWorkflowForm.NotificationDestination,
|
||||
caseWorkflowForm.NotificationSubject,
|
||||
caseWorkflowForm.NotificationBody, values, token);
|
||||
notificationDestination,
|
||||
notificationSubject,
|
||||
notificationBody, token);
|
||||
}
|
||||
|
||||
if (caseWorkflowForm.EnableHttpEndpoint != 1)
|
||||
if (caseWorkflowForm.EnableHttpEndpoint == 1)
|
||||
{
|
||||
return Ok(entry);
|
||||
}
|
||||
|
||||
if (caseWorkflowForm.HttpEndpointTypeId != null)
|
||||
{
|
||||
await SendHttpEndpoint.SendAsync(caseWorkflowForm.HttpEndpoint,
|
||||
caseWorkflowForm.HttpEndpointTypeId.Value
|
||||
, values);
|
||||
var endpoint = archivePayload.ReplaceTokens(caseWorkflowForm.HttpEndpoint);
|
||||
if (caseWorkflowStatus.HttpEndpointTypeId == 1)
|
||||
{
|
||||
await SendHttpEndpoint.PostAsync(endpoint, PreparePostBodyString(caseWorkflowEntry, model.Payload, archivePayload, existingCase, caseWorkflowStatus, caseWorkflowForm), log);
|
||||
}
|
||||
else
|
||||
{
|
||||
await SendHttpEndpoint.GetAsync(endpoint, log);
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(entry);
|
||||
@@ -192,6 +205,25 @@ namespace Jube.App.Controllers.Repository
|
||||
}
|
||||
}
|
||||
|
||||
private string PreparePostBodyString(CaseWorkflowFormEntry caseWorkflowEntry, Dictionary<string, object> formPayload, EntityAnalysisModelInstanceEntryPayload payload, Case existingCase, CaseWorkflowStatus caseWorkflowStatus, CaseWorkflowForm caseWorkflowForm)
|
||||
{
|
||||
var jObject = JObject.FromObject(caseWorkflowEntry, jsonSerializationHelper.ArchiveJsonSerializer);
|
||||
var payloadJObject = JObject.FromObject(formPayload);
|
||||
jObject["payload"] = payloadJObject;
|
||||
jObject["caseWorkflowFormName"] = caseWorkflowForm.Name;
|
||||
|
||||
var caseJObject = JObject.FromObject(existingCase, jsonSerializationHelper.ArchiveJsonSerializer);
|
||||
caseJObject.Remove("json");
|
||||
jObject["case"] = caseJObject;
|
||||
|
||||
caseJObject["caseWorkflowStatus"] = caseWorkflowStatus.Name;
|
||||
|
||||
var casePayloadJObject = JObject.FromObject(payload, jsonSerializationHelper.ArchiveJsonSerializer);
|
||||
caseJObject["payload"] = casePayloadJObject;
|
||||
|
||||
return jObject.ToString();
|
||||
}
|
||||
|
||||
[HttpGet("ByCaseKeyValue")]
|
||||
public async Task<ActionResult<List<CaseWorkflowFormEntryDto>>> GetByCaseKeyValueAsync(string key, string value, CancellationToken token = default)
|
||||
{
|
||||
@@ -205,7 +237,7 @@ namespace Jube.App.Controllers.Repository
|
||||
return Forbid();
|
||||
}
|
||||
|
||||
return Ok(mapper.Map<List<CaseWorkflowFormEntry>>(await repository.GetByCaseKeyValueActiveOnlyAsync(key, value, token)));
|
||||
return Ok(mapper.Map<List<CaseWorkflowFormEntry>>(await repositoryCaseWorkflowFormEntry.GetByCaseKeyValueActiveOnlyAsync(key, value, token)));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -116,10 +116,10 @@ namespace Jube.App.Controllers.Session
|
||||
var sw = new StopWatch();
|
||||
sw.Start();
|
||||
|
||||
var value = await postgres.ExecuteByOrderedParametersAsync(modelCompiled.SelectSqlSearch
|
||||
+ " "
|
||||
+ modelCompiled.WhereSql
|
||||
+ " " + modelCompiled.OrderSql + " limit 100", tokens, token).ConfigureAwait(false);
|
||||
var value = await postgres.ExecuteByOrderedParametersAsync(modelCompiled.SelectSqlSearch
|
||||
+ " "
|
||||
+ modelCompiled.WhereSql
|
||||
+ " " + modelCompiled.OrderSql + " limit 100", tokens, token).ConfigureAwait(false);
|
||||
|
||||
sw.Stop();
|
||||
|
||||
@@ -146,7 +146,7 @@ namespace Jube.App.Controllers.Session
|
||||
|
||||
private async Task<SessionCaseSearchCompiledSql> CheckRebuildAsync(SessionCaseSearchCompiledSql modelCompiled, CancellationToken token = default)
|
||||
{
|
||||
if (modelCompiled.Rebuild == 1 && modelCompiled.RebuildDate != null)
|
||||
if (modelCompiled.Rebuild == 1 && (modelCompiled.RebuildDate != null || modelCompiled.RebuildDate == default(DateTime)))
|
||||
{
|
||||
return await CompileSql.CompileAsync(dbContext, modelCompiled, userName, token).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
+4
-4
@@ -11,11 +11,11 @@
|
||||
* see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload
|
||||
namespace Jube.App.Dto
|
||||
{
|
||||
// ReSharper disable once ClassNeverInstantiated.Global
|
||||
public class EntityModelActivationRulePayload
|
||||
public class CaseWorkflowDisplayExecutionDto
|
||||
{
|
||||
public bool Visible { get; set; }
|
||||
public int CaseId { get; set; }
|
||||
public int CaseWorkflowDisplayId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ namespace Jube.App.Dto
|
||||
public bool Active { get; set; }
|
||||
public string SelectJson { get; set; }
|
||||
public string FilterJson { get; set; }
|
||||
public string FilterTokens { get; set; }
|
||||
public string Description { get; set; }
|
||||
public bool EnableHttpEndpoint { get; set; }
|
||||
public string HttpEndpoint { get; set; }
|
||||
|
||||
@@ -2,23 +2,24 @@
|
||||
*
|
||||
* This file is part of Jube™ software.
|
||||
*
|
||||
* Jube™ is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License
|
||||
* Jube™ is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* Jube™ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* Jube™ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License along with Jube™. If not,
|
||||
* You should have received a copy of the GNU Affero General Public License along with Jube™. If not,
|
||||
* see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Jube.App.Dto
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class CaseWorkflowFormEntryDto
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Payload { get; set; }
|
||||
public Dictionary<string, object> Payload { get; set; }
|
||||
public DateTime CreatedDate { get; set; }
|
||||
public string CreatedUser { get; set; }
|
||||
public string CaseKey { get; set; }
|
||||
@@ -26,4 +27,4 @@ namespace Jube.App.Dto
|
||||
public int CaseWorkflowFormId { get; set; }
|
||||
public string CaseKeyValue { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
*
|
||||
* This file is part of Jube™ software.
|
||||
*
|
||||
* Jube™ is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License
|
||||
* Jube™ is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* Jube™ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* Jube™ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License along with Jube™. If not,
|
||||
* You should have received a copy of the GNU Affero General Public License along with Jube™. If not,
|
||||
* see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Jube.App.Dto
|
||||
{
|
||||
public class CaseWorkflowMacroExecutionDto
|
||||
{
|
||||
public int CaseId { get; set; }
|
||||
public int CaseWorkflowMacroId { get; set; }
|
||||
public string Payload { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
<tr>
|
||||
<td class="sTBorderStyle"><label for="NotificationBody">Body</label></td>
|
||||
<td>
|
||||
<textarea id="NotificationBody"></textarea>
|
||||
<textarea class="generalTextArea" id="NotificationBody"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
<tr>
|
||||
<td class="sTBorderStyle"><label for="NotificationBody">Body</label></td>
|
||||
<td>
|
||||
<textarea id="NotificationBody"></textarea>
|
||||
<textarea class="generalTextArea" id="NotificationBody"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -150,7 +150,7 @@
|
||||
<label for="NotificationBody">Body</label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea id="NotificationBody"></textarea>
|
||||
<textarea class="generalTextArea" id="NotificationBody"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
+13
-15
@@ -29,6 +29,7 @@ namespace Jube.App
|
||||
using Code.WatcherDispatch;
|
||||
using DynamicEnvironment;
|
||||
using Engine;
|
||||
using Engine.Helpers;
|
||||
using FluentMigrator.Runner;
|
||||
using log4net;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
@@ -63,17 +64,17 @@ namespace Jube.App
|
||||
{
|
||||
var cancellationTokenProvider = AddSingletonForCancellationToken(services);
|
||||
var taskCoordinator = AddSingletonForTaskCoordinator(services, cancellationTokenProvider);
|
||||
var contractResolver = AddSingletonForDefaultContractResolver(services);
|
||||
var contractResolver = AddSingletonForJsonSerializationHelper(services);
|
||||
|
||||
var dynamicEnvironment = AddSingletonForDynamicEnvironmentAndLogging(services, out var log);
|
||||
ConfigureThreadPool(dynamicEnvironment, log);
|
||||
ValidateConnectionToPostgres(dynamicEnvironment.AppSettings("ConnectionString"), log);
|
||||
|
||||
var callbacks = AddSingletonForCallbacks(services);
|
||||
|
||||
|
||||
var cacheService = AddSingletonForCacheService(services, callbacks, Int32.Parse(dynamicEnvironment.AppSettings("CallbackTimeout") ?? "10000"),
|
||||
taskCoordinator, dynamicEnvironment, log);
|
||||
|
||||
|
||||
var rabbitMqConnection = AddSingletonForRabbitMqConnection(services, dynamicEnvironment, log);
|
||||
|
||||
AddSingletonForEngine(services, dynamicEnvironment, log, rabbitMqConnection, cacheService, contractResolver, taskCoordinator);
|
||||
@@ -254,14 +255,14 @@ namespace Jube.App
|
||||
|
||||
private static void AddSingletonForEngine(IServiceCollection services
|
||||
, DynamicEnvironment dynamicEnvironment, ILog log, IConnection rabbitMqConnection,
|
||||
CacheService cacheService, DefaultContractResolver contractResolver, ITaskCoordinator taskCoordinator)
|
||||
CacheService cacheService, JsonSerializationHelper jsonSerializationHelper, ITaskCoordinator taskCoordinator)
|
||||
{
|
||||
if (!dynamicEnvironment.AppSettings("EnableEngine").Equals("True", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var engine = new Engine(dynamicEnvironment, log, rabbitMqConnection, cacheService, contractResolver, taskCoordinator);
|
||||
var engine = new Engine(dynamicEnvironment, log, rabbitMqConnection, cacheService, jsonSerializationHelper, taskCoordinator);
|
||||
|
||||
services.AddSingleton(engine);
|
||||
}
|
||||
@@ -334,15 +335,12 @@ namespace Jube.App
|
||||
return dynamicEnvironment;
|
||||
}
|
||||
|
||||
private static DefaultContractResolver AddSingletonForDefaultContractResolver(IServiceCollection services)
|
||||
private static JsonSerializationHelper AddSingletonForJsonSerializationHelper(IServiceCollection services)
|
||||
{
|
||||
|
||||
var contractResolver = new DefaultContractResolver
|
||||
{
|
||||
NamingStrategy = new CamelCaseNamingStrategy()
|
||||
};
|
||||
services.AddSingleton(contractResolver);
|
||||
return contractResolver;
|
||||
var jsonSerializationHelper = new JsonSerializationHelper();
|
||||
services.AddSingleton(jsonSerializationHelper);
|
||||
return jsonSerializationHelper;
|
||||
}
|
||||
|
||||
private static void ValidateConnectionToPostgres(string connectionString, ILog log)
|
||||
@@ -503,10 +501,10 @@ namespace Jube.App
|
||||
}
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
|
||||
var lifetime = app.ApplicationServices.GetRequiredService<IHostApplicationLifetime>();
|
||||
app.UseWhen(context => context.Request.Path.StartsWithSegments("/api") &&
|
||||
lifetime.ApplicationStopping.IsCancellationRequested,
|
||||
lifetime.ApplicationStopping.IsCancellationRequested,
|
||||
branch => branch.UseConditionalConnectionCloseWhenStopping());
|
||||
|
||||
app.UseWhen(context => context.Request.Path.StartsWithSegments("/Account/Login"), appBuilder =>
|
||||
@@ -666,7 +664,7 @@ namespace Jube.App
|
||||
{
|
||||
log.Debug("Start: No manual thread pool parameters have been set will configure based on CPU count and certain other estimates.");
|
||||
}
|
||||
|
||||
|
||||
var logicalCores = Environment.ProcessorCount;
|
||||
var workerThreads = logicalCores * 2;
|
||||
var ioThreads = logicalCores * 4;
|
||||
|
||||
@@ -292,10 +292,10 @@ $(document).ready(function () {
|
||||
|
||||
$("#CaseFormSubmitButton").click(function (e) {
|
||||
e.preventDefault();
|
||||
const clonedArray = JSON.parse(JSON.stringify(values));
|
||||
let clonedArray = {};
|
||||
const $inputs = jQuery('#CaseFormHTML :input');
|
||||
$inputs.each(function () {
|
||||
clonedArray[this.name] = jQuery(this).val();
|
||||
clonedArray[this.id] = jQuery(this).val();
|
||||
});
|
||||
|
||||
const buttonObject = $("#CaseFormSubmitButton").kendoButton().data("kendoButton");
|
||||
@@ -308,7 +308,7 @@ $(document).ready(function () {
|
||||
contentType: "application/json; charset=utf-8",
|
||||
dataType: "json",
|
||||
data: JSON.stringify({
|
||||
payload: JSON.stringify(clonedArray),
|
||||
payload: clonedArray,
|
||||
caseWorkflowFormId: SelectedCasesWorkflowFormID,
|
||||
caseKey: CaseKey,
|
||||
caseKeyValue: CaseKeyValue,
|
||||
@@ -546,8 +546,8 @@ function CallMacro(e) {
|
||||
if (Macros[i].id === e) {
|
||||
try {
|
||||
const data = {
|
||||
caseWorkflowMacroId: Macros[i].id,
|
||||
payload: JSON.stringify(values)
|
||||
caseId: CaseId,
|
||||
caseWorkflowMacroId: Macros[i].id
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
@@ -1211,22 +1211,23 @@ function DisplayMenu(selectedCasesWorkflowDisplayId) {
|
||||
$.each(Displays,
|
||||
function (i, displayValue) {
|
||||
if (displayValue.id === selectedCasesWorkflowDisplayId) {
|
||||
$("#CaseDisplayHTML").show();
|
||||
const data = {
|
||||
caseId: CaseId,
|
||||
caseWorkflowDisplayId: selectedCasesWorkflowDisplayId
|
||||
};
|
||||
|
||||
let finalHtml = displayValue.html;
|
||||
const tokens = displayValue.html.match(/\[@(.*?)]/g);
|
||||
$.each(tokens,
|
||||
function (j, tokenValue) {
|
||||
const token = tokenValue.slice(2, -2);
|
||||
$.each(ResponsePayload,
|
||||
function (k, responsePayloadValue) {
|
||||
if (token === responsePayloadValue.name) {
|
||||
finalHtml = finalHtml.replace(tokens[j], responsePayloadValue.value);
|
||||
}
|
||||
});
|
||||
});
|
||||
$.ajax({
|
||||
url: "../api/CaseWorkflowDisplayExecution",
|
||||
type: "POST",
|
||||
contentType: "application/json; charset=utf-8",
|
||||
dataType: "json",
|
||||
data: JSON.stringify(data),
|
||||
success: function (data) {
|
||||
$("#CaseDisplayHTML").html(data);
|
||||
$("#CaseDisplayHTML").show();
|
||||
}
|
||||
});
|
||||
|
||||
$("#CaseDisplayHTML").html(finalHtml);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
@@ -1482,16 +1483,6 @@ function createActivations(activationsData) {
|
||||
function customEditor(container, options) {
|
||||
$('<textarea required name="' + options.field + '" style="height: 100px; width: 100%;" />')
|
||||
.appendTo(container);
|
||||
/* .kendoAutoComplete({
|
||||
minLength: 3,
|
||||
dataTextField: "NoteSuggestion",
|
||||
filter: "contains",
|
||||
dataSource: {
|
||||
type: "json",
|
||||
serverFiltering: true,
|
||||
transport: { read: "/Service/GetNoteSuggestions.ashx" }
|
||||
}
|
||||
});*/
|
||||
}
|
||||
|
||||
function SaveCaseKeyJournalSession(columns) {
|
||||
@@ -1675,4 +1666,6 @@ function DisplayServerValidationErrors(responseObject) {
|
||||
for (let key in responseObject.errors) {
|
||||
list.append('<li>' + responseObject.errors[key].errorMessage + '</li>')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//# sourceURL=Case.js
|
||||
@@ -189,17 +189,20 @@ function OnSelect(e) {
|
||||
if (typeof item.caseWorkflowId !== "undefined") {
|
||||
$.get("../api/CaseWorkflowFilter/ByGuid/" + item.guid,
|
||||
function (data) {
|
||||
if (!data.notFound) {
|
||||
if (typeof data !== "undefined") {
|
||||
const currentBuildJson = {
|
||||
filterJson: JSON.parse(data.filterJson),
|
||||
selectJson: JSON.parse(data.selectJson)
|
||||
};
|
||||
if (typeof data !== "undefined") {
|
||||
const currentBuildJson = {
|
||||
filterJson: JSON.parse(data.filterJson),
|
||||
selectJson: JSON.parse(data.selectJson),
|
||||
|
||||
CompileSqlOnServer(data.filterJson, data.selectJson, data.filterJson, item.parentNode().guid, item.guid, item.guid, true, true);
|
||||
initCaseFilterBuilder(true, currentCaseWorkflowGuid, currentBuildJson);
|
||||
jsonChangedFromFilterDefault = false;
|
||||
};
|
||||
|
||||
if (data.filterTokens !== "undefined") {
|
||||
currentBuildJson["filterTokens"] = JSON.parse(data.filterTokens);
|
||||
}
|
||||
|
||||
CompileSqlOnServer(data.filterJson, data.selectJson, null, item.parentNode().guid, item.guid, item.guid, true, true);
|
||||
initCaseFilterBuilder(true, currentCaseWorkflowGuid, currentBuildJson);
|
||||
jsonChangedFromFilterDefault = false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@@ -212,7 +215,11 @@ function OnSelect(e) {
|
||||
selectJson: JSON.parse(data.selectJson)
|
||||
};
|
||||
|
||||
CompileSqlOnServer(data.filterJson, data.selectJson, data.filterJson, data.caseWorkflowGuid, data.caseWorkflowFilterGuid, true, true);
|
||||
if (data.filterTokens !== "undefined") {
|
||||
currentBuildJson["filterTokens"] = JSON.parse(data.filterTokens);
|
||||
}
|
||||
|
||||
CompileSqlOnServer(data.filterJson, data.selectJson, data.filterTokens, data.caseWorkflowGuid, data.caseWorkflowFilterGuid, true, true);
|
||||
initCaseFilterBuilder(true, currentCaseWorkflowGuid, currentBuildJson);
|
||||
jsonChangedFromFilterDefault = true;
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@ if (typeof id === "undefined") {
|
||||
function (data) {
|
||||
const casesFilterBuilder = {
|
||||
filterJson: JSON.parse(data.filterJson),
|
||||
selectJson: JSON.parse(data.selectJson)
|
||||
selectJson: JSON.parse(data.selectJson),
|
||||
filterTokens: JSON.parse(data.filterTokens),
|
||||
};
|
||||
|
||||
initCaseFilterBuilder(false, parentKey, casesFilterBuilder);
|
||||
@@ -48,7 +49,7 @@ function GetData() {
|
||||
selectJson: builderResult.selectJson,
|
||||
filterJson: builderResult.filterJson,
|
||||
filterSql: builderResult.filterSql,
|
||||
filterTokens: builderResult.filterTokens
|
||||
filterTokens: JSON.stringify(builderResult.params, null, 2)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -16,4 +16,8 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Context\"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -19,74 +19,18 @@ namespace Jube.Case
|
||||
public class Notification(ILog log, DynamicEnvironment dynamicEnvironment)
|
||||
{
|
||||
public async Task SendAsync(int notificationType, string notificationDestination, string notificationSubject,
|
||||
string notificationBody, Dictionary<string, string> values, CancellationToken token = default
|
||||
string notificationBody, CancellationToken token = default
|
||||
)
|
||||
{
|
||||
var replacedNotificationDestination = notificationDestination;
|
||||
if (!String.IsNullOrEmpty(replacedNotificationDestination))
|
||||
{
|
||||
var notificationDestinationTokens =
|
||||
Tokenisation.ReturnTokens(replacedNotificationDestination);
|
||||
|
||||
foreach (var notificationToken in notificationDestinationTokens)
|
||||
{
|
||||
if (!values.TryGetValue(notificationToken, out var value))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var notificationReplaceToken = $"[@{notificationToken}@]";
|
||||
replacedNotificationDestination =
|
||||
replacedNotificationDestination.Replace(notificationReplaceToken,
|
||||
value);
|
||||
}
|
||||
}
|
||||
|
||||
var replacedNotificationSubject = notificationSubject;
|
||||
if (!String.IsNullOrEmpty(replacedNotificationSubject))
|
||||
{
|
||||
var notificationSubjectTokens = Tokenisation.ReturnTokens(replacedNotificationSubject);
|
||||
foreach (var notificationToken in notificationSubjectTokens)
|
||||
{
|
||||
if (!values.TryGetValue(notificationToken, out var value))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var notificationReplaceToken = $"[@{notificationToken}@]";
|
||||
replacedNotificationSubject =
|
||||
replacedNotificationSubject.Replace(notificationReplaceToken, value);
|
||||
}
|
||||
}
|
||||
|
||||
var replacedNotificationBody = notificationBody;
|
||||
if (!String.IsNullOrEmpty(replacedNotificationBody))
|
||||
{
|
||||
var notificationBodyTokens = Tokenisation.ReturnTokens(replacedNotificationBody);
|
||||
|
||||
foreach (var notificationToken in notificationBodyTokens)
|
||||
{
|
||||
if (!values.TryGetValue(notificationToken, out var value))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var notificationReplaceToken = $"[@{notificationToken}@]";
|
||||
replacedNotificationBody =
|
||||
replacedNotificationBody.Replace(notificationReplaceToken, value);
|
||||
}
|
||||
}
|
||||
|
||||
if (notificationType == 1)
|
||||
{
|
||||
var sendMail = new SendMail(dynamicEnvironment, log);
|
||||
sendMail.Send(replacedNotificationDestination, replacedNotificationSubject,
|
||||
replacedNotificationBody);
|
||||
sendMail.Send(notificationDestination, notificationSubject, notificationBody);
|
||||
}
|
||||
else
|
||||
{
|
||||
var sendSms = new SendSms(dynamicEnvironment, log);
|
||||
await sendSms.SendAsync(replacedNotificationDestination, replacedNotificationBody, token);
|
||||
await sendSms.SendAsync(notificationDestination, notificationBody, token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,46 +14,52 @@
|
||||
namespace Jube.Case
|
||||
{
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
using log4net;
|
||||
|
||||
public static class SendHttpEndpoint
|
||||
{
|
||||
public static async Task SendAsync(string httpEndpoint, byte httpEndpointTypeId, Dictionary<string, string> values)
|
||||
public static async Task PostAsync(string httpEndpoint, string body, ILog log)
|
||||
{
|
||||
if (String.IsNullOrEmpty(httpEndpoint))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var urlTokens = Tokenisation.ReturnTokens(httpEndpoint);
|
||||
using var client = new HttpClient();
|
||||
|
||||
var replacedUrl = httpEndpoint;
|
||||
foreach (var token in urlTokens)
|
||||
try
|
||||
{
|
||||
if (values.TryGetValue(token, out var replacement))
|
||||
{
|
||||
replacedUrl = replacedUrl.Replace($"[@{token}@]", replacement);
|
||||
}
|
||||
using var content = new StringContent(body, Encoding.UTF8, "application/json");
|
||||
using var response = await client.PostAsync(httpEndpoint, content).ConfigureAwait(false);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Error($"Failed to dispatch to {httpEndpoint} for verb POST with payload {body} with {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task GetAsync(string httpEndpoint, ILog log)
|
||||
{
|
||||
if (String.IsNullOrEmpty(httpEndpoint))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var client = new HttpClient();
|
||||
|
||||
if (httpEndpointTypeId == 1)
|
||||
try
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(values);
|
||||
using var content = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
|
||||
using var response = await client.PostAsync(replacedUrl, content).ConfigureAwait(false);
|
||||
using var response = await client.GetAsync(httpEndpoint).ConfigureAwait(false);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
catch (Exception ex)
|
||||
{
|
||||
using var response = await client.GetAsync(replacedUrl).ConfigureAwait(false);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
log.Error($"Failed to dispatch to {httpEndpoint} for verb GET with {ex}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -955,13 +955,12 @@ namespace Jube.Data.Poco
|
||||
[Key(0)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column] [Nullable] [Key(1)] public string Payload { get; set; }
|
||||
[Column] [Nullable] [Key(2)] public DateTime? CreatedDate { get; set; }
|
||||
[Column] [Nullable] [Key(3)] public string CreatedUser { get; set; }
|
||||
[Column] [Nullable] [Key(4)] public string CaseKey { get; set; }
|
||||
[Column] [Nullable] [Key(5)] public int? CaseId { get; set; }
|
||||
[Column] [Nullable] [Key(6)] public int? CaseWorkflowFormId { get; set; }
|
||||
[Column] [Nullable] [Key(7)] public string CaseKeyValue { get; set; }
|
||||
[Column] [Nullable] [Key(1)] public DateTime? CreatedDate { get; set; }
|
||||
[Column] [Nullable] [Key(2)] public string CreatedUser { get; set; }
|
||||
[Column] [Nullable] [Key(3)] public string CaseKey { get; set; }
|
||||
[Column] [Nullable] [Key(4)] public int? CaseId { get; set; }
|
||||
[Column] [Nullable] [Key(5)] public int? CaseWorkflowFormId { get; set; }
|
||||
[Column] [Nullable] [Key(6)] public string CaseKeyValue { get; set; }
|
||||
|
||||
[Association(ThisKey = "CaseId", OtherKey = "Id", CanBeNull = true,
|
||||
Relationship = Relationship.ManyToOne)]
|
||||
|
||||
@@ -105,6 +105,18 @@ namespace Jube.Data.Repository
|
||||
&& w.Id == id && (w.Deleted == 0 || w.Deleted == null), token);
|
||||
}
|
||||
|
||||
public Task<CaseWorkflowDisplay> GetByIdActiveOnlyAsync(int id, CancellationToken token = default)
|
||||
{
|
||||
return dbContext.CaseWorkflowDisplay.FirstOrDefaultAsync(w =>
|
||||
w.CaseWorkflow.EntityAnalysisModel.TenantRegistryId == tenantRegistryId
|
||||
&& w.Id == id && (w.Deleted == 0 || w.Deleted == null)
|
||||
&& w.Active == 1
|
||||
&& (w.CaseWorkflowDisplayRole.RoleRegistry.UserRegistry.Name == userName
|
||||
&& w.CaseWorkflowDisplayRole.Deleted == 0 || w.CaseWorkflowDisplayRole.Deleted == null)
|
||||
&& (w.CaseWorkflow.CaseWorkflowRole.RoleRegistry.UserRegistry.Name == userName
|
||||
&& w.CaseWorkflow.CaseWorkflowRole.Deleted == 0 || w.CaseWorkflow.CaseWorkflowRole.Deleted == null), token);
|
||||
}
|
||||
|
||||
public async Task<CaseWorkflowDisplay> InsertAsync(CaseWorkflowDisplay model, CancellationToken token = default)
|
||||
{
|
||||
model.CreatedUser = userName;
|
||||
@@ -132,7 +144,7 @@ namespace Jube.Data.Repository
|
||||
|
||||
model.Version = existing.Version + 1;
|
||||
model.CreatedUser = userName ?? model.CreatedUser;
|
||||
model.Guid = model.Guid == Guid.Empty ? Guid.NewGuid() : model.Guid;
|
||||
model.Guid = existing.Guid;
|
||||
model.CreatedDate = DateTime.Now;
|
||||
|
||||
await dbContext.UpdateAsync(model, token: token);
|
||||
|
||||
@@ -100,12 +100,6 @@ namespace Jube.Dictionary
|
||||
return TryAddInternal(key, new InternalValue(value));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool TryAdd(string key, Guid value)
|
||||
{
|
||||
return TryAddInternal(key, new InternalValue(value));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool ContainsKey(string key)
|
||||
{
|
||||
@@ -191,6 +185,12 @@ namespace Jube.Dictionary
|
||||
return estimatedSizeBytes;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool TryAdd(string key, Guid value)
|
||||
{
|
||||
return TryAddInternal(key, new InternalValue(value));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static long EstimateStringSize(string? s)
|
||||
{
|
||||
|
||||
@@ -49,7 +49,6 @@
|
||||
<Folder Include="Extensions\System.String\zzzRegexPattern\"/>
|
||||
<Folder Include="Extensions\System.String\_CoreObject\"/>
|
||||
<Folder Include="Extensions\System.String\_ExtractValueType\"/>
|
||||
<Folder Include="Serialization\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -30,6 +30,10 @@ namespace Jube.Dictionary
|
||||
private TKey[] keys;
|
||||
private TValue[] values;
|
||||
|
||||
public PooledDictionary() : this(null)
|
||||
{
|
||||
}
|
||||
|
||||
public PooledDictionary(int? initialCapacity = null)
|
||||
{
|
||||
if (initialCapacity.HasValue)
|
||||
|
||||
+40
-17
@@ -11,23 +11,15 @@
|
||||
* see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Jube.Cache.Redis.Serialization.DictionaryNoBoxing.Newtonsoft
|
||||
namespace Jube.Dictionary.Serialization
|
||||
{
|
||||
using Dictionary.Models;
|
||||
using global::Newtonsoft.Json;
|
||||
using DictionaryNoBoxing=Dictionary.DictionaryNoBoxing;
|
||||
using Models;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
public class DictionaryNoBoxingValueOnlyNewtonsoftConverter : JsonConverter<DictionaryNoBoxing>
|
||||
public class DictionaryNoBoxingConverter : JsonConverter<DictionaryNoBoxing>
|
||||
{
|
||||
public override bool CanRead
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, DictionaryNoBoxing value, JsonSerializer serializer)
|
||||
public override void WriteJson(JsonWriter writer, DictionaryNoBoxing? value, JsonSerializer serializer)
|
||||
{
|
||||
writer.WriteStartObject();
|
||||
|
||||
@@ -59,7 +51,8 @@ namespace Jube.Cache.Redis.Serialization.DictionaryNoBoxing.Newtonsoft
|
||||
case InternalValue.ValueType.None:
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
writer.WriteNull();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,9 +60,39 @@ namespace Jube.Cache.Redis.Serialization.DictionaryNoBoxing.Newtonsoft
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
|
||||
public override DictionaryNoBoxing ReadJson(JsonReader reader, Type objectType, DictionaryNoBoxing existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
public override DictionaryNoBoxing ReadJson(JsonReader reader, Type objectType,
|
||||
DictionaryNoBoxing? existing, bool hasExisting, JsonSerializer serializer)
|
||||
{
|
||||
throw new NotImplementedException("Deserialization not implemented.");
|
||||
var dict = existing ?? new DictionaryNoBoxing();
|
||||
var obj = JObject.Load(reader);
|
||||
|
||||
foreach (var prop in obj.Properties())
|
||||
{
|
||||
var token = prop.Value;
|
||||
switch (token.Type)
|
||||
{
|
||||
case JTokenType.Float:
|
||||
dict.Add(prop.Name, token.Value<double>());
|
||||
break;
|
||||
case JTokenType.Integer:
|
||||
dict.Add(prop.Name, token.Value<int>());
|
||||
break;
|
||||
case JTokenType.Boolean:
|
||||
dict.Add(prop.Name, token.Value<bool>());
|
||||
break;
|
||||
case JTokenType.Date:
|
||||
dict.Add(prop.Name, token.Value<DateTime>());
|
||||
break;
|
||||
case JTokenType.Null:
|
||||
dict.Add(prop.Name, null);
|
||||
break;
|
||||
default:
|
||||
dict.Add(prop.Name, token.Value<string>());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ namespace Jube.Engine.BackgroundTasks.Context
|
||||
public JsonSerializationHelper JsonSerializationHelper
|
||||
{
|
||||
get;
|
||||
set;
|
||||
} = new JsonSerializationHelper();
|
||||
|
||||
public Services Services
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
namespace Jube.Engine.BackgroundTasks.TaskStarters.Case
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Data.Context;
|
||||
@@ -10,8 +9,12 @@ namespace Jube.Engine.BackgroundTasks.TaskStarters.Case
|
||||
using Data.Repository;
|
||||
using DynamicEnvironment;
|
||||
using EntityAnalysisModelInvoke.Models.CaseManagement;
|
||||
using EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
using EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload.Extensions;
|
||||
using Helpers;
|
||||
using Jube.Case;
|
||||
using log4net;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
public static class CaseProcessing
|
||||
@@ -19,6 +22,8 @@ namespace Jube.Engine.BackgroundTasks.TaskStarters.Case
|
||||
public static async Task CreateAsync(DynamicEnvironment dynamicEnvironment,
|
||||
CreateCase createCase,
|
||||
ILog log,
|
||||
JsonSerializationHelper jsonSerializationHelper,
|
||||
EntityAnalysisModelInstanceEntryPayload payload = null,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var dbContext =
|
||||
@@ -80,8 +85,7 @@ namespace Jube.Engine.BackgroundTasks.TaskStarters.Case
|
||||
|
||||
var existing = await query.ExecuteAsync(model.CaseWorkflowGuid, model.CaseKey, model.CaseKeyValue, token).ConfigureAwait(false);
|
||||
|
||||
var repositoryCasesWorkflowsStatus =
|
||||
new CaseWorkflowStatusRepository(dbContext, createCase.TenantRegistryId);
|
||||
var repositoryCasesWorkflowsStatus = new CaseWorkflowStatusRepository(dbContext, createCase.TenantRegistryId);
|
||||
|
||||
CaseWorkflowStatus finalCasesWorkflowsStatus = null;
|
||||
if (existing == null)
|
||||
@@ -114,36 +118,36 @@ namespace Jube.Engine.BackgroundTasks.TaskStarters.Case
|
||||
if (finalCasesWorkflowsStatus != null)
|
||||
{
|
||||
caseBytes = createCase.Json.Length;
|
||||
var jObject = JObject.Parse(model.Json);
|
||||
|
||||
var values = new Dictionary<string, string>();
|
||||
foreach (var (key, value) in jObject)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
values.Add(key, value.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
if (finalCasesWorkflowsStatus.EnableNotification == 1 ||
|
||||
finalCasesWorkflowsStatus.EnableHttpEndpoint == 1)
|
||||
{
|
||||
|
||||
var context = payload ?? JsonConvert.DeserializeObject<EntityAnalysisModelInstanceEntryPayload>(createCase.Json, jsonSerializationHelper.DefaultJsonSerializerSettingsSettings);
|
||||
|
||||
if (finalCasesWorkflowsStatus.EnableNotification == 1)
|
||||
{
|
||||
var notificationSubject = context.ReplaceTokens(finalCasesWorkflowsStatus.NotificationSubject);
|
||||
var notificationDestination = context.ReplaceTokens(finalCasesWorkflowsStatus.NotificationDestination);
|
||||
var notificationBody = context.ReplaceTokens(finalCasesWorkflowsStatus.NotificationBody);
|
||||
|
||||
var notification = new Notification(log, dynamicEnvironment);
|
||||
await notification.SendAsync(finalCasesWorkflowsStatus.NotificationTypeId ?? 1,
|
||||
finalCasesWorkflowsStatus.NotificationDestination,
|
||||
finalCasesWorkflowsStatus.NotificationSubject,
|
||||
finalCasesWorkflowsStatus.NotificationBody, values, token);
|
||||
notificationDestination,
|
||||
notificationSubject,
|
||||
notificationBody, token);
|
||||
}
|
||||
|
||||
if (finalCasesWorkflowsStatus.EnableHttpEndpoint == 1)
|
||||
{
|
||||
if (finalCasesWorkflowsStatus.HttpEndpointTypeId != null)
|
||||
var endpoint = context.ReplaceTokens(finalCasesWorkflowsStatus.HttpEndpoint);
|
||||
if (finalCasesWorkflowsStatus.HttpEndpointTypeId == 1)
|
||||
{
|
||||
await SendHttpEndpoint.SendAsync(finalCasesWorkflowsStatus.HttpEndpoint,
|
||||
finalCasesWorkflowsStatus.HttpEndpointTypeId.Value
|
||||
, values);
|
||||
await SendHttpEndpoint.PostAsync(endpoint, PreparePostBodyString(model, jsonSerializationHelper.ArchiveJsonSerializer, finalCasesWorkflowsStatus), log);
|
||||
}
|
||||
else
|
||||
{
|
||||
await SendHttpEndpoint.GetAsync(endpoint, log);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -175,5 +179,23 @@ namespace Jube.Engine.BackgroundTasks.TaskStarters.Case
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string PreparePostBodyString(Case createCase, JsonSerializer jsonSerializer, CaseWorkflowStatus finalCasesWorkflowsStatus, EntityAnalysisModelInstanceEntryPayload payload = null)
|
||||
{
|
||||
var jObject = JObject.FromObject(createCase, jsonSerializer);
|
||||
|
||||
if (payload == null)
|
||||
{
|
||||
jObject["context"] = JObject.Parse(createCase.Json);
|
||||
}
|
||||
else
|
||||
{
|
||||
jObject["context"] = JObject.FromObject(payload);
|
||||
}
|
||||
|
||||
jObject["caseWorkflowStatus"] = finalCasesWorkflowsStatus.Name;
|
||||
jObject.Remove("json");
|
||||
return jObject.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,12 +37,12 @@ namespace Jube.Engine.BackgroundTasks.TaskStarters
|
||||
if (!context.ConcurrentQueues.PendingCases.TryDequeue(out var createCase))
|
||||
{
|
||||
await Task.Delay(100);
|
||||
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
await CaseProcessing.CreateAsync(context.Services.DynamicEnvironment,
|
||||
createCase, context.Services.Log);
|
||||
createCase, context.Services.Log, context.JsonSerializationHelper);
|
||||
|
||||
// ReSharper disable once RedundantAssignment
|
||||
createCase = null;
|
||||
|
||||
@@ -20,8 +20,8 @@ namespace Jube.Engine
|
||||
using Cache;
|
||||
using DynamicEnvironment;
|
||||
using Exhaustive;
|
||||
using Helpers;
|
||||
using log4net;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using RabbitMQ.Client;
|
||||
using TaskCancellation;
|
||||
using Context=BackgroundTasks.Context.Context;
|
||||
@@ -31,18 +31,18 @@ namespace Jube.Engine
|
||||
ILog log,
|
||||
IConnection rabbitMqConnection,
|
||||
CacheService cacheService,
|
||||
DefaultContractResolver contractResolver,
|
||||
JsonSerializationHelper jsonSerializationHelper,
|
||||
ITaskCoordinator taskCoordinator)
|
||||
{
|
||||
public readonly Context Context = new Context
|
||||
{
|
||||
JsonSerializationHelper = jsonSerializationHelper,
|
||||
Services =
|
||||
{
|
||||
DynamicEnvironment = dynamicEnvironment,
|
||||
Log = log,
|
||||
RabbitMqConnection = rabbitMqConnection,
|
||||
CacheService = cacheService,
|
||||
ContractResolver = contractResolver,
|
||||
TaskCoordinator = taskCoordinator
|
||||
}
|
||||
};
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Context
|
||||
using System.Threading.Tasks;
|
||||
using DynamicEnvironment;
|
||||
using log4net;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntry;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
using TaskCancellation.TaskHelper;
|
||||
using EntityAnalysisModel=EntityAnalysisModelManager.EntityAnalysisModel.EntityAnalysisModel;
|
||||
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Context.Extensions.AbstractionRu
|
||||
using EntityAnalysisModelManager.EntityAnalysisModel.Models.Models;
|
||||
using Helpers;
|
||||
using log4net;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntry;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
|
||||
public static class EntityAnalysisModelAbstractionRuleAggregatorUtility
|
||||
{
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Context.Extensions.AbstractionRu
|
||||
using EntityAnalysisModelManager.EntityAnalysisModel.Models.Models;
|
||||
using log4net;
|
||||
using Microsoft.VisualBasic;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntry;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
using ReflectionHelpers;
|
||||
using TaskCancellation.TaskHelper;
|
||||
|
||||
@@ -146,7 +146,7 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Context.Extensions.AbstractionRu
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
foreach (var kvp in abstractionRuleMatches)
|
||||
{
|
||||
AbstractionRuleMatches[kvp.Key] = kvp.Value;
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Context.Extensions
|
||||
if (context.EntityAnalysisModelInstanceEntryPayload.EntityAnalysisModelReprocessingRuleInstanceId.HasValue)
|
||||
{
|
||||
await ArchiverProcessing.CaseCreationAndArchiveStorageAsync(context.EntityAnalysisModelInstanceEntryPayload,
|
||||
context.EntityAnalysisModel.JsonSerializationHelper.ArchiveJsonSerializer,
|
||||
context.EntityAnalysisModel.JsonSerializationHelper,
|
||||
null, null, context.Environment, context.Log).ConfigureAwait(false);
|
||||
|
||||
if (context.Log.IsInfoEnabled)
|
||||
|
||||
+4
-53
@@ -14,11 +14,10 @@
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Context.Extensions.ActivationRules
|
||||
{
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using EntityAnalysisModelManager.EntityAnalysisModel.Models.Models;
|
||||
using Helpers;
|
||||
using Models;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntryPayload.Extensions;
|
||||
using Newtonsoft.Json;
|
||||
using RabbitMQ.Client;
|
||||
|
||||
@@ -36,9 +35,9 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Context.Extensions.ActivationRul
|
||||
|
||||
var notification = new Notification
|
||||
{
|
||||
NotificationBody = ReplaceTokens(context, evaluateActivationRule.NotificationBody),
|
||||
NotificationDestination = ReplaceTokens(context, evaluateActivationRule.NotificationDestination),
|
||||
NotificationSubject = ReplaceTokens(context, evaluateActivationRule.NotificationSubject),
|
||||
NotificationBody = context.EntityAnalysisModelInstanceEntryPayload.ReplaceTokens(evaluateActivationRule.NotificationBody),
|
||||
NotificationDestination = context.EntityAnalysisModelInstanceEntryPayload.ReplaceTokens(evaluateActivationRule.NotificationDestination),
|
||||
NotificationSubject = context.EntityAnalysisModelInstanceEntryPayload.ReplaceTokens(evaluateActivationRule.NotificationSubject),
|
||||
NotificationTypeId = evaluateActivationRule.NotificationTypeId
|
||||
};
|
||||
|
||||
@@ -74,53 +73,5 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Context.Extensions.ActivationRul
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string ReplaceTokens(Context context, string message)
|
||||
{
|
||||
var notificationTokenizationList = NotificationTokenization.ReturnTokens(message);
|
||||
|
||||
if (context.Log.IsInfoEnabled)
|
||||
{
|
||||
context.Log.Info(
|
||||
$"Entity Invoke: GUID {context.EntityAnalysisModelInstanceEntryPayload.EntityAnalysisModelInstanceEntryGuid} and model {context.EntityAnalysisModel.Instance.Id} has found {notificationTokenizationList.Count} tokens in message {message}.");
|
||||
}
|
||||
|
||||
foreach (var notificationToken in notificationTokenizationList)
|
||||
{
|
||||
var notificationTokenValue = "";
|
||||
if (context.EntityAnalysisModelInstanceEntryPayload.Payload.TryGetValue(notificationToken, out var valuePayload))
|
||||
{
|
||||
notificationTokenValue = valuePayload.ToString();
|
||||
}
|
||||
else if (context.EntityAnalysisModelInstanceEntryPayload.Abstraction.TryGetValue(notificationToken,
|
||||
out var valueAbstraction))
|
||||
{
|
||||
notificationTokenValue = valueAbstraction.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
else if (context.EntityAnalysisModelInstanceEntryPayload.TtlCounter.TryGetValue(notificationToken,
|
||||
out var valueTtlCounter))
|
||||
{
|
||||
notificationTokenValue = valueTtlCounter.ToString();
|
||||
}
|
||||
else if (
|
||||
context.EntityAnalysisModelInstanceEntryPayload.AbstractionCalculation.TryGetValue(notificationToken,
|
||||
out var valueAbstractionCalculation))
|
||||
{
|
||||
notificationTokenValue = valueAbstractionCalculation
|
||||
.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
var notificationReplaceToken = $"[@{notificationToken}@]";
|
||||
message = message.Replace(notificationReplaceToken, notificationTokenValue);
|
||||
|
||||
if (context.Log.IsInfoEnabled)
|
||||
{
|
||||
context.Log.Info(
|
||||
$"Entity Invoke: GUID {context.EntityAnalysisModelInstanceEntryPayload.EntityAnalysisModelInstanceEntryGuid} and model {context.EntityAnalysisModel.Instance.Id} has finalized notification message {message}.");
|
||||
}
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Context.Extensions.ActivationRul
|
||||
{
|
||||
using System;
|
||||
using EntityAnalysisModelManager.EntityAnalysisModel.Models.Models;
|
||||
using Models;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
|
||||
public static class ActivationRuleResponseElevationExtensions
|
||||
{
|
||||
|
||||
+2
-2
@@ -21,7 +21,7 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Context.Extensions.ActivationRul
|
||||
using Data.Poco;
|
||||
using EntityAnalysisModelManager.EntityAnalysisModel.Models.Models.EntityAnalysisModelInlineScript;
|
||||
using Models.CaseManagement;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntry;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
using RabbitMQ.Client;
|
||||
using ReflectionHelpers;
|
||||
using EntityAnalysisModel=EntityAnalysisModelManager.EntityAnalysisModel.EntityAnalysisModel;
|
||||
@@ -117,7 +117,7 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Context.Extensions.ActivationRul
|
||||
context.Log.Info(
|
||||
$"Entity Invoke: GUID {context.EntityAnalysisModelInstanceEntryPayload.EntityAnalysisModelInstanceEntryGuid} and model {context.EntityAnalysisModel.Instance.Id} has finished testing the activation rule and it has a matched status of {matched}.");
|
||||
}
|
||||
|
||||
|
||||
if (context.Log.IsInfoEnabled)
|
||||
{
|
||||
context.Log.Info(
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Context.Extensions.ReflectionHel
|
||||
using EntityAnalysisModelManager.EntityAnalysisModel;
|
||||
using EntityAnalysisModelManager.EntityAnalysisModel.Models.Models;
|
||||
using log4net;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntry;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
|
||||
public static class ReflectRuleHelper
|
||||
{
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Context.Extensions
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntry.TasksPerformance;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntryPayload.TasksPerformance;
|
||||
using TaskCancellation.TaskHelper;
|
||||
|
||||
public static class WaitReadTasksExtensions
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Context.Extensions
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntry.TasksPerformance;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntryPayload.TasksPerformance;
|
||||
using TaskCancellation.TaskHelper;
|
||||
|
||||
public static class WaitWriteTasksExtensions
|
||||
|
||||
+5
-5
@@ -16,21 +16,21 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Context.Extensions
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Dictionary;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntry;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
using RabbitMQ.Client;
|
||||
|
||||
public static class WriteResponseJsonAndQueueAsynchronousResponseMessageExtension
|
||||
{
|
||||
public static async Task WriteResponseJsonAndQueueAsynchronousResponseMessageAsync(this Context context, IModel rabbitMqChannel)
|
||||
{
|
||||
if (context.Environment.AppSettings("PartialResponseMessageSerialisation").Equals("True",StringComparison.CurrentCultureIgnoreCase))
|
||||
if (context.Environment.AppSettings("PartialResponseMessageSerialisation").Equals("True", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
if (context.Log.IsInfoEnabled)
|
||||
{
|
||||
context.Log.Info(
|
||||
$"HTTP Handler Entity: GUID payload {context.EntityAnalysisModelInstanceEntryPayload.EntityAnalysisModelInstanceEntryGuid} model id is {context.EntityAnalysisModel.Instance.Id} has partial serialised response environment variable.");
|
||||
}
|
||||
|
||||
|
||||
context.JsonResult = BuildJsonResponses.BuildPartialResponsePayloadJson(context);
|
||||
}
|
||||
else
|
||||
@@ -40,10 +40,10 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Context.Extensions
|
||||
context.Log.Info(
|
||||
$"HTTP Handler Entity: GUID payload {context.EntityAnalysisModelInstanceEntryPayload.EntityAnalysisModelInstanceEntryGuid} model id is {context.EntityAnalysisModel.Instance.Id} has partial serialised response environment variable false and will serialise full response.");
|
||||
}
|
||||
|
||||
|
||||
context.JsonResult = BuildJsonResponses.BuildFullJson(context.EntityAnalysisModelInstanceEntryPayload, context.EntityAnalysisModel.JsonSerializationHelper.ArchiveJsonSerializer);
|
||||
}
|
||||
|
||||
|
||||
if (context.Environment.AppSettings("AMQP").Equals("True", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
PublishToAmqp(context, rabbitMqChannel);
|
||||
|
||||
@@ -23,11 +23,11 @@ namespace Jube.Engine.EntityAnalysisModelInvoke
|
||||
using Exceptions;
|
||||
using Extraction;
|
||||
using Models.Payload.AsyncInvocationCallbackToken;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntry;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
using TaskCancellation.TaskHelper;
|
||||
using EntityAnalysisModel=EntityAnalysisModelManager.EntityAnalysisModel.EntityAnalysisModel;
|
||||
|
||||
public class EntityAnalysisModelInvoke
|
||||
public static class EntityAnalysisModelInvoke
|
||||
{
|
||||
public static async Task<Context.Context> InvokeAsync(EntityAnalysisModel entityAnalysisModel,
|
||||
MemoryStream inputStream, int? maxBytes = null,
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Extraction
|
||||
using DynamicEnvironment;
|
||||
using Helpers;
|
||||
using log4net;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntry;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
using EntityAnalysisModel=EntityAnalysisModelManager.EntityAnalysisModel.EntityAnalysisModel;
|
||||
|
||||
public class EntityAnalysisModelDictionaryNoBoxingExtractor(
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Extraction
|
||||
using Extensions.YourNamespace.Extensions;
|
||||
using Helpers;
|
||||
using log4net;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntry;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using EntityAnalysisModel=EntityAnalysisModelManager.EntityAnalysisModel.EntityAnalysisModel;
|
||||
|
||||
|
||||
@@ -13,14 +13,14 @@
|
||||
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Extraction.Extensions
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Data.Poco;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntry;
|
||||
using Jube.Engine.EntityAnalysisModelManager.EntityAnalysisModel.Models.Models;
|
||||
|
||||
namespace YourNamespace.Extensions
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Data.Poco;
|
||||
using EntityAnalysisModelManager.EntityAnalysisModel.Models.Models;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
|
||||
public static class ArchiveKeyExtensions
|
||||
{
|
||||
|
||||
+2
-2
@@ -15,8 +15,8 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Extraction.Helpers
|
||||
{
|
||||
using System;
|
||||
using Dictionary;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntry;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntry.TasksPerformance;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
using Models.Payload.EntityAnalysisModelInstanceEntryPayload.TasksPerformance;
|
||||
using EntityAnalysisModel=EntityAnalysisModelManager.EntityAnalysisModel.EntityAnalysisModel;
|
||||
|
||||
public static class EntityAnalysisModelInstanceEntryPayloadHelpers
|
||||
|
||||
-63
@@ -1,63 +0,0 @@
|
||||
/* Copyright (C) 2022-present Jube Holdings Limited.
|
||||
*
|
||||
* This file is part of Jube™ software.
|
||||
*
|
||||
* Jube™ is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* Jube™ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License along with Jube™. If not,
|
||||
* see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Cache.Redis.Serialization.DictionaryNoBoxing.Newtonsoft;
|
||||
using CaseManagement;
|
||||
using Data.Poco;
|
||||
using Dictionary;
|
||||
using Newtonsoft.Json;
|
||||
using TasksPerformance;
|
||||
|
||||
|
||||
|
||||
public class EntityAnalysisModelInstanceEntryPayload
|
||||
{
|
||||
[JsonProperty(Order = 1)] [JsonConverter(typeof(DictionaryNoBoxingValueOnlyNewtonsoftConverter))] public DictionaryNoBoxing Payload { get; set; }
|
||||
[JsonProperty(Order = 2)] public ResponseElevation ResponseElevation { get; set; } = new ResponseElevation();
|
||||
[JsonProperty(Order = 3)] public string EntityAnalysisModelInstanceName { get; set; }
|
||||
[JsonProperty(Order = 4)] public double R { get; set; }
|
||||
[JsonProperty(Order = 5)] public DateTime CreatedDate { get; set; }
|
||||
[JsonProperty(Order = 6)] public Guid EntityAnalysisModelGuid { get; set; }
|
||||
[JsonProperty(Order = 7)] public string EntityAnalysisModelName { get; set; }
|
||||
[JsonProperty(Order = 8)] public Guid EntityAnalysisModelInstanceGuid { get; set; }
|
||||
[JsonProperty(Order = 9)] public Guid EntityAnalysisModelInstanceEntryGuid { get; set; }
|
||||
[JsonProperty(Order = 10)] public string EntityInstanceEntryId { get; set; }
|
||||
[JsonProperty(Order = 11)] public double ResponseElevationLimit { get; set; }
|
||||
[JsonProperty(Order = 12)] public DateTime ReferenceDate { get; set; }
|
||||
[JsonProperty(Order = 13)] public int? EntityAnalysisModelReprocessingRuleInstanceId { get; set; }
|
||||
[JsonProperty(Order = 14)] public DateTime ArchiveEnqueueDate { get; set; }
|
||||
[JsonProperty(Order = 15)] public bool MatchedGatewayRule { get; set; }
|
||||
[JsonProperty(Order = 16)] public int? PrevailingEntityAnalysisModelActivationRuleId { get; set; }
|
||||
[JsonProperty(Order = 17)] public string PrevailingEntityAnalysisModelActivationRuleName { get; set; }
|
||||
[JsonProperty(Order = 18)] public int EntityAnalysisModelActivationRuleCount { get; set; }
|
||||
[JsonProperty(Order = 19)] public PooledDictionary<string, double> Dictionary { get; set; }
|
||||
[JsonProperty(Order = 20)] public PooledDictionary<string, long> TtlCounter { get; set; }
|
||||
[JsonProperty(Order = 21)] public PooledDictionary<string, double> Sanction { get; set; }
|
||||
[JsonProperty(Order = 22)] public PooledDictionary<string, double> Abstraction { get; set; }
|
||||
[JsonProperty(Order = 23)] public PooledDictionary<string, double> AbstractionCalculation { get; set; }
|
||||
[JsonProperty(Order = 24)] public PooledDictionary<string, double> HttpAdaptation { get; set; }
|
||||
[JsonProperty(Order = 25)] public PooledDictionary<string, double> ExhaustiveAdaptation { get; set; }
|
||||
[JsonProperty(Order = 26)] public PooledDictionary<string, EntityModelActivationRulePayload> Activation { get; set; }
|
||||
[JsonProperty(Order = 27)] public CreateCase CreateCasePayload { get; set; }
|
||||
[JsonProperty(Order = 28)] public PooledDictionary<string, double> Tag { get; set; }
|
||||
[JsonProperty(Order = 30)] public InvokeTaskPerformance InvokeTaskPerformance { get; set; }
|
||||
[JsonIgnore] public List<ArchiveKey> ArchiveKeys { get; init; }
|
||||
[JsonIgnore] public bool EnableRdbmsArchive { get; init; }
|
||||
[JsonIgnore] public int EntityAnalysisModelId { get; init; }
|
||||
[JsonIgnore] public int TenantRegistryId { get; init; }
|
||||
}
|
||||
}
|
||||
+40
-40
@@ -11,7 +11,7 @@
|
||||
* see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntry
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload
|
||||
{
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -74,28 +74,28 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisMod
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
private static void AddTagToJObject(Context context, JObject jObject)
|
||||
{
|
||||
|
||||
var kvpEntityAnalysisModelTags= context.EntityAnalysisModel.Collections.EntityAnalysisModelTags.Where(w => w.ResponsePayload).ToArray();
|
||||
var kvpEntityAnalysisModelTags = context.EntityAnalysisModel.Collections.EntityAnalysisModelTags.Where(w => w.ResponsePayload).ToArray();
|
||||
if (!kvpEntityAnalysisModelTags.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var kvpEntityAnalysisModelTagsArray = new JArray();
|
||||
jObject.Add("Tag",kvpEntityAnalysisModelTagsArray);
|
||||
jObject.Add("Tag", kvpEntityAnalysisModelTagsArray);
|
||||
foreach (var kvpEntityAnalysisModelTag in kvpEntityAnalysisModelTags)
|
||||
{
|
||||
var value = context.EntityAnalysisModelInstanceEntryPayload.Activation.FirstOrDefault(f => f.Key == kvpEntityAnalysisModelTag.Name);
|
||||
if (value.Key != null)
|
||||
{
|
||||
kvpEntityAnalysisModelTagsArray.Add(JToken.FromObject(value));
|
||||
kvpEntityAnalysisModelTagsArray.Add(JToken.FromObject(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void AddActivationToJObject(Context context, JObject jObject)
|
||||
{
|
||||
|
||||
@@ -104,19 +104,19 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisMod
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var kvpModelActivationRulesArray = new JArray();
|
||||
jObject.Add("Activation",kvpModelActivationRulesArray);
|
||||
jObject.Add("Activation", kvpModelActivationRulesArray);
|
||||
foreach (var kvpModelActivationRule in kvpModelActivationRules)
|
||||
{
|
||||
var value = context.EntityAnalysisModelInstanceEntryPayload.Activation.FirstOrDefault(f => f.Key == kvpModelActivationRule.Name);
|
||||
if (value.Key != null)
|
||||
{
|
||||
kvpModelActivationRulesArray.Add(JToken.FromObject(value));
|
||||
kvpModelActivationRulesArray.Add(JToken.FromObject(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void AddExhaustiveAdaptationToJObject(Context context, JObject jObject)
|
||||
{
|
||||
|
||||
@@ -125,19 +125,19 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisMod
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var kvpExhaustiveModelsArray = new JArray();
|
||||
jObject.Add("ExhaustiveAdaptation",kvpExhaustiveModelsArray);
|
||||
jObject.Add("ExhaustiveAdaptation", kvpExhaustiveModelsArray);
|
||||
foreach (var kvpExhaustiveModel in kvpExhaustiveModels)
|
||||
{
|
||||
var value = context.EntityAnalysisModelInstanceEntryPayload.ExhaustiveAdaptation.FirstOrDefault(f => f.Key == kvpExhaustiveModel.Name);
|
||||
if (value.Key != null)
|
||||
{
|
||||
kvpExhaustiveModelsArray.Add(JToken.FromObject(value));
|
||||
kvpExhaustiveModelsArray.Add(JToken.FromObject(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void AddHttpAdaptationToJObject(Context context, JObject jObject)
|
||||
{
|
||||
|
||||
@@ -146,19 +146,19 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisMod
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var kvpEntityAnalysisModelAdaptationsArray = new JArray();
|
||||
jObject.Add("HttpAdaptation",kvpEntityAnalysisModelAdaptationsArray);
|
||||
jObject.Add("HttpAdaptation", kvpEntityAnalysisModelAdaptationsArray);
|
||||
foreach (var kvpEntityAnalysisModelAdaptation in kvpEntityAnalysisModelAdaptations)
|
||||
{
|
||||
var value = context.EntityAnalysisModelInstanceEntryPayload.ExhaustiveAdaptation.FirstOrDefault(f => f.Key == kvpEntityAnalysisModelAdaptation.Value.Name);
|
||||
if (value.Key != null)
|
||||
{
|
||||
kvpEntityAnalysisModelAdaptationsArray.Add(JToken.FromObject(value));
|
||||
kvpEntityAnalysisModelAdaptationsArray.Add(JToken.FromObject(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void AddAbstractionCalculationToJObject(Context context, JObject jObject)
|
||||
{
|
||||
|
||||
@@ -167,19 +167,19 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisMod
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var kvpEntityAnalysisModelAbstractionCalculationsArray = new JArray();
|
||||
jObject.Add("AbstractionCalculation",kvpEntityAnalysisModelAbstractionCalculationsArray);
|
||||
jObject.Add("AbstractionCalculation", kvpEntityAnalysisModelAbstractionCalculationsArray);
|
||||
foreach (var kvpEntityAnalysisModelAbstractionCalculation in kvpEntityAnalysisModelAbstractionCalculations)
|
||||
{
|
||||
var value = context.EntityAnalysisModelInstanceEntryPayload.AbstractionCalculation.FirstOrDefault(f => f.Key == kvpEntityAnalysisModelAbstractionCalculation.Name);
|
||||
if (value.Key != null)
|
||||
{
|
||||
kvpEntityAnalysisModelAbstractionCalculationsArray.Add(JToken.FromObject(value));
|
||||
kvpEntityAnalysisModelAbstractionCalculationsArray.Add(JToken.FromObject(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void AddAbstractionToJObject(Context context, JObject jObject)
|
||||
{
|
||||
|
||||
@@ -188,19 +188,19 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisMod
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var kvpAbstractionsJArray = new JArray();
|
||||
jObject.Add("Abstraction",kvpAbstractionsJArray);
|
||||
jObject.Add("Abstraction", kvpAbstractionsJArray);
|
||||
foreach (var kvpAbstraction in kvpAbstractions)
|
||||
{
|
||||
var value = context.EntityAnalysisModelInstanceEntryPayload.Abstraction.FirstOrDefault(f => f.Key == kvpAbstraction.Name);
|
||||
if (value.Key != null)
|
||||
{
|
||||
kvpAbstractionsJArray.Add(JToken.FromObject(value));
|
||||
kvpAbstractionsJArray.Add(JToken.FromObject(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void AddSanctionToJObject(Context context, JObject jObject)
|
||||
{
|
||||
|
||||
@@ -209,19 +209,19 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisMod
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var kvpEntityAnalysisModelSanctionsArray = new JArray();
|
||||
jObject.Add("Sanction",kvpEntityAnalysisModelSanctionsArray);
|
||||
jObject.Add("Sanction", kvpEntityAnalysisModelSanctionsArray);
|
||||
foreach (var kvpEntityAnalysisModelSanction in kvpEntityAnalysisModelSanctions)
|
||||
{
|
||||
var value = context.EntityAnalysisModelInstanceEntryPayload.Sanction.FirstOrDefault(f => f.Key == kvpEntityAnalysisModelSanction.Name);
|
||||
if (value.Key != null)
|
||||
{
|
||||
kvpEntityAnalysisModelSanctionsArray.Add(JToken.FromObject(value));
|
||||
kvpEntityAnalysisModelSanctionsArray.Add(JToken.FromObject(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void AddTtlCounterToJObject(Context context, JObject jObject)
|
||||
{
|
||||
|
||||
@@ -230,19 +230,19 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisMod
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var kvpModelTtlCountersArray = new JArray();
|
||||
jObject.Add("TtlCounter",kvpModelTtlCountersArray);
|
||||
jObject.Add("TtlCounter", kvpModelTtlCountersArray);
|
||||
foreach (var kvpModelTtlCounter in kvpModelTtlCounters)
|
||||
{
|
||||
var value = context.EntityAnalysisModelInstanceEntryPayload.TtlCounter.FirstOrDefault(f => f.Key == kvpModelTtlCounter.Name);
|
||||
if (value.Key != null)
|
||||
{
|
||||
kvpModelTtlCountersArray.Add(JToken.FromObject(value));
|
||||
kvpModelTtlCountersArray.Add(JToken.FromObject(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void AddDictionaryToJObject(Context context, JObject jObject)
|
||||
{
|
||||
|
||||
@@ -251,19 +251,19 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisMod
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var kvpDictionariesJArray = new JArray();
|
||||
jObject.Add("Dictionary",kvpDictionariesJArray);
|
||||
jObject.Add("Dictionary", kvpDictionariesJArray);
|
||||
foreach (var kvpDictionary in kvpDictionaries)
|
||||
{
|
||||
var value = context.EntityAnalysisModelInstanceEntryPayload.Dictionary.FirstOrDefault(f => f.Key == kvpDictionary.Value.Name);
|
||||
if (value.Key != null)
|
||||
{
|
||||
kvpDictionariesJArray.Add(JToken.FromObject(value));
|
||||
kvpDictionariesJArray.Add(JToken.FromObject(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void AddCreateCaseToJObject(Context context, JObject jObject)
|
||||
{
|
||||
|
||||
@@ -272,7 +272,7 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisMod
|
||||
jObject.Add("CreateCase", JToken.FromObject(context.EntityAnalysisModelInstanceEntryPayload.CreateCase));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static JObject CreateJObject(Context context)
|
||||
{
|
||||
|
||||
+2
-3
@@ -11,11 +11,10 @@
|
||||
* see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntry
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Cache.Redis.Serialization.DictionaryNoBoxing.Newtonsoft;
|
||||
using CaseManagement;
|
||||
using Data.Poco;
|
||||
using Dictionary;
|
||||
@@ -24,7 +23,7 @@ namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisMod
|
||||
|
||||
public class EntityAnalysisModelInstanceEntryPayload
|
||||
{
|
||||
[JsonProperty(Order = 1)] [JsonConverter(typeof(DictionaryNoBoxingValueOnlyNewtonsoftConverter))] public DictionaryNoBoxing Payload { get; set; }
|
||||
[JsonProperty(Order = 1)] public DictionaryNoBoxing Payload { get; set; }
|
||||
[JsonProperty(Order = 2)] public ResponseElevation ResponseElevation { get; set; } = new ResponseElevation();
|
||||
[JsonProperty(Order = 3)] public string EntityAnalysisModelInstanceName { get; set; }
|
||||
[JsonProperty(Order = 4)] public double R { get; set; }
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
* see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntry
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload
|
||||
{
|
||||
public class EntityModelActivationRulePayload
|
||||
{
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/* Copyright (C) 2022-present Jube Holdings Limited.
|
||||
*
|
||||
* This file is part of Jube™ software.
|
||||
*
|
||||
* Jube™ is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* Jube™ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License along with Jube™. If not,
|
||||
* see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload.Extensions
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Case;
|
||||
|
||||
public static class EntityAnalysisModelInstanceEntryPayloadExtensions
|
||||
{
|
||||
public static string ReplaceTokens(this EntityAnalysisModelInstanceEntryPayload entityAnalysisModelInstanceEntryPayload, string existing)
|
||||
{
|
||||
var lookup = new Dictionary<string, Func<string, string>>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
["Payload"] = key => entityAnalysisModelInstanceEntryPayload.Payload.TryGetValue(key, out var v) ? v.ToString() : null,
|
||||
["Abstraction"] = key => entityAnalysisModelInstanceEntryPayload.Abstraction.TryGetValue(key, out var v) ? v.ToString(CultureInfo.InvariantCulture) : null,
|
||||
["Dictionary"] = key => entityAnalysisModelInstanceEntryPayload.Dictionary.TryGetValue(key, out var v) ? v.ToString(CultureInfo.InvariantCulture) : null,
|
||||
["TtlCounter"] = key => entityAnalysisModelInstanceEntryPayload.TtlCounter.TryGetValue(key, out var v) ? v.ToString(CultureInfo.InvariantCulture) : null,
|
||||
["Sanction"] = key => entityAnalysisModelInstanceEntryPayload.Sanction.TryGetValue(key, out var v) ? v.ToString(CultureInfo.InvariantCulture) : null,
|
||||
["HttpAdaptation"] = key => entityAnalysisModelInstanceEntryPayload.HttpAdaptation.TryGetValue(key, out var v) ? v.ToString(CultureInfo.InvariantCulture) : null,
|
||||
["ExhaustiveAdaptation"] = key => entityAnalysisModelInstanceEntryPayload.ExhaustiveAdaptation.TryGetValue(key, out var v) ? v.ToString(CultureInfo.InvariantCulture) : null,
|
||||
["Activation"] = key => entityAnalysisModelInstanceEntryPayload.Activation.ContainsKey(key) ? "true" : "false"
|
||||
};
|
||||
|
||||
var result = existing;
|
||||
|
||||
foreach (var token in Tokenisation.ReturnTokens(existing))
|
||||
{
|
||||
var splits = token.Split('.', 2);
|
||||
if (splits.Length < 2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!lookup.TryGetValue(splits[0], out var resolver))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var value = resolver(splits[1]);
|
||||
if (value is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
result = result.Replace($"[@{token}@]", value);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
* see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Models
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload
|
||||
{
|
||||
using System;
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
* see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntry.TasksPerformance
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload.TasksPerformance
|
||||
{
|
||||
|
||||
public class InvokeTaskPerformance
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
* see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntry.TasksPerformance
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload.TasksPerformance
|
||||
{
|
||||
public class InvokeTasksPerformance
|
||||
{
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
* see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntry.TasksPerformance
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload.TasksPerformance
|
||||
{
|
||||
public class ReadTasksPerformance
|
||||
{
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
// ReSharper disable UnusedMember.Global
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntry.TasksPerformance
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload.TasksPerformance
|
||||
{
|
||||
public class TaskPerformance(long computeTime, long memory)
|
||||
{
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
* see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntry.TasksPerformance
|
||||
namespace Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload.TasksPerformance
|
||||
{
|
||||
public class WriteTasksPerformance
|
||||
{
|
||||
+2
-2
@@ -23,8 +23,8 @@ namespace Jube.Engine.EntityAnalysisModelManager.BackgroundTasks.TaskStarters.Ab
|
||||
using EntityAnalysisModel;
|
||||
using EntityAnalysisModel.Models.Models;
|
||||
using EntityAnalysisModelInvoke.Context.Extensions.ReflectionHelpers;
|
||||
using EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntry;
|
||||
using EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntry.TasksPerformance;
|
||||
using EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
using EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload.TasksPerformance;
|
||||
using Microsoft.VisualBasic;
|
||||
|
||||
public static class AbstractionRuleCaching
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ namespace Jube.Engine.EntityAnalysisModelManager.BackgroundTasks.TaskStarters.Ab
|
||||
using EntityAnalysisModel;
|
||||
using EntityAnalysisModel.Models.Models;
|
||||
using EntityAnalysisModelInvoke.Context.Extensions.AbstractionRulesWithSearchKeys;
|
||||
using EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntry;
|
||||
using EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
using log4net;
|
||||
using Microsoft.VisualBasic;
|
||||
|
||||
|
||||
+4
-4
@@ -22,7 +22,7 @@ namespace Jube.Engine.EntityAnalysisModelManager.BackgroundTasks.TaskStarters.Ar
|
||||
using Data.Poco;
|
||||
using Data.Repository;
|
||||
using DynamicEnvironment;
|
||||
using EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntry;
|
||||
using EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
using log4net;
|
||||
|
||||
public static class ArchiverArchiveRepository
|
||||
@@ -44,7 +44,7 @@ namespace Jube.Engine.EntityAnalysisModelManager.BackgroundTasks.TaskStarters.Ar
|
||||
var dbContext =
|
||||
DataConnectionDbContext.GetDbContextDataConnection(dynamicEnvironment.AppSettings("ConnectionString"));
|
||||
dbContext.CommandTimeout = 0;
|
||||
|
||||
|
||||
if (log.IsInfoEnabled)
|
||||
{
|
||||
log.Info("Database Persist: Opened an SQL Bulk Collection via repository.");
|
||||
@@ -58,7 +58,7 @@ namespace Jube.Engine.EntityAnalysisModelManager.BackgroundTasks.TaskStarters.Ar
|
||||
}
|
||||
catch (Exception ex) when (ex is not OperationCanceledException)
|
||||
{
|
||||
bulkInsertMessageBuffer.Archive.Clear(); //TODO[RC]: Create a dead letter archive.
|
||||
bulkInsertMessageBuffer.Archive.Clear();
|
||||
log.Error($"Database Persist: Archive Bulk Copy failed {ex}.");
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace Jube.Engine.EntityAnalysisModelManager.BackgroundTasks.TaskStarters.Ar
|
||||
}
|
||||
catch (Exception ex) when (ex is not OperationCanceledException)
|
||||
{
|
||||
bulkInsertMessageBuffer.ArchiveKeys.Clear(); //TODO[RC]: Create a dead letter archive.
|
||||
bulkInsertMessageBuffer.ArchiveKeys.Clear();
|
||||
log.Error($"Database Persist: Archive Keys Bulk Copy failed {ex}.");
|
||||
}
|
||||
|
||||
|
||||
+5
-6
@@ -21,15 +21,15 @@ namespace Jube.Engine.EntityAnalysisModelManager.BackgroundTasks.TaskStarters.Ar
|
||||
using Data.Poco;
|
||||
using DynamicEnvironment;
|
||||
using EntityAnalysisModelInvoke.Models.CaseManagement;
|
||||
using EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntry;
|
||||
using EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
using Jube.Engine.BackgroundTasks.TaskStarters.Case;
|
||||
using Jube.Engine.Helpers;
|
||||
using log4net;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
public static class ArchiverProcessing
|
||||
{
|
||||
public static async Task CaseCreationAndArchiveStorageAsync(EntityAnalysisModelInstanceEntryPayload payload,
|
||||
JsonSerializer jsonSerializer,
|
||||
JsonSerializationHelper jsonSerializationHelper,
|
||||
ArchiveBuffer bulkInsertMessageBuffer,
|
||||
ConcurrentQueue<CreateCase> pendingCases,
|
||||
DynamicEnvironment dynamicEnvironment,
|
||||
@@ -38,15 +38,14 @@ namespace Jube.Engine.EntityAnalysisModelManager.BackgroundTasks.TaskStarters.Ar
|
||||
{
|
||||
try
|
||||
{
|
||||
var json = BuildJsonResponses.BuildFullJson(payload, jsonSerializer);
|
||||
var json = BuildJsonResponses.BuildFullJson(payload, jsonSerializationHelper.ArchiveJsonSerializer);
|
||||
var jsonString = Encoding.UTF8.GetString(json.ToArray());
|
||||
|
||||
if (payload.CreateCase != null)
|
||||
{
|
||||
if (payload.EntityAnalysisModelReprocessingRuleInstanceId.HasValue)
|
||||
{
|
||||
await CaseProcessing.CreateAsync(dynamicEnvironment,
|
||||
payload.CreateCase, log, token);
|
||||
await CaseProcessing.CreateAsync(dynamicEnvironment, payload.CreateCase, log, jsonSerializationHelper, payload, token);
|
||||
// ReSharper disable once RedundantAssignment
|
||||
payload.CreateCase = null;
|
||||
}
|
||||
|
||||
+1
-1
@@ -110,7 +110,7 @@ namespace Jube.Engine.EntityAnalysisModelManager.BackgroundTasks.TaskStarters
|
||||
try
|
||||
{
|
||||
await ArchiverProcessing.CaseCreationAndArchiveStorageAsync(payload,
|
||||
context.JsonSerializationHelper.ArchiveJsonSerializer,
|
||||
context.JsonSerializationHelper,
|
||||
buffer,
|
||||
context.ConcurrentQueues.PendingCases,
|
||||
context.Services.DynamicEnvironment, context.Services.Log, token).ConfigureAwait(false);
|
||||
|
||||
-3
@@ -14,12 +14,9 @@
|
||||
namespace Jube.Engine.EntityAnalysisModelManager.BackgroundTasks.TaskStarters
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using Context;
|
||||
using Data.Context;
|
||||
using Data.Poco;
|
||||
using Data.Repository;
|
||||
|
||||
public class PersistToActivationWatcherPollingTaskStarter(Context context)
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ namespace Jube.Engine.EntityAnalysisModelManager.EntityAnalysisModel.Models
|
||||
using Data.Poco;
|
||||
using EntityAnalysisModelInvoke.Context;
|
||||
using EntityAnalysisModelInvoke.Models;
|
||||
using EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntry;
|
||||
using EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
using Jube.Cache.Redis.Callback;
|
||||
using Jube.Engine.BackgroundTasks.TaskStarters.Models;
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Jube.Engine.Exhaustive
|
||||
using Data.Repository.Interface;
|
||||
using Dictionary;
|
||||
using DynamicEnvironment;
|
||||
using EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntry;
|
||||
using EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
using Helpers;
|
||||
using log4net;
|
||||
using Utilities;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
namespace Jube.Engine.Helpers
|
||||
{
|
||||
using System;
|
||||
using Cache.Redis.Serialization.DictionaryNoBoxing.Newtonsoft;
|
||||
using Dictionary.Serialization;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
@@ -29,12 +29,12 @@ namespace Jube.Engine.Helpers
|
||||
{
|
||||
get
|
||||
{
|
||||
var serializer = new JsonSerializerSettings
|
||||
var serializer = new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = defaultContractResolver
|
||||
};
|
||||
|
||||
serializer.Converters.Add(new DictionaryNoBoxingValueOnlyNewtonsoftConverter());
|
||||
|
||||
serializer.Converters.Add(new DictionaryNoBoxingConverter());
|
||||
|
||||
return serializer;
|
||||
}
|
||||
@@ -87,8 +87,8 @@ namespace Jube.Engine.Helpers
|
||||
ContractResolver = defaultContractResolver
|
||||
};
|
||||
|
||||
serializer.Converters.Add(new DictionaryNoBoxingValueOnlyNewtonsoftConverter());
|
||||
|
||||
serializer.Converters.Add(new DictionaryNoBoxingConverter());
|
||||
|
||||
return serializer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/* Copyright (C) 2022-present Jube Holdings Limited.
|
||||
*
|
||||
* This file is part of Jube™ software.
|
||||
*
|
||||
* Jube™ is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* Jube™ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License along with Jube™. If not,
|
||||
* see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Jube.Migrations.Branches
|
||||
{
|
||||
using FluentMigrator;
|
||||
|
||||
[Migration(20260222075400)]
|
||||
public class GitHubIssueBranch115 : Migration
|
||||
{
|
||||
public override void Up()
|
||||
{
|
||||
UpdateCaseWorkflowDisplayForNewTokenisationFormat();
|
||||
UpdateCaseWorkflowFilterForIncorrectCaseWorkflowStatusGuidToName();
|
||||
}
|
||||
|
||||
private void UpdateCaseWorkflowFilterForIncorrectCaseWorkflowStatusGuidToName()
|
||||
{
|
||||
|
||||
Execute.Sql("""
|
||||
update "CaseWorkflowFilter"
|
||||
set "SelectJson" =
|
||||
jsonb_set(
|
||||
"SelectJson",
|
||||
array ['rules', elem_index::text, 'field'],
|
||||
'"\"CaseWorkflowStatus\".\"Name\""'::jsonb,
|
||||
true)
|
||||
from (select pos - 1 as elem_index
|
||||
from "CaseWorkflowFilter" s,
|
||||
jsonb_array_elements(s."SelectJson" #> '{rules}') with ordinality arr(elem, pos)
|
||||
where elem ->> 'id' = 'CaseWorkflowStatus') sub;
|
||||
""");
|
||||
}
|
||||
|
||||
private void UpdateCaseWorkflowDisplayForNewTokenisationFormat()
|
||||
{
|
||||
|
||||
Execute.Sql("""
|
||||
update "CaseWorkflowDisplay" set "Html" =
|
||||
replace("Html",'<div style=''font-size:30px''>[@CurrencyAmount@]</div>','<div style=''font-size:30px''>[@Payload.AccountId@]</div>')
|
||||
where "Html" like '%<div style=''font-size:30px''>[@CurrencyAmount@]</div>%'
|
||||
""");
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
using Jube.Dictionary;
|
||||
using Jube.Engine.EntityAnalysisModelInvoke.Context;
|
||||
using Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntry;
|
||||
using Jube.Engine.EntityAnalysisModelInvoke.Models.Payload.EntityAnalysisModelInstanceEntryPayload;
|
||||
var context = new Context
|
||||
{
|
||||
EntityAnalysisModelInstanceEntryPayload = new EntityAnalysisModelInstanceEntryPayload
|
||||
|
||||
@@ -1101,7 +1101,7 @@ namespace Jube.Service.Authentication
|
||||
"The transaction amount is:" + Environment.NewLine +
|
||||
"<br/>" + Environment.NewLine +
|
||||
"<br/>" + Environment.NewLine +
|
||||
"<div style='font-size:30px'>[@CurrencyAmount@]</div>" + Environment.NewLine +
|
||||
"<div style='font-size:30px'>[@Payload.AccountId@]</div>" + Environment.NewLine +
|
||||
"<br/>" + Environment.NewLine +
|
||||
"The tokens are taken from the Cases Workflows XPath and can be laid out in HTML."
|
||||
}, token);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user