From 03b21d29b48d5ea9672dbe1b0d0632a75df485e6 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Thu, 27 Sep 2018 17:15:42 +0000 Subject: [PATCH] --- devdocs/todo.txt | 9 +++ .../Controllers/AttachmentController.cs | 6 +- .../AyaNova/Controllers/LicenseController.cs | 4 +- .../AyaNova/Controllers/LocaleController.cs | 6 +- .../AyaNova/Controllers/MetricsController.cs | 4 +- .../Controllers/ServerStateController.cs | 2 +- server/AyaNova/Controllers/TagController.cs | 8 +-- .../AyaNova/Controllers/TagGroupController.cs | 6 +- server/AyaNova/Controllers/TrialController.cs | 2 +- .../Controllers/UserOptionsController.cs | 4 +- server/AyaNova/biz/EventLogProcessor.cs | 2 +- server/AyaNova/biz/ImportAyaNova7Biz.cs | 4 +- server/AyaNova/biz/LocaleBiz.cs | 2 +- server/AyaNova/biz/UserBiz.cs | 48 +++++++++++-- server/AyaNova/biz/WidgetBiz.cs | 8 +-- server/AyaNova/util/AySchema.cs | 4 +- server/AyaNova/util/Seeder.cs | 67 ++++++++++++++----- 17 files changed, 135 insertions(+), 51 deletions(-) diff --git a/devdocs/todo.txt b/devdocs/todo.txt index f8a9de04..ca88fcff 100644 --- a/devdocs/todo.txt +++ b/devdocs/todo.txt @@ -38,6 +38,7 @@ IMMEDIATE ITEMS: - Is generating non-unique names causing crash due to validation error. Add uniqufication code, maybe just a serial number - PAINFULLY slow to generate widgets, the db ops are taking orders of magnitude too long, can any db steps be saved?? - Is it an issue if it keeps on working slowly in the background?? + - Took from 5pm to 642 am to do 1720 widgets of the 20000 called for and seemed very slow doing just one at that point - Maybe do it in chunks at a time so that it will properly interleave with other types of data so there is some of everything all at once and slowly adds more - BUG BUG: 2018-09-26 16:47:34.3677|INFO|Seeder|Seeding 100 user(s) 2018-09-26 16:47:34.4053|INFO|Seeder|Seeding 100 user(s) @@ -49,6 +50,14 @@ IMMEDIATE ITEMS: 2018-09-26 16:47:47.0864|INFO|Seeder|User seeding completed It's not awaiting the generation and instead is opening the server immediately and saying seeding completed when it isn't + + - LOG WARNING?? + - Why the warning about first/firstordefault?? + 2018-09-27 07:58:26.6301|WARN|AyaNova.Startup|License key not found in database, running in unlicensed mode + 2018-09-27 07:58:26.6442|INFO|AyaNova.Startup|DEBUG MODE TRIAL LICENSE KEY BEING FETCHED + 2018-09-27 07:58:27.1822|WARN|Microsoft.EntityFrameworkCore.Query|Query: '(from License _1 in DbSet select [_1]).FirstOrDefault()' uses First/FirstOrDefault/Last/LastOrDefault operation without OrderBy and filter which may lead to unpredictable results. + 2018-09-27 07:58:27.2694|INFO|Seeder|SEEDER: SeedDatabase, level is: LargeCorporateMultiRegionalTrialDataSet + - EventLogProcessor.AddEntry: CHANGE this to save the context itself and then change all callers to handle that (remove save) - I originally didn't have the save in there because I thought subsequent code might all share in the single context save, however that's impossible as things like the search indexing require a save to harvest id's so it's not actually saving any time just adding complexity diff --git a/server/AyaNova/Controllers/AttachmentController.cs b/server/AyaNova/Controllers/AttachmentController.cs index 1c6a1fb8..1a54f37c 100644 --- a/server/AyaNova/Controllers/AttachmentController.cs +++ b/server/AyaNova/Controllers/AttachmentController.cs @@ -239,7 +239,7 @@ namespace AyaNova.Api.Controllers }); //Log - EventLogProcessor.AddEntry(new Event(UserId, attachToObject.ObjectId, attachToObject.ObjectType, AyaEvent.AttachmentCreate, v.DisplayFileName), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(UserId, attachToObject.ObjectId, attachToObject.ObjectType, AyaEvent.AttachmentCreate, v.DisplayFileName), ct); ct.SaveChanges(); } } @@ -306,7 +306,7 @@ namespace AyaNova.Api.Controllers FileUtil.deleteFileAttachment(dbObj, ct); //Log - EventLogProcessor.AddEntry(new Event(UserId, dbObj.AttachToObjectId, dbObj.AttachToObjectType, AyaEvent.AttachmentDelete, dbObj.DisplayFileName), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(UserId, dbObj.AttachToObjectId, dbObj.AttachToObjectType, AyaEvent.AttachmentDelete, dbObj.DisplayFileName), ct); ct.SaveChanges(); return NoContent(); } @@ -385,7 +385,7 @@ namespace AyaNova.Api.Controllers } //Log - EventLogProcessor.AddEntry(new Event(UserId, dbObj.AttachToObjectId, dbObj.AttachToObjectType, AyaEvent.AttachmentDownload, dbObj.DisplayFileName), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(UserId, dbObj.AttachToObjectId, dbObj.AttachToObjectType, AyaEvent.AttachmentDownload, dbObj.DisplayFileName), ct); ct.SaveChanges(); return PhysicalFile(filePath, mimetype, dbObj.DisplayFileName); diff --git a/server/AyaNova/Controllers/LicenseController.cs b/server/AyaNova/Controllers/LicenseController.cs index 420d8736..d6b6cc15 100644 --- a/server/AyaNova/Controllers/LicenseController.cs +++ b/server/AyaNova/Controllers/LicenseController.cs @@ -127,7 +127,7 @@ namespace AyaNova.Api.Controllers } var ret = AyaNova.Core.License.LicenseInfoAsJson; //Log - EventLogProcessor.AddEntry(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.License, AyaEvent.LicenseFetch), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.License, AyaEvent.LicenseFetch), ct); ct.SaveChanges(); return Ok(new ApiOkResponse(ret)); @@ -180,7 +180,7 @@ namespace AyaNova.Api.Controllers var ret = Core.License.RequestTrial(requestData.EmailAddress, requestData.RegisteredTo, log); //Log - EventLogProcessor.AddEntry(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.License, AyaEvent.LicenseTrialRequest), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.License, AyaEvent.LicenseTrialRequest), ct); ct.SaveChanges(); return Ok(new ApiOkResponse(ret)); diff --git a/server/AyaNova/Controllers/LocaleController.cs b/server/AyaNova/Controllers/LocaleController.cs index a351b334..a66745ed 100644 --- a/server/AyaNova/Controllers/LocaleController.cs +++ b/server/AyaNova/Controllers/LocaleController.cs @@ -187,7 +187,7 @@ namespace AyaNova.Api.Controllers await ct.SaveChangesAsync(); //Log - EventLogProcessor.AddEntry(new Event(biz.userId, o.Id, AyaType.Locale, AyaEvent.Created), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(biz.userId, o.Id, AyaType.Locale, AyaEvent.Created), ct); await ct.SaveChangesAsync(); return CreatedAtAction("GetLocale", new { id = o.Id }, new ApiCreatedResponse(o)); @@ -247,7 +247,7 @@ namespace AyaNova.Api.Controllers } //Log - EventLogProcessor.AddEntry(new Event(biz.userId, oDbParent.Id, AyaType.Locale, AyaEvent.Modified), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(biz.userId, oDbParent.Id, AyaType.Locale, AyaEvent.Modified), ct); try { @@ -317,7 +317,7 @@ namespace AyaNova.Api.Controllers } //Log - EventLogProcessor.AddEntry(new Event(biz.userId, oFromDb.Id, AyaType.Locale, AyaEvent.Modified), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(biz.userId, oFromDb.Id, AyaType.Locale, AyaEvent.Modified), ct); try { diff --git a/server/AyaNova/Controllers/MetricsController.cs b/server/AyaNova/Controllers/MetricsController.cs index 01e9346a..6c1773fd 100644 --- a/server/AyaNova/Controllers/MetricsController.cs +++ b/server/AyaNova/Controllers/MetricsController.cs @@ -68,7 +68,7 @@ namespace AyaNova.Api.Controllers string sResult = await GetTheMetrics("plain"); //Log - EventLogProcessor.AddEntry(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.Metrics, AyaEvent.Retrieved), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.Metrics, AyaEvent.Retrieved), ct); await ct.SaveChangesAsync(); return Content(sResult); @@ -100,7 +100,7 @@ namespace AyaNova.Api.Controllers JObject json = JObject.Parse(sResult); //Log - EventLogProcessor.AddEntry(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.Metrics, AyaEvent.Retrieved), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.Metrics, AyaEvent.Retrieved), ct); await ct.SaveChangesAsync(); return Ok(new ApiOkResponse(json)); diff --git a/server/AyaNova/Controllers/ServerStateController.cs b/server/AyaNova/Controllers/ServerStateController.cs index 3cd7fee8..c93c0247 100644 --- a/server/AyaNova/Controllers/ServerStateController.cs +++ b/server/AyaNova/Controllers/ServerStateController.cs @@ -95,7 +95,7 @@ namespace AyaNova.Api.Controllers serverState.SetState(desiredState, state.Reason); //Log - EventLogProcessor.AddEntry(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.ServerState, AyaEvent.ServerStateChange, $"{state.ServerState}-{state.Reason}"), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.ServerState, AyaEvent.ServerStateChange, $"{state.ServerState}-{state.Reason}"), ct); ct.SaveChanges(); return NoContent(); diff --git a/server/AyaNova/Controllers/TagController.cs b/server/AyaNova/Controllers/TagController.cs index 09471903..bcadc93d 100644 --- a/server/AyaNova/Controllers/TagController.cs +++ b/server/AyaNova/Controllers/TagController.cs @@ -169,7 +169,7 @@ namespace AyaNova.Api.Controllers await ct.SaveChangesAsync(); //Log - EventLogProcessor.AddEntry(new Event(biz.userId, o.Id, AyaType.Tag, AyaEvent.Created), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(biz.userId, o.Id, AyaType.Tag, AyaEvent.Created), ct); await ct.SaveChangesAsync(); return CreatedAtAction("GetTag", new { id = o.Id }, new ApiCreatedResponse(o)); @@ -222,7 +222,7 @@ namespace AyaNova.Api.Controllers } //Log - EventLogProcessor.AddEntry(new Event(biz.userId, oFromDb.Id, AyaType.Tag, AyaEvent.Modified), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(biz.userId, oFromDb.Id, AyaType.Tag, AyaEvent.Modified), ct); try { @@ -294,7 +294,7 @@ namespace AyaNova.Api.Controllers } //Log - EventLogProcessor.AddEntry(new Event(biz.userId, oFromDb.Id, AyaType.Tag, AyaEvent.Modified), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(biz.userId, oFromDb.Id, AyaType.Tag, AyaEvent.Modified), ct); try { @@ -359,7 +359,7 @@ namespace AyaNova.Api.Controllers } //Log - EventLogProcessor.AddEntry(new Event(UserId, id, AyaType.Tag, AyaEvent.TagMassUntag), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(UserId, id, AyaType.Tag, AyaEvent.TagMassUntag), ct); await ct.SaveChangesAsync(); return NoContent(); diff --git a/server/AyaNova/Controllers/TagGroupController.cs b/server/AyaNova/Controllers/TagGroupController.cs index 42f35176..1f24bb61 100644 --- a/server/AyaNova/Controllers/TagGroupController.cs +++ b/server/AyaNova/Controllers/TagGroupController.cs @@ -204,7 +204,7 @@ namespace AyaNova.Api.Controllers await ct.SaveChangesAsync(); //Log - EventLogProcessor.AddEntry(new Event(biz.userId, o.Id, AyaType.TagGroup, AyaEvent.Created), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(biz.userId, o.Id, AyaType.TagGroup, AyaEvent.Created), ct); await ct.SaveChangesAsync(); return CreatedAtAction("GetTagGroup", new { id = o.Id }, new ApiCreatedResponse(o)); @@ -257,7 +257,7 @@ namespace AyaNova.Api.Controllers } //Log - EventLogProcessor.AddEntry(new Event(biz.userId, oFromDb.Id, AyaType.TagGroup, AyaEvent.Modified), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(biz.userId, oFromDb.Id, AyaType.TagGroup, AyaEvent.Modified), ct); try { @@ -329,7 +329,7 @@ namespace AyaNova.Api.Controllers } //Log - EventLogProcessor.AddEntry(new Event(biz.userId, oFromDb.Id, AyaType.TagGroup, AyaEvent.Modified), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(biz.userId, oFromDb.Id, AyaType.TagGroup, AyaEvent.Modified), ct); try { diff --git a/server/AyaNova/Controllers/TrialController.cs b/server/AyaNova/Controllers/TrialController.cs index a8737860..71f691b6 100644 --- a/server/AyaNova/Controllers/TrialController.cs +++ b/server/AyaNova/Controllers/TrialController.cs @@ -97,7 +97,7 @@ namespace AyaNova.Api.Controllers JobsBiz.AddJob(j, ct); //Log - EventLogProcessor.AddEntry(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.TrialSeeder, AyaEvent.Created, size), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.TrialSeeder, AyaEvent.Created, size), ct); ct.SaveChanges(); diff --git a/server/AyaNova/Controllers/UserOptionsController.cs b/server/AyaNova/Controllers/UserOptionsController.cs index 9a75194f..ec382de9 100644 --- a/server/AyaNova/Controllers/UserOptionsController.cs +++ b/server/AyaNova/Controllers/UserOptionsController.cs @@ -136,7 +136,7 @@ namespace AyaNova.Api.Controllers try { //Log - EventLogProcessor.AddEntry(new Event(biz.userId, o.Id, AyaType.UserOptions, AyaEvent.Modified), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(biz.userId, o.Id, AyaType.UserOptions, AyaEvent.Modified), ct); await ct.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) @@ -207,7 +207,7 @@ namespace AyaNova.Api.Controllers try { //Log - EventLogProcessor.AddEntry(new Event(biz.userId, o.Id, AyaType.UserOptions, AyaEvent.Modified), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(biz.userId, o.Id, AyaType.UserOptions, AyaEvent.Modified), ct); await ct.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) diff --git a/server/AyaNova/biz/EventLogProcessor.cs b/server/AyaNova/biz/EventLogProcessor.cs index 7ade3dcb..463ded7a 100644 --- a/server/AyaNova/biz/EventLogProcessor.cs +++ b/server/AyaNova/biz/EventLogProcessor.cs @@ -22,7 +22,7 @@ namespace AyaNova.Biz /// /// /// - internal static void AddEntry(Event newEvent, AyContext ct) + internal static void AddEntryToContextNoSave(Event newEvent, AyContext ct) { ct.Event.Add(newEvent); } diff --git a/server/AyaNova/biz/ImportAyaNova7Biz.cs b/server/AyaNova/biz/ImportAyaNova7Biz.cs index f31c9697..50af1628 100644 --- a/server/AyaNova/biz/ImportAyaNova7Biz.cs +++ b/server/AyaNova/biz/ImportAyaNova7Biz.cs @@ -248,9 +248,9 @@ namespace AyaNova.Biz //handle EventLog entries for users now that we have the user's created //Created - EventLogProcessor.AddEntry(new Event(Creator, RavenId, ayaType, AyaEvent.Created, Created), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(Creator, RavenId, ayaType, AyaEvent.Created, Created), ct); //MODIFIED - EventLogProcessor.AddEntry(new Event(Modifier, RavenId, ayaType, AyaEvent.Modified, Modified), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(Modifier, RavenId, ayaType, AyaEvent.Modified, Modified), ct); await ct.SaveChangesAsync(); } diff --git a/server/AyaNova/biz/LocaleBiz.cs b/server/AyaNova/biz/LocaleBiz.cs index f2979f67..1f4ae55a 100644 --- a/server/AyaNova/biz/LocaleBiz.cs +++ b/server/AyaNova/biz/LocaleBiz.cs @@ -539,7 +539,7 @@ namespace AyaNova.Biz ct.SaveChanges(); //Log now that we have the Id, note that there is no source created / modified for this so just attributing to current userId - EventLogProcessor.AddEntry(new Event(userId, l.Id, AyaType.Locale, AyaEvent.Created), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(userId, l.Id, AyaType.Locale, AyaEvent.Created), ct); ct.SaveChanges(); } diff --git a/server/AyaNova/biz/UserBiz.cs b/server/AyaNova/biz/UserBiz.cs index d78c5699..6d7b5e62 100644 --- a/server/AyaNova/biz/UserBiz.cs +++ b/server/AyaNova/biz/UserBiz.cs @@ -35,7 +35,7 @@ namespace AyaNova.Biz } //todo: - //then after that go into widget and anywhere else that there is this associated type code being called for event and search and implement everywhere, + //then after that go into widget and anywhere else that there is this associated type code being called for event and search and implement everywhere, //then update seeder code to use it and get back on to the main critical path again in the todo internal static UserBiz GetBiz(AyContext ct, Microsoft.AspNetCore.Http.HttpContext httpContext) @@ -82,7 +82,7 @@ namespace AyaNova.Biz // await ct.SaveChangesAsync(); //Log event - EventLogProcessor.AddEntry(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct); await ct.SaveChangesAsync(); //SEARCH INDEXING @@ -93,6 +93,44 @@ namespace AyaNova.Biz } } + //////////////////////////////////////////////////////////////////////////////////////////////// + //CREATE + internal User Create(User inObj) + { + //This is a new user so it will have been posted with a password in plaintext which needs to be salted and hashed + inObj.Salt = Hasher.GenerateSalt(); + inObj.Password = Hasher.hash(inObj.Salt, inObj.Password); + + Validate(inObj, null); + if (HasErrors) + return null; + else + { + //do stuff with User + User outObj = inObj; + outObj.OwnerId = UserId; + //Seeder sets user options in advance so no need to create them here in that case + if (outObj.UserOptions == null) + outObj.UserOptions = new UserOptions(UserId); + + ct.User.Add(outObj); + //save to get Id + ct.SaveChanges(); + + //Handle child and associated items + + //Log event + EventLogProcessor.AddEntryToContextNoSave(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct); + //ct.SaveChanges(); + + //SEARCH INDEXING + Search.ProcessNewObjectKeywords(ct, UserLocaleId, outObj.Id, BizType, outObj.Name, outObj.EmployeeNumber, outObj.Notes, outObj.Name); + + return outObj; + + } + } + //////////////////////////////////////////////////////////////////////////////////////////////// /// GET @@ -104,7 +142,7 @@ namespace AyaNova.Biz if (ret != null) { //Log - EventLogProcessor.AddEntry(new Event(UserId, fetchId, BizType, AyaEvent.Retrieved), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(UserId, fetchId, BizType, AyaEvent.Retrieved), ct); ct.SaveChanges(); } return ret; @@ -226,7 +264,7 @@ namespace AyaNova.Biz //Log modification - EventLogProcessor.AddEntry(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct); ct.SaveChanges(); //Update keywords Search.ProcessUpdatedObjectKeywords(ct, UserLocaleId, dbObj.Id, BizType, dbObj.Name, dbObj.EmployeeNumber, dbObj.Notes, dbObj.Name); @@ -260,7 +298,7 @@ namespace AyaNova.Biz return false; //Log modification - EventLogProcessor.AddEntry(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct); ct.SaveChanges(); //Update keywords Search.ProcessUpdatedObjectKeywords(ct, UserLocaleId, dbObj.Id, BizType, dbObj.Name, dbObj.EmployeeNumber, dbObj.Notes, dbObj.Name); diff --git a/server/AyaNova/biz/WidgetBiz.cs b/server/AyaNova/biz/WidgetBiz.cs index 729b5819..e27da3e6 100644 --- a/server/AyaNova/biz/WidgetBiz.cs +++ b/server/AyaNova/biz/WidgetBiz.cs @@ -62,7 +62,7 @@ namespace AyaNova.Biz //Handle child and associated items: //EVENT LOG - EventLogProcessor.AddEntry(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct); await ct.SaveChangesAsync(); //SEARCH INDEXING @@ -84,7 +84,7 @@ namespace AyaNova.Biz if (ret != null) { //Log - EventLogProcessor.AddEntry(new Event(UserId, fetchId, BizType, AyaEvent.Retrieved), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(UserId, fetchId, BizType, AyaEvent.Retrieved), ct); ct.SaveChanges(); } return ret; @@ -180,7 +180,7 @@ namespace AyaNova.Biz return false; //Log modification - EventLogProcessor.AddEntry(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct); ct.SaveChanges(); //Update keywords Search.ProcessUpdatedObjectKeywords(ct, UserLocaleId, dbObj.Id, BizType, dbObj.Name, dbObj.Notes, dbObj.Name); @@ -202,7 +202,7 @@ namespace AyaNova.Biz return false; //Log modification - EventLogProcessor.AddEntry(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct); + EventLogProcessor.AddEntryToContextNoSave(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct); ct.SaveChanges(); //Update keywords Search.ProcessUpdatedObjectKeywords(ct, UserLocaleId, dbObj.Id, BizType, dbObj.Name, dbObj.Notes, dbObj.Name); diff --git a/server/AyaNova/util/AySchema.cs b/server/AyaNova/util/AySchema.cs index 8c1687a8..9d608b6d 100644 --- a/server/AyaNova/util/AySchema.cs +++ b/server/AyaNova/util/AySchema.cs @@ -23,7 +23,7 @@ namespace AyaNova.Util private const int DESIRED_SCHEMA_LEVEL = 9; internal const long EXPECTED_COLUMN_COUNT = 99; - internal const long EXPECTED_INDEX_COUNT = 20; + internal const long EXPECTED_INDEX_COUNT = 21; //!!!!WARNING: BE SURE TO UPDATE THE DbUtil::PrepareDatabaseForSeeding WHEN NEW TABLES ADDED!!!! ///////////////////////////////////////////////////////////////// @@ -136,7 +136,7 @@ namespace AyaNova.Util //too little is bad if search takes a dogs age to find anything exec("CREATE TABLE asearchdictionary (id BIGSERIAL PRIMARY KEY, word varchar(255) not null)"); - // exec("CREATE UNIQUE INDEX tagname_idx ON atag (name);"); + exec("CREATE UNIQUE INDEX searchdictword_idx ON asearchdictionary (word);"); exec("CREATE TABLE asearchkey (id BIGSERIAL PRIMARY KEY, wordid bigint not null REFERENCES asearchdictionary (id), objectid bigint not null, objecttype integer not null, inname bool not null)"); //create locale text tables diff --git a/server/AyaNova/util/Seeder.cs b/server/AyaNova/util/Seeder.cs index 197f4ff3..21d59d82 100644 --- a/server/AyaNova/util/Seeder.cs +++ b/server/AyaNova/util/Seeder.cs @@ -6,6 +6,7 @@ using Microsoft.Extensions.Logging; using Microsoft.EntityFrameworkCore; using Bogus; using AyaNova.Api.ControllerHelpers; +using System.Diagnostics; namespace AyaNova.Util @@ -46,10 +47,10 @@ namespace AyaNova.Util DbUtil.PrepareDatabaseForSeeding(log); //Seed special test data for integration testing - log.LogInformation("Seeding known users"); + //log.LogInformation("Seeding known users"); SeedKnownUsers(log); - log.LogInformation("Seeding all other data"); + //log.LogInformation("Seeding all other data"); switch (slevel) { @@ -109,6 +110,12 @@ namespace AyaNova.Util //this is a large corporation with multiple branches in multiple locations all in the same country //Each location has a full staff and corporate head office has an overarching staff member in charge of each location case SeedLevel.LargeCorporateMultiRegionalTrialDataSet: + + //PERF + log.LogInformation($"Seeding user(s)...."); + var watch = new Stopwatch(); + watch.Start(); + //IT administrator, can change ops but nothing else GenSeedUser(log, 2, AuthorizationRoles.OpsAdminFull, UserType.NonSchedulable); @@ -119,7 +126,12 @@ namespace AyaNova.Util GenSeedUser(log, 5, AuthorizationRoles.DispatchLimited | AuthorizationRoles.InventoryLimited | AuthorizationRoles.OpsAdminLimited, UserType.NonSchedulable); //techs - GenSeedUser(log, 100, AuthorizationRoles.TechFull | AuthorizationRoles.DispatchLimited, UserType.Schedulable); + //GenSeedUser(log, 100, AuthorizationRoles.TechFull | AuthorizationRoles.DispatchLimited, UserType.Schedulable); + for (int i = 0; i < 20; i++) + { + GenSeedUser(log, 5, AuthorizationRoles.TechFull | AuthorizationRoles.DispatchLimited, UserType.Schedulable); + } + //limited techs GenSeedUser(log, 50, AuthorizationRoles.TechLimited | AuthorizationRoles.DispatchLimited, UserType.Schedulable); @@ -146,13 +158,20 @@ namespace AyaNova.Util GenSeedUser(log, 5, AuthorizationRoles.AccountingFull | AuthorizationRoles.BizAdminLimited, UserType.NonSchedulable); //100 full on client users - GenSeedUser(log, 100, AuthorizationRoles.ClientFull, UserType.Client); + GenSeedUser(log, 20, AuthorizationRoles.ClientFull, UserType.Client); //100 limited client users - GenSeedUser(log, 100, AuthorizationRoles.ClientLimited, UserType.Client); + GenSeedUser(log, 20, AuthorizationRoles.ClientLimited, UserType.Client); + + //PERF + watch.Stop(); + log.LogInformation($"** (SYNC) Users seeded in {watch.ElapsedMilliseconds} ms"); //20000 widgets - GenSeedWidget(log, 20000); + for (int i = 0; i < 400; i++) + { + GenSeedWidget(log, 50); + } break; } @@ -172,6 +191,12 @@ namespace AyaNova.Util } + public static long RUNNING_COUNT = 0; + public static string Uniquify(string s) + { + //return s + " " + ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds(); + return s + " " + (++RUNNING_COUNT).ToString(); + } ////////////////////////////////////////////////////// @@ -239,9 +264,15 @@ namespace AyaNova.Util } - public async static void GenSeedUser(ILogger log, int count, AuthorizationRoles roles, UserType userType, bool active = true, string login = null, string password = null) + + + public static void GenSeedUser(ILogger log, int count, AuthorizationRoles roles, UserType userType, bool active = true, string login = null, string password = null) { - log.LogInformation($"Seeding {count.ToString()} user(s)"); + // log.LogInformation($"Seeding {count.ToString()} user(s)"); + //var watch = new Stopwatch(); + //watch.Start(); + + UserBiz Biz = UserBiz.GetBizInternal(ServiceProviderProvider.DBContext); //allow creation of not entirely ready users (missing client id or subcontractor vendor id etc) Biz.SeedOrImportRelaxedRulesMode = true; @@ -252,7 +283,7 @@ namespace AyaNova.Util u.Active = active; u.OwnerId = 1; var p = new Bogus.Person(); - u.Name = p.FullName; + u.Name = Uniquify(p.FullName); // u.Salt = Hasher.GenerateSalt(); if (login != null) { @@ -275,22 +306,27 @@ namespace AyaNova.Util u.UserOptions = new UserOptions(1); u.UserOptions.EmailAddress = p.Email.Replace("gmail.com", "helloayanova.com").Replace("hotmail.com", "helloayanova.com").Replace("yahoo.com", "helloayanova.com"); - var NewObject = await Biz.CreateAsync(u); + //var NewObject = Biz.CreateAsync(u).Result; + + var NewObject = Biz.Create(u);//sync version seems consistently faster than async one if (NewObject == null) { log.LogError($"Seeder::GenSeedUser error creating user {u.Name}\r\n" + Biz.GetErrorsAsString()); throw new System.Exception("Seeder::GenSeedUser error creating user\r\n" + Biz.GetErrorsAsString()); } } - log.LogInformation("User seeding completed"); + // watch.Stop(); + // log.LogInformation($"{count.ToString()} user(s) seeded in {watch.ElapsedMilliseconds} ms"); } ////////////////////////////////////////////////////// //Seed widget for testing // - public static async void GenSeedWidget(ILogger log, int count) + public static void GenSeedWidget(ILogger log, int count) { log.LogInformation($"Seeding {count.ToString()} Widget(s)"); + var watch = new Stopwatch(); + watch.Start(); //get a context just for this op to save memory on changetracking //AyContext ct = ServiceProviderProvider.DBContext; WidgetBiz Biz = WidgetBiz.GetBizInternal(ServiceProviderProvider.DBContext); @@ -298,7 +334,7 @@ namespace AyaNova.Util for (int x = 0; x < count; x++) { Widget o = new Widget(); - o.Name = f.Commerce.ProductName() + x.ToString(); + o.Name = Uniquify(f.Commerce.ProductName()); o.Active = true; o.StartDate = f.Date.Between(DateTime.Now, DateTime.Now.AddMinutes(60)); o.EndDate = f.Date.Between(DateTime.Now.AddMinutes(90), DateTime.Now.AddHours(5)); @@ -307,14 +343,15 @@ namespace AyaNova.Util //this is nonsense but just to test an enum o.Roles = AuthorizationRoles.DispatchLimited | AuthorizationRoles.InventoryLimited | AuthorizationRoles.OpsAdminLimited; o.Notes = f.Lorem.Paragraph(); - var NewObject = await Biz.CreateAsync(o); + var NewObject = Biz.CreateAsync(o).Result; if (NewObject == null) { log.LogError($"Seeder::GenSeedWidget error creating widget {o.Name}\r\n" + Biz.GetErrorsAsString()); throw new System.Exception("Seeder::GenSeedWidget error creating widget\r\n" + Biz.GetErrorsAsString()); } } - log.LogInformation("Widget seeding completed"); + watch.Stop(); + log.LogInformation($"{count.ToString()} Widget(s) seeded in {watch.ElapsedMilliseconds} ms"); } }//eoc