Esempio n. 1
0
        /// <summary>
        /// Execute handler
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="process"></param>
        /// <param name="processType"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public TResult Execute <TResult>(IBaseProcess <TResult> process, Type processType, params object[] args) where TResult : VoidResult, new()
        {
            var strategyHandler = SystemBootstrapper.GetInstance <IStrategyHandler>();

            if (strategyHandler.IsNull() || !strategyHandler.AutoHandleErrorProcesses)
            {
                try
                {
                    return(Next.Execute(process, processType, args));
                }
                catch (Exception ex)
                {
                    return(VoidResult.FaultedResult <TResult>(ex));
                }
            }

            var strategyResult = strategyHandler.Execute(() => Next.Execute(process, processType, args));

            if (strategyResult.Exception != null)
            {
                return(VoidResult.FaultedResult <TResult>(strategyResult.Exception));
            }

            return(strategyResult.Result);
        }
Esempio n. 2
0
        /// <summary>
        /// Handle process result
        /// </summary>
        /// <typeparam name="TProcess"></typeparam>
        /// <param name="process"></param>
        /// <param name="type"></param>
        /// <param name="response"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public MiddlewareResult HandleAfterExecution <TProcess>(TProcess process, Type type, VoidResult response, IHttpContextWrapper context) where TProcess : IBaseProcess <VoidResult>
        {
            var headers = SystemBootstrapper.GetInstance <List <ResponseHeaderAttribute> >();

            headers.ForEach(header =>
            {
                foreach (var responseHeader in header.Headers)
                {
                    context.Headers.AddToResponse(responseHeader.Key, responseHeader.Value);
                }
            });

            var headerAttribute = type
                                  .GetCustomAttributes(true)
                                  .Where(x => x.GetType() == typeof(ResponseHeaderAttribute) || x.GetType().IsSubclassOf(typeof(ResponseHeaderAttribute)))
                                  .Cast <ResponseHeaderAttribute>()
                                  .ToList();

            headerAttribute.ForEach(header =>
            {
                foreach (var responseHeader in header.Headers)
                {
                    context.Headers.AddToResponse(responseHeader.Key, responseHeader.Value);
                }
            });

            return(MiddlewareResult.DoNothing);
        }
        /// <summary>
        /// Register background tasks
        /// </summary>
        private static void RegisterBackground()
        {
            var channel = SystemBootstrapper.GetInstance <IMessageChannel>();

            if (!channel.IsNull())
            {
                var processRepo = SystemBootstrapper.GetInstance <ProcessRepository>();
                processRepo.OfType <IDistributedProcess>().ForEach(type =>
                {
                    channel.Subscribe <string>(type.Name, message =>
                    {
                        var meta = message.Deserialize <DistributedProcessMetadata>();

                        var executor = SystemBootstrapper.GetInstance <IProcessExecutor>();
                        var instance = SystemBootstrapper.GetInstance(type) as IBaseProcess <VoidResult>;
                        SystemBootstrapper.Bootstrap(instance);

                        instance.EpicId            = meta.EpicId;
                        instance.CallerProcessName = meta.CallerProcessName;

                        Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new CultureInfo(meta.CultureName);

                        executor.ExecuteBackground(instance, meta.Payload);
                    });
                });
            }
        }
Esempio n. 4
0
 /// <summary>
 /// Authentication callback
 /// </summary>
 /// <returns></returns>
 internal bool Authenticate()
 {
     return(SystemBootstrapper.GetInstance <IAuthenticationManager>()?
            .GetCurrentPrincipal()?
            .Identity?
            .IsAuthenticated == true);
 }
Esempio n. 5
0
        /// <summary>
        /// CTOR
        /// </summary>
        /// <param name="faultMessage"></param>
        /// <param name="translateFaultMessage"></param>
        public GeneralErrorInfo(string faultMessage, bool translateFaultMessage = true)
        {
            var localizer = SystemBootstrapper.GetInstance <ILocalizationProvider>();

            FaultMessage       = faultMessage;
            UserVisibleMessage = translateFaultMessage ? localizer?.Get(faultMessage)?.Value ?? null : null;
        }
Esempio n. 6
0
        /// <summary>
        /// Write response
        /// </summary>
        /// <param name="httpResponse"></param>
        /// <returns></returns>
        public void PutResponse(HttpResponseMessage httpResponse)
        {
            var contextAccessor = _httpContextAccessor ?? SystemBootstrapper.GetInstance <IHttpContextAccessor>();
            var context         = _httpContextAccessor.HttpContext;

            if (httpResponse?.Headers?.Any() == true)
            {
                foreach (var header in httpResponse?.Headers)
                {
                    context.Response.Headers.Add(header.Key, new StringValues(header.Value.ToArray()));
                }
            }

            if (httpResponse?.Content?.Headers?.Any() == true)
            {
                foreach (var header in httpResponse?.Content?.Headers)
                {
                    context.Response.Headers.Add(header.Key, new StringValues(header.Value.ToArray()));
                }
            }

            context.Response.StatusCode = (int)httpResponse.StatusCode;

            if (!httpResponse.Content.IsNull())
            {
                var body = httpResponse.Content.ReadAsStreamAsync().Result;
                body.CopyToAsync(context.Response.Body).Wait();
                body.Close();
            }
        }
Esempio n. 7
0
        /// <summary>
        /// CTOR
        /// </summary>
        /// <param name="faultMessage"></param>
        /// <param name="httpStatusCode"></param>
        /// <param name="translateFaultMessage"></param>
        public CodeSpecificErrorInfo(string faultMessage, HttpStatusCode httpStatusCode, bool translateFaultMessage = true)
        {
            var localizer = SystemBootstrapper.GetInstance <ILocalizationProvider>();

            FaultMessage       = faultMessage;
            UserVisibleMessage = translateFaultMessage ? localizer?.Get(faultMessage)?.Value ?? null : null;
            HttpStatusCode     = httpStatusCode;
        }
Esempio n. 8
0
        public void MyService_WhenInjected_ReturnsValue()
        {
            var service = new RegistrationService();

            SystemBootstrapper.Init(service, typeof(DotNetCoreTests).Assembly);
            SystemBootstrapper.Bootstrap(this);

            Assert.Equal(3, MyService1.Add(1, 2));
        }
Esempio n. 9
0
        /// <summary>
        /// CTOR
        /// </summary>
        /// <param name="exception"></param>
        public UnmanagedExceptionErrorInfo(Exception exception)
        {
            Exception    = exception;
            FaultMessage = exception.Message;

            var localizer = SystemBootstrapper.GetInstance <ILocalizationProvider>();

            UserVisibleMessage = localizer?.Get("SystemError")?.Value ?? "Something happened!";
        }
Esempio n. 10
0
        /// <summary>
        /// <see cref="ISyncTask"/> execution handle
        /// </summary>
        public void Execute()
        {
            var factor   = SystemBootstrapper.GetInstance <IProcessFactory>();
            var executor = SystemBootstrapper.GetInstance <IProcessExecutor>();

            var instance = factor.Create <VoidResult>(InnerProcessType);

            executor.Execute(instance);
        }
Esempio n. 11
0
        public void MyService_WhenRegistered_InstantiatedAsInterface_ReturnsValue()
        {
            var service = new RegistrationService();

            SystemBootstrapper.Init(service, typeof(DotNetCoreTests).Assembly);

            var srv = SystemBootstrapper.GetInstance <IMyService1>();

            Assert.Equal(3, srv.Add(1, 2));
        }
Esempio n. 12
0
        /// <summary>
        /// Inject all properties and fields annotated with <see cref="ImportAttribute"/>
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="recursive"></param>
        private void InjectInternal(object obj, bool recursive)
        {
            if (obj == null)
            {
                return;
            }
            if (obj is IEnumerable)
            {
                return;
            }

            var type         = obj.GetType();
            var assemblyName = type.Assembly.FullName;

            if (assemblyName.StartsWith("System"))
            {
                return;
            }
            if (assemblyName.StartsWith("Microsoft"))
            {
                return;
            }

            // public and private properties and fields
            var injectables = GetInjectables(type);

            foreach (var injectable in injectables)
            {
                var instance = SystemBootstrapper.GetInstance(injectable.PropertyType);

                if (instance != null)
                {
                    injectable.SetValue(obj, instance);
                }
            }

            if (recursive)
            {
                var fields     = GetFields(type);
                var properties = GetProperties(type);

                // Recursively inject instances of child properties to all properties
                foreach (var property in properties)
                {
                    InjectInternal(property.GetValue(obj), recursive);
                }

                // Recursively inject instances of child properties to all fields
                foreach (var field in fields)
                {
                    InjectInternal(field.GetValue(obj), recursive);
                }
            }
        }
Esempio n. 13
0
        public void MyService_WhenRegistered_InstantiatedAsConcrete_ReturnsValue()
        {
            var service = new RegistrationService();

            service.Register <MyService1>();

            SystemBootstrapper.Init(service, typeof(SimpleInjectorTests).Assembly);

            var srv = SystemBootstrapper.GetInstance <MyService1>();

            Assert.Equal(3, srv.Add(1, 2));
        }
Esempio n. 14
0
        /// <summary>
        /// CTOR
        /// </summary>
        public WebMediator()
        {
            // Order is important
            CustomUrlHandlers = new List <ICustomUrlHandler>
            {
                new DocsHandler()
            };

            // order is not important
            Filters = new List <IFilter>
            {
                new TypeFilter(),
                new HttpMethodFilter(),
                new RouteFilter()
            };

            // order is not important
            FactoryFilters = new List <IFactoryFilter> {
                new IsCachedFactoryFilter()
            };

            DefaultModelBinders = new Dictionary <SignalsApiMethod, BaseModelBinder>
            {
                { SignalsApiMethod.OPTIONS, new FromQuery() },
                { SignalsApiMethod.GET, new FromQuery() },
                { SignalsApiMethod.HEAD, new FromHeader() },
                { SignalsApiMethod.POST, new FromBody() },
                { SignalsApiMethod.PUT, new FromBody() },
                { SignalsApiMethod.DELETE, new FromQuery() }
            };

            // order is important, JsonResult is default fallback
            ResultHandlers = new List <IResultHandler> {
                new HeaderAdderHandler(),
                new AuthenticationFailResultFilter(),
                new AuthorizationFailResultFilter(),
                new UnmanagedFailResultFilter(),
                new SpecificationFailResultFilter(),
                new CodeSpecificFailResultFilter(),
                new GeneralFailResultFilter(),
                new CacheResultHandler(),
                new FileResultHandler(),
                new XmlResultHandler(),
                new NativeResultHandler(),
                new JsonResultHandler()
            };

            // get process repo instance
            ProcessRepository = SystemBootstrapper.GetInstance <ProcessRepository>();
            ProcessFactory    = SystemBootstrapper.GetInstance <IProcessFactory>();
            ProcessExecutor   = SystemBootstrapper.GetInstance <IProcessExecutor>();
        }
Esempio n. 15
0
        /// <summary>
        /// .Net core middleware registration extension
        /// </summary>
        /// <param name="app"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseSignals(this IApplicationBuilder app)
        {
            var mediator = SystemBootstrapper.GetInstance <WebMediator>();

            // mediator middleware
            return(app.Use(async(httpContext, next) =>
            {
                if (mediator.Dispatch() != MiddlewareResult.StopExecutionAndStopMiddlewarePipe)
                {
                    await next();
                }
            }));
        }
Esempio n. 16
0
        /// <summary>
        /// Append docs to http response
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public MiddlewareResult RenderContent(IHttpContextWrapper context)
        {
            if (!context.RawUrl.ToLowerInvariant().Contains("api/spec"))
            {
                return(MiddlewareResult.DoNothing);
            }

            var cache    = SystemBootstrapper.GetInstance <ICache>();
            var cacheKey = "cache:api/spec";

            OpenApiDocument docs;
            var             cachedDocs = cache.Get <OpenApiDocument>(cacheKey);

            if (cachedDocs.IsNull())
            {
                docs = GenerateDocs();

                cache.Set(new CacheEntry(cacheKey, docs)
                {
                    ExpirationTime   = TimeSpan.FromDays(10000),
                    ExpirationPolicy = CacheExpirationPolicy.Sliding
                });
            }
            else
            {
                docs = cachedDocs;
            }

            string docsString;
            string contentType;

            if (context.RawUrl.ToLowerInvariant().EndsWith(".yaml"))
            {
                docsString  = docs.Serialize(OpenApiSpecVersion.OpenApi2_0, OpenApiFormat.Yaml);
                contentType = "text/x-yaml";
            }
            else
            {
                docsString  = docs.Serialize(OpenApiSpecVersion.OpenApi2_0, OpenApiFormat.Json);
                contentType = "application/json";
            }

            context.PutResponse(new HttpResponseMessage
            {
                Content = new StringContent(docsString, System.Text.Encoding.UTF8, contentType)
            });

            return(MiddlewareResult.StopExecutionAndStopMiddlewarePipe);
        }
Esempio n. 17
0
        /// <summary>
        /// Handle process result
        /// </summary>
        /// <typeparam name="TProcess"></typeparam>
        /// <param name="process"></param>
        /// <param name="type"></param>
        /// <param name="response"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public MiddlewareResult HandleAfterExecution <TProcess>(TProcess process, Type type, VoidResult response, IHttpContextWrapper context) where TProcess : IBaseProcess <VoidResult>
        {
            if (!response.IsFaulted)
            {
                var cacheAttribute = type.GetCustomAttributes(typeof(OutputCacheAttribute), true).Cast <OutputCacheAttribute>().SingleOrDefault();

                if (cacheAttribute != null && (cacheAttribute.Location == CacheLocation.Server || cacheAttribute.Location == CacheLocation.ClientAndServer))
                {
                    var cache = SystemBootstrapper.GetInstance <ICache>();
                    if (cache != null)
                    {
                        var key = type.FullName;

                        if (!cacheAttribute.VaryByQueryParams.IsNullOrHasZeroElements())
                        {
                            var queryValues = context
                                              ?.Query
                                              ?.Where(x => cacheAttribute.VaryByQueryParams.Contains(x.Key))
                                              ?.OrderBy(x => x.Key)
                                              ?.Select(x => x.Value)
                                              ?.SerializeJson();

                            if (!queryValues.IsNullOrEmpty())
                            {
                                key = $"{type.FullName}+{queryValues}";
                            }
                        }

                        var entry = cache.Get(key);

                        if (entry.IsNull())
                        {
                            cache.Set(new CacheEntry(key, response)
                            {
                                ExpirationTime   = TimeSpan.FromSeconds(cacheAttribute.Duration),
                                ExpirationPolicy = CacheExpirationPolicy.Absolute
                            });
                        }
                    }
                }

                if (cacheAttribute != null && (cacheAttribute.Location == CacheLocation.Client || cacheAttribute.Location == CacheLocation.ClientAndServer))
                {
                    context.Headers.AddToResponse("Cache-Control", $"max-age={cacheAttribute.Duration}, public");
                }
            }

            return(MiddlewareResult.DoNothing);
        }
Esempio n. 18
0
        /// <summary>
        /// Validates instance
        /// </summary>
        /// <typeparam name="TProcess"></typeparam>
        /// <param name="instance"></param>
        /// <param name="type"></param>
        /// <param name="context"></param>
        /// <returns>Is instance valid</returns>
        public MiddlewareResult IsValidInstance <TProcess>(TProcess instance, Type type, IHttpContextWrapper context) where TProcess : IBaseProcess <VoidResult>
        {
            var cacheAttribute = type.GetCustomAttributes(typeof(OutputCacheAttribute), true).Cast <OutputCacheAttribute>().SingleOrDefault();

            if (cacheAttribute != null && (cacheAttribute.Location == CacheLocation.Server || cacheAttribute.Location == CacheLocation.ClientAndServer))
            {
                var cache = SystemBootstrapper.GetInstance <ICache>();
                if (cache != null)
                {
                    var key = type.FullName;

                    if (!cacheAttribute.VaryByQueryParams.IsNullOrHasZeroElements())
                    {
                        var queryValues = context
                                          ?.Query
                                          ?.Where(x => cacheAttribute.VaryByQueryParams.Contains(x.Key))
                                          ?.OrderBy(x => x.Key)
                                          ?.Select(x => x.Value)
                                          ?.SerializeJson();

                        if (!queryValues.IsNullOrEmpty())
                        {
                            key = $"{type.FullName}+{queryValues}";
                        }
                    }

                    var entry = cache.Get(key);

                    if (!entry.IsNull())
                    {
                        var webMediator = SystemBootstrapper.GetInstance <WebMediator>();
                        var httpContext = SystemBootstrapper.GetInstance <IHttpContextWrapper>();

                        foreach (var executeEvent in webMediator.ResultHandlers)
                        {
                            var result = executeEvent.HandleAfterExecution(instance, type, (VoidResult)entry.Value, httpContext);
                            if (result != MiddlewareResult.DoNothing)
                            {
                                return(result);
                            }
                        }
                    }
                }
            }

            return(MiddlewareResult.DoNothing);
        }
        /// <summary>
        /// Schedule recurring tasks
        /// </summary>
        private static void ScheduleRecurring()
        {
            var bgRegistry = SystemBootstrapper.GetInstance <ITaskRegistry>();

            if (!bgRegistry.IsNull())
            {
                var processRepo = SystemBootstrapper.GetInstance <ProcessRepository>();
                processRepo.OfType <IRecurringProcess>().ForEach(type =>
                {
                    var instance = SystemBootstrapper.GetInstance(type) as IRecurringProcess;
                    var task     = new RecurringTaskWrapper(type);

                    bgRegistry.ScheduleTask(task, instance.Profile);
                });

                bgRegistry.Start();
            }
        }
Esempio n. 20
0
        /// <summary>
        /// CTOR
        /// </summary>
        /// <param name="specificaitonResult"></param>
        public SpecificationErrorInfo(SpecificationResult specificaitonResult)
        {
            if (!specificaitonResult.IsValid)
            {
                FaultMessage = specificaitonResult.Input.IsNull() ?
                               $"Specificaiton {specificaitonResult.SpecificationType.Name} failed" :
                               $"Specificaiton {specificaitonResult.SpecificationType.Name} failed for input {specificaitonResult.Input.GetType().Name} with payload {specificaitonResult.Input.SerializeJson()}";

                var localizer = SystemBootstrapper.GetInstance <ILocalizationProvider>();

                if (!localizer.IsNull())
                {
                    var specificaitonName = specificaitonResult.SpecificationType.Name;
                    var parametarlessName = specificaitonName.Split('`')[0];
                    UserVisibleMessage = localizer?.Get(parametarlessName)?.Value;
                }
            }
        }
Esempio n. 21
0
        /// <summary>
        /// Execute handler
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="process"></param>
        /// <param name="processType"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public TResult Execute <TResult>(IBaseProcess <TResult> process, Type processType, params object[] args) where TResult : VoidResult, new()
        {
            var auditProvider = SystemBootstrapper.GetInstance <IAuditProvider>();

            if (auditProvider.IsNull())
            {
                return(Next.Execute(process, processType, args));
            }

            var entry = auditProvider.Entry();

            entry.Originator = ApplicationConfiguration.Instance?.ApplicationName ?? Environment.MachineName;
            entry.Process    = process.Name;
            entry.EventType  = process.Description;
            entry.EpicId     = process.EpicId;
            entry.Payload    = args?.SerializeJson();

            return(auditProvider.Audit(entry, () => Next.Execute(process, processType, args)));
        }
Esempio n. 22
0
        /// <summary>
        /// Execute handler
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="process"></param>
        /// <param name="processType"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public TResult Execute <TResult>(IBaseProcess <TResult> process, Type processType, params object[] args) where TResult : VoidResult, new()
        {
            var innerResult = Next.Execute(process, processType, args);
            var logger      = SystemBootstrapper.GetInstance <ILogger>();

            if (logger.IsNull())
            {
                return(innerResult);
            }

            if (innerResult.IsFaulted)
            {
                if (innerResult.IsSystemFault)
                {
                    var errorInfo = innerResult.ErrorMessages.OfType <UnmanagedExceptionErrorInfo>().SingleOrDefault();
                    var exception = errorInfo.Exception;
                    var entry     = LogEntry.Exception(exception, message: innerResult.GetFaultMessage());

                    entry.ProcessName    = process.Name;
                    entry.Action         = exception.TargetSite?.Name;
                    entry.Origin         = ApplicationConfiguration.Instance?.ApplicationName ?? Environment.MachineName;
                    entry.Payload        = args?.SerializeJson();
                    entry.UserIdentifier = process.BaseContext?.CurrentUserPrincipal?.Identity?.Name;

                    logger.Fatal(entry);
                }
                else
                {
                    var entry = LogEntry.Trace(message: innerResult.GetFaultMessage(), payload: args);

                    entry.ProcessName    = process.Name;
                    entry.Action         = process.Name;
                    entry.Origin         = ApplicationConfiguration.Instance?.ApplicationName ?? Environment.MachineName;
                    entry.Payload        = args?.SerializeJson();
                    entry.UserIdentifier = process.BaseContext?.CurrentUserPrincipal?.Identity?.Name;

                    logger.Info(entry);
                }
            }

            return(innerResult);
        }
        /// <summary>
        /// Send email on startup
        /// </summary>
        private static void NotifyOnStartup()
        {
            var config     = BackgroundApplicationConfiguration.Instance.StartupNotificationConfiguration;
            var smtpClient = SystemBootstrapper.GetInstance <ISmtpClient>();

            if (!smtpClient.IsNull() && !config.IsNull())
            {
                var tos     = config.Emails;
                var subject = config.Subject;
                var body    = config.Body;

                if (tos.IsNullOrHasZeroElements())
                {
                    return;
                }
                if (subject.IsNullOrEmpty())
                {
                    return;
                }
                if (body.IsNullOrEmpty())
                {
                    return;
                }

                var from = ApplicationConfiguration.Instance.ApplicationEmail;

                var message = new MailMessage();
                message.From       = new MailAddress(from);
                message.Subject    = subject;
                message.Body       = body;
                message.IsBodyHtml = true;

                foreach (var to in tos)
                {
                    message.To.Add(to);
                }

                var sendTask = smtpClient.SendMailAsync(message);
                Task.WaitAll(sendTask);
            }
        }
Esempio n. 24
0
        /// <summary>
        /// OWIN middleware registration extension
        /// </summary>
        /// <param name="app"></param>
        /// <param name="configurationCallback"></param>
        /// <returns></returns>
        public static IAppBuilder MapSignals(this IAppBuilder app, Action <FluentWebApplicationBootstrapConfiguration> configurationCallback)
        {
            var ass = AppDomain.CurrentDomain.GetAssemblies();
            // get entry assembly
            StackTrace stackTrace = new StackTrace();
            // TODO: workaround for tests
            var assembly = stackTrace.GetFrame(1).GetMethod().DeclaringType.Assembly;

            // configure web applicaiton
            var configuration = new FluentWebApplicationBootstrapConfiguration();

            configurationCallback(configuration);
            configuration.ScanAssemblies.Add(assembly);
            configuration.Bootstrap(configuration.ScanAssemblies.ToArray());

            // register midleware for handling session
            app.Use(async(IOwinContext context, Func <Task> next) =>
            {
                HttpContextBase httpContext = context.Get <HttpContextBase>(typeof(HttpContextBase).FullName);
                httpContext.SetSessionStateBehavior(SessionStateBehavior.Required);
                await next.Invoke();
            });

            // handle session
            app.UseStageMarker(PipelineStage.MapHandler);

            var mediator = SystemBootstrapper.GetInstance <WebMediator>();

            // mediator middleware
            return(app.Use(async(IOwinContext context, Func <Task> next) =>
            {
                if (mediator.Dispatch() != MiddlewareResult.StopExecutionAndStopMiddlewarePipe)
                {
                    await next.Invoke();
                }
            }));
        }
Esempio n. 25
0
        /// <summary>
        /// Authorization callback
        /// </summary>
        /// <param name="feature"></param>
        /// <returns></returns>
        internal bool Authorize(string feature)
        {
            var permissionManager = SystemBootstrapper.GetInstance <IPermissionManager>();

            return(permissionManager.HasPermission(feature, Roles.Cast <Enum>().ToArray()));
        }
Esempio n. 26
0
        /// <summary>
        /// Register all aspects into dependency resolver
        /// </summary>
        /// <returns></returns>
        public IServiceContainer Bootstrap(params Assembly[] scanAssemblies)
        {
            // Proc config validation
            ApplicationConfiguration config = null;

            try
            {
                config = ApplicationConfiguration.Instance;
            }
            catch { }
            finally
            {
                if (config.IsNull())
                {
                    throw new Exception("Signals.Core.Configuration.ApplicationConfiguration is not provided. Please use a configuration provider to provide configuration values!");
                }
            }

            if (DependencyResolver.IsNull() || DependencyResolver().IsNull())
            {
                throw new Exception("Dependency resolver not configured");
            }

            var resolver = DependencyResolver();

            if (!Logging.IsNull() && !Logging().IsNull())
            {
                resolver.Register(typeof(ILogger), Logging());
            }
            if (!Auditing.IsNull() && !Auditing().IsNull())
            {
                resolver.Register(typeof(IAuditProvider), Auditing());
            }
            if (!Cache.IsNull() && !Cache().IsNull())
            {
                resolver.Register(typeof(ICache), Cache());
            }
            if (!Localization.IsNull() && !Localization().IsNull())
            {
                resolver.Register(typeof(ILocalizationProvider), Localization());
            }
            if (!Storage.IsNull() && !Storage().IsNull())
            {
                resolver.Register(typeof(IStorageProvider), Storage());
            }
            if (!MessageChannel.IsNull() && !MessageChannel().IsNull())
            {
                resolver.Register(typeof(IMessageChannel), MessageChannel());
            }
            if (!AuthenticationManager.IsNull() && !AuthenticationManager().IsNull())
            {
                resolver.Register(typeof(IAuthenticationManager), AuthenticationManager());
            }
            if (!AuthorizationManager.IsNull() && !AuthorizationManager().IsNull())
            {
                resolver.Register(typeof(IAuthorizationManager), AuthorizationManager());
            }
            if (!TaskRegistry.IsNull() && !TaskRegistry().IsNull())
            {
                resolver.Register(typeof(ITaskRegistry), TaskRegistry());
            }
            if (!PermissionProvider.IsNull() && !PermissionProvider().IsNull())
            {
                resolver.Register(typeof(IPermissionProvider), PermissionProvider());
            }
            if (!Benchmarker.IsNull() && !Benchmarker().IsNull())
            {
                resolver.Register(typeof(IBenchmarker), Benchmarker());
            }
            if (!PermissionManager.IsNull() && !PermissionManager().IsNull())
            {
                resolver.Register(typeof(IPermissionManager), PermissionManager());
            }

            resolver.Register <CriticalErrorCallbackManager>();
            resolver.Register <IProcessFactory, ProcessFactory>();
            resolver.Register <IProcessExecutor, ProcessExecutor>();

            resolver.Register <IBusinessProcessContext, BusinessProcessContext>();
            resolver.Register <IApiProcessContext, ApiProcessContext>();
            resolver.Register <IDistributedProcessContext, DistributedProcessContext>();
            resolver.Register <IFileExportProcessContext, FileExportProcessContext>();
            resolver.Register <IFileImportProcessContext, FileImportProcessContext>();
            resolver.Register <IRecurringProcessContext, RecurringProcessContext>();

            resolver.Register <Mediator>();

            RegisterProcesses(config, resolver, scanAssemblies);
            RegisterErrorHendling(config, resolver);
            RegisterJsonSerializerSettings(config, resolver);
            RegisterSmtp(config, resolver);
            RegisterSyncLogProvider(config, resolver);

            var services = SystemBootstrapper.Init(resolver, scanAssemblies);

            return(services);
        }
Esempio n. 27
0
        /// <summary>
        /// Executed when test class is initialized
        /// </summary>
        public BaseProcessesTest()
        {
            string environment = null;

            FileConfigurationProvider ProviderForFile(string name) => new FileConfigurationProvider
            {
                File           = name,
                Path           = environment.IsNullOrEmpty() ? Path.Combine(AppContext.BaseDirectory, $"configs") : Path.Combine(AppContext.BaseDirectory, $"configs", environment),
                ReloadOnAccess = false
            };

            EnvironmentConfiguration.UseProvider(ProviderForFile("environment.config.json"));
            environment = EnvironmentConfiguration.Instance.Environment;

            ApplicationConfiguration.UseProvider(ProviderForFile("application.config.json"));
            DomainConfiguration.UseProvider(ProviderForFile("domain.config.json"));

            TestBootstrapConfiguraiton config = new TestBootstrapConfiguraiton
            {
                RegistrationService = new RegistrationService(),
                CacheConfiguration  = new InMemoryCacheConfiguration
                {
                    DataProvider     = new InMemoryDataProvider(),
                    ExpirationPolicy = CacheExpirationPolicy.Sliding,
                    ExpirationTime   = TimeSpan.FromMinutes(1)
                },
                LoggerConfiguration = new DatabaseLoggingConfiguration
                {
                    Database     = DomainConfiguration.Instance.DatabaseConfiguration.ActiveConfiguration.Database,
                    Host         = DomainConfiguration.Instance.DatabaseConfiguration.ActiveConfiguration.IpAddress,
                    Username     = DomainConfiguration.Instance.DatabaseConfiguration.ActiveConfiguration.Uid,
                    Password     = DomainConfiguration.Instance.DatabaseConfiguration.ActiveConfiguration.Pwd,
                    DataProvider = DataProvider.SqlClient,
                    TableName    = "LogEntity"
                },
                LocalizationConfiguration = new JsonDataProviderConfiguration
                {
                    DirectoryPath       = Path.Combine(AppContext.BaseDirectory, "system.resources"),
                    FileExtension       = "app",
                    LocalizationSources = new List <LocalizationSource>
                    {
                        new LocalizationSource
                        {
                            Name       = "Mail messages",
                            SourcePath = "mailmessages"
                        },
                        new LocalizationSource
                        {
                            Name       = "Validation rules",
                            SourcePath = "validationrules"
                        },
                        new LocalizationSource
                        {
                            Name       = "Pages",
                            SourcePath = "pages"
                        },
                        new LocalizationSource
                        {
                            Name       = "Processes",
                            SourcePath = "processes"
                        }
                    }
                },
                StrategyBuilder = new StrategyBuilder().SetAutoHandling(false)
            };

            config.JsonSerializerSettings = new Newtonsoft.Json.JsonSerializerSettings();
            config.JsonSerializerSettings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);

            var assemblies = Directory.GetFiles(AppContext.BaseDirectory, "*.dll").Select(file => Assembly.LoadFrom(file)).ToArray();

            config.Bootstrap(assemblies);

            SystemBootstrapper.Bootstrap(this);
        }
Esempio n. 28
0
        /// <summary>
        /// Get api document generated from all api processes
        /// </summary>
        /// <returns></returns>
        private OpenApiDocument GenerateDocs()
        {
            var headers         = SystemBootstrapper.GetInstance <List <ResponseHeaderAttribute> >();
            var processRepo     = SystemBootstrapper.GetInstance <ProcessRepository>();
            var allApiProcesses = processRepo.OfType <IApiProcess>();

            var document = new OpenApiDocument
            {
                Info = new OpenApiInfo
                {
                    Version = ApplicationConfiguration.Instance.ApplicationVersion,
                    Title   = ApplicationConfiguration.Instance.ApplicationName,
                },
                Servers = new List <OpenApiServer>
                {
                    new OpenApiServer {
                        Url = $"{WebApplicationConfiguration.Instance.WebUrl.TrimEnd('/')}/api/"
                    }
                },
                Paths      = new OpenApiPaths(),
                Components = new OpenApiComponents()
            };

            if (allApiProcesses.Any())
            {
                var assemblyNamespace = allApiProcesses.First().Assembly.FullName.Split(',')[0];
                foreach (var type in allApiProcesses)
                {
                    var instance         = SystemBootstrapper.GetInstance(type) as IBaseProcess <VoidResult>;
                    var attribute        = type.GetCustomAttributes(typeof(SignalsApiAttribute), false).Cast <SignalsApiAttribute>().SingleOrDefault();
                    var headerAttributes = type
                                           .GetCustomAttributes(typeof(ResponseHeaderAttribute), false)
                                           .Cast <ResponseHeaderAttribute>()
                                           .Concat(headers)
                                           .DistinctBy(x => x.Headers.Keys)
                                           .ToList();

                    var contentType = EnumExtensions.GetDescription(SerializationFormat.Json);
                    var httpMethod  = SignalsApiMethod.ANY;

                    if (!attribute.IsNull())
                    {
                        if (attribute.ExposeApiDocs == false)
                        {
                            continue;
                        }
                        contentType = EnumExtensions.GetDescription(attribute.ResponseType);
                        httpMethod  = attribute.HttpMethod;
                    }

                    var pathItem      = new OpenApiPathItem();
                    var operationItem = new OpenApiOperation();

                    var path            = type.FullName.Replace(assemblyNamespace, "").Replace('.', '/');
                    var processGenerics = type.BaseType.GetGenericArguments();

                    var headersDictionary = new Dictionary <string, OpenApiHeader>();

                    foreach (var header in headerAttributes)
                    {
                        foreach (var headerValue in header.Headers)
                        {
                            headersDictionary.Add(headerValue.Key, new OpenApiHeader
                            {
                                Schema = new OpenApiSchema
                                {
                                    Type = "string"
                                },
                                Example = new OpenApiString(headerValue.Value)
                            });
                        }
                    }

                    operationItem.Tags = new List <OpenApiTag>
                    {
                        new OpenApiTag
                        {
                            Name = type.Namespace.Split('.').Last()
                        }
                    };
                    operationItem.Summary     = instance.Description.IsNullOrEmpty() ? instance.Name : instance.Description;
                    operationItem.Description = instance.Name;
                    operationItem.OperationId = type.Name;

                    // Determine the request based on the process type
                    Type request = null;
                    Type response;
                    var  processType = type.BaseType.Name;
                    switch (processType)
                    {
                    case "ProxyApiProcess`5":
                        request = processGenerics[3];
                        break;

                    case "ProxyApiProcess`4":
                        request = processGenerics[1];
                        break;

                    case "ProxyApiProcess`3":
                        break;

                    case "AutoApiProcess`3":
                        request = processGenerics[2];
                        break;

                    case "AutoApiProcess`2":
                        request = processGenerics[1];
                        break;

                    case "AutoApiProcess`1":
                        break;

                    default:
                        request = processGenerics.Length > 1 ? processGenerics.First() : null;
                        break;
                    }

                    // Determine the response based on the process type
                    if (processType.StartsWith("ProxyApiProcess") ||
                        processType.StartsWith("AutoApiProcess"))
                    {
                        var underlyingProcessType     = processGenerics.First();
                        var underlyingProcessGenerics = underlyingProcessType.BaseType.GetGenericArguments();
                        response = underlyingProcessGenerics.Any() ? underlyingProcessGenerics.Last() : null;
                    }
                    else
                    {
                        response = processGenerics.Last();
                    }

                    // Determine the payload response
                    if (response != null)
                    {
                        if (response.Name.StartsWith("MethodResult") ||
                            response.Name.StartsWith("ListResult"))
                        {
                            response = response.GetGenericArguments().First();
                        }
                        else if (response.Name.StartsWith("VoidResult"))
                        {
                            response = null;
                        }
                    }

                    var enumTypes = new List <Type>();

                    var requestSchema  = Deserialize(request, ref enumTypes);
                    var responseSchema = Deserialize(response, ref enumTypes);

                    var requestPath = string.Empty;
                    if (request != null)
                    {
                        requestPath = $"{request.Namespace.Replace($"{assemblyNamespace}.", string.Empty)}.{request.Name}";
                    }

                    var responsePath = string.Empty;
                    if (response != null)
                    {
                        responsePath = $"{response.Namespace.Replace($"{assemblyNamespace}.", string.Empty)}.{response.Name}";
                    }

                    if (!requestSchema.IsNullOrHasZeroElements())
                    {
                        if (httpMethod == SignalsApiMethod.POST)
                        {
                            operationItem.RequestBody = new OpenApiRequestBody
                            {
                                Content = new Dictionary <string, OpenApiMediaType>
                                {
                                    {
                                        contentType,
                                        new OpenApiMediaType
                                        {
                                            Schema = new OpenApiSchema
                                            {
                                                Reference = request != null
                                                    ? new OpenApiReference
                                                {
                                                    Id               = $"definitions/{requestPath}",
                                                    Type             = ReferenceType.Schema,
                                                    ExternalResource = ""
                                                }
                                                    : null,
                                                Properties = requestSchema
                                            }
                                        }
                                    }
                                }
                            };
                        }
                        else
                        {
                            foreach (var pair in requestSchema)
                            {
                                if (pair.Value.Properties.Any())
                                {
                                    operationItem.Parameters.Add(new OpenApiParameter
                                    {
                                        In        = ParameterLocation.Query,
                                        Name      = pair.Key,
                                        Reference = request != null
                                            ? new OpenApiReference
                                        {
                                            Id               = $"definitions/{requestPath}",
                                            Type             = ReferenceType.Schema,
                                            ExternalResource = ""
                                        }
                                            : null,
                                        Schema = pair.Value
                                    });

                                    if (!document.Components.Schemas.ContainsKey(requestPath))
                                    {
                                        document.Components.Schemas.Add($"{requestPath}", new OpenApiSchema {
                                            Properties = pair.Value.Properties
                                        });
                                    }
                                }
                                else
                                {
                                    operationItem.Parameters.Add(new OpenApiParameter
                                    {
                                        In     = ParameterLocation.Query,
                                        Name   = pair.Key,
                                        Schema = pair.Value
                                    });
                                }
                            }
                        }
                    }

                    operationItem.Responses = new OpenApiResponses
                    {
                        ["default"] = new OpenApiResponse
                        {
                            Content = new Dictionary <string, OpenApiMediaType>
                            {
                                {
                                    contentType,
                                    new OpenApiMediaType
                                    {
                                        Schema = new OpenApiSchema
                                        {
                                            Reference = new OpenApiReference
                                            {
                                                Id               = $"definitions/{responsePath}",
                                                Type             = ReferenceType.Schema,
                                                ExternalResource = ""
                                            },
                                            Properties = responseSchema
                                        }
                                    }
                                }
                            },
                            Headers = headersDictionary
                        }
                    };

                    if (request != null)
                    {
                        if (!document.Components.Schemas.ContainsKey(requestPath))
                        {
                            document.Components.Schemas.Add(requestPath, new OpenApiSchema {
                                Properties = requestSchema
                            });
                        }
                    }

                    if (response != null)
                    {
                        if (!document.Components.Schemas.ContainsKey(responsePath))
                        {
                            document.Components.Schemas.Add(responsePath, new OpenApiSchema {
                                Properties = responseSchema
                            });
                        }
                    }

                    foreach (var enumType in enumTypes)
                    {
                        if (!document.Components.Schemas.ContainsKey(enumType.Name))
                        {
                            var enums = Enum.GetNames(enumType).Select(x => new OpenApiString(x)).Cast <IOpenApiAny>().ToList();
                            document.Components.Schemas.Add(enumType.Name, new OpenApiSchema {
                                Enum = enums, Type = "string"
                            });
                        }
                    }

                    pathItem.Operations = new Dictionary <OperationType, OpenApiOperation>();

                    foreach (var method in Map(httpMethod))
                    {
                        pathItem.Operations.Add(method, operationItem);
                    }

                    document.Paths.Add(path, pathItem);
                }
            }

            return(document);

            Dictionary <string, OpenApiSchema> Deserialize(Type type, ref List <Type> enumTypes)
            {
                if (type == null)
                {
                    return(null);
                }

                var result = new Dictionary <string, OpenApiSchema>();
                // Set schema props of the parent property
                var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
                Stack <OpenApiSchemaNode> toProcess = new Stack <OpenApiSchemaNode>(properties.Select(x => new OpenApiSchemaNode {
                    Property = x
                }));
                Stack <OpenApiSchema> parentSchemas = new Stack <OpenApiSchema>();

                var MAX_DEPTH = 5;

                // build the object hierarchy
                while (toProcess.Count > 0)
                {
                    var propertyNode = toProcess.Pop();
                    var schema       = GetOpenApiSchema(propertyNode.Property, ref enumTypes);
                    var parentSchema = parentSchemas.Count == 0 ? null : parentSchemas.Pop();
                    if (propertyNode.Depth == MAX_DEPTH)
                    {
                        continue;
                    }

                    if (parentSchema != null)
                    {
                        if (parentSchema.Type == "array")
                        {
                            parentSchema.Items = parentSchema.Items ?? new OpenApiSchema();
                            parentSchema.Items.Properties.Add(schema.Title, schema);
                        }
                        else
                        {
                            parentSchema.Properties.Add(schema.Title, schema);
                        }
                    }
                    else
                    {
                        result.Add(propertyNode.Property.Name, schema);
                    }

                    // process the complex types
                    if (!propertyNode.Property.PropertyType.IsPrimitive &&
                        !propertyNode.Property.PropertyType.IsValueType &&
                        !typeof(IEnumerable).IsAssignableFrom(propertyNode.Property.PropertyType) &&
                        typeof(string) != propertyNode.Property.PropertyType)
                    {
                        properties = propertyNode.Property.PropertyType.GetProperties(BindingFlags.Instance | BindingFlags.Public);
                        foreach (var propertyInfo in properties)
                        {
                            toProcess.Push(new OpenApiSchemaNode {
                                Property = propertyInfo, Depth = propertyNode.Depth + 1
                            });
                            parentSchemas.Push(schema);
                        }
                    }
                    else if (typeof(IDictionary).IsAssignableFrom(propertyNode.Property.PropertyType))
                    {
                        var argument = propertyNode.Property.PropertyType.GetGenericArguments().LastOrDefault();
                        var value    = GetDefaultValue(argument);
                        var obj      = new
                        {
                            @string = value
                        };

                        properties = obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);

                        foreach (var propertyInfo in properties)
                        {
                            toProcess.Push(new OpenApiSchemaNode {
                                Property = propertyInfo, Depth = propertyNode.Depth + 1
                            });
                            parentSchemas.Push(schema);
                        }
                    }
                    else if (typeof(IEnumerable).IsAssignableFrom(propertyNode.Property.PropertyType) &&
                             typeof(string) != propertyNode.Property.PropertyType)
                    {
                        properties = propertyNode.Property.PropertyType
                                     .GetGenericArguments()
                                     .FirstOrDefault()?
                                     .GetProperties(BindingFlags.Instance | BindingFlags.Public) ?? new PropertyInfo[0];
                        foreach (var propertyInfo in properties)
                        {
                            toProcess.Push(new OpenApiSchemaNode {
                                Property = propertyInfo, Depth = propertyNode.Depth + 1
                            });
                            parentSchemas.Push(schema);
                        }
                    }
                }

                return(result);
            }

            object GetDefaultValue(Type t)
            {
                if (t.IsValueType && Nullable.GetUnderlyingType(t) == null)
                {
                    return(Activator.CreateInstance(t));
                }
                else
                {
                    return(null);
                }
            }

            OpenApiSchema GetOpenApiSchema(PropertyInfo property, ref List <Type> enumTypes)
            {
                var schema = new OpenApiSchema
                {
                    Title = property.Name
                };

                // set the property name
                if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType) &&
                    typeof(string) != property.PropertyType)
                {
                    schema.Type = "array";
                    return(schema);
                }
                else if (property.PropertyType.IsEnum)
                {
                    var enums = Enum.GetNames(property.PropertyType).Select(x => new OpenApiString(x)).Cast <IOpenApiAny>().ToList();
                    schema.Enum      = enums;
                    schema.Type      = property.PropertyType.Name;
                    schema.Format    = "int32";
                    schema.Example   = enums.FirstOrDefault();
                    schema.Reference = new OpenApiReference
                    {
                        Id               = $"definitions/{property.PropertyType.Name}",
                        Type             = ReferenceType.Schema,
                        ExternalResource = ""
                    };

                    enumTypes.Add(property.PropertyType);
                    return(schema);
                }

                switch (Type.GetTypeCode(property.PropertyType))
                {
                case TypeCode.Boolean:
                {
                    schema.Type = "boolean";
                    break;
                }

                case TypeCode.Byte:
                {
                    schema.Type   = "string";
                    schema.Format = "byte";
                    break;
                }

                case TypeCode.Char:
                {
                    schema.Type = "string";
                    break;
                }

                case TypeCode.DateTime:
                {
                    schema.Type   = "string";
                    schema.Format = "date-time";
                    break;
                }

                case TypeCode.Decimal:
                {
                    schema.Type   = "number";
                    schema.Format = "double";
                    break;
                }

                case TypeCode.Double:
                {
                    schema.Type   = "number";
                    schema.Format = "double";
                    break;
                }

                case TypeCode.Int16:
                {
                    schema.Type   = "integer";
                    schema.Format = "int32";
                    break;
                }

                case TypeCode.Int32:
                {
                    schema.Type   = "integer";
                    schema.Format = "int32";
                    break;
                }

                case TypeCode.Int64:
                {
                    schema.Type   = "integer";
                    schema.Format = "int64";
                    break;
                }

                case TypeCode.SByte:
                {
                    schema.Type   = "string";
                    schema.Format = "byte";
                    break;
                }

                case TypeCode.Single:
                {
                    schema.Type   = "number";
                    schema.Format = "float";
                    break;
                }

                case TypeCode.String:
                {
                    schema.Type = "string";
                    break;
                }

                case TypeCode.UInt16:
                {
                    schema.Type   = "integer";
                    schema.Format = "int32";
                    break;
                }

                case TypeCode.UInt32:
                {
                    schema.Type   = "integer";
                    schema.Format = "int32";
                    break;
                }

                case TypeCode.UInt64:
                {
                    schema.Type   = "integer";
                    schema.Format = "int64";
                    break;
                }
                }

                return(schema);
            }

            // map http method to open api method
            List <OperationType> Map(SignalsApiMethod method)
            {
                if (method == SignalsApiMethod.ANY)
                {
                    return new List <OperationType>
                           {
                               OperationType.Get,
                               OperationType.Post
                           }
                }
                ;
                else if (method == SignalsApiMethod.DELETE)
                {
                    return new List <OperationType> {
                               OperationType.Delete,
                    }
                }
                ;
                else if (method == SignalsApiMethod.GET)
                {
                    return new List <OperationType> {
                               OperationType.Get,
                    }
                }
                ;
                else if (method == SignalsApiMethod.OPTIONS)
                {
                    return new List <OperationType> {
                               OperationType.Options,
                    }
                }
                ;
                else if (method == SignalsApiMethod.PATCH)
                {
                    return new List <OperationType> {
                               OperationType.Patch,
                    }
                }
                ;
                else if (method == SignalsApiMethod.POST)
                {
                    return new List <OperationType> {
                               OperationType.Post,
                    }
                }
                ;
                else if (method == SignalsApiMethod.PUT)
                {
                    return new List <OperationType> {
                               OperationType.Put,
                    }
                }
                ;

                return(new List <OperationType>());
            }
        }
Esempio n. 29
0
        public static HtmlString Translate(this IHtmlHelper helper, string key)
        {
            var translation = SystemBootstrapper.GetInstance <ILocalizationProvider>()?.Get(key)?.Value;

            return(new HtmlString(translation ?? "Localization provider not initialized"));
        }
Esempio n. 30
0
        /// <summary>
        /// Execute handler
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="process"></param>
        /// <param name="processType"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public TResult Execute <TResult>(IBaseProcess <TResult> process, Type processType, params object[] args) where TResult : VoidResult, new()
        {
            try
            {
                return(Next.Execute(process, processType, args));
            }
            catch (Exception ex)
            {
                var criticalAttributes = processType.GetCustomAttributes(typeof(CriticalAttribute), true).Cast <CriticalAttribute>().ToList();

                if (criticalAttributes.Any())
                {
                    var manager = SystemBootstrapper.GetInstance <CriticalErrorCallbackManager>();
                    manager?.InvokeError(process, processType, args, ex);
                }

                var happeningDate = DateTime.UtcNow;
                if (ApplicationConfiguration.Instance?.CriticalConfiguration != null)
                {
                    string InterpolateException(string originalString)
                    {
                        return(originalString
                               .Replace("[#Date#]", happeningDate.ToString(CultureInfo.InvariantCulture))
                               .Replace("[#Process#]", processType.Name)
                               .Replace("[#Message#]", ex.Message)
                               .Replace("[#StackTrace#]", ex.StackTrace)
                               .Replace("[#Data#]", args?.SerializeJson()));
                    }

                    var client = SystemBootstrapper.GetInstance <ISmtpClient>();

                    if (!client.IsNull())
                    {
                        foreach (var attribute in criticalAttributes)
                        {
                            var emails = attribute.NotificaitonEmails?.Split(',')?.Select(x => x.Trim())?.ToList();

                            if (!emails.IsNullOrHasZeroElements())
                            {
                                var from    = ApplicationConfiguration.Instance.ApplicationEmail;
                                var to      = emails;
                                var subject = InterpolateException(ApplicationConfiguration.Instance.CriticalConfiguration.Subject);
                                var body    = InterpolateException(ApplicationConfiguration.Instance.CriticalConfiguration.Body);

                                var data = $@"Date: {happeningDate.ToString(CultureInfo.InvariantCulture)}{Environment.NewLine}
Process: {processType.Name}{Environment.NewLine}
Message: {ex.Message}{Environment.NewLine}
StackTrace: {ex.StackTrace}{Environment.NewLine}
Data: {args?.SerializeJson()}{Environment.NewLine}";

                                Attachment attachment = Attachment.CreateAttachmentFromString(data, "critical_info.txt");

                                var message = new MailMessage();
                                message.From       = new MailAddress(from);
                                message.Subject    = subject;
                                message.Body       = body;
                                message.IsBodyHtml = true;

                                foreach (var email in emails)
                                {
                                    message.To.Add(email);
                                }

                                message.Attachments.Add(attachment);
                                client.Send(message);
                            }
                        }
                    }
                }

                throw;
            }
        }