diff --git a/services/backup/docker-server/contents/server/CMakeLists.txt b/services/backup/docker-server/contents/server/CMakeLists.txt index fee1159b6..53fc4d4f6 100644 --- a/services/backup/docker-server/contents/server/CMakeLists.txt +++ b/services/backup/docker-server/contents/server/CMakeLists.txt @@ -1,132 +1,132 @@ PROJECT(backup C CXX) cmake_minimum_required(VERSION 3.16) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY bin) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) set(CMAKE_CXX_STANDARD 17) # FIND LIBS set(protobuf_MODULE_COMPATIBLE TRUE) find_package(Protobuf CONFIG REQUIRED) message(STATUS "Using protobuf ${Protobuf_VERSION}") set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf) set(_PROTOBUF_PROTOC $) # gRPC building parameters set(gRPC_BUILD_CSHARP_EXT OFF) set(gRPC_SSL_PROVIDER "package" CACHE STRING "SSL library provider") # Disable unused plugins set(gRPC_BUILD_GRPC_PHP_PLUGIN OFF) set(gRPC_BUILD_GRPC_RUBY_PLUGIN OFF) set(gRPC_BUILD_GRPC_PYTHON_PLUGIN OFF) set(gRPC_BUILD_GRPC_CSHARP_PLUGIN OFF) # Find gRPC installation # Looks for gRPCConfig.cmake file installed by gRPC's cmake installation. find_package(gRPC CONFIG REQUIRED) message(STATUS "Using gRPC ${gRPC_VERSION}") set(_GRPC_GRPCPP gRPC::grpc++) set(_GRPC_CPP_PLUGIN_EXECUTABLE $) set(BUILD_TESTING OFF CACHE BOOL "Turn off tests" FORCE) find_package(AWSSDK REQUIRED COMPONENTS core dynamodb) find_package(Boost 1.40 COMPONENTS program_options REQUIRED) file(GLOB GENERATED_CODE "./_generated/*.cc") set(DEV_SOURCE_CODE "") set(DEV_HEADERS_PATH "") if ($ENV{COMM_SERVICES_DEV_MODE} MATCHES 1) file(GLOB DEV_SOURCE_CODE "./dev/*.cpp" "./src/*.dev.cpp") set(DEV_HEADERS_PATH "./dev") endif() -file(GLOB SOURCE_CODE "./src/*.cpp") +file(GLOB SOURCE_CODE "./src/*.cpp" "./src/**/*.cpp") list(FILTER SOURCE_CODE EXCLUDE REGEX ".*.dev.cpp$") foreach (ITEM ${DEV_SOURCE_CODE}) string(REPLACE "/" ";" SPLIT_ITEM ${ITEM}) list(GET SPLIT_ITEM -1 FILE_FULL_NAME) string(REPLACE ".dev.cpp" ".cpp" FILE_NAME ${FILE_FULL_NAME}) list(FILTER SOURCE_CODE EXCLUDE REGEX ".*${FILE_NAME}$") list(APPEND SOURCE_CODE "${ITEM}") endforeach() include_directories( ./src ./src/DatabaseEntities ./_generated ${Boost_INCLUDE_DIR} ${DEV_HEADERS_PATH} ) set( LIBS ${_GRPC_GRPCPP} ${_PROTOBUF_LIBPROTOBUF} gRPC::grpc++_reflection ${AWSSDK_LINK_LIBRARIES} ${Boost_LIBRARIES} ) #SERVER add_executable( backup ${GENERATED_CODE} ${SOURCE_CODE} ) target_link_libraries( backup ${LIBS} ) install( TARGETS backup RUNTIME DESTINATION bin/ ) # TEST if ($ENV{COMM_TEST_SERVICES} MATCHES 1) file(GLOB TEST_CODE "./test/*.cpp") list(FILTER SOURCE_CODE EXCLUDE REGEX "./src/server.cpp") enable_testing() find_package(GTest REQUIRED) include_directories( ${GTEST_INCLUDE_DIR} ./test ) add_executable( runTests ${GENERATED_CODE} ${SOURCE_CODE} ${TEST_CODE} ) target_link_libraries( runTests ${LIBS} gtest gtest_main ) add_test( NAME runTests COMMAND runTests ) endif() diff --git a/services/backup/docker-server/contents/server/src/Constants.h b/services/backup/docker-server/contents/server/src/Constants.h index cb5f2328d..ac049429d 100644 --- a/services/backup/docker-server/contents/server/src/Constants.h +++ b/services/backup/docker-server/contents/server/src/Constants.h @@ -1,26 +1,32 @@ #pragma once #include namespace comm { namespace network { // 4MB limit // WARNING: use keeping in mind that grpc adds its own headers to messages // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md // so the message that actually is being sent over the network looks like this // [Compressed-Flag] [Message-Length] [Message] // [Compressed-Flag] 1 byte - added by grpc // [Message-Length] 4 bytes - added by grpc // [Message] N bytes - actual data // so for every message we get 5 additional bytes of data // as mentioned here // https://github.com/grpc/grpc/issues/15734#issuecomment-396962671 // grpc stream may contain more than one message const size_t GRPC_CHUNK_SIZE_LIMIT = 4 * 1024 * 1024; const size_t GRPC_METADATA_SIZE_PER_MESSAGE = 5; const std::string AWS_REGION = "us-east-2"; +#ifdef COMM_TEST_SERVICES +const std::string LOG_TABLE_NAME = "backup-service-log-test"; +#else +const std::string LOG_TABLE_NAME = "backup-service-log"; +#endif + } // namespace network } // namespace comm diff --git a/services/backup/docker-server/contents/server/src/DatabaseEntities/DatabaseEntitiesTools.h b/services/backup/docker-server/contents/server/src/DatabaseEntities/DatabaseEntitiesTools.h index e7e7d2cfe..ad0473960 100644 --- a/services/backup/docker-server/contents/server/src/DatabaseEntities/DatabaseEntitiesTools.h +++ b/services/backup/docker-server/contents/server/src/DatabaseEntities/DatabaseEntitiesTools.h @@ -1,19 +1,21 @@ #pragma once #include "Item.h" +#include "LogItem.h" + #include #include namespace comm { namespace network { namespace database { template std::shared_ptr createItemByType() { static_assert(std::is_base_of::value, "T must inherit from Item"); return std::make_shared(); } } // namespace database } // namespace network } // namespace comm diff --git a/services/backup/docker-server/contents/server/src/DatabaseEntities/LogItem.cpp b/services/backup/docker-server/contents/server/src/DatabaseEntities/LogItem.cpp new file mode 100644 index 000000000..c4e0f5ac4 --- /dev/null +++ b/services/backup/docker-server/contents/server/src/DatabaseEntities/LogItem.cpp @@ -0,0 +1,98 @@ +#include "LogItem.h" + +#include "AwsTools.h" +#include "Constants.h" + +#include + +namespace comm { +namespace network { +namespace database { + +const std::string LogItem::FIELD_BACKUP_ID = "backupID"; +const std::string LogItem::FIELD_LOG_ID = "logID"; +const std::string LogItem::FIELD_PERSISTED_IN_BLOB = "persistedInBlob"; +const std::string LogItem::FIELD_VALUE = "value"; +const std::string LogItem::FIELD_ATTACHMENT_HOLDERS = "attachmentHolders"; + +std::string LogItem::tableName = LOG_TABLE_NAME; + +LogItem::LogItem( + const std::string backupID, + const std::string logID, + const bool persistedInBlob, + const std::string value, + std::vector attachmentHolders) + : backupID(backupID), + logID(logID), + persistedInBlob(persistedInBlob), + value(value), + attachmentHolders(attachmentHolders) { + this->validate(); +} + +LogItem::LogItem(const AttributeValues &itemFromDB) { + this->assignItemFromDatabase(itemFromDB); +} + +void LogItem::validate() const { + if (!this->backupID.size()) { + throw std::runtime_error("backupID empty"); + } + if (!this->logID.size()) { + throw std::runtime_error("logID empty"); + } + if (!this->value.size()) { + throw std::runtime_error("value empty"); + } + // todo maybe check if values is not too big if persistedInBlob is false +} + +void LogItem::assignItemFromDatabase(const AttributeValues &itemFromDB) { + try { + this->backupID = itemFromDB.at(LogItem::FIELD_BACKUP_ID).GetS(); + this->logID = itemFromDB.at(LogItem::FIELD_LOG_ID).GetS(); + this->persistedInBlob = std::stoi( + std::string(itemFromDB.at(LogItem::FIELD_PERSISTED_IN_BLOB).GetS()) + .c_str()); + this->value = itemFromDB.at(LogItem::FIELD_VALUE).GetS(); + this->attachmentHolders = + itemFromDB.at(LogItem::FIELD_ATTACHMENT_HOLDERS).GetSS(); + } catch (std::logic_error &e) { + throw std::runtime_error( + "invalid log item provided, " + std::string(e.what())); + } + this->validate(); +} + +std::string LogItem::getTableName() const { + return LogItem::tableName; +} + +std::string LogItem::getPrimaryKey() const { + return LogItem::FIELD_BACKUP_ID; +} + +std::string LogItem::getBackupID() const { + return this->backupID; +} + +std::string LogItem::getLogID() const { + return this->logID; +} + +bool LogItem::getPersistedInBlob() const { + return this->persistedInBlob; +} + +std::string LogItem::getValue() const { + return this->value; +} + +std::vector LogItem::getAttachmentHolders() const { + return this->attachmentHolders; +} + +} // namespace database +} // namespace network +} // namespace comm diff --git a/services/backup/docker-server/contents/server/src/DatabaseEntities/LogItem.h b/services/backup/docker-server/contents/server/src/DatabaseEntities/LogItem.h new file mode 100644 index 000000000..f7148c8b9 --- /dev/null +++ b/services/backup/docker-server/contents/server/src/DatabaseEntities/LogItem.h @@ -0,0 +1,54 @@ +#pragma once + +#include "Item.h" + +#include +#include + +namespace comm { +namespace network { +namespace database { + +class LogItem : public Item { + + std::string backupID; + std::string logID; + bool persistedInBlob; + std::string value; + std::vector attachmentHolders; + + void validate() const override; + +public: + static std::string tableName; + static const std::string FIELD_BACKUP_ID; + static const std::string FIELD_LOG_ID; + static const std::string FIELD_PERSISTED_IN_BLOB; + static const std::string FIELD_VALUE; + static const std::string FIELD_ATTACHMENT_HOLDERS; + + LogItem() { + } + LogItem( + const std::string backupID, + const std::string logID, + const bool persistedInBlob, + const std::string value, + std::vector attachmentHolders); + LogItem(const AttributeValues &itemFromDB); + + void assignItemFromDatabase(const AttributeValues &itemFromDB) override; + + std::string getTableName() const override; + std::string getPrimaryKey() const override; + + std::string getBackupID() const; + std::string getLogID() const; + bool getPersistedInBlob() const; + std::string getValue() const; + std::vector getAttachmentHolders() const; +}; + +} // namespace database +} // namespace network +} // namespace comm