This commit is contained in:
@@ -70,9 +70,10 @@ namespace AyaNova.Api.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
//BULK OPS
|
//BULK OPS
|
||||||
//
|
//
|
||||||
|
//
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Bulk add tags to list of object id's specified
|
/// Bulk add tags to list of object id's specified
|
||||||
@@ -102,7 +103,6 @@ namespace AyaNova.Api.Controllers
|
|||||||
JObject o = JObject.FromObject(new
|
JObject o = JObject.FromObject(new
|
||||||
{
|
{
|
||||||
idList = idList,
|
idList = idList,
|
||||||
op = "add-tag",
|
|
||||||
tag = tag
|
tag = tag
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -110,6 +110,7 @@ namespace AyaNova.Api.Controllers
|
|||||||
j.Name = JobName;
|
j.Name = JobName;
|
||||||
j.ObjectType = ayaType;
|
j.ObjectType = ayaType;
|
||||||
j.JobType = JobType.BulkCoreBizObjectOperation;
|
j.JobType = JobType.BulkCoreBizObjectOperation;
|
||||||
|
j.SubType = JobSubType.TagAdd;
|
||||||
j.Exclusive = false;
|
j.Exclusive = false;
|
||||||
j.JobInfo = o.ToString();
|
j.JobInfo = o.ToString();
|
||||||
await JobsBiz.AddJobAsync(j, ct);
|
await JobsBiz.AddJobAsync(j, ct);
|
||||||
@@ -142,7 +143,6 @@ namespace AyaNova.Api.Controllers
|
|||||||
var JobName = $"Bulk operation: Add tag \"{tag}\" on any {ayaType}";
|
var JobName = $"Bulk operation: Add tag \"{tag}\" on any {ayaType}";
|
||||||
JObject o = JObject.FromObject(new
|
JObject o = JObject.FromObject(new
|
||||||
{
|
{
|
||||||
op = "add-any-tag",
|
|
||||||
tag = tag
|
tag = tag
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -150,6 +150,7 @@ namespace AyaNova.Api.Controllers
|
|||||||
j.Name = JobName;
|
j.Name = JobName;
|
||||||
j.ObjectType = ayaType;
|
j.ObjectType = ayaType;
|
||||||
j.JobType = JobType.BulkCoreBizObjectOperation;
|
j.JobType = JobType.BulkCoreBizObjectOperation;
|
||||||
|
j.SubType = JobSubType.TagAddAny;
|
||||||
j.Exclusive = false;
|
j.Exclusive = false;
|
||||||
j.JobInfo = o.ToString();
|
j.JobInfo = o.ToString();
|
||||||
await JobsBiz.AddJobAsync(j, ct);
|
await JobsBiz.AddJobAsync(j, ct);
|
||||||
@@ -184,8 +185,7 @@ namespace AyaNova.Api.Controllers
|
|||||||
var JobName = $"Bulk operation: Remove tag \"{tag}\" from {ayaType} ({idList.Count} specified)";
|
var JobName = $"Bulk operation: Remove tag \"{tag}\" from {ayaType} ({idList.Count} specified)";
|
||||||
JObject o = JObject.FromObject(new
|
JObject o = JObject.FromObject(new
|
||||||
{
|
{
|
||||||
idList = idList,
|
idList = idList,
|
||||||
op = "remove-tag",
|
|
||||||
tag = tag
|
tag = tag
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -193,6 +193,7 @@ namespace AyaNova.Api.Controllers
|
|||||||
j.Name = JobName;
|
j.Name = JobName;
|
||||||
j.ObjectType = ayaType;
|
j.ObjectType = ayaType;
|
||||||
j.JobType = JobType.BulkCoreBizObjectOperation;
|
j.JobType = JobType.BulkCoreBizObjectOperation;
|
||||||
|
j.SubType = JobSubType.TagRemove;
|
||||||
j.Exclusive = false;
|
j.Exclusive = false;
|
||||||
j.JobInfo = o.ToString();
|
j.JobInfo = o.ToString();
|
||||||
await JobsBiz.AddJobAsync(j, ct);
|
await JobsBiz.AddJobAsync(j, ct);
|
||||||
@@ -226,13 +227,13 @@ namespace AyaNova.Api.Controllers
|
|||||||
var JobName = $"Bulk operation: Remove tag \"{tag}\" from any {ayaType}";
|
var JobName = $"Bulk operation: Remove tag \"{tag}\" from any {ayaType}";
|
||||||
JObject o = JObject.FromObject(new
|
JObject o = JObject.FromObject(new
|
||||||
{
|
{
|
||||||
op = "remove-any-tag",
|
|
||||||
tag = tag
|
tag = tag
|
||||||
});
|
});
|
||||||
|
|
||||||
OpsJob j = new OpsJob();
|
OpsJob j = new OpsJob();
|
||||||
j.Name = JobName;
|
j.Name = JobName;
|
||||||
j.ObjectType = ayaType;
|
j.ObjectType = ayaType;
|
||||||
|
j.SubType = JobSubType.TagRemoveAny;
|
||||||
j.JobType = JobType.BulkCoreBizObjectOperation;
|
j.JobType = JobType.BulkCoreBizObjectOperation;
|
||||||
j.Exclusive = false;
|
j.Exclusive = false;
|
||||||
j.JobInfo = o.ToString();
|
j.JobInfo = o.ToString();
|
||||||
@@ -273,7 +274,6 @@ namespace AyaNova.Api.Controllers
|
|||||||
JObject o = JObject.FromObject(new
|
JObject o = JObject.FromObject(new
|
||||||
{
|
{
|
||||||
idList = idList,
|
idList = idList,
|
||||||
op = "replace-tag",
|
|
||||||
fromTag = fromTag,
|
fromTag = fromTag,
|
||||||
toTag = toTag
|
toTag = toTag
|
||||||
});
|
});
|
||||||
@@ -282,6 +282,7 @@ namespace AyaNova.Api.Controllers
|
|||||||
j.ObjectType = ayaType;
|
j.ObjectType = ayaType;
|
||||||
j.Name = JobName;
|
j.Name = JobName;
|
||||||
j.JobType = JobType.BulkCoreBizObjectOperation;
|
j.JobType = JobType.BulkCoreBizObjectOperation;
|
||||||
|
j.SubType = JobSubType.TagReplace;
|
||||||
j.Exclusive = false;
|
j.Exclusive = false;
|
||||||
j.JobInfo = o.ToString();
|
j.JobInfo = o.ToString();
|
||||||
await JobsBiz.AddJobAsync(j, ct);
|
await JobsBiz.AddJobAsync(j, ct);
|
||||||
@@ -319,7 +320,6 @@ namespace AyaNova.Api.Controllers
|
|||||||
var JobName = $"Bulk operation: Replace tag \"{fromTag}\" with tag \"{toTag}\" on any {ayaType}";
|
var JobName = $"Bulk operation: Replace tag \"{fromTag}\" with tag \"{toTag}\" on any {ayaType}";
|
||||||
JObject o = JObject.FromObject(new
|
JObject o = JObject.FromObject(new
|
||||||
{
|
{
|
||||||
op = "replace-any-tag",
|
|
||||||
fromTag = fromTag,
|
fromTag = fromTag,
|
||||||
toTag = toTag
|
toTag = toTag
|
||||||
});
|
});
|
||||||
@@ -328,6 +328,7 @@ namespace AyaNova.Api.Controllers
|
|||||||
j.Name = JobName;
|
j.Name = JobName;
|
||||||
j.ObjectType = ayaType;
|
j.ObjectType = ayaType;
|
||||||
j.JobType = JobType.BulkCoreBizObjectOperation;
|
j.JobType = JobType.BulkCoreBizObjectOperation;
|
||||||
|
j.SubType = JobSubType.TagReplaceAny;
|
||||||
j.Exclusive = false;
|
j.Exclusive = false;
|
||||||
j.JobInfo = o.ToString();
|
j.JobInfo = o.ToString();
|
||||||
await JobsBiz.AddJobAsync(j, ct);
|
await JobsBiz.AddJobAsync(j, ct);
|
||||||
|
|||||||
@@ -9,11 +9,25 @@ namespace AyaNova.Biz
|
|||||||
{
|
{
|
||||||
NotSet = 0,
|
NotSet = 0,
|
||||||
TestWidgetJob = 1,//test job for unit testing
|
TestWidgetJob = 1,//test job for unit testing
|
||||||
CoreJobSweeper = 2,
|
CoreJobSweeper = 2,
|
||||||
SeedTestData = 4,
|
SeedTestData = 4,
|
||||||
BulkCoreBizObjectOperation = 5
|
BulkCoreBizObjectOperation = 5
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// SubTypes for jobs that have further distinctions
|
||||||
|
/// </summary>
|
||||||
|
public enum JobSubType : int
|
||||||
|
{
|
||||||
|
NotSet = 0,
|
||||||
|
TagAdd = 1,
|
||||||
|
TagAddAny = 2,
|
||||||
|
TagRemove = 4,
|
||||||
|
TagRemoveAny = 5,
|
||||||
|
TagReplace = 6,
|
||||||
|
TagReplaceAny = 7
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}//eons
|
}//eons
|
||||||
@@ -396,8 +396,11 @@ namespace AyaNova.Biz
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
internal static async Task ProcessJobAsync(OpsJob job, AyContext ct)
|
internal static async Task ProcessJobAsync(OpsJob job, AyContext ct)
|
||||||
{
|
{
|
||||||
|
var JobDescription = $"{job.Name} {job.JobType.ToString()}";
|
||||||
|
if (job.SubType!=JobSubType.NotSet)
|
||||||
|
JobDescription += $":{job.SubType}";
|
||||||
|
|
||||||
log.LogDebug($"ProcessJobAsync -> Processing job {job.Name} (type {job.JobType.ToString()})");
|
log.LogDebug($"ProcessJobAsync -> Processing job {JobDescription}");
|
||||||
IJobObject o = null;
|
IJobObject o = null;
|
||||||
|
|
||||||
switch (job.JobType)
|
switch (job.JobType)
|
||||||
@@ -408,7 +411,9 @@ namespace AyaNova.Biz
|
|||||||
case JobType.SeedTestData:
|
case JobType.SeedTestData:
|
||||||
o = (IJobObject)BizObjectFactory.GetBizObject(AyaType.TrialSeeder, ct);
|
o = (IJobObject)BizObjectFactory.GetBizObject(AyaType.TrialSeeder, ct);
|
||||||
break;
|
break;
|
||||||
case JobType.BulkCoreBizObjectOperation:
|
case JobType.BulkCoreBizObjectOperation:
|
||||||
|
//bulk op, hand off to biz object to deal with
|
||||||
|
//note, convention is that there is an idList in job.jobinfo json if preselected else it's all objects of type
|
||||||
o = (IJobObject)BizObjectFactory.GetBizObject(job.ObjectType, ct);
|
o = (IJobObject)BizObjectFactory.GetBizObject(job.ObjectType, ct);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -416,7 +421,7 @@ namespace AyaNova.Biz
|
|||||||
}
|
}
|
||||||
|
|
||||||
await o.HandleJobAsync(job);
|
await o.HandleJobAsync(job);
|
||||||
log.LogDebug($"ProcessJobAsync -> Job completed {job.Name} (type {job.JobType.ToString()})");
|
log.LogDebug($"ProcessJobAsync -> Job completed {JobDescription}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ using EnumsNET;
|
|||||||
using AyaNova.Util;
|
using AyaNova.Util;
|
||||||
using AyaNova.Api.ControllerHelpers;
|
using AyaNova.Api.ControllerHelpers;
|
||||||
using AyaNova.Models;
|
using AyaNova.Models;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace AyaNova.Biz
|
namespace AyaNova.Biz
|
||||||
{
|
{
|
||||||
@@ -42,7 +44,7 @@ namespace AyaNova.Biz
|
|||||||
if (HasErrors)
|
if (HasErrors)
|
||||||
return null;
|
return null;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newObject.Tags = TagBiz.NormalizeTags(newObject.Tags);
|
newObject.Tags = TagBiz.NormalizeTags(newObject.Tags);
|
||||||
newObject.CustomFields = JsonUtil.CompactJson(newObject.CustomFields);
|
newObject.CustomFields = JsonUtil.CompactJson(newObject.CustomFields);
|
||||||
await ct.Widget.AddAsync(newObject);
|
await ct.Widget.AddAsync(newObject);
|
||||||
@@ -173,7 +175,7 @@ namespace AyaNova.Biz
|
|||||||
//RESTART SERIAL
|
//RESTART SERIAL
|
||||||
//
|
//
|
||||||
internal async Task<bool> RestartSerial(long newSerial)
|
internal async Task<bool> RestartSerial(long newSerial)
|
||||||
{
|
{
|
||||||
using (var command = ct.Database.GetDbConnection().CreateCommand())
|
using (var command = ct.Database.GetDbConnection().CreateCommand())
|
||||||
{
|
{
|
||||||
command.CommandText = $"alter table awidget alter column serial restart with {newSerial}";
|
command.CommandText = $"alter table awidget alter column serial restart with {newSerial}";
|
||||||
@@ -286,6 +288,9 @@ namespace AyaNova.Biz
|
|||||||
//basically any error condition during job processing should throw up an exception if it can't be handled
|
//basically any error condition during job processing should throw up an exception if it can't be handled
|
||||||
switch (job.JobType)
|
switch (job.JobType)
|
||||||
{
|
{
|
||||||
|
case JobType.BulkCoreBizObjectOperation:
|
||||||
|
await ProcessBulkJobAsync(job);
|
||||||
|
break;
|
||||||
case JobType.TestWidgetJob:
|
case JobType.TestWidgetJob:
|
||||||
await ProcessTestJobAsync(job);
|
await ProcessTestJobAsync(job);
|
||||||
break;
|
break;
|
||||||
@@ -304,18 +309,50 @@ namespace AyaNova.Biz
|
|||||||
var sleepTime = 30 * 1000;
|
var sleepTime = 30 * 1000;
|
||||||
//Simulate a long running job here
|
//Simulate a long running job here
|
||||||
await JobsBiz.UpdateJobStatusAsync(job.GId, JobStatus.Running, ct);
|
await JobsBiz.UpdateJobStatusAsync(job.GId, JobStatus.Running, ct);
|
||||||
await JobsBiz.LogJobAsync(job.GId, $"WidgetBiz::ProcessTestJob started, sleeping for {sleepTime} seconds...", ct);
|
await JobsBiz.LogJobAsync(job.GId, $"Widget ProcessTestJob started, sleeping for {sleepTime} seconds...", ct);
|
||||||
//Uncomment this to test if the job prevents other routes from running
|
//Uncomment this to test if the job prevents other routes from running
|
||||||
//result is NO it doesn't prevent other requests, so we are a-ok for now
|
//result is NO it doesn't prevent other requests, so we are a-ok for now
|
||||||
await Task.Delay(sleepTime);
|
await Task.Delay(sleepTime);
|
||||||
await JobsBiz.LogJobAsync(job.GId, "WidgetBiz::ProcessTestJob done sleeping setting job to finished", ct);
|
await JobsBiz.LogJobAsync(job.GId, "Widget ProcessTestJob done sleeping setting job to finished", ct);
|
||||||
await JobsBiz.UpdateJobStatusAsync(job.GId, JobStatus.Completed, ct);
|
await JobsBiz.UpdateJobStatusAsync(job.GId, JobStatus.Completed, ct);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Other job handlers here...
|
|
||||||
|
private async Task ProcessBulkJobAsync(OpsJob job)
|
||||||
|
{
|
||||||
|
|
||||||
|
//Simulate a long running job here
|
||||||
|
await JobsBiz.UpdateJobStatusAsync(job.GId, JobStatus.Running, ct);
|
||||||
|
await JobsBiz.LogJobAsync(job.GId, $"Widget BulkJob {job.SubType} started...", ct);
|
||||||
|
|
||||||
|
List<long> idList = new List<long>();
|
||||||
|
|
||||||
|
JObject jobData = JObject.Parse(job.JobInfo);
|
||||||
|
if (jobData.ContainsKey("idList"))
|
||||||
|
{
|
||||||
|
idList = jobData["idList"].Value<List<long>>();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
//we need to fetch a list of them all because ALL items was selected
|
||||||
|
}
|
||||||
|
var seedLevel = (Seeder.SeedLevel)jobData["seedLevel"].Value<int>();
|
||||||
|
var timeZoneOffset = jobData["timeZoneOffset"].Value<decimal>();
|
||||||
|
|
||||||
|
//either process an id list or fetch all objects and process
|
||||||
|
|
||||||
|
//call out processor for each item in turn
|
||||||
|
switch (job.SubType)
|
||||||
|
{
|
||||||
|
case JobSubType.TagAdd:
|
||||||
|
}
|
||||||
|
|
||||||
|
await JobsBiz.LogJobAsync(job.GId, $"Widget BulkJob {job.SubType} completed", ct);
|
||||||
|
await JobsBiz.UpdateJobStatusAsync(job.GId, JobStatus.Completed, ct);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace AyaNova.Models
|
|||||||
public DateTime Created { get; set; }
|
public DateTime Created { get; set; }
|
||||||
public uint Concurrency { get; set; }
|
public uint Concurrency { get; set; }
|
||||||
|
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
@@ -27,10 +27,12 @@ namespace AyaNova.Models
|
|||||||
public DateTime StartAfter { get; set; }
|
public DateTime StartAfter { get; set; }
|
||||||
[Required]
|
[Required]
|
||||||
public JobType JobType { get; set; }
|
public JobType JobType { get; set; }
|
||||||
|
public JobSubType SubType { get; set; }
|
||||||
public long ObjectId { get; set; }
|
public long ObjectId { get; set; }
|
||||||
public AyaType ObjectType { get; set; }
|
public AyaType ObjectType { get; set; }
|
||||||
[Required]
|
[Required]
|
||||||
public JobStatus JobStatus { get; set; }
|
public JobStatus JobStatus { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Json string of any required extra info for job
|
/// Json string of any required extra info for job
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -45,6 +47,7 @@ namespace AyaNova.Models
|
|||||||
Exclusive = false;
|
Exclusive = false;
|
||||||
StartAfter = Created;
|
StartAfter = Created;
|
||||||
JobType = JobType.NotSet;
|
JobType = JobType.NotSet;
|
||||||
|
SubType = JobSubType.NotSet;
|
||||||
ObjectId = 0;
|
ObjectId = 0;
|
||||||
ObjectType = AyaType.NoType;
|
ObjectType = AyaType.NoType;
|
||||||
JobStatus = JobStatus.Sleeping;
|
JobStatus = JobStatus.Sleeping;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace AyaNova.Util
|
|||||||
//!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImporting WHEN NEW TABLES ADDED!!!!
|
//!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImporting WHEN NEW TABLES ADDED!!!!
|
||||||
private const int DESIRED_SCHEMA_LEVEL = 11;
|
private const int DESIRED_SCHEMA_LEVEL = 11;
|
||||||
|
|
||||||
internal const long EXPECTED_COLUMN_COUNT = 305;
|
internal const long EXPECTED_COLUMN_COUNT = 306;
|
||||||
internal const long EXPECTED_INDEX_COUNT = 134;
|
internal const long EXPECTED_INDEX_COUNT = 134;
|
||||||
|
|
||||||
//!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImporting WHEN NEW TABLES ADDED!!!!
|
//!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImporting WHEN NEW TABLES ADDED!!!!
|
||||||
@@ -270,7 +270,7 @@ namespace AyaNova.Util
|
|||||||
LogUpdateMessage(log);
|
LogUpdateMessage(log);
|
||||||
|
|
||||||
await ExecQueryAsync("CREATE TABLE aopsjob (gid uuid PRIMARY KEY, name text not null, created timestamp not null, exclusive bool not null, " +
|
await ExecQueryAsync("CREATE TABLE aopsjob (gid uuid PRIMARY KEY, name text not null, created timestamp not null, exclusive bool not null, " +
|
||||||
"startafter timestamp not null, jobtype integer not null, objectid bigint null, objecttype integer null, jobstatus integer not null, jobinfo text null)");
|
"startafter timestamp not null, jobtype integer not null, subtype integer null, objectid bigint null, objecttype integer null, jobstatus integer not null, jobinfo text null)");
|
||||||
await ExecQueryAsync("CREATE TABLE aopsjoblog (gid uuid PRIMARY KEY, jobid uuid not null REFERENCES aopsjob (gid), created timestamp not null, statustext text not null)");
|
await ExecQueryAsync("CREATE TABLE aopsjoblog (gid uuid PRIMARY KEY, jobid uuid not null REFERENCES aopsjob (gid), created timestamp not null, statustext text not null)");
|
||||||
|
|
||||||
await SetSchemaLevelAsync(++currentSchema);
|
await SetSchemaLevelAsync(++currentSchema);
|
||||||
|
|||||||
Reference in New Issue
Block a user