diff --git a/receiver/CMakeLists.txt b/receiver/CMakeLists.txt index 5e37450686580a56e1a1fd1a34748fd86026b06a..c4b327d95e07c6c1eccdda2ed298abfe85f9b001 100644 --- a/receiver/CMakeLists.txt +++ b/receiver/CMakeLists.txt @@ -11,7 +11,6 @@ set(SOURCE_FILES src/request_handler_db_write.cpp src/request_handler_authorize.cpp src/statistics_sender_fluentd.cpp - src/connection_authorizer.cpp src/requests_dispatcher.cpp ) @@ -49,9 +48,9 @@ set(TEST_SOURCE_FILES unittests/test_config.cpp unittests/test_request.cpp unittests/test_request_factory.cpp - unittests/test_authorizer.cpp unittests/test_request_handler_file_write.cpp unittests/test_request_handler_db_writer.cpp + unittests/test_request_handler_authorizer.cpp unittests/test_statistics_sender_influx_db.cpp unittests/test_statistics_sender_fluentd.cpp unittests/mock_receiver_config.cpp diff --git a/receiver/src/connection.h b/receiver/src/connection.h index beed990030c9c87cb17e23971d2597738486cf15..4d4c921f6f7831308e3a64fe81000febb3d27520 100644 --- a/receiver/src/connection.h +++ b/receiver/src/connection.h @@ -16,7 +16,6 @@ #include "request.h" #include "statistics.h" #include "logger/logger.h" -#include "connection_authorizer.h" #include "requests_dispatcher.h" namespace asapo { diff --git a/receiver/src/connection_authorizer.cpp b/receiver/src/connection_authorizer.cpp deleted file mode 100644 index a682a4aea12ae53ff33ae9c3eec2960084a79c71..0000000000000000000000000000000000000000 --- a/receiver/src/connection_authorizer.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "connection_authorizer.h" - -#include "receiver_logger.h" - - -namespace asapo { - -Error ConnectionAuthorizer::Authorize(std::string beamtime_id,std::string uri) const noexcept { - Error err; - if (err) { - log__->Error("error authorizing beamtime "+ beamtime_id +" on "+ uri + " - " + err->Explain()); - } else { - log__->Debug("authorized beamtime "+ beamtime_id +" on "+ uri); - } - - return nullptr; -} -ConnectionAuthorizer::ConnectionAuthorizer() : log__{GetDefaultReceiverLogger()}{ - -} - -} \ No newline at end of file diff --git a/receiver/src/connection_authorizer.h b/receiver/src/connection_authorizer.h deleted file mode 100644 index 39093a2011b84a33d089a51456f7d5abc7559580..0000000000000000000000000000000000000000 --- a/receiver/src/connection_authorizer.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef ASAPO_RECEIVER_AUTHORIZER_H -#define ASAPO_RECEIVER_AUTHORIZER_H - -#include "common/error.h" -#include "preprocessor/definitions.h" -#include "logger/logger.h" - -namespace asapo { - -class ConnectionAuthorizer { - public: - ConnectionAuthorizer(); - VIRTUAL Error Authorize(std::string beamtime_id,std::string uri) const noexcept; - const AbstractLogger* log__; - private: -}; - -} - -#endif //ASAPO_RECEIVER_AUTHORIZER_H diff --git a/receiver/src/receiver_config.cpp b/receiver/src/receiver_config.cpp index 28977ad95b819aaa3dd5040b0a94e543574f7c74..d2eb57eb7e716b0305ec61762b1453998fac35fd 100644 --- a/receiver/src/receiver_config.cpp +++ b/receiver/src/receiver_config.cpp @@ -21,7 +21,8 @@ Error ReceiverConfigFactory::SetConfigFromFile(std::string file_name) { (err = parser.GetBool("WriteToDb", &config.write_to_db)) || (err = parser.GetString("BrokerDbAddress", &config.broker_db_uri)) || (err = parser.GetString("Tag", &config.tag)) || - (err = parser.GetUInt64("AuthorizationInterval", &config.authorization_interval)) || + (err = parser.GetString("AuthorizationServer", &config.authorization_server)) || + (err = parser.GetUInt64("AuthorizationInterval", &config.authorization_interval_ms)) || (err = parser.GetString("RootFolder", &config.root_folder)) || (err = parser.GetString("MonitorDbName", &config.monitor_db_name)); (err = parser.GetString("LogLevel", &log_level)); diff --git a/receiver/src/receiver_config.h b/receiver/src/receiver_config.h index 7fb5ad4bc8417926a736602e067c6658d231c3ff..d99d07617b84de3a53d5e0edbff06dec75a1e5cc 100644 --- a/receiver/src/receiver_config.h +++ b/receiver/src/receiver_config.h @@ -13,7 +13,8 @@ struct ReceiverConfig { std::string broker_db_uri; std::string root_folder; uint64_t listen_port = 0; - uint64_t authorization_interval = 0; + std::string authorization_server; + uint64_t authorization_interval_ms = 0; bool write_to_disk = false; bool write_to_db = false; LogLevel log_level = LogLevel::Info; diff --git a/receiver/src/request.cpp b/receiver/src/request.cpp index a3d8e1b5e594cc0b627ab1644cf321941b8e143f..b157543fdce335aec8f25c0bd7ee10ff7ee3f6ae 100644 --- a/receiver/src/request.cpp +++ b/receiver/src/request.cpp @@ -42,7 +42,7 @@ Error Request::Handle(Statistics* statistics) { } for (auto handler : handlers_) { statistics->StartTimer(handler->GetStatisticEntity()); - auto err = handler->ProcessRequest(*this); + auto err = handler->ProcessRequest(this); if (err) { return err; } @@ -84,10 +84,17 @@ const std::string &Request::GetOriginUri() const { const std::string &Request::GetBeamtimeId() const { return beamtime_id_; } -void Request::SetBeamtimeID(std::string beamtime_id) { +void Request::SetBeamtimeId(std::string beamtime_id) { beamtime_id_ = std::move(beamtime_id); } +Opcode Request::GetOpCode() const { + return request_header_.op_code; +} +const char* Request::GetMessage() const { + return request_header_.message; +} + std::unique_ptr<Request> RequestFactory::GenerateRequest(const GenericRequestHeader& request_header, SocketDescriptor socket_fd,std::string origin_uri, Error* err) const noexcept { diff --git a/receiver/src/request.h b/receiver/src/request.h index 7c518ed48a70d2f02c58f536210bbb3c20d40283..67644d38f81204a0315f04a306cf19730685e76e 100644 --- a/receiver/src/request.h +++ b/receiver/src/request.h @@ -29,9 +29,12 @@ class Request { VIRTUAL uint64_t GetDataID() const; VIRTUAL std::string GetFileName() const; VIRTUAL const FileData& GetData() const; + VIRTUAL Opcode GetOpCode() const; + VIRTUAL const char* GetMessage() const; + const std::string& GetOriginUri() const; VIRTUAL const std::string& GetBeamtimeId() const; - void SetBeamtimeID(std::string beamtime_id); + VIRTUAL void SetBeamtimeId(std::string beamtime_id); std::unique_ptr<IO> io__; private: Error AllocateDataBuffer(); diff --git a/receiver/src/request_handler.h b/receiver/src/request_handler.h index b4a0dc1f39724047876847dbcbe5f8cc7e5d8002..49d4da20a8cc3b555d3d3f3a875cf3434d5553f0 100644 --- a/receiver/src/request_handler.h +++ b/receiver/src/request_handler.h @@ -10,7 +10,7 @@ class Request; class RequestHandler { public: - virtual Error ProcessRequest(const Request& request) const = 0; + virtual Error ProcessRequest(Request* request) const = 0; virtual StatisticEntity GetStatisticEntity() const = 0; virtual ~RequestHandler() = default; private: diff --git a/receiver/src/request_handler_authorize.cpp b/receiver/src/request_handler_authorize.cpp index 361f7fc6efa8e5d40b776572fb364bf3c8dd8217..dd806bf89710b9fb01dad87877cef5da4ef87f9f 100644 --- a/receiver/src/request_handler_authorize.cpp +++ b/receiver/src/request_handler_authorize.cpp @@ -1,18 +1,64 @@ #include "request_handler_authorize.h" #include "receiver_config.h" #include "receiver_logger.h" +#include "request.h" + + +using std::chrono::high_resolution_clock; namespace asapo { -Error RequestHandlerAuthorize::ProcessRequest(const Request& request) const { +Error RequestHandlerAuthorize::ProcessRequest(Request* request) const { + Error auth_error = asapo::ReceiverErrorTemplates::kAuthorizationFailure.Generate(); + auto op_code = request->GetOpCode(); + if (op_code != kOpcodeAuthorize && beamtime_id_.empty()) { + return ReceiverErrorTemplates::kAuthorizationFailure.Generate(); + } + if ((op_code == kOpcodeAuthorize && beamtime_id_.empty()) || + (op_code != kOpcodeAuthorize && !beamtime_id_.empty())) { + auto elapsed_ms = std::chrono::duration_cast<std::chrono::milliseconds> + ( high_resolution_clock::now() - last_updated_).count(); + if (op_code == kOpcodeAuthorize || elapsed_ms>=GetReceiverConfig()->authorization_interval_ms) { + HttpCode code; + Error err; + std::string request_string = std::string("{\"BeamtimeId\":\"") + (op_code == kOpcodeAuthorize?request->GetMessage():beamtime_id_) + + "\",\"OriginHost\":\""+ + request->GetOriginUri()+"\"}"; + auto response = http_client__->Post(GetReceiverConfig()->authorization_server+"/authorize",request_string,&code,&err); + if (err) { + auth_error->Append(err->Explain()); + log__->Error("failure authorizing at " + GetReceiverConfig()->authorization_server + " request: "+request_string + " - " + + err->Explain()); + return auth_error; + } + if (code != HttpCode::OK) { + log__->Error("failure authorizing at " + GetReceiverConfig()->authorization_server + " request: "+request_string + " - " + + "return code "+std::to_string(int(code))); + return auth_error; + } + last_updated_ = high_resolution_clock::now(); + beamtime_id_ = response; + } + request->SetBeamtimeId(beamtime_id_); + return nullptr; + } + + if (op_code == kOpcodeAuthorize && !beamtime_id_.empty()) { + auth_error->Append("already authorized"); + log__->Error("failure authorizing at " + GetReceiverConfig()->authorization_server + " - " + + "already authorized"); + return auth_error; + + } return nullptr; } -RequestHandlerAuthorize::RequestHandlerAuthorize(): log__{GetDefaultReceiverLogger()} { +RequestHandlerAuthorize::RequestHandlerAuthorize(): log__{GetDefaultReceiverLogger()}, + http_client__{DefaultHttpClient()}{ } StatisticEntity RequestHandlerAuthorize::GetStatisticEntity() const { - return StatisticEntity::kDatabase; + return StatisticEntity::kAuthorizer; } diff --git a/receiver/src/request_handler_authorize.h b/receiver/src/request_handler_authorize.h index 7dc730cfa7e9763c4d9668b0ac584919488aad45..3c4da8667979644c79253e429e7d6fc41374696a 100644 --- a/receiver/src/request_handler_authorize.h +++ b/receiver/src/request_handler_authorize.h @@ -1,8 +1,12 @@ #ifndef ASAPO_REQUEST_HANDLER_AUTHORIZE_H #define ASAPO_REQUEST_HANDLER_AUTHORIZE_H +#include <chrono> + #include "request_handler.h" #include "logger/logger.h" +#include "http_client/http_client.h" + #include "io/io.h" @@ -12,9 +16,12 @@ class RequestHandlerAuthorize final: public RequestHandler { public: RequestHandlerAuthorize(); StatisticEntity GetStatisticEntity() const override; - Error ProcessRequest(const Request& request) const override; + Error ProcessRequest(Request* request) const override; const AbstractLogger* log__; + std::unique_ptr<HttpClient>http_client__; private: + mutable std::string beamtime_id_; + mutable std::chrono::high_resolution_clock::time_point last_updated_; }; } diff --git a/receiver/src/request_handler_db_write.cpp b/receiver/src/request_handler_db_write.cpp index 17580b9b729756a93b4084ab286c34b0eb899e5a..ff2daaaff4d30d1aa8c49c7c8bfa3473c46ea023 100644 --- a/receiver/src/request_handler_db_write.cpp +++ b/receiver/src/request_handler_db_write.cpp @@ -5,9 +5,9 @@ namespace asapo { -Error RequestHandlerDbWrite::ProcessRequest(const Request& request) const { +Error RequestHandlerDbWrite::ProcessRequest(Request* request) const { if (db_name_.empty()) { - db_name_=request.GetBeamtimeId(); + db_name_=request->GetBeamtimeId(); } if (Error err = ConnectToDbIfNeeded() ) { @@ -15,9 +15,9 @@ Error RequestHandlerDbWrite::ProcessRequest(const Request& request) const { } FileInfo file_info; - file_info.name = request.GetFileName(); - file_info.size = request.GetDataSize(); - file_info.id = request.GetDataID(); + file_info.name = request->GetFileName(); + file_info.size = request->GetDataSize(); + file_info.id = request->GetDataID(); auto err = db_client__->Insert(file_info, false); if (!err) { log__->Debug(std::string{"insert record to "} + kDBCollectionName + " in " + db_name_ + diff --git a/receiver/src/request_handler_db_write.h b/receiver/src/request_handler_db_write.h index f93ed822c9bc22d79e8099e60586d000f12cfae1..dc0152f848739da55470df9dea7b828c70d6b942 100644 --- a/receiver/src/request_handler_db_write.h +++ b/receiver/src/request_handler_db_write.h @@ -13,7 +13,7 @@ class RequestHandlerDbWrite final: public RequestHandler { public: RequestHandlerDbWrite(); StatisticEntity GetStatisticEntity() const override; - Error ProcessRequest(const Request& request) const override; + Error ProcessRequest(Request* request) const override; std::unique_ptr<Database> db_client__; const AbstractLogger* log__; private: diff --git a/receiver/src/request_handler_file_write.cpp b/receiver/src/request_handler_file_write.cpp index f171484fdf4c921821c76cbb3104a7c3c1c587e5..5350353443059cda88967df10b3ef55c7aa1100c 100644 --- a/receiver/src/request_handler_file_write.cpp +++ b/receiver/src/request_handler_file_write.cpp @@ -7,16 +7,16 @@ namespace asapo { -Error RequestHandlerFileWrite::ProcessRequest(const Request& request) const { - auto fsize = request.GetDataSize(); +Error RequestHandlerFileWrite::ProcessRequest(Request* request) const { + auto fsize = request->GetDataSize(); if (fsize <= 0 || fsize > kMaxFileSize) { return ReceiverErrorTemplates::kBadRequest.Generate(); } - const FileData& data = request.GetData(); + const FileData& data = request->GetData(); - auto fname = request.GetFileName(); - auto root_folder = GetReceiverConfig()->root_folder + kPathSeparator + request.GetBeamtimeId()+kPathSeparator; + auto fname = request->GetFileName(); + auto root_folder = GetReceiverConfig()->root_folder + kPathSeparator + request->GetBeamtimeId()+kPathSeparator; auto err = io__->WriteDataToFile(root_folder + fname, data, fsize); if (!err) { log__->Debug("saved file of size " + std::to_string(fsize) + " to " + root_folder + fname); diff --git a/receiver/src/request_handler_file_write.h b/receiver/src/request_handler_file_write.h index 95756f6881d8d3d17e05bea9ba5ac9923c652bb5..a0d36b48a2aa8dad0a7e6c5a357668746754b2db 100644 --- a/receiver/src/request_handler_file_write.h +++ b/receiver/src/request_handler_file_write.h @@ -14,7 +14,7 @@ class RequestHandlerFileWrite final: public RequestHandler { public: RequestHandlerFileWrite(); StatisticEntity GetStatisticEntity() const override; - Error ProcessRequest(const Request& request) const override; + Error ProcessRequest(Request* request) const override; std::unique_ptr<IO> io__; const AbstractLogger* log__; }; diff --git a/receiver/src/requests_dispatcher.cpp b/receiver/src/requests_dispatcher.cpp index 33bdd3f7e2c3eef6ab525aef24a84a502330bfa7..37eb1be7d1b512ccd7b7ce59341c304dfd430c07 100644 --- a/receiver/src/requests_dispatcher.cpp +++ b/receiver/src/requests_dispatcher.cpp @@ -10,7 +10,6 @@ RequestsDispatcher::RequestsDispatcher(SocketDescriptor socket_fd, std::string a io__{GenerateDefaultIO()}, log__{GetDefaultReceiverLogger()}, request_factory__{new RequestFactory{}}, - authorizer__{new ConnectionAuthorizer}, socket_fd_{socket_fd}, producer_uri_{std::move(address)} { } diff --git a/receiver/src/requests_dispatcher.h b/receiver/src/requests_dispatcher.h index 9242ef8d478426e79833f80b333d977f625e905b..8acb96d7c111e5767a7e9acb7955daa997fc320e 100644 --- a/receiver/src/requests_dispatcher.h +++ b/receiver/src/requests_dispatcher.h @@ -7,7 +7,6 @@ #include "io/io.h" #include "statistics.h" #include "logger/logger.h" -#include "connection_authorizer.h" namespace asapo { @@ -20,7 +19,6 @@ class RequestsDispatcher { std::unique_ptr<IO> io__; const AbstractLogger* log__; std::unique_ptr<RequestFactory> request_factory__; - std::unique_ptr<ConnectionAuthorizer>authorizer__; private: SocketDescriptor socket_fd_; std::string producer_uri_; diff --git a/receiver/src/statistics.h b/receiver/src/statistics.h index be72cbfe07b283f5eea5c03896ea2ed5682ca046..7d7cee7f6d264a656459f9d3101227df2fed9524 100644 --- a/receiver/src/statistics.h +++ b/receiver/src/statistics.h @@ -18,6 +18,7 @@ enum StatisticEntity : int { kDatabase = 0, kDisk, kNetwork, + kAuthorizer }; struct StatisticsToSend { diff --git a/receiver/unittests/mock_receiver_config.cpp b/receiver/unittests/mock_receiver_config.cpp index 1783f3facd5bebf802f9dbc71ff04369e3ebd9ac..ae51f8f86bcaa0e294882f2f3f53ae454aaad5b6 100644 --- a/receiver/unittests/mock_receiver_config.cpp +++ b/receiver/unittests/mock_receiver_config.cpp @@ -38,7 +38,8 @@ Error SetReceiverConfig (const ReceiverConfig& config) { config_string += "," + std::string("\"MonitorDbName\":") + "\"" + config.monitor_db_name + "\""; config_string += "," + std::string("\"BrokerDbAddress\":") + "\"" + config.broker_db_uri + "\""; config_string += "," + std::string("\"ListenPort\":") + std::to_string(config.listen_port); - config_string += "," + std::string("\"AuthorizationInterval\":") + std::to_string(config.authorization_interval); + config_string += "," + std::string("\"AuthorizationInterval\":") + std::to_string(config.authorization_interval_ms); + config_string += "," + std::string("\"AuthorizationServer\":") + "\"" + config.authorization_server + "\""; config_string += "," + std::string("\"WriteToDisk\":") + (config.write_to_disk ? "true" : "false"); config_string += "," + std::string("\"WriteToDb\":") + (config.write_to_db ? "true" : "false"); config_string += "," + std::string("\"LogLevel\":") + "\"" + log_level + "\""; @@ -48,6 +49,7 @@ Error SetReceiverConfig (const ReceiverConfig& config) { config_string += "}"; + EXPECT_CALL(mock_io, ReadFileToString_t("fname", _)).WillOnce( testing::Return(config_string) ); diff --git a/receiver/unittests/mock_statistics.h b/receiver/unittests/receiver_mocking.h similarity index 65% rename from receiver/unittests/mock_statistics.h rename to receiver/unittests/receiver_mocking.h index f639caa0433fb57f23e900c7daafb443494cd998..891f3ba2012b092f28e0d672d7d3ce5404e0d09b 100644 --- a/receiver/unittests/mock_statistics.h +++ b/receiver/unittests/receiver_mocking.h @@ -5,6 +5,7 @@ #include <gmock/gmock.h> #include "../src/statistics.h" +#include "../src/request.h" namespace asapo { @@ -42,6 +43,22 @@ class MockStatistics : public asapo::Statistics { }; +class MockRequest: public Request { + public: + MockRequest(const GenericRequestHeader& request_header, SocketDescriptor socket_fd,std::string origin_uri): + Request(request_header, socket_fd,std::move(origin_uri)) {}; + + MOCK_CONST_METHOD0(GetFileName, std::string()); + MOCK_CONST_METHOD0(GetDataSize, uint64_t()); + MOCK_CONST_METHOD0(GetDataID, uint64_t()); + MOCK_CONST_METHOD0(GetData, const asapo::FileData & ()); + MOCK_CONST_METHOD0(GetBeamtimeId, const std::string & ()); + MOCK_CONST_METHOD0(GetOpCode, asapo::Opcode ()); + MOCK_CONST_METHOD0(GetMessage, const char* ()); + MOCK_METHOD1(SetBeamtimeId, void (std::string)); +}; + + } #endif //ASAPO_MOCK_STATISTICS_H diff --git a/receiver/unittests/test_authorizer.cpp b/receiver/unittests/test_authorizer.cpp deleted file mode 100644 index 56b54aa5c624c282f638cc0492f9383067f5aff8..0000000000000000000000000000000000000000 --- a/receiver/unittests/test_authorizer.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include <gtest/gtest.h> -#include <gmock/gmock.h> - -#include "unittests/MockIO.h" -#include "unittests/MockLogger.h" -#include "../src/connection.h" -#include "../src/receiver_error.h" -#include "../src/request.h" -#include "../src/statistics.h" -#include "mock_statistics.h" -#include "../src/connection_authorizer.h" -#include "../src/receiver_config.h" -#include "../src/receiver_config_factory.h" -#include "mock_receiver_config.h" - - -using ::testing::Test; -using ::testing::Return; -using ::testing::_; -using ::testing::DoAll; -using ::testing::SetArgReferee; -using ::testing::Gt; -using ::testing::Eq; -using ::testing::Ne; -using ::testing::Mock; -using ::testing::NiceMock; -using ::testing::SaveArg; -using ::testing::SaveArgPointee; -using ::testing::InSequence; -using ::testing::HasSubstr; -using ::testing::StrEq; -using ::testing::SetArgPointee; -using ::testing::AllOf; -using testing::Sequence; - - -namespace { - -//TEST(AuthorizerTests, AuthorizerReturnsOk) { -// EXPECT_CALL(mock_logger, Debug(AllOf(HasSubstr("authorized"),HasSubstr("test"), HasSubstr(connected_uri)))); -//} - - - -} diff --git a/receiver/unittests/test_config.cpp b/receiver/unittests/test_config.cpp index 4dba7c99377df64e229bfff3b59922bc3a9bc4da..45e2a4e1a628ab745523edde35919ccd9f23ec2f 100644 --- a/receiver/unittests/test_config.cpp +++ b/receiver/unittests/test_config.cpp @@ -58,8 +58,8 @@ TEST_F(ConfigTests, ReadSettings) { test_config.broker_db_uri = "localhost:27017"; test_config.log_level = asapo::LogLevel::Error; test_config.root_folder = "test_fodler"; - test_config.authorization_interval = 10000; - + test_config.authorization_interval_ms = 10000; + test_config.authorization_server = "AuthorizationServer"; auto err = asapo::SetReceiverConfig(test_config); @@ -70,7 +70,8 @@ TEST_F(ConfigTests, ReadSettings) { ASSERT_THAT(config->monitor_db_name, Eq("db_test")); ASSERT_THAT(config->broker_db_uri, Eq("localhost:27017")); ASSERT_THAT(config->listen_port, Eq(4200)); - ASSERT_THAT(config->authorization_interval, Eq(10000)); + ASSERT_THAT(config->authorization_interval_ms, Eq(10000)); + ASSERT_THAT(config->authorization_server, Eq("AuthorizationServer")); ASSERT_THAT(config->write_to_disk, Eq(true)); ASSERT_THAT(config->write_to_db, Eq(true)); ASSERT_THAT(config->log_level, Eq(asapo::LogLevel::Error)); diff --git a/receiver/unittests/test_connection.cpp b/receiver/unittests/test_connection.cpp index ca2be07d197b4aea9302ed7d30bd638292ea2430..f340ccfdd4ad15bfd743b67bbb905e464e1d9ed6 100644 --- a/receiver/unittests/test_connection.cpp +++ b/receiver/unittests/test_connection.cpp @@ -7,8 +7,7 @@ #include "../src/receiver_error.h" #include "../src/request.h" #include "../src/statistics.h" -#include "mock_statistics.h" -#include "../src/connection_authorizer.h" +#include "receiver_mocking.h" #include "../src/receiver_config.h" #include "../src/receiver_config_factory.h" #include "../src/requests_dispatcher.h" diff --git a/receiver/unittests/test_request.cpp b/receiver/unittests/test_request.cpp index f3fb5b5b8a571e0389900998dcdf4d807a8ea313..c946249f196e1f86966dd287ecfbffff43012762 100644 --- a/receiver/unittests/test_request.cpp +++ b/receiver/unittests/test_request.cpp @@ -9,7 +9,7 @@ #include "../src/request_handler_db_write.h" #include "database/database.h" -#include "mock_statistics.h" +#include "receiver_mocking.h" #include "mock_receiver_config.h" using ::testing::Test; @@ -48,8 +48,8 @@ namespace { class MockReqestHandler : public asapo::RequestHandler { public: - Error ProcessRequest(const Request& request) const override { - return Error{ProcessRequest_t(request)}; + Error ProcessRequest(Request* request) const override { + return Error{ProcessRequest_t(*request)}; } StatisticEntity GetStatisticEntity() const override { @@ -68,6 +68,8 @@ class RequestTests : public Test { uint64_t data_size_ {100}; uint64_t data_id_{15}; std::string expected_origin_uri="origin_uri"; + asapo::Opcode expected_op_code=asapo::kOpcodeTransferData; + char expected_request_message[asapo::kMaxMessageSize]="test message"; std::unique_ptr<Request> request; NiceMock<MockIO> mock_io; NiceMock<MockStatistics> mock_statistics; @@ -76,6 +78,8 @@ class RequestTests : public Test { stat = &mock_statistics; generic_request_header.data_size = data_size_; generic_request_header.data_id = data_id_; + generic_request_header.op_code = expected_op_code; + strcpy(generic_request_header.message,expected_request_message); request.reset(new Request{generic_request_header, socket_fd_,expected_origin_uri}); request->io__ = std::unique_ptr<asapo::IO> {&mock_io}; ON_CALL(mock_io, Receive_t(socket_fd_, _, data_size_, _)).WillByDefault( @@ -179,6 +183,20 @@ TEST_F(RequestTests, GetDataID) { ASSERT_THAT(id, Eq(data_id_)); } +TEST_F(RequestTests, GetOpCode) { + auto code = request->GetOpCode(); + + ASSERT_THAT(code, Eq(expected_op_code)); +} + + +TEST_F(RequestTests, GetRequestMessage) { + auto message = request->GetMessage(); + + ASSERT_THAT(message, testing::StrEq(expected_request_message)); +} + + TEST_F(RequestTests, OriginUriEmptyByDefault) { auto uri = request->GetOriginUri(); diff --git a/receiver/unittests/test_request_factory.cpp b/receiver/unittests/test_request_factory.cpp index 46b3f8c7d32eab86d84093dd3e28b49483e1e1e0..8ebfba7e2ab93103ef4dd7cd13cb925212a1fa03 100644 --- a/receiver/unittests/test_request_factory.cpp +++ b/receiver/unittests/test_request_factory.cpp @@ -13,7 +13,7 @@ #include "database/database.h" -#include "mock_statistics.h" +#include "receiver_mocking.h" #include "mock_receiver_config.h" diff --git a/receiver/unittests/test_request_handler_authorizer.cpp b/receiver/unittests/test_request_handler_authorizer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f062f253e922f262cf8d0d6b76ed7c3bee0e64c7 --- /dev/null +++ b/receiver/unittests/test_request_handler_authorizer.cpp @@ -0,0 +1,240 @@ +#include <gtest/gtest.h> +#include <gmock/gmock.h> + +#include "unittests/MockHttpClient.h" +#include "unittests/MockLogger.h" + +#include "../src/receiver_error.h" +#include "../src/request.h" +#include "../src/request_handler.h" +#include "../src/request_handler_authorize.h" +#include "common/networking.h" +#include "mock_receiver_config.h" +#include "preprocessor/definitions.h" + +#include "receiver_mocking.h" + +#include "../src/receiver_config.h" +#include "mock_receiver_config.h" + + +using ::testing::Test; +using ::testing::Return; +using ::testing::ReturnRef; +using ::testing::_; +using ::testing::DoAll; +using ::testing::SetArgReferee; +using ::testing::Gt; +using ::testing::Eq; +using ::testing::Ne; +using ::testing::Mock; +using ::testing::NiceMock; +using ::testing::InSequence; +using ::testing::SetArgPointee; +using ::testing::AllOf; +using ::testing::HasSubstr; + +using asapo::MockRequest; +using ::asapo::Error; +using ::asapo::ErrorInterface; +using ::asapo::FileDescriptor; +using ::asapo::SocketDescriptor; +using ::asapo::MockHttpClient; +using asapo::Request; +using asapo::RequestHandlerAuthorize; +using ::asapo::GenericRequestHeader; +using asapo::ReceiverConfig; +using asapo::SetReceiverConfig; +using asapo::HttpCode; + +namespace { + +TEST(Authorizer, Constructor) { + RequestHandlerAuthorize handler; + ASSERT_THAT(dynamic_cast<asapo::HttpClient*>(handler.http_client__.get()), Ne(nullptr)); + ASSERT_THAT(dynamic_cast<const asapo::AbstractLogger*>(handler.log__), Ne(nullptr)); +} + + +class AuthorizerHandlerTests : public Test { + public: + RequestHandlerAuthorize handler; + MockHttpClient mock_http_client; + std::unique_ptr<MockRequest> mock_request; + ReceiverConfig config; + + NiceMock<asapo::MockLogger> mock_logger; + std::string expected_beamtime_id = "beamtime_id"; + std::string expected_producer_uri = "producer_uri"; + std::string expected_authorization_server = "authorizer_host"; + std::string expect_request_string = std::string("{\"BeamtimeId\":\"") + expected_beamtime_id+ "\",\"OriginHost\":\""+ + expected_producer_uri+"\"}"; + + void MockRequestData(); + void SetUp() override { + GenericRequestHeader request_header; + mock_request.reset(new MockRequest{request_header, 1,expected_producer_uri}); + handler.http_client__ = std::unique_ptr<asapo::HttpClient> {&mock_http_client}; + handler.log__ = &mock_logger; + config.authorization_server = expected_authorization_server; + config.authorization_interval_ms = 0; + SetReceiverConfig(config); + } + void TearDown() override { + handler.http_client__.release(); + } + void MockAuthRequest(bool error,HttpCode code = HttpCode::OK) { + if (error) + { + EXPECT_CALL(mock_http_client, Post_t(expected_authorization_server+"/authorize", expect_request_string, _, _)). + WillOnce( + DoAll(SetArgPointee<3>(new asapo::SimpleError("http error")), + Return("") + )); + EXPECT_CALL(mock_logger, Error(AllOf(HasSubstr("failure authorizing"), + HasSubstr("http error"), + HasSubstr(expected_beamtime_id), + HasSubstr(expected_producer_uri), + HasSubstr(expected_authorization_server)))); + + } else + { + EXPECT_CALL(mock_http_client, Post_t(expected_authorization_server+"/authorize", expect_request_string, _, _)). + WillOnce( + DoAll(SetArgPointee<3>(nullptr), + SetArgPointee<2>(code), + Return(expected_beamtime_id) + )); + if (code == HttpCode::OK) { + EXPECT_CALL(*mock_request, SetBeamtimeId(expected_beamtime_id)); + } else { + EXPECT_CALL(mock_logger, Error(AllOf(HasSubstr("failure authorizing"), + HasSubstr("return code"), + HasSubstr(std::to_string(int(code))), + HasSubstr(expected_beamtime_id), + HasSubstr(expected_producer_uri), + HasSubstr(expected_authorization_server)))); + } + + } + + + } + Error MockFirstAuthorization(bool error, HttpCode code = HttpCode::OK) { + EXPECT_CALL(*mock_request, GetOpCode()) + .WillOnce(Return(asapo::kOpcodeAuthorize)) + ; + EXPECT_CALL(*mock_request, GetMessage()) + .WillOnce(Return(expected_beamtime_id.c_str())) + ; + + MockAuthRequest(error,code); + return handler.ProcessRequest(mock_request.get()); + } + +}; + +TEST_F(AuthorizerHandlerTests, CheckStatisticEntity) { + auto entity = handler.GetStatisticEntity(); + ASSERT_THAT(entity, Eq(asapo::StatisticEntity::kAuthorizer)); +} + +TEST_F(AuthorizerHandlerTests, ErrorNotAuthorizedYet) { + EXPECT_CALL(*mock_request, GetOpCode()) + .WillOnce(Return(asapo::kOpcodeTransferData)) + ; + + auto err = handler.ProcessRequest(mock_request.get()); + + ASSERT_THAT(err, Eq(asapo::ReceiverErrorTemplates::kAuthorizationFailure)); +} + +TEST_F(AuthorizerHandlerTests, ErrorProcessingAuthorizeRequest) { + + auto err = MockFirstAuthorization(true); + + ASSERT_THAT(err, Eq(asapo::ReceiverErrorTemplates::kAuthorizationFailure)); +} + + +TEST_F(AuthorizerHandlerTests, AuthorizeRequestreturns401) { + + auto err = MockFirstAuthorization(false,HttpCode::Unauthorized); + + ASSERT_THAT(err, Eq(asapo::ReceiverErrorTemplates::kAuthorizationFailure)); +} + + +TEST_F(AuthorizerHandlerTests, AuthorizeOk) { + auto err = MockFirstAuthorization(false); + + ASSERT_THAT(err, Eq(nullptr)); +} + +TEST_F(AuthorizerHandlerTests, ErrorOnSecondAuthorize) { + MockFirstAuthorization(false); + EXPECT_CALL(*mock_request, GetOpCode()) + .WillOnce(Return(asapo::kOpcodeAuthorize)); + + EXPECT_CALL(mock_logger, Error(AllOf(HasSubstr("failure authorizing"), + HasSubstr("already authorized"), + HasSubstr(expected_authorization_server)))); + + + auto err = handler.ProcessRequest(mock_request.get()); + + ASSERT_THAT(err, Eq(asapo::ReceiverErrorTemplates::kAuthorizationFailure)); +} + +TEST_F(AuthorizerHandlerTests, ErrorOnDataTransferRequestAuthorize) { + MockFirstAuthorization(false); + EXPECT_CALL(*mock_request, GetOpCode()) + .WillOnce(Return(asapo::kOpcodeTransferData)); + MockAuthRequest(true); + + auto err = handler.ProcessRequest(mock_request.get()); + + ASSERT_THAT(err, Eq(asapo::ReceiverErrorTemplates::kAuthorizationFailure)); +} + + +TEST_F(AuthorizerHandlerTests, DataTransferRequestAuthorizeReturns401) { + MockFirstAuthorization(false); + EXPECT_CALL(*mock_request, GetOpCode()) + .WillOnce(Return(asapo::kOpcodeTransferData)); + MockAuthRequest(false,HttpCode::Unauthorized); + + auto err = handler.ProcessRequest(mock_request.get()); + + ASSERT_THAT(err, Eq(asapo::ReceiverErrorTemplates::kAuthorizationFailure)); +} + +TEST_F(AuthorizerHandlerTests, DataTransferRequestAuthorizeReturnsOK) { + MockFirstAuthorization(false); + EXPECT_CALL(*mock_request, GetOpCode()) + .WillOnce(Return(asapo::kOpcodeTransferData)); + MockAuthRequest(false); + + auto err = handler.ProcessRequest(mock_request.get()); + + ASSERT_THAT(err, Eq(nullptr)); +} + +TEST_F(AuthorizerHandlerTests, DataTransferRequestAuthorizeUsesCachedValue) { + config.authorization_interval_ms = 10000; + SetReceiverConfig(config); + MockFirstAuthorization(false); + EXPECT_CALL(*mock_request, GetOpCode()) + .WillOnce(Return(asapo::kOpcodeTransferData)); + EXPECT_CALL(mock_http_client, Post_t(_, _, _, _)).Times(0); + EXPECT_CALL(*mock_request, SetBeamtimeId(expected_beamtime_id)); + + auto err = handler.ProcessRequest(mock_request.get()); + + ASSERT_THAT(err, Eq(nullptr)); +} + + + + +} \ No newline at end of file diff --git a/receiver/unittests/test_request_handler_db_writer.cpp b/receiver/unittests/test_request_handler_db_writer.cpp index ff24f9daaddb273432c7e3574b20f2e7f7117f4d..ac718d4c1f6a6a57345cb600dd5b7747f95198a0 100644 --- a/receiver/unittests/test_request_handler_db_writer.cpp +++ b/receiver/unittests/test_request_handler_db_writer.cpp @@ -14,7 +14,9 @@ #include "mock_receiver_config.h" #include "common/data_structs.h" +#include "receiver_mocking.h" +using asapo::MockRequest; using asapo::FileInfo; using ::testing::Test; using ::testing::Return; @@ -50,18 +52,6 @@ using asapo::ReceiverConfig; namespace { -class MockRequest: public Request { - public: - MockRequest(const GenericRequestHeader& request_header, SocketDescriptor socket_fd): - Request(request_header, socket_fd,"") {}; - - MOCK_CONST_METHOD0(GetFileName, std::string()); - MOCK_CONST_METHOD0(GetDataSize, uint64_t()); - MOCK_CONST_METHOD0(GetDataID, uint64_t()); - MOCK_CONST_METHOD0(GetData, const asapo::FileData & ()); - MOCK_CONST_METHOD0(GetBeamtimeId, const std::string & ()); -}; - class DbWriterHandlerTests : public Test { public: RequestHandlerDbWrite handler; @@ -76,7 +66,7 @@ class DbWriterHandlerTests : public Test { request_header.data_id = 2; handler.db_client__ = std::unique_ptr<asapo::Database> {&mock_db}; handler.log__ = &mock_logger; - mock_request.reset(new NiceMock<MockRequest> {request_header, 1}); + mock_request.reset(new NiceMock<MockRequest> {request_header, 1,""}); ON_CALL(*mock_request, GetBeamtimeId()).WillByDefault(ReturnRef(expected_beamtime_id)); } void TearDown() override { @@ -112,7 +102,7 @@ TEST_F(DbWriterHandlerTests, ProcessRequestCallsConnectDbWhenNotConnected) { EXPECT_CALL(mock_db, Connect_t("127.0.0.1:27017", expected_beamtime_id, asapo::kDBCollectionName)). WillOnce(testing::Return(nullptr)); - auto err = handler.ProcessRequest(*mock_request); + auto err = handler.ProcessRequest(mock_request.get()); ASSERT_THAT(err, Eq(nullptr)); } @@ -121,7 +111,7 @@ TEST_F(DbWriterHandlerTests, ProcessRequestReturnsErrorWhenCannotConnect) { EXPECT_CALL(mock_db, Connect_t(_, _, asapo::kDBCollectionName)). WillOnce(testing::Return(new asapo::SimpleError(""))); - auto err = handler.ProcessRequest(*mock_request); + auto err = handler.ProcessRequest(mock_request.get()); ASSERT_THAT(err, Ne(nullptr)); @@ -133,8 +123,8 @@ TEST_F(DbWriterHandlerTests, ProcessRequestDoesNotCallConnectSecondTime) { EXPECT_CALL(mock_db, Connect_t(_, _, asapo::kDBCollectionName)). WillOnce(testing::Return(nullptr)); - handler.ProcessRequest(*mock_request); - handler.ProcessRequest(*mock_request); + handler.ProcessRequest(mock_request.get()); + handler.ProcessRequest(mock_request.get()); } MATCHER_P(CompareFileInfo, file, "") { @@ -189,7 +179,7 @@ TEST_F(DbWriterHandlerTests, CallsInsert) { ) ); - handler.ProcessRequest(*mock_request); + handler.ProcessRequest(mock_request.get()); } } \ No newline at end of file diff --git a/receiver/unittests/test_request_handler_file_write.cpp b/receiver/unittests/test_request_handler_file_write.cpp index 16558f68460b9e050f7ebd11ff94562e43f7b2f8..7073736e67fd53a5828ff8f993fb4e5a1d0accc6 100644 --- a/receiver/unittests/test_request_handler_file_write.cpp +++ b/receiver/unittests/test_request_handler_file_write.cpp @@ -12,6 +12,8 @@ #include "mock_receiver_config.h" #include "preprocessor/definitions.h" +#include "receiver_mocking.h" + using ::testing::Test; using ::testing::Return; using ::testing::ReturnRef; @@ -37,6 +39,7 @@ using ::asapo::MockIO; using asapo::Request; using asapo::RequestHandlerFileWrite; using ::asapo::GenericRequestHeader; +using asapo::MockRequest; namespace { @@ -46,18 +49,6 @@ TEST(FileWrite, Constructor) { ASSERT_THAT(dynamic_cast<const asapo::AbstractLogger*>(handler.log__), Ne(nullptr)); } - -class MockRequest: public Request { - public: - MockRequest(const GenericRequestHeader& request_header, SocketDescriptor socket_fd): - Request(request_header, socket_fd,"") {}; - - MOCK_CONST_METHOD0(GetFileName, std::string()); - MOCK_CONST_METHOD0(GetDataSize, uint64_t()); - MOCK_CONST_METHOD0(GetData, const asapo::FileData & ()); - MOCK_CONST_METHOD0(GetBeamtimeId, const std::string & ()); -}; - class FileWriteHandlerTests : public Test { public: RequestHandlerFileWrite handler; @@ -71,7 +62,7 @@ class FileWriteHandlerTests : public Test { void SetUp() override { GenericRequestHeader request_header; request_header.data_id = 2; - mock_request.reset(new MockRequest{request_header, 1}); + mock_request.reset(new MockRequest{request_header, 1,""}); handler.io__ = std::unique_ptr<asapo::IO> {&mock_io}; handler.log__ = &mock_logger; } @@ -92,7 +83,7 @@ TEST_F(FileWriteHandlerTests, ErrorWhenZeroFileSize) { .WillOnce(Return(0)) ; - auto err = handler.ProcessRequest(*mock_request); + auto err = handler.ProcessRequest(mock_request.get()); ASSERT_THAT(err, Eq(asapo::ReceiverErrorTemplates::kBadRequest)); } @@ -102,7 +93,7 @@ TEST_F(FileWriteHandlerTests, ErrorWhenTooBigFileSize) { .WillOnce(Return(asapo::kMaxFileSize + 1)) ; - auto err = handler.ProcessRequest(*mock_request); + auto err = handler.ProcessRequest(mock_request.get()); ASSERT_THAT(err, Eq(asapo::ReceiverErrorTemplates::kBadRequest)); } @@ -142,7 +133,7 @@ TEST_F(FileWriteHandlerTests, CallsWriteFile) { Return(asapo::IOErrorTemplates::kUnknownIOError.Generate().release()) ); - auto err = handler.ProcessRequest(*mock_request); + auto err = handler.ProcessRequest(mock_request.get()); ASSERT_THAT(err, Eq(asapo::IOErrorTemplates::kUnknownIOError)); } @@ -162,7 +153,7 @@ TEST_F(FileWriteHandlerTests, WritesToLog) { ) ) ); - handler.ProcessRequest(*mock_request); + handler.ProcessRequest(mock_request.get()); } diff --git a/receiver/unittests/test_requests_dispatcher.cpp b/receiver/unittests/test_requests_dispatcher.cpp index 6e41c2af0a412148376c31bd7cd107b881d05c21..0f8bed97cc48546169854b20f50b44f023830f4d 100644 --- a/receiver/unittests/test_requests_dispatcher.cpp +++ b/receiver/unittests/test_requests_dispatcher.cpp @@ -6,7 +6,7 @@ #include "../src/receiver_error.h" #include "../src/request.h" #include "../src/statistics.h" -#include "mock_statistics.h" +#include "receiver_mocking.h" #include "mock_receiver_config.h" #include "../src/requests_dispatcher.h" @@ -59,7 +59,6 @@ TEST(RequestDispatcher, Constructor) { ASSERT_THAT(dynamic_cast<asapo::IO*>(dispatcher.io__.get()), Ne(nullptr)); ASSERT_THAT(dynamic_cast<asapo::RequestFactory*>(dispatcher.request_factory__.get()), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::AbstractLogger*>(dispatcher.log__), Ne(nullptr)); - ASSERT_THAT(dynamic_cast<asapo::ConnectionAuthorizer*>(dispatcher.authorizer__.get()), Ne(nullptr)); } class MockRequest: public Request { @@ -90,15 +89,6 @@ class MockRequestFactory: public asapo::RequestFactory { }; -class MockAuthorizer: public asapo::ConnectionAuthorizer { - public: - Error Authorize(std::string beamtime_id,std::string uri) const noexcept override { - return Error{Authorize_t(beamtime_id,uri)}; - } - MOCK_CONST_METHOD2(Authorize_t, ErrorInterface * (std::string beamtime_id,std::string uri)); - -}; - ACTION_P(SaveArg1ToGenericNetworkResponse, value) { auto resp = *static_cast<const GenericNetworkResponse*>(arg1); @@ -114,7 +104,6 @@ class RequestsDispatcherTests : public Test { MockRequestFactory mock_factory; NiceMock<MockStatistics> mock_statictics; NiceMock<asapo::MockLogger> mock_logger; - NiceMock<MockAuthorizer> mock_authorizer; asapo::ReceiverConfig test_config; GenericRequestHeader header; @@ -122,20 +111,18 @@ class RequestsDispatcherTests : public Test { std::unique_ptr<Request> request{&mock_request}; void SetUp() override { - test_config.authorization_interval = 0; + test_config.authorization_interval_ms = 0; SetReceiverConfig(test_config); dispatcher = std::unique_ptr<RequestsDispatcher> {new RequestsDispatcher{0, connected_uri, &mock_statictics}}; dispatcher->io__ = std::unique_ptr<asapo::IO> {&mock_io}; dispatcher->statistics__ = &mock_statictics; dispatcher->request_factory__ = std::unique_ptr<asapo::RequestFactory> {&mock_factory}; dispatcher->log__ = &mock_logger; - dispatcher->authorizer__ = std::unique_ptr<asapo::ConnectionAuthorizer> {&mock_authorizer}; } void TearDown() override { dispatcher->io__.release(); dispatcher->request_factory__.release(); - dispatcher->authorizer__.release(); request.release(); } void MockReceiveRequest(bool error ){