This commit is contained in:
@@ -44,8 +44,6 @@ TODO: restrict server so randos can't login since the client now has all the log
|
|||||||
not sure how to do that and still support phone via cellular network or other people's wifi from logging in
|
not sure how to do that and still support phone via cellular network or other people's wifi from logging in
|
||||||
Firewall settings I guess of some kind or maybe require a manual edit to the password, like add a 1 to the end of all of them or something?
|
Firewall settings I guess of some kind or maybe require a manual edit to the password, like add a 1 to the end of all of them or something?
|
||||||
|
|
||||||
todo: Notification look for and implement //TODO: notify OPSNOTIFY
|
|
||||||
When notification system is in place
|
|
||||||
|
|
||||||
todo: OPS notification created for failed jobs
|
todo: OPS notification created for failed jobs
|
||||||
also maybe direct immediate email bypassing generator?
|
also maybe direct immediate email bypassing generator?
|
||||||
|
|||||||
@@ -576,13 +576,12 @@ namespace AyaNova.Api.Controllers
|
|||||||
var filePath = FileUtil.GetPermanentAttachmentFilePath(dbObject.StoredFileName);
|
var filePath = FileUtil.GetPermanentAttachmentFilePath(dbObject.StoredFileName);
|
||||||
if (!System.IO.File.Exists(filePath))
|
if (!System.IO.File.Exists(filePath))
|
||||||
{
|
{
|
||||||
//TODO: notify OPSNOTIFY
|
|
||||||
//TODO: notify this should trigger some kind of notification to the ops people
|
|
||||||
//and a red light on the dashboard
|
|
||||||
//TODO: this should reset the validity
|
//TODO: this should reset the validity
|
||||||
|
|
||||||
var errText = $"Physical file {dbObject.StoredFileName} not found despite attachment record, this file is missing";
|
var errText = $"Physical file {dbObject.StoredFileName} not found despite attachment record, this file is missing";
|
||||||
log.LogError(errText);
|
log.LogError(errText);
|
||||||
|
await NotifyEventProcessor.AddOpsProblemEvent($"File attachment issue: {errText}");
|
||||||
|
|
||||||
return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND, null, errText));
|
return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND, null, errText));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ namespace AyaNova.Biz
|
|||||||
|
|
||||||
log.LogDebug(msg);
|
log.LogDebug(msg);
|
||||||
await JobsBiz.LogJobAsync(job.GId, msg);
|
await JobsBiz.LogJobAsync(job.GId, msg);
|
||||||
//TODO: notify OPSNOTIFY
|
await NotifyEventProcessor.AddOpsProblemEvent($"Attachments issue:{msg}");
|
||||||
var outList = ForeignFilesNotLikelyAttachmentsFoundInAttachmentsFolder.Take(25).ToList();
|
var outList = ForeignFilesNotLikelyAttachmentsFoundInAttachmentsFolder.Take(25).ToList();
|
||||||
foreach (string s in outList)
|
foreach (string s in outList)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -191,11 +191,11 @@ namespace AyaNova.Biz
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//BACKUP
|
//BACKUP
|
||||||
await CoreJobBackup.DoWorkAsync();
|
await CoreJobBackup.DoWorkAsync();
|
||||||
|
|
||||||
//NOTIFICATIONS
|
//NOTIFICATIONS
|
||||||
await CoreJobNotify.DoWorkAsync();
|
await CoreJobNotify.DoWorkAsync();
|
||||||
await CoreNotificationSweeper.DoWorkAsync();
|
await CoreNotificationSweeper.DoWorkAsync();
|
||||||
|
|
||||||
@@ -249,8 +249,9 @@ namespace AyaNova.Biz
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
log.LogError(ex, "JobsBiz::ProcessJobsAsync unexpected error during processing");
|
var msg = "Server::ProcessJobsAsync unexpected error during processing";
|
||||||
//TODO: notify OPSNOTIFY
|
log.LogError(ex, msg);
|
||||||
|
await NotifyEventProcessor.AddOpsProblemEvent(msg, ex);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace AyaNova.Biz
|
|||||||
//This handles general notification events not requiring a decision or tied to an object that are basically just a immediate message to the user
|
//This handles general notification events not requiring a decision or tied to an object that are basically just a immediate message to the user
|
||||||
//e.g. ops problems, DefaultNotification, NotifyHealthCheck etc
|
//e.g. ops problems, DefaultNotification, NotifyHealthCheck etc
|
||||||
//optional user id to send directly to them
|
//optional user id to send directly to them
|
||||||
internal static async Task AddGeneralNotifyEvent(NotifyEventType eventType, string message, long userId = 0)
|
internal static async Task AddGeneralNotifyEvent(NotifyEventType eventType, string message, Exception except = null, long userId = 0)
|
||||||
{
|
{
|
||||||
log.LogTrace($"AddGeneralNotifyEvent processing: [type:{eventType}, userId:{userId}, message:{message}]");
|
log.LogTrace($"AddGeneralNotifyEvent processing: [type:{eventType}, userId:{userId}, message:{message}]");
|
||||||
#if (DEBUG)
|
#if (DEBUG)
|
||||||
@@ -86,6 +86,11 @@ namespace AyaNova.Biz
|
|||||||
|
|
||||||
//check subscriptions for event and send accordingly to each user
|
//check subscriptions for event and send accordingly to each user
|
||||||
var subs = await ct.NotifySubscription.Where(z => z.EventType == eventType).ToListAsync();
|
var subs = await ct.NotifySubscription.Where(z => z.EventType == eventType).ToListAsync();
|
||||||
|
|
||||||
|
//append exception message if not null
|
||||||
|
if (except != null)
|
||||||
|
message += $"\nException error: {ExceptionUtil.ExtractAllExceptionMessages(except)}";
|
||||||
|
|
||||||
foreach (var sub in subs)
|
foreach (var sub in subs)
|
||||||
{
|
{
|
||||||
//note flag ~SERVER~ means to client to substitute "Server" translation key text instead
|
//note flag ~SERVER~ means to client to substitute "Server" translation key text instead
|
||||||
|
|||||||
@@ -53,9 +53,7 @@ namespace AyaNova.Biz
|
|||||||
{
|
{
|
||||||
|
|
||||||
//Algorithm: For deactivation favor subcontractors first over servicetechs, favor ones that have no login records and finally favor by oldest last login
|
//Algorithm: For deactivation favor subcontractors first over servicetechs, favor ones that have no login records and finally favor by oldest last login
|
||||||
//theory is to catch the least likely to be currently active techs
|
//theory is to catch the least likely to be currently active techs
|
||||||
|
|
||||||
//TODO: notify OPSNOTIFY Notify about each and every tech that is set inactive to bizadmin users
|
|
||||||
|
|
||||||
var NoLoginTechList = await ct.User.Where(z => z.Active == true && z.LastLogin == null && (
|
var NoLoginTechList = await ct.User.Where(z => z.Active == true && z.LastLogin == null && (
|
||||||
z.UserType == UserType.Service ||
|
z.UserType == UserType.Service ||
|
||||||
@@ -65,7 +63,9 @@ namespace AyaNova.Biz
|
|||||||
foreach (User u in NoLoginTechList)
|
foreach (User u in NoLoginTechList)
|
||||||
{
|
{
|
||||||
u.Active = false;
|
u.Active = false;
|
||||||
_log.LogInformation($"User {u.Name} with no prior login automatically set to inactive to free up license");
|
var msg = $"User {u.Name} with no prior login automatically set to inactive to free up downgraded license";
|
||||||
|
await NotifyEventProcessor.AddOpsProblemEvent(msg);
|
||||||
|
_log.LogInformation(msg);
|
||||||
}
|
}
|
||||||
await ct.SaveChangesAsync();
|
await ct.SaveChangesAsync();
|
||||||
|
|
||||||
@@ -89,7 +89,8 @@ namespace AyaNova.Biz
|
|||||||
User dbObject = ct.User.FirstOrDefault(z => z.Id == 1);
|
User dbObject = ct.User.FirstOrDefault(z => z.Id == 1);
|
||||||
dbObject.Password = Hasher.hash(dbObject.Salt, ServerBootConfig.AYANOVA_SET_SUPERUSER_PW);
|
dbObject.Password = Hasher.hash(dbObject.Salt, ServerBootConfig.AYANOVA_SET_SUPERUSER_PW);
|
||||||
ct.SaveChanges();
|
ct.SaveChanges();
|
||||||
//TODO: notify OPSNOTIFY
|
|
||||||
|
NotifyEventProcessor.AddOpsProblemEvent("AYANOVA_SET_SUPERUSER_PW setting was used at most recent server boot to reset SuperUser account password").Wait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,13 +43,17 @@ namespace AyaNova.Biz
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
AyaNova.Api.ControllerHelpers.ApiServerState apiServerState = null;
|
AyaNova.Api.ControllerHelpers.ApiServerState apiServerState = null;
|
||||||
|
string BackupStatusNotification = string.Empty;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
BackupIsRunning = true;
|
BackupIsRunning = true;
|
||||||
|
|
||||||
//LOCK DOWN SERVER
|
//LOCK DOWN SERVER
|
||||||
apiServerState = (AyaNova.Api.ControllerHelpers.ApiServerState)ServiceProviderProvider.Provider.GetService(typeof(AyaNova.Api.ControllerHelpers.ApiServerState));
|
apiServerState = (AyaNova.Api.ControllerHelpers.ApiServerState)ServiceProviderProvider.Provider.GetService(typeof(AyaNova.Api.ControllerHelpers.ApiServerState));
|
||||||
apiServerState.SetClosed("BACKUP RUNNING");
|
apiServerState.SetClosed("BACKUP RUNNING");
|
||||||
await JobsBiz.LogJobAsync(Guid.Empty, $"Starting backup job {(OnDemand ? "manual / on demand" : "scheduled") } ");
|
var jobstartmessage = $"Starting backup job {(OnDemand ? "manual / on demand" : "scheduled") } ";
|
||||||
|
await JobsBiz.LogJobAsync(Guid.Empty, jobstartmessage);
|
||||||
|
BackupStatusNotification = jobstartmessage + "\n";
|
||||||
log.LogDebug("Backup starting");
|
log.LogDebug("Backup starting");
|
||||||
var DemandFileNamePrepend = OnDemand ? "manual-" : string.Empty;
|
var DemandFileNamePrepend = OnDemand ? "manual-" : string.Empty;
|
||||||
//*************
|
//*************
|
||||||
@@ -74,13 +78,16 @@ namespace AyaNova.Biz
|
|||||||
var Result = RunProgram.Run(BackupUtilityCommand, Arguments, log, MAXIMUM_MS_ALLOWED_FOR_PROCESSING);
|
var Result = RunProgram.Run(BackupUtilityCommand, Arguments, log, MAXIMUM_MS_ALLOWED_FOR_PROCESSING);
|
||||||
if (string.IsNullOrWhiteSpace(Result))
|
if (string.IsNullOrWhiteSpace(Result))
|
||||||
{
|
{
|
||||||
log.LogDebug("BACKUP SUCCESSFUL (NO ERROR)");
|
var ms = "Backup of database completed OK";
|
||||||
|
log.LogDebug(ms);
|
||||||
|
BackupStatusNotification += (ms + "\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await JobsBiz.LogJobAsync(Guid.Empty, $"Error during data backup \"{Result}\"");
|
var msg = $"Error during data backup \"{Result}\"";
|
||||||
|
await JobsBiz.LogJobAsync(Guid.Empty, msg);
|
||||||
log.LogError($"BACKUP ERROR: {Result}");
|
log.LogError($"BACKUP ERROR: {Result}");
|
||||||
//TODO: notify OPSNOTIFY
|
await NotifyEventProcessor.AddGeneralNotifyEvent(NotifyEventType.BackupStatus, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
//DO FILE BACKUP IF ATTACHMENTS BACKED UP
|
//DO FILE BACKUP IF ATTACHMENTS BACKED UP
|
||||||
@@ -88,6 +95,10 @@ namespace AyaNova.Biz
|
|||||||
{
|
{
|
||||||
await JobsBiz.LogJobAsync(Guid.Empty, $"Attachments backup starting");
|
await JobsBiz.LogJobAsync(Guid.Empty, $"Attachments backup starting");
|
||||||
FileUtil.BackupAttachments(DemandFileNamePrepend);
|
FileUtil.BackupAttachments(DemandFileNamePrepend);
|
||||||
|
var ms = "Backup of file attachments completed OK";
|
||||||
|
log.LogDebug(ms);
|
||||||
|
BackupStatusNotification += (ms + "\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//PRUNE DATA BACKUP SETS NOT KEPT
|
//PRUNE DATA BACKUP SETS NOT KEPT
|
||||||
@@ -95,7 +106,8 @@ namespace AyaNova.Biz
|
|||||||
FileUtil.DatabaseBackupCleanUp(ServerGlobalOpsSettingsCache.Backup.BackupSetsToKeep);
|
FileUtil.DatabaseBackupCleanUp(ServerGlobalOpsSettingsCache.Backup.BackupSetsToKeep);
|
||||||
|
|
||||||
//v.next - COPY TO ONLINE STORAGE
|
//v.next - COPY TO ONLINE STORAGE
|
||||||
//***************
|
//***************
|
||||||
|
|
||||||
log.LogDebug("Backup completed");
|
log.LogDebug("Backup completed");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -103,7 +115,7 @@ namespace AyaNova.Biz
|
|||||||
await JobsBiz.LogJobAsync(Guid.Empty, "Backup failed with errors:");
|
await JobsBiz.LogJobAsync(Guid.Empty, "Backup failed with errors:");
|
||||||
await JobsBiz.LogJobAsync(Guid.Empty, ExceptionUtil.ExtractAllExceptionMessages(ex));
|
await JobsBiz.LogJobAsync(Guid.Empty, ExceptionUtil.ExtractAllExceptionMessages(ex));
|
||||||
log.LogError(ex, "Backup failed");
|
log.LogError(ex, "Backup failed");
|
||||||
//TODO: notify OPSNOTIFY
|
await NotifyEventProcessor.AddGeneralNotifyEvent(NotifyEventType.BackupStatus, "Backup failed", ex);
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -114,6 +126,7 @@ namespace AyaNova.Biz
|
|||||||
apiServerState.ResumePriorState();
|
apiServerState.ResumePriorState();
|
||||||
BackupIsRunning = false;
|
BackupIsRunning = false;
|
||||||
await JobsBiz.LogJobAsync(Guid.Empty, $"Backup - fully complete, server re-opened");
|
await JobsBiz.LogJobAsync(Guid.Empty, $"Backup - fully complete, server re-opened");
|
||||||
|
await NotifyEventProcessor.AddGeneralNotifyEvent(NotifyEventType.BackupStatus, $"Backup completed server re-opened\nStatus:{BackupStatusNotification}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,16 +3,6 @@ using System.Threading.Tasks;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using AyaNova.Models;
|
using AyaNova.Models;
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Text;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using AyaNova.Util;
|
|
||||||
using AyaNova.Models;
|
|
||||||
|
|
||||||
namespace AyaNova.Biz
|
namespace AyaNova.Biz
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user