first version - w/o dry run mode and logs

This commit is contained in:
Ondřej Fischer 2019-10-23 09:55:18 +02:00
parent 78ff45f7fd
commit 6ad24c6c6e
15 changed files with 398 additions and 184 deletions

View File

@ -8,6 +8,7 @@ int main(int argc, char *argv[])
QCoreApplication a(argc, argv);
ColnodAPI *api = new ColnodAPI();
/*api->downloadData(); // this will start downloading data
QObject::connect(api, &ColnodAPI::dataDownloaded, [=](){
qDebug() << "now I have all data";

View File

@ -1,9 +1,10 @@
#include "colnodapi.h"
ColnodAPI::ColnodAPI()
ColnodAPI::ColnodAPI(bool debug)
{
reqMan = new RequestManager();
dataMan = new DataManager();
debugMode = debug;
}
@ -45,7 +46,8 @@ void ColnodAPI::loadTokensFromColnod()
Response* resp = reqMan->getTokens();
connect(resp, &Response::ready, [=](){
dataMan->fillFullTokensColnod(resp->getJson());
areChangedDataReady();
resp->deleteLater();
});
}
@ -89,7 +91,7 @@ void ColnodAPI::loadDeletedDataFromColnod()
void ColnodAPI::loadDataFromDB()
{
dataMan->fillTokensDB();
dataMan->fillTokensToDeleteDB();
}
//void ColnodAPI::syncDataFromColnod()
@ -102,10 +104,12 @@ void ColnodAPI::loadDataFromDB()
void ColnodAPI::syncDataFromColnod()
{
dataMan->filterTokensColnod();
syncUpdatedDataFromColnod();
syncDeletedDataFromColnod();
if (dataMan->getLastSync() != 0)
syncDeletedDataFromColnod();
//dataMan->updateLastSync();
dataMan->clear();
// dataMan->clear();
}
void ColnodAPI::syncUpdatedDataFromColnod()
@ -124,36 +128,71 @@ void ColnodAPI::syncDeletedDataFromColnod()
void ColnodAPI::syncDataFromDB()
{
// TODO
dataMan->loadTokensToAdd();
dataMan->loadTokensToDelete();
dataMan->filterTokensDB();
processDataToColnod();
connect(this, &ColnodAPI::dataProcessed, dataMan, &DataManager::clear);
connect(this, &ColnodAPI::dataProcessed, dataMan, &DataManager::setLastSync);
connect(this, &ColnodAPI::dataProcessed, [=](){
auto resp = reqMan->getTokensUpdated(dataMan->getActualSync());
connect(resp, &Response::ready, [=](){
dataMan->fillTokensColnod(resp->getJson());
dataMan->setLastUpdate();
dataMan->clear();
emit syncFinished();
resp->deleteLater();
});
});
}
void ColnodAPI::processDataToColnod()
{
QList<QString>* tokensToDelete = dataMan->getTokensToDelete();
if ((*tokensToDelete)[0] != "empty")
{
Response* resp0 = reqMan->deleteTokens(tokensToDelete);
connect(resp0, &Response::ready, [=](){
isProcessDone();
resp0->deleteLater();
});
auto tokensToUpdate = dataMan->getTokensToUpdateDB();
if (tokensToUpdate.contains("empty")){
qDebug() << "No tokens to be modified.";
return;
}
QHash<QString, QPointer<Token>>* tokens = dataMan->getTokens();
if (!tokens[0].contains("empty"))
{
Response* resp1 = reqMan->setTokens(tokens);
connect(resp1, &Response::ready, [=](){
isProcessDone();
resp1->deleteLater();
});
}
dataMan->clear();
connect(this, &ColnodAPI::dataProcessed, this, &ColnodAPI::loadDataFromColnod);
auto tokensToDelete = dataMan->getTokensToDeleteDB();
auto resp0 = reqMan->setTokens(tokensToUpdate);
auto resp1 = reqMan->deleteTokens(tokensToDelete);
connect(resp0, &Response::ready, [=](){
updateFinished = true;
areDataProcessed();
resp0->deleteLater();
});
connect(resp1, &Response::ready, [=](){
deleteFinished = true;
areDataProcessed();
resp1->deleteLater();
});
}
// old version
//void ColnodAPI::processDataToColnod()
//{
// QList<QString>* tokensToDelete = dataMan->getTokensToDelete();
// if ((*tokensToDelete)[0] != "empty")
// {
// Response* resp0 = reqMan->deleteTokens(tokensToDelete);
// connect(resp0, &Response::ready, [=](){
// isProcessDone();
// resp0->deleteLater();
// });
// }
// QHash<QString, QPointer<Token>>* tokens = dataMan->getTokens();
// if (!tokens[0].contains("empty"))
// {
// Response* resp1 = reqMan->setTokens(tokens);
// connect(resp1, &Response::ready, [=](){
// isProcessDone();
// resp1->deleteLater();
// });
// }
// dataMan->clear();
// connect(this, &ColnodAPI::dataProcessed, this, &ColnodAPI::loadDataFromColnod);
//}
// For full sync
void ColnodAPI::prepareDatabase()
{
dataMan->emptyDatabase();
@ -173,9 +212,9 @@ void ColnodAPI::areChangedDataReady()
}
void ColnodAPI::isProcessDone()
void ColnodAPI::areDataProcessed()
{
if (dataMan->haveProcessData())
if (deleteFinished && updateFinished)
{
emit dataProcessed();
}

View File

@ -13,19 +13,11 @@ class ColnodAPI : public QObject
public:
ColnodAPI();
///
//void downloadData();
//void syncDataFromColnod();
//void syncDataToColnod();
///
ColnodAPI(bool debugMode = false);
void syncDataFromColnod();
void syncDataFromDB();
void prepareDatabase();
public slots:
@ -36,6 +28,7 @@ public slots:
signals:
void dataDownloaded();
void dataProcessed();
void syncFinished();
private slots:
@ -52,17 +45,17 @@ private:
void syncDeletedDataFromColnod();
void areDataReady();
void areChangedDataReady();
void isProcessDone();
void areDataProcessed();
void processDataToColnod();
RequestManager* reqMan = nullptr;
// Data* data = nullptr;
DataManager* dataMan = nullptr;
bool dataReady[2] = {false};
int index = 0;
const int numOfMembers = 2;
bool debugMode = false;
bool updateFinished = false;
bool deleteFinished = false;
};
#endif // COLNODAPI_H

View File

@ -25,20 +25,24 @@ void DatabaseManager::saveSubject(Subject* subject, QString table)
QString id = subject->idToStringWithoutBraces();
if (checkIfExists(id, table))
{
query.prepare(QString("UPDATE %1 SET name = :name, last_update = :last_update "
query.prepare(QString("UPDATE %1 SET id = :id, description = :description, last_update = last_update:, name = :name, pin = :pin"
"WHERE id = :id)").arg(table));
query.bindValue(":id", id);
query.bindValue(":description", subject->getDescription());
query.bindValue(":name", subject->getName());
query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
query.bindValue(":pin", subject->getPin());
query.exec();
}
else
{
query.prepare(QString("INSERT INTO %1 (id, name, last_update) "
"VALUES (:id, :name, :last_update)").arg(table));
query.prepare(QString("INSERT INTO %1 (id, description, last_update, name, pin) "
"VALUES (:id, :description, :last_update, :name, :pin)").arg(table));
query.bindValue(":id", id);
query.bindValue(":name", subject->getName());
query.bindValue(":description", subject->getDescription());
query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
query.bindValue(":name", subject->getName());
query.bindValue(":pin", subject->getPin());
query.exec();
}
}
@ -48,22 +52,41 @@ void DatabaseManager::saveToken(Token* token, QString table)
QString id = token->idToStringWithoutBraces();
if (checkIfExists(id, table))
{
query.prepare(QString("UPDATE %1 SET last_update = :last_update, token_data = :data, subject_id = :subject_id) "
query.prepare(QString("UPDATE %1 SET id = :id, auth_errors = :auth_errors, description = :description, enabled = :enabled, name = :name, no_validity = :no_validity, time_to_live = :time_to_live, token_bits = :token_bits, token_data = :token_data, token_type = :token_type, subject_id = :subject_id, last_modified = :last_modified deleted = :deleted) "
"WHERE id = :id").arg(table));
query.bindValue(":id", id);
query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
query.bindValue(":data", token->getTokenData());
query.bindValue(":auth_errors", token->getAuthErrors());
query.bindValue(":description", token->getDescription());
query.bindValue(":enabled", token->getFlags().contains("Enabled"));
query.bindValue(":name", token->getName());
query.bindValue(":no_validity", token->getFlags().contains("NoValidity"));
query.bindValue(":time_to_live", token->getTimeToLive());
query.bindValue(":token_bits", token->getTokenBits());
query.bindValue(":token_data", token->getTokenData());
query.bindValue(":token_type", token->getTokenType());
query.bindValue(":subject_id", token->subjectIdToStringWithoutBraces());
query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
query.bindValue(":deleted", token->getDeleted());
query.exec();
}
else
{
query.prepare(QString("INSERT INTO %1 (id, last_update, token_data, subject_id) "
"VALUES (:id, :last_update, :data, :subject_id)").arg(table));
query.prepare(QString("INSERT INTO %1 (id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted) "
"VALUES (:id, :auth_errors, :description, :enabled, :last_update, :name, :no_validity, :time_to_live, :token_bits, :token_data, :token_type, :subject_id, :last_modified, :deleted)").arg(table));
query.bindValue(":id", id);
query.bindValue(":auth_errors", token->getAuthErrors());
query.bindValue(":description", token->getDescription());
query.bindValue(":enabled", token->getFlags().contains("Enabled"));
query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
query.bindValue(":data", token->getTokenData());
query.bindValue(":name", token->getName());
query.bindValue(":no_validity", token->getFlags().contains("NoValidity"));
query.bindValue(":time_to_live", token->getTimeToLive());
query.bindValue(":token_bits", token->getTokenBits());
query.bindValue(":token_data", token->getTokenData());
query.bindValue(":token_type", token->getTokenType());
query.bindValue(":subject_id", token->subjectIdToStringWithoutBraces());
query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
query.bindValue(":deleted", token->getDeleted());
query.exec();
}
}
@ -96,10 +119,13 @@ void DatabaseManager::saveSubjectAttribute(Subject *subject, QString table)
}
}
void DatabaseManager::deleteItem(QString id, QString table)
void DatabaseManager::setDeleted(QString id, QString table)
{
query.prepare(QString("DELETE FROM %1 WHERE id = :id").arg(table));
quint64 now = getNow();
QString nowString = QDateTime::fromMSecsSinceEpoch(now).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", nowString);
query.exec();
}
@ -125,7 +151,6 @@ int DatabaseManager::createTestRecord(QString msg)
return id;
}
bool DatabaseManager::checkIfExists(QString id, QString table)
{
query.prepare(QString("SELECT EXISTS(SELECT 1 FROM %1 WHERE id = :id)").arg(table));
@ -143,36 +168,51 @@ void DatabaseManager::dropTables()
void DatabaseManager::createTables()
{
query.exec("CREATE TABLE colnod_subject ("
"id CHAR(36) primary key,"
"name VARCHAR(255),"
"last_update timestamp)");
"id character(36) primary key NOT NULL,"
//"access_pin smallint,"
"description character varying(255),"
"last_update timestamp NOT NULL,"
"name character varying(255),"
"pin character varying(255))");
query.exec("CREATE TABLE colnod_token ("
"id CHAR(36) primary key,"
"id CHAR(36) primary key NOT NULL,"
"auth_errors INTEGER NOT NULL,"
"description VARCHAR(255),"
"enabled BOOLEAN NOT NULL,"
"last_update timestamp NOT NULL,"
"name VARCHAR(255),"
"no_validity BOOLEAN NOT NULL,"
"time_to_live INTEGER NOT NULL,"
"token_bits INTEGER,"
"token_data VARCHAR(255),"
"token_type VARCHAR(255),"
"subject_id CHAR(36),"
"last_update timestamp)");
"last_modified timestamp,"
"deleted BOOLEAN)");
query.exec("CREATE TABLE colnod_subject_attribute ("
"id VARCHAR(255) primary key,"
"attribute_key VARCHAR(255),"
"attribute_value VARCHAR(255),"
"subject_id CHAR(36))");
query.exec("CREATE TABLE users ("
"id VARCHAR(255) primary key,"
"email VARCHAR(255),"
"token_data VARCHAR(255),"
"last_update timestamp)");
}
uint64_t DatabaseManager::getAndSetLastSync()
uint64_t DatabaseManager::getLastSync()
{
query.exec("SELECT EXTRACT(EPOCH FROM (SELECT last_sync FROM config))*1000");
query.exec("SELECT last_sync FROM config");
query.next();
uint64_t temp = query.value(0).toULongLong();
query.exec("UPDATE config SET last_sync = NOW()");
quint64 temp = query.value(0).toULongLong();
return temp;
}
void DatabaseManager::updateLastSync(quint64 lastSync)
{
query.prepare("UPDATE config SET last_sync = :last_sync");
query.bindValue(":last_sync", lastSync);
query.exec();
}
void DatabaseManager::makeTestingLast_sync()
{
query.prepare("INSERT INTO last_changes (last_sync) "
@ -181,15 +221,6 @@ void DatabaseManager::makeTestingLast_sync()
query.exec();
}
void DatabaseManager::updateLastSync()
{
query.prepare("INSERT INTO changes (last_sync) "
"VALUES (:time)");
query.bindValue(":time", QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz"));
query.exec();
}
QSqlQuery* DatabaseManager::getTokensToAdd()
{
QSqlQuery* qry = new QSqlQuery;
@ -212,3 +243,42 @@ QUuid DatabaseManager::getId(QString name)
query.next();
return query.value(0).toUuid();
}
QSqlQuery* DatabaseManager::getUpdatedTokens()
{
QSqlQuery* qry = new QSqlQuery;
qry->exec("SELECT id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted "
"FROM colnod_token WHERE EXTRACT(EPOCH FROM last_modified) * 1000 > EXTRACT(EPOCH FROM last_update) * 1000");
return qry;
}
QSqlQuery* DatabaseManager::getToken(QString id)
{
QSqlQuery* qry = new QSqlQuery;
qry->prepare("SELECT SELECT id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted "
"FROM colnod_token WHERE id = :id");
qry->bindValue(":id", id);
qry->exec();
if (qry->next()){
return qry;
}
else {
return nullptr;
}
}
quint64 DatabaseManager::getNow()
{
query.exec("SELECT EXTRACT(EPOCH FROM NOW())*1000");
query.next();
return query.value(0).toULongLong();
}
void DatabaseManager::setLastUpdate(QString id, quint64 lastUpdate)
{
query.prepare("UPDATE colnod_token SET last_update = :lastUpdate WHERE id = :id");
query.bindValue(":id", id);
query.bindValue(":lastUpdate", lastUpdate);
query.exec();
}

View File

@ -23,7 +23,8 @@ public:
void saveSubject(Subject* subject, QString table);
void saveToken(Token* token, QString table);
void saveSubjectAttribute(Subject* subject, QString table);
void deleteItem(QString id, QString table);
void setDeleted(QString id, QString table);
QString getTestMessage(int id);
int createTestRecord(QString msg);
@ -35,12 +36,19 @@ public:
void createTables();
bool getOpened() {return opened;}
uint64_t getAndSetLastSync();
void updateLastSync();
quint64 getLastSync();
void updateLastSync(quint64 lastSync);
quint64 getNow();
QSqlQuery* getUpdatedTokens();
QSqlQuery* getToken(QString id);
// Old version
QSqlQuery* getTokensToAdd();
QSqlQuery* getTokensToDelete();
void setLastUpdate(QString id, quint64 lastUpdate);
QUuid getId(QString name);

View File

@ -3,7 +3,9 @@
DataManager::DataManager()
{
db = new DatabaseManager("192.168.1.94", "deloitte", "postgres", "34rjkciea12");
lastSync = db->getAndSetLastSync();
nextLastSync = db->getNow();
lastSync = db->getLastSync();
qDebug() << lastSync;
//db = new DatabaseManager("localhost", "deloitte", "postgres", "34rjkciea12");
}
@ -37,13 +39,14 @@ void DataManager::fillTokensColnod(QString response)
{
auto token = new Token();
token->fromJSON(item.toObject());
tokensColnod.insert(token->idToStringWithoutBraces(), token);
token->setDeleted(false);
tokensToUpdateColnod.insert(token->idToStringWithoutBraces(), token);
}
}
else
{
auto token = new Token("empty");
tokensColnod.insert(token->idToStringWithoutBraces(), token);
tokensToUpdateColnod.insert(token->idToStringWithoutBraces(), token);
}
}
@ -67,10 +70,18 @@ void DataManager::fillSubjectsColnod(QString response)
}
}
// fills tokensDB and tokensToDeleteDB
void DataManager::fillTokensDB()
{
QSqlQuery* query = db->getUpdatedTokens(lastSync);
// TODO
QSqlQuery* query = db->getUpdatedTokens();
while (query->next())
{
auto token = new Token;
token->fromSQLRecord(query);
tokensToUpdateDB.insert(token->idToStringWithoutBraces(), token);
}
qDebug() << "Number of tokens to update from DB: "<< tokensToUpdateDB.size();
qDebug() << "Number of tokens to delete from DB: "<< tokensToDeleteDB.size();
}
void DataManager::fillSubjectsDB()
@ -84,14 +95,11 @@ void DataManager::fillSubjectsToDeleteColnod(QString json)
QJsonArray items = doc.object()["items"].toArray();
if (items.size() > 0)
{
for (QJsonValueRef item : items)
{
for (QJsonValueRef item : items) {
subjectsToDeleteColnod.append(item.toString());
}
}
else
{
else {
subjectsToDeleteColnod.append("empty");
}
}
@ -102,13 +110,11 @@ void DataManager::fillTokensToDeleteColnod(QString json)
QJsonArray items = doc.object()["items"].toArray();
if (items.size() > 0)
{
for (QJsonValueRef item : items)
{
for (QJsonValueRef item : items) {
tokensToDeleteColnod.append(item.toString());
}
}
else
{
else {
tokensToDeleteColnod.append("empty");
}
}
@ -118,16 +124,9 @@ void DataManager::fillSubjectsToDeleteDB()
// Not needed yet
}
void DataManager::fillTokensToDeleteDB()
{
// TODO
// get data from db, maybe it's better to get all tokens together then filter deleted
}
void DataManager::pushSubjectsToDB()
{
if (subjectsColnod.contains("empty"))
{
if (subjectsColnod.contains("empty")) {
qDebug() << "All subjects are up to date";
return;
}
@ -145,19 +144,19 @@ void DataManager::pushSubjectsToDB()
void DataManager::pushTokensToDB()
{
if (tokensColnod.contains("empty"))
if (tokensToUpdateColnod.contains("empty"))
{
qDebug() << "All tokens are up to date";
return;
}
//QSqlDatabase::database().transaction();
qDebug() << "Tokens in progress...";
for (auto token : tokensColnod)
for (auto token : tokensToUpdateColnod)
{
db->saveToken(token, "colnod_token");
}
//QSqlDatabase::database().commit();
qDebug() << tokensColnod.size() << " tokens has been updated";
qDebug() << tokensToUpdateColnod.size() << " tokens has been updated";
}
void DataManager::deleteSubjectsFromDB()
@ -168,12 +167,10 @@ void DataManager::deleteSubjectsFromDB()
return;
}
qDebug() << "Deleted subjects in progress...";
//QSqlDatabase::database().transaction();
for (auto subjectId : subjectsToDeleteColnod)
{
db->deleteItem(subjectId, "colnod_subject");
db->setDeleted(subjectId, "colnod_subject");
}
//QSqlDatabase::database().commit();
qDebug() << subjectsToDeleteColnod.size() << "subject has beed deleted";
}
@ -184,33 +181,35 @@ void DataManager::deleteTokensFromDB()
qDebug() << "No tokens to be deleted";
return;
}
// QSqlDatabase::database().transaction();
qDebug() << "Deleted tokens in progress...";
for (auto tokenId : tokensToDeleteColnod)
{
db->deleteItem(tokenId, "colnod_token");
db->setDeleted(tokenId, "colnod_token");
}
//QSqlDatabase::database().commit();
qDebug() << tokensToDeleteColnod.size() << "tokens has beed deleted";
}
bool DataManager::haveData()
{
if ( !subjectsColnod.isEmpty() && !tokensColnod.isEmpty() )
if ( !subjectsColnod.isEmpty() && !tokensToUpdateColnod.isEmpty() )
return true;
return false;
}
bool DataManager::haveChangedData()
{
if ( !subjectsColnod.isEmpty() && !tokensColnod.isEmpty() && !subjectsToDeleteColnod.isEmpty() && !tokensToDeleteColnod.isEmpty() )
if ( !subjectsColnod.isEmpty() &&
!tokensToUpdateColnod.isEmpty() &&
!subjectsToDeleteColnod.isEmpty() &&
!tokensToDeleteColnod.isEmpty() &&
!fullTokensColnod.isEmpty() )
return true;
return false;
}
bool DataManager::haveProcessData()
{
if ( !tokensColnod.isEmpty() && !tokensToDeleteColnod.isEmpty())
if ( !tokensToUpdateColnod.isEmpty() && !tokensToDeleteColnod.isEmpty())
return true;
return false;
}
@ -225,19 +224,48 @@ void DataManager::clear()
{
subjectsColnod.clear();
subjectsToDeleteColnod.clear();
tokensColnod.clear();
tokensToUpdateColnod.clear();
tokensToDeleteColnod.clear();
subjectsDB.clear();
subjectsToDeleteDB.clear();
tokensDB.clear();
tokensToUpdateDB.clear();
tokensToDeleteDB.clear();
fullTokensColnod.clear();
}
void DataManager::updateLastSync()
{
db->updateLastSync();
db->updateLastSync(nextLastSync);
}
void DataManager::filterTokensDB()
{
for (auto token : tokensToUpdateDB)
{
QString id = token->idToStringWithoutBraces();
Q_ASSERT(token = fullTokensColnod.value(id));
if (fullTokensColnod.contains(id) && token < fullTokensColnod.value(id))
tokensToUpdateDB.remove(id);
}
}
void DataManager::filterTokensColnod()
{
for (auto token : tokensToUpdateColnod)
{
QString id = token->idToStringWithoutBraces();
auto record = db->getToken(id);
if (!record)
continue;
auto tokenDB = new Token;
tokenDB->fromSQLRecord(record);
Q_ASSERT(tokenDB != token);
if (tokenDB > token)
tokensToUpdateColnod.remove(id);
}
}
// old version
void DataManager::loadTokensToAdd()
{
QSqlQuery* query = db->getTokensToAdd();
@ -245,10 +273,10 @@ void DataManager::loadTokensToAdd()
{
Token* token = new Token(query->value(0).toString(), query->value(1).toString());
token->setSubjectId(db->getId(token->getName()));
tokensDB.insert(token->idToStringWithoutBraces(), token);
tokensToUpdateDB.insert(token->idToStringWithoutBraces(), token);
}
if (tokensDB.isEmpty())
tokensDB.insert("empty", nullptr);
if (tokensToUpdateDB.isEmpty())
tokensToUpdateDB.insert("empty", nullptr);
}
void DataManager::loadTokensToDelete()
@ -263,4 +291,12 @@ void DataManager::loadTokensToDelete()
}
void DataManager::setLastUpdate()
{
for (auto token : tokensToUpdateColnod){
db->setLastUpdate(token->idToStringWithoutBraces(), token->getLastUpdate());
}
}

View File

@ -28,7 +28,9 @@ public:
void fillTokensDB();
void fillSubjectsDB();
void fillSubjectsToDeleteDB();
void fillTokensToDeleteDB();
void filterTokensDB();
void filterTokensColnod();
void pushSubjectsToDB();
void pushTokensToDB();
@ -42,26 +44,34 @@ public:
bool haveProcessData();
void emptyDatabase();
void clear();
void loadTokensToAdd();
void loadTokensToDelete();
QHash<QString, QPointer<Token>>* getTokens() {return &tokensColnod;}
QList<QString>* getTokensToDelete() {return &tokensToDeleteColnod;}
QHash<QString, QPointer<Token>> getTokensToUpdateColnod() {return tokensToUpdateColnod;}
QList<QString> getTokensToDeleteColnod() {return tokensToDeleteColnod;}
QHash<QString, QPointer<Token>> getTokensToUpdateDB() {return tokensToUpdateDB;}
QList<QString> getTokensToDeleteDB() {return tokensToDeleteDB;}
const uint64_t &getLastSync() {return lastSync;}
const quint64 &getLastSync() {return lastSync;}
const quint64 &getActualSync() {return nextLastSync;}
public slots:
void clear();
void setLastSync() {db->updateLastSync(nextLastSync);}
void setLastUpdate();
private:
DatabaseManager *db = nullptr;
uint64_t lastSync;
quint64 lastSync;
quint64 nextLastSync;
QHash<QString, QPointer<Subject>> subjectsColnod;
QHash<QString, QPointer<Token>> tokensColnod;
QHash<QString, QPointer<Token>> tokensToUpdateColnod;
QHash<QString, QPointer<Token>> fullTokensColnod;
QHash<QString, QPointer<Subject>> subjectsDB; // in future
QHash<QString, QPointer<Token>> tokensDB;
QHash<QString, QPointer<Token>> tokensToUpdateDB;
QList<QString> subjectsToDeleteColnod;

View File

@ -25,11 +25,11 @@ void Entity::setDescription(const QString &description) {
Entity::description = description;
}
uint64_t Entity::getLastUpdate() const {
quint64 Entity::getLastUpdate() const {
return lastUpdate;
}
void Entity::setLastUpdate(uint64_t lastUpdate) {
void Entity::setLastUpdate(quint64 lastUpdate) {
this->lastUpdate = lastUpdate;
}
@ -48,7 +48,7 @@ void Entity::fromJSON(const QJsonObject &json) {
QJsonObject Entity::toJSON() const {
QJsonObject json;
json.value("id") = id.toString();
json.value("id") = id.toString().mid(1,36);
json.value("name") = name;
json.value("description") = description;
json.value("lastUpdate") = lastUpdate;

View File

@ -20,8 +20,8 @@ public:
const QString &getDescription() const;
void setDescription(const QString &description);
uint64_t getLastUpdate() const;
void setLastUpdate(uint64_t lastUpdate);
quint64 getLastUpdate() const;
void setLastUpdate(quint64 lastUpdate);
QString idToStringWithoutBraces();

View File

@ -18,6 +18,7 @@ RequestManager::RequestManager()
Response* RequestManager::login()
{
Q_ASSERT(!loginResponse);
loginResponse = new Response;
QNetworkRequest request;
QString hash = encryptedPassword(this->password);
@ -157,28 +158,13 @@ QByteArray RequestManager::makeTimeStampJson(uint64_t time)
return doc.toJson();
}
QByteArray RequestManager::makeTokensJson(QHash<QString, QPointer<Token> > *tokens)
QByteArray RequestManager::makeTokensJson(const QHash<QString, QPointer<Token> > &tokens)
{
QJsonObject items;
QJsonArray jsonTokens;
for (auto token : *tokens)
for (auto token : tokens)
{
QJsonObject jsonToken;
jsonToken.insert("id",token->idToStringWithoutBraces());
jsonToken.insert("name",token->getName());
jsonToken.insert("description", token->getDescription());
jsonToken.insert("tokenType", token->getTokenType());
jsonToken.insert("tokenBits", token->getTokenBits());
jsonToken.insert("tokenData", token->getTokenData());
jsonToken.insert("timeToLive", token->getTimeToLive());
jsonToken.insert("authErrors", token->getAuthErrors());
QJsonArray flags;
auto flagStructure = token->getFlags();
for (auto flag : flagStructure)
flags.push_back(flag);
jsonToken.insert("flags", flags);
jsonToken.insert("subjectId", token->subjectIdToStringWithoutBraces());
jsonTokens.push_back(jsonToken);
jsonTokens.push_back(token->toJSON());
}
items.insert("items", jsonTokens);
QJsonDocument doc;
@ -186,10 +172,10 @@ QByteArray RequestManager::makeTokensJson(QHash<QString, QPointer<Token> > *toke
return doc.toJson();
}
QByteArray RequestManager::makeIdsJson(QList<QString>* ids)
QByteArray RequestManager::makeIdsJson(const QList<QString> &ids)
{
QJsonArray jsonIds;
for (auto id : *ids)
for (auto id : ids)
{
jsonIds.push_back(id);
}
@ -265,12 +251,12 @@ Response* RequestManager::getAccessGroupMembershipDeleted(uint64_t time)
return postRequestReturnLogic("/AccessManager/getAccessGroupMembershipDeleted", makeTimeStampJson(time));
}
Response* RequestManager::setTokens(QHash<QString, QPointer<Token> > *tokens)
Response* RequestManager::setTokens(const QHash<QString, QPointer<Token> > &tokens)
{
return postRequestReturnLogic("/TokenManager/setTokens", makeTokensJson(tokens));
}
Response* RequestManager::deleteTokens(QList<QString>* ids)
Response* RequestManager::deleteTokens(const QList<QString> &ids)
{
return postRequestReturnLogic("/TokenManager/deleteTokens", makeIdsJson(ids));
}

View File

@ -49,8 +49,8 @@ public:
Response* getAccessGroupMembershipUpdated(uint64_t time);
Response* getAccessGroupMembershipDeleted(uint64_t time);
Response* setTokens(QHash<QString, QPointer<Token>>* tokens);
Response* deleteTokens(QList<QString>* ids);
Response* setTokens(const QHash<QString, QPointer<Token>> &tokens);
Response* deleteTokens(const QList<QString> &ids);
Response* login(); //I want it private, but unittest???
@ -65,8 +65,8 @@ private:
QString getLoginHeader(QString username, QString hash);
QByteArray makeTimeStampJson(uint64_t time);
QByteArray makeTokensJson(QHash<QString, QPointer<Token>>* tokens);
QByteArray makeIdsJson(QList<QString>* ids);
QByteArray makeTokensJson(const QHash<QString, QPointer<Token>> &tokens);
QByteArray makeIdsJson(const QList<QString> &ids);
Response* getLoginResponse();
private slots:

View File

@ -21,6 +21,7 @@ Token::Token(QString namee)
this->name = namee;
}
void Token::fromJSON(const QJsonObject &json) {
Entity::fromJSON(json);
@ -49,11 +50,33 @@ QJsonObject Token::toJSON() const {
json.value("timeToLive") = timeToLive;
json.value("authErrors") = authErrors;
json.value("flags") = QJsonArray::fromStringList(flags.toList());
json.value("subjectId") = subjectId.toString();
json.value("subjectId") = subjectId.toString().mid(1,36);
return json;
}
void Token::fromSQLRecord(QSqlQuery *query)
{
id = query->value(0).toUuid();
authErrors = query->value(1).toInt();
description = query->value(2).toString();
QSet<QString> flags;
if (query->value(6).toBool())
flags.insert("NoValidity");
if (query->value(3).toBool())
flags.insert("Enabled");
this->flags = flags;
lastUpdate = query->value(4).toUInt();
name = query->value(5).toString();
timeToLive = query->value(7).toInt();
tokenBits = query->value(8).toInt();
tokenData = query->value(9).toString();
tokenType = query->value(10).toString();
subjectId = query->value(11).toUuid();
lastModified = query->value(12).toUInt();
deleted = query->value(13).toBool();
}
const QString &Token::getTokenType() const {
return tokenType;
}
@ -78,19 +101,19 @@ void Token::setTokenData(const QString &tokenData) {
Token::tokenData = tokenData;
}
qint64 Token::getValidFrom() const {
quint64 Token::getValidFrom() const {
return validFrom;
}
void Token::setValidFrom(qint64 validFrom) {
void Token::setValidFrom(quint64 validFrom) {
Token::validFrom = validFrom;
}
qint64 Token::getValidTo() const {
quint64 Token::getValidTo() const {
return validTo;
}
void Token::setValidTo(qint64 validTo) {
void Token::setValidTo(quint64 validTo) {
Token::validTo = validTo;
}
@ -129,3 +152,21 @@ void Token::setSubjectId(const QUuid &subjectId) {
QString Token::subjectIdToStringWithoutBraces(){
return subjectId.toString().mid(1,36);
}
quint64 Token::getLastModified() const {
return lastModified;
}
void Token::setLastModified(const quint64 &lastModified) {
Token::lastModified = lastModified;
}
bool Token::getDeleted() const
{
return deleted;
}
void Token::setDeleted(const bool &deleted)
{
this->deleted = deleted;
}

View File

@ -4,6 +4,8 @@
#include "entity.h"
#include <QSet>
#include <qsqlquery.h>
#include <QVariant>
class Token : public Entity {
@ -13,16 +15,24 @@ public:
Token() = default;
Token(QString name, QString tokenData, QString decription = "mobile");
Token(QString name);
friend bool operator<(const Token &rToken, const Token &lToken){
return rToken.getLastModified() < lToken.getLastUpdate();
}
friend bool operator>(const Token &rToken, const Token &lToken){
return rToken.getLastModified() > lToken.getLastUpdate();
}
const QString &getTokenType() const;
void setTokenType(const QString &tokenType);
int getTokenBits() const;
void setTokenBits(int tokenBits);
const QString &getTokenData() const;
void setTokenData(const QString &tokenData);
qint64 getValidFrom() const;
void setValidFrom(qint64 validFrom);
qint64 getValidTo() const;
void setValidTo(qint64 validTo);
quint64 getValidFrom() const;
void setValidFrom(quint64 validFrom);
quint64 getValidTo() const;
void setValidTo(quint64 validTo);
int getTimeToLive() const;
void setTimeToLive(int timeToLive);
int getAuthErrors() const;
@ -31,22 +41,28 @@ public:
void setFlags(const QSet<QString> &flags);
const QUuid &getSubjectId() const;
void setSubjectId(const QUuid &subjectId);
quint64 getLastModified() const;
void setLastModified(const quint64 &lastModified);
bool getDeleted() const;
void setDeleted(const bool &deleted);
QString subjectIdToStringWithoutBraces();
void fromSQLRecord(QSqlQuery* query);
void fromJSON(const QJsonObject &json) override;
QJsonObject toJSON() const override;
protected:
QString tokenType;
int tokenBits;
QString tokenData;
qint64 validFrom;
qint64 validTo;
quint64 validFrom;
quint64 validTo;
int timeToLive;
int authErrors;
QSet<QString> flags;
QUuid subjectId;
quint64 lastModified;
bool deleted;
};

View File

@ -222,7 +222,7 @@ void UnitTest::setTokens()
}
RequestManager* testAccess = new RequestManager();
QSignalSpy spy(testAccess, SIGNAL(responseReady()));
Response* response = testAccess->setTokens(&tokens);
Response* response = testAccess->setTokens(tokens);
QCOMPARE(spy.count(), 0);
spy.wait(15000);
QVERIFY(spy.isValid());
@ -238,7 +238,7 @@ void UnitTest::deleteTokens()
QList<QString> ids;
ids.append("582c982d-6fd7-4856-8548-7ce542791c7a");
ids.append("3ff23b41-3da3-4b33-82ce-d8e2d8c9a546");
Response* response = testAccess->deleteTokens(&ids);
Response* response = testAccess->deleteTokens(ids);
QCOMPARE(spy.count(), 0);
spy.wait(15000);
QVERIFY(spy.isValid());

View File

@ -2,25 +2,38 @@
void ComplexTest::initTestCase()
{
reqMan = new RequestManager;
auto reqMan1 = new RequestManager;
QList<QString> ids;
ids.append("582c982d-6fd7-4856-8548-7ce542791c7a");
ids.append("3ff23b41-3da3-4b33-82ce-d8e2d8c9a546");
Response* deleteTokensResp = reqMan1->deleteTokens(ids);
QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready);
QCOMPARE(deleteTokensRespSpy.count(), 0);
deleteTokensRespSpy.wait(10000);
QTest::qWait(2500);
start = QDateTime::currentMSecsSinceEpoch()-2000;
api = new ColnodAPI;
qDebug() << start;
}
void ComplexTest::cleanupTestCase()
{
QList<QString> ids;
ids.append("582c982d-6fd7-4856-8548-7ce542791c7a");
Response* deleteTokensResp = reqMan->deleteTokens(&ids);
ids.append("3ff23b41-3da3-4b33-82ce-d8e2d8c9a546");
auto reqMan = new RequestManager;
Response* deleteTokensResp = reqMan->deleteTokens(ids);
QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready);
QCOMPARE(deleteTokensRespSpy.count(), 0);
deleteTokensRespSpy.wait(10000);
QCOMPARE(deleteTokensRespSpy.count(), 1);
}
void ComplexTest::complexTest()
{
// LOGIN_BEGIN
reqMan = new RequestManager;
QSignalSpy loginSpy(reqMan, &RequestManager::successLogin);
Response* loginResp = reqMan->login();
QSignalSpy loginRespSpy(loginResp, &Response::ready);
@ -46,7 +59,7 @@ void ComplexTest::complexTest()
QHash<QString, QPointer<Token>> tokens;
auto token = getTestToken();
tokens.insert(token->idToStringWithoutBraces(), token);
Response* setTokensResp = reqMan->setTokens(&tokens);
Response* setTokensResp = reqMan->setTokens(tokens);
QSignalSpy setTokensRespSpy(setTokensResp, &Response::ready);
QCOMPARE(setTokensRespSpy.count(), 0);
setTokensRespSpy.wait(10000);
@ -70,7 +83,7 @@ void ComplexTest::complexTest()
// DELETE_TOKENS_CHECK_BEGIN
QList<QString> ids;
ids.append("582c982d-6fd7-4856-8548-7ce542791c7a");
Response* deleteTokensResp = reqMan->deleteTokens(&ids);
Response* deleteTokensResp = reqMan->deleteTokens(ids);
QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready);
QCOMPARE(deleteTokensRespSpy.count(), 0);
deleteTokensRespSpy.wait(10000);
@ -104,7 +117,7 @@ void ComplexTest::complexTest()
void ComplexTest::fullSync()
{
api->prepareDatabase();
api->downloadData();
api->loadDataFromColnod();
QSignalSpy spy(api, &ColnodAPI::dataDownloaded);
spy.wait(10000);
api->syncDataFromColnod();
@ -116,11 +129,12 @@ void ComplexTest::syncLastUpdated()
api->loadDataFromColnod();
QSignalSpy spy(api, &ColnodAPI::dataDownloaded);
spy.wait(10000);
api->loadDataFromDB();
api->syncDataFromColnod();
// api->syncChangedDataToColnod();
spy.wait(10000);
api->syncDataFromColnod();
api->syncDataFromDB();
QSignalSpy processSpy(api, &ColnodAPI::dataProcessed);
processSpy.wait(10000);
qDebug() << "All right, at least should be.";
}