diff --git a/.gitignore b/.gitignore index 5f8c3feae5ccb8f8500cf0d54ded6da0079cfe02..d7c8d680d0598ba1ac993843cf1d2ee7f45fad02 100644 --- a/.gitignore +++ b/.gitignore @@ -129,7 +129,7 @@ asapo_tools/pkg #version files -common/cpp/include/asapo/common/version.h +common/cpp/include/asapo/common/internal/version.h common/go/src/asapo_common/version/version_lib.go diff --git a/CMakeModules/prepare_version.cmake b/CMakeModules/prepare_version.cmake index 02bd80de29d1097719e79e97c87df80b850e7a76..7ef56e9486d3c798234c767aedcca48654cf5821 100644 --- a/CMakeModules/prepare_version.cmake +++ b/CMakeModules/prepare_version.cmake @@ -1,4 +1,4 @@ string(TIMESTAMP TIMESTAMP "%H:%M:%S %d.%m.%Y UTC" UTC) -configure_file(${PROJECT_SOURCE_DIR}/common/cpp/include/asapo/common/version.h.in ${PROJECT_SOURCE_DIR}/common/cpp/include/asapo/common/version.h @ONLY) +configure_file(${PROJECT_SOURCE_DIR}/common/cpp/include/asapo/common/internal/version.h.in ${PROJECT_SOURCE_DIR}/common/cpp/include/asapo/common/internal/version.h @ONLY) configure_file(${PROJECT_SOURCE_DIR}/common/go/src/asapo_common/version/version_lib.go.in ${PROJECT_SOURCE_DIR}/common/go/src/asapo_common/version/version_lib.go @ONLY) diff --git a/common/cpp/CMakeLists.txt b/common/cpp/CMakeLists.txt index 4f29376de775ae22d75dc1891c047d140e5efa91..8f90ff257a0db963ffc133518e2768c020975fc7 100644 --- a/common/cpp/CMakeLists.txt +++ b/common/cpp/CMakeLists.txt @@ -6,6 +6,9 @@ add_subdirectory(src/json_parser) add_subdirectory(src/data_structs) +add_subdirectory(src/version) + + add_subdirectory(src/http_client) add_subdirectory(src/logger) diff --git a/common/cpp/include/asapo/common/version.h.in b/common/cpp/include/asapo/common/internal/version.h.in similarity index 79% rename from common/cpp/include/asapo/common/version.h.in rename to common/cpp/include/asapo/common/internal/version.h.in index 5edb453a45dbcdfc94402b7699a08bdf4c99805d..22f7de8e83814a9c7a693cddfa20cbdbb37d1544 100644 --- a/common/cpp/include/asapo/common/version.h.in +++ b/common/cpp/include/asapo/common/internal/version.h.in @@ -4,10 +4,13 @@ #include <iostream> #include "string.h" -#include "data_structs.h" +#include "asapo/common/data_structs.h" +#include "asapo/common/error.h" +#include "asapo/http_client/http_client.h" namespace asapo { + const char kVersion[] = "@ASAPO_VERSION@@ASAPO_VERSION_COMMIT@"; inline void ExitAfterPrintVersionIfNeeded(std::string prefix,int argc, char* argv[]) { @@ -33,7 +36,9 @@ inline int VersionToNumber(const std::string& version) { return int(atof(version.c_str()+2)*1000); } +Error ExtractVersionFromResponse(const std::string &response, + std::string* server_info, + bool* supported); } - #endif //ASAPO_VERSION_H diff --git a/common/cpp/src/version/CMakeLists.txt b/common/cpp/src/version/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..71abb5416d246fb255410e132556e4f43f5c5b7b --- /dev/null +++ b/common/cpp/src/version/CMakeLists.txt @@ -0,0 +1,12 @@ +set(TARGET_NAME version) +set(SOURCE_FILES + version.cpp +) + +################################ +# Library +################################ + +add_library(${TARGET_NAME} OBJECT ${SOURCE_FILES}) +target_include_directories(${TARGET_NAME} PUBLIC ${ASAPO_CXX_COMMON_INCLUDE_DIR} + ${CMAKE_SOURCE_DIR}/3d_party/rapidjson/include) diff --git a/common/cpp/src/version/version.cpp b/common/cpp/src/version/version.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1f9d2a39285946f5f3a3a2322f6c54b800c31bf3 --- /dev/null +++ b/common/cpp/src/version/version.cpp @@ -0,0 +1,27 @@ +#include "asapo/common/internal/version.h" +#include "asapo/json_parser/json_parser.h" + +namespace asapo { + +Error ExtractVersionFromResponse(const std::string &response, + std::string* server_info, + bool* supported) { + JsonStringParser parser(response); + std::string server_version, current_client_protocol, client_supported; + Error err; + if ((err = parser.GetString("softwareVersion", &server_version)) + || (err = parser.GetString("clientSupported", &client_supported)) + || (err = parser.Embedded("clientProtocol").GetString("versionInfo", ¤t_client_protocol))) { + return err; + } + if (server_info) { + *server_info = + "Server version: " + server_version + ", protocol on server: " + current_client_protocol; + } + if (supported) { + *supported = client_supported == "yes"; + } + return nullptr; +} + +} \ No newline at end of file diff --git a/consumer/api/cpp/CMakeLists.txt b/consumer/api/cpp/CMakeLists.txt index 24661f0da20047c86732a811b657cf9f8d5e24ee..47d30a20f9a39dd6f83f070f39d6ac67e838fa68 100644 --- a/consumer/api/cpp/CMakeLists.txt +++ b/consumer/api/cpp/CMakeLists.txt @@ -12,7 +12,7 @@ set(SOURCE_FILES # Library ################################ add_library(${TARGET_NAME} STATIC ${SOURCE_FILES} $<TARGET_OBJECTS:system_io> - $<TARGET_OBJECTS:json_parser> $<TARGET_OBJECTS:data_structs> $<TARGET_OBJECTS:curl_http_client> ) + $<TARGET_OBJECTS:json_parser> $<TARGET_OBJECTS:data_structs> $<TARGET_OBJECTS:version> $<TARGET_OBJECTS:curl_http_client> ) target_include_directories(${TARGET_NAME} PUBLIC include ${ASAPO_CXX_COMMON_INCLUDE_DIR} ${LIBFABRIC_INCLUDE_DIR} ${CURL_INCLUDE_DIRS}) diff --git a/consumer/api/cpp/include/asapo/asapo_consumer.h b/consumer/api/cpp/include/asapo/asapo_consumer.h index e9dee4e9b5ebe0b003680e268eae48b32e91a32b..176d1d56269f35053b1fe8285a84352f6b72d487 100644 --- a/consumer/api/cpp/include/asapo/asapo_consumer.h +++ b/consumer/api/cpp/include/asapo/asapo_consumer.h @@ -3,7 +3,6 @@ #include "asapo/consumer/consumer.h" #include "asapo/consumer/consumer_error.h" -#include "asapo/common/version.h" #include <ostream> #endif //ASAPO_ASAPO_CONSUMER_H diff --git a/consumer/api/cpp/include/asapo/consumer/consumer.h b/consumer/api/cpp/include/asapo/consumer/consumer.h index 2cd1d71b678dcb22554489f9f9bf4428f970f64e..dba769567f4fec4dbd39de384f50f79205a024bc 100644 --- a/consumer/api/cpp/include/asapo/consumer/consumer.h +++ b/consumer/api/cpp/include/asapo/consumer/consumer.h @@ -27,6 +27,14 @@ class Consumer { \return nullptr of command was successful, otherwise error. */ virtual Error ResetLastReadMarker(std::string group_id, std::string stream) = 0; + //! Return version + /*! + \param client_info - for client version + \param server_info - for server + \param supported - set to true if client is supported by server + \return nullptr of command was successful, otherwise error. + */ + virtual Error GetVersionInfo(std::string* client_info,std::string* server_info, bool* supported) = 0; virtual Error SetLastReadMarker(std::string group_id, uint64_t value, std::string stream) = 0; diff --git a/consumer/api/cpp/src/consumer_impl.cpp b/consumer/api/cpp/src/consumer_impl.cpp index 5df785afa0bf6151206a71b7ab22200e40170094..6ac36b34e5290de72dabab928d7c1eb35ec95d72 100644 --- a/consumer/api/cpp/src/consumer_impl.cpp +++ b/consumer/api/cpp/src/consumer_impl.cpp @@ -12,7 +12,7 @@ #include "fabric_consumer_client.h" #include "rds_response_error.h" -#include "asapo/common/version.h" +#include "asapo/common/internal/version.h" using std::chrono::system_clock; @@ -734,7 +734,7 @@ Error ConsumerImpl::UpdateFolderTokenIfNeeded(bool ignore_existing) { RequestInfo ConsumerImpl::CreateFolderTokenRequest() const { RequestInfo ri; ri.host = endpoint_; - ri.api = "/asapo-authorizer/"+kConsumerProtocol.GetAuthorizerVersion()+"/folder"; + ri.api = "/asapo-authorizer/" + kConsumerProtocol.GetAuthorizerVersion() + "/folder"; ri.post = true; ri.body = "{\"Folder\":\"" + source_path_ + "\",\"BeamtimeId\":\"" + source_credentials_.beamtime_id + "\",\"Token\":\"" @@ -909,4 +909,38 @@ RequestInfo ConsumerImpl::GetSizeRequestForSingleMessagesStream(std::string &str return ri; } +RequestInfo ConsumerImpl::GetVersionRequest() const { + RequestInfo ri; + ri.host = endpoint_; + ri.api = "/asapo-discovery/" + kConsumerProtocol.GetDiscoveryVersion() + "/version"; + ri.extra_params = "&client=consumer&protocol=" + kConsumerProtocol.GetVersion(); + return ri; +} + +Error ConsumerImpl::GetServerVersionInfo(std::string* server_info, bool* supported) { + auto ri = GetVersionRequest(); + RequestOutput output; + auto err = ProcessRequest(&output, ri, nullptr); + if (err) { + return err; + } + return ExtractVersionFromResponse(output.string_output,server_info,supported); } + +Error ConsumerImpl::GetVersionInfo(std::string* client_info, std::string* server_info, bool* supported) { + if (client_info == nullptr && server_info == nullptr && supported == nullptr) { + return ConsumerErrorTemplates::kWrongInput.Generate("missing parameters"); + } + if (client_info != nullptr) { + *client_info = + "software version: " + std::string(kVersion) + ", consumer protocol: " + kConsumerProtocol.GetVersion(); + } + + if (server_info != nullptr || supported != nullptr) { + return GetServerVersionInfo(server_info,supported); + } + + return nullptr; +} + +} \ No newline at end of file diff --git a/consumer/api/cpp/src/consumer_impl.h b/consumer/api/cpp/src/consumer_impl.h index 94217754e20c1c001e24604fc30511e9a4b8c10f..ef0ee3ac8679b32d415dee65442565e28da66558 100644 --- a/consumer/api/cpp/src/consumer_impl.h +++ b/consumer/api/cpp/src/consumer_impl.h @@ -84,6 +84,7 @@ class ConsumerImpl final : public asapo::Consumer { Error GetById(uint64_t id, MessageMeta* info, MessageData* data, std::string stream) override; + Error GetVersionInfo(std::string* client_info,std::string* server_info, bool* supported) override; void SetTimeout(uint64_t timeout_ms) override; void ForceNoRdma() override; @@ -146,6 +147,7 @@ class ConsumerImpl final : public asapo::Consumer { uint64_t GetCurrentCount(std::string stream, const RequestInfo& ri, Error* err); RequestInfo GetStreamListRequest(const std::string &from, const StreamFilter &filter) const; + Error GetServerVersionInfo(std::string* server_info, bool* supported) ; std::string endpoint_; std::string current_broker_uri_; @@ -169,6 +171,8 @@ class ConsumerImpl final : public asapo::Consumer { RequestInfo GetSizeRequestForDatasetStream(std::string &stream, bool include_incomplete) const; uint64_t ParseGetCurrentCountResponce(Error* err, const std::string &responce) const; RequestInfo GetDiscoveryRequest(const std::string &service_name) const; + RequestInfo GetVersionRequest() const; + }; } diff --git a/consumer/api/cpp/src/fabric_consumer_client.cpp b/consumer/api/cpp/src/fabric_consumer_client.cpp index ed3524a993c264bce3b0eaaae6c487f569deadb0..774513e1f4d7dab3abce541dfa3e4b1261d46d5b 100644 --- a/consumer/api/cpp/src/fabric_consumer_client.cpp +++ b/consumer/api/cpp/src/fabric_consumer_client.cpp @@ -3,7 +3,7 @@ #include <iostream> #include "fabric_consumer_client.h" #include "rds_response_error.h" -#include "asapo/common/version.h" +#include "asapo/common/internal/version.h" using namespace asapo; diff --git a/consumer/api/cpp/src/tcp_consumer_client.cpp b/consumer/api/cpp/src/tcp_consumer_client.cpp index 5846a4a940b7e1099a34ac2082f82a2e8b5c8084..d58f05d6bb3213beeb39ec7e0a539ed181a68345 100644 --- a/consumer/api/cpp/src/tcp_consumer_client.cpp +++ b/consumer/api/cpp/src/tcp_consumer_client.cpp @@ -2,7 +2,7 @@ #include "asapo/io/io_factory.h" #include "asapo/common/networking.h" #include "rds_response_error.h" -#include "asapo/common/version.h" +#include "asapo/common/internal/version.h" namespace asapo { diff --git a/consumer/api/cpp/unittests/test_consumer_impl.cpp b/consumer/api/cpp/unittests/test_consumer_impl.cpp index c2048a67df97d8b60d71f6f09402b0e475d5bd8e..6ad5448e5d336702803094aa454d40e4292e9555 100644 --- a/consumer/api/cpp/unittests/test_consumer_impl.cpp +++ b/consumer/api/cpp/unittests/test_consumer_impl.cpp @@ -14,6 +14,7 @@ #include "asapo/http_client/http_error.h" #include "mocking.h" #include "../src/tcp_consumer_client.h" +#include "asapo/common/internal/version.h" using asapo::ConsumerFactory; using asapo::Consumer; @@ -1342,4 +1343,30 @@ TEST_F(ConsumerImplTests, GetCurrentDataSetCounteUsesCorrectUri) { ASSERT_THAT(size, Eq(10)); } + +TEST_F(ConsumerImplTests, GetVersionInfoClientOnly) { + std::string client_info; + auto err = consumer->GetVersionInfo(&client_info,nullptr,nullptr); + ASSERT_THAT(err, Eq(nullptr)); + ASSERT_THAT(client_info, HasSubstr(std::string(asapo::kVersion))); + ASSERT_THAT(client_info, HasSubstr(asapo::kConsumerProtocol.GetVersion())); +} + +TEST_F(ConsumerImplTests, GetVersionInfoWithServer) { + + std::string result = R"({"softwareVersion":"20.03.1, build 7a9294ad","clientSupported":"no", "clientProtocol":{"versionInfo":"v0.2"}})"; + + EXPECT_CALL(mock_http_client, Get_t(HasSubstr(expected_server_uri + "/asapo-discovery/v0.1/version?token=token&client=consumer&protocol=v0.1"), _,_)).WillOnce(DoAll( + SetArgPointee<1>(HttpCode::OK), + SetArgPointee<2>(nullptr), + Return(result))); + + std::string client_info,server_info; + auto err = consumer->GetVersionInfo(&client_info,&server_info,nullptr); + ASSERT_THAT(err, Eq(nullptr)); + ASSERT_THAT(server_info, HasSubstr("20.03.1")); + ASSERT_THAT(server_info, HasSubstr("v0.2")); +} + + } diff --git a/deploy/nomad_consul_docker/orchestr_config.py b/deploy/nomad_consul_docker/orchestr_config.py index 5e91651d3bd413a2359790284df9da1b6023b904..52f5da0e6d6fc01be04c96a3d73320170919e1ba 100644 --- a/deploy/nomad_consul_docker/orchestr_config.py +++ b/deploy/nomad_consul_docker/orchestr_config.py @@ -59,8 +59,6 @@ def process_file(file_in,file_out): filein = open(file_in) src = Template(filein.read()) d = set_parameters() - print d - with open(file_out, "w") as out: out.write(src.substitute(d)) diff --git a/discovery/src/asapo_discovery/protocols/protocols.go b/discovery/src/asapo_discovery/protocols/protocols.go index 0d52d1737734d83a756ceda68f3c7b12fd6e99ba..ada29e7f0e67348e233e8eb21f40903c0c12080a 100644 --- a/discovery/src/asapo_discovery/protocols/protocols.go +++ b/discovery/src/asapo_discovery/protocols/protocols.go @@ -20,8 +20,8 @@ type Protocol struct { } type ProtocolInfo struct { - Info string - MicroserviceAPis map[string]string + VersionInfo string `json:"versionInfo"` + MicroservicesApi map[string]string `json:"microservicesApi"` } func (p *Protocol) IsValid() (hint string, ok bool) { @@ -76,8 +76,8 @@ func GetSupportedProtocolsArray(client string) ([]ProtocolInfo, error) { res:=make([]ProtocolInfo,0) for _,protocol := range protocols { var info ProtocolInfo - info.Info = protocol.GetString() - info.MicroserviceAPis = protocol.MicroserviceAPis + info.VersionInfo = protocol.GetString() + info.MicroservicesApi = protocol.MicroserviceAPis res = append(res, info) } return res,nil diff --git a/discovery/src/asapo_discovery/server/get_version.go b/discovery/src/asapo_discovery/server/get_version.go index 2c9d937ae82f3fb7db21e457ee6125308507b1dc..3e2abebd5afd815adb2bda77982424acff6c5992 100644 --- a/discovery/src/asapo_discovery/server/get_version.go +++ b/discovery/src/asapo_discovery/server/get_version.go @@ -11,12 +11,10 @@ import ( ) type versionInfo struct { - CoreServices string - ClientConsumerProtocol protocols.ProtocolInfo - ClientProducerProtocol protocols.ProtocolInfo - ClientSupported string - SupportedProducerProtocols []protocols.ProtocolInfo - SupportedConsumerProtocols []protocols.ProtocolInfo + SoftwareVersion string `json:"softwareVersion"` + ClientProtocol protocols.ProtocolInfo `json:"clientProtocol"` + ClientSupported string `json:"clientSupported"` + SupportedProtocols []protocols.ProtocolInfo `json:"supportedProtocols"` } func extractProtocol(r *http.Request) (string, error) { @@ -55,23 +53,25 @@ func checkDiscoveryApiVersion(w http.ResponseWriter, r *http.Request) bool { } func getVersionInfo(client string, ver string) (versionInfo, error) { - info, err := getCoreInfo() + info, err := getCoreInfo(client) if err != nil { return versionInfo{}, err } + if ver=="" { + return info, nil + } updateClientInfo(client, ver, &info) return info, nil } -func getCoreInfo() (versionInfo, error) { +func getCoreInfo(client string) (versionInfo, error) { var info versionInfo - info.CoreServices = version.GetVersion() - var err error - info.SupportedConsumerProtocols, err = protocols.GetSupportedProtocolsArray("consumer") - if err != nil { - return versionInfo{}, err + info.SoftwareVersion = version.GetVersion() + if client=="" { + return info, nil } - info.SupportedProducerProtocols, err = protocols.GetSupportedProtocolsArray("producer") + var err error + info.SupportedProtocols, err = protocols.GetSupportedProtocolsArray(client) if err != nil { return versionInfo{}, err } @@ -85,10 +85,10 @@ func updateClientInfo(client string, ver string, info *versionInfo) { pInfo,valid := getProtocolInfo(client, ver, info) setSupported(valid, info) if client == "consumer" { - info.ClientConsumerProtocol = pInfo + info.ClientProtocol = pInfo } else if client == "producer" { - info.ClientProducerProtocol = pInfo + info.ClientProtocol = pInfo } } @@ -103,13 +103,13 @@ func setSupported(valid bool, info *versionInfo) { func getProtocolInfo(client string, ver string, info *versionInfo) (pInfo protocols.ProtocolInfo, valid bool) { protocol, err := protocols.FindProtocol(client, ver) if err != nil { - pInfo.Info = ver + " (" + err.Error() + ")" + pInfo.VersionInfo = ver + " (" + err.Error() + ")" valid = false } else { var hint string hint, valid = protocol.IsValid() - pInfo.Info = ver + " (" + hint + ")" - pInfo.MicroserviceAPis = protocol.MicroserviceAPis + pInfo.VersionInfo = ver + " (" + hint + ")" + pInfo.MicroservicesApi = protocol.MicroserviceAPis } return } diff --git a/discovery/src/asapo_discovery/server/get_version_test.go b/discovery/src/asapo_discovery/server/get_version_test.go index cf4b0db1ca39c76e3f00d37a6132b63f91c38958..5a1e99c8a159a36b9c884b51b83a8d97d11c851e 100644 --- a/discovery/src/asapo_discovery/server/get_version_test.go +++ b/discovery/src/asapo_discovery/server/get_version_test.go @@ -19,29 +19,31 @@ var versionTests = []struct { message string }{ {"", versionInfo{ - CoreServices: coreVer, - ClientConsumerProtocol: protocols.ProtocolInfo{}, - ClientProducerProtocol: protocols.ProtocolInfo{}, - ClientSupported: "", + SoftwareVersion: coreVer, + ClientProtocol: protocols.ProtocolInfo{}, + ClientSupported: "", }, http.StatusOK, "no client"}, + {"?client=consumer", versionInfo{ + SoftwareVersion: coreVer, + ClientProtocol: protocols.ProtocolInfo{"", nil}, + ClientSupported: "no", + }, http.StatusOK, "consumer client, no protocol"}, + {"?client=consumer&protocol=v0.1", versionInfo{ - CoreServices: coreVer, - ClientConsumerProtocol: protocols.ProtocolInfo{"v0.1 (current)", + SoftwareVersion: coreVer, + ClientProtocol: protocols.ProtocolInfo{"v0.1 (current)", map[string]string{"Authorizer":"v0.1", "Broker":"v0.1", "Data cache service":"v0.1", "Discovery":"v0.1", "File Transfer":"v0.1"}}, - ClientProducerProtocol: protocols.ProtocolInfo{}, ClientSupported: "yes", }, http.StatusOK, "consumer client"}, {"?client=producer&protocol=v0.1", versionInfo{ - CoreServices: coreVer, - ClientProducerProtocol: protocols.ProtocolInfo{"v0.1 (current)",map[string]string{"Discovery":"v0.1", "Receiver":"v0.1"}}, - ClientConsumerProtocol: protocols.ProtocolInfo{}, - ClientSupported: "yes", + SoftwareVersion: coreVer, + ClientProtocol: protocols.ProtocolInfo{"v0.1 (current)",map[string]string{"Discovery":"v0.1", "Receiver":"v0.1"}}, + ClientSupported: "yes", }, http.StatusOK, "producer client"}, {"?client=producer&protocol=v0.2", versionInfo{ - CoreServices: coreVer, - ClientProducerProtocol: protocols.ProtocolInfo{"v0.2 (unknown protocol)",nil}, - ClientConsumerProtocol: protocols.ProtocolInfo{}, - ClientSupported: "no", + SoftwareVersion: coreVer, + ClientProtocol: protocols.ProtocolInfo{"v0.2 (unknown protocol)",nil}, + ClientSupported: "no", }, http.StatusOK, "producer client unknown"}, } @@ -53,9 +55,10 @@ func TestVersionTests(t *testing.T) { var info versionInfo json.Unmarshal(w.Body.Bytes(), &info) fmt.Println(w.Body.String()) - assert.Equal(t, test.result.ClientConsumerProtocol,info.ClientConsumerProtocol, test.message) - assert.Equal(t, true,len(info.SupportedProducerProtocols)>0, test.message) - assert.Equal(t, true,len(info.SupportedConsumerProtocols)>0, test.message) + assert.Equal(t, test.result.ClientProtocol,info.ClientProtocol, test.message) + if test.message!="no client" { + assert.Equal(t, true,len(info.SupportedProtocols)>0, test.message) + } } } } diff --git a/discovery/src/asapo_discovery/server/routes_test.go b/discovery/src/asapo_discovery/server/routes_test.go index 34a020ca5c25fc56b01ce0a8523d6df9b1e20d22..e72d0c55abfba927659cf6e56f651046b504e2a0 100644 --- a/discovery/src/asapo_discovery/server/routes_test.go +++ b/discovery/src/asapo_discovery/server/routes_test.go @@ -145,7 +145,6 @@ func (suite *GetServicesTestSuite) TestGetVersions() { suite.Equal(http.StatusOK, w.Code, "code ok") // we dont really check what it returns, just that route is ok suite.Contains(w.Body.String(), version.GetVersion(), "core version") - suite.Contains(w.Body.String(), "SupportedConsumerProtocols", "consumer protocols") - suite.Contains(w.Body.String(), "SupportedProducerProtocols", "producers protocols") + suite.Contains(w.Body.String(), "supportedProtocols", "protocols") assertExpectations(suite.T()) } diff --git a/examples/consumer/getnext/getnext.cpp b/examples/consumer/getnext/getnext.cpp index ae48a1a29a3594f749523b5e4fe1432f86377b93..d30e87e578210fb3776e34c18c1fd4d332ad321b 100644 --- a/examples/consumer/getnext/getnext.cpp +++ b/examples/consumer/getnext/getnext.cpp @@ -265,7 +265,6 @@ void TryGetStream(Args* args) { } int main(int argc, char* argv[]) { - asapo::ExitAfterPrintVersionIfNeeded("GetNext consumer Example", argc, argv); Args params; params.datasets = false; if (argc != 8 && argc != 9) { diff --git a/examples/pipeline/in_to_out/in_to_out.cpp b/examples/pipeline/in_to_out/in_to_out.cpp index 801d9f32a0653776f4a2093a2a3d545bcad19dc3..e96985a02266e9a7e5fa3bde748e0ba6361e3478 100644 --- a/examples/pipeline/in_to_out/in_to_out.cpp +++ b/examples/pipeline/in_to_out/in_to_out.cpp @@ -206,7 +206,6 @@ std::unique_ptr<asapo::Producer> CreateProducer(const Args &args) { } int main(int argc, char* argv[]) { - asapo::ExitAfterPrintVersionIfNeeded("GetNext consumer Example", argc, argv); Args args; if (argc != 11) { std::cout << "Usage: " + std::string{argv[0]} diff --git a/examples/producer/dummy-data-producer/dummy_data_producer.cpp b/examples/producer/dummy-data-producer/dummy_data_producer.cpp index d983f01e2d419a5b5ca0356e746d4a64d16b54be..560cd20ba6b9f89aa52d40deae4cab08319f2666 100644 --- a/examples/producer/dummy-data-producer/dummy_data_producer.cpp +++ b/examples/producer/dummy-data-producer/dummy_data_producer.cpp @@ -69,7 +69,6 @@ void TryGetDataSourceAndToken(Args* args) { void ProcessCommandArguments(int argc, char* argv[], Args* args) { - asapo::ExitAfterPrintVersionIfNeeded("Dummy Data Producer", argc, argv); if (argc != 8 && argc != 9) { std::cout << "Usage: " << argv[0] << diff --git a/producer/api/cpp/CMakeLists.txt b/producer/api/cpp/CMakeLists.txt index 896c05265d55a5b9c9cea5fbfc75fc877d8716d0..24b5722350e4392b898e3d4b350055184c8b8c4b 100644 --- a/producer/api/cpp/CMakeLists.txt +++ b/producer/api/cpp/CMakeLists.txt @@ -14,7 +14,7 @@ set(SOURCE_FILES # Library ################################ add_library(${TARGET_NAME} STATIC ${SOURCE_FILES} $<TARGET_OBJECTS:system_io> $<TARGET_OBJECTS:logger> $<TARGET_OBJECTS:json_parser> - $<TARGET_OBJECTS:curl_http_client> $<TARGET_OBJECTS:request_pool> $<TARGET_OBJECTS:data_structs>) + $<TARGET_OBJECTS:curl_http_client> $<TARGET_OBJECTS:request_pool> $<TARGET_OBJECTS:data_structs> $<TARGET_OBJECTS:version>) target_include_directories(${TARGET_NAME} PUBLIC include ${ASAPO_CXX_COMMON_INCLUDE_DIR}) target_link_libraries(${TARGET_NAME} ${CURL_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) diff --git a/producer/api/cpp/include/asapo/asapo_producer.h b/producer/api/cpp/include/asapo/asapo_producer.h index 1e5ea176cd474cfb25e98e0523ea16ee0ac0418b..152abe230de7e0fe2f7604c55d0f7f3885fccb76 100644 --- a/producer/api/cpp/include/asapo/asapo_producer.h +++ b/producer/api/cpp/include/asapo/asapo_producer.h @@ -2,7 +2,6 @@ #define ASAPO_ASAPO_PRODUCER_H #include "asapo/common/io_error.h" -#include "asapo/common/version.h" #include "asapo/producer/producer.h" #include "asapo/producer/producer_error.h" diff --git a/producer/api/cpp/include/asapo/producer/producer.h b/producer/api/cpp/include/asapo/producer/producer.h index c8de7d637ff86f09f2f976e52f792e23a54cc816..a2fde18ebeeb2f3ae0a02784bf6f5ccf39382bc3 100644 --- a/producer/api/cpp/include/asapo/producer/producer.h +++ b/producer/api/cpp/include/asapo/producer/producer.h @@ -23,6 +23,15 @@ class Producer { virtual ~Producer() = default; + //! Return version + /*! + \param client_info - for client version + \param server_info - for server + \param supported - set to true if client is supported by server + \return nullptr of command was successful, otherwise error. + */ + virtual Error GetVersionInfo(std::string* client_info,std::string* server_info, bool* supported) const = 0; + //! Get stream information from receiver /*! \param stream - stream to send messages to diff --git a/producer/api/cpp/src/producer_impl.cpp b/producer/api/cpp/src/producer_impl.cpp index cba069bb723f350b3713166b27c00208af13671b..6779fbacb0e8f88707bdf6d2d1d526024baf294f 100644 --- a/producer/api/cpp/src/producer_impl.cpp +++ b/producer/api/cpp/src/producer_impl.cpp @@ -1,16 +1,16 @@ #include <iostream> -#include <iostream> #include <cstring> #include <future> #include "producer_impl.h" #include "producer_logger.h" -#include "asapo/io/io_factory.h" #include "asapo/producer/producer_error.h" #include "producer_request_handler_factory.h" #include "producer_request.h" #include "asapo/common/data_structs.h" #include "asapo/request/request_pool_error.h" +#include "asapo/http_client/http_client.h" +#include "asapo/common/internal/version.h" namespace asapo { @@ -18,7 +18,7 @@ const size_t ProducerImpl::kDiscoveryServiceUpdateFrequencyMs = 10000; // 10s ProducerImpl::ProducerImpl(std::string endpoint, uint8_t n_processing_threads, uint64_t timeout_ms, asapo::RequestHandlerType type): - log__{GetDefaultProducerLogger()}, timeout_ms_{timeout_ms} { + log__{GetDefaultProducerLogger()},httpclient__{DefaultHttpClient()}, timeout_ms_{timeout_ms},endpoint_{endpoint} { switch (type) { case RequestHandlerType::kTcp: discovery_service_.reset(new ReceiverDiscoveryService{endpoint, ProducerImpl::kDiscoveryServiceUpdateFrequencyMs}); @@ -392,5 +392,31 @@ void ProducerImpl::SetRequestsQueueLimits(uint64_t size, uint64_t volume) { request_pool__->SetLimits(RequestPoolLimits{size,volume}); } +Error ProducerImpl::GetVersionInfo(std::string* client_info, std::string* server_info, bool* supported) const { + if (client_info == nullptr && server_info == nullptr && supported == nullptr) { + return ProducerErrorTemplates::kWrongInput.Generate("missing parameters"); + } + if (client_info != nullptr) { + *client_info = + "software version: " + std::string(kVersion) + ", consumer protocol: " + kProducerProtocol.GetVersion(); + } + + if (server_info != nullptr || supported != nullptr) { + return GetServerVersionInfo(server_info, supported); + } + return nullptr; +} + +Error ProducerImpl::GetServerVersionInfo(std::string* server_info, + bool* supported) const { + auto endpoint = endpoint_ +"/asapo-discovery/"+kProducerProtocol.GetDiscoveryVersion()+"/version?client=producer&protocol="+kProducerProtocol.GetVersion(); + HttpCode code; + Error err; + auto response = httpclient__->Get(endpoint, &code, &err); + if (err) { + return err; + } + return ExtractVersionFromResponse(response,server_info,supported); +} } \ No newline at end of file diff --git a/producer/api/cpp/src/producer_impl.h b/producer/api/cpp/src/producer_impl.h index a60b59c7dfd0a49b43f2757c782917ab3262a1e2..53fda3df0a07508efce6dc7f7ef891af2601bf4a 100644 --- a/producer/api/cpp/src/producer_impl.h +++ b/producer/api/cpp/src/producer_impl.h @@ -30,6 +30,9 @@ class ProducerImpl : public Producer { ProducerImpl(const ProducerImpl &) = delete; ProducerImpl &operator=(const ProducerImpl &) = delete; + + Error GetVersionInfo(std::string* client_info,std::string* server_info, bool* supported) const override; + StreamInfo GetStreamInfo(std::string stream, uint64_t timeout_ms, Error* err) const override; StreamInfo GetLastStream(uint64_t timeout_ms, Error* err) const override; @@ -56,6 +59,7 @@ class ProducerImpl : public Producer { RequestCallback callback) override; AbstractLogger* log__; + std::unique_ptr<HttpClient> httpclient__; std::unique_ptr<RequestPool> request_pool__; Error SetCredentials(SourceCredentials source_cred) override; @@ -74,6 +78,9 @@ class ProducerImpl : public Producer { uint64_t ingest_mode); std::string source_cred_string_; uint64_t timeout_ms_; + std::string endpoint_; + Error GetServerVersionInfo(std::string* server_info, + bool* supported) const; }; struct StreamInfoResult { diff --git a/producer/api/cpp/src/producer_request.cpp b/producer/api/cpp/src/producer_request.cpp index 32dfaa87e9cbbd9905a1013e1457d8d35b5e1cda..7d41d0d44c1311674214c1d72bf72e0955d5f044 100644 --- a/producer/api/cpp/src/producer_request.cpp +++ b/producer/api/cpp/src/producer_request.cpp @@ -1,5 +1,6 @@ #include <asapo/asapo_producer.h> #include "producer_request.h" +#include "asapo/common/internal/version.h" namespace asapo { diff --git a/producer/api/cpp/src/receiver_discovery_service.cpp b/producer/api/cpp/src/receiver_discovery_service.cpp index 9a92bf9746de0b62d91ee3b56569593ba7af4837..b1130b7ec6043a9635c2336c57de719967e48eda 100644 --- a/producer/api/cpp/src/receiver_discovery_service.cpp +++ b/producer/api/cpp/src/receiver_discovery_service.cpp @@ -6,7 +6,7 @@ #include "producer_logger.h" #include "asapo/json_parser/json_parser.h" -#include "asapo/common/version.h" +#include "asapo/common/internal/version.h" namespace asapo { diff --git a/producer/api/cpp/unittests/test_producer_impl.cpp b/producer/api/cpp/unittests/test_producer_impl.cpp index bdea491aceec053a3b03579c6e38e01be7c9c3dc..5219352f164def64bf0b0d1c819af0feba464c3d 100644 --- a/producer/api/cpp/unittests/test_producer_impl.cpp +++ b/producer/api/cpp/unittests/test_producer_impl.cpp @@ -1,5 +1,3 @@ -#pragma clang diagnostic push -#pragma ide diagnostic ignored "InfiniteRecursion" #include <gtest/gtest.h> #include <gmock/gmock.h> @@ -11,6 +9,7 @@ #include "../src/request_handler_tcp.h" #include "asapo/request/request_pool_error.h" +#include "asapo/unittests/MockHttpClient.h" #include "mocking.h" @@ -26,10 +25,13 @@ using ::testing::Ne; using ::testing::Mock; using ::testing::InSequence; using ::testing::HasSubstr; +using testing::SetArgPointee; using asapo::RequestPool; using asapo::ProducerRequest; +using asapo::MockHttpClient; + MATCHER_P10(M_CheckSendRequest, op_code, source_credentials, metadata, file_id, file_size, message, stream, ingest_mode, @@ -56,6 +58,8 @@ TEST(ProducerImpl, Constructor) { asapo::ProducerImpl producer{"", 4, 3600000, asapo::RequestHandlerType::kTcp}; ASSERT_THAT(dynamic_cast<asapo::AbstractLogger*>(producer.log__), Ne(nullptr)); ASSERT_THAT(dynamic_cast<asapo::RequestPool*>(producer.request_pool__.get()), Ne(nullptr)); + ASSERT_THAT(dynamic_cast<const asapo::HttpClient*>(producer.httpclient__.get()), Ne(nullptr)); + } class ProducerImplTests : public testing::Test { @@ -64,7 +68,8 @@ class ProducerImplTests : public testing::Test { asapo::ProducerRequestHandlerFactory factory{&service}; testing::NiceMock<asapo::MockLogger> mock_logger; testing::NiceMock<MockRequestPull> mock_pull{&factory, &mock_logger}; - asapo::ProducerImpl producer{"", 1, 3600000, asapo::RequestHandlerType::kTcp}; + std::string expected_server_uri = "test:8400"; + asapo::ProducerImpl producer{expected_server_uri, 1, 3600000, asapo::RequestHandlerType::kTcp}; uint64_t expected_size = 100; uint64_t expected_id = 10; uint64_t expected_dataset_id = 100; @@ -88,9 +93,15 @@ class ProducerImplTests : public testing::Test { std::string expected_fullpath = "filename"; bool expected_managed_memory = true; bool expected_unmanaged_memory = false; + + MockHttpClient* mock_http_client; + void SetUp() override { producer.log__ = &mock_logger; producer.request_pool__ = std::unique_ptr<RequestPool>{&mock_pull}; + mock_http_client = new MockHttpClient; + producer.httpclient__.reset(mock_http_client); + } void TearDown() override { producer.request_pool__.release(); @@ -510,8 +521,20 @@ TEST_F(ProducerImplTests, ReturnDataIfCanotAddToQueue) { } +TEST_F(ProducerImplTests, GetVersionInfoWithServer) { + + std::string result = R"({"softwareVersion":"20.03.1, build 7a9294ad","clientSupported":"no", "clientProtocol":{"versionInfo":"v0.2"}})"; + EXPECT_CALL(*mock_http_client, Get_t(HasSubstr(expected_server_uri + "/asapo-discovery/v0.1/version?client=producer&protocol=v0.1"), _,_)).WillOnce(DoAll( + SetArgPointee<1>(asapo::HttpCode::OK), + SetArgPointee<2>(nullptr), + Return(result))); + std::string client_info,server_info; + auto err = producer.GetVersionInfo(&client_info,&server_info,nullptr); + ASSERT_THAT(err, Eq(nullptr)); + ASSERT_THAT(server_info, HasSubstr("20.03.1")); + ASSERT_THAT(server_info, HasSubstr("v0.2")); } -#pragma clang diagnostic pop \ No newline at end of file +} diff --git a/producer/event_monitor_producer/src/main_eventmon.cpp b/producer/event_monitor_producer/src/main_eventmon.cpp index d30e479a8bf6e8af518b818ee0aa4cc8accaf040..72446fa522c48bbdd9724fedc639985874afe1ae 100644 --- a/producer/event_monitor_producer/src/main_eventmon.cpp +++ b/producer/event_monitor_producer/src/main_eventmon.cpp @@ -15,7 +15,7 @@ #include "asapo/preprocessor/definitions.h" #include "asapo/io/io_factory.h" -#include "asapo/common/version.h" +#include "asapo/common/internal/version.h" using asapo::Producer; using asapo::EventMonConfigFactory; diff --git a/receiver/src/main.cpp b/receiver/src/main.cpp index 2f119b2005f4e68a7983b4be247874df7217e735..e00c94fbd97b8e9047bb34d52c49c18cf9b92546 100644 --- a/receiver/src/main.cpp +++ b/receiver/src/main.cpp @@ -6,7 +6,7 @@ #include "receiver_config.h" #include "receiver_data_server/receiver_data_server_logger.h" -#include "asapo/common/version.h" +#include "asapo/common/internal/version.h" #include "receiver_data_server/receiver_data_server.h" #include "receiver_data_server/net_server/rds_tcp_server.h" diff --git a/receiver/src/receiver_data_server/request_handler/receiver_data_server_request_handler.cpp b/receiver/src/receiver_data_server/request_handler/receiver_data_server_request_handler.cpp index f4e5af4b6d938e4e2f60b9c02f8934760c5430b4..0f8f387faf1d2bd20490a4e6b409612b1c81e81d 100644 --- a/receiver/src/receiver_data_server/request_handler/receiver_data_server_request_handler.cpp +++ b/receiver/src/receiver_data_server/request_handler/receiver_data_server_request_handler.cpp @@ -1,7 +1,7 @@ #include "receiver_data_server_request_handler.h" #include "../receiver_data_server_error.h" -#include "asapo/common/version.h" +#include "asapo/common/internal/version.h" namespace asapo { ReceiverDataServerRequestHandler::ReceiverDataServerRequestHandler(RdsNetServer* server, diff --git a/receiver/src/request_handler/request_handler_authorize.cpp b/receiver/src/request_handler/request_handler_authorize.cpp index c0294754c49d3fdb0c66eefc94fe95b213b44e13..314b351a46acf31fc5ef08312a4ee989523fc2a8 100644 --- a/receiver/src/request_handler/request_handler_authorize.cpp +++ b/receiver/src/request_handler/request_handler_authorize.cpp @@ -4,7 +4,7 @@ #include "../request.h" #include "asapo/json_parser/json_parser.h" -#include "asapo/common/version.h" +#include "asapo/common/internal/version.h" using std::chrono::system_clock; diff --git a/tests/automatic/full_chain/send_recv_streams/send_recv_streams.cpp b/tests/automatic/full_chain/send_recv_streams/send_recv_streams.cpp index 9e18200837e755a3c9e2fbeca72d7064b1ab4cc3..7858801dcd1ea3b0ef8a4e53225c42fde5be4f16 100644 --- a/tests/automatic/full_chain/send_recv_streams/send_recv_streams.cpp +++ b/tests/automatic/full_chain/send_recv_streams/send_recv_streams.cpp @@ -73,7 +73,6 @@ ProducerPtr CreateProducer(const Args& args) { } int main(int argc, char* argv[]) { - asapo::ExitAfterPrintVersionIfNeeded("GetNext consumer Example", argc, argv); Args args; if (argc != 4) { std::cout << "Usage: " + std::string{argv[0]} diff --git a/tests/automatic/producer/beamtime_metadata/beamtime_metadata.cpp b/tests/automatic/producer/beamtime_metadata/beamtime_metadata.cpp index 5d91a1fd83076ae400f20452e146cbd31629e058..dc1c1f1eff961eb3d87f7edbba81922fc1a2b074 100644 --- a/tests/automatic/producer/beamtime_metadata/beamtime_metadata.cpp +++ b/tests/automatic/producer/beamtime_metadata/beamtime_metadata.cpp @@ -21,7 +21,6 @@ void PrintCommandArguments(const Args& args) { } void ProcessCommandArguments(int argc, char* argv[], Args* args) { - asapo::ExitAfterPrintVersionIfNeeded("dummy beamtime metadata", argc, argv); if (argc != 4) { std::cout << "Usage: " << argv[0] << diff --git a/tests/manual/performance_broker_receiver/getlast_broker.cpp b/tests/manual/performance_broker_receiver/getlast_broker.cpp index 59011a35aeee20a613a19c85b37a8d264715e4fc..f6a3c1a9270c5ec2de4e63a8ecd8345a0e02fa42 100644 --- a/tests/manual/performance_broker_receiver/getlast_broker.cpp +++ b/tests/manual/performance_broker_receiver/getlast_broker.cpp @@ -169,7 +169,6 @@ int ReadAllData(const Args& params, uint64_t* duration_ms, int* nerrors, int* nb } int main(int argc, char* argv[]) { - asapo::ExitAfterPrintVersionIfNeeded("GetLast consumer Example", argc, argv); Args params; params.datasets = false; if (argc != 9 && argc != 10) { diff --git a/tests/manual/producer_cpp/producer.cpp b/tests/manual/producer_cpp/producer.cpp index c198a7506144518a54c0f81f5c15aea2935c2a49..03607b93839e1599617ad19286a76e593734c748 100644 --- a/tests/manual/producer_cpp/producer.cpp +++ b/tests/manual/producer_cpp/producer.cpp @@ -1,7 +1,7 @@ #include <thread> #include <chrono> #include "asapo/asapo_producer.h" - +#include <iostream> void ProcessAfterSend(asapo::RequestCallbackPayload payload, asapo::Error err) { if (err) {