add API to recover from content archive

This commit is contained in:
Stephen Birarda 2018-02-15 11:20:02 -08:00
parent 6f8381d378
commit 2020ce5907
3 changed files with 60 additions and 14 deletions

View file

@ -18,6 +18,7 @@
#include <fstream>
#include <time.h>
#include <QBuffer>
#include <QDateTime>
#include <QDebug>
#include <QDir>
@ -256,6 +257,22 @@ void DomainContentBackupManager::deleteBackup(MiniPromise::Promise promise, cons
});
}
bool DomainContentBackupManager::recoverFromBackupZip(QuaZip& zip, const QString& backupName) {
if (!zip.open(QuaZip::Mode::mdUnzip)) {
qWarning() << "Failed to unzip file: " << zip.getZipName();
return false;
} else {
_isRecovering = true;
for (auto& handler : _backupHandlers) {
handler->recoverBackup(zip);
}
qDebug() << "Successfully started recovering from " << zip.getZipName();
return true;
}
}
void DomainContentBackupManager::recoverFromBackup(MiniPromise::Promise promise, const QString& backupName) {
if (_isRecovering) {
promise->resolve({
@ -277,19 +294,9 @@ void DomainContentBackupManager::recoverFromBackup(MiniPromise::Promise promise,
QFile backupFile { backupDir.filePath(backupName) };
if (backupFile.open(QIODevice::ReadOnly)) {
QuaZip zip { &backupFile };
if (!zip.open(QuaZip::Mode::mdUnzip)) {
qWarning() << "Failed to unzip file: " << backupName;
success = false;
} else {
_isRecovering = true;
_recoveryFilename = backupName;
for (auto& handler : _backupHandlers) {
handler->recoverBackup(zip);
}
qDebug() << "Successfully started recovering from " << backupName;
success = true;
}
success = recoverFromBackupZip(zip, backupName);
backupFile.close();
} else {
success = false;
@ -301,7 +308,28 @@ void DomainContentBackupManager::recoverFromBackup(MiniPromise::Promise promise,
});
}
void DomainContentBackupManager::recoverFromUploadedBackup(MiniPromise::Promise promise, QByteArray uploadedBackup) {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "recoverFromUploadedBackup", Q_ARG(MiniPromise::Promise, promise),
Q_ARG(QByteArray, uploadedBackup));
return;
}
qDebug() << "Recovering from uploaded content archive";
// create a buffer and then a QuaZip from that buffer
QBuffer uploadedBackupBuffer { &uploadedBackup };
QuaZip uploadedZip { &uploadedBackupBuffer };
bool success = recoverFromBackupZip(uploadedZip, MANUAL_BACKUP_PREFIX + "uploaded.zip");
promise->resolve({
{ "success", success }
});
}
std::vector<BackupItemInfo> DomainContentBackupManager::getAllBackups() {
QDir backupDir { _backupDirectory };
auto matchingFiles =
backupDir.entryInfoList({ AUTOMATIC_BACKUP_PREFIX + "*.zip", MANUAL_BACKUP_PREFIX + "*.zip" },

View file

@ -63,6 +63,7 @@ public slots:
void getAllBackupsAndStatus(MiniPromise::Promise promise);
void createManualBackup(MiniPromise::Promise promise, const QString& name);
void recoverFromBackup(MiniPromise::Promise promise, const QString& backupName);
void recoverFromUploadedBackup(MiniPromise::Promise promise, QByteArray uploadedBackup);
void deleteBackup(MiniPromise::Promise promise, const QString& backupName);
void consolidateBackup(MiniPromise::Promise promise, QString fileName);
@ -85,6 +86,8 @@ protected:
std::pair<bool, QString> createBackup(const QString& prefix, const QString& name);
bool recoverFromBackupZip(QuaZip& backupZip, const QString& backupName);
private:
const QString _backupDirectory;
std::vector<BackupHandlerPointer> _backupHandlers;

View file

@ -2273,10 +2273,25 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|| uploadedFilename.endsWith(".json.gz", Qt::CaseInsensitive)) {
// invoke our method to hand the new octree file off to the octree server
QMetaObject::invokeMethod(this, "handleOctreeFileReplacement",
Qt::QueuedConnection, Q_ARG(QByteArray, formData[0].second));
Qt::QueuedConnection, Q_ARG(QByteArray, firstFormData.second));
// respond with a 200 for success
connection->respond(HTTPConnection::StatusCode200);
} else if (uploadedFilename.endsWith(".zip", Qt::CaseInsensitive)) {
auto deferred = makePromise("recoverFromUploadedBackup");
deferred->then([connection, JSON_MIME_TYPE](QString error, QVariantMap result) {
QJsonObject rootJSON;
auto success = result["success"].toBool();
rootJSON["success"] = success;
QJsonDocument docJSON(rootJSON);
connection->respond(success ? HTTPConnection::StatusCode200 : HTTPConnection::StatusCode400, docJSON.toJson(),
JSON_MIME_TYPE.toUtf8());
});
_contentManager->recoverFromUploadedBackup(deferred, firstFormData.second);
return true;
} else {
// we don't have handling for this filetype, send back a 400 for failure
connection->respond(HTTPConnection::StatusCode400);