This commit is contained in:
2020-05-19 23:54:57 +00:00
parent 337482714d
commit 81270c45de
4 changed files with 104 additions and 47 deletions

View File

@@ -8,7 +8,8 @@
working on: BACKUP finish routes, on demand and download and listing working on: BACKUP finish routes, on demand and download and listing
Then test with actual attachments to ensure it's working for that part as well Then test with actual attachments to ensure it's working for that part as well
Upload backup file so can restore?
only works if we have automated restore which is doubtful at any point
todo: OPS routes (SERVER AND CLIENT) todo: OPS routes (SERVER AND CLIENT)
- Backup, restore https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3369 - Backup, restore https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3369

View File

@@ -1,10 +1,14 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore;
using AyaNova.Models; using AyaNova.Models;
using AyaNova.Api.ControllerHelpers; using AyaNova.Api.ControllerHelpers;
using AyaNova.Biz;
using System.Threading.Tasks;
using AyaNova.Biz;
using Newtonsoft.Json.Linq;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//************************************************************************************************************** */ //************************************************************************************************************** */
@@ -57,21 +61,61 @@ namespace AyaNova.Api.Controllers
serverState = apiServerState; serverState = apiServerState;
} }
/*
LOOKAT:
A backup archive consists of a similar format to the v7 data dumper utility, json file per object in subdirectories corresponding to object type all in a zip archive
Route to trigger restore from selected file /// <summary>
Route to force immediate backup /// Trigger immediate system backup
Backup code in biz objects "IBackup" interface (which in turn is probably going to implement an IExport interface as it serves dual purpose ///
of exporting data, or maybe that's special purpose custom objects for exporting like csv etc since there is likely a graph of data involved) /// </summary>
/// <returns>Job Id</returns>
[HttpPost("backup-now")]
[Authorize]
public async Task<IActionResult> PostServerState()
{
if (serverState.IsClosed)
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
if (!Authorized.HasAnyRole(HttpContext.Items, AuthorizationRoles.OpsAdminFull | AuthorizationRoles.OpsAdminLimited))
return StatusCode(403, new ApiNotAuthorizedResponse());
var JobName = $"Backup (on demand)";
OpsJob j = new OpsJob();
j.Name = JobName;
j.ObjectType = AyaType.NoType;
j.JobType = JobType.Backup;
j.SubType = JobSubType.NotSet;
j.Exclusive = true;
await JobsBiz.AddJobAsync(j, ct);
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.ServerJob, AyaEvent.Created, JobName), ct);
return Accepted(new { JobId = j.GId });
}
#region old shit
/*
LOOKAT:
A backup archive consists of a similar format to the v7 data dumper utility, json file per object in subdirectories corresponding to object type all in a zip archive
Route to trigger restore from selected file
Route to force immediate backup
Backup code in biz objects "IBackup" interface (which in turn is probably going to implement an IExport interface as it serves dual purpose
of exporting data, or maybe that's special purpose custom objects for exporting like csv etc since there is likely a graph of data involved)
- object is exported / backed up to json - object is exported / backed up to json
Restore code in biz objects "IRestore" interface Restore code in biz objects "IRestore" interface
- object(s) imported via restore and data given to them or file or whatever (See discource project) - object(s) imported via restore and data given to them or file or whatever (See discource project)
*/ */
//TODO: Copy the code from ImportAyaNova7Controller upload method instead of this old crap //TODO: Copy the code from ImportAyaNova7Controller upload method instead of this old crap
// /// <summary> // /// <summary>
// /// Upload AyaNova backup files // /// Upload AyaNova backup files
@@ -183,7 +227,7 @@ Restore code in biz objects "IRestore" interface
// } // }
// return mediaType.Encoding; // return mediaType.Encoding;
// } // }
#endregion old shit
}//eoc }//eoc
}//eons }//eons

View File

@@ -407,6 +407,10 @@ namespace AyaNova.Biz
switch (job.JobType) 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(ct, true);
break;
case JobType.TestWidgetJob: case JobType.TestWidgetJob:
o = (IJobObject)BizObjectFactory.GetBizObject(AyaType.Widget, ct); o = (IJobObject)BizObjectFactory.GetBizObject(AyaType.Widget, ct);
break; break;
@@ -422,6 +426,7 @@ namespace AyaNova.Biz
throw new System.NotSupportedException($"ProcessJobAsync type {job.JobType.ToString()} is not supported"); throw new System.NotSupportedException($"ProcessJobAsync type {job.JobType.ToString()} is not supported");
} }
if (o != null)
await o.HandleJobAsync(job); await o.HandleJobAsync(job);
log.LogDebug($"ProcessJobAsync -> Job completed {JobDescription}"); log.LogDebug($"ProcessJobAsync -> Job completed {JobDescription}");
} }

View File

@@ -22,13 +22,15 @@ namespace AyaNova.Biz
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
// //
// //
public static async Task DoWorkAsync(AyContext ct) public static async Task DoWorkAsync(AyContext ct, bool OnDemand = false)
{ {
if (BackupIsRunning) return; if (BackupIsRunning) return;
log.LogTrace("Checking if backup should run");
//get NOW in utc //get NOW in utc
DateTime utcNow = DateTime.UtcNow; DateTime utcNow = DateTime.UtcNow;
if (!OnDemand)
{
log.LogTrace("Checking if backup should run");
//what time should we backup today? //what time should we backup today?
DateTime todayBackupTime = new DateTime(utcNow.Year, utcNow.Month, utcNow.Day, ServerGlobalOpsSettings.BackupTime.Hour, ServerGlobalOpsSettings.BackupTime.Minute, 0, DateTimeKind.Utc);//first start with NOW DateTime todayBackupTime = new DateTime(utcNow.Year, utcNow.Month, utcNow.Day, ServerGlobalOpsSettings.BackupTime.Hour, ServerGlobalOpsSettings.BackupTime.Minute, 0, DateTimeKind.Utc);//first start with NOW
//Are we there yet? //Are we there yet?
@@ -44,23 +46,23 @@ namespace AyaNova.Biz
log.LogTrace("Hasn't been 24 hours since last backup yet"); return;//nope//nope, so we have already run today's backup log.LogTrace("Hasn't been 24 hours since last backup yet"); return;//nope//nope, so we have already run today's backup
} }
//Ok, we're into backup time and it's been more than 24 hours since it last ran so let's do this... //Ok, we're into backup time and it's been more than 24 hours since it last ran so let's do this...
}
AyaNova.Api.ControllerHelpers.ApiServerState apiServerState = null; AyaNova.Api.ControllerHelpers.ApiServerState apiServerState = null;
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 JOB RUNNING"); apiServerState.SetClosed("BACKUP RUNNING");
log.LogDebug("Backup starting"); log.LogDebug("Backup starting");
//************* //*************
//DO DATA BACKUP //DO DATA BACKUP
//build command //build command
//this is valid: //this is valid on windows
//C:\data\code\PostgreSQLPortable_12.0\App\PgSQL\bin\pg_dump --dbname=postgresql://postgres:raven@127.0.0.1:5432/AyaNova -Fc > huge_new.backup //C:\data\code\PostgreSQLPortable_12.0\App\PgSQL\bin\pg_dump --dbname=postgresql://postgres:raven@127.0.0.1:5432/AyaNova -Fc > huge_new.backup
//"AYANOVA_DB_CONNECTION": "Server=localhost;Username=postgres;Password=raven;Database=AyaNova;",
Npgsql.NpgsqlConnectionStringBuilder PostgresConnectionString = new Npgsql.NpgsqlConnectionStringBuilder(ServerBootConfig.AYANOVA_DB_CONNECTION); Npgsql.NpgsqlConnectionStringBuilder PostgresConnectionString = new Npgsql.NpgsqlConnectionStringBuilder(ServerBootConfig.AYANOVA_DB_CONNECTION);
var DBNameParameter = $"--dbname=postgresql://{PostgresConnectionString.Username}:{PostgresConnectionString.Password}@{PostgresConnectionString.Host}:{PostgresConnectionString.Port}/{PostgresConnectionString.Database}"; var DBNameParameter = $"--dbname=postgresql://{PostgresConnectionString.Username}:{PostgresConnectionString.Password}@{PostgresConnectionString.Host}:{PostgresConnectionString.Port}/{PostgresConnectionString.Database}";
@@ -80,6 +82,7 @@ namespace AyaNova.Biz
else else
log.LogError($"BACKUP ERROR: {Result}"); log.LogError($"BACKUP ERROR: {Result}");
//PRUNE DATA BACKUP SETS NOT KEPT //PRUNE DATA BACKUP SETS NOT KEPT
FileUtil.DatabaseBackupCleanUp(ServerGlobalOpsSettings.BackupSetsToKeep); FileUtil.DatabaseBackupCleanUp(ServerGlobalOpsSettings.BackupSetsToKeep);
@@ -96,13 +99,14 @@ namespace AyaNova.Biz
//v.next - COPY TO ONLINE STORAGE //v.next - COPY TO ONLINE STORAGE
//*************** //***************
if (!OnDemand)
{
//Update last backup //Update last backup
var biz = GlobalOpsSettingsBiz.GetBiz(ct); var biz = GlobalOpsSettingsBiz.GetBiz(ct);
var OpSet = await biz.GetAsync(false); var OpSet = await biz.GetAsync(false);
OpSet.LastBackup = utcNow; OpSet.LastBackup = utcNow;
await biz.ReplaceAsync(OpSet); await biz.ReplaceAsync(OpSet);
}
log.LogDebug("Backup completed"); log.LogDebug("Backup completed");
} }
catch (Exception ex) catch (Exception ex)
@@ -116,6 +120,9 @@ namespace AyaNova.Biz
BackupIsRunning = false; BackupIsRunning = false;
} }
} }
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
}//eoc }//eoc
}//eons }//eons