Skip to content

Commit

Permalink
refactor: improved backup classes to improve testability
Browse files Browse the repository at this point in the history
  • Loading branch information
lewislarsen committed Jul 2, 2024
1 parent 5e27030 commit f906df3
Show file tree
Hide file tree
Showing 12 changed files with 292 additions and 266 deletions.
4 changes: 2 additions & 2 deletions app/Jobs/RunFileBackupTaskJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace App\Jobs;

use App\Services\Backup\Tasks\FileBackup;
use App\Services\Backup\Tasks\FileBackupTask;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
Expand All @@ -24,7 +24,7 @@ public function __construct(public int $backupTaskId)

public function handle(): void
{
$action = new FileBackup;
$action = new FileBackupTask;
$action->handle($this->backupTaskId);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<?php

namespace App\Services\Backup;
namespace app\Services\Backup\Adapters;

use app\Services\Backup\Contracts\SFTPInterface;
use phpseclib3\Net\SFTP;

class SFTPAdapter implements SFTPInterface
Expand Down
5 changes: 3 additions & 2 deletions app/Services/Backup/Backup.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,17 @@
use App\Models\BackupDestination;
use App\Models\BackupTask;
use App\Models\BackupTaskLog;
use app\Services\Backup\Adapters\SFTPAdapter;
use App\Services\Backup\BackupDestinations\Contracts\BackupDestinationInterface;
use App\Services\Backup\BackupDestinations\S3;
use App\Services\Backup\Contracts\BackupDestinationInterface;
use app\Services\Backup\Contracts\SFTPInterface;
use App\Services\Backup\Traits\BackupHelpers;
use Closure;
use DateTime;
use DateTimeZone;
use Exception;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use InvalidArgumentException;
use phpseclib3\Crypt\Common\PrivateKey;
use phpseclib3\Crypt\PublicKeyLoader;
use RuntimeException;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace App\Services\Backup;
namespace app\Services\Backup\Contracts;

use phpseclib3\Net\SFTP;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

declare(strict_types=1);

namespace App\Services\Backup\Contracts;
namespace App\Services\Backup\BackupDestinations\Contracts;

use App\Services\Backup\SFTPInterface;
use app\Services\Backup\Contracts\SFTPInterface;

interface BackupDestinationInterface
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

namespace App\Services\Backup\BackupDestinations;

use App\Services\Backup\Contracts\BackupDestinationInterface;
use App\Services\Backup\SFTPInterface;
use App\Services\Backup\BackupDestinations\Contracts\BackupDestinationInterface;
use app\Services\Backup\Contracts\SFTPInterface;
use App\Services\Backup\Traits\BackupHelpers;
use Aws\Api\DateTimeResult;
use Aws\S3\S3Client;
Expand Down
156 changes: 156 additions & 0 deletions app/Services/Backup/Tasks/AbstractBackupTask.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
<?php

namespace App\Services\Backup\Tasks;

use App\Models\BackupTask as BackupTaskModel;
use App\Models\BackupTaskLog;
use App\Services\Backup\Backup;
use Exception;
use Illuminate\Support\Facades\Log;

abstract class AbstractBackupTask extends Backup
{
/**
* @var BackupTaskModel
*/
protected BackupTaskModel $backupTask;
/**
* @var BackupTaskLog
*/
protected BackupTaskLog $backupTaskLog;
/**
* @var string
*/
protected string $logOutput = '';
/**
* @var float
*/
protected float $scriptRunTime;
/**
* @var int|null
*/
protected ?int $backupSize = null;

/**
* @param int $backupTaskId
*/
public function __construct(int $backupTaskId)
{
parent::__construct();
$this->scriptRunTime = microtime(true);
$this->backupTask = $this->obtainBackupTask($backupTaskId);
}

/**
* @return void
*/
abstract protected function performBackup(): void;

/**
* @return void
* @throws Exception
*/
public function handle(): void
{
Log::info("Starting backup task: {$this->backupTask->id}");

$this->initializeBackup();

try {
$this->performBackup();
$this->finalizeSuccessfulBackup();
} catch (Exception $exception) {
$this->handleBackupFailure($exception);
} finally {
$this->cleanupBackup();
}
}

/**
* @return void
* @throws Exception
*/
protected function initializeBackup(): void
{
$this->backupTask->setScriptUpdateTime();
$this->backupTaskLog = $this->recordBackupTaskLog($this->backupTask->id, $this->logOutput);
$this->updateBackupTaskStatus($this->backupTask, BackupTaskModel::STATUS_RUNNING);
$this->logMessage('Backup task started.');
$this->updateBackupTaskLogOutput($this->backupTaskLog, $this->logOutput);
}

/**
* @return void
* @throws Exception
*/
protected function finalizeSuccessfulBackup(): void
{
$this->logMessage('Backup task has finished successfully!');
$this->backupTaskLog->setSuccessfulTime();
$this->updateBackupTaskLogOutput($this->backupTaskLog, $this->logOutput);
}

/**
* @param Exception $exception
* @return void
*/
protected function handleBackupFailure(Exception $exception): void
{
$this->logOutput .= 'Error in backup process: ' . $exception->getMessage() . "\n";
Log::error("Error in backup process for task {$this->backupTask->id}: " . $exception->getMessage(), ['exception' => $exception]);
}

/**
* @return void
*/
protected function cleanupBackup(): void
{
$this->updateBackupTaskLogOutput($this->backupTaskLog, $this->logOutput);
$this->backupTaskLog->setFinishedTime();
$this->updateBackupTaskStatus($this->backupTask, BackupTaskModel::STATUS_READY);
$this->backupTask->sendNotifications();
$this->backupTask->updateLastRanAt();
$this->backupTask->resetScriptUpdateTime();

$elapsedTime = microtime(true) - $this->scriptRunTime;
$this->backupTask->data()->create([
'duration' => $elapsedTime,
'size' => $this->backupSize,
]);

Log::info("Completed backup task: {$this->backupTask->label} ({$this->backupTask->id}).");
}

/**
* @param string $message
* @param string $timezone
* @return string
* @throws Exception
*/
protected function logWithTimestamp(string $message, string $timezone): string
{
$timestampedMessage = parent::logWithTimestamp($message, $timezone);
$this->logOutput .= $timestampedMessage;
return $timestampedMessage;
}

/**
* @param string $message
* @return void
* @throws Exception
*/
protected function logMessage(string $message): void
{
$this->logWithTimestamp($message, $this->backupTask->user->timezone);
}

/**
* @param string $extension
* @return string
*/
protected function generateBackupFileName(string $extension): string
{
$prefix = $this->backupTask->hasFileNameAppended() ? $this->backupTask->appended_file_name . '_' : '';
return "{$prefix}backup_{$this->backupTask->id}_" . date('YmdHis') . ".{$extension}";
}
}
122 changes: 0 additions & 122 deletions app/Services/Backup/Tasks/DatabaseBackup.php

This file was deleted.

Loading

0 comments on commit f906df3

Please sign in to comment.