This commit is contained in:
2018-08-28 20:12:51 +00:00
parent ecb6b3d7c6
commit 5cd914767d
17 changed files with 62 additions and 53 deletions

View File

@@ -1,13 +1,15 @@
Business history log
FROM CASE 79
A central event log used to track major changes to business objects and major events of significance in AyaNova.
??Has some sort of checksum or verification so we can tell it wasn't fucked with (too hard to implement, would be something like a blockchain?)
A central event log used to track major changes to business objects and major events of significance in AyaNova
Consumed by various widgets for record history purposes
Default feature, no need to turn on or off keeps logs for 45 days, users who want more can
Default feature, no need to turn on or off
Items are only removed from log when source object is deleted (and replaced with a deleted entry and textual description of deleted item)
Needs a cleaner job that periodically looks for non-existant objects that are logged
Has to handle a scenario where there is no data for an object because in future we will likely have a purge feature or maybe a feature to turn it off and needs to accept that scenario
?FUTURE: Has some sort of checksum or verification so we can tell it wasn't fucked with (too hard to implement, would be something like a blockchain?)
?FUTURE: Needs a cleaner job that periodically looks for non-existant objects that are logged
?FUTURE: keeps logs for 45 days initially keeps forever or until object is deleted
ROUTES
------

View File

@@ -20,7 +20,7 @@ CODING WORK
Overall plan for now: anything standing in the way of making the initial client shell UI needs to be done first, everything else can wait
- Audit log
- Route for retrieving as log format for reading (like reports: one for specific object id and type, one for user id as log of what they've been doing etc)
- Make sure trial generated data generates log events so that we can properly test with huge dataset
- Test with huge dataset
- Remove CREATED from all objects now that event log tracks it
- Localized text

View File

@@ -239,7 +239,7 @@ namespace AyaNova.Api.Controllers
});
//Log
EventLogProcessor.AddEntry(new Event(UserId, attachToObject.ObjectId, attachToObject.ObjectType, AyaEvent.AttachmentCreate, v.DisplayFileName), ct);
//EventLogProcessor.AddEntry(new Event(UserId, attachToObject.ObjectId, attachToObject.ObjectType, AyaEvent.AttachmentCreate, v.DisplayFileName), ct);
}
}
@@ -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.AddEntry(new Event(UserId, dbObj.AttachToObjectId, dbObj.AttachToObjectType, AyaEvent.AttachmentDelete, dbObj.DisplayFileName), ct);
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.AddEntry(new Event(UserId, dbObj.AttachToObjectId, dbObj.AttachToObjectType, AyaEvent.AttachmentDownload, dbObj.DisplayFileName), ct);
return PhysicalFile(filePath, mimetype, dbObj.DisplayFileName);

View File

@@ -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.AddEntry(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.License, AyaEvent.LicenseFetch), ct);
return Ok(new ApiOkResponse(ret));
}
@@ -179,7 +179,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.AddEntry(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.License, AyaEvent.LicenseTrialRequest), ct);
return Ok(new ApiOkResponse(ret));
}

View File

@@ -163,7 +163,7 @@ namespace AyaNova.Api.Controllers
await ct.SaveChangesAsync();
//Log
EventLogProcessor.AddEntry(new Event(biz.userId, o.Id, AyaType.Locale, AyaEvent.Created), ct);
//EventLogProcessor.AddEntry(new Event(biz.userId, o.Id, AyaType.Locale, AyaEvent.Created), ct);
return CreatedAtAction("GetLocale", new { id = o.Id }, new ApiCreatedResponse(o));
}
@@ -241,7 +241,7 @@ namespace AyaNova.Api.Controllers
}
//Log
EventLogProcessor.AddEntry(new Event(biz.userId, oDbParent.Id, AyaType.Locale, AyaEvent.Modified), ct);
//EventLogProcessor.AddEntry(new Event(biz.userId, oDbParent.Id, AyaType.Locale, AyaEvent.Modified), ct);
return Ok(new ApiOkResponse(new { ConcurrencyToken = oFromDb.ConcurrencyToken }));
}
@@ -310,7 +310,7 @@ namespace AyaNova.Api.Controllers
}
//Log
EventLogProcessor.AddEntry(new Event(biz.userId, oFromDb.Id, AyaType.Locale, AyaEvent.Modified), ct);
//EventLogProcessor.AddEntry(new Event(biz.userId, oFromDb.Id, AyaType.Locale, AyaEvent.Modified), ct);
return Ok(new ApiOkResponse(new { ConcurrencyToken = oFromDb.ConcurrencyToken }));
}

View File

@@ -82,7 +82,7 @@ namespace AyaNova.Api.Controllers
//Log
EventLogProcessor.AddEntry(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.LogFile, AyaEvent.Retrieved,logname), ct);
// EventLogProcessor.AddEntry(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.LogFile, AyaEvent.Retrieved,logname), ct);
return Content(System.IO.File.ReadAllText(logFilePath));

View File

@@ -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.AddEntry(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.Metrics, AyaEvent.Retrieved), ct);
return Content(sResult);
}
@@ -99,7 +99,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.AddEntry(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.Metrics, AyaEvent.Retrieved), ct);
return Ok(new ApiOkResponse(json));
}

View File

@@ -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.AddEntry(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.ServerState, AyaEvent.ServerStateChange, $"{state.ServerState}-{state.Reason}"), ct);
return NoContent();
}

View File

@@ -170,7 +170,7 @@ namespace AyaNova.Api.Controllers
await ct.SaveChangesAsync();
//Log
EventLogProcessor.AddEntry(new Event(biz.userId, o.Id, AyaType.Tag, AyaEvent.Created), ct);
//EventLogProcessor.AddEntry(new Event(biz.userId, o.Id, AyaType.Tag, AyaEvent.Created), ct);
return CreatedAtAction("GetTag", new { id = o.Id }, new ApiCreatedResponse(o));
}
@@ -241,7 +241,7 @@ namespace AyaNova.Api.Controllers
}
//Log
EventLogProcessor.AddEntry(new Event(biz.userId, oFromDb.Id, AyaType.Tag, AyaEvent.Modified), ct);
//EventLogProcessor.AddEntry(new Event(biz.userId, oFromDb.Id, AyaType.Tag, AyaEvent.Modified), ct);
return Ok(new ApiOkResponse(new { ConcurrencyToken = oFromDb.ConcurrencyToken }));
}
@@ -309,7 +309,7 @@ namespace AyaNova.Api.Controllers
}
//Log
EventLogProcessor.AddEntry(new Event(biz.userId, oFromDb.Id, AyaType.Tag, AyaEvent.Modified), ct);
//EventLogProcessor.AddEntry(new Event(biz.userId, oFromDb.Id, AyaType.Tag, AyaEvent.Modified), ct);
return Ok(new ApiOkResponse(new { ConcurrencyToken = oFromDb.ConcurrencyToken }));
}

View File

@@ -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.AddEntry(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.TrialSeeder, AyaEvent.Created,size), ct);
return Accepted(new { JobId = j.GId });//202 accepted

View File

@@ -86,7 +86,7 @@ namespace AyaNova.Api.Controllers
}
//Log
EventLogProcessor.AddEntry(new Event(biz.userId, o.Id, AyaType.Widget, AyaEvent.Retrieved), ct);
EventLogProcessor.AddEntryAndSave(new Event(biz.userId, o.Id, AyaType.Widget, AyaEvent.Retrieved), ct);
return Ok(new ApiOkResponse(o));
}
@@ -216,6 +216,8 @@ namespace AyaNova.Api.Controllers
try
{
//Log
EventLogProcessor.AddEntryNoSave(new Event(biz.userId, o.Id, AyaType.Widget, AyaEvent.Modified), ct);
await ct.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
@@ -233,8 +235,7 @@ namespace AyaNova.Api.Controllers
}
}
//Log
EventLogProcessor.AddEntry(new Event(biz.userId, o.Id, AyaType.Widget, AyaEvent.Modified), ct);
return Ok(new ApiOkResponse(new { ConcurrencyToken = o.ConcurrencyToken }));
}
@@ -291,6 +292,8 @@ namespace AyaNova.Api.Controllers
try
{
//Log
EventLogProcessor.AddEntryNoSave(new Event(biz.userId, o.Id, AyaType.Widget, AyaEvent.Modified), ct);
await ct.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
@@ -306,8 +309,7 @@ namespace AyaNova.Api.Controllers
}
//Log
EventLogProcessor.AddEntry(new Event(biz.userId, o.Id, AyaType.Widget, AyaEvent.Modified), ct);
return Ok(new ApiOkResponse(new { ConcurrencyToken = o.ConcurrencyToken }));
}
@@ -353,11 +355,12 @@ namespace AyaNova.Api.Controllers
}
else
{
//Log
EventLogProcessor.AddEntryNoSave(new Event(biz.userId, o.Id, AyaType.Widget, AyaEvent.Created), ct);
//save and success return
await ct.SaveChangesAsync();
//Log
EventLogProcessor.AddEntry(new Event(biz.userId, o.Id, AyaType.Widget, AyaEvent.Created), ct);
return CreatedAtAction("GetWidget", new { id = o.Id }, new ApiCreatedResponse(o));
}

View File

@@ -378,12 +378,12 @@ namespace AyaNova
lb.ValidateLocales();
#if (DEBUG)
// Util.DbUtil.DropAndRecreateDb(_log);
// AySchema.CheckAndUpdate(dbContext, _log);
// lb.ValidateLocales();
// AyaNova.Core.License.Initialize(apiServerState, dbContext, _log);
// AyaNova.Core.License.Fetch(apiServerState, dbContext, _log);
// Util.Seeder.SeedDatabase(dbContext, Util.Seeder.SeedLevel.SmallOneManShopTrialDataSet);
Util.DbUtil.DropAndRecreateDb(_log);
AySchema.CheckAndUpdate(dbContext, _log);
lb.ValidateLocales();
AyaNova.Core.License.Initialize(apiServerState, dbContext, _log);
AyaNova.Core.License.Fetch(apiServerState, dbContext, _log);
Util.Seeder.SeedDatabase(dbContext, Util.Seeder.SeedLevel.MediumLocalServiceCompanyTrialDataSet);
#endif

View File

@@ -17,11 +17,23 @@ namespace AyaNova.Biz
/// <summary>
/// Add an entry to the log
/// DOES NOT SAVE
/// </summary>
/// <param name="newEvent"></param>
/// <param name="ct"></param>
/// <returns></returns>
internal static void AddEntry(Event newEvent, AyContext ct)
internal static void AddEntryNoSave(Event newEvent, AyContext ct)
{
ct.Event.Add(newEvent);
}
/// <summary>
/// Add and SAVE entry to the log
/// </summary>
/// <param name="newEvent"></param>
/// <param name="ct"></param>
/// <returns></returns>
internal static void AddEntryAndSave(Event newEvent, AyContext ct)
{
ct.Event.Add(newEvent);
ct.SaveChanges();

View File

@@ -16,7 +16,6 @@ namespace AyaNova.Models
[Required]
public long OwnerId { get; set; }
public string Name { get; set; }
public DateTime Created { get; set; }
public decimal? DollarAmount { get; set; }
public bool? Active { get; set; }
public AuthorizationRoles Roles { get; set; }
@@ -24,12 +23,6 @@ namespace AyaNova.Models
public DateTime? EndDate { get; set; }
public Widget()
{
Created = System.DateTime.UtcNow;
}
}
}

View File

@@ -22,7 +22,7 @@ namespace AyaNova.Util
//!!!!WARNING: BE SURE TO UPDATE THE DbUtil::PrepareDatabaseForSeeding WHEN NEW TABLES ADDED!!!!
private const int DESIRED_SCHEMA_LEVEL = 9;
internal const long EXPECTED_COLUMN_COUNT = 76;
internal const long EXPECTED_COLUMN_COUNT = 75;
internal const long EXPECTED_INDEX_COUNT = 15;
//!!!!WARNING: BE SURE TO UPDATE THE DbUtil::PrepareDatabaseForSeeding WHEN NEW TABLES ADDED!!!!
@@ -172,7 +172,7 @@ namespace AyaNova.Util
//Add widget table
//id, text, longtext, boolean, currency,
exec("CREATE TABLE awidget (id BIGSERIAL PRIMARY KEY, ownerid bigint not null, name varchar(255) not null, created timestamp not null, " +
exec("CREATE TABLE awidget (id BIGSERIAL PRIMARY KEY, ownerid bigint not null, name varchar(255) not null, " +
"startdate timestamp, enddate timestamp, dollaramount money, active bool, roles int4)");
setSchemaLevel(++currentSchema);

View File

@@ -119,6 +119,7 @@ namespace AyaNova.Util
//2000 widgets
GenSeedWidget(2000, ct);
//GenSeedWidget(100, ct);
break;
//this is a large corporation with multiple branches in multiple locations all in the same country
@@ -257,14 +258,13 @@ namespace AyaNova.Util
//
public static void GenSeedWidget(int count, AyContext ct)
{
var s="blah";
for (int x = 0; x < count; x++)
{
Widget o = new Widget();
var f = new Bogus.Faker();
o.Name = f.Commerce.ProductName();
o.Active = f.Random.Bool();
o.StartDate = f.Date.Between(DateTime.Now, DateTime.Now.AddMinutes(60));
o.EndDate = f.Date.Between(DateTime.Now.AddMinutes(90), DateTime.Now.AddHours(5));
@@ -273,9 +273,13 @@ namespace AyaNova.Util
//this is nonsense but just to test an enum
o.Roles = AuthorizationRoles.DispatchLimited | AuthorizationRoles.InventoryLimited | AuthorizationRoles.OpsAdminLimited;
ct.Widget.Add(o);
ct.SaveChanges();
EventLogProcessor.AddEntry(new Event(o.OwnerId, o.Id, AyaType.Widget, AyaEvent.Created), ct);
// ct.SaveChanges();
//Log
EventLogProcessor.AddEntryNoSave(new Event(o.OwnerId, o.Id, AyaType.Widget, AyaEvent.Created), ct);
}
ct.SaveChanges();
var v=s;
}

View File

@@ -19,7 +19,6 @@ namespace raven_integration
{
"id": 0,
"name": "string",
"created": "2018-02-09T16:45:56.057Z",
"dollarAmount": 0,
"active": true,
"roles": 0
@@ -28,7 +27,6 @@ namespace raven_integration
//CREATE
dynamic w1 = new JObject();
w1.name = Util.Uniquify("First Test WIDGET");
w1.created = DateTime.Now.ToString();
w1.dollarAmount = 1.11m;
w1.active = true;
w1.roles = 0;
@@ -40,7 +38,6 @@ namespace raven_integration
dynamic w2 = new JObject();
w2.name = Util.Uniquify("Second Test WIDGET");
w2.created = DateTime.Now.ToString();
w2.dollarAmount = 2.22m;
w2.active = true;
w2.roles = 0;
@@ -161,7 +158,6 @@ namespace raven_integration
dynamic w2 = new JObject();
w2.name = Util.Uniquify("PutConcurrencyViolationShouldFail");
w2.created = DateTime.Now.ToString();
w2.dollarAmount = 2.22m;
w2.active = true;
w2.roles = 0;
@@ -199,7 +195,6 @@ namespace raven_integration
dynamic w2 = new JObject();
w2.name = Util.Uniquify("PatchConcurrencyViolationShouldFail");
w2.created = DateTime.Now.ToString();
w2.dollarAmount = 2.22m;
w2.active = true;
w2.roles = 0;