mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 11:58:10 +02:00
Merge pull request #12420 from birarda/feat/content-settings-backup-handler
Add a content settings backup handler
This commit is contained in:
commit
f67931c936
9 changed files with 156 additions and 17 deletions
66
domain-server/src/ContentSettingsBackupHandler.cpp
Normal file
66
domain-server/src/ContentSettingsBackupHandler.cpp
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
//
|
||||||
|
// ContentSettingsBackupHandler.cpp
|
||||||
|
// domain-server/src
|
||||||
|
//
|
||||||
|
// Created by Stephen Birarda on 2/15/18.
|
||||||
|
// Copyright 2018 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "ContentSettingsBackupHandler.h"
|
||||||
|
|
||||||
|
#include <quazip5/quazip.h>
|
||||||
|
#include <quazip5/quazipfile.h>
|
||||||
|
|
||||||
|
ContentSettingsBackupHandler::ContentSettingsBackupHandler(DomainServerSettingsManager& domainServerSettingsManager) :
|
||||||
|
_settingsManager(domainServerSettingsManager)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static const QString CONTENT_SETTINGS_BACKUP_FILENAME = "content-settings.json";
|
||||||
|
|
||||||
|
void ContentSettingsBackupHandler::createBackup(QuaZip& zip) {
|
||||||
|
|
||||||
|
// grab the content settings as JSON,excluding default values and values hidden from backup
|
||||||
|
QJsonObject contentSettingsJSON = _settingsManager.settingsResponseObjectForType("", true, false, true, false, true);
|
||||||
|
|
||||||
|
// make a QJSonDocument using the object
|
||||||
|
QJsonDocument contentSettingsDocument { contentSettingsJSON };
|
||||||
|
|
||||||
|
QuaZipFile zipFile { &zip };
|
||||||
|
|
||||||
|
zipFile.open(QIODevice::WriteOnly, QuaZipNewInfo(CONTENT_SETTINGS_BACKUP_FILENAME));
|
||||||
|
zipFile.write(contentSettingsDocument.toJson());
|
||||||
|
zipFile.close();
|
||||||
|
|
||||||
|
if (zipFile.getZipError() != UNZ_OK) {
|
||||||
|
qCritical().nospace() << "Failed to zip " << CONTENT_SETTINGS_BACKUP_FILENAME << ": " << zipFile.getZipError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContentSettingsBackupHandler::recoverBackup(QuaZip& zip) {
|
||||||
|
if (!zip.setCurrentFile(CONTENT_SETTINGS_BACKUP_FILENAME)) {
|
||||||
|
qWarning() << "Failed to find" << CONTENT_SETTINGS_BACKUP_FILENAME << "while recovering backup";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QuaZipFile zipFile { &zip };
|
||||||
|
if (!zipFile.open(QIODevice::ReadOnly)) {
|
||||||
|
qCritical() << "Failed to open" << CONTENT_SETTINGS_BACKUP_FILENAME << "in backup";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto rawData = zipFile.readAll();
|
||||||
|
zipFile.close();
|
||||||
|
|
||||||
|
QJsonDocument jsonDocument = QJsonDocument::fromJson(rawData);
|
||||||
|
|
||||||
|
if (!_settingsManager.restoreSettingsFromObject(jsonDocument.object(), ContentSettings)) {
|
||||||
|
qCritical() << "Failed to restore settings from" << CONTENT_SETTINGS_BACKUP_FILENAME << "in content archive";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
35
domain-server/src/ContentSettingsBackupHandler.h
Normal file
35
domain-server/src/ContentSettingsBackupHandler.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
//
|
||||||
|
// ContentSettingsBackupHandler.h
|
||||||
|
// domain-server/src
|
||||||
|
//
|
||||||
|
// Created by Stephen Birarda on 2/15/18.
|
||||||
|
// Copyright 2018 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_ContentSettingsBackupHandler_h
|
||||||
|
#define hifi_ContentSettingsBackupHandler_h
|
||||||
|
|
||||||
|
#include "BackupHandler.h"
|
||||||
|
#include "DomainServerSettingsManager.h"
|
||||||
|
|
||||||
|
class ContentSettingsBackupHandler : public BackupHandlerInterface {
|
||||||
|
public:
|
||||||
|
ContentSettingsBackupHandler(DomainServerSettingsManager& domainServerSettingsManager);
|
||||||
|
|
||||||
|
void loadBackup(QuaZip& zip) {};
|
||||||
|
|
||||||
|
void createBackup(QuaZip& zip);
|
||||||
|
|
||||||
|
void recoverBackup(QuaZip& zip);
|
||||||
|
|
||||||
|
void deleteBackup(QuaZip& zip) {};
|
||||||
|
|
||||||
|
void consolidateBackup(QuaZip& zip) {};
|
||||||
|
private:
|
||||||
|
DomainServerSettingsManager& _settingsManager;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_ContentSettingsBackupHandler_h
|
|
@ -155,9 +155,6 @@ bool DomainContentBackupManager::process() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DomainContentBackupManager::aboutToFinish() {
|
void DomainContentBackupManager::aboutToFinish() {
|
||||||
qCDebug(domain_server) << "Persist thread about to finish...";
|
|
||||||
backup();
|
|
||||||
qCDebug(domain_server) << "Persist thread done with about to finish...";
|
|
||||||
_stopThread = true;
|
_stopThread = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include <StatTracker.h>
|
#include <StatTracker.h>
|
||||||
|
|
||||||
#include "AssetsBackupHandler.h"
|
#include "AssetsBackupHandler.h"
|
||||||
|
#include "ContentSettingsBackupHandler.h"
|
||||||
#include "DomainServerNodeData.h"
|
#include "DomainServerNodeData.h"
|
||||||
#include "EntitiesBackupHandler.h"
|
#include "EntitiesBackupHandler.h"
|
||||||
#include "NodeConnectionData.h"
|
#include "NodeConnectionData.h"
|
||||||
|
@ -297,8 +298,13 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
||||||
maybeHandleReplacementEntityFile();
|
maybeHandleReplacementEntityFile();
|
||||||
|
|
||||||
_contentManager.reset(new DomainContentBackupManager(getContentBackupDir(), _settingsManager.settingsResponseObjectForType("6")["entity_server_settings"].toObject()));
|
_contentManager.reset(new DomainContentBackupManager(getContentBackupDir(), _settingsManager.settingsResponseObjectForType("6")["entity_server_settings"].toObject()));
|
||||||
_contentManager->addBackupHandler(BackupHandlerPointer(new EntitiesBackupHandler(getEntitiesFilePath(), getEntitiesReplacementFilePath())));
|
|
||||||
_contentManager->addBackupHandler(BackupHandlerPointer(new AssetsBackupHandler(getContentBackupDir())));
|
connect(_contentManager.get(), &DomainContentBackupManager::started, _contentManager.get(), [this](){
|
||||||
|
_contentManager->addBackupHandler(BackupHandlerPointer(new EntitiesBackupHandler(getEntitiesFilePath(), getEntitiesReplacementFilePath())));
|
||||||
|
_contentManager->addBackupHandler(BackupHandlerPointer(new AssetsBackupHandler(getContentBackupDir())));
|
||||||
|
_contentManager->addBackupHandler(BackupHandlerPointer(new ContentSettingsBackupHandler(_settingsManager)));
|
||||||
|
});
|
||||||
|
|
||||||
_contentManager->initialize(true);
|
_contentManager->initialize(true);
|
||||||
|
|
||||||
qDebug() << "Existing backups:";
|
qDebug() << "Existing backups:";
|
||||||
|
@ -380,7 +386,7 @@ DomainServer::~DomainServer() {
|
||||||
|
|
||||||
if (_contentManager) {
|
if (_contentManager) {
|
||||||
_contentManager->aboutToFinish();
|
_contentManager->aboutToFinish();
|
||||||
_contentManager->terminating();
|
_contentManager->terminate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <QtCore/QJsonArray>
|
#include <QtCore/QJsonArray>
|
||||||
#include <QtCore/QJsonObject>
|
#include <QtCore/QJsonObject>
|
||||||
#include <QtCore/QStandardPaths>
|
#include <QtCore/QStandardPaths>
|
||||||
|
#include <QtCore/QThread>
|
||||||
#include <QtCore/QUrl>
|
#include <QtCore/QUrl>
|
||||||
#include <QtCore/QUrlQuery>
|
#include <QtCore/QUrlQuery>
|
||||||
|
|
||||||
|
@ -32,6 +33,8 @@
|
||||||
#include <SettingHelpers.h>
|
#include <SettingHelpers.h>
|
||||||
#include <AvatarData.h> //for KillAvatarReason
|
#include <AvatarData.h> //for KillAvatarReason
|
||||||
#include <FingerprintUtils.h>
|
#include <FingerprintUtils.h>
|
||||||
|
#include <shared/QtHelpers.h>
|
||||||
|
|
||||||
#include "DomainServerNodeData.h"
|
#include "DomainServerNodeData.h"
|
||||||
|
|
||||||
const QString SETTINGS_DESCRIPTION_RELATIVE_PATH = "/resources/describe-settings.json";
|
const QString SETTINGS_DESCRIPTION_RELATIVE_PATH = "/resources/describe-settings.json";
|
||||||
|
@ -1196,6 +1199,17 @@ bool DomainServerSettingsManager::handleAuthenticatedHTTPRequest(HTTPConnection
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DomainServerSettingsManager::restoreSettingsFromObject(QJsonObject settingsToRestore, SettingsType settingsType) {
|
bool DomainServerSettingsManager::restoreSettingsFromObject(QJsonObject settingsToRestore, SettingsType settingsType) {
|
||||||
|
|
||||||
|
if (thread() != QThread::currentThread()) {
|
||||||
|
bool success;
|
||||||
|
|
||||||
|
BLOCKING_INVOKE_METHOD(this, "restoreSettingsFromObject",
|
||||||
|
Q_RETURN_ARG(bool, success),
|
||||||
|
Q_ARG(QJsonObject, settingsToRestore),
|
||||||
|
Q_ARG(SettingsType, settingsType));
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
QJsonArray& filteredDescriptionArray = settingsType == DomainSettings
|
QJsonArray& filteredDescriptionArray = settingsType == DomainSettings
|
||||||
? _domainSettingsDescription : _contentSettingsDescription;
|
? _domainSettingsDescription : _contentSettingsDescription;
|
||||||
|
|
||||||
|
@ -1321,6 +1335,20 @@ QJsonObject DomainServerSettingsManager::settingsResponseObjectForType(const QSt
|
||||||
bool includeDefaults, bool isForBackup) {
|
bool includeDefaults, bool isForBackup) {
|
||||||
QJsonObject responseObject;
|
QJsonObject responseObject;
|
||||||
|
|
||||||
|
if (thread() != QThread::currentThread()) {
|
||||||
|
|
||||||
|
BLOCKING_INVOKE_METHOD(this, "settingsResponseObjectForType",
|
||||||
|
Q_RETURN_ARG(QJsonObject, responseObject),
|
||||||
|
Q_ARG(const QString&, typeValue),
|
||||||
|
Q_ARG(bool, isAuthenticated),
|
||||||
|
Q_ARG(bool, includeDomainSettings),
|
||||||
|
Q_ARG(bool, includeContentSettings),
|
||||||
|
Q_ARG(bool, includeDefaults),
|
||||||
|
Q_ARG(bool, isForBackup));
|
||||||
|
|
||||||
|
return responseObject;
|
||||||
|
}
|
||||||
|
|
||||||
if (!typeValue.isEmpty() || isAuthenticated) {
|
if (!typeValue.isEmpty() || isAuthenticated) {
|
||||||
// convert the string type value to a QJsonValue
|
// convert the string type value to a QJsonValue
|
||||||
QJsonValue queryType = typeValue.isEmpty() ? QJsonValue() : QJsonValue(typeValue.toInt());
|
QJsonValue queryType = typeValue.isEmpty() ? QJsonValue() : QJsonValue(typeValue.toInt());
|
||||||
|
|
|
@ -111,6 +111,13 @@ public:
|
||||||
|
|
||||||
void debugDumpGroupsState();
|
void debugDumpGroupsState();
|
||||||
|
|
||||||
|
/// thread safe method to retrieve a JSON representation of settings
|
||||||
|
Q_INVOKABLE QJsonObject settingsResponseObjectForType(const QString& typeValue, bool isAuthenticated = false,
|
||||||
|
bool includeDomainSettings = true, bool includeContentSettings = true,
|
||||||
|
bool includeDefaults = true, bool isForBackup = false);
|
||||||
|
/// thread safe method to restore settings from a JSON object
|
||||||
|
Q_INVOKABLE bool restoreSettingsFromObject(QJsonObject settingsToRestore, SettingsType settingsType);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void updateNodePermissions();
|
void updateNodePermissions();
|
||||||
void settingsUpdated();
|
void settingsUpdated();
|
||||||
|
@ -130,9 +137,6 @@ private:
|
||||||
QStringList _argumentList;
|
QStringList _argumentList;
|
||||||
|
|
||||||
QJsonArray filteredDescriptionArray(bool isContentSettings);
|
QJsonArray filteredDescriptionArray(bool isContentSettings);
|
||||||
QJsonObject settingsResponseObjectForType(const QString& typeValue, bool isAuthenticated = false,
|
|
||||||
bool includeDomainSettings = true, bool includeContentSettings = true,
|
|
||||||
bool includeDefaults = true, bool isForBackup = false);
|
|
||||||
bool recurseJSONObjectAndOverwriteSettings(const QJsonObject& postedObject, SettingsType settingsType);
|
bool recurseJSONObjectAndOverwriteSettings(const QJsonObject& postedObject, SettingsType settingsType);
|
||||||
|
|
||||||
void updateSetting(const QString& key, const QJsonValue& newValue, QVariantMap& settingMap,
|
void updateSetting(const QString& key, const QJsonValue& newValue, QVariantMap& settingMap,
|
||||||
|
@ -143,8 +147,6 @@ private:
|
||||||
|
|
||||||
void splitSettingsDescription();
|
void splitSettingsDescription();
|
||||||
|
|
||||||
bool restoreSettingsFromObject(QJsonObject settingsToRestore, SettingsType settingsType);
|
|
||||||
|
|
||||||
double _descriptionVersion;
|
double _descriptionVersion;
|
||||||
|
|
||||||
QJsonArray _descriptionArray;
|
QJsonArray _descriptionArray;
|
||||||
|
|
|
@ -24,28 +24,30 @@ EntitiesBackupHandler::EntitiesBackupHandler(QString entitiesFilePath, QString e
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const QString ENTITIES_BACKUP_FILENAME = "models.json.gz";
|
||||||
|
|
||||||
void EntitiesBackupHandler::createBackup(QuaZip& zip) {
|
void EntitiesBackupHandler::createBackup(QuaZip& zip) {
|
||||||
QFile entitiesFile { _entitiesFilePath };
|
QFile entitiesFile { _entitiesFilePath };
|
||||||
|
|
||||||
if (entitiesFile.open(QIODevice::ReadOnly)) {
|
if (entitiesFile.open(QIODevice::ReadOnly)) {
|
||||||
QuaZipFile zipFile { &zip };
|
QuaZipFile zipFile { &zip };
|
||||||
zipFile.open(QIODevice::WriteOnly, QuaZipNewInfo("models.json.gz", _entitiesFilePath));
|
zipFile.open(QIODevice::WriteOnly, QuaZipNewInfo(ENTITIES_BACKUP_FILENAME, _entitiesFilePath));
|
||||||
zipFile.write(entitiesFile.readAll());
|
zipFile.write(entitiesFile.readAll());
|
||||||
zipFile.close();
|
zipFile.close();
|
||||||
if (zipFile.getZipError() != UNZ_OK) {
|
if (zipFile.getZipError() != UNZ_OK) {
|
||||||
qCritical() << "Failed to zip models.json.gz: " << zipFile.getZipError();
|
qCritical().nospace() << "Failed to zip " << ENTITIES_BACKUP_FILENAME << ": " << zipFile.getZipError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntitiesBackupHandler::recoverBackup(QuaZip& zip) {
|
void EntitiesBackupHandler::recoverBackup(QuaZip& zip) {
|
||||||
if (!zip.setCurrentFile("models.json.gz")) {
|
if (!zip.setCurrentFile(ENTITIES_BACKUP_FILENAME)) {
|
||||||
qWarning() << "Failed to find models.json.gz while recovering backup";
|
qWarning() << "Failed to find" << ENTITIES_BACKUP_FILENAME << "while recovering backup";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QuaZipFile zipFile { &zip };
|
QuaZipFile zipFile { &zip };
|
||||||
if (!zipFile.open(QIODevice::ReadOnly)) {
|
if (!zipFile.open(QIODevice::ReadOnly)) {
|
||||||
qCritical() << "Failed to open models.json.gz in backup";
|
qCritical() << "Failed to open" << ENTITIES_BACKUP_FILENAME << "in backup";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto rawData = zipFile.readAll();
|
auto rawData = zipFile.readAll();
|
||||||
|
@ -61,7 +63,7 @@ void EntitiesBackupHandler::recoverBackup(QuaZip& zip) {
|
||||||
data.resetIdAndVersion();
|
data.resetIdAndVersion();
|
||||||
|
|
||||||
if (zipFile.getZipError() != UNZ_OK) {
|
if (zipFile.getZipError() != UNZ_OK) {
|
||||||
qCritical() << "Failed to unzip models.json.gz: " << zipFile.getZipError();
|
qCritical().nospace() << "Failed to unzip " << ENTITIES_BACKUP_FILENAME << ": " << zipFile.getZipError();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,8 @@ void GenericThread::initialize(bool isThreaded, QThread::Priority priority) {
|
||||||
_thread->setObjectName(objectName());
|
_thread->setObjectName(objectName());
|
||||||
|
|
||||||
// when the worker thread is started, call our engine's run..
|
// when the worker thread is started, call our engine's run..
|
||||||
|
|
||||||
|
connect(_thread, &QThread::started, this, &GenericThread::started);
|
||||||
connect(_thread, &QThread::started, this, &GenericThread::threadRoutine);
|
connect(_thread, &QThread::started, this, &GenericThread::threadRoutine);
|
||||||
connect(_thread, &QThread::finished, this, &GenericThread::finished);
|
connect(_thread, &QThread::finished, this, &GenericThread::finished);
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ public slots:
|
||||||
void threadRoutine();
|
void threadRoutine();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void started();
|
||||||
void finished();
|
void finished();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
Loading…
Reference in a new issue