diff --git a/.vscode/launch.json b/.vscode/launch.json index c77c09c4..60193070 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -63,7 +63,7 @@ "AYANOVA_DB_CONNECTION": "Server=localhost;Username=postgres;Password=raven;Database=AyaNova;CommandTimeout=300;", "AYANOVA_DATA_PATH": "c:\\temp\\ravendata", "AYANOVA_USE_URLS": "http://*:7575;", - "AYANOVA_PERMANENTLY_ERASE_DATABASE":"true", + //"AYANOVA_PERMANENTLY_ERASE_DATABASE":"true", //"AYANOVA_REMOVE_LICENSE_FROM_DB":"true", //"AYANOVA_REPORT_RENDERING_TIMEOUT":"1", //"AYANOVA_REPORT_RENDER_API_URL_OVERRIDE": "http://localhost:7575", diff --git a/dist/latest-version.json b/dist/latest-version.json index 16175473..8e6a2888 100644 --- a/dist/latest-version.json +++ b/dist/latest-version.json @@ -1,4 +1,4 @@ { - "latestversion":"8.0.44", + "latestversion":"8.0.42", "changelogurl":"https://ayanova.com/docs/changelog/#ayanova-8042-2023-04-06" } \ No newline at end of file diff --git a/server/AyaNova/biz/JobsBiz.cs b/server/AyaNova/biz/JobsBiz.cs index a93460d4..7c5f0684 100644 --- a/server/AyaNova/biz/JobsBiz.cs +++ b/server/AyaNova/biz/JobsBiz.cs @@ -295,6 +295,12 @@ namespace AyaNova.Biz await CoreIntegrationLogSweeper.DoWorkAsync(); if (!KeepOnWorking()) return; +#if !SUBSCRIPTION_BUILD + //CHECK IF NEW VERSION AVAILABLE + //this will alert users on login for perpetual server instances + await CoreJobVersionCheck.DoWorkAsync(); +#endif + log.LogTrace("Processing exclusive dynamic jobs"); @@ -374,58 +380,61 @@ namespace AyaNova.Biz /// internal static async Task ProcessJobAsync(OpsJob job) { - + var JobDescription = $"{job.Name} - {job.JobType.ToString()}"; if (job.SubType != JobSubType.NotSet) JobDescription += $":{job.SubType}"; await LogJobAsync(job.GId, $"LT:ProcessingJob \"{JobDescription}\""); log.LogDebug($"ProcessJobAsync -> Processing job {JobDescription}"); IJobObject o = null; - try{ - using (AyContext ct = ServiceProviderProvider.DBContext) + try { - switch (job.JobType) + using (AyContext ct = ServiceProviderProvider.DBContext) { - case JobType.Backup: - //This is called when on demand only, normal backups are processed above with normal system jobs - await CoreJobBackup.DoWorkAsync(true); - await UpdateJobStatusAsync(job.GId, JobStatus.Completed); - break; - case JobType.TestJob: - o = (IJobObject)BizObjectFactory.GetBizObject(AyaType.ServerJob, ct, 1, AuthorizationRoles.BizAdmin); - break; - case JobType.SeedTestData: - o = (IJobObject)BizObjectFactory.GetBizObject(AyaType.TrialSeeder, ct, 1, AuthorizationRoles.BizAdmin); - break; - case JobType.AttachmentMaintenance: - o = (IJobObject)BizObjectFactory.GetBizObject(AyaType.FileAttachment, ct, 1, AuthorizationRoles.BizAdmin); - break; - case JobType.BatchCoreObjectOperation: - //batch 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 + switch (job.JobType) + { + case JobType.Backup: + //This is called when on demand only, normal backups are processed above with normal system jobs + await CoreJobBackup.DoWorkAsync(true); + await UpdateJobStatusAsync(job.GId, JobStatus.Completed); + break; + case JobType.TestJob: + o = (IJobObject)BizObjectFactory.GetBizObject(AyaType.ServerJob, ct, 1, AuthorizationRoles.BizAdmin); + break; + case JobType.SeedTestData: + o = (IJobObject)BizObjectFactory.GetBizObject(AyaType.TrialSeeder, ct, 1, AuthorizationRoles.BizAdmin); + break; + case JobType.AttachmentMaintenance: + o = (IJobObject)BizObjectFactory.GetBizObject(AyaType.FileAttachment, ct, 1, AuthorizationRoles.BizAdmin); + break; + case JobType.BatchCoreObjectOperation: + //batch 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 - //case 4357 - var tempObject=BizObjectFactory.GetBizObject(job.AType, ct, 1, AuthorizationRoles.BizAdmin); - if(! (tempObject is IJobObject)){ - throw new System.NotSupportedException($"ProcessJobAsync type {job.JobType.ToString()} is not supported for Batch operations"); - } - o = (IJobObject)tempObject; - break; - case JobType.RenderReport: - o = (IJobObject)BizObjectFactory.GetBizObject(AyaType.Report, ct, 1, AuthorizationRoles.BizAdmin); - break; - default: - throw new System.NotSupportedException($"ProcessJobAsync type {job.JobType.ToString()} is not supported"); + //case 4357 + var tempObject = BizObjectFactory.GetBizObject(job.AType, ct, 1, AuthorizationRoles.BizAdmin); + if (!(tempObject is IJobObject)) + { + throw new System.NotSupportedException($"ProcessJobAsync type {job.JobType.ToString()} is not supported for Batch operations"); + } + o = (IJobObject)tempObject; + break; + case JobType.RenderReport: + o = (IJobObject)BizObjectFactory.GetBizObject(AyaType.Report, ct, 1, AuthorizationRoles.BizAdmin); + break; + default: + throw new System.NotSupportedException($"ProcessJobAsync type {job.JobType.ToString()} is not supported"); + } + + if (o != null) + await o.HandleJobAsync(job); } - - if (o != null) - await o.HandleJobAsync(job); + log.LogDebug($"ProcessJobAsync -> Job completed {JobDescription}"); } - log.LogDebug($"ProcessJobAsync -> Job completed {JobDescription}"); - } - catch(Exception ex){ + catch (Exception ex) + { await LogJobAsync(job.GId, $"LT:BatchJob \"{JobDescription}\" - LT:Failed "); - log.LogError(ex,$"ProcessJobAsync -> job failed {JobDescription}"); + log.LogError(ex, $"ProcessJobAsync -> job failed {JobDescription}"); await JobsBiz.UpdateJobStatusAsync(job.GId, JobStatus.Failed); } } diff --git a/server/AyaNova/generator/CoreJobVersionCheck.cs b/server/AyaNova/generator/CoreJobVersionCheck.cs index 3c9b9d51..bc861376 100644 --- a/server/AyaNova/generator/CoreJobVersionCheck.cs +++ b/server/AyaNova/generator/CoreJobVersionCheck.cs @@ -4,10 +4,14 @@ using Microsoft.Extensions.Logging; using AyaNova.Models; using AyaNova.Util; +using System.Net.Http; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + namespace AyaNova.Biz { - + /// /// called by Generator to check new releases automatically /// @@ -18,18 +22,11 @@ namespace AyaNova.Biz private static DateTime _lastCheck = DateTime.MinValue; #if (DEBUG) - private static TimeSpan FAST_TRACK = new TimeSpan(0, 1, 0); - private static TimeSpan SLOW_TRACK = new TimeSpan(0, 5, 0); + + private static TimeSpan CHECK_INTERVAL = new TimeSpan(0, 0, 30);//30 seconds #else -#if (SUBSCRIPTION_BUILD) - //subscription servers need to check more frequently because the month to month rentals could be dodgy when 24 hours - //also it's all in-network so there is no downside or performance hit for this - private static TimeSpan FAST_TRACK = new TimeSpan(0, 30, 0); - private static TimeSpan SLOW_TRACK = new TimeSpan(0, 30, 0); -#else - private static TimeSpan FAST_TRACK = new TimeSpan(0, 30, 0); - private static TimeSpan SLOW_TRACK = new TimeSpan(24, 0, 0); -#endif + + private static TimeSpan CHECK_INTERVAL = new TimeSpan(24, 0, 0);//every day #endif //////////////////////////////////////////////////////////////////////////////////////////////// @@ -37,69 +34,80 @@ namespace AyaNova.Biz // public static async Task DoWorkAsync() { - log.LogTrace("Job starting"); - var tsSinceLastCheck = DateTime.UtcNow - _lastCheck; - //which track are we on? - /* - FAST TRACK=30 minutes - SLOW TRACK= 24 hours - NONE = 0,//fast track (no license) - ActiveTrial = 1,//fast track (because they may be testing a migration and running out of time and don't want to cancel it) - ExpiredTrial = 2,//fast track - ActivePurchased = 3,//slow track - ExpiredPurchased = 4,//fast track - Revoked = 5//slow track - */ - TimeSpan tsCheckFrequency; - switch (AyaNova.Core.License.ActiveKey.Status) - { - case AyaNova.Core.License.AyaNovaLicenseKey.LicenseStatus.NONE: - case AyaNova.Core.License.AyaNovaLicenseKey.LicenseStatus.ActiveTrial: - case AyaNova.Core.License.AyaNovaLicenseKey.LicenseStatus.ExpiredTrial: - case AyaNova.Core.License.AyaNovaLicenseKey.LicenseStatus.ExpiredPurchased: - tsCheckFrequency = FAST_TRACK; - break; - default: - tsCheckFrequency = SLOW_TRACK; - break; - } - log.LogTrace($"Check frequency{tsCheckFrequency}"); - if (tsSinceLastCheck < tsCheckFrequency) - { - log.LogTrace($"Not yet"); + if (DateTime.UtcNow - _lastCheck < CHECK_INTERVAL) return; - } - using (AyContext ct = AyaNova.Util.ServiceProviderProvider.DBContext) + log.LogDebug("Check starting"); + + // ServerGlobalOpsSettingsCache.LATEST_VERSION = "8.0.44"; + // ServerGlobalOpsSettingsCache.CHANGE_LOG_URL = "https://ayanova.com/docs/changelog/"; + + + try { - try//allow exception to bubble up but using try block to ensure the lastcheck is set properly regardless so this doesn't spin out of control - { - var ServerState = (AyaNova.Api.ControllerHelpers.ApiServerState)ServiceProviderProvider.Provider.GetService(typeof(AyaNova.Api.ControllerHelpers.ApiServerState)); - var ret = await AyaNova.Core.License.FetchKeyAsync(ServerState, ct, log, true); - //When this was enabled never saw a failed fetch, trying again without it - //#if (DEBUG) - // log.LogInformation("TEMP TEST LOG: CoreJobVersionCheck - result is: " + ret); - //#endif - //most often the result will be "notfound" but in future might be other results - if (ret == "ok") - { - //Eventlog - await EventLogProcessor.LogEventToDatabaseAsync(new Event(1, 0, AyaType.License, AyaEvent.LicenseFetch, "FromCoreJob"), ct); - } - if (ret != "notfound") - { - //I'm thinking do not log internally failed except as debug event as this would fill up log file - //instead if they have a license issue they can do manual fetch and then that will log so they can see error - //(also it will return an error to the client) - log.LogDebug($"FetchLicense - failed: {ret}"); - } - } - finally + var client = ServiceProviderProvider.HttpClientFactory.CreateClient(); + var res = await client.GetAsync("https://ayanova.com/download/latest-version.json"); + string responseText = string.Empty; + + + if (res.IsSuccessStatusCode) { - _lastCheck = DateTime.UtcNow; + responseText = await res.Content.ReadAsStringAsync(); + var responseJson = JObject.Parse(responseText); + //validate contains version string and that it appears to be valid + if (responseJson.ContainsKey("latestversion")) + { + var v = responseJson["latestversion"].Value(); + if (v.Contains(".")) + { + ServerGlobalOpsSettingsCache.LATEST_VERSION = v; + } + else + { + log.LogDebug($"version json response latestversion missing or malformed, response was: {responseText}"); + } + } + else + { + log.LogDebug($"version json response latestversion missing or malformed, response was: {responseText}"); + } + + + + if (responseJson.ContainsKey("changelogurl")) + { + var u = responseJson["changelogurl"].Value(); + if (u.Contains("http")) + { + ServerGlobalOpsSettingsCache.CHANGE_LOG_URL = u; + } + else + { + log.LogDebug($"version json response changelogurl missing or malformed, response was: {responseText}"); + } + } + else + { + log.LogDebug($"version json response changelogurl missing or malformed, response was: {responseText}"); + } + + } + else + { + log.LogWarning($"Error checking AyaNova website for updated release version: {res.ReasonPhrase},{responseText}"); } } + catch (Exception ex) + { + + log.LogError(ex, "Error checking AyaNova website for updated version"); + } + finally + { + _lastCheck = DateTime.UtcNow; + } + } ///////////////////////////////////////////////////////////////////// }//eoc