mirror of
https://gitlab.com/spaceti-app/integrations/acs/colnod-connector.git
synced 2026-07-12 14:20:46 +02:00
Fix memory leaks and add error handling
This commit is contained in:
parent
8d6dc6714c
commit
8f16ac06a6
@ -1,7 +1,7 @@
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include "datamanager.h"
|
||||
#include "colnodapi.h"
|
||||
#include "syncmanager.h"
|
||||
#include <QCommandLineParser>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@ -15,15 +15,19 @@ int main(int argc, char *argv[])
|
||||
QCommandLineOption dryModeOption("dryMode", "ColnodAPI", "Read-only mode, prints changes which would normally be made");
|
||||
parser.addOption(dryModeOption);
|
||||
parser.process(app);
|
||||
auto *api = new ColnodAPI(parser.isSet(dryModeOption));
|
||||
api->loadDataFromDB();
|
||||
api->loadDataFromColnod();
|
||||
QObject::connect(api, &ColnodAPI::dataDownloaded, [=](){
|
||||
api->syncDataFromColnodToDB();
|
||||
api->syncDataFromDBToColnod();
|
||||
QObject::connect(api, &ColnodAPI::syncFinished, [=](){
|
||||
SyncManager api(parser.isSet(dryModeOption));
|
||||
api.loadDataFromDB();
|
||||
api.loadDataFromColnod();
|
||||
QObject::connect(&api, &SyncManager::dataDownloaded, [&](){
|
||||
api.syncDataFromColnodToDB();
|
||||
api.syncDataFromDBToColnod();
|
||||
QObject::connect(&api, &SyncManager::syncFinished, [](){
|
||||
qDebug() << "Quit";
|
||||
QCoreApplication::exit();
|
||||
});
|
||||
});
|
||||
QObject::connect(&api, &SyncManager::error, [](){
|
||||
QCoreApplication::exit(1);
|
||||
});
|
||||
return QCoreApplication::exec();
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ INCLUDEPATH += $$PWD
|
||||
#SRC_DIR = $$PWD
|
||||
message($$PWD)
|
||||
SOURCES += \
|
||||
$$PWD/colnodapi.cpp \
|
||||
$$PWD/databasemanager.cpp \
|
||||
$$PWD/datamanager.cpp \
|
||||
$$PWD/entity.cpp \
|
||||
@ -10,10 +9,10 @@ SOURCES += \
|
||||
$$PWD/requestmanager.cpp \
|
||||
$$PWD/response.cpp \
|
||||
$$PWD/subject.cpp \
|
||||
$$PWD/syncmanager.cpp \
|
||||
$$PWD/token.cpp
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/colnodapi.h \
|
||||
$$PWD/databasemanager.h \
|
||||
$$PWD/datamanager.h \
|
||||
$$PWD/entity.h \
|
||||
@ -21,5 +20,6 @@ HEADERS += \
|
||||
$$PWD/requestmanager.h \
|
||||
$$PWD/response.h \
|
||||
$$PWD/subject.h \
|
||||
$$PWD/syncmanager.h \
|
||||
$$PWD/token.h
|
||||
message($$SOURCES)
|
||||
|
||||
@ -9,14 +9,15 @@ DatabaseManager::DatabaseManager(const QString& host, const QString& dbName, con
|
||||
db.setPassword(password);
|
||||
if (!db.open())
|
||||
{
|
||||
qDebug() << "Opening error" + db.lastError().text();
|
||||
log("Opening error" + db.lastError().text());
|
||||
emit error();
|
||||
}
|
||||
query = QSqlQuery("query", db);
|
||||
this->dryMode = dryMode;
|
||||
}
|
||||
|
||||
// add or update subject to db
|
||||
int DatabaseManager::saveSubject(Subject* subject, const QString& table)
|
||||
int DatabaseManager::saveSubject(std::shared_ptr<Subject> subject, const QString& table)
|
||||
{
|
||||
QString id = subject->idToStringWithoutBraces();
|
||||
if (checkIfExists(id, table))
|
||||
@ -46,7 +47,7 @@ int DatabaseManager::saveSubject(Subject* subject, const QString& table)
|
||||
}
|
||||
|
||||
// add or update token to DB
|
||||
int DatabaseManager::saveToken(Token* token, const QString& table)
|
||||
int DatabaseManager::saveToken(std::shared_ptr<Token> token, const QString& table)
|
||||
{
|
||||
QString id = token->idToStringWithoutBraces();
|
||||
if (checkIfExists(id, table))
|
||||
@ -93,7 +94,7 @@ int DatabaseManager::saveToken(Token* token, const QString& table)
|
||||
}
|
||||
|
||||
// add of update subject attributes
|
||||
void DatabaseManager::saveSubjectAttributes(Subject *subject, const QString& table)
|
||||
void DatabaseManager::saveSubjectAttributes(std::shared_ptr<Subject> subject, const QString& table)
|
||||
{
|
||||
auto attributes = subject->getAtr();
|
||||
for (const auto& attribute : attributes){
|
||||
@ -123,10 +124,10 @@ void DatabaseManager::saveSubjectAttributes(Subject *subject, const QString& tab
|
||||
void DatabaseManager::setDeleted(const QString& id, const QString& table, quint64 time)
|
||||
{
|
||||
//quint64 now = getNow();
|
||||
//QString nowString = QDateTime::fromMSecsSinceEpoch(now).toString("yyyy-MM-dd hh:mm:ss.zzz");
|
||||
QString nowString = QDateTime::fromMSecsSinceEpoch(time).toString("yyyy-MM-dd hh:mm:ss.zzz");
|
||||
query.prepare(QString("UPDATE %1 SET deleted = true, last_update = :now, last_modified = :now WHERE id = :id").arg(table));
|
||||
query.bindValue(":id", id);
|
||||
query.bindValue(":now", time);
|
||||
query.bindValue(":now", nowString);
|
||||
executeQuery(query);
|
||||
}
|
||||
|
||||
@ -151,31 +152,37 @@ QString DatabaseManager::getLastQuery(const QSqlQuery& query) const
|
||||
return str;
|
||||
}
|
||||
|
||||
void DatabaseManager::executeNonPreperedQuery(const QString &statement, QSqlQuery &query) const
|
||||
void DatabaseManager::executeNonPreperedQuery(const QString &statement, QSqlQuery &query)
|
||||
|
||||
{
|
||||
if (dryMode){
|
||||
QString sqlStatement = getLastQuery(query);
|
||||
qDebug() << sqlStatement;
|
||||
if (statement.startsWith("SELECT"))
|
||||
query.exec(statement);
|
||||
}
|
||||
else{
|
||||
query.exec(statement);
|
||||
if (!dryMode || statement.startsWith("SELECT")){
|
||||
if (!query.exec(statement)){
|
||||
QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text());
|
||||
log(QString(msg));
|
||||
emit error();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool DatabaseManager::executeQuery(QSqlQuery &query) const
|
||||
bool DatabaseManager::executeQuery(QSqlQuery &query)
|
||||
{
|
||||
if (dryMode){
|
||||
QString sqlStatement = getLastQuery(query);
|
||||
qDebug() << sqlStatement;
|
||||
if (sqlStatement.startsWith("SELECT"))
|
||||
query.exec();
|
||||
return true;
|
||||
|
||||
}
|
||||
bool res = query.exec();
|
||||
return res;
|
||||
|
||||
if (!dryMode || query.isSelect()){
|
||||
if (!query.exec()){
|
||||
QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text());
|
||||
log(QString(msg));
|
||||
emit error();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DatabaseManager::dropTables()
|
||||
@ -285,7 +292,7 @@ QString DatabaseManager::getSubjectNameByTokenId(const QString &tokenId)
|
||||
if (query.next())
|
||||
return query.value(0).toString();
|
||||
qWarning() << "Token:" << tokenId << "is not assigned to any subject";
|
||||
return "No Subject";
|
||||
return "(No subject)";
|
||||
}
|
||||
|
||||
QString DatabaseManager::getSubjectNameById(const QString &id)
|
||||
@ -296,7 +303,7 @@ QString DatabaseManager::getSubjectNameById(const QString &id)
|
||||
if (query.next())
|
||||
return query.value(0).toString();
|
||||
qWarning() << "Subject:" << id << "doesn't exists";
|
||||
return "No Subject";
|
||||
return "(No subject)";
|
||||
}
|
||||
|
||||
bool DatabaseManager::checkDeletedToken(const QString &id)
|
||||
|
||||
@ -19,9 +19,9 @@ class DatabaseManager : public QObject
|
||||
public:
|
||||
DatabaseManager(const QString& host, const QString& dbName, const QString& user, const QString& password, const bool& dryMode = false);
|
||||
|
||||
int saveSubject(Subject* subject, const QString& table);
|
||||
int saveToken(Token* token, const QString& table);
|
||||
void saveSubjectAttributes(Subject* subject, const QString& table);
|
||||
int saveSubject(std::shared_ptr<Subject> subject, const QString& table);
|
||||
int saveToken(std::shared_ptr<Token> token, const QString& table);
|
||||
void saveSubjectAttributes(std::shared_ptr<Subject> subject, const QString& table);
|
||||
void setDeleted(const QString& id, const QString& table, quint64 time);
|
||||
|
||||
void dropTables();
|
||||
@ -44,9 +44,12 @@ public:
|
||||
|
||||
private:
|
||||
bool checkIfExists(const QString& id, const QString& table);
|
||||
bool executeQuery(QSqlQuery &query) const;
|
||||
bool executeQuery(QSqlQuery &query);
|
||||
QString getLastQuery(const QSqlQuery &query) const;
|
||||
void executeNonPreperedQuery(const QString &statement, QSqlQuery& query) const;
|
||||
void executeNonPreperedQuery(const QString &statement, QSqlQuery& query);
|
||||
|
||||
signals:
|
||||
void error();
|
||||
|
||||
private:
|
||||
QSqlDatabase db;
|
||||
|
||||
@ -2,12 +2,13 @@
|
||||
|
||||
DataManager::DataManager(const bool &dryMode)
|
||||
{
|
||||
db = new DatabaseManager("192.168.1.94", "deloitte", "postgres", "34rjkciea12", dryMode);
|
||||
//db = new DatabaseManager("localhost", "deloitte", "postgres", "34rjkciea12");
|
||||
db = std::make_shared<DatabaseManager>("192.168.1.94", "deloitte", "postgres", "34rjkciea12", dryMode);
|
||||
//db = std::make_shared<DatabaseManager>("localhost", "deloitte", "postgres", "34rjkciea12");
|
||||
Logger::setDBMan(db);
|
||||
nextLastSync = db->getNow();
|
||||
lastSync = db->getLastSync();
|
||||
this->dryMode = dryMode;
|
||||
connect(db.get(), &DatabaseManager::error, this, &DataManager::error);
|
||||
}
|
||||
|
||||
// load all tokens from colnod to comparing with working set from DB
|
||||
@ -18,14 +19,14 @@ void DataManager::fillFullTokensColnod(const QString& response)
|
||||
if (!items.empty())
|
||||
{
|
||||
for (QJsonValueRef item : items){
|
||||
auto token = new Token();
|
||||
auto token = std::make_shared<Token>();
|
||||
token->fromJSON(item.toObject());
|
||||
allTokensFromColnod.insert(token->idToStringWithoutBraces(), token);
|
||||
}
|
||||
}
|
||||
else{
|
||||
qCritical() << "Colnod is Empty";
|
||||
auto token = new Token("empty");
|
||||
auto token = std::make_shared<Token>("empty");
|
||||
allTokensFromColnod.insert(token->idToStringWithoutBraces(), token);
|
||||
}
|
||||
}
|
||||
@ -39,7 +40,7 @@ void DataManager::fillTokensToUpdateColnod(const QString& response)
|
||||
{
|
||||
for (QJsonValueRef item : items)
|
||||
{
|
||||
auto token = new Token();
|
||||
auto token = std::make_shared<Token>();
|
||||
token->fromJSON(item.toObject());
|
||||
token->setDeleted(false);
|
||||
tokensToUpdateFromColnodToDB.insert(token->idToStringWithoutBraces(), token);
|
||||
@ -49,7 +50,7 @@ void DataManager::fillTokensToUpdateColnod(const QString& response)
|
||||
else
|
||||
{
|
||||
qInfo() << "Colnod: 0 tokens to update";
|
||||
auto token = new Token("empty");
|
||||
auto token = std::make_shared<Token>("empty");
|
||||
tokensToUpdateFromColnodToDB.insert(token->getName(), token);
|
||||
}
|
||||
}
|
||||
@ -63,7 +64,7 @@ void DataManager::fillSubjectsToUpdateColnod(const QString& response)
|
||||
{
|
||||
for (QJsonValueRef item : items)
|
||||
{
|
||||
auto subject = new Subject();
|
||||
auto subject = std::make_shared<Subject>();
|
||||
subject->fromJSON(item.toObject());
|
||||
subjectsToUpdateFromColnodToDB.insert(subject->idToStringWithoutBraces(), subject);
|
||||
}
|
||||
@ -72,7 +73,7 @@ void DataManager::fillSubjectsToUpdateColnod(const QString& response)
|
||||
else
|
||||
{
|
||||
qInfo() << "Colnod:" << "0 subjects to update";
|
||||
Subject* subject = new Subject("empty");
|
||||
auto subject = std::make_shared<Subject>("empty");
|
||||
subjectsToUpdateFromColnodToDB.insert(subject->getName(), subject);
|
||||
}
|
||||
}
|
||||
@ -83,7 +84,7 @@ void DataManager::fillTokensToChangeDB()
|
||||
QSqlQuery* query = db->getUpdatedTokens();
|
||||
while (query->next())
|
||||
{
|
||||
auto token = new Token;
|
||||
auto token = std::make_shared<Token>();
|
||||
token->fromSQLRecord(query);
|
||||
if (token->getDeleted()){ // sort to delete / to update
|
||||
tokensFromDBToDeleteFromColnod.append(token->idToStringWithoutBraces());
|
||||
@ -288,7 +289,7 @@ void DataManager::filterTokensColnod()
|
||||
auto record = db->getToken(id);
|
||||
if (!record)
|
||||
continue;
|
||||
auto tokenDB = new Token;
|
||||
auto tokenDB = std::shared_ptr<Token>();
|
||||
tokenDB->fromSQLRecord(record);
|
||||
Q_ASSERT(tokenDB != token);
|
||||
if (*tokenDB > *token)
|
||||
|
||||
@ -42,9 +42,9 @@ public:
|
||||
|
||||
void emptyDatabase();
|
||||
|
||||
QHash<QString, QPointer<Token>> getTokensToUpdateColnod() {return tokensToUpdateFromColnodToDB;}
|
||||
QHash<QString, std::shared_ptr<Token>> getTokensToUpdateColnod() {return tokensToUpdateFromColnodToDB;}
|
||||
QList<QString> getTokensToDeleteColnod() {return tokensFromColnodToDeleteFromDB;}
|
||||
QHash<QString, QPointer<Token>> getTokensToUpdateDB() {return tokensToUpdateFromDBToColnod;}
|
||||
QHash<QString, std::shared_ptr<Token>> getTokensToUpdateDB() {return tokensToUpdateFromDBToColnod;}
|
||||
QList<QString> getTokensToDeleteDB() {return tokensFromDBToDeleteFromColnod;}
|
||||
|
||||
const quint64 &getLastSync() {return lastSync;}
|
||||
@ -55,17 +55,20 @@ public slots:
|
||||
void setLastSync() {db->updateLastSync(nextLastSync);}
|
||||
void setLastUpdate();
|
||||
|
||||
signals:
|
||||
void error();
|
||||
|
||||
private:
|
||||
DatabaseManager *db = nullptr;
|
||||
std::shared_ptr<DatabaseManager> db;
|
||||
|
||||
quint64 lastSync; // time of last run
|
||||
quint64 nextLastSync; // time of begin of this run
|
||||
|
||||
QHash<QString, QPointer<Subject>> subjectsToUpdateFromColnodToDB;
|
||||
QHash<QString, QPointer<Token>> tokensToUpdateFromColnodToDB;
|
||||
QHash<QString, QPointer<Token>> allTokensFromColnod;
|
||||
QHash<QString, QPointer<Subject>> subjectsDB; // in future
|
||||
QHash<QString, QPointer<Token>> tokensToUpdateFromDBToColnod;
|
||||
QHash<QString, std::shared_ptr<Subject>> subjectsToUpdateFromColnodToDB;
|
||||
QHash<QString, std::shared_ptr<Token>> tokensToUpdateFromColnodToDB;
|
||||
QHash<QString, std::shared_ptr<Token>> allTokensFromColnod;
|
||||
QHash<QString, std::shared_ptr<Subject>> subjectsDB; // in future
|
||||
QHash<QString, std::shared_ptr<Token>> tokensToUpdateFromDBToColnod;
|
||||
|
||||
QList<QString> subjectsFromColnodToDeleteFromDB;
|
||||
QList<QString> tokensFromColnodToDeleteFromDB;
|
||||
|
||||
@ -3,6 +3,8 @@
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QUuid>
|
||||
#include <QtCore/QJsonObject>
|
||||
#include <QDebug>
|
||||
#include <memory>
|
||||
|
||||
|
||||
class Entity : public QObject {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#include "logger.h"
|
||||
|
||||
DatabaseManager *Logger::dbMan = nullptr;
|
||||
std::shared_ptr<DatabaseManager> Logger::dbMan = nullptr;
|
||||
Logger *Logger::logger = nullptr;
|
||||
|
||||
Logger::Logger()
|
||||
@ -26,21 +26,24 @@ void Logger::logToDb(const QString &msg)
|
||||
Logger::dbMan->log(msg);
|
||||
}
|
||||
|
||||
void Logger::setDBMan(DatabaseManager *dbMan)
|
||||
void Logger::setDBMan(std::shared_ptr<DatabaseManager> dbMan)
|
||||
{
|
||||
Logger::dbMan = dbMan;
|
||||
}
|
||||
|
||||
QString Logger::makeTokenMsg(const QString &tokenId, const QString &action, const QString &source)
|
||||
{
|
||||
QString msg = QString("Token: %1 of subject: %2 %3. Source: %4").arg(tokenId,dbMan->getSubjectNameByTokenId(tokenId), action, source);
|
||||
return msg;
|
||||
return QString("Token: %1 of subject: %2 %3. Source: %4").arg(tokenId,dbMan->getSubjectNameByTokenId(tokenId), action, source);
|
||||
}
|
||||
|
||||
QString Logger::makeSubjectMsg(const QString &subjectId, const QString &action, const QString &source)
|
||||
{
|
||||
QString msg = QString("Subject: %1 %2. Source: %3").arg(dbMan->getSubjectNameById(subjectId), action, source);
|
||||
return msg;
|
||||
return QString("Subject: %1 %2. Source: %3").arg(dbMan->getSubjectNameById(subjectId), action, source);
|
||||
}
|
||||
|
||||
QString Logger::makeErrorMsg(const QString &source, const QString &errMsg)
|
||||
{
|
||||
return QString("Source: %1, Error: %2").arg(source, errMsg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -13,16 +13,16 @@ class Logger
|
||||
|
||||
Logger();
|
||||
|
||||
static DatabaseManager *dbMan;
|
||||
static std::shared_ptr<DatabaseManager> dbMan;
|
||||
|
||||
public:
|
||||
static Logger *getLogger();
|
||||
static void log(const QString& msg);
|
||||
static void logToDb(const QString& msg);
|
||||
static void setDBMan(DatabaseManager* dbMan);
|
||||
static void setDBMan(std::shared_ptr<DatabaseManager> dbMan);
|
||||
static QString makeTokenMsg(const QString& tokenId, const QString& action, const QString& source);
|
||||
static QString makeSubjectMsg(const QString& subjectId, const QString& action, const QString& source);
|
||||
|
||||
static QString makeErrorMsg(const QString& source, const QString& errMsg);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@ -2,16 +2,14 @@
|
||||
|
||||
RequestManager::RequestManager()
|
||||
{
|
||||
manager = new QNetworkAccessManager();
|
||||
token = "";
|
||||
loginStatus = false;
|
||||
QObject::connect(manager, &QNetworkAccessManager::sslErrors, this, &RequestManager::onSSLError);
|
||||
manager = std::make_unique<QNetworkAccessManager>();
|
||||
connect(manager.get(), &QNetworkAccessManager::sslErrors, this, &RequestManager::onSSLError);
|
||||
}
|
||||
|
||||
Response* RequestManager::login()
|
||||
std::shared_ptr<Response> RequestManager::login()
|
||||
{
|
||||
Q_ASSERT(!loginResponse);
|
||||
loginResponse = new Response;
|
||||
loginResponse = std::make_shared<Response>();
|
||||
QNetworkRequest request;
|
||||
QString hash = encryptedPassword(this->password);
|
||||
authHeader = getLoginHeader(this->user, hash);
|
||||
@ -22,25 +20,24 @@ Response* RequestManager::login()
|
||||
request.setUrl(this->host + "/AaaManager/authSession");
|
||||
request.setRawHeader("Authorization", authHeader.toLocal8Bit());
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json; charset=UTF-8");
|
||||
|
||||
QJsonDocument jsonDocument;
|
||||
jsonDocument.setObject(reqBody);
|
||||
QNetworkReply* reply = manager->post(request, jsonDocument.toJson());
|
||||
loginResponse->setReply(reply);
|
||||
QObject::connect(reply, &QNetworkReply::finished, [=]() {
|
||||
connect(reply, &QNetworkReply::finished, [=]() {
|
||||
if (reply->error())
|
||||
{
|
||||
qDebug() << "Login failed: "<< reply->errorString();
|
||||
Logger::logToDb(Logger::makeErrorMsg("Request Manager", reply->errorString()));
|
||||
loginStatus = false;
|
||||
reply->deleteLater();
|
||||
emit error();
|
||||
return;
|
||||
}
|
||||
//qDebug() << "Logged in successfully.";
|
||||
loginStatus = true;
|
||||
emit successLogin();
|
||||
reply->deleteLater();
|
||||
});
|
||||
connect(this, &RequestManager::successLogin, loginResponse, &Response::ready);
|
||||
connect(this, &RequestManager::successLogin, loginResponse.get(), &Response::ready);
|
||||
connect(this, &RequestManager::successLogin, this, &RequestManager::prepareAuthHeader);
|
||||
return loginResponse;
|
||||
}
|
||||
@ -55,12 +52,12 @@ QNetworkReply* RequestManager::postRequest(const QString& endpoint, const QByteA
|
||||
QObject::connect(reply, &QNetworkReply::finished, [=]() {
|
||||
if (reply->error())
|
||||
{
|
||||
qDebug() << "Authorization failed: " << reply->errorString();
|
||||
Logger::logToDb(Logger::makeErrorMsg("Request Manager", reply->errorString()));
|
||||
loginStatus = false;
|
||||
reply->deleteLater();
|
||||
emit error();
|
||||
return;
|
||||
}
|
||||
//qDebug() << "Authorized successfully, response ready.";
|
||||
emit responseReady();
|
||||
reply->deleteLater();
|
||||
});
|
||||
@ -68,7 +65,7 @@ QNetworkReply* RequestManager::postRequest(const QString& endpoint, const QByteA
|
||||
}
|
||||
|
||||
// This will ensure login is called only once
|
||||
Response* RequestManager::getLoginResponse() {
|
||||
std::shared_ptr<Response> RequestManager::getLoginResponse() {
|
||||
if (!loginResponse){
|
||||
loginResponse = login();
|
||||
}
|
||||
@ -79,7 +76,7 @@ Response* RequestManager::postRequestReturnLogic(const QString& endpoint, const
|
||||
{
|
||||
auto loginResponse = getLoginResponse();
|
||||
Q_ASSERT(loginResponse);
|
||||
auto* response = new Response;
|
||||
auto response = new Response;
|
||||
|
||||
if (!loginStatus){
|
||||
connect(this, &RequestManager::successLogin, [=](){
|
||||
@ -121,7 +118,7 @@ QString RequestManager::getLoginHeader(const QString& username, const QString& h
|
||||
void RequestManager::prepareAuthHeader()
|
||||
{
|
||||
jsonResponse = loginResponse->getJson();
|
||||
token = getFromJson(jsonResponse, "id");
|
||||
QString token = getFromJson(jsonResponse, "id");
|
||||
QString authValue = token + ":";
|
||||
authHeader = "Basic " + authValue.toLocal8Bit().toBase64();
|
||||
}
|
||||
@ -146,7 +143,7 @@ QByteArray RequestManager::makeTimestampJson(uint64_t time)
|
||||
return doc.toJson();
|
||||
}
|
||||
|
||||
QByteArray RequestManager::makeTokensJson(const QHash<QString, QPointer<Token> > &tokens)
|
||||
QByteArray RequestManager::makeTokensJson(const QHash<QString, std::shared_ptr<Token>> &tokens)
|
||||
{
|
||||
QJsonObject items;
|
||||
QJsonArray jsonTokens;
|
||||
@ -239,7 +236,7 @@ Response* RequestManager::getAccessGroupMembershipDeleted(uint64_t time)
|
||||
return postRequestReturnLogic("/AccessManager/getAccessGroupMembershipDeleted", makeTimestampJson(time));
|
||||
}
|
||||
|
||||
Response* RequestManager::setTokens(const QHash<QString, QPointer<Token> > &tokens)
|
||||
Response* RequestManager::setTokens(const QHash<QString, std::shared_ptr<Token>> &tokens)
|
||||
{
|
||||
return postRequestReturnLogic("/TokenManager/setTokens", makeTokensJson(tokens));
|
||||
}
|
||||
|
||||
@ -31,7 +31,12 @@ class RequestManager : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
friend class UnitTest;
|
||||
friend class ComplexTest;
|
||||
|
||||
RequestManager();
|
||||
|
||||
// this should be in ColnodAPI class BEGIN
|
||||
Response* getSubjects();
|
||||
Response* getTokens();
|
||||
Response* getTokenSubject();
|
||||
@ -49,47 +54,47 @@ public:
|
||||
Response* getAccessGroupMembershipUpdated(uint64_t time);
|
||||
Response* getAccessGroupMembershipDeleted(uint64_t time);
|
||||
|
||||
Response* setTokens(const QHash<QString, QPointer<Token>> &tokens);
|
||||
Response* setTokens(const QHash<QString, std::shared_ptr<Token>> &tokens);
|
||||
Response* deleteTokens(const QList<QString> &ids);
|
||||
|
||||
Response* login(); //I want it private, but unittest???
|
||||
|
||||
const QJsonDocument &getConfig() const {return config;}
|
||||
const QString &getResponse() const {return jsonResponse;}
|
||||
// END
|
||||
|
||||
private:
|
||||
// should be public
|
||||
QNetworkReply* postRequest(const QString& endpoint, const QByteArray& json = QByteArray());
|
||||
Response* postRequestReturnLogic(const QString& endpoint, const QByteArray& data = QByteArray());
|
||||
|
||||
std::shared_ptr<Response> login();
|
||||
std::shared_ptr<Response> getLoginResponse();
|
||||
QString getFromJson(const QString& json, const QString &member);
|
||||
QString encryptedPassword(const QString& password);
|
||||
QString getLoginHeader(const QString& username, const QString& hash);
|
||||
|
||||
// in colnod api as well
|
||||
QByteArray makeTimestampJson(uint64_t time);
|
||||
QByteArray makeTokensJson(const QHash<QString, QPointer<Token>> &tokens);
|
||||
QByteArray makeIdsJson(const QList<QString> &ids);
|
||||
Response* getLoginResponse();
|
||||
QByteArray makeTokensJson(const QHash<QString, std::shared_ptr<Token>> &tokens); // maybe better to be in Token class
|
||||
QByteArray makeIdsJson(const QList<QString> &ids); // Entity class
|
||||
|
||||
private slots:
|
||||
void onSSLError(QNetworkReply *reply, const QList<QSslError> &errors);
|
||||
//void onReplyFinished(QNetworkReply *reply);
|
||||
void prepareAuthHeader();
|
||||
|
||||
signals:
|
||||
void successLogin();
|
||||
void responseReady();
|
||||
|
||||
void error();
|
||||
|
||||
private:
|
||||
QNetworkAccessManager* manager = nullptr;
|
||||
Response* loginResponse = nullptr;
|
||||
std::unique_ptr<QNetworkAccessManager> manager;
|
||||
std::shared_ptr<Response> loginResponse;
|
||||
QJsonDocument config;
|
||||
QString authHeader;
|
||||
QString host = "https://192.168.1.3:8443";
|
||||
const QString host = "https://192.168.1.3:8443";
|
||||
//QString host = "https://localhost:8080";
|
||||
|
||||
QString password = "spaceti1";
|
||||
QString user = "spaceti";
|
||||
QString token;
|
||||
const QString password = "spaceti1";
|
||||
const QString user = "spaceti";
|
||||
QString jsonResponse;
|
||||
bool loginStatus;
|
||||
bool loginStatus = false;
|
||||
|
||||
};
|
||||
|
||||
@ -39,6 +39,6 @@ private:
|
||||
QSet<QString> pinFlags;
|
||||
//QList<QPointer<Attribute>> atr;
|
||||
QList<QPair<QString, QString>> atr;
|
||||
const std::array<QString, 6> attributeTypes = {"Jmeno", "Prijmeni", "ProfilParking", "Spolecnost", "Profil", "spz"};
|
||||
const QList<QString> attributeTypes = {"Jmeno", "Prijmeni", "ProfilParking", "Spolecnost", "Profil", "spz"};
|
||||
|
||||
};
|
||||
|
||||
@ -1,13 +1,16 @@
|
||||
#include "colnodapi.h"
|
||||
#include "syncmanager.h"
|
||||
|
||||
ColnodAPI::ColnodAPI(bool dryMode)
|
||||
SyncManager::SyncManager(bool dryMode)
|
||||
{
|
||||
reqMan = new RequestManager();
|
||||
dataMan = new DataManager(dryMode);
|
||||
reqMan = std::make_unique<RequestManager>();
|
||||
dataMan = std::make_unique<DataManager>(dryMode);
|
||||
this->dryMode = dryMode;
|
||||
|
||||
connect(reqMan.get(), &RequestManager::error, this, &SyncManager::error);
|
||||
connect(dataMan.get(), &DataManager::error, this, &SyncManager::error);
|
||||
}
|
||||
|
||||
void ColnodAPI::loadDataFromColnod()
|
||||
void SyncManager::loadDataFromColnod()
|
||||
{
|
||||
loadTokensFromColnod();
|
||||
loadUpdatedDataFromColnod();
|
||||
@ -15,7 +18,7 @@ void ColnodAPI::loadDataFromColnod()
|
||||
}
|
||||
|
||||
// download all tokens form colnod for comparing with tokens to update from DB
|
||||
void ColnodAPI::loadTokensFromColnod()
|
||||
void SyncManager::loadTokensFromColnod()
|
||||
{
|
||||
Response* resp = reqMan->getTokens();
|
||||
connect(resp, &Response::ready, [=](){
|
||||
@ -26,7 +29,7 @@ void ColnodAPI::loadTokensFromColnod()
|
||||
}
|
||||
|
||||
// fill tokens/subjects to update in data manager
|
||||
void ColnodAPI::loadUpdatedDataFromColnod()
|
||||
void SyncManager::loadUpdatedDataFromColnod()
|
||||
{
|
||||
uint64_t lastUpdate = dataMan->getLastSync();
|
||||
Response* resp0 = reqMan->getSubjectsUpdated(lastUpdate);
|
||||
@ -45,7 +48,7 @@ void ColnodAPI::loadUpdatedDataFromColnod()
|
||||
}
|
||||
|
||||
// fill tokens/subjects to delete in data manager
|
||||
void ColnodAPI::loadDeletedDataFromColnod()
|
||||
void SyncManager::loadDeletedDataFromColnod()
|
||||
{
|
||||
uint64_t lastUpdate = dataMan->getLastSync();
|
||||
Response* resp2 = reqMan->getSubjectsDeleted(lastUpdate);
|
||||
@ -65,12 +68,12 @@ void ColnodAPI::loadDeletedDataFromColnod()
|
||||
}
|
||||
|
||||
// fill structures in data manager (tokens to updata/to delte)
|
||||
void ColnodAPI::loadDataFromDB()
|
||||
void SyncManager::loadDataFromDB()
|
||||
{
|
||||
dataMan->fillTokensToChangeDB();
|
||||
}
|
||||
|
||||
void ColnodAPI::syncDataFromColnodToDB()
|
||||
void SyncManager::syncDataFromColnodToDB()
|
||||
{
|
||||
syncUpdatedDataFromColnodToDB();
|
||||
if (dataMan->getLastSync() != 0)
|
||||
@ -78,21 +81,21 @@ void ColnodAPI::syncDataFromColnodToDB()
|
||||
}
|
||||
|
||||
// push data from colnod to DB
|
||||
void ColnodAPI::syncUpdatedDataFromColnodToDB()
|
||||
void SyncManager::syncUpdatedDataFromColnodToDB()
|
||||
{
|
||||
dataMan->pushSubjectsToDB();
|
||||
dataMan->pushTokensToDB();
|
||||
}
|
||||
|
||||
// set deleted tokens from Colnod, delete subject
|
||||
void ColnodAPI::syncDeletedDataFromColnodToDB()
|
||||
void SyncManager::syncDeletedDataFromColnodToDB()
|
||||
{
|
||||
dataMan->deleteSubjectsFromDB();
|
||||
dataMan->setDeletedToTokensFromDB();
|
||||
}
|
||||
|
||||
// push changes form DB to Colnod
|
||||
void ColnodAPI::syncDataFromDBToColnod()
|
||||
void SyncManager::syncDataFromDBToColnod()
|
||||
{
|
||||
|
||||
if (!dataMan->getTokensToUpdateDB().contains("empty")){
|
||||
@ -105,9 +108,9 @@ void ColnodAPI::syncDataFromDBToColnod()
|
||||
}
|
||||
else
|
||||
updateFinished = true;
|
||||
connect(this, &ColnodAPI::dataUpdatedToColnod, dataMan, &DataManager::clear);
|
||||
connect(this, &ColnodAPI::dataUpdatedToColnod, dataMan, &DataManager::setLastSync);
|
||||
connect(this, &ColnodAPI::dataUpdatedToColnod, [=](){
|
||||
connect(this, &SyncManager::dataUpdatedToColnod, dataMan.get(), &DataManager::clear);
|
||||
connect(this, &SyncManager::dataUpdatedToColnod, dataMan.get(), &DataManager::setLastSync);
|
||||
connect(this, &SyncManager::dataUpdatedToColnod, [=](){
|
||||
auto resp = reqMan->getTokensUpdated(dataMan->getCurrentSync());
|
||||
connect(resp, &Response::ready, [=](){
|
||||
dataMan->fillTokensToUpdateColnod(resp->getJson());
|
||||
@ -121,7 +124,7 @@ void ColnodAPI::syncDataFromDBToColnod()
|
||||
}
|
||||
|
||||
// add or update tokens to Colnod
|
||||
void ColnodAPI::syncUpdatedDataFromDBToColnod()
|
||||
void SyncManager::syncUpdatedDataFromDBToColnod()
|
||||
{
|
||||
auto tokensToUpdate = dataMan->getTokensToUpdateDB();
|
||||
if (dryMode){
|
||||
@ -139,7 +142,7 @@ void ColnodAPI::syncUpdatedDataFromDBToColnod()
|
||||
}
|
||||
|
||||
// delete tokens in Colnod
|
||||
void ColnodAPI::syncDeletedDataFromDBToColnod()
|
||||
void SyncManager::syncDeletedDataFromDBToColnod()
|
||||
{
|
||||
dataMan->filterTokensDB();
|
||||
auto tokensToDelete = dataMan->getTokensToDeleteDB();
|
||||
@ -158,20 +161,20 @@ void ColnodAPI::syncDeletedDataFromDBToColnod()
|
||||
}
|
||||
|
||||
// For full sync
|
||||
void ColnodAPI::prepareDatabase()
|
||||
void SyncManager::prepareDatabase()
|
||||
{
|
||||
dataMan->emptyDatabase();
|
||||
}
|
||||
|
||||
// emit signal when all data is downloaded from Colnod
|
||||
void ColnodAPI::areChangedDataReady()
|
||||
void SyncManager::areChangedDataReady()
|
||||
{
|
||||
if (dataMan->haveChangedData())
|
||||
emit dataDownloaded();
|
||||
}
|
||||
|
||||
// emit signal when writing to Colnod is finised
|
||||
void ColnodAPI::areDataUpdatedToColnod()
|
||||
void SyncManager::areDataUpdatedToColnod()
|
||||
{
|
||||
if (deleteFinished && updateFinished)
|
||||
{
|
||||
@ -4,13 +4,13 @@
|
||||
#include "datamanager.h"
|
||||
#include "logger.h"
|
||||
|
||||
class ColnodAPI : public QObject
|
||||
class SyncManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
ColnodAPI(bool dryMode = false);
|
||||
SyncManager(bool dryMode = false);
|
||||
|
||||
void syncDataFromColnodToDB();
|
||||
void syncDataFromDBToColnod();
|
||||
@ -25,6 +25,7 @@ signals:
|
||||
void dataDownloaded();
|
||||
void dataUpdatedToColnod();
|
||||
void syncFinished();
|
||||
void error();
|
||||
|
||||
private slots:
|
||||
|
||||
@ -46,8 +47,8 @@ private:
|
||||
void areDataUpdatedToColnod();
|
||||
|
||||
private:
|
||||
RequestManager* reqMan = nullptr;
|
||||
DataManager* dataMan = nullptr;
|
||||
std::unique_ptr<RequestManager> reqMan;
|
||||
std::unique_ptr<DataManager> dataMan;
|
||||
bool dryMode = false;
|
||||
bool updateFinished = false;
|
||||
bool deleteFinished = false;
|
||||
@ -22,6 +22,10 @@ Token::Token(const QString &name)
|
||||
this->setName(name);
|
||||
}
|
||||
|
||||
Token::~Token()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Token::fromJSON(const QJsonObject &json) {
|
||||
Entity::fromJSON(json);
|
||||
|
||||
@ -14,6 +14,7 @@ public:
|
||||
Token() = default;
|
||||
Token(const QString& name, QString tokenData, const QString& decription = "mobile");
|
||||
Token(const QString& name);
|
||||
~Token() override;
|
||||
|
||||
friend bool operator<(const Token &lToken, const Token &rToken){
|
||||
return lToken.getLastModified() < rToken.getLastUpdate();
|
||||
|
||||
@ -14,7 +14,7 @@ void UnitTest::loginSuccessfully()
|
||||
spy.wait(timeout);
|
||||
|
||||
QCOMPARE(spy.count(), 1);
|
||||
QString json = testAccess->getResponse();
|
||||
QString json = testAccess->jsonResponse;
|
||||
qDebug() << json;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
|
||||
QVERIFY2(doc.object().value("id").isString(), "No parameter 'id' in response");
|
||||
@ -211,15 +211,14 @@ void UnitTest::setTokens()
|
||||
QJsonObject obj = doc.object();
|
||||
QJsonArray arr = obj["items"].toArray();
|
||||
qDebug() << arr;
|
||||
QHash<QString, QPointer<Token>> tokens;
|
||||
QHash<QString, std::shared_ptr<Token>> tokens;
|
||||
for (auto object : arr)
|
||||
{
|
||||
auto token = new Token;
|
||||
auto token = std::shared_ptr<Token>();
|
||||
token->fromJSON(object.toObject());
|
||||
qDebug() << token;
|
||||
tokens.insert(token->idToStringWithoutBraces(), token);
|
||||
}
|
||||
auto* testAccess = new RequestManager();
|
||||
auto testAccess = new RequestManager();
|
||||
QSignalSpy spy(testAccess, SIGNAL(responseReady()));
|
||||
Response* response = testAccess->setTokens(tokens);
|
||||
QCOMPARE(spy.count(), 0);
|
||||
|
||||
@ -13,7 +13,7 @@ void ComplexTest::initTestCase()
|
||||
// QTest::qWait(2500);
|
||||
// Logger *logger = Logger::getLogger();
|
||||
start = QDateTime::currentMSecsSinceEpoch()-2000;
|
||||
api = new ColnodAPI();
|
||||
api = new SyncManager();
|
||||
qDebug() << start;
|
||||
|
||||
}
|
||||
@ -37,8 +37,8 @@ void ComplexTest::complexTest()
|
||||
// LOGIN_BEGIN
|
||||
reqMan = new RequestManager;
|
||||
QSignalSpy loginSpy(reqMan, &RequestManager::successLogin);
|
||||
Response* loginResp = reqMan->login();
|
||||
QSignalSpy loginRespSpy(loginResp, &Response::ready);
|
||||
auto loginResp = reqMan->login();
|
||||
QSignalSpy loginRespSpy(loginResp.get(), &Response::ready);
|
||||
QCOMPARE(loginSpy.count(), 0);
|
||||
QCOMPARE(loginRespSpy.count(), 0);
|
||||
loginSpy.wait(timeout);
|
||||
@ -58,7 +58,7 @@ void ComplexTest::complexTest()
|
||||
|
||||
|
||||
// ADD_TOKENS_CHECK_BEGIN
|
||||
QHash<QString, QPointer<Token>> tokens;
|
||||
QHash<QString, std::shared_ptr<Token>> tokens;
|
||||
auto token = getTestToken();
|
||||
tokens.insert(token->idToStringWithoutBraces(), token);
|
||||
Response* setTokensResp = reqMan->setTokens(tokens);
|
||||
@ -117,14 +117,14 @@ void ComplexTest::fullSync()
|
||||
{
|
||||
api->prepareDatabase();
|
||||
api->loadDataFromColnod();
|
||||
QSignalSpy spy(api, &ColnodAPI::dataDownloaded);
|
||||
QSignalSpy spy(api, &SyncManager::dataDownloaded);
|
||||
spy.wait(timeout);
|
||||
api->loadDataFromDB();
|
||||
api->syncDataFromColnodToDB();
|
||||
api->syncDataFromDBToColnod();
|
||||
QSignalSpy processSpy(api, &ColnodAPI::dataUpdatedToColnod);
|
||||
QSignalSpy processSpy(api, &SyncManager::dataUpdatedToColnod);
|
||||
processSpy.wait(timeout);
|
||||
QSignalSpy finish(api, &ColnodAPI::syncFinished);
|
||||
QSignalSpy finish(api, &SyncManager::syncFinished);
|
||||
finish.wait(timeout);
|
||||
}
|
||||
|
||||
@ -132,14 +132,14 @@ void ComplexTest::syncLastUpdated()
|
||||
{
|
||||
Logger::log("ahoj");
|
||||
api->loadDataFromColnod();
|
||||
QSignalSpy spy(api, &ColnodAPI::dataDownloaded);
|
||||
QSignalSpy spy(api, &SyncManager::dataDownloaded);
|
||||
spy.wait(timeout);
|
||||
api->loadDataFromDB();
|
||||
api->syncDataFromColnodToDB();
|
||||
api->syncDataFromDBToColnod();
|
||||
QSignalSpy processSpy(api, &ColnodAPI::dataUpdatedToColnod);
|
||||
QSignalSpy processSpy(api, &SyncManager::dataUpdatedToColnod);
|
||||
processSpy.wait(timeout);
|
||||
QSignalSpy finish(api, &ColnodAPI::syncFinished);
|
||||
QSignalSpy finish(api, &SyncManager::syncFinished);
|
||||
finish.wait(timeout);
|
||||
qDebug() << "All right, at least should be.";
|
||||
}
|
||||
@ -175,7 +175,7 @@ QJsonDocument ComplexTest::getJsonDoc(const QString &json)
|
||||
return QJsonDocument::fromJson(json.toUtf8());
|
||||
}
|
||||
|
||||
QPointer<Token> ComplexTest::getTestToken()
|
||||
std::shared_ptr<Token> ComplexTest::getTestToken()
|
||||
{
|
||||
QJsonObject jsonToken;
|
||||
jsonToken.insert("id", "062c93f6-ba3e-46af-a3a6-7a2988d1f0e9");
|
||||
@ -191,7 +191,7 @@ QPointer<Token> ComplexTest::getTestToken()
|
||||
flags.push_back("NoValidity");
|
||||
jsonToken.insert("flags", flags);
|
||||
jsonToken.insert("subjectId", "72b37f7e-5761-4e6c-8e87-20c0bed0d904");
|
||||
QPointer<Token> token = new Token;
|
||||
auto token = std::shared_ptr<Token>();
|
||||
token->fromJSON(jsonToken);
|
||||
return token;
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
#include <QtTest/QtTest>
|
||||
#include "response.h"
|
||||
#include "requestmanager.h"
|
||||
#include "colnodapi.h"
|
||||
#include "syncmanager.h"
|
||||
#include "logger.h"
|
||||
|
||||
class ComplexTest : public QObject
|
||||
@ -25,7 +25,7 @@ private:
|
||||
int getNumOfSubjects();
|
||||
int getNumOfTokens();
|
||||
QJsonDocument getJsonDoc(const QString &json);
|
||||
QPointer<Token> getTestToken();
|
||||
std::shared_ptr<Token> getTestToken();
|
||||
|
||||
|
||||
// VARIABLES
|
||||
@ -34,7 +34,7 @@ private:
|
||||
QString password = "spaceti1";
|
||||
RequestManager* reqMan = nullptr;
|
||||
uint64_t start = 0;
|
||||
ColnodAPI* api = nullptr;
|
||||
SyncManager* api = nullptr;
|
||||
|
||||
static constexpr qint16 timeout = 10000;
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user