From 416a20b211539c8db06c26a2297de9109ef69f32 Mon Sep 17 00:00:00 2001 From: claiff Date: Tue, 18 Oct 2022 12:19:24 +0300 Subject: add smtp queue messages --- CMakeLists.txt | 2 ++ src/logger/logger_set.cpp | 2 +- src/management/mail.hpp | 1 - src/message/sender.cpp | 62 +++++++++++++++++++++------------------ src/message/sender.hpp | 9 ++++-- src/message/thread_safe_queue.cpp | 21 +++++++++++++ src/message/thread_safe_queue.hpp | 29 ++++++++++++++++++ src/service/smtp.cpp | 15 ++++++---- src/service/smtp.hpp | 3 ++ 9 files changed, 104 insertions(+), 40 deletions(-) create mode 100644 src/message/thread_safe_queue.cpp create mode 100644 src/message/thread_safe_queue.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7351684..ea033d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,6 +107,8 @@ set(SRC_FILES ${MESSAGE_DIR}/sender.hpp ${MESSAGE_DIR}/sender.cpp + ${MESSAGE_DIR}/thread_safe_queue.hpp + ${MESSAGE_DIR}/thread_safe_queue.cpp ${MESSAGE_DIR}/builder/date.hpp ${MESSAGE_DIR}/builder/date.cpp diff --git a/src/logger/logger_set.cpp b/src/logger/logger_set.cpp index e46b6cc..e7a8dd9 100644 --- a/src/logger/logger_set.cpp +++ b/src/logger/logger_set.cpp @@ -1,7 +1,7 @@ #include "logger_set.hpp" #include "journal.hpp" #include "phosphor.hpp" -#include + namespace smtp::logger { std::shared_ptr < LoggerSet > LoggerSet::mInstance = nullptr; diff --git a/src/management/mail.hpp b/src/management/mail.hpp index 94919e6..39d4048 100644 --- a/src/management/mail.hpp +++ b/src/management/mail.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include "file/mail/types/ifile_manipulator.hpp" diff --git a/src/message/sender.cpp b/src/message/sender.cpp index 30073a8..a200092 100644 --- a/src/message/sender.cpp +++ b/src/message/sender.cpp @@ -16,9 +16,10 @@ namespace smtp::message // // Constructors/Destructors // - Sender::Sender( manage::Settings& settings_storage, manage::Mail const& mail_to ) + Sender::Sender( manage::Settings const& settings_storage, manage::Mail const& mail_to, ThreadSafeQueue& message_queue ) : mSettingsStorage( settings_storage ) , mMailTo( mail_to ) + , mMessageQueue( message_queue ) { } @@ -27,7 +28,7 @@ namespace smtp::message //Public methods // - bool Sender::Send( std::string const& mail_from, std::string const& subject, std::string const& text ) + void Sender::Send() { static const std::string METHOD_NAME = "Send message"; @@ -35,35 +36,38 @@ namespace smtp::message curl_slist* recipients = nullptr; WriteThis upload_ctx{}; auto curl = curl_easy_init(); - //TODO сделать инициализацию через регистратор инициализаторов - if( !InitCurl( curl, upload_ctx, mail_from )) - { - logger::LoggerSet::GetInstance()->LogError( METHOD_NAME, "Error to initializate message service" ); - return false; - } - //TODO раздать mail_to другим методам - auto mail_to = mMailTo.GetMailToSend(); - if( mail_to.empty()) - { - logger::LoggerSet::GetInstance()->LogError( METHOD_NAME, "We haven't any mail to" ); - return false; - } - FillRecipients( curl, recipients ); - UpdateMailText( mail_from, subject, text ); - - result = curl_easy_perform( curl ); - if( result != CURLE_OK ) - { - std::string message = "Error to send messge: " + std::string( curl_easy_strerror( result )); - logger::LoggerSet::GetInstance()->LogError( METHOD_NAME, message ); - return false; - } - //TODO сделать деинициализацию через регистратор деинициализаторов - curl_slist_free_all( recipients ); - curl_easy_cleanup( curl ); - return true; + while(1) + { + auto message = mMessageQueue.WaitAndPop(); + if( !InitCurl( curl, upload_ctx, mSettingsStorage.GetUserName() )) + { + logger::LoggerSet::GetInstance()->LogError( METHOD_NAME, "Error to initializate message service" ); + } + //TODO раздать mail_to другим методам + auto mail_to = mMailTo.GetMailToSend(); + if( mail_to.empty()) + { + logger::LoggerSet::GetInstance()->LogError( METHOD_NAME, "We haven't any mail to" ); + } + FillRecipients( curl, recipients ); + + + UpdateMailText( mSettingsStorage.GetUserName(), message->subject, message->text ); + + result = curl_easy_perform( curl ); + + if( result != CURLE_OK ) + { + std::string message = "Error to send messge: " + std::string( curl_easy_strerror( result )); + logger::LoggerSet::GetInstance()->LogError( METHOD_NAME, message ); + } + upload_ctx.counter = 0; + } + //TODO сделать деинициализацию через регистратор деинициализаторов + curl_slist_free_all( recipients ); + curl_easy_cleanup( curl ); } // diff --git a/src/message/sender.hpp b/src/message/sender.hpp index 3118319..2419e4c 100644 --- a/src/message/sender.hpp +++ b/src/message/sender.hpp @@ -7,6 +7,8 @@ #include "management/settings.hpp" #include "management/mail.hpp" +#include "thread_safe_queue.hpp" + namespace smtp::message { struct WriteThis @@ -17,10 +19,10 @@ namespace smtp::message class Sender { public: - Sender( manage::Settings& settings_storage, manage::Mail const& mail_to ); + Sender( manage::Settings const& settings_storage, manage::Mail const& mail_to, ThreadSafeQueue& message_queue ); ~Sender() = default; - bool Send( std::string const& mail_from, std::string const& subject, std::string const& text ); + void Send(); private: bool InitCurl( CURL* curl, WriteThis const& upload_ctx, std::string const& mail_from ); void UpdateMailText( std::string const& mail_from, std::string const& subject, std::string const& textt ) const; @@ -28,8 +30,9 @@ namespace smtp::message std::string GetHostPortData() const; static size_t ReadCallBack( void *ptr, size_t size, size_t nmemb, void *userp ); - manage::Settings& mSettingsStorage; + manage::Settings const& mSettingsStorage; manage::Mail const& mMailTo; + ThreadSafeQueue& mMessageQueue; }; } diff --git a/src/message/thread_safe_queue.cpp b/src/message/thread_safe_queue.cpp new file mode 100644 index 0000000..092a2ac --- /dev/null +++ b/src/message/thread_safe_queue.cpp @@ -0,0 +1,21 @@ +#include "thread_safe_queue.hpp" + +namespace smtp::message +{ + void ThreadSafeQueue::Push( Message const &message) + { + std::lock_guard lock{mMutex}; + mMessageQueue.push( message ); + mCondition.notify_one(); + } + + std::shared_ptr ThreadSafeQueue::WaitAndPop() + { + std::unique_lock lock{mMutex}; + mCondition.wait(lock, [this](){return !mMessageQueue.empty();}); + auto result = std::make_shared(mMessageQueue.front()); + mMessageQueue.pop(); + return result; + } + +} diff --git a/src/message/thread_safe_queue.hpp b/src/message/thread_safe_queue.hpp new file mode 100644 index 0000000..5bb1ee4 --- /dev/null +++ b/src/message/thread_safe_queue.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include +#include +#include +#include + +namespace smtp::message +{ + struct Message + { + std::string subject; + std::string text; + }; + + class ThreadSafeQueue + { + public: + ThreadSafeQueue() = default; + ~ThreadSafeQueue() = default; + + void Push( Message const& message ); + std::shared_ptr WaitAndPop(); + private: + mutable std::mutex mMutex; + std::queue mMessageQueue; + std::condition_variable mCondition; + }; +} diff --git a/src/service/smtp.cpp b/src/service/smtp.cpp index 3c71161..6c2f1ad 100644 --- a/src/service/smtp.cpp +++ b/src/service/smtp.cpp @@ -14,6 +14,10 @@ namespace smtp::service CreateMessengerInterface( connection ); CreateSettingsManagerInterface( connection ); CreateMailManagerInterface( connection ); + + message::Sender sender{mSettingsStorage, mMailTo, mMessageQueue}; + std::thread sender_message( &message::Sender::Send, std::move(sender) ); + sender_message.detach(); } // @@ -33,9 +37,9 @@ namespace smtp::service static constexpr char SMTP_INTERFACE_NAME[] = "xyz.openbmc_project.Messenger"; mObjectServer = std::make_shared( connection ); - mMessengerInterface = mObjectServer->add_interface( SMTP_OBJECT_NAME, SMTP_INTERFACE_NAME ); + mMessengerInterface = mObjectServer->add_interface( SMTP_OBJECT_NAME, SMTP_INTERFACE_NAME ); - AddMessengerMethods(); + AddMessengerMethods(); mMessengerInterface->initialize(); } @@ -70,10 +74,9 @@ namespace smtp::service { static constexpr char SMTP_SEND_MESSAGE_METHOD_NAME[] = "SendMail"; - mMessengerInterface->register_method( SMTP_SEND_MESSAGE_METHOD_NAME, [this]( std::string const& mail_from, - std::string const& theme, - std::string const& text ) - { return message::Sender{ mSettingsStorage, mMailTo }.Send( mail_from, theme, text );}); + mMessengerInterface->register_method( SMTP_SEND_MESSAGE_METHOD_NAME, [this]( std::string const& theme, + std::string const& text ) + { mMessageQueue.Push({theme, text});}); } void Smtp::AddSettingsManagerMethods() diff --git a/src/service/smtp.hpp b/src/service/smtp.hpp index 47ff209..0d8aea1 100644 --- a/src/service/smtp.hpp +++ b/src/service/smtp.hpp @@ -7,6 +7,7 @@ #include "management/mail.hpp" #include "management/settings.hpp" +#include "message/thread_safe_queue.hpp" namespace smtp::service { @@ -35,5 +36,7 @@ namespace smtp::service ObjectServerPtr mObjectServer; manage::Settings mSettingsStorage; manage::Mail mMailTo; + + message::ThreadSafeQueue mMessageQueue; }; } -- cgit v1.2.3