public static void Start(SchemaBuilder sb) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { sb.Include <ResetPasswordRequestEntity>() .WithQuery(() => e => new { Entity = e, e.Id, e.RequestDate, e.Code, e.User, e.User.Email }); EmailLogic.AssertStarted(sb); EmailModelLogic.RegisterEmailModel <ResetPasswordRequestEmail>(() => new EmailTemplateEntity { Messages = CultureInfoLogic.ForEachCulture(culture => new EmailTemplateMessageEmbedded(culture) { Text = "<p>{0}</p>".FormatWith(AuthEmailMessage.YouRecentlyRequestedANewPassword.NiceToString()) + "<p>{0} @[User.UserName]</p>".FormatWith(AuthEmailMessage.YourUsernameIs.NiceToString()) + "<p>{0}</p>".FormatWith(AuthEmailMessage.YouCanResetYourPasswordByFollowingTheLinkBelow.NiceToString()) + "<p><a href=\"@[m:Url]\">@[m:Url]</a></p>", Subject = AuthEmailMessage.ResetPasswordRequestSubject.NiceToString() }).ToMList() }); } }
public static void Start(SchemaBuilder sb) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { sb.Include <ResetPasswordRequestEntity>() .WithQuery(() => e => new { Entity = e, e.Id, e.RequestDate, e.Code, e.User, e.User.Email }); EmailLogic.AssertStarted(sb); EmailModelLogic.RegisterEmailModel <ResetPasswordRequestEmail>(() => new EmailTemplateEntity { DisableAuthorization = true, Messages = CultureInfoLogic.ForEachCulture(culture => new EmailTemplateMessageEmbedded(culture) { Text = "<p>{0}</p>".FormatWith(AuthEmailMessage.YouRecentlyRequestedANewPassword.NiceToString()) + "<p>{0} @[User.UserName]</p>".FormatWith(AuthEmailMessage.YourUsernameIs.NiceToString()) + "<p>{0}</p>".FormatWith(AuthEmailMessage.YouCanResetYourPasswordByFollowingTheLinkBelow.NiceToString()) + "<p><a href=\"@[m:Url]\">@[m:Url]</a></p>", Subject = AuthEmailMessage.ResetPasswordRequestSubject.NiceToString() }).ToMList() }); new Graph <ResetPasswordRequestEntity> .Execute(ResetPasswordRequestOperation.Execute) { CanBeNew = false, CanBeModified = false, CanExecute = (e) => e.Lapsed == false ? null : AuthEmailMessage.YourResetPasswordRequestHasExpired.NiceToString(), Execute = (e, args) => { string password = args.GetArg <string>(); e.Lapsed = true; var user = e.User; var error = UserEntity.OnValidatePassword(password); if (error != null) { throw new ApplicationException(error); } user.PasswordHash = Security.EncodePassword(password); using (AuthLogic.Disable()) user.Execute(UserOperation.Save); } } .Register(); } }
public RedirectResult TraslateAppendix(string from) { HelpPermissions.ViewHelp.AssertAuthorized(); var entity = this.ExtractEntity <AppendixHelpEntity>().ApplyChanges(this).Value; entity.AsignTranslatedAppendix(CultureInfoLogic.GetCultureInfoEntity(from)); return(null); }
public static void Start(SchemaBuilder sb, bool countLocalizationHits) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { CultureInfoLogic.AssertStarted(sb); PermissionAuthLogic.RegisterTypes(typeof(TranslationPermission)); if (countLocalizationHits) { DescriptionManager.NotLocalizedMember += DescriptionManager_NotLocalizedMemeber; } } }
public static void Start(SchemaBuilder sb, DynamicQueryManager dqm, ISMSProvider provider, Func <SMSConfigurationEmbedded> getConfiguration) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { CultureInfoLogic.AssertStarted(sb); SMSLogic.getConfiguration = getConfiguration; SMSLogic.Provider = provider; sb.Include <SMSMessageEntity>() .WithQuery(dqm, () => m => new { Entity = m, m.Id, Source = m.From, m.DestinationNumber, m.State, m.SendDate, m.Template }); sb.Include <SMSTemplateEntity>() .WithQuery(dqm, () => t => new { Entity = t, t.Id, t.Name, IsActive = t.IsActiveNow(), Source = t.From, t.AssociatedType, t.StartDate, t.EndDate, }); SMSMessageGraph.Register(); SMSTemplateGraph.Register(); Validator.PropertyValidator <SMSTemplateEntity>(et => et.Messages).StaticPropertyValidation += (t, pi) => { if (!t.Messages.Any(m => m.CultureInfo.Is(SMSLogic.Configuration.DefaultCulture))) { return(SMSTemplateMessage.ThereMustBeAMessageFor0.NiceToString().FormatWith(SMSLogic.Configuration.DefaultCulture.EnglishName)); } return(null); }; } }
public static void Start( SchemaBuilder sb, Func <EmailConfigurationEmbedded> getConfiguration, Func <EmailTemplateEntity?, Lite <Entity>?, SmtpConfigurationEntity> getSmtpConfiguration, Func <EmailMessageEntity, SmtpClient>?getSmtpClient = null, IFileTypeAlgorithm?attachment = null) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { if (getSmtpClient == null && getSmtpConfiguration != null) { getSmtpClient = message => getSmtpConfiguration(message.Template?.Let(a => EmailTemplateLogic.EmailTemplatesLazy.Value.GetOrThrow(a)), message.Target).GenerateSmtpClient(); } FilePathEmbeddedLogic.AssertStarted(sb); CultureInfoLogic.AssertStarted(sb); EmailLogic.getConfiguration = getConfiguration; EmailLogic.GetSmtpClient = getSmtpClient ?? throw new ArgumentNullException(nameof(getSmtpClient)); EmailTemplateLogic.Start(sb, getSmtpConfiguration); if (attachment != null) { FileTypeLogic.Register(EmailFileType.Attachment, attachment); } Schema.Current.WhenIncluded <ProcessEntity>(() => EmailPackageLogic.Start(sb)); sb.Include <EmailMessageEntity>() .WithQuery(() => e => new { Entity = e, e.Id, e.State, e.Subject, e.Template, e.Sent, e.Target, e.Package, e.Exception, }); PermissionAuthLogic.RegisterPermissions(AsyncEmailSenderPermission.ViewAsyncEmailSenderPanel); SenderManager = new EmailSenderManager(); EmailGraph.Register(); } }
public static void Start( SchemaBuilder sb, Func <EmailConfigurationEmbedded> getConfiguration, Func <EmailTemplateEntity?, Lite <Entity>?, EmailMessageEntity?, EmailSenderConfigurationEntity> getEmailSenderConfiguration, IFileTypeAlgorithm?attachment = null) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { FilePathEmbeddedLogic.AssertStarted(sb); CultureInfoLogic.AssertStarted(sb); EmailLogic.getConfiguration = getConfiguration; EmailTemplateLogic.Start(sb, getEmailSenderConfiguration); EmailSenderConfigurationLogic.Start(sb); if (attachment != null) { FileTypeLogic.Register(EmailFileType.Attachment, attachment); } Schema.Current.WhenIncluded <ProcessEntity>(() => EmailPackageLogic.Start(sb)); sb.Include <EmailMessageEntity>() .WithQuery(() => e => new { Entity = e, e.Id, e.State, e.Subject, e.Template, e.Sent, e.Target, e.Package, e.Exception, }); PermissionAuthLogic.RegisterPermissions(AsyncEmailSenderPermission.ViewAsyncEmailSenderPanel); SenderManager = new EmailSenderManager(getEmailSenderConfiguration); EmailGraph.Register(); QueryLogic.Expressions.Register((EmailPackageEntity a) => a.EmailMessages(), () => typeof(EmailMessageEntity).NicePluralName()); ExceptionLogic.DeleteLogs += ExceptionLogic_DeleteLogs; ExceptionLogic.DeleteLogs += ExceptionLogic_DeletePackages; } }
public static void Start(SchemaBuilder sb, string?systemUserName, string?anonymousUserName) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { SystemUserName = systemUserName; AnonymousUserName = anonymousUserName; CultureInfoLogic.AssertStarted(sb); sb.Include <UserEntity>(); sb.Include <RoleEntity>() .WithSave(RoleOperation.Save) .WithDelete(RoleOperation.Delete) .WithQuery(() => r => new { Entity = r, r.Id, r.Name, }); roles = sb.GlobalLazy(CacheRoles, new InvalidateWith(typeof(RoleEntity)), AuthLogic.NotifyRulesChanged); rolesInverse = sb.GlobalLazy(() => roles.Value.Inverse(), new InvalidateWith(typeof(RoleEntity))); rolesByName = sb.GlobalLazy(() => roles.Value.ToDictionaryEx(a => a.ToString()), new InvalidateWith(typeof(RoleEntity))); mergeStrategies = sb.GlobalLazy(() => { var strategies = Database.Query <RoleEntity>().Select(r => KVP.Create(r.ToLite(), r.MergeStrategy)).ToDictionary(); var graph = roles.Value; Dictionary <Lite <RoleEntity>, RoleData> result = new Dictionary <Lite <RoleEntity>, RoleData>(); foreach (var r in graph.CompilationOrder()) { var strat = strategies.GetOrThrow(r); var baseValues = graph.RelatedTo(r).Select(r2 => result[r2].DefaultAllowed); result.Add(r, new RoleData { MergeStrategy = strat, DefaultAllowed = strat == MergeStrategy.Union ? baseValues.Any(a => a) : baseValues.All(a => a) }); } return(result); }, new InvalidateWith(typeof(RoleEntity)), AuthLogic.NotifyRulesChanged); sb.Schema.EntityEvents <RoleEntity>().Saving += Schema_Saving; QueryLogic.Queries.Register(RoleQuery.RolesReferedBy, () => from r in Database.Query <RoleEntity>() from rc in r.Roles select new { Entity = r, r.Id, r.Name, Refered = rc, }); sb.Include <UserEntity>() .WithQuery(() => e => new { Entity = e, e.Id, e.UserName, e.Email, e.Role, e.State, }); UserGraph.Register(); } }
public static void Start(SchemaBuilder sb, string?systemUserName, string?anonymousUserName) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { SystemUserName = systemUserName; AnonymousUserName = anonymousUserName; CultureInfoLogic.AssertStarted(sb); sb.Include <UserEntity>() .WithExpressionFrom((RoleEntity r) => r.Users()) .WithQuery(() => e => new { Entity = e, e.Id, e.UserName, e.Email, e.Role, e.State, e.CultureInfo, }); sb.Include <RoleEntity>() .WithSave(RoleOperation.Save) .WithDelete(RoleOperation.Delete) .WithQuery(() => r => new { Entity = r, r.Id, r.Name, }); roles = sb.GlobalLazy(CacheRoles, new InvalidateWith(typeof(RoleEntity)), AuthLogic.NotifyRulesChanged); rolesInverse = sb.GlobalLazy(() => roles.Value.Inverse(), new InvalidateWith(typeof(RoleEntity))); rolesByName = sb.GlobalLazy(() => roles.Value.ToDictionaryEx(a => a.ToString() !), new InvalidateWith(typeof(RoleEntity))); mergeStrategies = sb.GlobalLazy(() => { var strategies = Database.Query <RoleEntity>().Select(r => KeyValuePair.Create(r.ToLite(), r.MergeStrategy)).ToDictionary(); var graph = roles.Value; Dictionary <Lite <RoleEntity>, RoleData> result = new Dictionary <Lite <RoleEntity>, RoleData>(); foreach (var r in graph.CompilationOrder()) { var strat = strategies.GetOrThrow(r); var baseValues = graph.RelatedTo(r).Select(r2 => result[r2].DefaultAllowed); result.Add(r, new RoleData { MergeStrategy = strat, DefaultAllowed = strat == MergeStrategy.Union ? baseValues.Any(a => a) : baseValues.All(a => a) }); } return(result); }, new InvalidateWith(typeof(RoleEntity)), AuthLogic.NotifyRulesChanged); sb.Schema.EntityEvents <RoleEntity>().Saving += Schema_Saving; UserGraph.Register(); EmailModelLogic.RegisterEmailModel <UserLockedMail>(() => new EmailTemplateEntity { Messages = CultureInfoLogic.ForEachCulture(culture => new EmailTemplateMessageEmbedded(culture) { Text = "<p>{0}</p>".FormatWith(AuthEmailMessage.YourAccountHasBeenLockedDueToSeveralFailedLogins.NiceToString()) + "<p>{0}</p>".FormatWith(AuthEmailMessage.YouCanResetYourPasswordByFollowingTheLinkBelow.NiceToString()) + "<p><a href=\"@[m:Url]\">@[m:Url]</a></p>", Subject = AuthEmailMessage.YourAccountHasBeenLocked.NiceToString() }).ToMList() }); } }
public static void Start(string connectionString) { using (HeavyProfiler.Log("Start")) using (var initial = HeavyProfiler.Log("Initial")) { StartParameters.IgnoredDatabaseMismatches = new List <Exception>(); StartParameters.IgnoredCodeErrors = new List <Exception>(); string?logDatabase = Connector.TryExtractDatabaseNameWithPostfix(ref connectionString, "_Log"); SchemaBuilder sb = new CustomSchemaBuilder { LogDatabaseName = logDatabase, Tracer = initial }; sb.Schema.Version = typeof(Starter).Assembly.GetName().Version; sb.Schema.ForceCultureInfo = CultureInfo.GetCultureInfo("en-US"); MixinDeclarations.Register <OperationLogEntity, DiffLogMixin>(); MixinDeclarations.Register <UserEntity, UserEmployeeMixin>(); OverrideAttributes(sb); var detector = SqlServerVersionDetector.Detect(connectionString); Connector.Default = new SqlConnector(connectionString, sb.Schema, detector !.Value); CacheLogic.Start(sb); DynamicLogicStarter.Start(sb); DynamicLogic.CompileDynamicCode(); DynamicLogic.RegisterMixins(); DynamicLogic.BeforeSchema(sb); TypeLogic.Start(sb); OperationLogic.Start(sb); ExceptionLogic.Start(sb); MigrationLogic.Start(sb); CultureInfoLogic.Start(sb); FilePathEmbeddedLogic.Start(sb); SmtpConfigurationLogic.Start(sb); EmailLogic.Start(sb, () => Configuration.Value.Email, (et, target) => Configuration.Value.SmtpConfiguration); AuthLogic.Start(sb, "System", null); AuthLogic.StartAllModules(sb); ResetPasswordRequestLogic.Start(sb); UserTicketLogic.Start(sb); SessionLogLogic.Start(sb); ProcessLogic.Start(sb); PackageLogic.Start(sb, packages: true, packageOperations: true); SchedulerLogic.Start(sb); QueryLogic.Start(sb); UserQueryLogic.Start(sb); UserQueryLogic.RegisterUserTypeCondition(sb, SouthwindGroup.UserEntities); UserQueryLogic.RegisterRoleTypeCondition(sb, SouthwindGroup.RoleEntities); ChartLogic.Start(sb); UserChartLogic.RegisterUserTypeCondition(sb, SouthwindGroup.UserEntities); UserChartLogic.RegisterRoleTypeCondition(sb, SouthwindGroup.RoleEntities); DashboardLogic.Start(sb); DashboardLogic.RegisterUserTypeCondition(sb, SouthwindGroup.UserEntities); DashboardLogic.RegisterRoleTypeCondition(sb, SouthwindGroup.RoleEntities); ViewLogLogic.Start(sb, new HashSet <Type> { typeof(UserQueryEntity), typeof(UserChartEntity), typeof(DashboardEntity) }); DiffLogLogic.Start(sb, registerAll: true); ExcelLogic.Start(sb, excelReport: true); ToolbarLogic.Start(sb); SMSLogic.Start(sb, null, () => Configuration.Value.Sms); SMSLogic.RegisterPhoneNumberProvider <PersonEntity>(p => p.Phone, p => null); SMSLogic.RegisterDataObjectProvider((PersonEntity p) => new { p.FirstName, p.LastName, p.Title, p.DateOfBirth }); SMSLogic.RegisterPhoneNumberProvider <CompanyEntity>(p => p.Phone, p => null); NoteLogic.Start(sb, typeof(UserEntity), /*Note*/ typeof(OrderEntity)); AlertLogic.Start(sb, typeof(UserEntity), /*Alert*/ typeof(OrderEntity)); FileLogic.Start(sb); TranslationLogic.Start(sb, countLocalizationHits: false); TranslatedInstanceLogic.Start(sb, () => CultureInfo.GetCultureInfo("en")); HelpLogic.Start(sb); WordTemplateLogic.Start(sb); MapLogic.Start(sb); PredictorLogic.Start(sb, () => new FileTypeAlgorithm(f => new PrefixPair(Starter.Configuration.Value.Folders.PredictorModelFolder))); PredictorLogic.RegisterAlgorithm(CNTKPredictorAlgorithm.NeuralNetwork, new CNTKNeuralNetworkPredictorAlgorithm()); PredictorLogic.RegisterPublication(ProductPredictorPublication.MonthlySales, new PublicationSettings(typeof(OrderEntity))); RestLogLogic.Start(sb); RestApiKeyLogic.Start(sb); WorkflowLogicStarter.Start(sb, () => Starter.Configuration.Value.Workflow); EmployeeLogic.Start(sb); ProductLogic.Start(sb); CustomerLogic.Start(sb); OrderLogic.Start(sb); ShipperLogic.Start(sb); StartSouthwindConfiguration(sb); TypeConditionLogic.Register <OrderEntity>(SouthwindGroup.UserEntities, o => o.Employee == EmployeeEntity.Current); TypeConditionLogic.Register <EmployeeEntity>(SouthwindGroup.UserEntities, e => EmployeeEntity.Current.Is(e)); TypeConditionLogic.Register <OrderEntity>(SouthwindGroup.CurrentCustomer, o => o.Customer == CustomerEntity.Current); TypeConditionLogic.Register <PersonEntity>(SouthwindGroup.CurrentCustomer, o => o == CustomerEntity.Current); TypeConditionLogic.Register <CompanyEntity>(SouthwindGroup.CurrentCustomer, o => o == CustomerEntity.Current); ProfilerLogic.Start(sb, timeTracker: true, heavyProfiler: true, overrideSessionTimeout: true); DynamicLogic.StartDynamicModules(sb); DynamicLogic.RegisterExceptionIfAny(); SetupCache(sb); Schema.Current.OnSchemaCompleted(); } }
public static List <CultureInfo> CurrentCultureInfos(CultureInfo defaultCulture) { var cultures = CultureInfoLogic.ApplicationCultures(isNeutral: null); return(cultures.OrderByDescending(a => a.Name == defaultCulture.Name).ThenBy(a => a.Name).ToList()); }
public static void Start(string connectionString, bool isPostgres, bool includeDynamic = true, bool detectSqlVersion = true) { using (HeavyProfiler.Log("Start")) using (var initial = HeavyProfiler.Log("Initial")) { StartParameters.IgnoredDatabaseMismatches = new List <Exception>(); StartParameters.IgnoredCodeErrors = new List <Exception>(); string?logDatabase = Connector.TryExtractDatabaseNameWithPostfix(ref connectionString, "_Log"); SchemaBuilder sb = new CustomSchemaBuilder { LogDatabaseName = logDatabase, Tracer = initial }; sb.Schema.Version = typeof(Starter).Assembly.GetName().Version !; sb.Schema.ForceCultureInfo = CultureInfo.GetCultureInfo("en-US"); MixinDeclarations.Register <OperationLogEntity, DiffLogMixin>(); MixinDeclarations.Register <UserEntity, UserEmployeeMixin>(); MixinDeclarations.Register <OrderDetailEmbedded, OrderDetailMixin>(); MixinDeclarations.Register <BigStringEmbedded, BigStringMixin>(); ConfigureBigString(sb); OverrideAttributes(sb); if (!isPostgres) { var sqlVersion = detectSqlVersion ? SqlServerVersionDetector.Detect(connectionString) : SqlServerVersion.AzureSQL; Connector.Default = new SqlServerConnector(connectionString, sb.Schema, sqlVersion !.Value); } else { var postgreeVersion = detectSqlVersion ? PostgresVersionDetector.Detect(connectionString) : null; Connector.Default = new PostgreSqlConnector(connectionString, sb.Schema, postgreeVersion); } CacheLogic.Start(sb, cacheInvalidator: sb.Settings.IsPostgres ? new PostgresCacheInvalidation() : null); DynamicLogicStarter.Start(sb); if (includeDynamic)//Dynamic { DynamicLogic.CompileDynamicCode(); DynamicLogic.RegisterMixins(); DynamicLogic.BeforeSchema(sb); }//Dynamic // Framework modules TypeLogic.Start(sb); OperationLogic.Start(sb); ExceptionLogic.Start(sb); QueryLogic.Start(sb); // Extensions modules MigrationLogic.Start(sb); CultureInfoLogic.Start(sb); FilePathEmbeddedLogic.Start(sb); BigStringLogic.Start(sb); EmailLogic.Start(sb, () => Configuration.Value.Email, (template, target, message) => Configuration.Value.EmailSender); AuthLogic.Start(sb, "System", "Anonymous"); /* null); anonymous*/ AuthLogic.StartAllModules(sb); ResetPasswordRequestLogic.Start(sb); UserTicketLogic.Start(sb); SessionLogLogic.Start(sb); WebAuthnLogic.Start(sb, () => Configuration.Value.WebAuthn); ProcessLogic.Start(sb); PackageLogic.Start(sb, packages: true, packageOperations: true); SchedulerLogic.Start(sb); OmniboxLogic.Start(sb); UserQueryLogic.Start(sb); UserQueryLogic.RegisterUserTypeCondition(sb, RG2Group.UserEntities); UserQueryLogic.RegisterRoleTypeCondition(sb, RG2Group.RoleEntities); UserQueryLogic.RegisterTranslatableRoutes(); ChartLogic.Start(sb, googleMapsChartScripts: false /*requires Google Maps API key in ChartClient */); UserChartLogic.RegisterUserTypeCondition(sb, RG2Group.UserEntities); UserChartLogic.RegisterRoleTypeCondition(sb, RG2Group.RoleEntities); UserChartLogic.RegisterTranslatableRoutes(); DashboardLogic.Start(sb); DashboardLogic.RegisterUserTypeCondition(sb, RG2Group.UserEntities); DashboardLogic.RegisterRoleTypeCondition(sb, RG2Group.RoleEntities); DashboardLogic.RegisterTranslatableRoutes(); ViewLogLogic.Start(sb, new HashSet <Type> { typeof(UserQueryEntity), typeof(UserChartEntity), typeof(DashboardEntity) }); DiffLogLogic.Start(sb, registerAll: true); ExcelLogic.Start(sb, excelReport: true); ToolbarLogic.Start(sb); ToolbarLogic.RegisterTranslatableRoutes(); FileLogic.Start(sb); TranslationLogic.Start(sb, countLocalizationHits: false); TranslatedInstanceLogic.Start(sb, () => CultureInfo.GetCultureInfo("en")); HelpLogic.Start(sb); WordTemplateLogic.Start(sb); MapLogic.Start(sb); RestLogLogic.Start(sb); RestApiKeyLogic.Start(sb); WorkflowLogicStarter.Start(sb, () => Starter.Configuration.Value.Workflow); ProfilerLogic.Start(sb, timeTracker: true, heavyProfiler: true, overrideSessionTimeout: true); // RG2 modules EmployeeLogic.Start(sb); ProductLogic.Start(sb); CustomerLogic.Start(sb); OrderLogic.Start(sb); ShipperLogic.Start(sb); ItemLogic.Start(sb); ItemCategoryLogic.Start(sb); StartRG2Configuration(sb); TypeConditionLogic.Register <OrderEntity>(RG2Group.UserEntities, o => o.Employee == EmployeeEntity.Current); TypeConditionLogic.Register <EmployeeEntity>(RG2Group.UserEntities, e => EmployeeEntity.Current.Is(e)); TypeConditionLogic.Register <OrderEntity>(RG2Group.CurrentCustomer, o => o.Customer == CustomerEntity.Current); TypeConditionLogic.Register <PersonEntity>(RG2Group.CurrentCustomer, o => o == CustomerEntity.Current); TypeConditionLogic.Register <CompanyEntity>(RG2Group.CurrentCustomer, o => o == CustomerEntity.Current); if (includeDynamic)//2 { DynamicLogic.StartDynamicModules(sb); }//2 SetupCache(sb); Schema.Current.OnSchemaCompleted(); if (includeDynamic)//3 { DynamicLogic.RegisterExceptionIfAny(); }//3 } }
public static void Start(string connectionString) { string logDatabase = Connector.TryExtractDatabaseNameWithPostfix(ref connectionString, "_Log"); SchemaBuilder sb = new SchemaBuilder(); sb.Schema.Version = typeof(Starter).Assembly.GetName().Version; sb.Schema.ForceCultureInfo = CultureInfo.GetCultureInfo("en-US"); MixinDeclarations.Register <OperationLogEntity, DiffLogMixin>(); MixinDeclarations.Register <UserEntity, UserEmployeeMixin>(); OverrideAttributes(sb); SetupDisconnectedStrategies(sb); DynamicQueryManager dqm = new DynamicQueryManager(); Connector.Default = new SqlConnector(connectionString, sb.Schema, dqm, SqlServerVersion.SqlServer2012); CacheLogic.Start(sb); TypeLogic.Start(sb, dqm); OperationLogic.Start(sb, dqm); MigrationLogic.Start(sb, dqm); CultureInfoLogic.Start(sb, dqm); EmbeddedFilePathLogic.Start(sb, dqm); SmtpConfigurationLogic.Start(sb, dqm); EmailLogic.Start(sb, dqm, () => Configuration.Value.Email, et => Configuration.Value.SmtpConfiguration); AuthLogic.Start(sb, dqm, "System", null); AuthLogic.StartAllModules(sb, dqm); ResetPasswordRequestLogic.Start(sb, dqm); UserTicketLogic.Start(sb, dqm); SessionLogLogic.Start(sb, dqm); ProcessLogic.Start(sb, dqm); PackageLogic.Start(sb, dqm, packages: true, packageOperations: true); MapLogic.Start(sb, dqm); SchedulerLogic.Start(sb, dqm); QueryLogic.Start(sb); UserQueryLogic.Start(sb, dqm); UserQueryLogic.RegisterUserTypeCondition(sb, SouthwindGroup.UserEntities); UserQueryLogic.RegisterRoleTypeCondition(sb, SouthwindGroup.RoleEntities); ChartLogic.Start(sb, dqm); UserChartLogic.RegisterUserTypeCondition(sb, SouthwindGroup.UserEntities); UserChartLogic.RegisterRoleTypeCondition(sb, SouthwindGroup.RoleEntities); DashboardLogic.Start(sb, dqm); DashboardLogic.RegisterUserTypeCondition(sb, SouthwindGroup.UserEntities); DashboardLogic.RegisterRoleTypeCondition(sb, SouthwindGroup.RoleEntities); ViewLogLogic.Start(sb, dqm, new HashSet <Type> { typeof(UserQueryEntity), typeof(UserChartEntity), typeof(DashboardEntity) }); DiffLogLogic.Start(sb, dqm); ExceptionLogic.Start(sb, dqm); SMSLogic.Start(sb, dqm, null, () => Configuration.Value.Sms); SMSLogic.RegisterPhoneNumberProvider <PersonEntity>(p => p.Phone, p => null); SMSLogic.RegisterDataObjectProvider((PersonEntity p) => new { p.FirstName, p.LastName, p.Title, p.DateOfBirth }); SMSLogic.RegisterPhoneNumberProvider <CompanyEntity>(p => p.Phone, p => null); NoteLogic.Start(sb, dqm, typeof(UserEntity), /*Note*/ typeof(OrderEntity)); AlertLogic.Start(sb, dqm, typeof(UserEntity), /*Alert*/ typeof(OrderEntity)); FileLogic.Start(sb, dqm); TranslationLogic.Start(sb, dqm); TranslatedInstanceLogic.Start(sb, dqm, () => CultureInfo.GetCultureInfo("en")); HelpLogic.Start(sb, dqm); WordTemplateLogic.Start(sb, dqm); EmployeeLogic.Start(sb, dqm); ProductLogic.Start(sb, dqm); CustomerLogic.Start(sb, dqm); OrderLogic.Start(sb, dqm); ShipperLogic.Start(sb, dqm); StartSouthwindConfiguration(sb, dqm); TypeConditionLogic.Register <OrderEntity>(SouthwindGroup.UserEntities, o => o.Employee.RefersTo(EmployeeEntity.Current)); TypeConditionLogic.Register <EmployeeEntity>(SouthwindGroup.UserEntities, e => e == EmployeeEntity.Current); TypeConditionLogic.Register <OrderEntity>(SouthwindGroup.CurrentCustomer, o => o.Customer == CustomerEntity.Current); TypeConditionLogic.Register <PersonEntity>(SouthwindGroup.CurrentCustomer, o => o == CustomerEntity.Current); TypeConditionLogic.Register <CompanyEntity>(SouthwindGroup.CurrentCustomer, o => o == CustomerEntity.Current); DisconnectedLogic.Start(sb, dqm); DisconnectedLogic.BackupFolder = @"D:\SouthwindTemp\Backups"; DisconnectedLogic.BackupNetworkFolder = @"D:\SouthwindTemp\Backups"; DisconnectedLogic.DatabaseFolder = @"D:\SouthwindTemp\Database"; ProfilerLogic.Start(sb, dqm, timeTracker: true, heavyProfiler: true, overrideSessionTimeout: true); SetupCache(sb); SetSchemaNames(Schema.Current); if (logDatabase.HasText()) { SetLogDatabase(sb.Schema, new DatabaseName(null, logDatabase)); } Schema.Current.OnSchemaCompleted(); }
public static void Start(string connectionString, bool isPostgres, string?azureStorageConnectionString, string?broadcastSecret, string?broadcastUrls, bool includeDynamic = true, bool detectSqlVersion = true) { AzureStorageConnectionString = azureStorageConnectionString; using (HeavyProfiler.Log("Start")) using (var initial = HeavyProfiler.Log("Initial")) { StartParameters.IgnoredDatabaseMismatches = new List <Exception>(); StartParameters.IgnoredCodeErrors = new List <Exception>(); string?logDatabase = Connector.TryExtractDatabaseNameWithPostfix(ref connectionString, "_Log"); SchemaBuilder sb = new CustomSchemaBuilder { LogDatabaseName = logDatabase, Tracer = initial }; sb.Schema.Version = typeof(Starter).Assembly.GetName().Version !; sb.Schema.ForceCultureInfo = CultureInfo.GetCultureInfo("en-US"); MixinDeclarations.Register <OperationLogEntity, DiffLogMixin>(); MixinDeclarations.Register <UserEntity, UserEmployeeMixin>(); MixinDeclarations.Register <OrderDetailEmbedded, OrderDetailMixin>(); MixinDeclarations.Register <BigStringEmbedded, BigStringMixin>(); ConfigureBigString(sb); OverrideAttributes(sb); if (!isPostgres) { var sqlVersion = detectSqlVersion ? SqlServerVersionDetector.Detect(connectionString) : SqlServerVersion.AzureSQL; Connector.Default = new SqlServerConnector(connectionString, sb.Schema, sqlVersion !.Value); } else { var postgreeVersion = detectSqlVersion ? PostgresVersionDetector.Detect(connectionString) : null; Connector.Default = new PostgreSqlConnector(connectionString, sb.Schema, postgreeVersion); } CacheLogic.Start(sb, serverBroadcast: sb.Settings.IsPostgres ? new PostgresBroadcast() : broadcastSecret != null && broadcastUrls != null ? new SimpleHttpBroadcast(broadcastSecret, broadcastUrls) : null);/*Cache*/ /* LightDynamic * DynamicLogic.Start(sb, withCodeGen: false); * LightDynamic */ DynamicLogicStarter.Start(sb); if (includeDynamic)//Dynamic { DynamicLogic.CompileDynamicCode(); DynamicLogic.RegisterMixins(); DynamicLogic.BeforeSchema(sb); }//Dynamic // Framework modules TypeLogic.Start(sb); OperationLogic.Start(sb); ExceptionLogic.Start(sb); QueryLogic.Start(sb); // Extensions modules MigrationLogic.Start(sb); CultureInfoLogic.Start(sb); FilePathEmbeddedLogic.Start(sb); BigStringLogic.Start(sb); EmailLogic.Start(sb, () => Configuration.Value.Email, (template, target, message) => Configuration.Value.EmailSender); AuthLogic.Start(sb, "System", "Anonymous"); /* null); anonymous*/ AuthLogic.Authorizer = new SouthwindAuthorizer(() => Configuration.Value.ActiveDirectory); AuthLogic.StartAllModules(sb, activeDirectoryIntegration: true); AzureADLogic.Start(sb, adGroups: true, deactivateUsersTask: true); ResetPasswordRequestLogic.Start(sb); UserTicketLogic.Start(sb); SessionLogLogic.Start(sb); TypeConditionLogic.RegisterCompile <UserEntity>(SouthwindTypeCondition.UserEntities, u => u.Is(UserEntity.Current)); ProcessLogic.Start(sb); PackageLogic.Start(sb, packages: true, packageOperations: true); SchedulerLogic.Start(sb); OmniboxLogic.Start(sb); UserQueryLogic.Start(sb); UserQueryLogic.RegisterUserTypeCondition(sb, SouthwindTypeCondition.UserEntities); UserQueryLogic.RegisterRoleTypeCondition(sb, SouthwindTypeCondition.RoleEntities); UserQueryLogic.RegisterTranslatableRoutes(); ChartLogic.Start(sb, googleMapsChartScripts: false /*requires Google Maps API key in ChartClient */); UserChartLogic.RegisterUserTypeCondition(sb, SouthwindTypeCondition.UserEntities); UserChartLogic.RegisterRoleTypeCondition(sb, SouthwindTypeCondition.RoleEntities); UserChartLogic.RegisterTranslatableRoutes(); DashboardLogic.Start(sb, GetFileTypeAlgorithm(p => p.CachedQueryFolder)); DashboardLogic.RegisterUserTypeCondition(sb, SouthwindTypeCondition.UserEntities); DashboardLogic.RegisterRoleTypeCondition(sb, SouthwindTypeCondition.RoleEntities); DashboardLogic.RegisterTranslatableRoutes(); ViewLogLogic.Start(sb, new HashSet <Type> { typeof(UserQueryEntity), typeof(UserChartEntity), typeof(DashboardEntity) }); SystemEventLogLogic.Start(sb); DiffLogLogic.Start(sb, registerAll: true); ExcelLogic.Start(sb, excelReport: true); ToolbarLogic.Start(sb); ToolbarLogic.RegisterTranslatableRoutes(); SMSLogic.Start(sb, null, () => Configuration.Value.Sms); NoteLogic.Start(sb, typeof(UserEntity), /*Note*/ typeof(OrderEntity)); AlertLogic.Start(sb, typeof(UserEntity), /*Alert*/ typeof(OrderEntity)); FileLogic.Start(sb); TranslationLogic.Start(sb, countLocalizationHits: false); TranslatedInstanceLogic.Start(sb, () => CultureInfo.GetCultureInfo("en")); HelpLogic.Start(sb); WordTemplateLogic.Start(sb); MapLogic.Start(sb); PredictorLogic.Start(sb, GetFileTypeAlgorithm(p => p.PredictorModelFolder)); PredictorLogic.RegisterAlgorithm(TensorFlowPredictorAlgorithm.NeuralNetworkGraph, new TensorFlowNeuralNetworkPredictor()); PredictorLogic.RegisterPublication(ProductPredictorPublication.MonthlySales, new PublicationSettings(typeof(OrderEntity))); RestLogLogic.Start(sb); RestApiKeyLogic.Start(sb); WorkflowLogicStarter.Start(sb, () => Starter.Configuration.Value.Workflow); ProfilerLogic.Start(sb, timeTracker: true, heavyProfiler: true, overrideSessionTimeout: true); // Southwind modules EmployeeLogic.Start(sb); ProductLogic.Start(sb); CustomerLogic.Start(sb); OrderLogic.Start(sb); ShipperLogic.Start(sb); StartSouthwindConfiguration(sb); TypeConditionLogic.Register <OrderEntity>(SouthwindTypeCondition.CurrentEmployee, o => o.Employee.Is(EmployeeEntity.Current)); if (includeDynamic)//2 { DynamicLogic.StartDynamicModules(sb); }//2 SetupCache(sb); Schema.Current.OnSchemaCompleted(); if (includeDynamic)//3 { DynamicLogic.RegisterExceptionIfAny(); }//3 } }
public static void Start(SchemaBuilder sb, Func <EmailTemplateEntity, Lite <Entity>?, SmtpConfigurationEntity?>?getSmtpConfiguration) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { CultureInfoLogic.AssertStarted(sb); TemplatingLogic.Start(sb); GetSmtpConfiguration = getSmtpConfiguration; sb.Include <EmailTemplateEntity>() .WithQuery(() => t => new { Entity = t, t.Id, t.Name, t.IsBodyHtml }); EmailTemplatesLazy = sb.GlobalLazy(() => Database.Query <EmailTemplateEntity>().ToDictionary(et => et.ToLite()) , new InvalidateWith(typeof(EmailTemplateEntity))); TemplatesByQueryName = sb.GlobalLazy(() => { return(EmailTemplatesLazy.Value.Values.SelectCatch(et => KVP.Create(et.Query.ToQueryName(), et)).GroupToDictionary()); }, new InvalidateWith(typeof(EmailTemplateEntity))); EmailModelLogic.Start(sb); EmailMasterTemplateLogic.Start(sb); sb.Schema.EntityEvents <EmailTemplateEntity>().PreSaving += new PreSavingEventHandler <EmailTemplateEntity>(EmailTemplate_PreSaving); sb.Schema.EntityEvents <EmailTemplateEntity>().Retrieved += EmailTemplateLogic_Retrieved; sb.Schema.Table <EmailModelEntity>().PreDeleteSqlSync += e => Administrator.UnsafeDeletePreCommand(Database.Query <EmailTemplateEntity>() .Where(a => a.Model.Is(e))); Validator.OverridePropertyValidator((EmailTemplateMessageEmbedded m) => m.Text).StaticPropertyValidation += EmailTemplateMessageText_StaticPropertyValidation; Validator.OverridePropertyValidator((EmailTemplateMessageEmbedded m) => m.Subject).StaticPropertyValidation += EmailTemplateMessageSubject_StaticPropertyValidation; EmailTemplateGraph.Register(); GlobalValueProvider.RegisterGlobalVariable("UrlLeft", _ => EmailLogic.Configuration.UrlLeft); GlobalValueProvider.RegisterGlobalVariable("Now", _ => TimeZoneManager.Now); GlobalValueProvider.RegisterGlobalVariable("Today", _ => TimeZoneManager.Now.Date, "d"); sb.Schema.Synchronizing += Schema_Synchronizing_Tokens; sb.Schema.Synchronizing += Schema_Synchronizing_DefaultTemplates; sb.Schema.Table <EmailModelEntity>().PreDeleteSqlSync += EmailTemplateLogic_PreDeleteSqlSync; Validator.PropertyValidator <EmailTemplateEntity>(et => et.Messages).StaticPropertyValidation += (et, pi) => { if (!et.Messages.Any(m => m.CultureInfo.Is(EmailLogic.Configuration.DefaultCulture))) { return(EmailTemplateMessage.ThereMustBeAMessageFor0.NiceToString().FormatWith(EmailLogic.Configuration.DefaultCulture.EnglishName)); } return(null); }; } }
public CultureInfoEntity GetCultureInfoEntity(string cultureName) { return(CultureInfoLogic.GetCultureInfoEntity(cultureName)); }
public static void RegisterAlertNotificationMail(SchemaBuilder sb) { EmailModelLogic.RegisterEmailModel <AlertNotificationMail>(() => new EmailTemplateEntity { Messages = CultureInfoLogic.ForEachCulture(culture => new EmailTemplateMessageEmbedded(culture) { Text = @" <p>Hi @[m:Entity],</p> <p>You have some pending alerts:</p> <ul> @foreach[m:Alerts] as $a <li> <strong>@[$a.AlertType]:</strong><br/> @[m:TextFormatted]<br/> <small>@[$a.AlertDate] @[$a.CreatedBy]</small> </li> @endforeach </ul> <p>Please visit <a href=""@[g:UrlLeft]"">@[g:UrlLeft]</a></p>", Subject = AlertMessage.NewUnreadNotifications.NiceToString(), }).ToMList() }); sb.Include <SendNotificationEmailTaskEntity>() .WithSave(SendNotificationEmailTaskOperation.Save) .WithQuery(() => e => new { Entity = e, e.Id, e.SendNotificationsOlderThan, e.SendBehavior, }); SchedulerLogic.ExecuteTask.Register((SendNotificationEmailTaskEntity task, ScheduledTaskContext ctx) => { var limit = DateTime.Now.AddMinutes(-task.SendNotificationsOlderThan); var query = Database.Query <AlertEntity>() .Where(a => a.State == AlertState.Saved && a.EmailNotificationsSent == 0 && a.Recipient != null && a.CreationDate < limit) .Where(a => task.SendBehavior == SendAlertTypeBehavior.All || task.SendBehavior == SendAlertTypeBehavior.Include && task.AlertTypes.Contains(a.AlertType !) || task.SendBehavior == SendAlertTypeBehavior.Exclude && !task.AlertTypes.Contains(a.AlertType !)); if (!query.Any()) { return(null); } var alerts = query .Select(a => new { Alert = a, Recipient = a.Recipient !.Entity }) .ToList(); EmailPackageEntity emailPackage = new EmailPackageEntity().Save(); var emails = alerts.GroupBy(a => a.Recipient, a => a.Alert).SelectMany(gr => new AlertNotificationMail((UserEntity)gr.Key, gr.ToList()).CreateEmailMessage()).ToList(); emails.ForEach(a => { a.State = EmailMessageState.ReadyToSend; a.Package = emailPackage.ToLite(); }); emails.BulkInsertQueryIds(a => a.Target !); query.UnsafeUpdate().Set(a => a.EmailNotificationsSent, a => 1).Execute(); return(emailPackage.ToLite()); });
public static void Start(SchemaBuilder sb, ISMSProvider?provider, Func <SMSConfigurationEmbedded> getConfiguration) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { CultureInfoLogic.AssertStarted(sb); sb.Schema.SchemaCompleted += () => Schema_SchemaCompleted(sb); SMSLogic.getConfiguration = getConfiguration; SMSLogic.Provider = provider; sb.Include <SMSMessageEntity>() .WithQuery(() => m => new { Entity = m, m.Id, m.From, m.DestinationNumber, m.State, m.SendDate, m.Template, m.Referred, m.Exception, }); sb.Include <SMSTemplateEntity>() .WithQuery(() => t => new { Entity = t, t.Id, t.Name, t.IsActive, t.From, t.Query, t.Model, }); sb.Schema.EntityEvents <SMSTemplateEntity>().PreSaving += new PreSavingEventHandler <SMSTemplateEntity>(EmailTemplate_PreSaving); sb.Schema.EntityEvents <SMSTemplateEntity>().Retrieved += SMSTemplateLogic_Retrieved; sb.Schema.Table <SMSModelEntity>().PreDeleteSqlSync += e => Administrator.UnsafeDeletePreCommand(Database.Query <SMSTemplateEntity>() .Where(a => a.Model.Is(e))); SMSTemplatesLazy = sb.GlobalLazy(() => Database.Query <SMSTemplateEntity>().ToDictionary(et => et.ToLite()) , new InvalidateWith(typeof(SMSTemplateEntity))); SMSTemplatesByQueryName = sb.GlobalLazy(() => { return(SMSTemplatesLazy.Value.Values.Where(q => q.Query != null).SelectCatch(et => KeyValuePair.Create(et.Query !.ToQueryName(), et)).GroupToDictionary()); }, new InvalidateWith(typeof(SMSTemplateEntity))); SMSMessageGraph.Register(); SMSTemplateGraph.Register(); Validator.PropertyValidator <SMSTemplateEntity>(et => et.Messages).StaticPropertyValidation += (t, pi) => { var dc = SMSLogic.Configuration?.DefaultCulture; if (dc != null && !t.Messages.Any(m => m.CultureInfo.Is(dc))) { return(SMSTemplateMessage.ThereMustBeAMessageFor0.NiceToString().FormatWith(dc.EnglishName)); } return(null); }; sb.AddUniqueIndex((SMSTemplateEntity t) => new { t.Model }, where : t => t.Model != null && t.IsActive == true); ExceptionLogic.DeleteLogs += ExceptionLogic_DeleteLogs; ExceptionLogic.DeleteLogs += ExceptionLogic_DeletePackages; } }
public static void Start(string connectionString, bool includeDynamic = true) { using (HeavyProfiler.Log("Start")) using (var initial = HeavyProfiler.Log("Initial")) { string? logDatabase = Connector.TryExtractDatabaseNameWithPostfix(ref connectionString, "_Log"); SchemaBuilder sb = new CustomSchemaBuilder { LogDatabaseName = logDatabase, Tracer = initial }; sb.Schema.Version = typeof(Starter).Assembly.GetName().Version!; sb.Schema.ForceCultureInfo = CultureInfo.GetCultureInfo("en-US"); MixinDeclarations.Register<OperationLogEntity, DiffLogMixin>(); MixinDeclarations.Register<UserEntity, UserEmployeeMixin>(); OverrideAttributes(sb); var detector = SqlServerVersionDetector.Detect(connectionString); Connector.Default = new SqlConnector(connectionString, sb.Schema, detector!.Value); CacheLogic.Start(sb); } TypeLogic.Start(sb); OperationLogic.Start(sb); ExceptionLogic.Start(sb); MigrationLogic.Start(sb); CultureInfoLogic.Start(sb); FilePathEmbeddedLogic.Start(sb); EmailLogic.Start(sb, () => Configuration.Value.Email, (et, target) => Configuration.Value.EmailSender); AuthLogic.Start(sb, "System", null); AuthLogic.StartAllModules(sb); ResetPasswordRequestLogic.Start(sb); UserTicketLogic.Start(sb); ProcessLogic.Start(sb); PackageLogic.Start(sb, packages: true, packageOperations: true); SchedulerLogic.Start(sb); QueryLogic.Start(sb); UserQueryLogic.Start(sb); UserQueryLogic.RegisterUserTypeCondition(sb, AtTestGroup.UserEntities); UserQueryLogic.RegisterRoleTypeCondition(sb, AtTestGroup.RoleEntities); ChartLogic.Start(sb); UserChartLogic.RegisterUserTypeCondition(sb, AtTestGroup.UserEntities); UserChartLogic.RegisterRoleTypeCondition(sb, AtTestGroup.RoleEntities); DashboardLogic.Start(sb); DashboardLogic.RegisterUserTypeCondition(sb, AtTestGroup.UserEntities); DashboardLogic.RegisterRoleTypeCondition(sb, AtTestGroup.RoleEntities); ViewLogLogic.Start(sb, new HashSet<Type> { typeof(UserQueryEntity), typeof(UserChartEntity), typeof(DashboardEntity) }); DiffLogLogic.Start(sb, registerAll: true); ExcelLogic.Start(sb, excelReport: true); ToolbarLogic.Start(sb); FileLogic.Start(sb); TranslationLogic.Start(sb, countLocalizationHits: false); TranslatedInstanceLogic.Start(sb, () => CultureInfo.GetCultureInfo("en")); WordTemplateLogic.Start(sb); MapLogic.Start(sb); PredictorLogic.Start(sb, () => new FileTypeAlgorithm(f => new PrefixPair(Starter.Configuration.Value.Folders.PredictorModelFolder))); PredictorLogic.RegisterAlgorithm(CNTKPredictorAlgorithm.NeuralNetwork, new CNTKNeuralNetworkPredictorAlgorithm()); PredictorLogic.RegisterPublication(ProductPredictorPublication.MonthlySales, new PublicationSettings(typeof(OrderEntity))); EmployeeLogic.Start(sb); ProductLogic.Start(sb); CustomerLogic.Start(sb); OrderLogic.Start(sb); ShipperLogic.Start(sb); StartAtTestConfiguration(sb); TypeConditionLogic.Register<OrderEntity>(AtTestGroup.UserEntities, o => o.Employee == EmployeeEntity.Current); TypeConditionLogic.Register<EmployeeEntity>(AtTestGroup.UserEntities, e => EmployeeEntity.Current.Is(e)); TypeConditionLogic.Register<OrderEntity>(AtTestGroup.CurrentCustomer, o => o.Customer == CustomerEntity.Current); TypeConditionLogic.Register<PersonEntity>(AtTestGroup.CurrentCustomer, o => o == CustomerEntity.Current); TypeConditionLogic.Register<CompanyEntity>(AtTestGroup.CurrentCustomer, o => o == CustomerEntity.Current); ProfilerLogic.Start(sb, timeTracker: true, heavyProfiler: true, overrideSessionTimeout: true); if (includeDynamic) { } SetupCache(sb); Schema.Current.OnSchemaCompleted(); }