From 0230abea790ddb7917ec366ae9b7b87c9038d3c4 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 16 Feb 2018 13:54:35 -0800 Subject: [PATCH] Fix backup loading not getting auto backups --- .../src/DomainContentBackupManager.cpp | 108 +++++++++++------- .../src/DomainContentBackupManager.h | 13 ++- domain-server/src/DomainServer.cpp | 4 +- 3 files changed, 79 insertions(+), 46 deletions(-) diff --git a/domain-server/src/DomainContentBackupManager.cpp b/domain-server/src/DomainContentBackupManager.cpp index 8ea3d2ba90..db924c4e4f 100644 --- a/domain-server/src/DomainContentBackupManager.cpp +++ b/domain-server/src/DomainContentBackupManager.cpp @@ -300,12 +300,7 @@ void DomainContentBackupManager::recoverFromBackup(MiniPromise::Promise promise, }); } -void DomainContentBackupManager::getAllBackupInformation(MiniPromise::Promise promise) { - if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "getAllBackupInformation", Q_ARG(MiniPromise::Promise, promise)); - return; - } - +std::vector DomainContentBackupManager::getAllBackups() { QDir backupDir { _backupDirectory }; auto matchingFiles = backupDir.entryInfoList({ AUTOMATIC_BACKUP_PREFIX + "*.zip", MANUAL_BACKUP_PREFIX + "*.zip" }, @@ -315,7 +310,7 @@ void DomainContentBackupManager::getAllBackupInformation(MiniPromise::Promise pr QString dateTimeFormat = "(" + DATETIME_FORMAT_RE + ")"; QRegExp backupNameFormat { prefixFormat + nameFormat + "-" + dateTimeFormat + "\\.zip" }; - QVariantList backups; + std::vector backups; for (const auto& fileInfo : matchingFiles) { auto fileName = fileInfo.fileName(); @@ -338,17 +333,53 @@ void DomainContentBackupManager::getAllBackupInformation(MiniPromise::Promise pr availabilityProgress += progress / _backupHandlers.size(); } - backups.push_back(QVariantMap({ - { "id", fileInfo.fileName() }, - { "name", name }, - { "createdAtMillis", createdAt.toMSecsSinceEpoch() }, - { "isAvailable", isAvailable }, - { "availabilityProgress", availabilityProgress }, - { "isManualBackup", type == MANUAL_BACKUP_PREFIX } - })); + backups.push_back( + { fileInfo.fileName(), name, fileInfo.absoluteFilePath(), createdAt, type == MANUAL_BACKUP_PREFIX }); } } + return backups; +} + +void DomainContentBackupManager::getAllBackupsAndStatus(MiniPromise::Promise promise) { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "getAllBackupInformation", Q_ARG(MiniPromise::Promise, promise)); + return; + } + + QDir backupDir { _backupDirectory }; + auto matchingFiles = + backupDir.entryInfoList({ AUTOMATIC_BACKUP_PREFIX + "*.zip", MANUAL_BACKUP_PREFIX + "*.zip" }, + QDir::Files | QDir::NoSymLinks, QDir::Name); + QString prefixFormat = "(" + QRegExp::escape(AUTOMATIC_BACKUP_PREFIX) + "|" + QRegExp::escape(MANUAL_BACKUP_PREFIX) + ")"; + QString nameFormat = "(.+)"; + QString dateTimeFormat = "(" + DATETIME_FORMAT_RE + ")"; + QRegExp backupNameFormat { prefixFormat + nameFormat + "-" + dateTimeFormat + "\\.zip" }; + + auto backups = getAllBackups(); + + QVariantList variantBackups; + + for (auto& backup : backups) { + bool isAvailable { true }; + float availabilityProgress { 0.0f }; + for (auto& handler : _backupHandlers) { + bool handlerIsAvailable { true }; + float progress { 0.0f }; + std::tie(handlerIsAvailable, progress) = handler->isAvailable(backup.absolutePath); + isAvailable &= handlerIsAvailable; + availabilityProgress += progress / _backupHandlers.size(); + } + variantBackups.push_back(QVariantMap({ + { "id", backup.id }, + { "name", backup.name }, + { "createdAtMillis", backup.createdAt.toMSecsSinceEpoch() }, + { "isAvailable", isAvailable }, + { "availabilityProgress", availabilityProgress }, + { "isManualBackup", backup.isManualBackup } + })); + } + float recoveryProgress = 0.0f; bool isRecovering = _isRecovering.load(); if (_isRecovering) { @@ -365,7 +396,7 @@ void DomainContentBackupManager::getAllBackupInformation(MiniPromise::Promise pr }; QVariantMap info { - { "backups", backups }, + { "backups", variantBackups }, { "status", status } }; @@ -404,32 +435,27 @@ void DomainContentBackupManager::removeOldBackupVersions(const BackupRule& rule) } void DomainContentBackupManager::load() { - QDir backupDir { _backupDirectory }; - if (backupDir.exists()) { - - auto matchingFiles = backupDir.entryInfoList({ "backup-*.zip" }, QDir::Files | QDir::NoSymLinks, QDir::Name); - - for (const auto& file : matchingFiles) { - QFile backupFile { file.absoluteFilePath() }; - if (!backupFile.open(QIODevice::ReadOnly)) { - qCritical() << "Could not open file:" << file.absoluteFilePath(); - qCritical() << " ERROR:" << backupFile.errorString(); - continue; - } - - QuaZip zip { &backupFile }; - if (!zip.open(QuaZip::mdUnzip)) { - qCritical() << "Could not open backup archive:" << file.absoluteFilePath(); - qCritical() << " ERROR:" << zip.getZipError(); - continue; - } - - for (auto& handler : _backupHandlers) { - handler->loadBackup(zip); - } - - zip.close(); + auto backups = getAllBackups(); + for (auto& backup : backups) { + QFile backupFile{ backup.absolutePath }; + if (!backupFile.open(QIODevice::ReadOnly)) { + qCritical() << "Could not open file:" << backup.absolutePath; + qCritical() << " ERROR:" << backupFile.errorString(); + continue; } + + QuaZip zip{ &backupFile }; + if (!zip.open(QuaZip::mdUnzip)) { + qCritical() << "Could not open backup archive:" << backup.absolutePath; + qCritical() << " ERROR:" << zip.getZipError(); + continue; + } + + for (auto& handler : _backupHandlers) { + handler->loadBackup(zip); + } + + zip.close(); } } diff --git a/domain-server/src/DomainContentBackupManager.h b/domain-server/src/DomainContentBackupManager.h index 4ec3d7bcc7..2cfda4b650 100644 --- a/domain-server/src/DomainContentBackupManager.h +++ b/domain-server/src/DomainContentBackupManager.h @@ -24,6 +24,14 @@ #include +struct BackupItemInfo { + QString id; + QString name; + QString absolutePath; + QDateTime createdAt; + bool isManualBackup; +}; + class DomainContentBackupManager : public GenericThread { Q_OBJECT public: @@ -43,14 +51,13 @@ public: int persistInterval = DEFAULT_PERSIST_INTERVAL, bool debugTimestampNow = false); + std::vector getAllBackups(); void addBackupHandler(BackupHandlerPointer handler); - void aboutToFinish(); /// call this to inform the persist thread that the owner is about to finish to support final persist - void replaceData(QByteArray data); public slots: - void getAllBackupInformation(MiniPromise::Promise promise); + void getAllBackupsAndStatus(MiniPromise::Promise promise); void createManualBackup(MiniPromise::Promise promise, const QString& name); void recoverFromBackup(MiniPromise::Promise promise, const QString& backupName); void deleteBackup(MiniPromise::Promise promise, const QString& backupName); diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index fe145b341b..157eaa483f 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -2128,13 +2128,13 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url return true; } else if (url.path() == URI_API_BACKUPS) { - auto deferred = makePromise("getAllBackupInformation"); + auto deferred = makePromise("getAllBackupsAndStatus"); deferred->then([connection, JSON_MIME_TYPE](QString error, QVariantMap result) { QJsonDocument docJSON(QJsonObject::fromVariantMap(result)); connection->respond(HTTPConnection::StatusCode200, docJSON.toJson(), JSON_MIME_TYPE.toUtf8()); }); - _contentManager->getAllBackupInformation(deferred); + _contentManager->getAllBackupsAndStatus(deferred); return true; } else if (url.path().startsWith(URI_API_BACKUPS_ID)) { auto id = url.path().mid(QString(URI_API_BACKUPS_ID).length());