123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422 |
- using Edge.Core.Configuration;
- using Edge.Core.Processor;
- using Edge.Core.UniversalApi.Auditing;
- using Microsoft.Extensions.DependencyInjection;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
- using System.Text;
- using System.Text.Json;
- using System.Text.Json.Serialization;
- using System.Threading.Tasks;
- namespace Edge.Core.UniversalApi
- {
- public class UniversalApiInvoker
- {
- private static JsonSerializerOptions jsonSerializerOptions;
- private IEnumerable<IAuditingStore> auditingStores;
- private IServiceProvider services;
- private bool config_DisableApiAuditing = false;
- private bool config_EnableApiInputAndOutputAuditing = false;
- static UniversalApiInvoker()
- {
- jsonSerializerOptions = new JsonSerializerOptions()
- {
- WriteIndented = true,
- PropertyNameCaseInsensitive = true,
- };
- jsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
- }
- internal UniversalApiInvoker(IServiceProvider services)
- {
- this.services = services;
- var configurator = this.services.GetService<Configurator>();
- this.config_DisableApiAuditing = bool.Parse(configurator.MetaConfiguration.Parameter
- ?.FirstOrDefault(p => p.Name.Equals("disableUniversalApiAuditing", StringComparison.OrdinalIgnoreCase))?.Value ?? "false");
- this.config_EnableApiInputAndOutputAuditing = bool.Parse(configurator.MetaConfiguration.Parameter
- ?.FirstOrDefault(p => p.Name.Equals("enableUniversalApiInputAndOutputAuditing", StringComparison.OrdinalIgnoreCase))?.Value ?? "false");
- this.auditingStores = services.GetRequiredService<IEnumerable<IAuditingStore>>();
- configurator.OnConfigFileChanged += (_, __) =>
- {
- this.config_DisableApiAuditing = bool.Parse(configurator.MetaConfiguration.Parameter
- ?.FirstOrDefault(p => p.Name.Equals("disableUniversalApiAuditing", StringComparison.OrdinalIgnoreCase))?.Value ?? "false");
- this.config_EnableApiInputAndOutputAuditing = bool.Parse(configurator.MetaConfiguration.Parameter
- ?.FirstOrDefault(p => p.Name.Equals("enableUniversalApiInputAndOutputAuditing", StringComparison.OrdinalIgnoreCase))?.Value ?? "false");
- };
- }
- public async Task<object> InvokeUniversalApiServiceAsync(IProcessor processor,
- string apiServiceName, JsonElement[] jsonFormatParameters,
- RequestContext requestContext)
- {
- var pDescriptor = processor.ProcessorDescriptor();
- #region
- AuditLogInfo auditLogInfo = null;
- if (!this.config_DisableApiAuditing)
- {
- auditLogInfo = new AuditLogInfo()
- {
- ClientIdentity = requestContext.ClientIdentity,
- DeviceHandlerOrAppName = pDescriptor.DeviceHandlerOrApp.ToString(),
- ExecutionTime = DateTime.Now,
- };
- auditLogInfo.Actions.Add(
- new AuditLogActionInfo()
- {
- ApiName = "service : " + apiServiceName,
- InputParameters =
- this.config_EnableApiInputAndOutputAuditing ?
- jsonFormatParameters?.Select(jp => jp.GetRawText())?.Aggregate("", (acc, n) => acc + ", " + n) ?? ""
- : null,
- });
- auditLogInfo.Prepare();
-
- this.auditingStores.Select(s => s.SaveAsync(auditLogInfo)).ToArray();
- }
- #endregion
- try
- {
- var targetApiInfo = pDescriptor.UniversalApiInfos
- .FirstOrDefault(api => api.ServiceApiInfo != null
- && api.ServiceApiInfo.Name == apiServiceName
- && api.ServiceApiInfo.GetParameters().Length == (jsonFormatParameters?.Length ?? 0));
- if (targetApiInfo == null) throw new ArgumentException("Could not find Universal Api in the processor has Service(Method) Parameter count == " + (jsonFormatParameters?.Length ?? 0));
- var apiDefinedParameters = targetApiInfo.ServiceApiInfo.GetParameters();
- List<object> ps = new List<object>();
- for (int i = 0; i < apiDefinedParameters.Length; i++)
- {
- try
- {
- var para = JsonSerializer.Deserialize(jsonFormatParameters[i].GetRawText(), apiDefinedParameters[i].ParameterType, jsonSerializerOptions);
- ps.Add(para);
- }
- catch (Exception exxx)
- {
- throw new ArgumentException("Could not Parse input parameter[" + i + "] to type: "
- + apiDefinedParameters[i].ParameterType.Name + " for target Universal Api: " + apiServiceName
- + Environment.NewLine + exxx);
- }
- }
- var executeResult = await InvokeUniversalApiServiceAsync(processor, targetApiInfo.ServiceApiInfo, ps.ToArray(), requestContext);
- #region
- if (!this.config_DisableApiAuditing)
- {
-
- if (this.config_EnableApiInputAndOutputAuditing)
- auditLogInfo.CommitWithExeResult(executeResult);
- else
- auditLogInfo.CommitWithExeResult(null);
- }
- #endregion
- return executeResult;
- }
- catch (Exception exxx)
- {
- #region
- if (!this.config_DisableApiAuditing)
- { auditLogInfo.CommitWithExceptions(new Exception[] { exxx }); }
- #endregion
- throw;
- }
- finally
- {
- #region
- if (!this.config_DisableApiAuditing)
- Task.WaitAll(this.auditingStores.Select(s => s.SaveAsync(auditLogInfo)).ToArray());
- #endregion
- }
- }
- public bool InvokeUniversalApiPropertySet(IProcessor processor,
- string apiPropertyName, JsonElement? propertySetValue,
- RequestContext requestContext)
- {
- var pDescriptor = processor.ProcessorDescriptor();
- #region
- AuditLogInfo auditLogInfo = null;
- if (!this.config_DisableApiAuditing)
- {
- auditLogInfo = new AuditLogInfo()
- {
- ClientIdentity = requestContext.ClientIdentity,
- DeviceHandlerOrAppName = pDescriptor.DeviceHandlerOrApp.ToString(),
- ExecutionTime = DateTime.Now,
- };
- auditLogInfo.Actions.Add(
- new AuditLogActionInfo()
- {
- ApiName = "property : " + apiPropertyName,
- InputParameters =
- this.config_EnableApiInputAndOutputAuditing ?
- propertySetValue?.GetRawText() ?? ""
- : null,
- });
-
- this.auditingStores.Select(s => s.SaveAsync(auditLogInfo)).ToArray();
- }
- #endregion
- try
- {
- var targetApiInfo = pDescriptor?.UniversalApiInfos
- .FirstOrDefault(api => api.PropertyApiInfo != null
- && api.PropertyApiInfo.Name == apiPropertyName);
- if (targetApiInfo == null) throw new ArgumentException("Could not find Universal Api in the processor has Property with name: " + apiPropertyName);
- object setValue = null;
- if (propertySetValue == null)
- {
- }
- else
- setValue = JsonSerializer.Deserialize(propertySetValue.Value.GetRawText(),
- targetApiInfo.PropertyApiInfo.PropertyType, jsonSerializerOptions);
- var executeResult = InvokeUniversalApiPropertySet(processor, targetApiInfo.PropertyApiInfo, setValue, requestContext);
- #region
- if (!this.config_DisableApiAuditing)
- {
-
- if (this.config_EnableApiInputAndOutputAuditing)
- auditLogInfo.CommitWithExeResult(executeResult);
- else
- auditLogInfo.CommitWithExeResult(null);
- }
- #endregion
- return executeResult;
- }
- catch (Exception exxx)
- {
- #region
- if (!this.config_DisableApiAuditing)
- {
- auditLogInfo.CommitWithExceptions(new Exception[] { exxx
- });
- }
- #endregion
- throw;
- }
- finally
- {
- #region
- if (!this.config_DisableApiAuditing)
- Task.WaitAll(this.auditingStores.Select(s => s.SaveAsync(auditLogInfo)).ToArray());
- #endregion
- }
- }
-
-
-
-
-
-
- public object InvokeUniversalApiPropertyGet(IProcessor processor,
- string apiPropertyName,
- RequestContext requestContext)
- {
- var pDescriptor = processor.ProcessorDescriptor();
- #region
- AuditLogInfo auditLogInfo = null;
- if (!this.config_DisableApiAuditing)
- {
- auditLogInfo = new AuditLogInfo()
- {
- ClientIdentity = requestContext.ClientIdentity,
- DeviceHandlerOrAppName = pDescriptor.DeviceHandlerOrApp.ToString(),
- ExecutionTime = DateTime.Now,
- };
- auditLogInfo.Actions.Add(
- new AuditLogActionInfo()
- {
- ApiName = "property : " + apiPropertyName,
- InputParameters = null,
- });
- auditLogInfo.Prepare();
-
- this.auditingStores.Select(s => s.SaveAsync(auditLogInfo)).ToArray();
- }
- #endregion
- try
- {
- var targetPropertyInfo = pDescriptor.UniversalApiInfos.Where(apiInfo =>
- (apiInfo.PropertyApiInfo?.Name ?? "") == apiPropertyName)
- .FirstOrDefault()?.PropertyApiInfo;
- if (targetPropertyInfo == null)
- throw new EntryPointNotFoundException("Could not find Universal Api Property with name: " + (targetPropertyInfo.Name ?? ""));
- if (!targetPropertyInfo.CanRead
- || targetPropertyInfo.GetMethod == null
- || (targetPropertyInfo.GetMethod?.IsPrivate ?? false))
- {
- throw new EntryPointNotFoundException("Universal Api Property with name: " + (targetPropertyInfo.Name ?? "") + " does not allow Get");
- }
- try
- {
-
- dynamic executeResult = null;
- if (pDescriptor.ProcessorType == ProcessorType.Application)
- executeResult = targetPropertyInfo.GetGetMethod().Invoke(processor, null);
- else if (pDescriptor.ProcessorType == ProcessorType.DeviceProcessor)
- executeResult = targetPropertyInfo.GetGetMethod().Invoke(pDescriptor.DeviceHandlerOrApp, null);
- #region
- if (!this.config_DisableApiAuditing)
- {
-
- if (this.config_EnableApiInputAndOutputAuditing)
- auditLogInfo.CommitWithExeResult(executeResult);
- else
- auditLogInfo.CommitWithExeResult(null);
- }
- #endregion
- return executeResult;
- }
- catch (Exception exx)
- {
- throw;
- }
- }
- catch (Exception exxx)
- {
- #region
- if (!this.config_DisableApiAuditing)
- {
- auditLogInfo.CommitWithExceptions(new Exception[] { exxx });
- }
- #endregion
- throw;
- }
- finally
- {
- #region
- if (!this.config_DisableApiAuditing)
- Task.WaitAll(this.auditingStores.Select(s => s.SaveAsync(auditLogInfo)).ToArray());
- #endregion
- }
- }
- private async Task<object> InvokeUniversalApiServiceAsync(IProcessor processor,
- MethodInfo apiServiceInfo, object[] methodParameters,
- RequestContext requestContext)
- {
- var descriptor = processor.ProcessorDescriptor();
- var targetMethodInfo = descriptor.UniversalApiInfos.Where(apiInfo =>
- (apiInfo.ServiceApiInfo?.Name ?? "") == apiServiceInfo.Name)
- .FirstOrDefault()?.ServiceApiInfo;
- if (targetMethodInfo == null)
- throw new EntryPointNotFoundException("Could not find Universal Api Method with name: " + (apiServiceInfo.Name ?? ""));
- try
- {
- dynamic result = null;
- if (descriptor.ProcessorType == ProcessorType.Application)
- result = await (dynamic)targetMethodInfo.Invoke(processor, methodParameters);
- else if (descriptor.ProcessorType == ProcessorType.DeviceProcessor)
- result = await (dynamic)targetMethodInfo.Invoke(descriptor.DeviceHandlerOrApp, methodParameters);
- return result;
- }
- catch (Exception exx)
- {
- throw;
- }
- }
-
-
-
-
-
-
-
- private bool InvokeUniversalApiPropertySet(IProcessor processor,
- PropertyInfo apiPropertyInfo, object propertySetValue,
- RequestContext requestContext)
- {
- var descriptor = processor.ProcessorDescriptor();
- var targetPropertyInfo = descriptor.UniversalApiInfos.Where(apiInfo =>
- (apiInfo.PropertyApiInfo?.Name ?? "") == apiPropertyInfo.Name)
- .FirstOrDefault()?.PropertyApiInfo;
- if (targetPropertyInfo == null)
- throw new EntryPointNotFoundException("Could not find Universal Api Property with name: " + (targetPropertyInfo.Name ?? ""));
- if (!targetPropertyInfo.CanWrite
- || targetPropertyInfo.SetMethod == null
- || (targetPropertyInfo.SetMethod?.IsPrivate ?? false))
- {
- throw new EntryPointNotFoundException("Universal Api Property with name: " + (targetPropertyInfo.Name ?? "") + " does not allow Set");
- }
- if (propertySetValue == null
- && !targetPropertyInfo.PropertyType.IsClass
- && !(targetPropertyInfo.PropertyType.IsGenericType && targetPropertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)))
- throw new ArgumentException("Universal Api Property with name: " + (targetPropertyInfo.Name ?? "")
- + " does not compatible has its Set type(" + targetPropertyInfo.PropertyType + ") to Null");
- if (propertySetValue != null && !targetPropertyInfo.PropertyType.IsAssignableFrom(propertySetValue?.GetType()))
- throw new ArgumentException("Universal Api Property with name: " + (targetPropertyInfo.Name ?? "")
- + " does not compatible has its Set type(" + targetPropertyInfo.PropertyType + ") to " + (propertySetValue?.GetType().Name ?? "null"));
- try
- {
-
- if (descriptor.ProcessorType == ProcessorType.Application)
- targetPropertyInfo.SetValue(processor, propertySetValue);
- else if (descriptor.ProcessorType == ProcessorType.DeviceProcessor)
- targetPropertyInfo.SetValue(descriptor.DeviceHandlerOrApp, propertySetValue);
- return true;
- }
- catch (Exception exx)
- {
- throw;
- }
- }
- }
- }
|