Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat/autobackupAllFiles #1045

Merged
merged 3 commits into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions TeslaSolarCharger.SharedBackend/Contracts/IConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ public interface IConstants
string FleetApiTokenRequested { get; }
string TokenRefreshUnauthorized { get; }
string TokenMissingScopes { get; }
string BackupZipBaseFileName { get; }
}
1 change: 1 addition & 0 deletions TeslaSolarCharger.SharedBackend/Values/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public class Constants : IConstants
public int MinSocLimit => 50;
public int DefaultOverage => -1000000;
public int MinimumSocDifference => 2;
public string BackupZipBaseFileName => "TSC-Backup.zip";

public string InstallationIdKey => "InstallationId";
public string FleetApiTokenRequested => "FleetApiTokenRequested";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public interface IBaseConfigurationService
Task UpdateBaseConfigurationAsync(DtoBaseConfiguration baseConfiguration);
Task UpdateMaxCombinedCurrent(int? maxCombinedCurrent);
void UpdatePowerBuffer(int powerBuffer);
Task<byte[]> DownloadBackup();
Task<byte[]> DownloadBackup(string backupFileNameSuffix, string? backupZipDestinationDirectory);
Task RestoreBackup(IFormFile file);
Task<string> CreateLocalBackupZipFile(string backupFileNameSuffix, string? backupZipDestinationDirectory);
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public void UpdatePowerBuffer(int powerBuffer) =>
[HttpGet]
public async Task<FileContentResult> DownloadBackup()
{
var bytes = await _service.DownloadBackup().ConfigureAwait(false);
var bytes = await _service.DownloadBackup(string.Empty, null).ConfigureAwait(false);
return File(bytes, "application/zip", "TSCBackup.zip");
}

Expand Down
2 changes: 0 additions & 2 deletions TeslaSolarCharger/Server/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@

try
{


var baseConfigurationConverter = app.Services.GetRequiredService<IBaseConfigurationConverter>();
await baseConfigurationConverter.ConvertAllEnvironmentVariables().ConfigureAwait(false);
await baseConfigurationConverter.ConvertBaseConfigToV1_0().ConfigureAwait(false);
Expand Down
10 changes: 8 additions & 2 deletions TeslaSolarCharger/Server/Scheduling/JobManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class JobManager
private readonly IConfigurationWrapper _configurationWrapper;
private readonly IDateTimeProvider _dateTimeProvider;

private IScheduler _scheduler;
private IScheduler? _scheduler;


#pragma warning disable CS8618
Expand Down Expand Up @@ -103,9 +103,15 @@ public async Task StartJobs()
await _scheduler.Start().ConfigureAwait(false);
}

public async Task StopJobs()
public async Task<bool> StopJobs()
{
_logger.LogTrace("{method}()", nameof(StopJobs));
if (_scheduler == null)
{
_logger.LogInformation("Jobs were not running, yet, so stop is not needed.");
return false;
}
await _scheduler.Shutdown(true).ConfigureAwait(false);
return true;
}
}
57 changes: 36 additions & 21 deletions TeslaSolarCharger/Server/Services/BaseConfigurationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using TeslaSolarCharger.Shared.Dtos.BaseConfiguration;
using TeslaSolarCharger.Shared.Dtos.Contracts;
using TeslaSolarCharger.Shared.Enums;
using TeslaSolarCharger.SharedBackend.Contracts;

namespace TeslaSolarCharger.Server.Services;

Expand All @@ -21,10 +22,12 @@ public class BaseConfigurationService : IBaseConfigurationService
private readonly ISettings _settings;
private readonly IPvValueService _pvValueService;
private readonly IDbConnectionStringHelper _dbConnectionStringHelper;
private readonly IConstants _constants;

public BaseConfigurationService(ILogger<BaseConfigurationService> logger, IConfigurationWrapper configurationWrapper,
JobManager jobManager, ITeslaMateMqttService teslaMateMqttService, ISolarMqttService solarMqttService,
ISettings settings, IPvValueService pvValueService, IDbConnectionStringHelper dbConnectionStringHelper)
ISettings settings, IPvValueService pvValueService, IDbConnectionStringHelper dbConnectionStringHelper,
IConstants constants)
{
_logger = logger;
_configurationWrapper = configurationWrapper;
Expand All @@ -34,12 +37,13 @@ public BaseConfigurationService(ILogger<BaseConfigurationService> logger, IConfi
_settings = settings;
_pvValueService = pvValueService;
_dbConnectionStringHelper = dbConnectionStringHelper;
_constants = constants;
}

public async Task UpdateBaseConfigurationAsync(DtoBaseConfiguration baseConfiguration)
{
_logger.LogTrace("{method}({@baseConfiguration})", nameof(UpdateBaseConfigurationAsync), baseConfiguration);
await _jobManager.StopJobs().ConfigureAwait(false);
var restartNeeded = await _jobManager.StopJobs().ConfigureAwait(false);
await _configurationWrapper.UpdateBaseConfigurationAsync(baseConfiguration).ConfigureAwait(false);
await _teslaMateMqttService.ConnectMqttClient().ConfigureAwait(false);
await _solarMqttService.ConnectMqttClient().ConfigureAwait(false);
Expand All @@ -61,7 +65,10 @@ public async Task UpdateBaseConfigurationAsync(DtoBaseConfiguration baseConfigur
}
_settings.PowerBuffer = null;

await _jobManager.StartJobs().ConfigureAwait(false);
if (restartNeeded)
{
await _jobManager.StartJobs().ConfigureAwait(false);
}
}

public async Task UpdateMaxCombinedCurrent(int? maxCombinedCurrent)
Expand All @@ -76,12 +83,19 @@ public void UpdatePowerBuffer(int powerBuffer)
_settings.PowerBuffer = powerBuffer;
}

public async Task<byte[]> DownloadBackup()
public async Task<byte[]> DownloadBackup(string backupFileNameSuffix, string? backupZipDestinationDirectory)
{
var destinationArchiveFileName = await CreateLocalBackupZipFile(backupFileNameSuffix, backupZipDestinationDirectory).ConfigureAwait(false);
var bytes = await File.ReadAllBytesAsync(destinationArchiveFileName).ConfigureAwait(false);
return bytes;
}

public async Task<string> CreateLocalBackupZipFile(string backupFileNameSuffix, string? backupZipDestinationDirectory)
{
var restartNeeded = false;
try
{
await _jobManager.StopJobs().ConfigureAwait(false);

restartNeeded = await _jobManager.StopJobs().ConfigureAwait(false);
var backupCopyDestinationDirectory = _configurationWrapper.BackupCopyDestinationDirectory();
CreateEmptyDirectory(backupCopyDestinationDirectory);

Expand All @@ -99,40 +113,38 @@ public async Task<byte[]> DownloadBackup()
File.Copy(baseConfigFileFullName, Path.Combine(backupCopyDestinationDirectory, Path.GetFileName(baseConfigFileFullName)), true);


var backupFileName = "TSC-Backup.zip";
var backupZipDirectory = _configurationWrapper.BackupZipDirectory();
if(Directory.Exists(backupZipDirectory))
var backupFileName = _constants.BackupZipBaseFileName + backupFileNameSuffix;
var backupZipDirectory = backupZipDestinationDirectory ?? _configurationWrapper.BackupZipDirectory();
if (Directory.Exists(backupZipDirectory))
{
Directory.Delete(backupZipDirectory, true);
}
Directory.CreateDirectory(backupZipDirectory);
var destinationArchiveFileName = Path.Combine(backupZipDirectory, backupFileName);
ZipFile.CreateFromDirectory(backupCopyDestinationDirectory, destinationArchiveFileName);
var bytes = await File.ReadAllBytesAsync(destinationArchiveFileName).ConfigureAwait(false);
return bytes;
return destinationArchiveFileName;
}
catch (Exception ex)
{
_logger.LogError(ex, "Couldn't download backup");
_logger.LogError(ex, "Couldn't create backup zip file");
throw;
}
finally
{
await _jobManager.StartJobs().ConfigureAwait(false);
if (restartNeeded)
{
await _jobManager.StartJobs().ConfigureAwait(false);
}
}



}


public async Task RestoreBackup(IFormFile file)
{
_logger.LogTrace("{method}({file})", nameof(RestoreBackup), file.FileName);
var jobsWereRunning = await _jobManager.StopJobs().ConfigureAwait(false);
try
{
await _jobManager.StopJobs().ConfigureAwait(false);

var restoreTempDirectory = _configurationWrapper.RestoreTempDirectory();
CreateEmptyDirectory(restoreTempDirectory);
var restoreFileName = "TSC-Restore.zip";
Expand All @@ -158,7 +170,10 @@ public async Task RestoreBackup(IFormFile file)
}
finally
{
await _jobManager.StartJobs().ConfigureAwait(false);
if (jobsWereRunning)
{
await _jobManager.StartJobs().ConfigureAwait(false);
}
}
}

Expand All @@ -172,7 +187,7 @@ private static void CreateEmptyDirectory(string path)
Directory.CreateDirectory(path);
}

public void CopyFiles(string sourceDir, string targetDir)
private void CopyFiles(string sourceDir, string targetDir)
{
// Create the target directory if it doesn't already exist
Directory.CreateDirectory(targetDir);
Expand Down
37 changes: 15 additions & 22 deletions TeslaSolarCharger/Server/Services/CoreService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using TeslaSolarCharger.Shared.Contracts;
using TeslaSolarCharger.Shared.Dtos;
using TeslaSolarCharger.Shared.Dtos.Contracts;
using TeslaSolarCharger.SharedBackend.Contracts;

namespace TeslaSolarCharger.Server.Services;

Expand All @@ -26,11 +27,14 @@ public class CoreService : ICoreService
private readonly ISettings _settings;
private readonly IFixedPriceService _fixedPriceService;
private readonly ITscConfigurationService _tscConfigurationService;
private readonly IBaseConfigurationService _baseConfigurationService;
private readonly IConstants _constants;

public CoreService(ILogger<CoreService> logger, IChargingService chargingService, IConfigurationWrapper configurationWrapper,
IDateTimeProvider dateTimeProvider, IConfigJsonService configJsonService, JobManager jobManager,
ITeslaMateMqttService teslaMateMqttService, ISolarMqttService solarMqttService, ISettings settings,
IFixedPriceService fixedPriceService, ITscConfigurationService tscConfigurationService)
IFixedPriceService fixedPriceService, ITscConfigurationService tscConfigurationService, IBaseConfigurationService baseConfigurationService,
IConstants constants)
{
_logger = logger;
_chargingService = chargingService;
Expand All @@ -43,6 +47,8 @@ public CoreService(ILogger<CoreService> logger, IChargingService chargingService
_settings = settings;
_fixedPriceService = fixedPriceService;
_tscConfigurationService = tscConfigurationService;
_baseConfigurationService = baseConfigurationService;
_constants = constants;
}

public Task<string?> GetCurrentVersion()
Expand Down Expand Up @@ -95,33 +101,20 @@ public async Task BackupDatabaseIfNeeded()
return;
}

var databaseFileName = _configurationWrapper.SqliteFileFullName();
if (!File.Exists(databaseFileName))
var destinationPath = _configurationWrapper.AutoBackupsZipDirectory();
if (!Directory.Exists(destinationPath))
{
_logger.LogWarning("Database file does not exist. Backup is not created.");
return;
Directory.CreateDirectory(destinationPath);
}
var backupFileNameSuffix = $"_{currentVersion}";

var resultFileName = GenerateResultFileName(databaseFileName, currentVersion);
if (File.Exists(resultFileName))
var resultingFileName = Path.Combine(destinationPath, $"{_constants.BackupZipBaseFileName + backupFileNameSuffix}");
if (File.Exists(resultingFileName))
{
_logger.LogInformation("Database before upgrade to current version already backed up.");
_logger.LogInformation("Backup for this version already created. No new backup needed.");
return;
}

File.Copy(databaseFileName, resultFileName, true);

var shmFileName = databaseFileName + "-shm";
if (File.Exists(shmFileName))
{
File.Copy(shmFileName, GenerateResultFileName(shmFileName, currentVersion), true);
}

var walFileName = databaseFileName + "-wal";
if (File.Exists(walFileName))
{
File.Copy(walFileName, GenerateResultFileName(walFileName, currentVersion), true);
}
await _baseConfigurationService.CreateLocalBackupZipFile(backupFileNameSuffix, destinationPath).ConfigureAwait(false);
}

private string GenerateResultFileName(string databaseFileName, string currentVersion)
Expand Down
1 change: 1 addition & 0 deletions TeslaSolarCharger/Server/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"ConfigFileLocation": "configs",
"BackupCopyDestinationDirectory": "backups",
"BackupZipDirectory": "backupZips",
"AutoBackupZipDirectory": "autoBackupZips",
"RestoreTempDirectory": "restores",
"CarConfigFilename": "carConfig.json",
"BaseConfigFileName": "baseConfig.json",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,5 @@ public interface IConfigurationWrapper
bool UseFleetApiProxy();
string RestoreTempDirectory();
string ConfigFileDirectory();
string AutoBackupsZipDirectory();
}
9 changes: 9 additions & 0 deletions TeslaSolarCharger/Shared/Wrappers/ConfigurationWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@
return Path.Combine(configFileDirectory, value);
}

public string AutoBackupsZipDirectory()
{
var configFileDirectory = ConfigFileDirectory();
var environmentVariableName = "AutoBackupZipDirectory";
var value = GetNotNullableConfigurationValue<string>(environmentVariableName);
logger.LogTrace("Config value extracted: [{key}]: {value}", environmentVariableName, value);
return Path.Combine(configFileDirectory, value);
}

public string RestoreTempDirectory()
{
var configFileDirectory = ConfigFileDirectory();
Expand Down Expand Up @@ -131,7 +140,7 @@
{
var environmentVariableName = "BackendApiBaseUrl";
var value = configuration.GetValue<string>(environmentVariableName);
return value;

Check warning on line 143 in TeslaSolarCharger/Shared/Wrappers/ConfigurationWrapper.cs

View workflow job for this annotation

GitHub Actions / Building TeslaSolarCharger image

Possible null reference return.
}

public bool IsDevelopmentEnvironment()
Expand Down
Loading