diff --git a/services/lib/src/DatabaseManagerBase.cpp b/services/lib/src/DatabaseManagerBase.cpp index 530bf3389..891710e8d 100644 --- a/services/lib/src/DatabaseManagerBase.cpp +++ b/services/lib/src/DatabaseManagerBase.cpp @@ -1,45 +1,47 @@ #include "DatabaseManagerBase.h" +#include "Item.h" + #include #include #include namespace comm { namespace network { namespace database { void DatabaseManagerBase::innerPutItem( std::shared_ptr item, const Aws::DynamoDB::Model::PutItemRequest &request) { const Aws::DynamoDB::Model::PutItemOutcome outcome = getDynamoDBClient()->PutItem(request); if (!outcome.IsSuccess()) { throw std::runtime_error(outcome.GetError().GetMessage()); } } void DatabaseManagerBase::innerRemoveItem(const Item &item) { Aws::DynamoDB::Model::DeleteItemRequest request; request.SetTableName(item.getTableName()); PrimaryKey pk = item.getPrimaryKey(); PrimaryKeyValue primaryKeyValue = item.getPrimaryKeyValue(); request.AddKey( pk.partitionKey, Aws::DynamoDB::Model::AttributeValue(primaryKeyValue.partitionKey)); if (pk.sortKey != nullptr && primaryKeyValue.sortKey != nullptr) { request.AddKey( *pk.sortKey, Aws::DynamoDB::Model::AttributeValue(*primaryKeyValue.sortKey)); } const Aws::DynamoDB::Model::DeleteItemOutcome &outcome = getDynamoDBClient()->DeleteItem(request); if (!outcome.IsSuccess()) { throw std::runtime_error(outcome.GetError().GetMessage()); } } } // namespace database } // namespace network } // namespace comm diff --git a/services/tunnelbroker/CMakeLists.txt b/services/tunnelbroker/CMakeLists.txt index faaee42d2..e0e5e42b4 100644 --- a/services/tunnelbroker/CMakeLists.txt +++ b/services/tunnelbroker/CMakeLists.txt @@ -1,150 +1,150 @@ PROJECT(tunnelbroker 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_package(PkgConfig REQUIRED) # FIND LIBS include(./cmake-components/grpc.cmake) include(./cmake-components/folly.cmake) # Find AMQP-CPP installation find_package(amqpcpp CONFIG REQUIRED) # Find Cryptopp installation pkg_check_modules(CRYPTOPP REQUIRED libcryptopp=8.6) # Find Libuv installation pkg_check_modules(LIBUV REQUIRED libuv=1.43.0) set(BUILD_TESTING OFF CACHE BOOL "Turn off tests" FORCE) set(WITH_GFLAGS OFF CACHE BOOL "Turn off gflags" FORCE) find_package(AWSSDK REQUIRED COMPONENTS core dynamodb) find_package(Boost 1.40 COMPONENTS program_options thread system REQUIRED) find_package(OpenSSL REQUIRED) add_subdirectory(./lib/glog) # Generated sources get_filename_component(proto "protos/tunnelbroker.proto" ABSOLUTE) get_filename_component(proto_path "${proto}" PATH) set(GENERATED_BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}/gen") set(GENERATED_CODE_DIR "${GENERATED_BASE_DIR}/_generated") file(MAKE_DIRECTORY ${GENERATED_CODE_DIR}) set(proto_srcs "${GENERATED_CODE_DIR}/tunnelbroker.pb.cc") set(proto_hdrs "${GENERATED_CODE_DIR}/tunnelbroker.pb.h") set(grpc_srcs "${GENERATED_CODE_DIR}/tunnelbroker.grpc.pb.cc") set(grpc_hdrs "${GENERATED_CODE_DIR}/tunnelbroker.grpc.pb.h") add_custom_command( OUTPUT "${proto_srcs}" "${proto_hdrs}" "${grpc_srcs}" "${grpc_hdrs}" COMMAND ${_PROTOBUF_PROTOC} ARGS --grpc_out "${GENERATED_CODE_DIR}" --cpp_out "${GENERATED_CODE_DIR}" -I "${proto_path}" --plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}" "${proto}" DEPENDS "${proto}" ) -file(GLOB SOURCE_CODE "./src/*.cpp" "./src/**/*.cpp") +file(GLOB_RECURSE SOURCE_CODE "./src/*.cpp") set(GENERATED_CODE ${proto_srcs} ${proto_hdrs} ${grpc_srcs} ${grpc_hdrs}) file(GLOB DOUBLE_CONVERSION_SOURCES "./lib/double-conversion/double-conversion/*.cc") include_directories( ./src ./src/Database ./src/DeliveryBroker ./src/Service ./src/Tools ./src/Amqp ${GENERATED_BASE_DIR} ${FOLLY_INCLUDES} ./lib/double-conversion ${Boost_INCLUDE_DIR} ${CRYPTOPP_INCLUDE_DIRS} ${LIBUV_INCLUDE_DIRS} ) set( SOURCE_CODE ${DOUBLE_CONVERSION_SOURCES} ${GENERATED_CODE} ${SOURCE_CODE} ) set( LIBS ${GRPC_LIBS} ${_PROTOBUF_LIBPROTOBUF} ${_REFLECTION} ${AWSSDK_LINK_LIBRARIES} ${CRYPTOPP_LIBRARIES} ${LIBUV_LIBRARIES} ${Boost_LIBRARIES} amqpcpp OpenSSL::SSL glog::glog ) #SERVER add_executable( tunnelbroker ${FOLLY_SOURCES} ${GENERATED_CODE} ${SOURCE_CODE} ) target_link_libraries( tunnelbroker ${LIBS} ) install( TARGETS tunnelbroker 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}) add_executable( runTests ${FOLLY_SOURCES} ${SOURCE_CODE} ${TEST_CODE} ) target_link_libraries( runTests ${LIBS} gtest gtest_main ) add_test( NAME runTests COMMAND runTests ) endif() diff --git a/services/tunnelbroker/Dockerfile b/services/tunnelbroker/Dockerfile index 954de4132..65a3e0a8f 100644 --- a/services/tunnelbroker/Dockerfile +++ b/services/tunnelbroker/Dockerfile @@ -1,31 +1,32 @@ FROM commapp/services-base:1.1 ARG MAKE_JOBS=4 ENV MAKEFLAGS="-j${MAKE_JOBS}" WORKDIR /transferred/scripts # Install SDKs COPY services/tunnelbroker/docker/install_amqp_cpp.sh . RUN ./install_amqp_cpp.sh COPY services/tunnelbroker/docker/install_cryptopp.sh . RUN ./install_cryptopp.sh COPY services/tunnelbroker/docker/install_libuv.sh . RUN ./install_libuv.sh ARG COMM_TEST_SERVICES ENV COMM_TEST_SERVICES=${COMM_TEST_SERVICES} WORKDIR /transferred COPY native/cpp/CommonCpp/grpc/protos/tunnelbroker.proto protos/tunnelbroker.proto COPY services/lib/cmake-components cmake-components COPY services/lib/docker/ scripts/ COPY services/tunnelbroker/docker/* docker/ COPY services/tunnelbroker/ . +COPY services/lib/src/* src/ RUN scripts/build_service.sh CMD if [ "$COMM_TEST_SERVICES" -eq 1 ]; then scripts/run_service.sh; else scripts/run_service.sh; fi diff --git a/services/tunnelbroker/src/Database/DatabaseManager.cpp b/services/tunnelbroker/src/Database/DatabaseManager.cpp index f23dd9434..285a0abbc 100644 --- a/services/tunnelbroker/src/Database/DatabaseManager.cpp +++ b/services/tunnelbroker/src/Database/DatabaseManager.cpp @@ -1,239 +1,241 @@ #include "DatabaseManager.h" +#include "DynamoDBTools.h" namespace comm { namespace network { namespace database { DatabaseManager &DatabaseManager::getInstance() { static DatabaseManager instance; return instance; } bool DatabaseManager::isTableAvailable(const std::string &tableName) { Aws::DynamoDB::Model::DescribeTableRequest request; request.SetTableName(tableName); // Check table availability by invoking DescribeTable const Aws::DynamoDB::Model::DescribeTableOutcome &result = getDynamoDBClient()->DescribeTable(request); return result.IsSuccess(); } void DatabaseManager::innerPutItem( std::shared_ptr item, const Aws::DynamoDB::Model::PutItemRequest &request) { const Aws::DynamoDB::Model::PutItemOutcome outcome = getDynamoDBClient()->PutItem(request); if (!outcome.IsSuccess()) { throw std::runtime_error(outcome.GetError().GetMessage()); } } template std::shared_ptr DatabaseManager::innerFindItem(Aws::DynamoDB::Model::GetItemRequest &request) { std::shared_ptr item = createItemByType(); request.SetTableName(item->getTableName()); const Aws::DynamoDB::Model::GetItemOutcome &outcome = getDynamoDBClient()->GetItem(request); if (!outcome.IsSuccess()) { throw std::runtime_error(outcome.GetError().GetMessage()); } const AttributeValues &outcomeItem = outcome.GetResult().GetItem(); if (!outcomeItem.size()) { return nullptr; } item->assignItemFromDatabase(outcomeItem); return std::move(item); } void DatabaseManager::innerRemoveItem( const Item &item, const std::string &key) { Aws::DynamoDB::Model::DeleteItemRequest request; request.SetTableName(item.getTableName()); request.AddKey( - item.getPrimaryKey(), Aws::DynamoDB::Model::AttributeValue(key)); + item.getPrimaryKey().partitionKey, + Aws::DynamoDB::Model::AttributeValue(key)); const Aws::DynamoDB::Model::DeleteItemOutcome &outcome = getDynamoDBClient()->DeleteItem(request); if (!outcome.IsSuccess()) { throw std::runtime_error(outcome.GetError().GetMessage()); } } void DatabaseManager::putSessionItem(const DeviceSessionItem &item) { Aws::DynamoDB::Model::PutItemRequest request; request.SetTableName(item.getTableName()); request.AddItem( DeviceSessionItem::FIELD_SESSION_ID, Aws::DynamoDB::Model::AttributeValue(item.getSessionID())); request.AddItem( DeviceSessionItem::FIELD_DEVICE_ID, Aws::DynamoDB::Model::AttributeValue(item.getDeviceID())); request.AddItem( DeviceSessionItem::FIELD_PUBKEY, Aws::DynamoDB::Model::AttributeValue(item.getPubKey())); request.AddItem( DeviceSessionItem::FIELD_NOTIFY_TOKEN, Aws::DynamoDB::Model::AttributeValue(item.getNotifyToken())); request.AddItem( DeviceSessionItem::FIELD_DEVICE_TYPE, Aws::DynamoDB::Model::AttributeValue(item.getDeviceType())); request.AddItem( DeviceSessionItem::FIELD_APP_VERSION, Aws::DynamoDB::Model::AttributeValue(item.getAppVersion())); request.AddItem( DeviceSessionItem::FIELD_DEVICE_OS, Aws::DynamoDB::Model::AttributeValue(item.getDeviceOs())); request.AddItem( DeviceSessionItem::FIELD_CHECKPOINT_TIME, Aws::DynamoDB::Model::AttributeValue( std::to_string(item.getCheckpointTime()))); request.AddItem( DeviceSessionItem::FIELD_EXPIRE, Aws::DynamoDB::Model::AttributeValue(std::to_string( static_cast(std::time(0)) + SESSION_RECORD_TTL))); this->innerPutItem(std::make_shared(item), request); } std::shared_ptr DatabaseManager::findSessionItem(const std::string &sessionID) { Aws::DynamoDB::Model::GetItemRequest request; request.AddKey( DeviceSessionItem::FIELD_SESSION_ID, Aws::DynamoDB::Model::AttributeValue(sessionID)); return std::move(this->innerFindItem(request)); } void DatabaseManager::removeSessionItem(const std::string &sessionID) { this->innerRemoveItem(*(createItemByType()), sessionID); } void DatabaseManager::putSessionSignItem(const SessionSignItem &item) { Aws::DynamoDB::Model::PutItemRequest request; request.SetTableName(item.getTableName()); request.AddItem( SessionSignItem::FIELD_SESSION_VERIFICATION, Aws::DynamoDB::Model::AttributeValue(item.getSign())); request.AddItem( SessionSignItem::FIELD_DEVICE_ID, Aws::DynamoDB::Model::AttributeValue(item.getDeviceID())); request.AddItem( SessionSignItem::FIELD_EXPIRE, Aws::DynamoDB::Model::AttributeValue(std::to_string( static_cast(std::time(0)) + SESSION_SIGN_RECORD_TTL))); this->innerPutItem(std::make_shared(item), request); } std::shared_ptr DatabaseManager::findSessionSignItem(const std::string &deviceID) { Aws::DynamoDB::Model::GetItemRequest request; request.AddKey( SessionSignItem::FIELD_DEVICE_ID, Aws::DynamoDB::Model::AttributeValue(deviceID)); return std::move(this->innerFindItem(request)); } void DatabaseManager::removeSessionSignItem(const std::string &deviceID) { this->innerRemoveItem(*(createItemByType()), deviceID); } void DatabaseManager::putPublicKeyItem(const PublicKeyItem &item) { Aws::DynamoDB::Model::PutItemRequest request; request.SetTableName(item.getTableName()); request.AddItem( PublicKeyItem::FIELD_DEVICE_ID, Aws::DynamoDB::Model::AttributeValue(item.getDeviceID())); request.AddItem( PublicKeyItem::FIELD_PUBLIC_KEY, Aws::DynamoDB::Model::AttributeValue(item.getPublicKey())); this->innerPutItem(std::make_shared(item), request); } std::shared_ptr DatabaseManager::findPublicKeyItem(const std::string &deviceID) { Aws::DynamoDB::Model::GetItemRequest request; request.AddKey( PublicKeyItem::FIELD_DEVICE_ID, Aws::DynamoDB::Model::AttributeValue(deviceID)); return std::move(this->innerFindItem(request)); } void DatabaseManager::removePublicKeyItem(const std::string &deviceID) { this->innerRemoveItem(*(createItemByType()), deviceID); } void DatabaseManager::putMessageItem(const MessageItem &item) { Aws::DynamoDB::Model::PutItemRequest request; request.SetTableName(item.getTableName()); request.AddItem( MessageItem::FIELD_MESSAGE_ID, Aws::DynamoDB::Model::AttributeValue(item.getMessageID())); request.AddItem( MessageItem::FIELD_FROM_DEVICE_ID, Aws::DynamoDB::Model::AttributeValue(item.getFromDeviceID())); request.AddItem( MessageItem::FIELD_TO_DEVICE_ID, Aws::DynamoDB::Model::AttributeValue(item.getToDeviceID())); request.AddItem( MessageItem::FIELD_PAYLOAD, Aws::DynamoDB::Model::AttributeValue(item.getPayload())); request.AddItem( MessageItem::FIELD_BLOB_HASHES, Aws::DynamoDB::Model::AttributeValue(item.getBlobHashes())); request.AddItem( MessageItem::FIELD_EXPIRE, Aws::DynamoDB::Model::AttributeValue(std::to_string( static_cast(std::time(0) + MESSAGE_RECORD_TTL)))); request.AddItem( MessageItem::FIELD_CREATED_AT, Aws::DynamoDB::Model::AttributeValue( std::to_string(tools::getCurrentTimestamp()))); this->innerPutItem(std::make_shared(item), request); } std::shared_ptr DatabaseManager::findMessageItem(const std::string &messageID) { Aws::DynamoDB::Model::GetItemRequest request; request.AddKey( MessageItem::FIELD_MESSAGE_ID, Aws::DynamoDB::Model::AttributeValue(messageID)); return std::move(this->innerFindItem(request)); } std::vector> DatabaseManager::findMessageItemsByReceiver(const std::string &toDeviceID) { std::vector> result; Aws::DynamoDB::Model::QueryRequest req; req.SetTableName(MessageItem().getTableName()); req.SetKeyConditionExpression( MessageItem::FIELD_TO_DEVICE_ID + " = :valueToMatch"); AttributeValues attributeValues; attributeValues.emplace(":valueToMatch", toDeviceID); req.SetExpressionAttributeValues(attributeValues); req.SetIndexName(MessageItem::INDEX_TO_DEVICE_ID); const Aws::DynamoDB::Model::QueryOutcome &outcome = getDynamoDBClient()->Query(req); if (!outcome.IsSuccess()) { throw std::runtime_error(outcome.GetError().GetMessage()); } const Aws::Vector &items = outcome.GetResult().GetItems(); for (auto &item : items) { result.push_back(std::make_shared(item)); } return result; } void DatabaseManager::removeMessageItem(const std::string &messageID) { this->innerRemoveItem(*(createItemByType()), messageID); } } // namespace database } // namespace network } // namespace comm diff --git a/services/tunnelbroker/src/Database/DeviceSessionItem.cpp b/services/tunnelbroker/src/Database/DeviceSessionItem.cpp index 97573f8da..227b2ca59 100644 --- a/services/tunnelbroker/src/Database/DeviceSessionItem.cpp +++ b/services/tunnelbroker/src/Database/DeviceSessionItem.cpp @@ -1,124 +1,128 @@ #include "DeviceSessionItem.h" #include "ConfigManager.h" #include "Tools.h" #include namespace comm { namespace network { namespace database { const std::string DeviceSessionItem::FIELD_SESSION_ID = "SessionID"; const std::string DeviceSessionItem::FIELD_DEVICE_ID = "DeviceID"; const std::string DeviceSessionItem::FIELD_PUBKEY = "PubKey"; const std::string DeviceSessionItem::FIELD_NOTIFY_TOKEN = "NotifyToken"; const std::string DeviceSessionItem::FIELD_DEVICE_TYPE = "DeviceType"; const std::string DeviceSessionItem::FIELD_APP_VERSION = "AppVersion"; const std::string DeviceSessionItem::FIELD_DEVICE_OS = "DeviceOS"; const std::string DeviceSessionItem::FIELD_CHECKPOINT_TIME = "CheckpointTime"; const std::string DeviceSessionItem::FIELD_EXPIRE = "Expire"; DeviceSessionItem::DeviceSessionItem( const std::string sessionID, const std::string deviceID, const std::string pubKey, const std::string notifyToken, const std::string deviceType, const std::string appVersion, const std::string deviceOs) : sessionID(sessionID), deviceID(deviceID), pubKey(pubKey), notifyToken(notifyToken), deviceType(deviceType), appVersion(appVersion), deviceOs(deviceOs) { this->validate(); } DeviceSessionItem::DeviceSessionItem(const AttributeValues &itemFromDB) { this->assignItemFromDatabase(itemFromDB); } void DeviceSessionItem::validate() const { if (!tools::validateSessionID(this->sessionID)) { throw std::runtime_error("Error: SessionID format is wrong."); } if (!tools::validateDeviceID(this->deviceID)) { throw std::runtime_error("Error: DeviceID format is wrong."); } tools::checkIfNotEmpty("pubKey", this->pubKey); tools::checkIfNotEmpty("notifyToken", this->notifyToken); tools::checkIfNotEmpty("deviceType", this->deviceType); tools::checkIfNotEmpty("appVersion", this->appVersion); tools::checkIfNotEmpty("deviceOs", this->deviceOs); } void DeviceSessionItem::assignItemFromDatabase( const AttributeValues &itemFromDB) { try { this->sessionID = itemFromDB.at(DeviceSessionItem::FIELD_SESSION_ID).GetS(); this->deviceID = itemFromDB.at(DeviceSessionItem::FIELD_DEVICE_ID).GetS(); this->pubKey = itemFromDB.at(DeviceSessionItem::FIELD_PUBKEY).GetS(); this->notifyToken = itemFromDB.at(DeviceSessionItem::FIELD_NOTIFY_TOKEN).GetS(); this->deviceType = itemFromDB.at(DeviceSessionItem::FIELD_DEVICE_TYPE).GetS(); this->appVersion = itemFromDB.at(DeviceSessionItem::FIELD_APP_VERSION).GetS(); this->deviceOs = itemFromDB.at(DeviceSessionItem::FIELD_DEVICE_OS).GetS(); this->checkpointTime = std::stoll( std::string( itemFromDB.at(DeviceSessionItem::FIELD_CHECKPOINT_TIME).GetS()) .c_str()); } catch (std::logic_error &e) { throw std::runtime_error( "Invalid device session database value " + std::string(e.what())); } this->validate(); } std::string DeviceSessionItem::getTableName() const { return config::ConfigManager::getInstance().getParameter( config::ConfigManager::OPTION_DYNAMODB_SESSIONS_TABLE); } -std::string DeviceSessionItem::getPrimaryKey() const { - return DeviceSessionItem::FIELD_SESSION_ID; +PrimaryKey DeviceSessionItem::getPrimaryKey() const { + return PrimaryKey(DeviceSessionItem::FIELD_SESSION_ID); +} + +PrimaryKeyValue DeviceSessionItem::getPrimaryKeyValue() const { + return PrimaryKeyValue(this->sessionID); } std::string DeviceSessionItem::getSessionID() const { return this->sessionID; } std::string DeviceSessionItem::getDeviceID() const { return this->deviceID; } std::string DeviceSessionItem::getPubKey() const { return this->pubKey; } std::string DeviceSessionItem::getNotifyToken() const { return this->notifyToken; } std::string DeviceSessionItem::getDeviceType() const { return this->deviceType; } std::string DeviceSessionItem::getAppVersion() const { return this->appVersion; } std::string DeviceSessionItem::getDeviceOs() const { return this->deviceOs; } int64_t DeviceSessionItem::getCheckpointTime() const { return this->checkpointTime; } } // namespace database } // namespace network } // namespace comm diff --git a/services/tunnelbroker/src/Database/DeviceSessionItem.h b/services/tunnelbroker/src/Database/DeviceSessionItem.h index eb17277b2..d3f1c081d 100644 --- a/services/tunnelbroker/src/Database/DeviceSessionItem.h +++ b/services/tunnelbroker/src/Database/DeviceSessionItem.h @@ -1,61 +1,62 @@ #pragma once #include "Item.h" #include namespace comm { namespace network { namespace database { class DeviceSessionItem : public Item { std::string sessionID; std::string deviceID; std::string pubKey; std::string notifyToken; std::string deviceType; std::string appVersion; std::string deviceOs; int64_t checkpointTime = 0; void validate() const override; public: static const std::string FIELD_SESSION_ID; static const std::string FIELD_DEVICE_ID; static const std::string FIELD_PUBKEY; static const std::string FIELD_NOTIFY_TOKEN; static const std::string FIELD_DEVICE_TYPE; static const std::string FIELD_APP_VERSION; static const std::string FIELD_DEVICE_OS; static const std::string FIELD_CHECKPOINT_TIME; static const std::string FIELD_EXPIRE; - std::string getPrimaryKey() const override; + PrimaryKey getPrimaryKey() const override; + PrimaryKeyValue getPrimaryKeyValue() const override; std::string getTableName() const override; std::string getSessionID() const; std::string getDeviceID() const; std::string getPubKey() const; std::string getNotifyToken() const; std::string getDeviceType() const; std::string getAppVersion() const; std::string getDeviceOs() const; int64_t getCheckpointTime() const; DeviceSessionItem() { } DeviceSessionItem( const std::string sessionID, const std::string deviceID, const std::string pubKey, const std::string notifyToken, const std::string deviceType, const std::string appVersion, const std::string deviceOs); DeviceSessionItem(const AttributeValues &itemFromDB); void assignItemFromDatabase(const AttributeValues &itemFromDB) override; }; } // namespace database } // namespace network } // namespace comm diff --git a/services/tunnelbroker/src/Database/Item.h b/services/tunnelbroker/src/Database/Item.h deleted file mode 100644 index bb25cdba0..000000000 --- a/services/tunnelbroker/src/Database/Item.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include -#include - -#include - -namespace comm { -namespace network { -namespace database { - -typedef Aws::Map - AttributeValues; - -class Item { - virtual void validate() const = 0; - -public: - virtual std::string getTableName() const = 0; - virtual std::string getPrimaryKey() const = 0; - virtual void assignItemFromDatabase(const AttributeValues &itemFromDB) = 0; -}; - -} // namespace database -} // namespace network -} // namespace comm diff --git a/services/tunnelbroker/src/Database/MessageItem.cpp b/services/tunnelbroker/src/Database/MessageItem.cpp index 347d2db22..fee22634d 100644 --- a/services/tunnelbroker/src/Database/MessageItem.cpp +++ b/services/tunnelbroker/src/Database/MessageItem.cpp @@ -1,105 +1,109 @@ #include "MessageItem.h" #include "ConfigManager.h" #include "Tools.h" #include namespace comm { namespace network { namespace database { const std::string MessageItem::FIELD_MESSAGE_ID = "MessageID"; const std::string MessageItem::FIELD_FROM_DEVICE_ID = "FromDeviceID"; const std::string MessageItem::FIELD_TO_DEVICE_ID = "ToDeviceID"; const std::string MessageItem::FIELD_PAYLOAD = "Payload"; const std::string MessageItem::FIELD_BLOB_HASHES = "BlobHashes"; const std::string MessageItem::FIELD_EXPIRE = "Expire"; const std::string MessageItem::FIELD_CREATED_AT = "CreatedAt"; const std::string MessageItem::INDEX_TO_DEVICE_ID = "ToDeviceID-index"; MessageItem::MessageItem( const std::string messageID, const std::string fromDeviceID, const std::string toDeviceID, const std::string payload, const std::string blobHashes) : messageID(messageID), fromDeviceID(fromDeviceID), toDeviceID(toDeviceID), payload(payload), blobHashes(blobHashes) { this->validate(); } MessageItem::MessageItem(const AttributeValues &itemFromDB) { this->assignItemFromDatabase(itemFromDB); } void MessageItem::validate() const { if (!tools::validateDeviceID(this->fromDeviceID)) { throw std::runtime_error("Error: FromDeviceID format is wrong."); } if (!tools::validateDeviceID(this->toDeviceID)) { throw std::runtime_error("Error: ToDeviceID format is wrong."); } tools::checkIfNotEmpty("messageID", this->messageID); } void MessageItem::assignItemFromDatabase(const AttributeValues &itemFromDB) { try { this->messageID = itemFromDB.at(MessageItem::FIELD_MESSAGE_ID).GetS(); this->fromDeviceID = itemFromDB.at(MessageItem::FIELD_FROM_DEVICE_ID).GetS(); this->toDeviceID = itemFromDB.at(MessageItem::FIELD_TO_DEVICE_ID).GetS(); this->payload = itemFromDB.at(MessageItem::FIELD_PAYLOAD).GetS(); this->blobHashes = itemFromDB.at(MessageItem::FIELD_BLOB_HASHES).GetS(); this->expire = std::stoull(itemFromDB.at(MessageItem::FIELD_EXPIRE).GetS()); this->createdAt = std::stoull(itemFromDB.at(MessageItem::FIELD_CREATED_AT).GetS()); } catch (const std::exception &e) { throw std::runtime_error( "Got an exception at MessageItem: " + std::string(e.what())); } this->validate(); } std::string MessageItem::getTableName() const { return config::ConfigManager::getInstance().getParameter( config::ConfigManager::OPTION_DYNAMODB_MESSAGES_TABLE); } -std::string MessageItem::getPrimaryKey() const { - return MessageItem::FIELD_MESSAGE_ID; +PrimaryKey MessageItem::getPrimaryKey() const { + return PrimaryKey(MessageItem::FIELD_MESSAGE_ID); +} + +PrimaryKeyValue MessageItem::getPrimaryKeyValue() const { + return PrimaryKeyValue(this->messageID); } std::string MessageItem::getMessageID() const { return this->messageID; } std::string MessageItem::getFromDeviceID() const { return this->fromDeviceID; } std::string MessageItem::getToDeviceID() const { return this->toDeviceID; } std::string MessageItem::getPayload() const { return this->payload; } std::string MessageItem::getBlobHashes() const { return this->blobHashes; } uint64_t MessageItem::getExpire() const { return this->expire; } uint64_t MessageItem::getCreatedAt() const { return this->createdAt; } } // namespace database } // namespace network } // namespace comm diff --git a/services/tunnelbroker/src/Database/MessageItem.h b/services/tunnelbroker/src/Database/MessageItem.h index 3b370e7b2..37d9e806e 100644 --- a/services/tunnelbroker/src/Database/MessageItem.h +++ b/services/tunnelbroker/src/Database/MessageItem.h @@ -1,56 +1,57 @@ #pragma once #include "Item.h" #include namespace comm { namespace network { namespace database { class MessageItem : public Item { std::string messageID; std::string fromDeviceID; std::string toDeviceID; std::string payload; std::string blobHashes; uint64_t expire; uint64_t createdAt; void validate() const override; public: static const std::string FIELD_MESSAGE_ID; static const std::string FIELD_FROM_DEVICE_ID; static const std::string FIELD_TO_DEVICE_ID; static const std::string FIELD_PAYLOAD; static const std::string FIELD_BLOB_HASHES; static const std::string FIELD_EXPIRE; static const std::string FIELD_CREATED_AT; static const std::string INDEX_TO_DEVICE_ID; - std::string getPrimaryKey() const override; + PrimaryKey getPrimaryKey() const override; + PrimaryKeyValue getPrimaryKeyValue() const override; std::string getTableName() const override; std::string getMessageID() const; std::string getFromDeviceID() const; std::string getToDeviceID() const; std::string getPayload() const; std::string getBlobHashes() const; uint64_t getExpire() const; uint64_t getCreatedAt() const; MessageItem() { } MessageItem( const std::string messageID, const std::string fromDeviceID, const std::string toDeviceID, const std::string payload, const std::string blobHashes); MessageItem(const AttributeValues &itemFromDB); void assignItemFromDatabase(const AttributeValues &itemFromDB) override; }; } // namespace database } // namespace network } // namespace comm diff --git a/services/tunnelbroker/src/Database/PublicKeyItem.cpp b/services/tunnelbroker/src/Database/PublicKeyItem.cpp index ee7be912a..36e491ca4 100644 --- a/services/tunnelbroker/src/Database/PublicKeyItem.cpp +++ b/services/tunnelbroker/src/Database/PublicKeyItem.cpp @@ -1,60 +1,64 @@ #include "PublicKeyItem.h" #include "ConfigManager.h" #include "Tools.h" namespace comm { namespace network { namespace database { const std::string PublicKeyItem::FIELD_DEVICE_ID = "DeviceID"; const std::string PublicKeyItem::FIELD_PUBLIC_KEY = "PublicKey"; PublicKeyItem::PublicKeyItem( const std::string deviceID, const std::string publicKey) : deviceID(deviceID), publicKey(publicKey) { this->validate(); } PublicKeyItem::PublicKeyItem(const AttributeValues &itemFromDB) { this->assignItemFromDatabase(itemFromDB); } void PublicKeyItem::validate() const { if (!tools::validateDeviceID(this->deviceID)) { throw std::runtime_error("Error: DeviceID format is wrong."); } tools::checkIfNotEmpty("publicKey", this->publicKey); } void PublicKeyItem::assignItemFromDatabase(const AttributeValues &itemFromDB) { try { this->publicKey = itemFromDB.at(PublicKeyItem::FIELD_PUBLIC_KEY).GetS(); this->deviceID = itemFromDB.at(PublicKeyItem::FIELD_DEVICE_ID).GetS(); } catch (const std::exception &e) { throw std::runtime_error( "Got an exception at PublicKeyItem: " + std::string(e.what())); } this->validate(); } std::string PublicKeyItem::getTableName() const { return config::ConfigManager::getInstance().getParameter( config::ConfigManager::OPTION_DYNAMODB_SESSIONS_PUBLIC_KEY_TABLE); } -std::string PublicKeyItem::getPrimaryKey() const { - return PublicKeyItem::FIELD_DEVICE_ID; +PrimaryKey PublicKeyItem::getPrimaryKey() const { + return PrimaryKey(PublicKeyItem::FIELD_DEVICE_ID); +} + +PrimaryKeyValue PublicKeyItem::getPrimaryKeyValue() const { + return PrimaryKeyValue(this->deviceID); } std::string PublicKeyItem::getDeviceID() const { return this->deviceID; } std::string PublicKeyItem::getPublicKey() const { return this->publicKey; } } // namespace database } // namespace network } // namespace comm diff --git a/services/tunnelbroker/src/Database/PublicKeyItem.h b/services/tunnelbroker/src/Database/PublicKeyItem.h index 5ae48dee7..744188f18 100644 --- a/services/tunnelbroker/src/Database/PublicKeyItem.h +++ b/services/tunnelbroker/src/Database/PublicKeyItem.h @@ -1,35 +1,36 @@ #pragma once #include "Item.h" #include namespace comm { namespace network { namespace database { class PublicKeyItem : public Item { std::string deviceID; std::string publicKey; void validate() const override; public: static const std::string FIELD_DEVICE_ID; static const std::string FIELD_PUBLIC_KEY; - std::string getPrimaryKey() const override; + PrimaryKey getPrimaryKey() const override; + PrimaryKeyValue getPrimaryKeyValue() const override; std::string getTableName() const override; std::string getDeviceID() const; std::string getPublicKey() const; PublicKeyItem() { } PublicKeyItem(const std::string deviceID, const std::string publicKey); PublicKeyItem(const AttributeValues &itemFromDB); void assignItemFromDatabase(const AttributeValues &itemFromDB) override; }; } // namespace database } // namespace network } // namespace comm diff --git a/services/tunnelbroker/src/Database/SessionSignItem.cpp b/services/tunnelbroker/src/Database/SessionSignItem.cpp index 8cb61a27e..f9a164cd4 100644 --- a/services/tunnelbroker/src/Database/SessionSignItem.cpp +++ b/services/tunnelbroker/src/Database/SessionSignItem.cpp @@ -1,64 +1,68 @@ #include "SessionSignItem.h" #include "ConfigManager.h" #include "Tools.h" namespace comm { namespace network { namespace database { const std::string SessionSignItem::FIELD_SESSION_VERIFICATION = "VerificationMessage"; const std::string SessionSignItem::FIELD_DEVICE_ID = "DeviceID"; const std::string SessionSignItem::FIELD_EXPIRE = "Expire"; SessionSignItem::SessionSignItem( const std::string sign, const std::string deviceID) : sign(sign), deviceID(deviceID) { this->validate(); } SessionSignItem::SessionSignItem(const AttributeValues &itemFromDB) { this->assignItemFromDatabase(itemFromDB); } void SessionSignItem::validate() const { if (!tools::validateDeviceID(this->deviceID)) { throw std::runtime_error("Error: DeviceID format is wrong."); } tools::checkIfNotEmpty("sign", this->sign); } void SessionSignItem::assignItemFromDatabase( const AttributeValues &itemFromDB) { try { this->sign = itemFromDB.at(SessionSignItem::FIELD_SESSION_VERIFICATION).GetS(); this->deviceID = itemFromDB.at(SessionSignItem::FIELD_DEVICE_ID).GetS(); } catch (const std::exception &e) { throw std::runtime_error( "Got an exception at SessionSignItem: " + std::string(e.what())); } this->validate(); } std::string SessionSignItem::getTableName() const { return config::ConfigManager::getInstance().getParameter( config::ConfigManager::OPTION_DYNAMODB_SESSIONS_VERIFICATION_TABLE); } -std::string SessionSignItem::getPrimaryKey() const { - return SessionSignItem::FIELD_DEVICE_ID; +PrimaryKey SessionSignItem::getPrimaryKey() const { + return PrimaryKey(SessionSignItem::FIELD_DEVICE_ID); +} + +PrimaryKeyValue SessionSignItem::getPrimaryKeyValue() const { + return PrimaryKeyValue(this->deviceID); } std::string SessionSignItem::getSign() const { return this->sign; } std::string SessionSignItem::getDeviceID() const { return this->deviceID; } } // namespace database } // namespace network } // namespace comm diff --git a/services/tunnelbroker/src/Database/SessionSignItem.h b/services/tunnelbroker/src/Database/SessionSignItem.h index d6b0e43cf..24426f794 100644 --- a/services/tunnelbroker/src/Database/SessionSignItem.h +++ b/services/tunnelbroker/src/Database/SessionSignItem.h @@ -1,36 +1,37 @@ #pragma once #include "Item.h" #include namespace comm { namespace network { namespace database { class SessionSignItem : public Item { std::string sign; std::string deviceID; void validate() const override; public: static const std::string FIELD_SESSION_VERIFICATION; static const std::string FIELD_DEVICE_ID; static const std::string FIELD_EXPIRE; - std::string getPrimaryKey() const override; + PrimaryKey getPrimaryKey() const override; + PrimaryKeyValue getPrimaryKeyValue() const override; std::string getTableName() const override; std::string getSign() const; std::string getDeviceID() const; SessionSignItem() { } SessionSignItem(const std::string sign, const std::string deviceID); SessionSignItem(const AttributeValues &itemFromDB); void assignItemFromDatabase(const AttributeValues &itemFromDB) override; }; } // namespace database } // namespace network } // namespace comm diff --git a/services/tunnelbroker/src/Tools/AwsTools.cpp b/services/tunnelbroker/src/Tools/AwsTools.cpp index b3b46269b..b473c4577 100644 --- a/services/tunnelbroker/src/Tools/AwsTools.cpp +++ b/services/tunnelbroker/src/Tools/AwsTools.cpp @@ -1,30 +1,20 @@ #include "AwsTools.h" #include "Constants.h" namespace comm { namespace network { Aws::String getAwsRegion() { auto profileName = Aws::Auth::GetConfigProfileName(); if (Aws::Config::HasCachedConfigProfile(profileName)) { auto profile = Aws::Config::GetCachedConfigProfile(profileName); Aws::String profileRegion = profile.GetRegion(); if (!profileRegion.empty()) { return profileRegion; } } return {}; } -std::unique_ptr getDynamoDBClient() { - Aws::Client::ClientConfiguration config; - config.region = getAwsRegion(); - if (config.region.empty()) { - throw std::runtime_error( - "Error: AWS region is not provided in the ~/.aws/config"); - } - return std::make_unique(config); -} - } // namespace network } // namespace comm diff --git a/services/tunnelbroker/src/Tools/AwsTools.h b/services/tunnelbroker/src/Tools/AwsTools.h index cc93d9558..803f47997 100644 --- a/services/tunnelbroker/src/Tools/AwsTools.h +++ b/services/tunnelbroker/src/Tools/AwsTools.h @@ -1,17 +1,16 @@ #pragma once #include #include #include #include #include namespace comm { namespace network { Aws::String getAwsRegion(); -std::unique_ptr getDynamoDBClient(); } // namespace network } // namespace comm