diff --git a/services/backup/docker-server/contents/server/src/Reactors/server/SendLogReactor.h b/services/backup/docker-server/contents/server/src/Reactors/server/SendLogReactor.h index 349c2724b..9d3da8823 100644 --- a/services/backup/docker-server/contents/server/src/Reactors/server/SendLogReactor.h +++ b/services/backup/docker-server/contents/server/src/Reactors/server/SendLogReactor.h @@ -1,107 +1,129 @@ #pragma once #include "Constants.h" #include "ServerReadReactorBase.h" #include "../_generated/backup.grpc.pb.h" #include "../_generated/backup.pb.h" #include #include #include namespace comm { namespace network { namespace reactor { class SendLogReactor : public ServerReadReactorBase< backup::SendLogRequest, google::protobuf::Empty> { enum class State { USER_ID = 1, LOG_CHUNK = 2, }; enum class PersistenceMethod { UNKNOWN = 0, DB = 1, BLOB = 2, }; State state = State::USER_ID; PersistenceMethod persistenceMethod = PersistenceMethod::UNKNOWN; std::string userID; + std::string backupID; + // either the value itself which is a dump of a single operation (if + // `persistedInBlob` is false) or the holder to blob (if `persistedInBlob` is + // true) + std::string value; - void storeInDatabase(const std::string &data) { - } + void storeInDatabase(); + std::string generateLogID(); void storeInBlob(const std::string &data) { } public: using ServerReadReactorBase:: ServerReadReactorBase; std::unique_ptr readRequest(backup::SendLogRequest request) override; void doneCallback() override; }; +void SendLogReactor::storeInDatabase() { + // TODO handle attachment holders + database::LogItem logItem( + this->backupID, + this->generateLogID(), + (this->persistenceMethod == PersistenceMethod::BLOB), + this->value, + {}); + database::DatabaseManager::getInstance().putLogItem(logItem); +} + +std::string SendLogReactor::generateLogID() { + // TODO replace mock + return generateRandomString(); +} + std::unique_ptr SendLogReactor::readRequest(backup::SendLogRequest request) { switch (this->state) { case State::USER_ID: { if (!request.has_userid()) { throw std::runtime_error("user id expected but not received"); } this->userID = request.userid(); this->state = State::LOG_CHUNK; return nullptr; }; case State::LOG_CHUNK: { if (!request.has_logdata()) { throw std::runtime_error("log data expected but not received"); } if (this->persistenceMethod == PersistenceMethod::DB) { throw std::runtime_error( "storing multiple chunks in the database is not allowed"); } std::string *chunk = request.mutable_logdata(); // decide if keep in DB or upload to blob if (chunk->size() <= LOG_DATA_SIZE_DATABASE_LIMIT) { if (this->persistenceMethod == PersistenceMethod::UNKNOWN) { this->persistenceMethod = PersistenceMethod::DB; - this->storeInDatabase(*chunk); + this->value = std::move(*chunk); + this->storeInDatabase(); } else if (this->persistenceMethod == PersistenceMethod::BLOB) { this->storeInBlob(*chunk); } else { throw std::runtime_error( "error - invalid persistence state for chunk smaller than " "database limit"); } } else { if (this->persistenceMethod != PersistenceMethod::UNKNOWN && this->persistenceMethod != PersistenceMethod::BLOB) { throw std::runtime_error( "error - invalid persistence state, uploading to blob should be " "continued but it is not"); } this->persistenceMethod = PersistenceMethod::BLOB; this->storeInBlob(*chunk); } std::cout << "log data received " << chunk->size() << std::endl; return nullptr; }; } throw std::runtime_error("send log - invalid state"); } void SendLogReactor::doneCallback() { // TODO implement std::cout << "receive logs done " << this->status.error_code() << "/" << this->status.error_message() << std::endl; } } // namespace reactor } // namespace network } // namespace comm