fix jsNode in remove sessionId
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<PackageId>Caspian.WorkflowFramework</PackageId>
|
<PackageId>Caspian.WorkflowFramework</PackageId>
|
||||||
<Version>1.1.0-preview.22</Version>
|
<Version>1.1.0-preview.25</Version>
|
||||||
<Authors>Behzad Alizadeh</Authors>
|
<Authors>Behzad Alizadeh</Authors>
|
||||||
<Company>Caspian</Company>
|
<Company>Caspian</Company>
|
||||||
<Product>Caspian.WorkflowFramework</Product>
|
<Product>Caspian.WorkflowFramework</Product>
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using Elsa.Common.Models;
|
|||||||
using Elsa.Workflows;
|
using Elsa.Workflows;
|
||||||
using Elsa.Workflows.Management;
|
using Elsa.Workflows.Management;
|
||||||
using Elsa.Workflows.Management.Filters;
|
using Elsa.Workflows.Management.Filters;
|
||||||
using Elsa.Workflows.Management.Services;
|
|
||||||
using Elsa.Workflows.Models;
|
using Elsa.Workflows.Models;
|
||||||
using Elsa.Workflows.Runtime;
|
using Elsa.Workflows.Runtime;
|
||||||
using Elsa.Workflows.Runtime.Filters;
|
using Elsa.Workflows.Runtime.Filters;
|
||||||
@@ -14,7 +13,6 @@ using Elsa.Workflows.Runtime.Messages;
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Converters;
|
using Newtonsoft.Json.Converters;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using San.MongoLogger;
|
using San.MongoLogger;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Dynamic;
|
using System.Dynamic;
|
||||||
@@ -264,77 +262,119 @@ public class WorkflowService : IWorkflowService, ILoggable
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region PublishEventAsync
|
#region PublishEventAsync
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async Task<WorkflowResponse<WorkflowModel>> PublishEventAsync(PublishEventModel input)
|
public async Task<WorkflowResponse<WorkflowModel>> PublishEventAsync(
|
||||||
|
PublishEventModel input)
|
||||||
{
|
{
|
||||||
var sw = Stopwatch.StartNew();
|
var sw = Stopwatch.StartNew();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_logger.Log("Start of PublishEventAsync", WFInstanceId: input.WorkflowInstanceId, input);
|
_logger.Log(
|
||||||
|
"Start of PublishEventAsync",
|
||||||
|
WFInstanceId: input.WorkflowInstanceId,
|
||||||
|
input);
|
||||||
|
|
||||||
WorkflowResponse<WorkflowModel> response;
|
var instance = await _workflowInstanceManager.FindByIdAsync(
|
||||||
|
input.WorkflowInstanceId);
|
||||||
var instance = await _workflowInstanceManager.FindByIdAsync(input.WorkflowInstanceId);
|
|
||||||
|
|
||||||
if (instance == null)
|
if (instance == null)
|
||||||
{
|
{
|
||||||
var msg = $"Workflow instance with id '{input.WorkflowInstanceId}' not found";
|
var notFoundResponse = new WorkflowResponse<WorkflowModel>
|
||||||
response = new WorkflowResponse<WorkflowModel>()
|
|
||||||
{
|
{
|
||||||
Status = 1,
|
Status = 1,
|
||||||
Message = msg,
|
Message =
|
||||||
|
$"Workflow instance with id " +
|
||||||
|
$"'{input.WorkflowInstanceId}' not found",
|
||||||
Data = null
|
Data = null
|
||||||
};
|
};
|
||||||
|
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
|
|
||||||
_logger.Log("End of PublishEventAsync", WFInstanceId: input.WorkflowInstanceId, response, sw.ElapsedMilliseconds);
|
_logger.Log(
|
||||||
|
"End of PublishEventAsync",
|
||||||
|
WFInstanceId: input.WorkflowInstanceId,
|
||||||
|
notFoundResponse,
|
||||||
|
sw.ElapsedMilliseconds);
|
||||||
|
|
||||||
return response;
|
return notFoundResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpandoObject payload;
|
/*
|
||||||
|
* JsonElement
|
||||||
|
* ↓
|
||||||
|
* ExpandoObject
|
||||||
|
* ↓
|
||||||
|
* اضافهشدن SessionId
|
||||||
|
* ↓
|
||||||
|
* PublishEvent
|
||||||
|
*/
|
||||||
|
|
||||||
var payloadObject = new JObject();
|
ExpandoObject payload = new();
|
||||||
|
|
||||||
if (input.EventData.ValueKind is not JsonValueKind.Undefined
|
if (input.EventData.ValueKind is not JsonValueKind.Undefined
|
||||||
and not JsonValueKind.Null)
|
and not JsonValueKind.Null)
|
||||||
{
|
{
|
||||||
if (input.EventData.ValueKind != JsonValueKind.Object)
|
if (input.EventData.ValueKind != JsonValueKind.Object)
|
||||||
throw new InvalidOperationException("EventData must be a JSON object.");
|
{
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
"EventData must be a JSON object.");
|
||||||
|
}
|
||||||
|
|
||||||
payloadObject = JObject.Parse(input.EventData.GetRawText());
|
var json = input.EventData.GetRawText();
|
||||||
|
|
||||||
|
var serializerSettings = new JsonSerializerSettings
|
||||||
|
{
|
||||||
|
Converters =
|
||||||
|
{
|
||||||
|
new ExpandoObjectConverter()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
payload =
|
||||||
|
JsonConvert.DeserializeObject<ExpandoObject>(
|
||||||
|
json,
|
||||||
|
serializerSettings)
|
||||||
|
?? new ExpandoObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ExpandoObject پیادهسازی IDictionary است؛
|
||||||
|
* بنابراین بدون Serialize/Deserialize مجدد میتوانیم
|
||||||
|
* SessionId را به Payload اضافه کنیم.
|
||||||
|
*/
|
||||||
if (!string.IsNullOrWhiteSpace(input.SessionId))
|
if (!string.IsNullOrWhiteSpace(input.SessionId))
|
||||||
{
|
{
|
||||||
payloadObject["SessionId"] = input.SessionId;
|
var payloadDictionary =
|
||||||
|
(IDictionary<string, object?>)payload;
|
||||||
|
|
||||||
|
payloadDictionary["SessionId"] = input.SessionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
var settings = new JsonSerializerSettings
|
await _eventPublisher.PublishAsync(
|
||||||
{
|
eventName: input.EventName,
|
||||||
Converters = { new ExpandoObjectConverter() }
|
correlationId: null,
|
||||||
};
|
workflowInstanceId: input.WorkflowInstanceId,
|
||||||
|
activityInstanceId: null,
|
||||||
|
payload: payload,
|
||||||
|
asynchronous: false);
|
||||||
|
|
||||||
payload = JsonConvert.DeserializeObject<ExpandoObject>(
|
var variables =
|
||||||
payloadObject.ToString(Formatting.None),
|
await _workflowInstanceVariableManager.GetVariablesAsync(
|
||||||
settings
|
input.WorkflowInstanceId);
|
||||||
) ?? new ExpandoObject();
|
|
||||||
|
|
||||||
//await _eventPublisher.PublishAsync(input.EventName, null, input.WorkflowInstanceId, null, input.EventData, asynchronous: true);
|
var dictionary = variables.ToDictionary(
|
||||||
await _eventPublisher.PublishAsync(input.EventName, null, input.WorkflowInstanceId, null, payload);
|
x => x.Variable.Name,
|
||||||
|
x => x.Value);
|
||||||
var variables = await _workflowInstanceVariableManager.GetVariablesAsync(input.WorkflowInstanceId);
|
|
||||||
|
|
||||||
// تبدیل به دیکشنری
|
|
||||||
var dictionary = variables.ToDictionary(a => a.Variable.Name, a => a.Value);
|
|
||||||
|
|
||||||
var workflowModel = dictionary.ConvertToWorkflowModel();
|
var workflowModel = dictionary.ConvertToWorkflowModel();
|
||||||
|
|
||||||
workflowModel.InstanceId = instance.Id;
|
workflowModel.InstanceId = instance.Id;
|
||||||
workflowModel.UserId = instance.ExternalUserId;
|
workflowModel.UserId = instance.ExternalUserId;
|
||||||
workflowModel.InstanceMode = "exist";
|
workflowModel.InstanceMode = "exist";
|
||||||
|
|
||||||
response = new WorkflowResponse<WorkflowModel>()
|
var response = new WorkflowResponse<WorkflowModel>
|
||||||
{
|
{
|
||||||
Status = 0,
|
Status = 0,
|
||||||
Message = "Success",
|
Message = "Success",
|
||||||
@@ -343,26 +383,36 @@ public class WorkflowService : IWorkflowService, ILoggable
|
|||||||
|
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
|
|
||||||
_logger.Log("End of PublishEventAsync", WFInstanceId: input.WorkflowInstanceId, response, sw.ElapsedMilliseconds);
|
_logger.Log(
|
||||||
|
"End of PublishEventAsync",
|
||||||
|
WFInstanceId: input.WorkflowInstanceId,
|
||||||
|
response,
|
||||||
|
sw.ElapsedMilliseconds);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
var response = new WorkflowResponse<WorkflowModel>()
|
sw.Stop();
|
||||||
|
|
||||||
|
var response = new WorkflowResponse<WorkflowModel>
|
||||||
{
|
{
|
||||||
Status = 100,
|
Status = 100,
|
||||||
Message = ex.Message,
|
Message = ex.Message,
|
||||||
Data = null
|
Data = null
|
||||||
};
|
};
|
||||||
|
|
||||||
sw.Stop();
|
_logger.Log(
|
||||||
|
"Exception occurs in PublishEventAsync",
|
||||||
_logger.Log("Exception occurs in PublishEventAsync", WFInstanceId: input.WorkflowInstanceId, response, sw.ElapsedMilliseconds, ex);
|
WFInstanceId: input.WorkflowInstanceId,
|
||||||
|
response,
|
||||||
|
sw.ElapsedMilliseconds,
|
||||||
|
ex);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region InquiryStateAsync
|
#region InquiryStateAsync
|
||||||
|
|||||||
@@ -1,226 +1,28 @@
|
|||||||
using System.Collections;
|
namespace Caspian.WorkflowFramework.Utility;
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Nodes;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace Caspian.WorkflowFramework.Utility;
|
|
||||||
|
|
||||||
public static class WorkflowVariableExtensions
|
public static class WorkflowVariableExtensions
|
||||||
{
|
{
|
||||||
private const string SessionIdKey = "SessionId";
|
private const string SessionIdKey = "SessionId";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// sessionId را از دیکشنری اصلی و تمام مقادیر تو در تو حذف میکند.
|
/// SessionId را فقط از سطح اول دیکشنری متغیرهای Workflow حذف میکند.
|
||||||
|
/// مقایسه نام کلید به حروف بزرگ و کوچک حساس نیست.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static Dictionary<string, object?> RemoveSessionId(
|
public static Dictionary<string, object?> RemoveSessionId(
|
||||||
this Dictionary<string, object?> variables)
|
this Dictionary<string, object?> variables)
|
||||||
{
|
{
|
||||||
if (variables == null || variables.Count == 0)
|
if (variables is null || variables.Count == 0)
|
||||||
return variables;
|
return variables!;
|
||||||
|
|
||||||
RemoveSessionIdKeys(variables);
|
var sessionIdKey = variables.Keys.FirstOrDefault(
|
||||||
|
key => string.Equals(
|
||||||
|
key,
|
||||||
|
SessionIdKey,
|
||||||
|
StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
foreach (var key in variables.Keys.ToList())
|
if (sessionIdKey is not null)
|
||||||
variables[key] = RemoveSessionIdRecursive(variables[key]);
|
variables.Remove(sessionIdKey);
|
||||||
|
|
||||||
return variables;
|
return variables;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static object? RemoveSessionIdRecursive(object? value)
|
|
||||||
{
|
|
||||||
if (value == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
switch (value)
|
|
||||||
{
|
|
||||||
// Dictionary و ExpandoObject
|
|
||||||
case IDictionary<string, object?> dictionary:
|
|
||||||
{
|
|
||||||
RemoveSessionIdKeys(dictionary);
|
|
||||||
|
|
||||||
foreach (var key in dictionary.Keys.ToList())
|
|
||||||
dictionary[key] = RemoveSessionIdRecursive(dictionary[key]);
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// System.Text.Json.Nodes
|
|
||||||
case JsonObject jsonObject:
|
|
||||||
{
|
|
||||||
RemoveSessionIdKeys(jsonObject);
|
|
||||||
|
|
||||||
foreach (var property in jsonObject.ToList())
|
|
||||||
jsonObject[property.Key] =
|
|
||||||
RemoveSessionIdFromJsonNode(property.Value);
|
|
||||||
|
|
||||||
return jsonObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
case JsonArray jsonArray:
|
|
||||||
{
|
|
||||||
for (var i = 0; i < jsonArray.Count; i++)
|
|
||||||
{
|
|
||||||
jsonArray[i] =
|
|
||||||
RemoveSessionIdFromJsonNode(jsonArray[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return jsonArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
// JsonElement تغییرپذیر نیست؛ پس نسخه پاکسازیشده میسازیم.
|
|
||||||
case JsonElement jsonElement:
|
|
||||||
{
|
|
||||||
var node = JsonNode.Parse(jsonElement.GetRawText());
|
|
||||||
|
|
||||||
if (node == null)
|
|
||||||
return jsonElement;
|
|
||||||
|
|
||||||
var cleanedNode = RemoveSessionIdFromJsonNode(node);
|
|
||||||
|
|
||||||
return cleanedNode == null
|
|
||||||
? jsonElement
|
|
||||||
: JsonSerializer.SerializeToElement(cleanedNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Newtonsoft.Json
|
|
||||||
case JObject jObject:
|
|
||||||
{
|
|
||||||
RemoveSessionIdKeys(jObject);
|
|
||||||
|
|
||||||
foreach (var property in jObject.Properties().ToList())
|
|
||||||
property.Value = RemoveSessionIdFromJToken(property.Value);
|
|
||||||
|
|
||||||
return jObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
case JArray jArray:
|
|
||||||
{
|
|
||||||
for (var i = 0; i < jArray.Count; i++)
|
|
||||||
jArray[i] = RemoveSessionIdFromJToken(jArray[i]);
|
|
||||||
|
|
||||||
return jArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
// سایر لیستها و آرایهها
|
|
||||||
case IList list:
|
|
||||||
{
|
|
||||||
for (var i = 0; i < list.Count; i++)
|
|
||||||
list[i] = RemoveSessionIdRecursive(list[i]);
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
case IEnumerable enumerable when value is not string:
|
|
||||||
{
|
|
||||||
foreach (var child in enumerable)
|
|
||||||
RemoveSessionIdRecursive(child);
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static JsonNode? RemoveSessionIdFromJsonNode(JsonNode? node)
|
|
||||||
{
|
|
||||||
if (node == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
switch (node)
|
|
||||||
{
|
|
||||||
case JsonObject jsonObject:
|
|
||||||
{
|
|
||||||
RemoveSessionIdKeys(jsonObject);
|
|
||||||
|
|
||||||
foreach (var property in jsonObject.ToList())
|
|
||||||
{
|
|
||||||
jsonObject[property.Key] =
|
|
||||||
RemoveSessionIdFromJsonNode(property.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case JsonArray jsonArray:
|
|
||||||
{
|
|
||||||
for (var i = 0; i < jsonArray.Count; i++)
|
|
||||||
{
|
|
||||||
jsonArray[i] =
|
|
||||||
RemoveSessionIdFromJsonNode(jsonArray[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static JToken RemoveSessionIdFromJToken(JToken token)
|
|
||||||
{
|
|
||||||
switch (token)
|
|
||||||
{
|
|
||||||
case JObject jObject:
|
|
||||||
{
|
|
||||||
RemoveSessionIdKeys(jObject);
|
|
||||||
|
|
||||||
foreach (var property in jObject.Properties().ToList())
|
|
||||||
property.Value = RemoveSessionIdFromJToken(property.Value);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case JArray jArray:
|
|
||||||
{
|
|
||||||
for (var i = 0; i < jArray.Count; i++)
|
|
||||||
jArray[i] = RemoveSessionIdFromJToken(jArray[i]);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RemoveSessionIdKeys(
|
|
||||||
IDictionary<string, object?> dictionary)
|
|
||||||
{
|
|
||||||
var keys = dictionary.Keys
|
|
||||||
.Where(IsSessionId)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
foreach (var key in keys)
|
|
||||||
dictionary.Remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RemoveSessionIdKeys(JsonObject jsonObject)
|
|
||||||
{
|
|
||||||
var keys = jsonObject
|
|
||||||
.Select(x => x.Key)
|
|
||||||
.Where(IsSessionId)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
foreach (var key in keys)
|
|
||||||
jsonObject.Remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RemoveSessionIdKeys(JObject jObject)
|
|
||||||
{
|
|
||||||
var properties = jObject.Properties()
|
|
||||||
.Where(x => IsSessionId(x.Name))
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
foreach (var property in properties)
|
|
||||||
property.Remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsSessionId(string key)
|
|
||||||
{
|
|
||||||
return string.Equals(
|
|
||||||
key,
|
|
||||||
SessionIdKey,
|
|
||||||
StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user