From ffa98fdd1bc521998f79a12510e5b53f45b74330 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 29 Apr 2025 06:45:48 +0200 Subject: [PATCH 001/105] initial setup of header filers --- CMakeLists.txt | 5 ++- .../usubscription/v3/RpcClientUSubscription.h | 41 +++++++++++++++++++ .../client/usubscription/v3/USubscription.h | 31 ++++++++++++++ .../v3/RpcClientUSubscription.cpp | 18 ++++++++ 4 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h create mode 100644 include/up-cpp/client/usubscription/v3/USubscription.h create mode 100644 src/client/usubscription/v3/RpcClientUSubscription.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 256391aae..89528e261 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,7 +48,10 @@ endif() file(GLOB_RECURSE SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") -add_library(${PROJECT_NAME} ${SRC_FILES}) +add_library(${PROJECT_NAME} ${SRC_FILES} + src/client/usubscription/v3/RpcClientUSubscription.cpp + include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h + include/up-cpp/client/usubscription/v3/USubscription.h) add_library(up-cpp::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) target_include_directories(${PROJECT_NAME} diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h new file mode 100644 index 000000000..7d2bf43aa --- /dev/null +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -0,0 +1,41 @@ +// +// Created by max on 28.04.25. +// + +#ifndef RPCCLIENTUSUBSCRIPTION_H +#define RPCCLIENTUSUBSCRIPTION_H + +#include + +#include "USubscription.h" +#include "up-cpp/communication/RpcClient.h" + +namespace uprotocol::core::usubscription::v3 { + +struct RpcClientUSubscription : USubscription { + + explicit RpcClientUSubscription(std::unique_ptr client) + : client_(std::move(client)){}; + + void default_call_option(); + + SubscriptionResponse subscribe(const SubscriptionRequest& subscription_request) override; + + UnsubscribeResponse unsubscribe(const UnsubscribeRequest& unsubscribe_request) override; + + FetchSubscriptionsResponse fetch_subscriptions(const FetchSubscriptionsRequest& fetch_subscribers_request) override; + + NotificationsResponse register_for_notifications(const NotificationsRequest& register_notifications_request) override; + + NotificationsResponse unregister_for_notifications(const NotificationsRequest& unregister_notifications_request) override; + + FetchSubscribersResponse fetch_subscribers(const FetchSubscribersRequest& fetch_subscribers_request) override; + +private: + std::unique_ptr client_; + +}; + +} // namespace uprotocol::core::usubscription::v3 + +#endif //RPCCLIENTUSUBSCRIPTION_H diff --git a/include/up-cpp/client/usubscription/v3/USubscription.h b/include/up-cpp/client/usubscription/v3/USubscription.h new file mode 100644 index 000000000..53aafb349 --- /dev/null +++ b/include/up-cpp/client/usubscription/v3/USubscription.h @@ -0,0 +1,31 @@ +// +// Created by max on 28.04.25. +// + +#ifndef USUBSCRIPTION_H +#define USUBSCRIPTION_H +#include "RpcClientUSubscription.h" + +namespace uprotocol::core::usubscription::v3 { + + struct USubscription { + + virtual ~USubscription() = default; + + virtual SubscriptionResponse subscribe(const SubscriptionRequest& subscription_request) = 0; + + virtual UnsubscribeResponse unsubscribe(const UnsubscribeRequest& unsubscribe_request) = 0; + + virtual FetchSubscriptionsResponse fetch_subscriptions(const FetchSubscriptionsRequest& fetch_subscribers_request) = 0; + + virtual NotificationsResponse register_for_notifications(const NotificationsRequest& register_notifications_request) =0 ; + + virtual NotificationsResponse unregister_for_notifications(const NotificationsRequest& unregister_notifications_request) = 0; + + virtual FetchSubscribersResponse fetch_subscribers(const FetchSubscribersRequest& fetch_subscribers_request) = 0; + + }; + +} // namespace uprotocol::core::usubscription::v3 + +#endif //USUBSCRIPTION_H diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp new file mode 100644 index 000000000..999e584f4 --- /dev/null +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -0,0 +1,18 @@ +// +// Created by max on 28.04.25. +// + +#include "up-cpp/client/usubscription/v3/RpcClientUSubscription.h" + +namespace uprotocol::core::usubscription::v3 { + using Payload = datamodel::builder::Payload; + + SubscriptionResponse RpcClientUSubscription::subscribe( + const SubscriptionRequest& subscription_request) { + Payload test_test(subscription_request); + auto invoke_handle = client_->invokeMethod(test_test, //TODO(max)); + return SubscriptionResponse(); + } + + } // namespace uprotocol::core::usubscription::v3 + From d720f57ef39d00282690b30659b81cfa96ef1064 Mon Sep 17 00:00:00 2001 From: lukas-he Date: Tue, 29 Apr 2025 15:03:10 +0200 Subject: [PATCH 002/105] Align wildcard handling with up-spec and up-rust (#317) * add methods (and headers) for wildcard handling including the tests * add method bodies for wildcard handling * fix linter warnings * fix linting * addressing Pete's review by providing check for no wildcards * fix tests and linting * equality compaison for authority name * fix format * Update comment to reflect wildcard is only "*" --- include/up-cpp/datamodel/validator/UUri.h | 31 ++++++++- src/datamodel/validator/UUri.cpp | 55 ++++++++------- test/coverage/datamodel/UUriValidatorTest.cpp | 67 ++++++++++++++----- 3 files changed, 109 insertions(+), 44 deletions(-) diff --git a/include/up-cpp/datamodel/validator/UUri.h b/include/up-cpp/datamodel/validator/UUri.h index 8989a5cf3..958d9a61c 100644 --- a/include/up-cpp/datamodel/validator/UUri.h +++ b/include/up-cpp/datamodel/validator/UUri.h @@ -150,10 +150,35 @@ isValidDefaultSource(const v1::UUri&); /// This is just a check for a zero-length authority name string. [[nodiscard]] bool isLocal(const v1::UUri&); -/// @brief Checks if a UUri uses wildcards +/// @brief Checks if a UUri has a wildcard authority name. /// -/// Checks for all types of wildcards, returns true if any are found. -[[nodiscard]] bool uses_wildcards(const v1::UUri&); +/// Checks if a UUri has a wildcard authority name, returns true if yes. +[[nodiscard]] bool has_wildcard_authority(const v1::UUri& uuri); + +/// @brief Checks if a UUri has a wildcard service id. +/// +/// Checks if a UUri has a wildcard service id, returns true if yes. +[[nodiscard]] bool has_wildcard_service_id(const v1::UUri& uuri); + +/// @brief Checks if a UUri has a wildcard service instance id. +/// +/// Checks if a UUri has a wildcard service instance id, returns true if yes. +[[nodiscard]] bool has_wildcard_service_instance_id(const v1::UUri& uuri); + +/// @brief Checks if a UUri has a wildcard version. +/// +/// Checks if a UUri has a wildcard version, returns true if yes. +[[nodiscard]] bool has_wildcard_version(const v1::UUri& uuri); + +/// @brief Checks if a UUri has a wildcard resoruce id. +/// +/// Checks if a UUri has a wildcard resoruce id, returns true if yes. +[[nodiscard]] bool has_wildcard_resource_id(const v1::UUri& uuri); + +/// @brief Checks if a UUri uses no wildcards +/// +/// Checks for all types of wildcards, returns true if no wildcards are found. +[[nodiscard]] bool verify_no_wildcards(const v1::UUri&); /// @brief This exception indicates that a UUri object was provided that /// did not contain valid UUri data. diff --git a/src/datamodel/validator/UUri.cpp b/src/datamodel/validator/UUri.cpp index f623b0f66..0a9e1e117 100644 --- a/src/datamodel/validator/UUri.cpp +++ b/src/datamodel/validator/UUri.cpp @@ -72,29 +72,34 @@ std::string_view message(Reason reason) { } } -bool uses_wildcards(const v1::UUri& uuri) { - constexpr auto LOWER_8_BIT_MASK = 0xFF; +bool has_wildcard_authority(const v1::UUri& uuri) { + return uuri.authority_name() == "*"; +} + +bool has_wildcard_service_id(const v1::UUri& uuri) { constexpr auto LOWER_16_BIT_MASK = 0xFFFF; + return (uuri.ue_id() & LOWER_16_BIT_MASK) == LOWER_16_BIT_MASK; +} + +bool has_wildcard_service_instance_id(const v1::UUri& uuri) { constexpr auto UPPER_16_BIT_MASK = 0xFFFF0000; + return (uuri.ue_id() & UPPER_16_BIT_MASK) == UPPER_16_BIT_MASK; +} - if (uuri.authority_name().find_first_of('*') != std::string::npos) { - return true; - } - if ((uuri.ue_id() & LOWER_16_BIT_MASK) == - LOWER_16_BIT_MASK) { // service ID - return true; - } - if ((uuri.ue_id() & UPPER_16_BIT_MASK) == - UPPER_16_BIT_MASK) { // service instance ID - return true; - } - if (uuri.ue_version_major() == LOWER_8_BIT_MASK) { - return true; - } - if (uuri.resource_id() == LOWER_16_BIT_MASK) { - return true; - } - return false; +bool has_wildcard_version(const v1::UUri& uuri) { + constexpr auto LOWER_8_BIT_MASK = 0xFF; + return uuri.ue_version_major() == LOWER_8_BIT_MASK; +} + +bool has_wildcard_resource_id(const v1::UUri& uuri) { + constexpr auto LOWER_16_BIT_MASK = 0xFFFF; + return uuri.resource_id() == LOWER_16_BIT_MASK; +} + +bool verify_no_wildcards(const v1::UUri& uuri) { + return !has_wildcard_authority(uuri) && !has_wildcard_service_id(uuri) && + !has_wildcard_service_instance_id(uuri) && + !has_wildcard_version(uuri) && !has_wildcard_resource_id(uuri); } ValidationResult isValid(const v1::UUri& uuri) { @@ -145,7 +150,7 @@ ValidationResult isValidFilter(const v1::UUri& uuri) { ValidationResult isValidRpcMethod(const v1::UUri& uuri) { // disallow wildcards - if (uses_wildcards(uuri)) { + if (!verify_no_wildcards(uuri)) { return {false, Reason::DISALLOWED_WILDCARD}; } @@ -159,7 +164,7 @@ ValidationResult isValidRpcMethod(const v1::UUri& uuri) { ValidationResult isValidRpcResponse(const v1::UUri& uuri) { // disallow wildcards - if (uses_wildcards(uuri)) { + if (!verify_no_wildcards(uuri)) { return {false, Reason::DISALLOWED_WILDCARD}; } @@ -183,7 +188,7 @@ ValidationResult isValidDefaultSource(const v1::UUri& uuri) { ValidationResult isValidPublishTopic(const v1::UUri& uuri) { // disallow wildcards - if (uses_wildcards(uuri)) { + if (!verify_no_wildcards(uuri)) { return {false, Reason::DISALLOWED_WILDCARD}; } @@ -197,7 +202,7 @@ ValidationResult isValidPublishTopic(const v1::UUri& uuri) { ValidationResult isValidNotificationSource(const v1::UUri& uuri) { // disallow wildcards - if (uses_wildcards(uuri)) { + if (!verify_no_wildcards(uuri)) { return {false, Reason::DISALLOWED_WILDCARD}; } @@ -211,7 +216,7 @@ ValidationResult isValidNotificationSource(const v1::UUri& uuri) { ValidationResult isValidNotificationSink(const v1::UUri& uuri) { // disallow wildcards - if (uses_wildcards(uuri)) { + if (!verify_no_wildcards(uuri)) { return {false, Reason::DISALLOWED_WILDCARD}; } diff --git a/test/coverage/datamodel/UUriValidatorTest.cpp b/test/coverage/datamodel/UUriValidatorTest.cpp index a1ffbb89f..c55b13ece 100644 --- a/test/coverage/datamodel/UUriValidatorTest.cpp +++ b/test/coverage/datamodel/UUriValidatorTest.cpp @@ -103,7 +103,8 @@ TEST_F(TestUUriValidator, Valid) { // NOLINT { auto uuri = get_u_uri(); uuri.set_resource_id(WILDCARD); - EXPECT_TRUE(uses_wildcards(uuri)); + EXPECT_TRUE(has_wildcard_resource_id(uuri)); + EXPECT_FALSE(verify_no_wildcards(uuri)); auto [valid, reason] = isValid(uuri); EXPECT_FALSE(valid); @@ -123,41 +124,50 @@ TEST_F(TestUUriValidator, Wildcards) { // NOLINT { // Check for no wildcards auto uuri = get_u_uri(); - EXPECT_FALSE(uses_wildcards(uuri)); + EXPECT_FALSE(has_wildcard_authority(uuri)); + EXPECT_FALSE(has_wildcard_service_id(uuri)); + EXPECT_FALSE(has_wildcard_service_instance_id(uuri)); + EXPECT_FALSE(has_wildcard_version(uuri)); + EXPECT_FALSE(has_wildcard_resource_id(uuri)); + EXPECT_TRUE(verify_no_wildcards(uuri)); } - { // Change Authority name to "hello*" (Any) + { // Change Authority name to "*" (Any) auto uuri = get_u_uri(); - uuri.set_authority_name("hello*"); - EXPECT_TRUE(uses_wildcards(uuri)); + uuri.set_authority_name("*"); + EXPECT_TRUE(has_wildcard_authority(uuri)); + EXPECT_FALSE(verify_no_wildcards(uuri)); } { // Set Service ID to FFFF (Any) and Instance ID to 1 constexpr uint32_t WILDCARD_SERVICE_UE_ID = 0x0001FFFF; auto uuri = get_u_uri(); uuri.set_ue_id(WILDCARD_SERVICE_UE_ID); - EXPECT_TRUE(uses_wildcards(uuri)); + EXPECT_TRUE(has_wildcard_service_id(uuri)); + EXPECT_FALSE(verify_no_wildcards(uuri)); } { // Set Service ID to 1 and Instance ID to FFFF (Any) constexpr uint32_t WILDCARD_INSTANCE_UE_ID = 0xFFFF0001; - // This changed in 581291f in up-spec auto uuri = get_u_uri(); uuri.set_ue_id(WILDCARD_INSTANCE_UE_ID); - EXPECT_TRUE(uses_wildcards(uuri)); + EXPECT_TRUE(has_wildcard_service_instance_id(uuri)); + EXPECT_FALSE(verify_no_wildcards(uuri)); } { // Set major version to FF (Any) constexpr uint32_t WILDCARD_VERSION_MAJOR = 0xFF; auto uuri = get_u_uri(); uuri.set_ue_version_major(WILDCARD_VERSION_MAJOR); - EXPECT_TRUE(uses_wildcards(uuri)); + EXPECT_TRUE(has_wildcard_version(uuri)); + EXPECT_FALSE(verify_no_wildcards(uuri)); } { // Set Resource ID to FFFF (any) auto uuri = get_u_uri(); uuri.set_resource_id(WILDCARD); - EXPECT_TRUE(uses_wildcards(uuri)); + EXPECT_TRUE(has_wildcard_resource_id(uuri)); + EXPECT_FALSE(verify_no_wildcards(uuri)); } } @@ -183,7 +193,12 @@ TEST_F(TestUUriValidator, ValidRpcMethod) { // NOLINT auto [valid, reason] = isValidRpcMethod(uuri); EXPECT_TRUE(valid); EXPECT_FALSE(reason.has_value()); - EXPECT_FALSE(uses_wildcards(uuri)); + EXPECT_FALSE(has_wildcard_authority(uuri)); + EXPECT_FALSE(has_wildcard_service_id(uuri)); + EXPECT_FALSE(has_wildcard_service_instance_id(uuri)); + EXPECT_FALSE(has_wildcard_version(uuri)); + EXPECT_FALSE(has_wildcard_resource_id(uuri)); + EXPECT_TRUE(verify_no_wildcards(uuri)); } { @@ -234,7 +249,7 @@ TEST_F(TestUUriValidator, ValidRpcResponse) { // NOLINT auto [valid, reason] = isValidRpcResponse(uuri); EXPECT_TRUE(valid); EXPECT_FALSE(reason.has_value()); - EXPECT_FALSE(uses_wildcards(uuri)); + EXPECT_TRUE(verify_no_wildcards(uuri)); } { @@ -285,7 +300,12 @@ TEST_F(TestUUriValidator, ValidPublishTopic) { // NOLINT auto [valid, reason] = isValidPublishTopic(uuri); EXPECT_TRUE(valid); EXPECT_FALSE(reason.has_value()); - EXPECT_FALSE(uses_wildcards(uuri)); + EXPECT_FALSE(has_wildcard_authority(uuri)); + EXPECT_FALSE(has_wildcard_service_id(uuri)); + EXPECT_FALSE(has_wildcard_service_instance_id(uuri)); + EXPECT_FALSE(has_wildcard_version(uuri)); + EXPECT_FALSE(has_wildcard_resource_id(uuri)); + EXPECT_TRUE(verify_no_wildcards(uuri)); } { @@ -345,7 +365,12 @@ TEST_F(TestUUriValidator, ValidNotificationSource) { // NOLINT auto [valid, reason] = isValidNotificationSource(uuri); EXPECT_TRUE(valid); EXPECT_FALSE(reason.has_value()); - EXPECT_FALSE(uses_wildcards(uuri)); + EXPECT_FALSE(has_wildcard_authority(uuri)); + EXPECT_FALSE(has_wildcard_service_id(uuri)); + EXPECT_FALSE(has_wildcard_service_instance_id(uuri)); + EXPECT_FALSE(has_wildcard_version(uuri)); + EXPECT_FALSE(has_wildcard_resource_id(uuri)); + EXPECT_TRUE(verify_no_wildcards(uuri)); } { @@ -404,7 +429,12 @@ TEST_F(TestUUriValidator, ValidNotificationSink) { // NOLINT auto [valid, reason] = isValidNotificationSink(uuri); EXPECT_TRUE(valid); EXPECT_FALSE(reason.has_value()); - EXPECT_FALSE(uses_wildcards(uuri)); + EXPECT_FALSE(has_wildcard_authority(uuri)); + EXPECT_FALSE(has_wildcard_service_id(uuri)); + EXPECT_FALSE(has_wildcard_service_instance_id(uuri)); + EXPECT_FALSE(has_wildcard_version(uuri)); + EXPECT_FALSE(has_wildcard_resource_id(uuri)); + EXPECT_TRUE(verify_no_wildcards(uuri)); } { @@ -448,7 +478,12 @@ TEST_F(TestUUriValidator, ValidSubscription) { // NOLINT auto [valid, reason] = isValidSubscription(uuri); EXPECT_TRUE(valid); EXPECT_FALSE(reason.has_value()); - EXPECT_FALSE(uses_wildcards(uuri)); + EXPECT_FALSE(has_wildcard_authority(uuri)); + EXPECT_FALSE(has_wildcard_service_id(uuri)); + EXPECT_FALSE(has_wildcard_service_instance_id(uuri)); + EXPECT_FALSE(has_wildcard_version(uuri)); + EXPECT_FALSE(has_wildcard_resource_id(uuri)); + EXPECT_TRUE(verify_no_wildcards(uuri)); } { From a980b37be50704f8afadf86a7b43f9754c249464 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Tue, 29 Apr 2025 15:42:06 +0200 Subject: [PATCH 003/105] Update RpcClientUSubscription to protobuf singature. Add subscription method, which is currently in dev --- .../usubscription/v3/RpcClientUSubscription.h | 84 +++++++++++++++---- .../client/usubscription/v3/USubscription.h | 6 +- .../v3/RpcClientUSubscription.cpp | 71 +++++++++++++--- 3 files changed, 127 insertions(+), 34 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index 7d2bf43aa..d351dd3fa 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -1,39 +1,87 @@ -// -// Created by max on 28.04.25. -// - #ifndef RPCCLIENTUSUBSCRIPTION_H #define RPCCLIENTUSUBSCRIPTION_H #include +#include "Consumer.h" -#include "USubscription.h" +// #include "USubscription.h" #include "up-cpp/communication/RpcClient.h" namespace uprotocol::core::usubscription::v3 { -struct RpcClientUSubscription : USubscription { - - explicit RpcClientUSubscription(std::unique_ptr client) - : client_(std::move(client)){}; - +struct RpcClientUSubscription : public uSubscription { +public: + RpcClientUSubscription() = default; + ~RpcClientUSubscription() override = default; + + explicit RpcClientUSubscription(std::unique_ptr rpc_client) + : rpc_client_(std::move(rpc_client)){}; + + + void Subscribe(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::SubscriptionRequest* request, + ::uprotocol::core::usubscription::v3::SubscriptionResponse* response, + ::google::protobuf::Closure* done) override; + + void Unsubscribe(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::UnsubscribeRequest* request, + ::uprotocol::core::usubscription::v3::UnsubscribeResponse* response, + ::google::protobuf::Closure* done) override; + + void FetchSubscriptions(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::FetchSubscriptionsRequest* request, + ::uprotocol::core::usubscription::v3::FetchSubscriptionsResponse* response, + ::google::protobuf::Closure* done) override; + + void RegisterForNotifications(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, + ::uprotocol::core::usubscription::v3::NotificationsResponse* response, + ::google::protobuf::Closure* done) override; + + void UnregisterForNotifications(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, + ::uprotocol::core::usubscription::v3::NotificationsResponse* response, + ::google::protobuf::Closure* done) override; + + void FetchSubscribers(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::FetchSubscribersRequest* request, + ::uprotocol::core::usubscription::v3::FetchSubscribersResponse* response, + ::google::protobuf::Closure* done) override; + + void Reset(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::ResetRequest* request, + ::uprotocol::core::usubscription::v3::ResetResponse* response, + ::google::protobuf::Closure* done) override; + +// Backup void default_call_option(); - SubscriptionResponse subscribe(const SubscriptionRequest& subscription_request) override; + // SubscriptionResponse subscribe(const SubscriptionRequest& subscription_request); - UnsubscribeResponse unsubscribe(const UnsubscribeRequest& unsubscribe_request) override; + // UnsubscribeResponse unsubscribe(const UnsubscribeRequest& unsubscribe_request); - FetchSubscriptionsResponse fetch_subscriptions(const FetchSubscriptionsRequest& fetch_subscribers_request) override; + // FetchSubscriptionsResponse fetch_subscriptions(const FetchSubscriptionsRequest& fetch_subscribers_request); - NotificationsResponse register_for_notifications(const NotificationsRequest& register_notifications_request) override; + // NotificationsResponse register_for_notifications(const NotificationsRequest& register_notifications_request); - NotificationsResponse unregister_for_notifications(const NotificationsRequest& unregister_notifications_request) override; + // NotificationsResponse unregister_for_notifications(const NotificationsRequest& unregister_notifications_request); - FetchSubscribersResponse fetch_subscribers(const FetchSubscribersRequest& fetch_subscribers_request) override; + // FetchSubscribersResponse fetch_subscribers(const FetchSubscribersRequest& fetch_subscribers_request); private: - std::unique_ptr client_; - + // RPC request + std::unique_ptr rpc_client_; + communication::RpcClient::InvokeHandle rpc_handle_; + SubscriptionResponse subscription_response_; + + // Transport + std::shared_ptr transport_; + + // URI info about the uSubscription service + client::usubscription::v3::USubscriptionUUriBuilder uSubscriptionUUriBuilder_; + + // Topic to subscribe to + const v1::UUri subscription_topic_; }; } // namespace uprotocol::core::usubscription::v3 diff --git a/include/up-cpp/client/usubscription/v3/USubscription.h b/include/up-cpp/client/usubscription/v3/USubscription.h index 53aafb349..0de39ca93 100644 --- a/include/up-cpp/client/usubscription/v3/USubscription.h +++ b/include/up-cpp/client/usubscription/v3/USubscription.h @@ -1,10 +1,6 @@ -// -// Created by max on 28.04.25. -// - #ifndef USUBSCRIPTION_H #define USUBSCRIPTION_H -#include "RpcClientUSubscription.h" +#include namespace uprotocol::core::usubscription::v3 { diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 999e584f4..f7d04e399 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -1,18 +1,67 @@ -// -// Created by max on 28.04.25. -// - #include "up-cpp/client/usubscription/v3/RpcClientUSubscription.h" +#include +#include namespace uprotocol::core::usubscription::v3 { using Payload = datamodel::builder::Payload; - SubscriptionResponse RpcClientUSubscription::subscribe( - const SubscriptionRequest& subscription_request) { - Payload test_test(subscription_request); - auto invoke_handle = client_->invokeMethod(test_test, //TODO(max)); - return SubscriptionResponse(); - } +void RpcClientUSubscription::Subscribe( + google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::SubscriptionRequest* request, + ::uprotocol::core::usubscription::v3::SubscriptionResponse* response, + ::google::protobuf::Closure* done) { + + constexpr uint16_t RESOURCE_ID_SUBSCRIBE = 0x0001; + // TODO(lennart): needs to be set + v1::UPriority priority; + std::chrono::milliseconds subscription_request_ttl; + + if ((request == nullptr) || (response == nullptr) || (done == nullptr)) { + controller->SetFailed("Invalid input parameters"); + done->Run(); + return; + } + + rpc_client_ = std::make_unique( + transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_SUBSCRIBE), + priority, subscription_request_ttl); + + auto on_response = [this, response](const auto& maybe_response) { + if (maybe_response.has_value() && + maybe_response.value().has_payload()) { + if (response->ParseFromString(maybe_response.value().payload())) { + if (response->topic().SerializeAsString() == + subscription_topic_.SerializeAsString()) { + subscription_response_ = *response; + } + } + } + }; + + try { + auto payload = datamodel::builder::Payload(request); + + rpc_handle_ = rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + + if (static_cast(rpc_handle_.isConnected()) == v1::OK) { // TODO(lennart): check if this is correct + response->CopyFrom(rpc_handle_.value); // Copy data to the response + } else { + controller->SetFailed("RPC call failed"); + } + + } catch (const std::exception& e) { + controller->SetFailed(std::string("Exception during Subscribe: ") + e.what()); + } + + done->Run(); +} - } // namespace uprotocol::core::usubscription::v3 +// Backup + // SubscriptionResponse RpcClientUSubscription::subscribe( + // const SubscriptionRequest& subscription_request) { + // Payload test_test(subscription_request); + // auto invoke_handle = client_->invokeMethod(test_test, //TODO(max)); + // return SubscriptionResponse(); + // } +} // namespace uprotocol::core::usubscription::v3 From 24a0ce43eba607ae3ce318659e882a65e546b362 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Tue, 29 Apr 2025 16:31:01 +0200 Subject: [PATCH 004/105] Update RpcLientUSubscription --- src/client/usubscription/v3/RpcClientUSubscription.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index f7d04e399..01486ff09 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -43,6 +43,9 @@ void RpcClientUSubscription::Subscribe( rpc_handle_ = rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + auto result = communication::Subscriber::subscribe( + transport_, subscription_topic_, std::move(callback)); // TODO(lennart) callback? + if (static_cast(rpc_handle_.isConnected()) == v1::OK) { // TODO(lennart): check if this is correct response->CopyFrom(rpc_handle_.value); // Copy data to the response } else { From d86189cce06543360712010340adac22a2e6d377 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Wed, 30 Apr 2025 12:15:49 +0200 Subject: [PATCH 005/105] before using Consumer --- src/client/usubscription/v3/RpcClientUSubscription.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 01486ff09..dca072b15 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -39,7 +39,7 @@ void RpcClientUSubscription::Subscribe( }; try { - auto payload = datamodel::builder::Payload(request); + auto payload = datamodel::builder::Payload(*request); rpc_handle_ = rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); From 26e716130cdff66fa21fc1cef3d707c49a7a1928 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Wed, 30 Apr 2025 16:27:24 +0200 Subject: [PATCH 006/105] Building without error. Test and check if functionality is correct. --- .../usubscription/v3/RpcClientUSubscription.h | 253 +++++++++++++----- .../v3/RpcClientUSubscription.cpp | 198 +++++++++++--- 2 files changed, 352 insertions(+), 99 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index d351dd3fa..399dc674c 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -1,89 +1,218 @@ +// SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef RPCCLIENTUSUBSCRIPTION_H #define RPCCLIENTUSUBSCRIPTION_H +#include +#include +#include +#include +#include #include -#include "Consumer.h" +#include -// #include "USubscription.h" -#include "up-cpp/communication/RpcClient.h" +#include namespace uprotocol::core::usubscription::v3 { +using uprotocol::core::usubscription::v3::SubscriptionRequest; +using uprotocol::core::usubscription::v3::UnsubscribeRequest; +using uprotocol::core::usubscription::v3::Update; +using uprotocol::core::usubscription::v3::uSubscription; + +/** + * @struct RpcClientUSubscriptionOptions + * @brief Additional details for uSubscription service. + * + * Each member represents an optional parameter for the uSubscription service. + */ +struct RpcClientUSubscriptionOptions { + /// Permission level of the subscription request + std::optional permission_level; + /// TAP token for access. + std::optional token; + /// Expiration time of the subscription. + std::optional when_expire; + /// Sample period for the subscription messages in milliseconds. + std::optional sample_period_ms; + /// Details of the subscriber. + std::optional subscriber_details; + /// Details of the subscription. + std::optional subscription_details; +}; -struct RpcClientUSubscription : public uSubscription { -public: - RpcClientUSubscription() = default; - ~RpcClientUSubscription() override = default; - - explicit RpcClientUSubscription(std::unique_ptr rpc_client) - : rpc_client_(std::move(rpc_client)){}; +/// @struct uSubscriptionUUriBuilder +/// @brief Structure to build uSubscription request URIs. +/// +/// This structure is used to build URIs for uSubscription service. It uses the +/// service options from uSubscription proto to set the authority name, ue_id, +/// ue_version_major, and the notification topic resource ID in the URI. +struct USubscriptionUUriBuilder { +private: + /// URI for the uSubscription service + v1::UUri uri_; + /// Resource ID of the notification topic + uint32_t sink_resource_id_; - - void Subscribe(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::SubscriptionRequest* request, - ::uprotocol::core::usubscription::v3::SubscriptionResponse* response, - ::google::protobuf::Closure* done) override; +public: + /// @brief Constructor for USubscriptionUUriBuilder. + USubscriptionUUriBuilder() { + // Get the service descriptor + const google::protobuf::ServiceDescriptor* service = + uSubscription::descriptor(); + const auto& service_options = service->options(); + + // Get the service options + const auto& service_name = + service_options.GetExtension(uprotocol::service_name); + const auto& service_version_major = + service_options.GetExtension(uprotocol::service_version_major); + const auto& service_id = + service_options.GetExtension(uprotocol::service_id); + const auto& notification_topic = + service_options.GetExtension(uprotocol::notification_topic, 0); + + // Set the values in the URI + uri_.set_authority_name(service_name); + uri_.set_ue_id(service_id); + uri_.set_ue_version_major(service_version_major); + sink_resource_id_ = notification_topic.id(); + } + + /// @brief Get the URI with a specific resource ID. + /// + /// @param resource_id The resource ID to set in the URI. + /// + /// @return The URI with the specified resource ID. + v1::UUri getServiceUriWithResourceId(uint32_t resource_id) const { + v1::UUri uri = uri_; // Copy the base URI + uri.set_resource_id(resource_id); + return uri; + } + + /// @brief Get the notification URI. + /// + /// @return The notification URI. + v1::UUri getNotificationUri() const { + v1::UUri uri = uri_; // Copy the base URI + uri.set_resource_id(sink_resource_id_); + return uri; + } +}; +/// @brief Interface for uEntities to create subscriptions. +/// +/// Like all L3 client APIs, the RpcClientUSubscription is a wrapper on top of the +/// L2 Communication APIs and USubscription service. +struct RpcClientUSubscription : public uSubscription{ + using RpcClientUSubscriptionOrStatus = + utils::Expected, v1::UStatus>; + using ListenCallback = transport::UTransport::ListenCallback; + using ListenHandle = transport::UTransport::ListenHandle; + using SubscriptionResponse = core::usubscription::v3::SubscriptionResponse; + + /// @brief Create a subscription + /// + /// @param transport Transport to register with. + /// @param subscription_topic Topic to subscribe to. + /// @param callback Function that is called when publish message is + /// received. + /// @param priority Priority of the subscription request. + /// @param subscribe_request_ttl Time to live for the subscription request. + /// @param rpc_client_usubscription_options Additional details for uSubscription service. + // [[nodiscard]] static RpcClientUSubscriptionOrStatus create( + // std::shared_ptr transport, + // const v1::UUri& subscription_topic, ListenCallback&& callback, + // v1::UPriority priority, + // std::chrono::milliseconds subscription_request_ttl, + // RpcClientUSubscriptionOptions rpc_client_usubscription_options); + + /// @brief Unsubscribe from the topic and call uSubscription service to + /// close the subscription. void Unsubscribe(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::UnsubscribeRequest* request, - ::uprotocol::core::usubscription::v3::UnsubscribeResponse* response, - ::google::protobuf::Closure* done) override; - - void FetchSubscriptions(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::FetchSubscriptionsRequest* request, - ::uprotocol::core::usubscription::v3::FetchSubscriptionsResponse* response, - ::google::protobuf::Closure* done) override; + const ::uprotocol::core::usubscription::v3::UnsubscribeRequest* request, + ::uprotocol::core::usubscription::v3::UnsubscribeResponse* response, + ::google::protobuf::Closure* done) override; - void RegisterForNotifications(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, - ::uprotocol::core::usubscription::v3::NotificationsResponse* response, - ::google::protobuf::Closure* done) override; + /// @brief getter for subscription update + /// + /// @return subscription update + Update getSubscriptionUpdate() const { return subscription_update_; } - void UnregisterForNotifications(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, - ::uprotocol::core::usubscription::v3::NotificationsResponse* response, - ::google::protobuf::Closure* done) override; + /// @brief Destructor + ~RpcClientUSubscription() = default; - void FetchSubscribers(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::FetchSubscribersRequest* request, - ::uprotocol::core::usubscription::v3::FetchSubscribersResponse* response, - ::google::protobuf::Closure* done) override; + /// This section for test code only delete later - void Reset(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::ResetRequest* request, - ::uprotocol::core::usubscription::v3::ResetResponse* response, - ::google::protobuf::Closure* done) override; +protected: + /// @brief Constructor + /// + /// @param transport Transport to register with. + /// @param subscriber_details Additional details about the subscriber. + RpcClientUSubscription(std::shared_ptr transport, + v1::UUri subscription_topic, + RpcClientUSubscriptionOptions rpc_client_usubscription_options = {}); -// Backup - void default_call_option(); - - // SubscriptionResponse subscribe(const SubscriptionRequest& subscription_request); - - // UnsubscribeResponse unsubscribe(const UnsubscribeRequest& unsubscribe_request); - - // FetchSubscriptionsResponse fetch_subscriptions(const FetchSubscriptionsRequest& fetch_subscribers_request); +private: + // Transport + std::shared_ptr transport_; - // NotificationsResponse register_for_notifications(const NotificationsRequest& register_notifications_request); + // Topic to subscribe to + const v1::UUri subscription_topic_; + // Additional details about uSubscription service + RpcClientUSubscriptionOptions rpc_client_usubscription_options_; - // NotificationsResponse unregister_for_notifications(const NotificationsRequest& unregister_notifications_request); + // URI info about the uSubscription service + USubscriptionUUriBuilder uSubscriptionUUriBuilder_; - // FetchSubscribersResponse fetch_subscribers(const FetchSubscribersRequest& fetch_subscribers_request); + // Subscription updates + std::unique_ptr noficationSinkHandle_; + Update subscription_update_; -private: // RPC request std::unique_ptr rpc_client_; communication::RpcClient::InvokeHandle rpc_handle_; SubscriptionResponse subscription_response_; - - // Transport - std::shared_ptr transport_; - - // URI info about the uSubscription service - client::usubscription::v3::USubscriptionUUriBuilder uSubscriptionUUriBuilder_; - - // Topic to subscribe to - const v1::UUri subscription_topic_; + UnsubscribeResponse unsubscribe_response_; + + // L2 Subscriber details + std::unique_ptr subscriber_; + + // Allow the protected constructor for this class to be used in make_unique + // inside of create() + friend std::unique_ptr + std::make_unique, + const uprotocol::v1::UUri, + uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions>( + std::shared_ptr&&, + const uprotocol::v1::UUri&&, + uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions&&); + + /// @brief Build SubscriptionRequest for subscription request + SubscriptionRequest buildSubscriptionRequest(); + + /// @brief Build UnsubscriptionRequest for unsubscription request + UnsubscribeRequest buildUnsubscriptionRequest(); + + /// @brief Create a notification sink to receive subscription updates + v1::UStatus createNotificationSink(); + + /// @brief Subscribe to the topic + /// + void Subscribe(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::SubscriptionRequest* request, + ::uprotocol::core::usubscription::v3::SubscriptionResponse* response, + ::google::protobuf::Closure* done) override; }; -} // namespace uprotocol::core::usubscription::v3 +} // namespace uprotocol::core::usubscription::v3 -#endif //RPCCLIENTUSUBSCRIPTION_H +#endif // RPCCLIENTUSUBSCRIPTION_H \ No newline at end of file diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index dca072b15..24ed9a6ad 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -1,9 +1,97 @@ -#include "up-cpp/client/usubscription/v3/RpcClientUSubscription.h" -#include -#include +// SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: Apache-2.0 + +#include +#include + +#include namespace uprotocol::core::usubscription::v3 { - using Payload = datamodel::builder::Payload; + +void someCallBack(const uprotocol::v1::UMessage& message) { + // Print the message + std::cout << message.DebugString() << std::endl; +} + +RpcClientUSubscription::RpcClientUSubscription(std::shared_ptr transport, + v1::UUri subscription_topic, + RpcClientUSubscriptionOptions rpc_client_usubscription_options) + : transport_(std::move(transport)), + subscription_topic_(std::move(subscription_topic)), + rpc_client_usubscription_options_(std::move(rpc_client_usubscription_options)), + rpc_client_(nullptr) { + // Initialize uSubscriptionUUriBuilder_ + uSubscriptionUUriBuilder_ = USubscriptionUUriBuilder(); +} + +// [[nodiscard]] RpcClientUSubscription::RpcClientUSubscriptionOrStatus RpcClientUSubscription::create( +// std::shared_ptr transport, +// const v1::UUri& subscription_topic, ListenCallback&& callback, +// v1::UPriority priority, std::chrono::milliseconds subscription_request_ttl, +// RpcClientUSubscriptionOptions rpc_client_usubscription_options) { +// auto rpc_client_usubscription = std::make_unique( +// std::forward>(transport), +// std::forward(subscription_topic), +// std::forward(rpc_client_usubscription_options)); + +// // Attempt to connect create notification sink for updates. +// auto status = rpc_client_usubscription->createNotificationSink(); +// if (status.code() == v1::UCode::OK) { +// status = rpc_client_usubscription->subscribe(priority, subscription_request_ttl, +// std::move(callback)); +// if (status.code() == v1::UCode::OK) { +// return RpcClientUSubscriptionOrStatus(std::move(rpc_client_usubscription)); +// } +// return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); +// } +// // If connection fails, return the error status. +// return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); +// } + +v1::UStatus RpcClientUSubscription::createNotificationSink() { + auto notification_sink_callback = [this](const v1::UMessage& update) { + if (update.has_payload()) { + Update data; + if (data.ParseFromString(update.payload())) { + if (data.topic().SerializeAsString() == + subscription_topic_.SerializeAsString()) { + subscription_update_ = std::move(data); + } + } + } + }; + + auto notification_topic = uSubscriptionUUriBuilder_.getNotificationUri(); + + auto result = communication::NotificationSink::create( + transport_, std::move(notification_sink_callback), notification_topic); + + if (result.has_value()) { + noficationSinkHandle_ = std::move(result).value(); + v1::UStatus status; + status.set_code(v1::UCode::OK); + return status; + } + return result.error(); +} + +SubscriptionRequest RpcClientUSubscription::buildSubscriptionRequest() { + auto attributes = utils::ProtoConverter::BuildSubscribeAttributes( + rpc_client_usubscription_options_.when_expire, rpc_client_usubscription_options_.subscription_details, + rpc_client_usubscription_options_.sample_period_ms); + + auto subscription_request = utils::ProtoConverter::BuildSubscriptionRequest( + subscription_topic_, attributes); + return subscription_request; +} void RpcClientUSubscription::Subscribe( google::protobuf::RpcController* controller, @@ -12,59 +100,95 @@ void RpcClientUSubscription::Subscribe( ::google::protobuf::Closure* done) { constexpr uint16_t RESOURCE_ID_SUBSCRIBE = 0x0001; - // TODO(lennart): needs to be set - v1::UPriority priority; - std::chrono::milliseconds subscription_request_ttl; + constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? + auto subscription_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); + auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; // TODO(lennart) priority + + auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); - if ((request == nullptr) || (response == nullptr) || (done == nullptr)) { - controller->SetFailed("Invalid input parameters"); - done->Run(); - return; - } rpc_client_ = std::make_unique( transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_SUBSCRIBE), priority, subscription_request_ttl); - + auto on_response = [this, response](const auto& maybe_response) { if (maybe_response.has_value() && - maybe_response.value().has_payload()) { + maybe_response.value().has_payload()) { if (response->ParseFromString(maybe_response.value().payload())) { if (response->topic().SerializeAsString() == - subscription_topic_.SerializeAsString()) { + subscription_topic_.SerializeAsString()) { subscription_response_ = *response; } } } }; - try { - auto payload = datamodel::builder::Payload(*request); + // SubscriptionRequest const subscription_request = buildSubscriptionRequest(); + auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct, has been subscription_request before - rpc_handle_ = rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + rpc_handle_ = + rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - auto result = communication::Subscriber::subscribe( - transport_, subscription_topic_, std::move(callback)); // TODO(lennart) callback? + // response->CopyFrom(rpc_handle_.value); - if (static_cast(rpc_handle_.isConnected()) == v1::OK) { // TODO(lennart): check if this is correct - response->CopyFrom(rpc_handle_.value); // Copy data to the response - } else { - controller->SetFailed("RPC call failed"); - } - - } catch (const std::exception& e) { - controller->SetFailed(std::string("Exception during Subscribe: ") + e.what()); - } + auto subscription_callback = someCallBack; + // Create a L2 subscription + auto result = communication::Subscriber::subscribe( + transport_, subscription_topic_, std::move(subscription_callback)); + if (result.has_value()) { + subscriber_ = std::move(result).value(); + v1::UStatus status; + status.set_code(v1::UCode::OK); + // return status; + done->Run(); + } + controller->SetFailed("result.error()"); done->Run(); } -// Backup - // SubscriptionResponse RpcClientUSubscription::subscribe( - // const SubscriptionRequest& subscription_request) { - // Payload test_test(subscription_request); - // auto invoke_handle = client_->invokeMethod(test_test, //TODO(max)); - // return SubscriptionResponse(); - // } +UnsubscribeRequest RpcClientUSubscription::buildUnsubscriptionRequest() { + auto unsubscribe_request = + utils::ProtoConverter::BuildUnSubscribeRequest(subscription_topic_); + return unsubscribe_request; +} + +void RpcClientUSubscription::Unsubscribe( + google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::UnsubscribeRequest* request, + ::uprotocol::core::usubscription::v3::UnsubscribeResponse* response, + ::google::protobuf::Closure* done) { + + constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? + constexpr uint16_t RESOURCE_ID_UNSUBSCRIBE = 0x0002; + auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); + auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; // TODO(lennart) priority + + rpc_client_ = std::make_unique( + transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_UNSUBSCRIBE), + priority, request_ttl); + + auto on_response = [this, response](const auto& maybe_response) { + if (maybe_response.has_value() && + maybe_response.value().has_payload()) { + if (response->ParseFromString(maybe_response.value().payload())) { + // if (response->topic().SerializeAsString() == // TODO(lennart) see if this check is somehow possible + // subscription_topic_.SerializeAsString()) { + unsubscribe_response_ = *response; + // } + } + } + }; + + // UnsubscribeRequest const unsubscribe_request = buildUnsubscriptionRequest(); + auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct, has been subscription_request before + + rpc_handle_ = + rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + + subscriber_.reset(); + + done->Run(); +} -} // namespace uprotocol::core::usubscription::v3 +} // namespace uprotocol::core::usubscription::v3 From 9eeeb021047c3d92f5e960768c591907baa4971d Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Fri, 2 May 2025 13:15:09 +0200 Subject: [PATCH 007/105] Added comment --- src/client/usubscription/v3/RpcClientUSubscription.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 24ed9a6ad..b3492ad11 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -131,7 +131,7 @@ void RpcClientUSubscription::Subscribe( // response->CopyFrom(rpc_handle_.value); - auto subscription_callback = someCallBack; + auto subscription_callback = someCallBack; // TODO(lennart) update with correct callback // Create a L2 subscription auto result = communication::Subscriber::subscribe( transport_, subscription_topic_, std::move(subscription_callback)); @@ -143,7 +143,9 @@ void RpcClientUSubscription::Subscribe( // return status; done->Run(); } + controller->SetFailed("result.error()"); + done->Run(); } From b09d890c030061cda15238a8a3577e194047e9d1 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Fri, 2 May 2025 16:51:25 +0200 Subject: [PATCH 008/105] =?UTF-8?q?Done=20for=20today.=20No=20major=20chan?= =?UTF-8?q?ges.=20Waiting=20for=20Pete=C2=B4s=20answer.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/usubscription/v3/RpcClientUSubscription.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index b3492ad11..a38cc6e0d 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -10,6 +10,7 @@ // SPDX-License-Identifier: Apache-2.0 #include +#include #include #include @@ -100,11 +101,12 @@ void RpcClientUSubscription::Subscribe( ::google::protobuf::Closure* done) { constexpr uint16_t RESOURCE_ID_SUBSCRIBE = 0x0001; + // TODO(lennart) see default_call_options() for the request in Rust constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? auto subscription_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; // TODO(lennart) priority - auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); + auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); // Might serve as default_call_options() in Rust rpc_client_ = std::make_unique( From 994924beef937bca4ddfb49b62afdbeeacfaf7bc Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Mon, 5 May 2025 11:32:07 +0200 Subject: [PATCH 009/105] Added missing methods for RpcClientUSubscription --- .../usubscription/v3/RpcClientUSubscription.h | 31 +++- .../v3/RpcClientUSubscription.cpp | 169 ++++++++++++++++-- 2 files changed, 189 insertions(+), 11 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index 399dc674c..6e3fedef7 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -117,7 +117,6 @@ struct RpcClientUSubscription : public uSubscription{ utils::Expected, v1::UStatus>; using ListenCallback = transport::UTransport::ListenCallback; using ListenHandle = transport::UTransport::ListenHandle; - using SubscriptionResponse = core::usubscription::v3::SubscriptionResponse; /// @brief Create a subscription /// @@ -141,6 +140,32 @@ struct RpcClientUSubscription : public uSubscription{ const ::uprotocol::core::usubscription::v3::UnsubscribeRequest* request, ::uprotocol::core::usubscription::v3::UnsubscribeResponse* response, ::google::protobuf::Closure* done) override; + + /// @brief Fetch all subscriptions for a given topic or subscriber contained inside a [`FetchSubscriptionsRequest`] + void FetchSubscriptions(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::FetchSubscriptionsRequest* request, + ::uprotocol::core::usubscription::v3::FetchSubscriptionsResponse* response, + ::google::protobuf::Closure* done) override; + + /// @brief Register for notifications relevant to a given topic inside a [`NotificationsRequest`] + /// changing in subscription status. + void RegisterForNotifications(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, + ::uprotocol::core::usubscription::v3::NotificationsResponse* response, + ::google::protobuf::Closure* done) override; + + /// @brief Unregister for notifications relevant to a given topic inside a [`NotificationsRequest`] + /// changing in subscription status. + void UnregisterForNotifications(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, + ::uprotocol::core::usubscription::v3::NotificationsResponse* response, + ::google::protobuf::Closure* done) override; + + /// @brief Fetch a list of subscribers that are currently subscribed to a given topic in a [`FetchSubscribersRequest`] + void FetchSubscribers(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::FetchSubscribersRequest* request, + ::uprotocol::core::usubscription::v3::FetchSubscribersResponse* response, + ::google::protobuf::Closure* done) override; /// @brief getter for subscription update /// @@ -180,8 +205,12 @@ struct RpcClientUSubscription : public uSubscription{ // RPC request std::unique_ptr rpc_client_; communication::RpcClient::InvokeHandle rpc_handle_; + SubscriptionResponse subscription_response_; UnsubscribeResponse unsubscribe_response_; + FetchSubscriptionsResponse fetch_subscription_response_; + NotificationsResponse notification_response_; + FetchSubscribersResponse fetch_subscribers_response_; // L2 Subscriber details std::unique_ptr subscriber_; diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index a38cc6e0d..2aa45f073 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -104,7 +104,7 @@ void RpcClientUSubscription::Subscribe( // TODO(lennart) see default_call_options() for the request in Rust constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? auto subscription_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; // TODO(lennart) priority + auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); // Might serve as default_call_options() in Rust @@ -129,9 +129,7 @@ void RpcClientUSubscription::Subscribe( auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct, has been subscription_request before rpc_handle_ = - rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - - // response->CopyFrom(rpc_handle_.value); + rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); auto subscription_callback = someCallBack; // TODO(lennart) update with correct callback // Create a L2 subscription @@ -166,7 +164,7 @@ void RpcClientUSubscription::Unsubscribe( constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? constexpr uint16_t RESOURCE_ID_UNSUBSCRIBE = 0x0002; auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; // TODO(lennart) priority + auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; rpc_client_ = std::make_unique( transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_UNSUBSCRIBE), @@ -176,17 +174,16 @@ void RpcClientUSubscription::Unsubscribe( if (maybe_response.has_value() && maybe_response.value().has_payload()) { if (response->ParseFromString(maybe_response.value().payload())) { - // if (response->topic().SerializeAsString() == // TODO(lennart) see if this check is somehow possible - // subscription_topic_.SerializeAsString()) { + if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe + subscription_topic_.SerializeAsString()) { unsubscribe_response_ = *response; - // } + } } } }; // UnsubscribeRequest const unsubscribe_request = buildUnsubscriptionRequest(); - auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct, has been subscription_request before - + auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct rpc_handle_ = rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); @@ -195,4 +192,156 @@ void RpcClientUSubscription::Unsubscribe( done->Run(); } +void RpcClientUSubscription::FetchSubscriptions( + google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::FetchSubscriptionsRequest* request, + ::uprotocol::core::usubscription::v3::FetchSubscriptionsResponse* response, + ::google::protobuf::Closure* done) { + + constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? + constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIPTIONS = 0x0003; + auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); + auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; + + rpc_client_ = std::make_unique( + transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_FETCH_SUBSCRIPTIONS), + priority, request_ttl); + + auto on_response = [this, response](const auto& maybe_response) { + if (maybe_response.has_value() && + maybe_response.value().has_payload()) { + if (response->ParseFromString(maybe_response.value().payload())) { + if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe + subscription_topic_.SerializeAsString()) { + fetch_subscription_response_ = *response; + } + } + } + }; + + // FetchSubscriptionsRequest const fetch_subscriptions_request = buildFetchSubscriptionsRequest(); + auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct + + rpc_handle_ = + rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + + // TODO(lennart) any handle for the response? + + done->Run(); +} + +void RpcClientUSubscription::RegisterForNotifications( + google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, + ::uprotocol::core::usubscription::v3::NotificationsResponse* response, + ::google::protobuf::Closure* done) { + + constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? + constexpr uint16_t RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS = 0x0006; + auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); + auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; + + rpc_client_ = std::make_unique( + transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS), + priority, request_ttl); + + auto on_response = [this, response](const auto& maybe_response) { + if (maybe_response.has_value() && + maybe_response.value().has_payload()) { + if (response->ParseFromString(maybe_response.value().payload())) { + if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe + subscription_topic_.SerializeAsString()) { + notification_response_ = *response; + } + } + } + }; + + // NotificationsRequest const register_notifications_request = buildRegisterNotificationsRequest(); + auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct + + rpc_handle_ = + rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + + // TODO(lennart) any handle for the response? + + done->Run(); +} + +void RpcClientUSubscription::UnregisterForNotifications( + google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, + ::uprotocol::core::usubscription::v3::NotificationsResponse* response, + ::google::protobuf::Closure* done) { + + constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? + constexpr uint16_t RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS = 0x0007; + auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); + auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; + + rpc_client_ = std::make_unique( + transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS), + priority, request_ttl); + + auto on_response = [this, response](const auto& maybe_response) { + if (maybe_response.has_value() && + maybe_response.value().has_payload()) { + if (response->ParseFromString(maybe_response.value().payload())) { + if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe + subscription_topic_.SerializeAsString()) { + notification_response_ = *response; + } + } + } + }; + + // NotificationsRequest const unregister_notifications_request = buildUnregisterNotificationsRequest(); + auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct + + rpc_handle_ = + rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + + // TODO(lennart) any handle for the response? + + done->Run(); +} + +void RpcClientUSubscription::FetchSubscribers( + google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::FetchSubscribersRequest* request, + ::uprotocol::core::usubscription::v3::FetchSubscribersResponse* response, + ::google::protobuf::Closure* done) { + + constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? + constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIBERS = 0x0008; + auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); + auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; + + rpc_client_ = std::make_unique( + transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_FETCH_SUBSCRIBERS), + priority, request_ttl); + + auto on_response = [this, response](const auto& maybe_response) { + if (maybe_response.has_value() && + maybe_response.value().has_payload()) { + if (response->ParseFromString(maybe_response.value().payload())) { + if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe + subscription_topic_.SerializeAsString()) { + fetch_subscribers_response_ = *response; + } + } + } + }; + + // FetchSubscribersRequest const fetch_subscribers_request = buildFetchSubscribersRequest(); + auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct + + rpc_handle_ = + rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + + // TODO(lennart) any handle for the response? + + done->Run(); +} + } // namespace uprotocol::core::usubscription::v3 From bf20377c1b9922cfcc7cccd332dac5be73f93b39 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Mon, 5 May 2025 12:52:45 +0200 Subject: [PATCH 010/105] Readded create-Method in RpcClientUSubscription. Created first MockTest --- .../usubscription/v3/RpcClientUSubscription.h | 10 ++-- .../v3/RpcClientUSubscription.cpp | 51 ++++++++++--------- test/CMakeLists.txt | 3 ++ 3 files changed, 34 insertions(+), 30 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index 6e3fedef7..af3052c4b 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -127,12 +127,10 @@ struct RpcClientUSubscription : public uSubscription{ /// @param priority Priority of the subscription request. /// @param subscribe_request_ttl Time to live for the subscription request. /// @param rpc_client_usubscription_options Additional details for uSubscription service. - // [[nodiscard]] static RpcClientUSubscriptionOrStatus create( - // std::shared_ptr transport, - // const v1::UUri& subscription_topic, ListenCallback&& callback, - // v1::UPriority priority, - // std::chrono::milliseconds subscription_request_ttl, - // RpcClientUSubscriptionOptions rpc_client_usubscription_options); + [[nodiscard]] static RpcClientUSubscriptionOrStatus create( + std::shared_ptr transport, + const v1::UUri& subscription_topic, ListenCallback&& callback, + RpcClientUSubscriptionOptions rpc_client_usubscription_options); /// @brief Unsubscribe from the topic and call uSubscription service to /// close the subscription. diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 2aa45f073..abc325bf5 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -33,29 +33,32 @@ RpcClientUSubscription::RpcClientUSubscription(std::shared_ptr transport, -// const v1::UUri& subscription_topic, ListenCallback&& callback, -// v1::UPriority priority, std::chrono::milliseconds subscription_request_ttl, -// RpcClientUSubscriptionOptions rpc_client_usubscription_options) { -// auto rpc_client_usubscription = std::make_unique( -// std::forward>(transport), -// std::forward(subscription_topic), -// std::forward(rpc_client_usubscription_options)); - -// // Attempt to connect create notification sink for updates. -// auto status = rpc_client_usubscription->createNotificationSink(); -// if (status.code() == v1::UCode::OK) { -// status = rpc_client_usubscription->subscribe(priority, subscription_request_ttl, -// std::move(callback)); -// if (status.code() == v1::UCode::OK) { -// return RpcClientUSubscriptionOrStatus(std::move(rpc_client_usubscription)); -// } -// return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); -// } -// // If connection fails, return the error status. -// return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); -// } +[[nodiscard]] RpcClientUSubscription::RpcClientUSubscriptionOrStatus RpcClientUSubscription::create( + std::shared_ptr transport, + const v1::UUri& subscription_topic, ListenCallback&& callback, + RpcClientUSubscriptionOptions rpc_client_usubscription_options) { + auto rpc_client_usubscription = std::make_unique( + std::forward>(transport), + std::forward(subscription_topic), + std::forward(rpc_client_usubscription_options)); + + google::protobuf::RpcController *controller = nullptr; + ::uprotocol::core::usubscription::v3::SubscriptionRequest const *subscription_request = nullptr; + SubscriptionResponse *subscription_response = nullptr; + + // Attempt to connect create notification sink for updates. + auto status = rpc_client_usubscription->createNotificationSink(); + if (status.code() == v1::UCode::OK) { + rpc_client_usubscription->Subscribe(controller, subscription_request, + subscription_response, nullptr); + if (status.code() == v1::UCode::OK) { + return RpcClientUSubscriptionOrStatus(std::move(rpc_client_usubscription)); + } + return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); + } + // If connection fails, return the error status. + return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); +} v1::UStatus RpcClientUSubscription::createNotificationSink() { auto notification_sink_callback = [this](const v1::UMessage& update) { @@ -332,7 +335,7 @@ void RpcClientUSubscription::FetchSubscribers( } } }; - + // FetchSubscribersRequest const fetch_subscribers_request = buildFetchSubscribersRequest(); auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bd7e6d67f..56c122710 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -84,6 +84,9 @@ add_coverage_test("NotificationSourceTest" coverage/communication/NotificationSo # client add_coverage_test("ConsumerTest" coverage/client/usubscription/v3/ConsumerTest.cpp) +# core +add_coverage_test("RpcClientUSubscriptionTest" coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp) + ########################## EXTRAS ############################################# add_extra_test("PublisherSubscriberTest" extra/PublisherSubscriberTest.cpp) add_extra_test("NotificationTest" extra/NotificationTest.cpp) From 638aa0bc3e85b72b2799ae00765d199f62ae1c2b Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Mon, 5 May 2025 12:53:27 +0200 Subject: [PATCH 011/105] Readded create-Method in RpcClientUSubscription. Created first MockTest --- .../v3/RpcClientUSubscriptionTest.cpp | 223 ++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp new file mode 100644 index 000000000..8ed25476f --- /dev/null +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -0,0 +1,223 @@ +// SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include + +#include + +#include "UTransportMock.h" + +namespace { +using MsgDiff = google::protobuf::util::MessageDifferencer; + +void someCallBack(const uprotocol::v1::UMessage& message) { + // Print the message + std::cout << message.DebugString() << std::endl; +} + +class RpcClientUSubscriptionTest : public testing::Test { +private: + std::shared_ptr mockTransportClient_; + std::shared_ptr mockTransportServer_; + uprotocol::v1::UUri client_uuri; + uprotocol::v1::UUri server_uuri; + uprotocol::v1::UUri subscription_uuri; + +protected: + // Run once per TEST_F. + // Used to set up clean environments per test. + + std::shared_ptr getMockTransportClient() + const { + return mockTransportClient_; + } + std::shared_ptr getMockTransportServer() + const { + return mockTransportServer_; + } + uprotocol::v1::UUri& getClientUUri() { return client_uuri; } + const uprotocol::v1::UUri& getServerUUri() const { return server_uuri; } + const uprotocol::v1::UUri& getSubscriptionUUri() const { + return subscription_uuri; + } + + void SetUp() override { + constexpr uint32_t TEST_UE_ID = 0x18000; + constexpr uint32_t DEFAULT_RESOURCE_ID = 0x8000; + // Create a generic transport uri + client_uuri.set_authority_name("random_string"); + client_uuri.set_ue_id(TEST_UE_ID); + client_uuri.set_ue_version_major(3); + client_uuri.set_resource_id(0); + + // Set up a transport + mockTransportClient_ = + std::make_shared(client_uuri); + + // Craete server default uri and set up a transport + server_uuri.set_authority_name("core.usubscription"); + server_uuri.set_ue_id(0); + server_uuri.set_ue_version_major(3); + server_uuri.set_resource_id(0); + + mockTransportServer_ = + std::make_shared(server_uuri); + + // Create a generic subscription uri + subscription_uuri.set_authority_name("10.0.0.2"); + subscription_uuri.set_ue_id(TEST_UE_ID); + subscription_uuri.set_ue_version_major(3); + subscription_uuri.set_resource_id(DEFAULT_RESOURCE_ID); + }; + void TearDown() override {} + + // Run once per execution of the test application. + // Used for setup of all tests. Has access to this instance. + RpcClientUSubscriptionTest() = default; + + void buildDefaultSourceURI(); + void buildValidNotificationURI(); + void buildInValidNotificationURI(); + + // Run once per execution of the test application. + // Used only for global setup outside of tests. + static void SetUpTestSuite() {} + static void TearDownTestSuite() {} + +public: + ~RpcClientUSubscriptionTest() override = default; +}; + +// Negative test case with no source filter +TEST_F(RpcClientUSubscriptionTest, ConstructorTestSuccess) { // NOLINT + // constexpr int REQUEST_TTL_TIME = 0x8000; + auto subscription_callback = someCallBack; + // auto subscribe_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); + // auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; + + auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); + + auto rpc_client_usubscription_or_status = + uprotocol::core::usubscription::v3::RpcClientUSubscription::create( + getMockTransportClient(), getSubscriptionUUri(), + subscription_callback, options); + + // Ensure that the rpc_client_usubscription creation was successful + ASSERT_TRUE(rpc_client_usubscription_or_status.has_value()); + + // Obtain a pointer to the created rpc_client_usubscription instance + const auto& rpc_client_usubscription_ptr = rpc_client_usubscription_or_status.value(); + + // Verify that the rpc_client_usubscription pointer is not null, indicating successful + // creation + ASSERT_NE(rpc_client_usubscription_ptr, nullptr); +} + +TEST_F(RpcClientUSubscriptionTest, SubscribeTestSuccess) { // NOLINT + constexpr uint32_t DEFAULT_RESOURCE_ID = 0x8000; + // constexpr int REQUEST_TTL_TIME = 0x8000; + auto subscription_callback = someCallBack; + // auto subscribe_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); + // auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; + + auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); + + auto rpc_client_usubscription_or_status = + uprotocol::core::usubscription::v3::RpcClientUSubscription::create( + getMockTransportClient(), getSubscriptionUUri(), + subscription_callback, options); + + // Ensure that the RpcClientUSubscription creation was successful + ASSERT_TRUE(rpc_client_usubscription_or_status.has_value()); + + // Obtain a pointer to the created rpc_client_usubscription instance + const auto& rpc_client_usubscription_ptr = rpc_client_usubscription_or_status.value(); + + // Verify that the rpc_client_usubscription pointer is not null, indicating successful + // creation + ASSERT_NE(rpc_client_usubscription_ptr, nullptr); + + // Create notification source sink uri to match resource id of sink + auto notification_uuri = getServerUUri(); + notification_uuri.set_resource_id(DEFAULT_RESOURCE_ID); + + // set format UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY + auto format = + uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY; + + auto notification_source = uprotocol::communication::NotificationSource( + getMockTransportServer(), std::move(notification_uuri), + std::move(getClientUUri()), format); + // Build payload + const std::string data = "test"; + auto payload = uprotocol::datamodel::builder::Payload(data, format); + + notification_source.notify(std::move(payload)); + + // Check send count + EXPECT_TRUE(getMockTransportServer()->getSendCount() == 1); + EXPECT_TRUE(getMockTransportClient()->getSendCount() == 1); +} + +TEST_F(RpcClientUSubscriptionTest, UnsubscribeTestSuccess) { // NOLINT + constexpr uint32_t DEFAULT_RESOURCE_ID = 0x8000; + // constexpr int REQUEST_TTL_TIME = 0x8000; + auto subscription_callback = someCallBack; + // auto subscribe_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); + // auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; + + auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); + + auto rpc_client_usubscription_or_status = + uprotocol::core::usubscription::v3::RpcClientUSubscription::create( + getMockTransportClient(), getSubscriptionUUri(), + subscription_callback, options); + + // Ensure that the rpc_client_usubscription creation was successful + ASSERT_TRUE(rpc_client_usubscription_or_status.has_value()); + + // Obtain a pointer to the created rpc_client_usubscription instance + const auto& rpc_client_usubscription_ptr = rpc_client_usubscription_or_status.value(); + + // Verify that the rpc_client_usubscription pointer is not null, indicating successful + // creation + ASSERT_NE(rpc_client_usubscription_ptr, nullptr); + + // Create notification source sink uri to match resource id of sink + auto notification_uuri = getServerUUri(); + notification_uuri.set_resource_id(DEFAULT_RESOURCE_ID); + + // set format UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY + auto format = + uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY; + + auto notification_source = uprotocol::communication::NotificationSource( + getMockTransportServer(), std::move(notification_uuri), + std::move(getClientUUri()), format); + // Build payload + const std::string data = "test"; + auto payload = uprotocol::datamodel::builder::Payload(data, format); + + notification_source.notify(std::move(payload)); + + // Check send count + EXPECT_TRUE(getMockTransportServer()->getSendCount() == 1); + EXPECT_TRUE(getMockTransportClient()->getSendCount() == 1); + + rpc_client_usubscription_ptr->Unsubscribe(nullptr, nullptr, nullptr, nullptr); + + EXPECT_TRUE(getMockTransportClient()->getSendCount() == 2); +} + +} // namespace From ad4c9c34a78d00e949f2918c94cf1c043385e47d Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Mon, 5 May 2025 17:05:10 +0200 Subject: [PATCH 012/105] Updated minor things in RpcClientUSubscription. --- .../v3/RpcClientUSubscription.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index abc325bf5..91b38a544 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -17,11 +17,6 @@ namespace uprotocol::core::usubscription::v3 { -void someCallBack(const uprotocol::v1::UMessage& message) { - // Print the message - std::cout << message.DebugString() << std::endl; -} - RpcClientUSubscription::RpcClientUSubscription(std::shared_ptr transport, v1::UUri subscription_topic, RpcClientUSubscriptionOptions rpc_client_usubscription_options) @@ -51,7 +46,7 @@ RpcClientUSubscription::RpcClientUSubscription(std::shared_ptrSubscribe(controller, subscription_request, subscription_response, nullptr); - if (status.code() == v1::UCode::OK) { + if (controller == nullptr) { return RpcClientUSubscriptionOrStatus(std::move(rpc_client_usubscription)); } return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); @@ -109,8 +104,6 @@ void RpcClientUSubscription::Subscribe( auto subscription_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; - auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); // Might serve as default_call_options() in Rust - rpc_client_ = std::make_unique( transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_SUBSCRIBE), @@ -134,7 +127,10 @@ void RpcClientUSubscription::Subscribe( rpc_handle_ = rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - auto subscription_callback = someCallBack; // TODO(lennart) update with correct callback + // TODO(lennart) any handle for the response? + + // Question TODO(max): communication::Subscriber::subscribe(...) necessary? + auto subscription_callback = nullptr; // TODO(lennart) update with correct callback // Create a L2 subscription auto result = communication::Subscriber::subscribe( transport_, subscription_topic_, std::move(subscription_callback)); @@ -147,7 +143,7 @@ void RpcClientUSubscription::Subscribe( done->Run(); } - controller->SetFailed("result.error()"); + controller->SetFailed("result.error()"); // TODO(lennart) method needs to be implemented done->Run(); } @@ -190,6 +186,8 @@ void RpcClientUSubscription::Unsubscribe( rpc_handle_ = rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + // TODO(lennart) any handle for the response? + subscriber_.reset(); done->Run(); From 6d693da6d3dc703774d69d6ce6f9a58450d7b172 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Thu, 8 May 2025 15:33:40 +0200 Subject: [PATCH 013/105] building first try of sending method --- .../usubscription/v3/RpcClientUSubscription.h | 109 ++-- .../client/usubscription/v3/USubscription.h | 18 +- .../v3/RpcClientUSubscription.cpp | 561 +++++++++--------- .../v3/RpcClientUSubscriptionTest.cpp | 140 +---- 4 files changed, 352 insertions(+), 476 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index af3052c4b..ef25e327e 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -21,6 +21,7 @@ #include #include +#include "up-cpp/client/usubscription/v3/USubscription.h" namespace uprotocol::core::usubscription::v3 { using uprotocol::core::usubscription::v3::SubscriptionRequest; @@ -112,7 +113,7 @@ struct USubscriptionUUriBuilder { /// /// Like all L3 client APIs, the RpcClientUSubscription is a wrapper on top of the /// L2 Communication APIs and USubscription service. -struct RpcClientUSubscription : public uSubscription{ +struct RpcClientUSubscription : public USubscription{ using RpcClientUSubscriptionOrStatus = utils::Expected, v1::UStatus>; using ListenCallback = transport::UTransport::ListenCallback; @@ -127,61 +128,63 @@ struct RpcClientUSubscription : public uSubscription{ /// @param priority Priority of the subscription request. /// @param subscribe_request_ttl Time to live for the subscription request. /// @param rpc_client_usubscription_options Additional details for uSubscription service. - [[nodiscard]] static RpcClientUSubscriptionOrStatus create( - std::shared_ptr transport, - const v1::UUri& subscription_topic, ListenCallback&& callback, - RpcClientUSubscriptionOptions rpc_client_usubscription_options); + // [[nodiscard]] static RpcClientUSubscriptionOrStatus create( + // std::shared_ptr transport, + // const v1::UUri& subscription_topic, ListenCallback&& callback, + // RpcClientUSubscriptionOptions rpc_client_usubscription_options); + /// @brief Subscribe to the topic + /// + utils::Expected subscribe(const SubscriptionRequest& subscription_request) override; + // void subscribe(google::protobuf::RpcController* controller, + // const ::uprotocol::core::usubscription::v3::SubscriptionRequest* request, + // ::uprotocol::core::usubscription::v3::SubscriptionResponse* response, + // ::google::protobuf::Closure* done) override; + /// @brief Unsubscribe from the topic and call uSubscription service to /// close the subscription. - void Unsubscribe(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::UnsubscribeRequest* request, - ::uprotocol::core::usubscription::v3::UnsubscribeResponse* response, - ::google::protobuf::Closure* done) override; + // void Unsubscribe(google::protobuf::RpcController* controller, + // const ::uprotocol::core::usubscription::v3::UnsubscribeRequest* request, + // ::uprotocol::core::usubscription::v3::UnsubscribeResponse* response, + // ::google::protobuf::Closure* done) override; - /// @brief Fetch all subscriptions for a given topic or subscriber contained inside a [`FetchSubscriptionsRequest`] - void FetchSubscriptions(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::FetchSubscriptionsRequest* request, - ::uprotocol::core::usubscription::v3::FetchSubscriptionsResponse* response, - ::google::protobuf::Closure* done) override; + // /// @brief Fetch all subscriptions for a given topic or subscriber contained inside a [`FetchSubscriptionsRequest`] + // void FetchSubscriptions(google::protobuf::RpcController* controller, + // const ::uprotocol::core::usubscription::v3::FetchSubscriptionsRequest* request, + // ::uprotocol::core::usubscription::v3::FetchSubscriptionsResponse* response, + // ::google::protobuf::Closure* done) override; - /// @brief Register for notifications relevant to a given topic inside a [`NotificationsRequest`] - /// changing in subscription status. - void RegisterForNotifications(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, - ::uprotocol::core::usubscription::v3::NotificationsResponse* response, - ::google::protobuf::Closure* done) override; + // /// @brief Register for notifications relevant to a given topic inside a [`NotificationsRequest`] + // /// changing in subscription status. + // void RegisterForNotifications(google::protobuf::RpcController* controller, + // const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, + // ::uprotocol::core::usubscription::v3::NotificationsResponse* response, + // ::google::protobuf::Closure* done) override; - /// @brief Unregister for notifications relevant to a given topic inside a [`NotificationsRequest`] - /// changing in subscription status. - void UnregisterForNotifications(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, - ::uprotocol::core::usubscription::v3::NotificationsResponse* response, - ::google::protobuf::Closure* done) override; - - /// @brief Fetch a list of subscribers that are currently subscribed to a given topic in a [`FetchSubscribersRequest`] - void FetchSubscribers(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::FetchSubscribersRequest* request, - ::uprotocol::core::usubscription::v3::FetchSubscribersResponse* response, - ::google::protobuf::Closure* done) override; - - /// @brief getter for subscription update - /// - /// @return subscription update - Update getSubscriptionUpdate() const { return subscription_update_; } + // /// @brief Unregister for notifications relevant to a given topic inside a [`NotificationsRequest`] + // /// changing in subscription status. + // void UnregisterForNotifications(google::protobuf::RpcController* controller, + // const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, + // ::uprotocol::core::usubscription::v3::NotificationsResponse* response, + // ::google::protobuf::Closure* done) override; + + // /// @brief Fetch a list of subscribers that are currently subscribed to a given topic in a [`FetchSubscribersRequest`] + // void FetchSubscribers(google::protobuf::RpcController* controller, + // const ::uprotocol::core::usubscription::v3::FetchSubscribersRequest* request, + // ::uprotocol::core::usubscription::v3::FetchSubscribersResponse* response, + // ::google::protobuf::Closure* done) override; /// @brief Destructor - ~RpcClientUSubscription() = default; + ~RpcClientUSubscription() override = default; /// This section for test code only delete later -protected: +// protected: /// @brief Constructor /// /// @param transport Transport to register with. /// @param subscriber_details Additional details about the subscriber. - RpcClientUSubscription(std::shared_ptr transport, - v1::UUri subscription_topic, + explicit RpcClientUSubscription(std::shared_ptr transport, RpcClientUSubscriptionOptions rpc_client_usubscription_options = {}); private: @@ -190,29 +193,13 @@ struct RpcClientUSubscription : public uSubscription{ // Topic to subscribe to const v1::UUri subscription_topic_; + // Additional details about uSubscription service RpcClientUSubscriptionOptions rpc_client_usubscription_options_; // URI info about the uSubscription service USubscriptionUUriBuilder uSubscriptionUUriBuilder_; - // Subscription updates - std::unique_ptr noficationSinkHandle_; - Update subscription_update_; - - // RPC request - std::unique_ptr rpc_client_; - communication::RpcClient::InvokeHandle rpc_handle_; - - SubscriptionResponse subscription_response_; - UnsubscribeResponse unsubscribe_response_; - FetchSubscriptionsResponse fetch_subscription_response_; - NotificationsResponse notification_response_; - FetchSubscribersResponse fetch_subscribers_response_; - - // L2 Subscriber details - std::unique_ptr subscriber_; - // Allow the protected constructor for this class to be used in make_unique // inside of create() friend std::unique_ptr @@ -232,12 +219,6 @@ struct RpcClientUSubscription : public uSubscription{ /// @brief Create a notification sink to receive subscription updates v1::UStatus createNotificationSink(); - /// @brief Subscribe to the topic - /// - void Subscribe(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::SubscriptionRequest* request, - ::uprotocol::core::usubscription::v3::SubscriptionResponse* response, - ::google::protobuf::Closure* done) override; }; } // namespace uprotocol::core::usubscription::v3 diff --git a/include/up-cpp/client/usubscription/v3/USubscription.h b/include/up-cpp/client/usubscription/v3/USubscription.h index 0de39ca93..9c387039d 100644 --- a/include/up-cpp/client/usubscription/v3/USubscription.h +++ b/include/up-cpp/client/usubscription/v3/USubscription.h @@ -1,24 +1,30 @@ #ifndef USUBSCRIPTION_H #define USUBSCRIPTION_H #include +#include +#include +#include "up-cpp/utils/Expected.h" namespace uprotocol::core::usubscription::v3 { struct USubscription { + template + using ResponseOrStatus = utils::Expected; + virtual ~USubscription() = default; - virtual SubscriptionResponse subscribe(const SubscriptionRequest& subscription_request) = 0; + virtual ResponseOrStatus subscribe(const SubscriptionRequest& subscription_request) = 0; - virtual UnsubscribeResponse unsubscribe(const UnsubscribeRequest& unsubscribe_request) = 0; + // virtual UnsubscribeResponse unsubscribe(const UnsubscribeRequest& unsubscribe_request) = 0; - virtual FetchSubscriptionsResponse fetch_subscriptions(const FetchSubscriptionsRequest& fetch_subscribers_request) = 0; + // virtual FetchSubscriptionsResponse fetch_subscriptions(const FetchSubscriptionsRequest& fetch_subscribers_request) = 0; - virtual NotificationsResponse register_for_notifications(const NotificationsRequest& register_notifications_request) =0 ; + // virtual NotificationsResponse register_for_notifications(const NotificationsRequest& register_notifications_request) =0 ; - virtual NotificationsResponse unregister_for_notifications(const NotificationsRequest& unregister_notifications_request) = 0; + // virtual NotificationsResponse unregister_for_notifications(const NotificationsRequest& unregister_notifications_request) = 0; - virtual FetchSubscribersResponse fetch_subscribers(const FetchSubscribersRequest& fetch_subscribers_request) = 0; + // virtual FetchSubscribersResponse fetch_subscribers(const FetchSubscribersRequest& fetch_subscribers_request) = 0; }; diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 91b38a544..a160f1dce 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -12,75 +12,78 @@ #include #include #include +#include #include +#include "up-cpp/communication/RpcClient.h" + +constexpr uint16_t RESOURCE_ID_SUBSCRIBE = 0x0001; +// TODO(lennart) see default_call_options() for the request in Rust +constexpr auto SUBSCRIPTION_REQUEST_TTL = std::chrono::milliseconds(0x0800); // TODO(lennart) change time +auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; // MUST be >= 4 namespace uprotocol::core::usubscription::v3 { RpcClientUSubscription::RpcClientUSubscription(std::shared_ptr transport, - v1::UUri subscription_topic, RpcClientUSubscriptionOptions rpc_client_usubscription_options) : transport_(std::move(transport)), - subscription_topic_(std::move(subscription_topic)), - rpc_client_usubscription_options_(std::move(rpc_client_usubscription_options)), - rpc_client_(nullptr) { + rpc_client_usubscription_options_(std::move(rpc_client_usubscription_options)) { // Initialize uSubscriptionUUriBuilder_ uSubscriptionUUriBuilder_ = USubscriptionUUriBuilder(); } -[[nodiscard]] RpcClientUSubscription::RpcClientUSubscriptionOrStatus RpcClientUSubscription::create( - std::shared_ptr transport, - const v1::UUri& subscription_topic, ListenCallback&& callback, - RpcClientUSubscriptionOptions rpc_client_usubscription_options) { - auto rpc_client_usubscription = std::make_unique( - std::forward>(transport), - std::forward(subscription_topic), - std::forward(rpc_client_usubscription_options)); +// [[nodiscard]] RpcClientUSubscription::RpcClientUSubscriptionOrStatus RpcClientUSubscription::create( +// std::shared_ptr transport, +// const v1::UUri& subscription_topic, ListenCallback&& callback, +// RpcClientUSubscriptionOptions rpc_client_usubscription_options) { +// auto rpc_client_usubscription = std::make_unique( +// std::forward>(transport), +// std::forward(rpc_client_usubscription_options)); - google::protobuf::RpcController *controller = nullptr; - ::uprotocol::core::usubscription::v3::SubscriptionRequest const *subscription_request = nullptr; - SubscriptionResponse *subscription_response = nullptr; - - // Attempt to connect create notification sink for updates. - auto status = rpc_client_usubscription->createNotificationSink(); - if (status.code() == v1::UCode::OK) { - rpc_client_usubscription->Subscribe(controller, subscription_request, - subscription_response, nullptr); - if (controller == nullptr) { - return RpcClientUSubscriptionOrStatus(std::move(rpc_client_usubscription)); - } - return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); - } - // If connection fails, return the error status. - return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); -} - -v1::UStatus RpcClientUSubscription::createNotificationSink() { - auto notification_sink_callback = [this](const v1::UMessage& update) { - if (update.has_payload()) { - Update data; - if (data.ParseFromString(update.payload())) { - if (data.topic().SerializeAsString() == - subscription_topic_.SerializeAsString()) { - subscription_update_ = std::move(data); - } - } - } - }; - - auto notification_topic = uSubscriptionUUriBuilder_.getNotificationUri(); - - auto result = communication::NotificationSink::create( - transport_, std::move(notification_sink_callback), notification_topic); - - if (result.has_value()) { - noficationSinkHandle_ = std::move(result).value(); - v1::UStatus status; - status.set_code(v1::UCode::OK); - return status; - } - return result.error(); -} +// google::protobuf::RpcController *controller = nullptr; +// ::uprotocol::core::usubscription::v3::SubscriptionRequest const *subscription_request = nullptr; +// SubscriptionResponse *subscription_response = nullptr; + +// // Attempt to connect create notification sink for updates. +// auto status = rpc_client_usubscription->createNotificationSink(); +// if (status.code() == v1::UCode::OK) { +// rpc_client_usubscription->Subscribe(controller, subscription_request, +// subscription_response, nullptr); +// if (controller == nullptr) { +// return RpcClientUSubscriptionOrStatus(std::move(rpc_client_usubscription)); +// } +// return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); +// } +// // If connection fails, return the error status. +// return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); +// } + +// v1::UStatus RpcClientUSubscription::createNotificationSink() { +// auto notification_sink_callback = [this](const v1::UMessage& update) { +// if (update.has_payload()) { +// Update data; +// if (data.ParseFromString(update.payload())) { +// if (data.topic().SerializeAsString() == +// subscription_topic_.SerializeAsString()) { +// subscription_update_ = std::move(data); +// } +// } +// } +// }; + +// auto notification_topic = uSubscriptionUUriBuilder_.getNotificationUri(); + +// auto result = communication::NotificationSink::create( +// transport_, std::move(notification_sink_callback), notification_topic); + +// if (result.has_value()) { +// noficationSinkHandle_ = std::move(result).value(); +// v1::UStatus status; +// status.set_code(v1::UCode::OK); +// return status; +// } +// return result.error(); +// } SubscriptionRequest RpcClientUSubscription::buildSubscriptionRequest() { auto attributes = utils::ProtoConverter::BuildSubscribeAttributes( @@ -92,257 +95,235 @@ SubscriptionRequest RpcClientUSubscription::buildSubscriptionRequest() { return subscription_request; } -void RpcClientUSubscription::Subscribe( - google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::SubscriptionRequest* request, - ::uprotocol::core::usubscription::v3::SubscriptionResponse* response, - ::google::protobuf::Closure* done) { +RpcClientUSubscription::ResponseOrStatus RpcClientUSubscription::subscribe(const SubscriptionRequest& subscription_request) { + + communication::RpcClient rpc_client( + transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_SUBSCRIBE), + priority, SUBSCRIPTION_REQUEST_TTL); + + datamodel::builder::Payload payload(subscription_request); + + auto invoke_future = + rpc_client.invokeMethod(std::move(payload)); + + auto message_or_status = invoke_future.get(); - constexpr uint16_t RESOURCE_ID_SUBSCRIBE = 0x0001; - // TODO(lennart) see default_call_options() for the request in Rust - constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? - auto subscription_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; + if (!message_or_status.has_value()) { + return ResponseOrStatus( + utils::Unexpected(message_or_status.error())); + } + SubscriptionResponse subscription_response; + subscription_response.ParseFromString(message_or_status.value().payload()); - rpc_client_ = std::make_unique( - transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_SUBSCRIBE), - priority, subscription_request_ttl); - - auto on_response = [this, response](const auto& maybe_response) { - if (maybe_response.has_value() && - maybe_response.value().has_payload()) { - if (response->ParseFromString(maybe_response.value().payload())) { - if (response->topic().SerializeAsString() == - subscription_topic_.SerializeAsString()) { - subscription_response_ = *response; - } - } - } - }; - - // SubscriptionRequest const subscription_request = buildSubscriptionRequest(); - auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct, has been subscription_request before - - rpc_handle_ = - rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - - // TODO(lennart) any handle for the response? - - // Question TODO(max): communication::Subscriber::subscribe(...) necessary? - auto subscription_callback = nullptr; // TODO(lennart) update with correct callback - // Create a L2 subscription - auto result = communication::Subscriber::subscribe( - transport_, subscription_topic_, std::move(subscription_callback)); - - if (result.has_value()) { - subscriber_ = std::move(result).value(); - v1::UStatus status; - status.set_code(v1::UCode::OK); - // return status; - done->Run(); + if (subscription_response.topic().SerializeAsString() == + subscription_topic_.SerializeAsString()) { + return ResponseOrStatus(subscription_response); } - controller->SetFailed("result.error()"); // TODO(lennart) method needs to be implemented - - done->Run(); + return ResponseOrStatus( + utils::Unexpected(message_or_status.error())); + } -UnsubscribeRequest RpcClientUSubscription::buildUnsubscriptionRequest() { - auto unsubscribe_request = - utils::ProtoConverter::BuildUnSubscribeRequest(subscription_topic_); - return unsubscribe_request; -} -void RpcClientUSubscription::Unsubscribe( - google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::UnsubscribeRequest* request, - ::uprotocol::core::usubscription::v3::UnsubscribeResponse* response, - ::google::protobuf::Closure* done) { - - constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? - constexpr uint16_t RESOURCE_ID_UNSUBSCRIBE = 0x0002; - auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; - - rpc_client_ = std::make_unique( - transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_UNSUBSCRIBE), - priority, request_ttl); - - auto on_response = [this, response](const auto& maybe_response) { - if (maybe_response.has_value() && - maybe_response.value().has_payload()) { - if (response->ParseFromString(maybe_response.value().payload())) { - if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe - subscription_topic_.SerializeAsString()) { - unsubscribe_response_ = *response; - } - } - } - }; - - // UnsubscribeRequest const unsubscribe_request = buildUnsubscriptionRequest(); - auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct - rpc_handle_ = - rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - - // TODO(lennart) any handle for the response? - - subscriber_.reset(); - done->Run(); -} -void RpcClientUSubscription::FetchSubscriptions( - google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::FetchSubscriptionsRequest* request, - ::uprotocol::core::usubscription::v3::FetchSubscriptionsResponse* response, - ::google::protobuf::Closure* done) { +// UnsubscribeRequest RpcClientUSubscription::buildUnsubscriptionRequest() { +// auto unsubscribe_request = +// utils::ProtoConverter::BuildUnSubscribeRequest(subscription_topic_); +// return unsubscribe_request; +// } + +// void RpcClientUSubscription::Unsubscribe( +// google::protobuf::RpcController* controller, +// const ::uprotocol::core::usubscription::v3::UnsubscribeRequest* request, +// ::uprotocol::core::usubscription::v3::UnsubscribeResponse* response, +// ::google::protobuf::Closure* done) { - constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? - constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIPTIONS = 0x0003; - auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; +// constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? +// constexpr uint16_t RESOURCE_ID_UNSUBSCRIBE = 0x0002; +// auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); +// auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; - rpc_client_ = std::make_unique( - transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_FETCH_SUBSCRIPTIONS), - priority, request_ttl); - - auto on_response = [this, response](const auto& maybe_response) { - if (maybe_response.has_value() && - maybe_response.value().has_payload()) { - if (response->ParseFromString(maybe_response.value().payload())) { - if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe - subscription_topic_.SerializeAsString()) { - fetch_subscription_response_ = *response; - } - } - } - }; - - // FetchSubscriptionsRequest const fetch_subscriptions_request = buildFetchSubscriptionsRequest(); - auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct - - rpc_handle_ = - rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - - // TODO(lennart) any handle for the response? - - done->Run(); -} - -void RpcClientUSubscription::RegisterForNotifications( - google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, - ::uprotocol::core::usubscription::v3::NotificationsResponse* response, - ::google::protobuf::Closure* done) { +// rpc_client_ = std::make_unique( +// transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_UNSUBSCRIBE), +// priority, request_ttl); + +// auto on_response = [this, response](const auto& maybe_response) { +// if (maybe_response.has_value() && +// maybe_response.value().has_payload()) { +// if (response->ParseFromString(maybe_response.value().payload())) { +// if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe +// subscription_topic_.SerializeAsString()) { +// unsubscribe_response_ = *response; +// } +// } +// } +// }; + +// // UnsubscribeRequest const unsubscribe_request = buildUnsubscriptionRequest(); +// auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct +// rpc_handle_ = +// rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + +// // TODO(lennart) any handle for the response? + +// subscriber_.reset(); + +// done->Run(); +// } + +// void RpcClientUSubscription::FetchSubscriptions( +// google::protobuf::RpcController* controller, +// const ::uprotocol::core::usubscription::v3::FetchSubscriptionsRequest* request, +// ::uprotocol::core::usubscription::v3::FetchSubscriptionsResponse* response, +// ::google::protobuf::Closure* done) { - constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? - constexpr uint16_t RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS = 0x0006; - auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; +// constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? +// constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIPTIONS = 0x0003; +// auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); +// auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; - rpc_client_ = std::make_unique( - transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS), - priority, request_ttl); - - auto on_response = [this, response](const auto& maybe_response) { - if (maybe_response.has_value() && - maybe_response.value().has_payload()) { - if (response->ParseFromString(maybe_response.value().payload())) { - if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe - subscription_topic_.SerializeAsString()) { - notification_response_ = *response; - } - } - } - }; - - // NotificationsRequest const register_notifications_request = buildRegisterNotificationsRequest(); - auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct - - rpc_handle_ = - rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - - // TODO(lennart) any handle for the response? - - done->Run(); -} - -void RpcClientUSubscription::UnregisterForNotifications( - google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, - ::uprotocol::core::usubscription::v3::NotificationsResponse* response, - ::google::protobuf::Closure* done) { +// rpc_client_ = std::make_unique( +// transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_FETCH_SUBSCRIPTIONS), +// priority, request_ttl); + +// auto on_response = [this, response](const auto& maybe_response) { +// if (maybe_response.has_value() && +// maybe_response.value().has_payload()) { +// if (response->ParseFromString(maybe_response.value().payload())) { +// if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe +// subscription_topic_.SerializeAsString()) { +// fetch_subscription_response_ = *response; +// } +// } +// } +// }; + +// // FetchSubscriptionsRequest const fetch_subscriptions_request = buildFetchSubscriptionsRequest(); +// auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct + +// rpc_handle_ = +// rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + +// // TODO(lennart) any handle for the response? + +// done->Run(); +// } + +// void RpcClientUSubscription::RegisterForNotifications( +// google::protobuf::RpcController* controller, +// const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, +// ::uprotocol::core::usubscription::v3::NotificationsResponse* response, +// ::google::protobuf::Closure* done) { - constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? - constexpr uint16_t RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS = 0x0007; - auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; +// constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? +// constexpr uint16_t RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS = 0x0006; +// auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); +// auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; - rpc_client_ = std::make_unique( - transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS), - priority, request_ttl); - - auto on_response = [this, response](const auto& maybe_response) { - if (maybe_response.has_value() && - maybe_response.value().has_payload()) { - if (response->ParseFromString(maybe_response.value().payload())) { - if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe - subscription_topic_.SerializeAsString()) { - notification_response_ = *response; - } - } - } - }; - - // NotificationsRequest const unregister_notifications_request = buildUnregisterNotificationsRequest(); - auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct - - rpc_handle_ = - rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - - // TODO(lennart) any handle for the response? - - done->Run(); -} - -void RpcClientUSubscription::FetchSubscribers( - google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::FetchSubscribersRequest* request, - ::uprotocol::core::usubscription::v3::FetchSubscribersResponse* response, - ::google::protobuf::Closure* done) { +// rpc_client_ = std::make_unique( +// transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS), +// priority, request_ttl); + +// auto on_response = [this, response](const auto& maybe_response) { +// if (maybe_response.has_value() && +// maybe_response.value().has_payload()) { +// if (response->ParseFromString(maybe_response.value().payload())) { +// if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe +// subscription_topic_.SerializeAsString()) { +// notification_response_ = *response; +// } +// } +// } +// }; + +// // NotificationsRequest const register_notifications_request = buildRegisterNotificationsRequest(); +// auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct + +// rpc_handle_ = +// rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + +// // TODO(lennart) any handle for the response? + +// done->Run(); +// } + +// void RpcClientUSubscription::UnregisterForNotifications( +// google::protobuf::RpcController* controller, +// const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, +// ::uprotocol::core::usubscription::v3::NotificationsResponse* response, +// ::google::protobuf::Closure* done) { - constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? - constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIBERS = 0x0008; - auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; +// constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? +// constexpr uint16_t RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS = 0x0007; +// auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); +// auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; - rpc_client_ = std::make_unique( - transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_FETCH_SUBSCRIBERS), - priority, request_ttl); - - auto on_response = [this, response](const auto& maybe_response) { - if (maybe_response.has_value() && - maybe_response.value().has_payload()) { - if (response->ParseFromString(maybe_response.value().payload())) { - if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe - subscription_topic_.SerializeAsString()) { - fetch_subscribers_response_ = *response; - } - } - } - }; - - // FetchSubscribersRequest const fetch_subscribers_request = buildFetchSubscribersRequest(); - auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct - - rpc_handle_ = - rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - - // TODO(lennart) any handle for the response? - - done->Run(); -} +// rpc_client_ = std::make_unique( +// transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS), +// priority, request_ttl); + +// auto on_response = [this, response](const auto& maybe_response) { +// if (maybe_response.has_value() && +// maybe_response.value().has_payload()) { +// if (response->ParseFromString(maybe_response.value().payload())) { +// if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe +// subscription_topic_.SerializeAsString()) { +// notification_response_ = *response; +// } +// } +// } +// }; + +// // NotificationsRequest const unregister_notifications_request = buildUnregisterNotificationsRequest(); +// auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct + +// rpc_handle_ = +// rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + +// // TODO(lennart) any handle for the response? + +// done->Run(); +// } + +// void RpcClientUSubscription::FetchSubscribers( +// google::protobuf::RpcController* controller, +// const ::uprotocol::core::usubscription::v3::FetchSubscribersRequest* request, +// ::uprotocol::core::usubscription::v3::FetchSubscribersResponse* response, +// ::google::protobuf::Closure* done) { + +// constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? +// constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIBERS = 0x0008; +// auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); +// auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; + +// rpc_client_ = std::make_unique( +// transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_FETCH_SUBSCRIBERS), +// priority, request_ttl); + +// auto on_response = [this, response](const auto& maybe_response) { +// if (maybe_response.has_value() && +// maybe_response.value().has_payload()) { +// if (response->ParseFromString(maybe_response.value().payload())) { +// if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe +// subscription_topic_.SerializeAsString()) { +// fetch_subscribers_response_ = *response; +// } +// } +// } +// }; + +// // FetchSubscribersRequest const fetch_subscribers_request = buildFetchSubscribersRequest(); +// auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct + +// rpc_handle_ = +// rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + +// // TODO(lennart) any handle for the response? + +// done->Run(); +// } } // namespace uprotocol::core::usubscription::v3 diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp index 8ed25476f..fe6a3ef33 100644 --- a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -21,11 +21,6 @@ namespace { using MsgDiff = google::protobuf::util::MessageDifferencer; -void someCallBack(const uprotocol::v1::UMessage& message) { - // Print the message - std::cout << message.DebugString() << std::endl; -} - class RpcClientUSubscriptionTest : public testing::Test { private: std::shared_ptr mockTransportClient_; @@ -101,123 +96,36 @@ class RpcClientUSubscriptionTest : public testing::Test { // Negative test case with no source filter TEST_F(RpcClientUSubscriptionTest, ConstructorTestSuccess) { // NOLINT - // constexpr int REQUEST_TTL_TIME = 0x8000; - auto subscription_callback = someCallBack; - // auto subscribe_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - // auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); - - auto rpc_client_usubscription_or_status = - uprotocol::core::usubscription::v3::RpcClientUSubscription::create( - getMockTransportClient(), getSubscriptionUUri(), - subscription_callback, options); - - // Ensure that the rpc_client_usubscription creation was successful - ASSERT_TRUE(rpc_client_usubscription_or_status.has_value()); - - // Obtain a pointer to the created rpc_client_usubscription instance - const auto& rpc_client_usubscription_ptr = rpc_client_usubscription_or_status.value(); - - // Verify that the rpc_client_usubscription pointer is not null, indicating successful - // creation - ASSERT_NE(rpc_client_usubscription_ptr, nullptr); + + auto rpc_client_usubscription = + std::make_unique(getMockTransportClient(), + options); + + // Verify that the RpcClientUSubscription pointer is not null, indicating successful + ASSERT_NE(rpc_client_usubscription, nullptr); } TEST_F(RpcClientUSubscriptionTest, SubscribeTestSuccess) { // NOLINT - constexpr uint32_t DEFAULT_RESOURCE_ID = 0x8000; - // constexpr int REQUEST_TTL_TIME = 0x8000; - auto subscription_callback = someCallBack; - // auto subscribe_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - // auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; - + auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); - - auto rpc_client_usubscription_or_status = - uprotocol::core::usubscription::v3::RpcClientUSubscription::create( - getMockTransportClient(), getSubscriptionUUri(), - subscription_callback, options); - - // Ensure that the RpcClientUSubscription creation was successful - ASSERT_TRUE(rpc_client_usubscription_or_status.has_value()); - - // Obtain a pointer to the created rpc_client_usubscription instance - const auto& rpc_client_usubscription_ptr = rpc_client_usubscription_or_status.value(); - - // Verify that the rpc_client_usubscription pointer is not null, indicating successful - // creation - ASSERT_NE(rpc_client_usubscription_ptr, nullptr); - - // Create notification source sink uri to match resource id of sink - auto notification_uuri = getServerUUri(); - notification_uuri.set_resource_id(DEFAULT_RESOURCE_ID); - - // set format UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY - auto format = - uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY; - - auto notification_source = uprotocol::communication::NotificationSource( - getMockTransportServer(), std::move(notification_uuri), - std::move(getClientUUri()), format); - // Build payload - const std::string data = "test"; - auto payload = uprotocol::datamodel::builder::Payload(data, format); - - notification_source.notify(std::move(payload)); - - // Check send count - EXPECT_TRUE(getMockTransportServer()->getSendCount() == 1); - EXPECT_TRUE(getMockTransportClient()->getSendCount() == 1); -} - -TEST_F(RpcClientUSubscriptionTest, UnsubscribeTestSuccess) { // NOLINT - constexpr uint32_t DEFAULT_RESOURCE_ID = 0x8000; - // constexpr int REQUEST_TTL_TIME = 0x8000; - auto subscription_callback = someCallBack; - // auto subscribe_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - // auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; - - auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); - - auto rpc_client_usubscription_or_status = - uprotocol::core::usubscription::v3::RpcClientUSubscription::create( - getMockTransportClient(), getSubscriptionUUri(), - subscription_callback, options); - - // Ensure that the rpc_client_usubscription creation was successful - ASSERT_TRUE(rpc_client_usubscription_or_status.has_value()); - - // Obtain a pointer to the created rpc_client_usubscription instance - const auto& rpc_client_usubscription_ptr = rpc_client_usubscription_or_status.value(); - - // Verify that the rpc_client_usubscription pointer is not null, indicating successful - // creation - ASSERT_NE(rpc_client_usubscription_ptr, nullptr); - - // Create notification source sink uri to match resource id of sink - auto notification_uuri = getServerUUri(); - notification_uuri.set_resource_id(DEFAULT_RESOURCE_ID); - - // set format UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY - auto format = - uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY; - - auto notification_source = uprotocol::communication::NotificationSource( - getMockTransportServer(), std::move(notification_uuri), - std::move(getClientUUri()), format); - // Build payload - const std::string data = "test"; - auto payload = uprotocol::datamodel::builder::Payload(data, format); - - notification_source.notify(std::move(payload)); - - // Check send count - EXPECT_TRUE(getMockTransportServer()->getSendCount() == 1); - EXPECT_TRUE(getMockTransportClient()->getSendCount() == 1); - - rpc_client_usubscription_ptr->Unsubscribe(nullptr, nullptr, nullptr, nullptr); - - EXPECT_TRUE(getMockTransportClient()->getSendCount() == 2); + + uprotocol::core::usubscription::v3::SubscriptionRequest subscription_request = uprotocol::utils::ProtoConverter::BuildSubscriptionRequest( + getSubscriptionUUri(), uprotocol::core::usubscription::v3::SubscribeAttributes()); + + auto rpc_client_usubscription = + std::make_unique(getMockTransportClient(), + options); + + // Verify that the RpcClientUSubscription pointer is not null, indicating successful + ASSERT_NE(rpc_client_usubscription, nullptr); + + auto result = rpc_client_usubscription->subscribe(subscription_request); + + ASSERT_NE(&result, nullptr); } } // namespace From 9bd68b345a5f45325b5bf519747249d41c244c20 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 29 Apr 2025 06:45:48 +0200 Subject: [PATCH 014/105] initial setup of header filers --- CMakeLists.txt | 5 ++- .../usubscription/v3/RpcClientUSubscription.h | 41 +++++++++++++++++++ .../client/usubscription/v3/USubscription.h | 31 ++++++++++++++ .../v3/RpcClientUSubscription.cpp | 18 ++++++++ 4 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h create mode 100644 include/up-cpp/client/usubscription/v3/USubscription.h create mode 100644 src/client/usubscription/v3/RpcClientUSubscription.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 256391aae..89528e261 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,7 +48,10 @@ endif() file(GLOB_RECURSE SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") -add_library(${PROJECT_NAME} ${SRC_FILES}) +add_library(${PROJECT_NAME} ${SRC_FILES} + src/client/usubscription/v3/RpcClientUSubscription.cpp + include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h + include/up-cpp/client/usubscription/v3/USubscription.h) add_library(up-cpp::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) target_include_directories(${PROJECT_NAME} diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h new file mode 100644 index 000000000..7d2bf43aa --- /dev/null +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -0,0 +1,41 @@ +// +// Created by max on 28.04.25. +// + +#ifndef RPCCLIENTUSUBSCRIPTION_H +#define RPCCLIENTUSUBSCRIPTION_H + +#include + +#include "USubscription.h" +#include "up-cpp/communication/RpcClient.h" + +namespace uprotocol::core::usubscription::v3 { + +struct RpcClientUSubscription : USubscription { + + explicit RpcClientUSubscription(std::unique_ptr client) + : client_(std::move(client)){}; + + void default_call_option(); + + SubscriptionResponse subscribe(const SubscriptionRequest& subscription_request) override; + + UnsubscribeResponse unsubscribe(const UnsubscribeRequest& unsubscribe_request) override; + + FetchSubscriptionsResponse fetch_subscriptions(const FetchSubscriptionsRequest& fetch_subscribers_request) override; + + NotificationsResponse register_for_notifications(const NotificationsRequest& register_notifications_request) override; + + NotificationsResponse unregister_for_notifications(const NotificationsRequest& unregister_notifications_request) override; + + FetchSubscribersResponse fetch_subscribers(const FetchSubscribersRequest& fetch_subscribers_request) override; + +private: + std::unique_ptr client_; + +}; + +} // namespace uprotocol::core::usubscription::v3 + +#endif //RPCCLIENTUSUBSCRIPTION_H diff --git a/include/up-cpp/client/usubscription/v3/USubscription.h b/include/up-cpp/client/usubscription/v3/USubscription.h new file mode 100644 index 000000000..53aafb349 --- /dev/null +++ b/include/up-cpp/client/usubscription/v3/USubscription.h @@ -0,0 +1,31 @@ +// +// Created by max on 28.04.25. +// + +#ifndef USUBSCRIPTION_H +#define USUBSCRIPTION_H +#include "RpcClientUSubscription.h" + +namespace uprotocol::core::usubscription::v3 { + + struct USubscription { + + virtual ~USubscription() = default; + + virtual SubscriptionResponse subscribe(const SubscriptionRequest& subscription_request) = 0; + + virtual UnsubscribeResponse unsubscribe(const UnsubscribeRequest& unsubscribe_request) = 0; + + virtual FetchSubscriptionsResponse fetch_subscriptions(const FetchSubscriptionsRequest& fetch_subscribers_request) = 0; + + virtual NotificationsResponse register_for_notifications(const NotificationsRequest& register_notifications_request) =0 ; + + virtual NotificationsResponse unregister_for_notifications(const NotificationsRequest& unregister_notifications_request) = 0; + + virtual FetchSubscribersResponse fetch_subscribers(const FetchSubscribersRequest& fetch_subscribers_request) = 0; + + }; + +} // namespace uprotocol::core::usubscription::v3 + +#endif //USUBSCRIPTION_H diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp new file mode 100644 index 000000000..999e584f4 --- /dev/null +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -0,0 +1,18 @@ +// +// Created by max on 28.04.25. +// + +#include "up-cpp/client/usubscription/v3/RpcClientUSubscription.h" + +namespace uprotocol::core::usubscription::v3 { + using Payload = datamodel::builder::Payload; + + SubscriptionResponse RpcClientUSubscription::subscribe( + const SubscriptionRequest& subscription_request) { + Payload test_test(subscription_request); + auto invoke_handle = client_->invokeMethod(test_test, //TODO(max)); + return SubscriptionResponse(); + } + + } // namespace uprotocol::core::usubscription::v3 + From 9ee1b4d8952104de69e3092fce0ca6ea22e8d7be Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Tue, 29 Apr 2025 15:42:06 +0200 Subject: [PATCH 015/105] Update RpcClientUSubscription to protobuf singature. Add subscription method, which is currently in dev --- .../usubscription/v3/RpcClientUSubscription.h | 84 +++++++++++++++---- .../client/usubscription/v3/USubscription.h | 6 +- .../v3/RpcClientUSubscription.cpp | 71 +++++++++++++--- 3 files changed, 127 insertions(+), 34 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index 7d2bf43aa..d351dd3fa 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -1,39 +1,87 @@ -// -// Created by max on 28.04.25. -// - #ifndef RPCCLIENTUSUBSCRIPTION_H #define RPCCLIENTUSUBSCRIPTION_H #include +#include "Consumer.h" -#include "USubscription.h" +// #include "USubscription.h" #include "up-cpp/communication/RpcClient.h" namespace uprotocol::core::usubscription::v3 { -struct RpcClientUSubscription : USubscription { - - explicit RpcClientUSubscription(std::unique_ptr client) - : client_(std::move(client)){}; - +struct RpcClientUSubscription : public uSubscription { +public: + RpcClientUSubscription() = default; + ~RpcClientUSubscription() override = default; + + explicit RpcClientUSubscription(std::unique_ptr rpc_client) + : rpc_client_(std::move(rpc_client)){}; + + + void Subscribe(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::SubscriptionRequest* request, + ::uprotocol::core::usubscription::v3::SubscriptionResponse* response, + ::google::protobuf::Closure* done) override; + + void Unsubscribe(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::UnsubscribeRequest* request, + ::uprotocol::core::usubscription::v3::UnsubscribeResponse* response, + ::google::protobuf::Closure* done) override; + + void FetchSubscriptions(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::FetchSubscriptionsRequest* request, + ::uprotocol::core::usubscription::v3::FetchSubscriptionsResponse* response, + ::google::protobuf::Closure* done) override; + + void RegisterForNotifications(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, + ::uprotocol::core::usubscription::v3::NotificationsResponse* response, + ::google::protobuf::Closure* done) override; + + void UnregisterForNotifications(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, + ::uprotocol::core::usubscription::v3::NotificationsResponse* response, + ::google::protobuf::Closure* done) override; + + void FetchSubscribers(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::FetchSubscribersRequest* request, + ::uprotocol::core::usubscription::v3::FetchSubscribersResponse* response, + ::google::protobuf::Closure* done) override; + + void Reset(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::ResetRequest* request, + ::uprotocol::core::usubscription::v3::ResetResponse* response, + ::google::protobuf::Closure* done) override; + +// Backup void default_call_option(); - SubscriptionResponse subscribe(const SubscriptionRequest& subscription_request) override; + // SubscriptionResponse subscribe(const SubscriptionRequest& subscription_request); - UnsubscribeResponse unsubscribe(const UnsubscribeRequest& unsubscribe_request) override; + // UnsubscribeResponse unsubscribe(const UnsubscribeRequest& unsubscribe_request); - FetchSubscriptionsResponse fetch_subscriptions(const FetchSubscriptionsRequest& fetch_subscribers_request) override; + // FetchSubscriptionsResponse fetch_subscriptions(const FetchSubscriptionsRequest& fetch_subscribers_request); - NotificationsResponse register_for_notifications(const NotificationsRequest& register_notifications_request) override; + // NotificationsResponse register_for_notifications(const NotificationsRequest& register_notifications_request); - NotificationsResponse unregister_for_notifications(const NotificationsRequest& unregister_notifications_request) override; + // NotificationsResponse unregister_for_notifications(const NotificationsRequest& unregister_notifications_request); - FetchSubscribersResponse fetch_subscribers(const FetchSubscribersRequest& fetch_subscribers_request) override; + // FetchSubscribersResponse fetch_subscribers(const FetchSubscribersRequest& fetch_subscribers_request); private: - std::unique_ptr client_; - + // RPC request + std::unique_ptr rpc_client_; + communication::RpcClient::InvokeHandle rpc_handle_; + SubscriptionResponse subscription_response_; + + // Transport + std::shared_ptr transport_; + + // URI info about the uSubscription service + client::usubscription::v3::USubscriptionUUriBuilder uSubscriptionUUriBuilder_; + + // Topic to subscribe to + const v1::UUri subscription_topic_; }; } // namespace uprotocol::core::usubscription::v3 diff --git a/include/up-cpp/client/usubscription/v3/USubscription.h b/include/up-cpp/client/usubscription/v3/USubscription.h index 53aafb349..0de39ca93 100644 --- a/include/up-cpp/client/usubscription/v3/USubscription.h +++ b/include/up-cpp/client/usubscription/v3/USubscription.h @@ -1,10 +1,6 @@ -// -// Created by max on 28.04.25. -// - #ifndef USUBSCRIPTION_H #define USUBSCRIPTION_H -#include "RpcClientUSubscription.h" +#include namespace uprotocol::core::usubscription::v3 { diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 999e584f4..f7d04e399 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -1,18 +1,67 @@ -// -// Created by max on 28.04.25. -// - #include "up-cpp/client/usubscription/v3/RpcClientUSubscription.h" +#include +#include namespace uprotocol::core::usubscription::v3 { using Payload = datamodel::builder::Payload; - SubscriptionResponse RpcClientUSubscription::subscribe( - const SubscriptionRequest& subscription_request) { - Payload test_test(subscription_request); - auto invoke_handle = client_->invokeMethod(test_test, //TODO(max)); - return SubscriptionResponse(); - } +void RpcClientUSubscription::Subscribe( + google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::SubscriptionRequest* request, + ::uprotocol::core::usubscription::v3::SubscriptionResponse* response, + ::google::protobuf::Closure* done) { + + constexpr uint16_t RESOURCE_ID_SUBSCRIBE = 0x0001; + // TODO(lennart): needs to be set + v1::UPriority priority; + std::chrono::milliseconds subscription_request_ttl; + + if ((request == nullptr) || (response == nullptr) || (done == nullptr)) { + controller->SetFailed("Invalid input parameters"); + done->Run(); + return; + } + + rpc_client_ = std::make_unique( + transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_SUBSCRIBE), + priority, subscription_request_ttl); + + auto on_response = [this, response](const auto& maybe_response) { + if (maybe_response.has_value() && + maybe_response.value().has_payload()) { + if (response->ParseFromString(maybe_response.value().payload())) { + if (response->topic().SerializeAsString() == + subscription_topic_.SerializeAsString()) { + subscription_response_ = *response; + } + } + } + }; + + try { + auto payload = datamodel::builder::Payload(request); + + rpc_handle_ = rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + + if (static_cast(rpc_handle_.isConnected()) == v1::OK) { // TODO(lennart): check if this is correct + response->CopyFrom(rpc_handle_.value); // Copy data to the response + } else { + controller->SetFailed("RPC call failed"); + } + + } catch (const std::exception& e) { + controller->SetFailed(std::string("Exception during Subscribe: ") + e.what()); + } + + done->Run(); +} - } // namespace uprotocol::core::usubscription::v3 +// Backup + // SubscriptionResponse RpcClientUSubscription::subscribe( + // const SubscriptionRequest& subscription_request) { + // Payload test_test(subscription_request); + // auto invoke_handle = client_->invokeMethod(test_test, //TODO(max)); + // return SubscriptionResponse(); + // } +} // namespace uprotocol::core::usubscription::v3 From a25c42f49048d234712b7c23d14ff3fbf4e6e18d Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Tue, 29 Apr 2025 16:31:01 +0200 Subject: [PATCH 016/105] Update RpcLientUSubscription --- src/client/usubscription/v3/RpcClientUSubscription.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index f7d04e399..01486ff09 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -43,6 +43,9 @@ void RpcClientUSubscription::Subscribe( rpc_handle_ = rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + auto result = communication::Subscriber::subscribe( + transport_, subscription_topic_, std::move(callback)); // TODO(lennart) callback? + if (static_cast(rpc_handle_.isConnected()) == v1::OK) { // TODO(lennart): check if this is correct response->CopyFrom(rpc_handle_.value); // Copy data to the response } else { From 278f77ace6c55b6e509a5f80fb01ee48484e0cfb Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Wed, 30 Apr 2025 12:15:49 +0200 Subject: [PATCH 017/105] before using Consumer --- src/client/usubscription/v3/RpcClientUSubscription.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 01486ff09..dca072b15 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -39,7 +39,7 @@ void RpcClientUSubscription::Subscribe( }; try { - auto payload = datamodel::builder::Payload(request); + auto payload = datamodel::builder::Payload(*request); rpc_handle_ = rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); From 5ff8a54091ada45f33df30b25a09f3c06e42390f Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Wed, 30 Apr 2025 16:27:24 +0200 Subject: [PATCH 018/105] Building without error. Test and check if functionality is correct. --- .../usubscription/v3/RpcClientUSubscription.h | 253 +++++++++++++----- .../v3/RpcClientUSubscription.cpp | 198 +++++++++++--- 2 files changed, 352 insertions(+), 99 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index d351dd3fa..399dc674c 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -1,89 +1,218 @@ +// SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef RPCCLIENTUSUBSCRIPTION_H #define RPCCLIENTUSUBSCRIPTION_H +#include +#include +#include +#include +#include #include -#include "Consumer.h" +#include -// #include "USubscription.h" -#include "up-cpp/communication/RpcClient.h" +#include namespace uprotocol::core::usubscription::v3 { +using uprotocol::core::usubscription::v3::SubscriptionRequest; +using uprotocol::core::usubscription::v3::UnsubscribeRequest; +using uprotocol::core::usubscription::v3::Update; +using uprotocol::core::usubscription::v3::uSubscription; + +/** + * @struct RpcClientUSubscriptionOptions + * @brief Additional details for uSubscription service. + * + * Each member represents an optional parameter for the uSubscription service. + */ +struct RpcClientUSubscriptionOptions { + /// Permission level of the subscription request + std::optional permission_level; + /// TAP token for access. + std::optional token; + /// Expiration time of the subscription. + std::optional when_expire; + /// Sample period for the subscription messages in milliseconds. + std::optional sample_period_ms; + /// Details of the subscriber. + std::optional subscriber_details; + /// Details of the subscription. + std::optional subscription_details; +}; -struct RpcClientUSubscription : public uSubscription { -public: - RpcClientUSubscription() = default; - ~RpcClientUSubscription() override = default; - - explicit RpcClientUSubscription(std::unique_ptr rpc_client) - : rpc_client_(std::move(rpc_client)){}; +/// @struct uSubscriptionUUriBuilder +/// @brief Structure to build uSubscription request URIs. +/// +/// This structure is used to build URIs for uSubscription service. It uses the +/// service options from uSubscription proto to set the authority name, ue_id, +/// ue_version_major, and the notification topic resource ID in the URI. +struct USubscriptionUUriBuilder { +private: + /// URI for the uSubscription service + v1::UUri uri_; + /// Resource ID of the notification topic + uint32_t sink_resource_id_; - - void Subscribe(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::SubscriptionRequest* request, - ::uprotocol::core::usubscription::v3::SubscriptionResponse* response, - ::google::protobuf::Closure* done) override; +public: + /// @brief Constructor for USubscriptionUUriBuilder. + USubscriptionUUriBuilder() { + // Get the service descriptor + const google::protobuf::ServiceDescriptor* service = + uSubscription::descriptor(); + const auto& service_options = service->options(); + + // Get the service options + const auto& service_name = + service_options.GetExtension(uprotocol::service_name); + const auto& service_version_major = + service_options.GetExtension(uprotocol::service_version_major); + const auto& service_id = + service_options.GetExtension(uprotocol::service_id); + const auto& notification_topic = + service_options.GetExtension(uprotocol::notification_topic, 0); + + // Set the values in the URI + uri_.set_authority_name(service_name); + uri_.set_ue_id(service_id); + uri_.set_ue_version_major(service_version_major); + sink_resource_id_ = notification_topic.id(); + } + + /// @brief Get the URI with a specific resource ID. + /// + /// @param resource_id The resource ID to set in the URI. + /// + /// @return The URI with the specified resource ID. + v1::UUri getServiceUriWithResourceId(uint32_t resource_id) const { + v1::UUri uri = uri_; // Copy the base URI + uri.set_resource_id(resource_id); + return uri; + } + + /// @brief Get the notification URI. + /// + /// @return The notification URI. + v1::UUri getNotificationUri() const { + v1::UUri uri = uri_; // Copy the base URI + uri.set_resource_id(sink_resource_id_); + return uri; + } +}; +/// @brief Interface for uEntities to create subscriptions. +/// +/// Like all L3 client APIs, the RpcClientUSubscription is a wrapper on top of the +/// L2 Communication APIs and USubscription service. +struct RpcClientUSubscription : public uSubscription{ + using RpcClientUSubscriptionOrStatus = + utils::Expected, v1::UStatus>; + using ListenCallback = transport::UTransport::ListenCallback; + using ListenHandle = transport::UTransport::ListenHandle; + using SubscriptionResponse = core::usubscription::v3::SubscriptionResponse; + + /// @brief Create a subscription + /// + /// @param transport Transport to register with. + /// @param subscription_topic Topic to subscribe to. + /// @param callback Function that is called when publish message is + /// received. + /// @param priority Priority of the subscription request. + /// @param subscribe_request_ttl Time to live for the subscription request. + /// @param rpc_client_usubscription_options Additional details for uSubscription service. + // [[nodiscard]] static RpcClientUSubscriptionOrStatus create( + // std::shared_ptr transport, + // const v1::UUri& subscription_topic, ListenCallback&& callback, + // v1::UPriority priority, + // std::chrono::milliseconds subscription_request_ttl, + // RpcClientUSubscriptionOptions rpc_client_usubscription_options); + + /// @brief Unsubscribe from the topic and call uSubscription service to + /// close the subscription. void Unsubscribe(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::UnsubscribeRequest* request, - ::uprotocol::core::usubscription::v3::UnsubscribeResponse* response, - ::google::protobuf::Closure* done) override; - - void FetchSubscriptions(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::FetchSubscriptionsRequest* request, - ::uprotocol::core::usubscription::v3::FetchSubscriptionsResponse* response, - ::google::protobuf::Closure* done) override; + const ::uprotocol::core::usubscription::v3::UnsubscribeRequest* request, + ::uprotocol::core::usubscription::v3::UnsubscribeResponse* response, + ::google::protobuf::Closure* done) override; - void RegisterForNotifications(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, - ::uprotocol::core::usubscription::v3::NotificationsResponse* response, - ::google::protobuf::Closure* done) override; + /// @brief getter for subscription update + /// + /// @return subscription update + Update getSubscriptionUpdate() const { return subscription_update_; } - void UnregisterForNotifications(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, - ::uprotocol::core::usubscription::v3::NotificationsResponse* response, - ::google::protobuf::Closure* done) override; + /// @brief Destructor + ~RpcClientUSubscription() = default; - void FetchSubscribers(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::FetchSubscribersRequest* request, - ::uprotocol::core::usubscription::v3::FetchSubscribersResponse* response, - ::google::protobuf::Closure* done) override; + /// This section for test code only delete later - void Reset(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::ResetRequest* request, - ::uprotocol::core::usubscription::v3::ResetResponse* response, - ::google::protobuf::Closure* done) override; +protected: + /// @brief Constructor + /// + /// @param transport Transport to register with. + /// @param subscriber_details Additional details about the subscriber. + RpcClientUSubscription(std::shared_ptr transport, + v1::UUri subscription_topic, + RpcClientUSubscriptionOptions rpc_client_usubscription_options = {}); -// Backup - void default_call_option(); - - // SubscriptionResponse subscribe(const SubscriptionRequest& subscription_request); - - // UnsubscribeResponse unsubscribe(const UnsubscribeRequest& unsubscribe_request); - - // FetchSubscriptionsResponse fetch_subscriptions(const FetchSubscriptionsRequest& fetch_subscribers_request); +private: + // Transport + std::shared_ptr transport_; - // NotificationsResponse register_for_notifications(const NotificationsRequest& register_notifications_request); + // Topic to subscribe to + const v1::UUri subscription_topic_; + // Additional details about uSubscription service + RpcClientUSubscriptionOptions rpc_client_usubscription_options_; - // NotificationsResponse unregister_for_notifications(const NotificationsRequest& unregister_notifications_request); + // URI info about the uSubscription service + USubscriptionUUriBuilder uSubscriptionUUriBuilder_; - // FetchSubscribersResponse fetch_subscribers(const FetchSubscribersRequest& fetch_subscribers_request); + // Subscription updates + std::unique_ptr noficationSinkHandle_; + Update subscription_update_; -private: // RPC request std::unique_ptr rpc_client_; communication::RpcClient::InvokeHandle rpc_handle_; SubscriptionResponse subscription_response_; - - // Transport - std::shared_ptr transport_; - - // URI info about the uSubscription service - client::usubscription::v3::USubscriptionUUriBuilder uSubscriptionUUriBuilder_; - - // Topic to subscribe to - const v1::UUri subscription_topic_; + UnsubscribeResponse unsubscribe_response_; + + // L2 Subscriber details + std::unique_ptr subscriber_; + + // Allow the protected constructor for this class to be used in make_unique + // inside of create() + friend std::unique_ptr + std::make_unique, + const uprotocol::v1::UUri, + uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions>( + std::shared_ptr&&, + const uprotocol::v1::UUri&&, + uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions&&); + + /// @brief Build SubscriptionRequest for subscription request + SubscriptionRequest buildSubscriptionRequest(); + + /// @brief Build UnsubscriptionRequest for unsubscription request + UnsubscribeRequest buildUnsubscriptionRequest(); + + /// @brief Create a notification sink to receive subscription updates + v1::UStatus createNotificationSink(); + + /// @brief Subscribe to the topic + /// + void Subscribe(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::SubscriptionRequest* request, + ::uprotocol::core::usubscription::v3::SubscriptionResponse* response, + ::google::protobuf::Closure* done) override; }; -} // namespace uprotocol::core::usubscription::v3 +} // namespace uprotocol::core::usubscription::v3 -#endif //RPCCLIENTUSUBSCRIPTION_H +#endif // RPCCLIENTUSUBSCRIPTION_H \ No newline at end of file diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index dca072b15..24ed9a6ad 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -1,9 +1,97 @@ -#include "up-cpp/client/usubscription/v3/RpcClientUSubscription.h" -#include -#include +// SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: Apache-2.0 + +#include +#include + +#include namespace uprotocol::core::usubscription::v3 { - using Payload = datamodel::builder::Payload; + +void someCallBack(const uprotocol::v1::UMessage& message) { + // Print the message + std::cout << message.DebugString() << std::endl; +} + +RpcClientUSubscription::RpcClientUSubscription(std::shared_ptr transport, + v1::UUri subscription_topic, + RpcClientUSubscriptionOptions rpc_client_usubscription_options) + : transport_(std::move(transport)), + subscription_topic_(std::move(subscription_topic)), + rpc_client_usubscription_options_(std::move(rpc_client_usubscription_options)), + rpc_client_(nullptr) { + // Initialize uSubscriptionUUriBuilder_ + uSubscriptionUUriBuilder_ = USubscriptionUUriBuilder(); +} + +// [[nodiscard]] RpcClientUSubscription::RpcClientUSubscriptionOrStatus RpcClientUSubscription::create( +// std::shared_ptr transport, +// const v1::UUri& subscription_topic, ListenCallback&& callback, +// v1::UPriority priority, std::chrono::milliseconds subscription_request_ttl, +// RpcClientUSubscriptionOptions rpc_client_usubscription_options) { +// auto rpc_client_usubscription = std::make_unique( +// std::forward>(transport), +// std::forward(subscription_topic), +// std::forward(rpc_client_usubscription_options)); + +// // Attempt to connect create notification sink for updates. +// auto status = rpc_client_usubscription->createNotificationSink(); +// if (status.code() == v1::UCode::OK) { +// status = rpc_client_usubscription->subscribe(priority, subscription_request_ttl, +// std::move(callback)); +// if (status.code() == v1::UCode::OK) { +// return RpcClientUSubscriptionOrStatus(std::move(rpc_client_usubscription)); +// } +// return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); +// } +// // If connection fails, return the error status. +// return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); +// } + +v1::UStatus RpcClientUSubscription::createNotificationSink() { + auto notification_sink_callback = [this](const v1::UMessage& update) { + if (update.has_payload()) { + Update data; + if (data.ParseFromString(update.payload())) { + if (data.topic().SerializeAsString() == + subscription_topic_.SerializeAsString()) { + subscription_update_ = std::move(data); + } + } + } + }; + + auto notification_topic = uSubscriptionUUriBuilder_.getNotificationUri(); + + auto result = communication::NotificationSink::create( + transport_, std::move(notification_sink_callback), notification_topic); + + if (result.has_value()) { + noficationSinkHandle_ = std::move(result).value(); + v1::UStatus status; + status.set_code(v1::UCode::OK); + return status; + } + return result.error(); +} + +SubscriptionRequest RpcClientUSubscription::buildSubscriptionRequest() { + auto attributes = utils::ProtoConverter::BuildSubscribeAttributes( + rpc_client_usubscription_options_.when_expire, rpc_client_usubscription_options_.subscription_details, + rpc_client_usubscription_options_.sample_period_ms); + + auto subscription_request = utils::ProtoConverter::BuildSubscriptionRequest( + subscription_topic_, attributes); + return subscription_request; +} void RpcClientUSubscription::Subscribe( google::protobuf::RpcController* controller, @@ -12,59 +100,95 @@ void RpcClientUSubscription::Subscribe( ::google::protobuf::Closure* done) { constexpr uint16_t RESOURCE_ID_SUBSCRIBE = 0x0001; - // TODO(lennart): needs to be set - v1::UPriority priority; - std::chrono::milliseconds subscription_request_ttl; + constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? + auto subscription_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); + auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; // TODO(lennart) priority + + auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); - if ((request == nullptr) || (response == nullptr) || (done == nullptr)) { - controller->SetFailed("Invalid input parameters"); - done->Run(); - return; - } rpc_client_ = std::make_unique( transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_SUBSCRIBE), priority, subscription_request_ttl); - + auto on_response = [this, response](const auto& maybe_response) { if (maybe_response.has_value() && - maybe_response.value().has_payload()) { + maybe_response.value().has_payload()) { if (response->ParseFromString(maybe_response.value().payload())) { if (response->topic().SerializeAsString() == - subscription_topic_.SerializeAsString()) { + subscription_topic_.SerializeAsString()) { subscription_response_ = *response; } } } }; - try { - auto payload = datamodel::builder::Payload(*request); + // SubscriptionRequest const subscription_request = buildSubscriptionRequest(); + auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct, has been subscription_request before - rpc_handle_ = rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + rpc_handle_ = + rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - auto result = communication::Subscriber::subscribe( - transport_, subscription_topic_, std::move(callback)); // TODO(lennart) callback? + // response->CopyFrom(rpc_handle_.value); - if (static_cast(rpc_handle_.isConnected()) == v1::OK) { // TODO(lennart): check if this is correct - response->CopyFrom(rpc_handle_.value); // Copy data to the response - } else { - controller->SetFailed("RPC call failed"); - } - - } catch (const std::exception& e) { - controller->SetFailed(std::string("Exception during Subscribe: ") + e.what()); - } + auto subscription_callback = someCallBack; + // Create a L2 subscription + auto result = communication::Subscriber::subscribe( + transport_, subscription_topic_, std::move(subscription_callback)); + if (result.has_value()) { + subscriber_ = std::move(result).value(); + v1::UStatus status; + status.set_code(v1::UCode::OK); + // return status; + done->Run(); + } + controller->SetFailed("result.error()"); done->Run(); } -// Backup - // SubscriptionResponse RpcClientUSubscription::subscribe( - // const SubscriptionRequest& subscription_request) { - // Payload test_test(subscription_request); - // auto invoke_handle = client_->invokeMethod(test_test, //TODO(max)); - // return SubscriptionResponse(); - // } +UnsubscribeRequest RpcClientUSubscription::buildUnsubscriptionRequest() { + auto unsubscribe_request = + utils::ProtoConverter::BuildUnSubscribeRequest(subscription_topic_); + return unsubscribe_request; +} + +void RpcClientUSubscription::Unsubscribe( + google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::UnsubscribeRequest* request, + ::uprotocol::core::usubscription::v3::UnsubscribeResponse* response, + ::google::protobuf::Closure* done) { + + constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? + constexpr uint16_t RESOURCE_ID_UNSUBSCRIBE = 0x0002; + auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); + auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; // TODO(lennart) priority + + rpc_client_ = std::make_unique( + transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_UNSUBSCRIBE), + priority, request_ttl); + + auto on_response = [this, response](const auto& maybe_response) { + if (maybe_response.has_value() && + maybe_response.value().has_payload()) { + if (response->ParseFromString(maybe_response.value().payload())) { + // if (response->topic().SerializeAsString() == // TODO(lennart) see if this check is somehow possible + // subscription_topic_.SerializeAsString()) { + unsubscribe_response_ = *response; + // } + } + } + }; + + // UnsubscribeRequest const unsubscribe_request = buildUnsubscriptionRequest(); + auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct, has been subscription_request before + + rpc_handle_ = + rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + + subscriber_.reset(); + + done->Run(); +} -} // namespace uprotocol::core::usubscription::v3 +} // namespace uprotocol::core::usubscription::v3 From fc89075cc87540e6897b948f0a9bbdcf912f7d5b Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Fri, 2 May 2025 13:15:09 +0200 Subject: [PATCH 019/105] Added comment --- src/client/usubscription/v3/RpcClientUSubscription.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 24ed9a6ad..b3492ad11 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -131,7 +131,7 @@ void RpcClientUSubscription::Subscribe( // response->CopyFrom(rpc_handle_.value); - auto subscription_callback = someCallBack; + auto subscription_callback = someCallBack; // TODO(lennart) update with correct callback // Create a L2 subscription auto result = communication::Subscriber::subscribe( transport_, subscription_topic_, std::move(subscription_callback)); @@ -143,7 +143,9 @@ void RpcClientUSubscription::Subscribe( // return status; done->Run(); } + controller->SetFailed("result.error()"); + done->Run(); } From 7ac2441a0c000ab09b1638a08e4d77f7799c415f Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Fri, 2 May 2025 16:51:25 +0200 Subject: [PATCH 020/105] =?UTF-8?q?Done=20for=20today.=20No=20major=20chan?= =?UTF-8?q?ges.=20Waiting=20for=20Pete=C2=B4s=20answer.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/usubscription/v3/RpcClientUSubscription.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index b3492ad11..a38cc6e0d 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -10,6 +10,7 @@ // SPDX-License-Identifier: Apache-2.0 #include +#include #include #include @@ -100,11 +101,12 @@ void RpcClientUSubscription::Subscribe( ::google::protobuf::Closure* done) { constexpr uint16_t RESOURCE_ID_SUBSCRIBE = 0x0001; + // TODO(lennart) see default_call_options() for the request in Rust constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? auto subscription_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; // TODO(lennart) priority - auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); + auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); // Might serve as default_call_options() in Rust rpc_client_ = std::make_unique( From 9329928cfc4e369ecf25a435d3c582628eaa60ce Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Mon, 5 May 2025 11:32:07 +0200 Subject: [PATCH 021/105] Added missing methods for RpcClientUSubscription --- .../usubscription/v3/RpcClientUSubscription.h | 31 +++- .../v3/RpcClientUSubscription.cpp | 169 ++++++++++++++++-- 2 files changed, 189 insertions(+), 11 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index 399dc674c..6e3fedef7 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -117,7 +117,6 @@ struct RpcClientUSubscription : public uSubscription{ utils::Expected, v1::UStatus>; using ListenCallback = transport::UTransport::ListenCallback; using ListenHandle = transport::UTransport::ListenHandle; - using SubscriptionResponse = core::usubscription::v3::SubscriptionResponse; /// @brief Create a subscription /// @@ -141,6 +140,32 @@ struct RpcClientUSubscription : public uSubscription{ const ::uprotocol::core::usubscription::v3::UnsubscribeRequest* request, ::uprotocol::core::usubscription::v3::UnsubscribeResponse* response, ::google::protobuf::Closure* done) override; + + /// @brief Fetch all subscriptions for a given topic or subscriber contained inside a [`FetchSubscriptionsRequest`] + void FetchSubscriptions(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::FetchSubscriptionsRequest* request, + ::uprotocol::core::usubscription::v3::FetchSubscriptionsResponse* response, + ::google::protobuf::Closure* done) override; + + /// @brief Register for notifications relevant to a given topic inside a [`NotificationsRequest`] + /// changing in subscription status. + void RegisterForNotifications(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, + ::uprotocol::core::usubscription::v3::NotificationsResponse* response, + ::google::protobuf::Closure* done) override; + + /// @brief Unregister for notifications relevant to a given topic inside a [`NotificationsRequest`] + /// changing in subscription status. + void UnregisterForNotifications(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, + ::uprotocol::core::usubscription::v3::NotificationsResponse* response, + ::google::protobuf::Closure* done) override; + + /// @brief Fetch a list of subscribers that are currently subscribed to a given topic in a [`FetchSubscribersRequest`] + void FetchSubscribers(google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::FetchSubscribersRequest* request, + ::uprotocol::core::usubscription::v3::FetchSubscribersResponse* response, + ::google::protobuf::Closure* done) override; /// @brief getter for subscription update /// @@ -180,8 +205,12 @@ struct RpcClientUSubscription : public uSubscription{ // RPC request std::unique_ptr rpc_client_; communication::RpcClient::InvokeHandle rpc_handle_; + SubscriptionResponse subscription_response_; UnsubscribeResponse unsubscribe_response_; + FetchSubscriptionsResponse fetch_subscription_response_; + NotificationsResponse notification_response_; + FetchSubscribersResponse fetch_subscribers_response_; // L2 Subscriber details std::unique_ptr subscriber_; diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index a38cc6e0d..2aa45f073 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -104,7 +104,7 @@ void RpcClientUSubscription::Subscribe( // TODO(lennart) see default_call_options() for the request in Rust constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? auto subscription_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; // TODO(lennart) priority + auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); // Might serve as default_call_options() in Rust @@ -129,9 +129,7 @@ void RpcClientUSubscription::Subscribe( auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct, has been subscription_request before rpc_handle_ = - rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - - // response->CopyFrom(rpc_handle_.value); + rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); auto subscription_callback = someCallBack; // TODO(lennart) update with correct callback // Create a L2 subscription @@ -166,7 +164,7 @@ void RpcClientUSubscription::Unsubscribe( constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? constexpr uint16_t RESOURCE_ID_UNSUBSCRIBE = 0x0002; auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; // TODO(lennart) priority + auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; rpc_client_ = std::make_unique( transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_UNSUBSCRIBE), @@ -176,17 +174,16 @@ void RpcClientUSubscription::Unsubscribe( if (maybe_response.has_value() && maybe_response.value().has_payload()) { if (response->ParseFromString(maybe_response.value().payload())) { - // if (response->topic().SerializeAsString() == // TODO(lennart) see if this check is somehow possible - // subscription_topic_.SerializeAsString()) { + if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe + subscription_topic_.SerializeAsString()) { unsubscribe_response_ = *response; - // } + } } } }; // UnsubscribeRequest const unsubscribe_request = buildUnsubscriptionRequest(); - auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct, has been subscription_request before - + auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct rpc_handle_ = rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); @@ -195,4 +192,156 @@ void RpcClientUSubscription::Unsubscribe( done->Run(); } +void RpcClientUSubscription::FetchSubscriptions( + google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::FetchSubscriptionsRequest* request, + ::uprotocol::core::usubscription::v3::FetchSubscriptionsResponse* response, + ::google::protobuf::Closure* done) { + + constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? + constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIPTIONS = 0x0003; + auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); + auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; + + rpc_client_ = std::make_unique( + transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_FETCH_SUBSCRIPTIONS), + priority, request_ttl); + + auto on_response = [this, response](const auto& maybe_response) { + if (maybe_response.has_value() && + maybe_response.value().has_payload()) { + if (response->ParseFromString(maybe_response.value().payload())) { + if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe + subscription_topic_.SerializeAsString()) { + fetch_subscription_response_ = *response; + } + } + } + }; + + // FetchSubscriptionsRequest const fetch_subscriptions_request = buildFetchSubscriptionsRequest(); + auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct + + rpc_handle_ = + rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + + // TODO(lennart) any handle for the response? + + done->Run(); +} + +void RpcClientUSubscription::RegisterForNotifications( + google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, + ::uprotocol::core::usubscription::v3::NotificationsResponse* response, + ::google::protobuf::Closure* done) { + + constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? + constexpr uint16_t RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS = 0x0006; + auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); + auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; + + rpc_client_ = std::make_unique( + transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS), + priority, request_ttl); + + auto on_response = [this, response](const auto& maybe_response) { + if (maybe_response.has_value() && + maybe_response.value().has_payload()) { + if (response->ParseFromString(maybe_response.value().payload())) { + if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe + subscription_topic_.SerializeAsString()) { + notification_response_ = *response; + } + } + } + }; + + // NotificationsRequest const register_notifications_request = buildRegisterNotificationsRequest(); + auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct + + rpc_handle_ = + rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + + // TODO(lennart) any handle for the response? + + done->Run(); +} + +void RpcClientUSubscription::UnregisterForNotifications( + google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, + ::uprotocol::core::usubscription::v3::NotificationsResponse* response, + ::google::protobuf::Closure* done) { + + constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? + constexpr uint16_t RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS = 0x0007; + auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); + auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; + + rpc_client_ = std::make_unique( + transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS), + priority, request_ttl); + + auto on_response = [this, response](const auto& maybe_response) { + if (maybe_response.has_value() && + maybe_response.value().has_payload()) { + if (response->ParseFromString(maybe_response.value().payload())) { + if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe + subscription_topic_.SerializeAsString()) { + notification_response_ = *response; + } + } + } + }; + + // NotificationsRequest const unregister_notifications_request = buildUnregisterNotificationsRequest(); + auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct + + rpc_handle_ = + rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + + // TODO(lennart) any handle for the response? + + done->Run(); +} + +void RpcClientUSubscription::FetchSubscribers( + google::protobuf::RpcController* controller, + const ::uprotocol::core::usubscription::v3::FetchSubscribersRequest* request, + ::uprotocol::core::usubscription::v3::FetchSubscribersResponse* response, + ::google::protobuf::Closure* done) { + + constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? + constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIBERS = 0x0008; + auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); + auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; + + rpc_client_ = std::make_unique( + transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_FETCH_SUBSCRIBERS), + priority, request_ttl); + + auto on_response = [this, response](const auto& maybe_response) { + if (maybe_response.has_value() && + maybe_response.value().has_payload()) { + if (response->ParseFromString(maybe_response.value().payload())) { + if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe + subscription_topic_.SerializeAsString()) { + fetch_subscribers_response_ = *response; + } + } + } + }; + + // FetchSubscribersRequest const fetch_subscribers_request = buildFetchSubscribersRequest(); + auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct + + rpc_handle_ = + rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + + // TODO(lennart) any handle for the response? + + done->Run(); +} + } // namespace uprotocol::core::usubscription::v3 From 80a2c594c7ac0d665e4456f6c1c70f7cfada4e12 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Mon, 5 May 2025 12:52:45 +0200 Subject: [PATCH 022/105] Readded create-Method in RpcClientUSubscription. Created first MockTest --- .../usubscription/v3/RpcClientUSubscription.h | 10 ++-- .../v3/RpcClientUSubscription.cpp | 51 ++++++++++--------- test/CMakeLists.txt | 3 ++ 3 files changed, 34 insertions(+), 30 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index 6e3fedef7..af3052c4b 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -127,12 +127,10 @@ struct RpcClientUSubscription : public uSubscription{ /// @param priority Priority of the subscription request. /// @param subscribe_request_ttl Time to live for the subscription request. /// @param rpc_client_usubscription_options Additional details for uSubscription service. - // [[nodiscard]] static RpcClientUSubscriptionOrStatus create( - // std::shared_ptr transport, - // const v1::UUri& subscription_topic, ListenCallback&& callback, - // v1::UPriority priority, - // std::chrono::milliseconds subscription_request_ttl, - // RpcClientUSubscriptionOptions rpc_client_usubscription_options); + [[nodiscard]] static RpcClientUSubscriptionOrStatus create( + std::shared_ptr transport, + const v1::UUri& subscription_topic, ListenCallback&& callback, + RpcClientUSubscriptionOptions rpc_client_usubscription_options); /// @brief Unsubscribe from the topic and call uSubscription service to /// close the subscription. diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 2aa45f073..abc325bf5 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -33,29 +33,32 @@ RpcClientUSubscription::RpcClientUSubscription(std::shared_ptr transport, -// const v1::UUri& subscription_topic, ListenCallback&& callback, -// v1::UPriority priority, std::chrono::milliseconds subscription_request_ttl, -// RpcClientUSubscriptionOptions rpc_client_usubscription_options) { -// auto rpc_client_usubscription = std::make_unique( -// std::forward>(transport), -// std::forward(subscription_topic), -// std::forward(rpc_client_usubscription_options)); - -// // Attempt to connect create notification sink for updates. -// auto status = rpc_client_usubscription->createNotificationSink(); -// if (status.code() == v1::UCode::OK) { -// status = rpc_client_usubscription->subscribe(priority, subscription_request_ttl, -// std::move(callback)); -// if (status.code() == v1::UCode::OK) { -// return RpcClientUSubscriptionOrStatus(std::move(rpc_client_usubscription)); -// } -// return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); -// } -// // If connection fails, return the error status. -// return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); -// } +[[nodiscard]] RpcClientUSubscription::RpcClientUSubscriptionOrStatus RpcClientUSubscription::create( + std::shared_ptr transport, + const v1::UUri& subscription_topic, ListenCallback&& callback, + RpcClientUSubscriptionOptions rpc_client_usubscription_options) { + auto rpc_client_usubscription = std::make_unique( + std::forward>(transport), + std::forward(subscription_topic), + std::forward(rpc_client_usubscription_options)); + + google::protobuf::RpcController *controller = nullptr; + ::uprotocol::core::usubscription::v3::SubscriptionRequest const *subscription_request = nullptr; + SubscriptionResponse *subscription_response = nullptr; + + // Attempt to connect create notification sink for updates. + auto status = rpc_client_usubscription->createNotificationSink(); + if (status.code() == v1::UCode::OK) { + rpc_client_usubscription->Subscribe(controller, subscription_request, + subscription_response, nullptr); + if (status.code() == v1::UCode::OK) { + return RpcClientUSubscriptionOrStatus(std::move(rpc_client_usubscription)); + } + return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); + } + // If connection fails, return the error status. + return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); +} v1::UStatus RpcClientUSubscription::createNotificationSink() { auto notification_sink_callback = [this](const v1::UMessage& update) { @@ -332,7 +335,7 @@ void RpcClientUSubscription::FetchSubscribers( } } }; - + // FetchSubscribersRequest const fetch_subscribers_request = buildFetchSubscribersRequest(); auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bd7e6d67f..56c122710 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -84,6 +84,9 @@ add_coverage_test("NotificationSourceTest" coverage/communication/NotificationSo # client add_coverage_test("ConsumerTest" coverage/client/usubscription/v3/ConsumerTest.cpp) +# core +add_coverage_test("RpcClientUSubscriptionTest" coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp) + ########################## EXTRAS ############################################# add_extra_test("PublisherSubscriberTest" extra/PublisherSubscriberTest.cpp) add_extra_test("NotificationTest" extra/NotificationTest.cpp) From 7e97be277bf8ecb333f93edfe9ebe00184b5a429 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Mon, 5 May 2025 12:53:27 +0200 Subject: [PATCH 023/105] Readded create-Method in RpcClientUSubscription. Created first MockTest --- .../v3/RpcClientUSubscriptionTest.cpp | 223 ++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp new file mode 100644 index 000000000..8ed25476f --- /dev/null +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -0,0 +1,223 @@ +// SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include + +#include + +#include "UTransportMock.h" + +namespace { +using MsgDiff = google::protobuf::util::MessageDifferencer; + +void someCallBack(const uprotocol::v1::UMessage& message) { + // Print the message + std::cout << message.DebugString() << std::endl; +} + +class RpcClientUSubscriptionTest : public testing::Test { +private: + std::shared_ptr mockTransportClient_; + std::shared_ptr mockTransportServer_; + uprotocol::v1::UUri client_uuri; + uprotocol::v1::UUri server_uuri; + uprotocol::v1::UUri subscription_uuri; + +protected: + // Run once per TEST_F. + // Used to set up clean environments per test. + + std::shared_ptr getMockTransportClient() + const { + return mockTransportClient_; + } + std::shared_ptr getMockTransportServer() + const { + return mockTransportServer_; + } + uprotocol::v1::UUri& getClientUUri() { return client_uuri; } + const uprotocol::v1::UUri& getServerUUri() const { return server_uuri; } + const uprotocol::v1::UUri& getSubscriptionUUri() const { + return subscription_uuri; + } + + void SetUp() override { + constexpr uint32_t TEST_UE_ID = 0x18000; + constexpr uint32_t DEFAULT_RESOURCE_ID = 0x8000; + // Create a generic transport uri + client_uuri.set_authority_name("random_string"); + client_uuri.set_ue_id(TEST_UE_ID); + client_uuri.set_ue_version_major(3); + client_uuri.set_resource_id(0); + + // Set up a transport + mockTransportClient_ = + std::make_shared(client_uuri); + + // Craete server default uri and set up a transport + server_uuri.set_authority_name("core.usubscription"); + server_uuri.set_ue_id(0); + server_uuri.set_ue_version_major(3); + server_uuri.set_resource_id(0); + + mockTransportServer_ = + std::make_shared(server_uuri); + + // Create a generic subscription uri + subscription_uuri.set_authority_name("10.0.0.2"); + subscription_uuri.set_ue_id(TEST_UE_ID); + subscription_uuri.set_ue_version_major(3); + subscription_uuri.set_resource_id(DEFAULT_RESOURCE_ID); + }; + void TearDown() override {} + + // Run once per execution of the test application. + // Used for setup of all tests. Has access to this instance. + RpcClientUSubscriptionTest() = default; + + void buildDefaultSourceURI(); + void buildValidNotificationURI(); + void buildInValidNotificationURI(); + + // Run once per execution of the test application. + // Used only for global setup outside of tests. + static void SetUpTestSuite() {} + static void TearDownTestSuite() {} + +public: + ~RpcClientUSubscriptionTest() override = default; +}; + +// Negative test case with no source filter +TEST_F(RpcClientUSubscriptionTest, ConstructorTestSuccess) { // NOLINT + // constexpr int REQUEST_TTL_TIME = 0x8000; + auto subscription_callback = someCallBack; + // auto subscribe_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); + // auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; + + auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); + + auto rpc_client_usubscription_or_status = + uprotocol::core::usubscription::v3::RpcClientUSubscription::create( + getMockTransportClient(), getSubscriptionUUri(), + subscription_callback, options); + + // Ensure that the rpc_client_usubscription creation was successful + ASSERT_TRUE(rpc_client_usubscription_or_status.has_value()); + + // Obtain a pointer to the created rpc_client_usubscription instance + const auto& rpc_client_usubscription_ptr = rpc_client_usubscription_or_status.value(); + + // Verify that the rpc_client_usubscription pointer is not null, indicating successful + // creation + ASSERT_NE(rpc_client_usubscription_ptr, nullptr); +} + +TEST_F(RpcClientUSubscriptionTest, SubscribeTestSuccess) { // NOLINT + constexpr uint32_t DEFAULT_RESOURCE_ID = 0x8000; + // constexpr int REQUEST_TTL_TIME = 0x8000; + auto subscription_callback = someCallBack; + // auto subscribe_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); + // auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; + + auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); + + auto rpc_client_usubscription_or_status = + uprotocol::core::usubscription::v3::RpcClientUSubscription::create( + getMockTransportClient(), getSubscriptionUUri(), + subscription_callback, options); + + // Ensure that the RpcClientUSubscription creation was successful + ASSERT_TRUE(rpc_client_usubscription_or_status.has_value()); + + // Obtain a pointer to the created rpc_client_usubscription instance + const auto& rpc_client_usubscription_ptr = rpc_client_usubscription_or_status.value(); + + // Verify that the rpc_client_usubscription pointer is not null, indicating successful + // creation + ASSERT_NE(rpc_client_usubscription_ptr, nullptr); + + // Create notification source sink uri to match resource id of sink + auto notification_uuri = getServerUUri(); + notification_uuri.set_resource_id(DEFAULT_RESOURCE_ID); + + // set format UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY + auto format = + uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY; + + auto notification_source = uprotocol::communication::NotificationSource( + getMockTransportServer(), std::move(notification_uuri), + std::move(getClientUUri()), format); + // Build payload + const std::string data = "test"; + auto payload = uprotocol::datamodel::builder::Payload(data, format); + + notification_source.notify(std::move(payload)); + + // Check send count + EXPECT_TRUE(getMockTransportServer()->getSendCount() == 1); + EXPECT_TRUE(getMockTransportClient()->getSendCount() == 1); +} + +TEST_F(RpcClientUSubscriptionTest, UnsubscribeTestSuccess) { // NOLINT + constexpr uint32_t DEFAULT_RESOURCE_ID = 0x8000; + // constexpr int REQUEST_TTL_TIME = 0x8000; + auto subscription_callback = someCallBack; + // auto subscribe_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); + // auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; + + auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); + + auto rpc_client_usubscription_or_status = + uprotocol::core::usubscription::v3::RpcClientUSubscription::create( + getMockTransportClient(), getSubscriptionUUri(), + subscription_callback, options); + + // Ensure that the rpc_client_usubscription creation was successful + ASSERT_TRUE(rpc_client_usubscription_or_status.has_value()); + + // Obtain a pointer to the created rpc_client_usubscription instance + const auto& rpc_client_usubscription_ptr = rpc_client_usubscription_or_status.value(); + + // Verify that the rpc_client_usubscription pointer is not null, indicating successful + // creation + ASSERT_NE(rpc_client_usubscription_ptr, nullptr); + + // Create notification source sink uri to match resource id of sink + auto notification_uuri = getServerUUri(); + notification_uuri.set_resource_id(DEFAULT_RESOURCE_ID); + + // set format UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY + auto format = + uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY; + + auto notification_source = uprotocol::communication::NotificationSource( + getMockTransportServer(), std::move(notification_uuri), + std::move(getClientUUri()), format); + // Build payload + const std::string data = "test"; + auto payload = uprotocol::datamodel::builder::Payload(data, format); + + notification_source.notify(std::move(payload)); + + // Check send count + EXPECT_TRUE(getMockTransportServer()->getSendCount() == 1); + EXPECT_TRUE(getMockTransportClient()->getSendCount() == 1); + + rpc_client_usubscription_ptr->Unsubscribe(nullptr, nullptr, nullptr, nullptr); + + EXPECT_TRUE(getMockTransportClient()->getSendCount() == 2); +} + +} // namespace From cb5d227a60c8a9a929064aaf33b65b040c48a2f1 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Mon, 5 May 2025 17:05:10 +0200 Subject: [PATCH 024/105] Updated minor things in RpcClientUSubscription. --- .../v3/RpcClientUSubscription.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index abc325bf5..91b38a544 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -17,11 +17,6 @@ namespace uprotocol::core::usubscription::v3 { -void someCallBack(const uprotocol::v1::UMessage& message) { - // Print the message - std::cout << message.DebugString() << std::endl; -} - RpcClientUSubscription::RpcClientUSubscription(std::shared_ptr transport, v1::UUri subscription_topic, RpcClientUSubscriptionOptions rpc_client_usubscription_options) @@ -51,7 +46,7 @@ RpcClientUSubscription::RpcClientUSubscription(std::shared_ptrSubscribe(controller, subscription_request, subscription_response, nullptr); - if (status.code() == v1::UCode::OK) { + if (controller == nullptr) { return RpcClientUSubscriptionOrStatus(std::move(rpc_client_usubscription)); } return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); @@ -109,8 +104,6 @@ void RpcClientUSubscription::Subscribe( auto subscription_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; - auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); // Might serve as default_call_options() in Rust - rpc_client_ = std::make_unique( transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_SUBSCRIBE), @@ -134,7 +127,10 @@ void RpcClientUSubscription::Subscribe( rpc_handle_ = rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - auto subscription_callback = someCallBack; // TODO(lennart) update with correct callback + // TODO(lennart) any handle for the response? + + // Question TODO(max): communication::Subscriber::subscribe(...) necessary? + auto subscription_callback = nullptr; // TODO(lennart) update with correct callback // Create a L2 subscription auto result = communication::Subscriber::subscribe( transport_, subscription_topic_, std::move(subscription_callback)); @@ -147,7 +143,7 @@ void RpcClientUSubscription::Subscribe( done->Run(); } - controller->SetFailed("result.error()"); + controller->SetFailed("result.error()"); // TODO(lennart) method needs to be implemented done->Run(); } @@ -190,6 +186,8 @@ void RpcClientUSubscription::Unsubscribe( rpc_handle_ = rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + // TODO(lennart) any handle for the response? + subscriber_.reset(); done->Run(); From 5fec55b07a982751b64fc0d0d469a29f1dbd04ed Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Thu, 8 May 2025 15:33:40 +0200 Subject: [PATCH 025/105] building first try of sending method --- .../usubscription/v3/RpcClientUSubscription.h | 109 ++-- .../client/usubscription/v3/USubscription.h | 18 +- .../v3/RpcClientUSubscription.cpp | 561 +++++++++--------- .../v3/RpcClientUSubscriptionTest.cpp | 140 +---- 4 files changed, 352 insertions(+), 476 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index af3052c4b..ef25e327e 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -21,6 +21,7 @@ #include #include +#include "up-cpp/client/usubscription/v3/USubscription.h" namespace uprotocol::core::usubscription::v3 { using uprotocol::core::usubscription::v3::SubscriptionRequest; @@ -112,7 +113,7 @@ struct USubscriptionUUriBuilder { /// /// Like all L3 client APIs, the RpcClientUSubscription is a wrapper on top of the /// L2 Communication APIs and USubscription service. -struct RpcClientUSubscription : public uSubscription{ +struct RpcClientUSubscription : public USubscription{ using RpcClientUSubscriptionOrStatus = utils::Expected, v1::UStatus>; using ListenCallback = transport::UTransport::ListenCallback; @@ -127,61 +128,63 @@ struct RpcClientUSubscription : public uSubscription{ /// @param priority Priority of the subscription request. /// @param subscribe_request_ttl Time to live for the subscription request. /// @param rpc_client_usubscription_options Additional details for uSubscription service. - [[nodiscard]] static RpcClientUSubscriptionOrStatus create( - std::shared_ptr transport, - const v1::UUri& subscription_topic, ListenCallback&& callback, - RpcClientUSubscriptionOptions rpc_client_usubscription_options); + // [[nodiscard]] static RpcClientUSubscriptionOrStatus create( + // std::shared_ptr transport, + // const v1::UUri& subscription_topic, ListenCallback&& callback, + // RpcClientUSubscriptionOptions rpc_client_usubscription_options); + /// @brief Subscribe to the topic + /// + utils::Expected subscribe(const SubscriptionRequest& subscription_request) override; + // void subscribe(google::protobuf::RpcController* controller, + // const ::uprotocol::core::usubscription::v3::SubscriptionRequest* request, + // ::uprotocol::core::usubscription::v3::SubscriptionResponse* response, + // ::google::protobuf::Closure* done) override; + /// @brief Unsubscribe from the topic and call uSubscription service to /// close the subscription. - void Unsubscribe(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::UnsubscribeRequest* request, - ::uprotocol::core::usubscription::v3::UnsubscribeResponse* response, - ::google::protobuf::Closure* done) override; + // void Unsubscribe(google::protobuf::RpcController* controller, + // const ::uprotocol::core::usubscription::v3::UnsubscribeRequest* request, + // ::uprotocol::core::usubscription::v3::UnsubscribeResponse* response, + // ::google::protobuf::Closure* done) override; - /// @brief Fetch all subscriptions for a given topic or subscriber contained inside a [`FetchSubscriptionsRequest`] - void FetchSubscriptions(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::FetchSubscriptionsRequest* request, - ::uprotocol::core::usubscription::v3::FetchSubscriptionsResponse* response, - ::google::protobuf::Closure* done) override; + // /// @brief Fetch all subscriptions for a given topic or subscriber contained inside a [`FetchSubscriptionsRequest`] + // void FetchSubscriptions(google::protobuf::RpcController* controller, + // const ::uprotocol::core::usubscription::v3::FetchSubscriptionsRequest* request, + // ::uprotocol::core::usubscription::v3::FetchSubscriptionsResponse* response, + // ::google::protobuf::Closure* done) override; - /// @brief Register for notifications relevant to a given topic inside a [`NotificationsRequest`] - /// changing in subscription status. - void RegisterForNotifications(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, - ::uprotocol::core::usubscription::v3::NotificationsResponse* response, - ::google::protobuf::Closure* done) override; + // /// @brief Register for notifications relevant to a given topic inside a [`NotificationsRequest`] + // /// changing in subscription status. + // void RegisterForNotifications(google::protobuf::RpcController* controller, + // const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, + // ::uprotocol::core::usubscription::v3::NotificationsResponse* response, + // ::google::protobuf::Closure* done) override; - /// @brief Unregister for notifications relevant to a given topic inside a [`NotificationsRequest`] - /// changing in subscription status. - void UnregisterForNotifications(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, - ::uprotocol::core::usubscription::v3::NotificationsResponse* response, - ::google::protobuf::Closure* done) override; - - /// @brief Fetch a list of subscribers that are currently subscribed to a given topic in a [`FetchSubscribersRequest`] - void FetchSubscribers(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::FetchSubscribersRequest* request, - ::uprotocol::core::usubscription::v3::FetchSubscribersResponse* response, - ::google::protobuf::Closure* done) override; - - /// @brief getter for subscription update - /// - /// @return subscription update - Update getSubscriptionUpdate() const { return subscription_update_; } + // /// @brief Unregister for notifications relevant to a given topic inside a [`NotificationsRequest`] + // /// changing in subscription status. + // void UnregisterForNotifications(google::protobuf::RpcController* controller, + // const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, + // ::uprotocol::core::usubscription::v3::NotificationsResponse* response, + // ::google::protobuf::Closure* done) override; + + // /// @brief Fetch a list of subscribers that are currently subscribed to a given topic in a [`FetchSubscribersRequest`] + // void FetchSubscribers(google::protobuf::RpcController* controller, + // const ::uprotocol::core::usubscription::v3::FetchSubscribersRequest* request, + // ::uprotocol::core::usubscription::v3::FetchSubscribersResponse* response, + // ::google::protobuf::Closure* done) override; /// @brief Destructor - ~RpcClientUSubscription() = default; + ~RpcClientUSubscription() override = default; /// This section for test code only delete later -protected: +// protected: /// @brief Constructor /// /// @param transport Transport to register with. /// @param subscriber_details Additional details about the subscriber. - RpcClientUSubscription(std::shared_ptr transport, - v1::UUri subscription_topic, + explicit RpcClientUSubscription(std::shared_ptr transport, RpcClientUSubscriptionOptions rpc_client_usubscription_options = {}); private: @@ -190,29 +193,13 @@ struct RpcClientUSubscription : public uSubscription{ // Topic to subscribe to const v1::UUri subscription_topic_; + // Additional details about uSubscription service RpcClientUSubscriptionOptions rpc_client_usubscription_options_; // URI info about the uSubscription service USubscriptionUUriBuilder uSubscriptionUUriBuilder_; - // Subscription updates - std::unique_ptr noficationSinkHandle_; - Update subscription_update_; - - // RPC request - std::unique_ptr rpc_client_; - communication::RpcClient::InvokeHandle rpc_handle_; - - SubscriptionResponse subscription_response_; - UnsubscribeResponse unsubscribe_response_; - FetchSubscriptionsResponse fetch_subscription_response_; - NotificationsResponse notification_response_; - FetchSubscribersResponse fetch_subscribers_response_; - - // L2 Subscriber details - std::unique_ptr subscriber_; - // Allow the protected constructor for this class to be used in make_unique // inside of create() friend std::unique_ptr @@ -232,12 +219,6 @@ struct RpcClientUSubscription : public uSubscription{ /// @brief Create a notification sink to receive subscription updates v1::UStatus createNotificationSink(); - /// @brief Subscribe to the topic - /// - void Subscribe(google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::SubscriptionRequest* request, - ::uprotocol::core::usubscription::v3::SubscriptionResponse* response, - ::google::protobuf::Closure* done) override; }; } // namespace uprotocol::core::usubscription::v3 diff --git a/include/up-cpp/client/usubscription/v3/USubscription.h b/include/up-cpp/client/usubscription/v3/USubscription.h index 0de39ca93..9c387039d 100644 --- a/include/up-cpp/client/usubscription/v3/USubscription.h +++ b/include/up-cpp/client/usubscription/v3/USubscription.h @@ -1,24 +1,30 @@ #ifndef USUBSCRIPTION_H #define USUBSCRIPTION_H #include +#include +#include +#include "up-cpp/utils/Expected.h" namespace uprotocol::core::usubscription::v3 { struct USubscription { + template + using ResponseOrStatus = utils::Expected; + virtual ~USubscription() = default; - virtual SubscriptionResponse subscribe(const SubscriptionRequest& subscription_request) = 0; + virtual ResponseOrStatus subscribe(const SubscriptionRequest& subscription_request) = 0; - virtual UnsubscribeResponse unsubscribe(const UnsubscribeRequest& unsubscribe_request) = 0; + // virtual UnsubscribeResponse unsubscribe(const UnsubscribeRequest& unsubscribe_request) = 0; - virtual FetchSubscriptionsResponse fetch_subscriptions(const FetchSubscriptionsRequest& fetch_subscribers_request) = 0; + // virtual FetchSubscriptionsResponse fetch_subscriptions(const FetchSubscriptionsRequest& fetch_subscribers_request) = 0; - virtual NotificationsResponse register_for_notifications(const NotificationsRequest& register_notifications_request) =0 ; + // virtual NotificationsResponse register_for_notifications(const NotificationsRequest& register_notifications_request) =0 ; - virtual NotificationsResponse unregister_for_notifications(const NotificationsRequest& unregister_notifications_request) = 0; + // virtual NotificationsResponse unregister_for_notifications(const NotificationsRequest& unregister_notifications_request) = 0; - virtual FetchSubscribersResponse fetch_subscribers(const FetchSubscribersRequest& fetch_subscribers_request) = 0; + // virtual FetchSubscribersResponse fetch_subscribers(const FetchSubscribersRequest& fetch_subscribers_request) = 0; }; diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 91b38a544..a160f1dce 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -12,75 +12,78 @@ #include #include #include +#include #include +#include "up-cpp/communication/RpcClient.h" + +constexpr uint16_t RESOURCE_ID_SUBSCRIBE = 0x0001; +// TODO(lennart) see default_call_options() for the request in Rust +constexpr auto SUBSCRIPTION_REQUEST_TTL = std::chrono::milliseconds(0x0800); // TODO(lennart) change time +auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; // MUST be >= 4 namespace uprotocol::core::usubscription::v3 { RpcClientUSubscription::RpcClientUSubscription(std::shared_ptr transport, - v1::UUri subscription_topic, RpcClientUSubscriptionOptions rpc_client_usubscription_options) : transport_(std::move(transport)), - subscription_topic_(std::move(subscription_topic)), - rpc_client_usubscription_options_(std::move(rpc_client_usubscription_options)), - rpc_client_(nullptr) { + rpc_client_usubscription_options_(std::move(rpc_client_usubscription_options)) { // Initialize uSubscriptionUUriBuilder_ uSubscriptionUUriBuilder_ = USubscriptionUUriBuilder(); } -[[nodiscard]] RpcClientUSubscription::RpcClientUSubscriptionOrStatus RpcClientUSubscription::create( - std::shared_ptr transport, - const v1::UUri& subscription_topic, ListenCallback&& callback, - RpcClientUSubscriptionOptions rpc_client_usubscription_options) { - auto rpc_client_usubscription = std::make_unique( - std::forward>(transport), - std::forward(subscription_topic), - std::forward(rpc_client_usubscription_options)); +// [[nodiscard]] RpcClientUSubscription::RpcClientUSubscriptionOrStatus RpcClientUSubscription::create( +// std::shared_ptr transport, +// const v1::UUri& subscription_topic, ListenCallback&& callback, +// RpcClientUSubscriptionOptions rpc_client_usubscription_options) { +// auto rpc_client_usubscription = std::make_unique( +// std::forward>(transport), +// std::forward(rpc_client_usubscription_options)); - google::protobuf::RpcController *controller = nullptr; - ::uprotocol::core::usubscription::v3::SubscriptionRequest const *subscription_request = nullptr; - SubscriptionResponse *subscription_response = nullptr; - - // Attempt to connect create notification sink for updates. - auto status = rpc_client_usubscription->createNotificationSink(); - if (status.code() == v1::UCode::OK) { - rpc_client_usubscription->Subscribe(controller, subscription_request, - subscription_response, nullptr); - if (controller == nullptr) { - return RpcClientUSubscriptionOrStatus(std::move(rpc_client_usubscription)); - } - return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); - } - // If connection fails, return the error status. - return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); -} - -v1::UStatus RpcClientUSubscription::createNotificationSink() { - auto notification_sink_callback = [this](const v1::UMessage& update) { - if (update.has_payload()) { - Update data; - if (data.ParseFromString(update.payload())) { - if (data.topic().SerializeAsString() == - subscription_topic_.SerializeAsString()) { - subscription_update_ = std::move(data); - } - } - } - }; - - auto notification_topic = uSubscriptionUUriBuilder_.getNotificationUri(); - - auto result = communication::NotificationSink::create( - transport_, std::move(notification_sink_callback), notification_topic); - - if (result.has_value()) { - noficationSinkHandle_ = std::move(result).value(); - v1::UStatus status; - status.set_code(v1::UCode::OK); - return status; - } - return result.error(); -} +// google::protobuf::RpcController *controller = nullptr; +// ::uprotocol::core::usubscription::v3::SubscriptionRequest const *subscription_request = nullptr; +// SubscriptionResponse *subscription_response = nullptr; + +// // Attempt to connect create notification sink for updates. +// auto status = rpc_client_usubscription->createNotificationSink(); +// if (status.code() == v1::UCode::OK) { +// rpc_client_usubscription->Subscribe(controller, subscription_request, +// subscription_response, nullptr); +// if (controller == nullptr) { +// return RpcClientUSubscriptionOrStatus(std::move(rpc_client_usubscription)); +// } +// return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); +// } +// // If connection fails, return the error status. +// return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); +// } + +// v1::UStatus RpcClientUSubscription::createNotificationSink() { +// auto notification_sink_callback = [this](const v1::UMessage& update) { +// if (update.has_payload()) { +// Update data; +// if (data.ParseFromString(update.payload())) { +// if (data.topic().SerializeAsString() == +// subscription_topic_.SerializeAsString()) { +// subscription_update_ = std::move(data); +// } +// } +// } +// }; + +// auto notification_topic = uSubscriptionUUriBuilder_.getNotificationUri(); + +// auto result = communication::NotificationSink::create( +// transport_, std::move(notification_sink_callback), notification_topic); + +// if (result.has_value()) { +// noficationSinkHandle_ = std::move(result).value(); +// v1::UStatus status; +// status.set_code(v1::UCode::OK); +// return status; +// } +// return result.error(); +// } SubscriptionRequest RpcClientUSubscription::buildSubscriptionRequest() { auto attributes = utils::ProtoConverter::BuildSubscribeAttributes( @@ -92,257 +95,235 @@ SubscriptionRequest RpcClientUSubscription::buildSubscriptionRequest() { return subscription_request; } -void RpcClientUSubscription::Subscribe( - google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::SubscriptionRequest* request, - ::uprotocol::core::usubscription::v3::SubscriptionResponse* response, - ::google::protobuf::Closure* done) { +RpcClientUSubscription::ResponseOrStatus RpcClientUSubscription::subscribe(const SubscriptionRequest& subscription_request) { + + communication::RpcClient rpc_client( + transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_SUBSCRIBE), + priority, SUBSCRIPTION_REQUEST_TTL); + + datamodel::builder::Payload payload(subscription_request); + + auto invoke_future = + rpc_client.invokeMethod(std::move(payload)); + + auto message_or_status = invoke_future.get(); - constexpr uint16_t RESOURCE_ID_SUBSCRIBE = 0x0001; - // TODO(lennart) see default_call_options() for the request in Rust - constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? - auto subscription_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; + if (!message_or_status.has_value()) { + return ResponseOrStatus( + utils::Unexpected(message_or_status.error())); + } + SubscriptionResponse subscription_response; + subscription_response.ParseFromString(message_or_status.value().payload()); - rpc_client_ = std::make_unique( - transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_SUBSCRIBE), - priority, subscription_request_ttl); - - auto on_response = [this, response](const auto& maybe_response) { - if (maybe_response.has_value() && - maybe_response.value().has_payload()) { - if (response->ParseFromString(maybe_response.value().payload())) { - if (response->topic().SerializeAsString() == - subscription_topic_.SerializeAsString()) { - subscription_response_ = *response; - } - } - } - }; - - // SubscriptionRequest const subscription_request = buildSubscriptionRequest(); - auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct, has been subscription_request before - - rpc_handle_ = - rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - - // TODO(lennart) any handle for the response? - - // Question TODO(max): communication::Subscriber::subscribe(...) necessary? - auto subscription_callback = nullptr; // TODO(lennart) update with correct callback - // Create a L2 subscription - auto result = communication::Subscriber::subscribe( - transport_, subscription_topic_, std::move(subscription_callback)); - - if (result.has_value()) { - subscriber_ = std::move(result).value(); - v1::UStatus status; - status.set_code(v1::UCode::OK); - // return status; - done->Run(); + if (subscription_response.topic().SerializeAsString() == + subscription_topic_.SerializeAsString()) { + return ResponseOrStatus(subscription_response); } - controller->SetFailed("result.error()"); // TODO(lennart) method needs to be implemented - - done->Run(); + return ResponseOrStatus( + utils::Unexpected(message_or_status.error())); + } -UnsubscribeRequest RpcClientUSubscription::buildUnsubscriptionRequest() { - auto unsubscribe_request = - utils::ProtoConverter::BuildUnSubscribeRequest(subscription_topic_); - return unsubscribe_request; -} -void RpcClientUSubscription::Unsubscribe( - google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::UnsubscribeRequest* request, - ::uprotocol::core::usubscription::v3::UnsubscribeResponse* response, - ::google::protobuf::Closure* done) { - - constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? - constexpr uint16_t RESOURCE_ID_UNSUBSCRIBE = 0x0002; - auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; - - rpc_client_ = std::make_unique( - transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_UNSUBSCRIBE), - priority, request_ttl); - - auto on_response = [this, response](const auto& maybe_response) { - if (maybe_response.has_value() && - maybe_response.value().has_payload()) { - if (response->ParseFromString(maybe_response.value().payload())) { - if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe - subscription_topic_.SerializeAsString()) { - unsubscribe_response_ = *response; - } - } - } - }; - - // UnsubscribeRequest const unsubscribe_request = buildUnsubscriptionRequest(); - auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct - rpc_handle_ = - rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - - // TODO(lennart) any handle for the response? - - subscriber_.reset(); - done->Run(); -} -void RpcClientUSubscription::FetchSubscriptions( - google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::FetchSubscriptionsRequest* request, - ::uprotocol::core::usubscription::v3::FetchSubscriptionsResponse* response, - ::google::protobuf::Closure* done) { +// UnsubscribeRequest RpcClientUSubscription::buildUnsubscriptionRequest() { +// auto unsubscribe_request = +// utils::ProtoConverter::BuildUnSubscribeRequest(subscription_topic_); +// return unsubscribe_request; +// } + +// void RpcClientUSubscription::Unsubscribe( +// google::protobuf::RpcController* controller, +// const ::uprotocol::core::usubscription::v3::UnsubscribeRequest* request, +// ::uprotocol::core::usubscription::v3::UnsubscribeResponse* response, +// ::google::protobuf::Closure* done) { - constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? - constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIPTIONS = 0x0003; - auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; +// constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? +// constexpr uint16_t RESOURCE_ID_UNSUBSCRIBE = 0x0002; +// auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); +// auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; - rpc_client_ = std::make_unique( - transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_FETCH_SUBSCRIPTIONS), - priority, request_ttl); - - auto on_response = [this, response](const auto& maybe_response) { - if (maybe_response.has_value() && - maybe_response.value().has_payload()) { - if (response->ParseFromString(maybe_response.value().payload())) { - if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe - subscription_topic_.SerializeAsString()) { - fetch_subscription_response_ = *response; - } - } - } - }; - - // FetchSubscriptionsRequest const fetch_subscriptions_request = buildFetchSubscriptionsRequest(); - auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct - - rpc_handle_ = - rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - - // TODO(lennart) any handle for the response? - - done->Run(); -} - -void RpcClientUSubscription::RegisterForNotifications( - google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, - ::uprotocol::core::usubscription::v3::NotificationsResponse* response, - ::google::protobuf::Closure* done) { +// rpc_client_ = std::make_unique( +// transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_UNSUBSCRIBE), +// priority, request_ttl); + +// auto on_response = [this, response](const auto& maybe_response) { +// if (maybe_response.has_value() && +// maybe_response.value().has_payload()) { +// if (response->ParseFromString(maybe_response.value().payload())) { +// if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe +// subscription_topic_.SerializeAsString()) { +// unsubscribe_response_ = *response; +// } +// } +// } +// }; + +// // UnsubscribeRequest const unsubscribe_request = buildUnsubscriptionRequest(); +// auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct +// rpc_handle_ = +// rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + +// // TODO(lennart) any handle for the response? + +// subscriber_.reset(); + +// done->Run(); +// } + +// void RpcClientUSubscription::FetchSubscriptions( +// google::protobuf::RpcController* controller, +// const ::uprotocol::core::usubscription::v3::FetchSubscriptionsRequest* request, +// ::uprotocol::core::usubscription::v3::FetchSubscriptionsResponse* response, +// ::google::protobuf::Closure* done) { - constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? - constexpr uint16_t RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS = 0x0006; - auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; +// constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? +// constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIPTIONS = 0x0003; +// auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); +// auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; - rpc_client_ = std::make_unique( - transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS), - priority, request_ttl); - - auto on_response = [this, response](const auto& maybe_response) { - if (maybe_response.has_value() && - maybe_response.value().has_payload()) { - if (response->ParseFromString(maybe_response.value().payload())) { - if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe - subscription_topic_.SerializeAsString()) { - notification_response_ = *response; - } - } - } - }; - - // NotificationsRequest const register_notifications_request = buildRegisterNotificationsRequest(); - auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct - - rpc_handle_ = - rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - - // TODO(lennart) any handle for the response? - - done->Run(); -} - -void RpcClientUSubscription::UnregisterForNotifications( - google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, - ::uprotocol::core::usubscription::v3::NotificationsResponse* response, - ::google::protobuf::Closure* done) { +// rpc_client_ = std::make_unique( +// transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_FETCH_SUBSCRIPTIONS), +// priority, request_ttl); + +// auto on_response = [this, response](const auto& maybe_response) { +// if (maybe_response.has_value() && +// maybe_response.value().has_payload()) { +// if (response->ParseFromString(maybe_response.value().payload())) { +// if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe +// subscription_topic_.SerializeAsString()) { +// fetch_subscription_response_ = *response; +// } +// } +// } +// }; + +// // FetchSubscriptionsRequest const fetch_subscriptions_request = buildFetchSubscriptionsRequest(); +// auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct + +// rpc_handle_ = +// rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + +// // TODO(lennart) any handle for the response? + +// done->Run(); +// } + +// void RpcClientUSubscription::RegisterForNotifications( +// google::protobuf::RpcController* controller, +// const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, +// ::uprotocol::core::usubscription::v3::NotificationsResponse* response, +// ::google::protobuf::Closure* done) { - constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? - constexpr uint16_t RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS = 0x0007; - auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; +// constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? +// constexpr uint16_t RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS = 0x0006; +// auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); +// auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; - rpc_client_ = std::make_unique( - transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS), - priority, request_ttl); - - auto on_response = [this, response](const auto& maybe_response) { - if (maybe_response.has_value() && - maybe_response.value().has_payload()) { - if (response->ParseFromString(maybe_response.value().payload())) { - if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe - subscription_topic_.SerializeAsString()) { - notification_response_ = *response; - } - } - } - }; - - // NotificationsRequest const unregister_notifications_request = buildUnregisterNotificationsRequest(); - auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct - - rpc_handle_ = - rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - - // TODO(lennart) any handle for the response? - - done->Run(); -} - -void RpcClientUSubscription::FetchSubscribers( - google::protobuf::RpcController* controller, - const ::uprotocol::core::usubscription::v3::FetchSubscribersRequest* request, - ::uprotocol::core::usubscription::v3::FetchSubscribersResponse* response, - ::google::protobuf::Closure* done) { +// rpc_client_ = std::make_unique( +// transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS), +// priority, request_ttl); + +// auto on_response = [this, response](const auto& maybe_response) { +// if (maybe_response.has_value() && +// maybe_response.value().has_payload()) { +// if (response->ParseFromString(maybe_response.value().payload())) { +// if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe +// subscription_topic_.SerializeAsString()) { +// notification_response_ = *response; +// } +// } +// } +// }; + +// // NotificationsRequest const register_notifications_request = buildRegisterNotificationsRequest(); +// auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct + +// rpc_handle_ = +// rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + +// // TODO(lennart) any handle for the response? + +// done->Run(); +// } + +// void RpcClientUSubscription::UnregisterForNotifications( +// google::protobuf::RpcController* controller, +// const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, +// ::uprotocol::core::usubscription::v3::NotificationsResponse* response, +// ::google::protobuf::Closure* done) { - constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? - constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIBERS = 0x0008; - auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; +// constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? +// constexpr uint16_t RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS = 0x0007; +// auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); +// auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; - rpc_client_ = std::make_unique( - transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_FETCH_SUBSCRIBERS), - priority, request_ttl); - - auto on_response = [this, response](const auto& maybe_response) { - if (maybe_response.has_value() && - maybe_response.value().has_payload()) { - if (response->ParseFromString(maybe_response.value().payload())) { - if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe - subscription_topic_.SerializeAsString()) { - fetch_subscribers_response_ = *response; - } - } - } - }; - - // FetchSubscribersRequest const fetch_subscribers_request = buildFetchSubscribersRequest(); - auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct - - rpc_handle_ = - rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - - // TODO(lennart) any handle for the response? - - done->Run(); -} +// rpc_client_ = std::make_unique( +// transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS), +// priority, request_ttl); + +// auto on_response = [this, response](const auto& maybe_response) { +// if (maybe_response.has_value() && +// maybe_response.value().has_payload()) { +// if (response->ParseFromString(maybe_response.value().payload())) { +// if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe +// subscription_topic_.SerializeAsString()) { +// notification_response_ = *response; +// } +// } +// } +// }; + +// // NotificationsRequest const unregister_notifications_request = buildUnregisterNotificationsRequest(); +// auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct + +// rpc_handle_ = +// rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + +// // TODO(lennart) any handle for the response? + +// done->Run(); +// } + +// void RpcClientUSubscription::FetchSubscribers( +// google::protobuf::RpcController* controller, +// const ::uprotocol::core::usubscription::v3::FetchSubscribersRequest* request, +// ::uprotocol::core::usubscription::v3::FetchSubscribersResponse* response, +// ::google::protobuf::Closure* done) { + +// constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? +// constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIBERS = 0x0008; +// auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); +// auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; + +// rpc_client_ = std::make_unique( +// transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_FETCH_SUBSCRIBERS), +// priority, request_ttl); + +// auto on_response = [this, response](const auto& maybe_response) { +// if (maybe_response.has_value() && +// maybe_response.value().has_payload()) { +// if (response->ParseFromString(maybe_response.value().payload())) { +// if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe +// subscription_topic_.SerializeAsString()) { +// fetch_subscribers_response_ = *response; +// } +// } +// } +// }; + +// // FetchSubscribersRequest const fetch_subscribers_request = buildFetchSubscribersRequest(); +// auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct + +// rpc_handle_ = +// rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); + +// // TODO(lennart) any handle for the response? + +// done->Run(); +// } } // namespace uprotocol::core::usubscription::v3 diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp index 8ed25476f..fe6a3ef33 100644 --- a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -21,11 +21,6 @@ namespace { using MsgDiff = google::protobuf::util::MessageDifferencer; -void someCallBack(const uprotocol::v1::UMessage& message) { - // Print the message - std::cout << message.DebugString() << std::endl; -} - class RpcClientUSubscriptionTest : public testing::Test { private: std::shared_ptr mockTransportClient_; @@ -101,123 +96,36 @@ class RpcClientUSubscriptionTest : public testing::Test { // Negative test case with no source filter TEST_F(RpcClientUSubscriptionTest, ConstructorTestSuccess) { // NOLINT - // constexpr int REQUEST_TTL_TIME = 0x8000; - auto subscription_callback = someCallBack; - // auto subscribe_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - // auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); - - auto rpc_client_usubscription_or_status = - uprotocol::core::usubscription::v3::RpcClientUSubscription::create( - getMockTransportClient(), getSubscriptionUUri(), - subscription_callback, options); - - // Ensure that the rpc_client_usubscription creation was successful - ASSERT_TRUE(rpc_client_usubscription_or_status.has_value()); - - // Obtain a pointer to the created rpc_client_usubscription instance - const auto& rpc_client_usubscription_ptr = rpc_client_usubscription_or_status.value(); - - // Verify that the rpc_client_usubscription pointer is not null, indicating successful - // creation - ASSERT_NE(rpc_client_usubscription_ptr, nullptr); + + auto rpc_client_usubscription = + std::make_unique(getMockTransportClient(), + options); + + // Verify that the RpcClientUSubscription pointer is not null, indicating successful + ASSERT_NE(rpc_client_usubscription, nullptr); } TEST_F(RpcClientUSubscriptionTest, SubscribeTestSuccess) { // NOLINT - constexpr uint32_t DEFAULT_RESOURCE_ID = 0x8000; - // constexpr int REQUEST_TTL_TIME = 0x8000; - auto subscription_callback = someCallBack; - // auto subscribe_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - // auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; - + auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); - - auto rpc_client_usubscription_or_status = - uprotocol::core::usubscription::v3::RpcClientUSubscription::create( - getMockTransportClient(), getSubscriptionUUri(), - subscription_callback, options); - - // Ensure that the RpcClientUSubscription creation was successful - ASSERT_TRUE(rpc_client_usubscription_or_status.has_value()); - - // Obtain a pointer to the created rpc_client_usubscription instance - const auto& rpc_client_usubscription_ptr = rpc_client_usubscription_or_status.value(); - - // Verify that the rpc_client_usubscription pointer is not null, indicating successful - // creation - ASSERT_NE(rpc_client_usubscription_ptr, nullptr); - - // Create notification source sink uri to match resource id of sink - auto notification_uuri = getServerUUri(); - notification_uuri.set_resource_id(DEFAULT_RESOURCE_ID); - - // set format UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY - auto format = - uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY; - - auto notification_source = uprotocol::communication::NotificationSource( - getMockTransportServer(), std::move(notification_uuri), - std::move(getClientUUri()), format); - // Build payload - const std::string data = "test"; - auto payload = uprotocol::datamodel::builder::Payload(data, format); - - notification_source.notify(std::move(payload)); - - // Check send count - EXPECT_TRUE(getMockTransportServer()->getSendCount() == 1); - EXPECT_TRUE(getMockTransportClient()->getSendCount() == 1); -} - -TEST_F(RpcClientUSubscriptionTest, UnsubscribeTestSuccess) { // NOLINT - constexpr uint32_t DEFAULT_RESOURCE_ID = 0x8000; - // constexpr int REQUEST_TTL_TIME = 0x8000; - auto subscription_callback = someCallBack; - // auto subscribe_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); - // auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; - - auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); - - auto rpc_client_usubscription_or_status = - uprotocol::core::usubscription::v3::RpcClientUSubscription::create( - getMockTransportClient(), getSubscriptionUUri(), - subscription_callback, options); - - // Ensure that the rpc_client_usubscription creation was successful - ASSERT_TRUE(rpc_client_usubscription_or_status.has_value()); - - // Obtain a pointer to the created rpc_client_usubscription instance - const auto& rpc_client_usubscription_ptr = rpc_client_usubscription_or_status.value(); - - // Verify that the rpc_client_usubscription pointer is not null, indicating successful - // creation - ASSERT_NE(rpc_client_usubscription_ptr, nullptr); - - // Create notification source sink uri to match resource id of sink - auto notification_uuri = getServerUUri(); - notification_uuri.set_resource_id(DEFAULT_RESOURCE_ID); - - // set format UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY - auto format = - uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY; - - auto notification_source = uprotocol::communication::NotificationSource( - getMockTransportServer(), std::move(notification_uuri), - std::move(getClientUUri()), format); - // Build payload - const std::string data = "test"; - auto payload = uprotocol::datamodel::builder::Payload(data, format); - - notification_source.notify(std::move(payload)); - - // Check send count - EXPECT_TRUE(getMockTransportServer()->getSendCount() == 1); - EXPECT_TRUE(getMockTransportClient()->getSendCount() == 1); - - rpc_client_usubscription_ptr->Unsubscribe(nullptr, nullptr, nullptr, nullptr); - - EXPECT_TRUE(getMockTransportClient()->getSendCount() == 2); + + uprotocol::core::usubscription::v3::SubscriptionRequest subscription_request = uprotocol::utils::ProtoConverter::BuildSubscriptionRequest( + getSubscriptionUUri(), uprotocol::core::usubscription::v3::SubscribeAttributes()); + + auto rpc_client_usubscription = + std::make_unique(getMockTransportClient(), + options); + + // Verify that the RpcClientUSubscription pointer is not null, indicating successful + ASSERT_NE(rpc_client_usubscription, nullptr); + + auto result = rpc_client_usubscription->subscribe(subscription_request); + + ASSERT_NE(&result, nullptr); } } // namespace From cf23e830687dcde5a835350d098eae3e9a0e962c Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 10 May 2025 10:36:02 +0200 Subject: [PATCH 026/105] fixed UTransport.h --- .../usubscription/v3/RpcClientUSubscription.h | 109 ++++--- .../client/usubscription/v3/USubscription.h | 35 ++- .../v3/RpcClientUSubscription.cpp | 293 ++---------------- .../v3/RpcClientUSubscriptionTest.cpp | 47 +-- 4 files changed, 127 insertions(+), 357 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index ef25e327e..4835843ac 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -14,20 +14,18 @@ #include #include -#include #include #include #include -#include +#include -#include #include "up-cpp/client/usubscription/v3/USubscription.h" namespace uprotocol::core::usubscription::v3 { -using uprotocol::core::usubscription::v3::SubscriptionRequest; -using uprotocol::core::usubscription::v3::UnsubscribeRequest; -using uprotocol::core::usubscription::v3::Update; -using uprotocol::core::usubscription::v3::uSubscription; +using v3::SubscriptionRequest; +using v3::UnsubscribeRequest; +using v3::Update; +using v3::uSubscription; /** * @struct RpcClientUSubscriptionOptions @@ -111,9 +109,9 @@ struct USubscriptionUUriBuilder { /// @brief Interface for uEntities to create subscriptions. /// -/// Like all L3 client APIs, the RpcClientUSubscription is a wrapper on top of the -/// L2 Communication APIs and USubscription service. -struct RpcClientUSubscription : public USubscription{ +/// Like all L3 client APIs, the RpcClientUSubscription is a wrapper on top of +/// the L2 Communication APIs and USubscription service. +struct RpcClientUSubscription : USubscription { using RpcClientUSubscriptionOrStatus = utils::Expected, v1::UStatus>; using ListenCallback = transport::UTransport::ListenCallback; @@ -127,7 +125,8 @@ struct RpcClientUSubscription : public USubscription{ /// received. /// @param priority Priority of the subscription request. /// @param subscribe_request_ttl Time to live for the subscription request. - /// @param rpc_client_usubscription_options Additional details for uSubscription service. + /// @param rpc_client_usubscription_options Additional details for + /// uSubscription service. // [[nodiscard]] static RpcClientUSubscriptionOrStatus create( // std::shared_ptr transport, // const v1::UUri& subscription_topic, ListenCallback&& callback, @@ -135,43 +134,53 @@ struct RpcClientUSubscription : public USubscription{ /// @brief Subscribe to the topic /// - utils::Expected subscribe(const SubscriptionRequest& subscription_request) override; + utils::Expected subscribe( + const SubscriptionRequest& subscription_request) override; // void subscribe(google::protobuf::RpcController* controller, - // const ::uprotocol::core::usubscription::v3::SubscriptionRequest* request, + // const ::uprotocol::core::usubscription::v3::SubscriptionRequest* + // request, // ::uprotocol::core::usubscription::v3::SubscriptionResponse* response, // ::google::protobuf::Closure* done) override; - + /// @brief Unsubscribe from the topic and call uSubscription service to /// close the subscription. // void Unsubscribe(google::protobuf::RpcController* controller, // const ::uprotocol::core::usubscription::v3::UnsubscribeRequest* request, // ::uprotocol::core::usubscription::v3::UnsubscribeResponse* response, // ::google::protobuf::Closure* done) override; - - // /// @brief Fetch all subscriptions for a given topic or subscriber contained inside a [`FetchSubscriptionsRequest`] - // void FetchSubscriptions(google::protobuf::RpcController* controller, - // const ::uprotocol::core::usubscription::v3::FetchSubscriptionsRequest* request, - // ::uprotocol::core::usubscription::v3::FetchSubscriptionsResponse* response, + + // /// @brief Fetch all subscriptions for a given topic or subscriber + // contained inside a [`FetchSubscriptionsRequest`] void + // FetchSubscriptions(google::protobuf::RpcController* controller, const + // ::uprotocol::core::usubscription::v3::FetchSubscriptionsRequest* request, + // ::uprotocol::core::usubscription::v3::FetchSubscriptionsResponse* + // response, // ::google::protobuf::Closure* done) override; - - // /// @brief Register for notifications relevant to a given topic inside a [`NotificationsRequest`] - // /// changing in subscription status. - // void RegisterForNotifications(google::protobuf::RpcController* controller, - // const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, + + // /// @brief Register for notifications relevant to a given topic inside a + // [`NotificationsRequest`] + // /// changing in subscription status. + // void RegisterForNotifications(google::protobuf::RpcController* + // controller, const + // ::uprotocol::core::usubscription::v3::NotificationsRequest* request, // ::uprotocol::core::usubscription::v3::NotificationsResponse* response, // ::google::protobuf::Closure* done) override; - - // /// @brief Unregister for notifications relevant to a given topic inside a [`NotificationsRequest`] - // /// changing in subscription status. - // void UnregisterForNotifications(google::protobuf::RpcController* controller, - // const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, + + // /// @brief Unregister for notifications relevant to a given topic inside + // a [`NotificationsRequest`] + // /// changing in subscription status. + // void UnregisterForNotifications(google::protobuf::RpcController* + // controller, const + // ::uprotocol::core::usubscription::v3::NotificationsRequest* request, // ::uprotocol::core::usubscription::v3::NotificationsResponse* response, // ::google::protobuf::Closure* done) override; - // /// @brief Fetch a list of subscribers that are currently subscribed to a given topic in a [`FetchSubscribersRequest`] - // void FetchSubscribers(google::protobuf::RpcController* controller, - // const ::uprotocol::core::usubscription::v3::FetchSubscribersRequest* request, - // ::uprotocol::core::usubscription::v3::FetchSubscribersResponse* response, + // /// @brief Fetch a list of subscribers that are currently subscribed to a + // given topic in a [`FetchSubscribersRequest`] void + // FetchSubscribers(google::protobuf::RpcController* controller, const + // ::uprotocol::core::usubscription::v3::FetchSubscribersRequest* request, + // ::uprotocol::core::usubscription::v3::FetchSubscribersResponse* + // response, // ::google::protobuf::Closure* done) override; /// @brief Destructor @@ -179,13 +188,14 @@ struct RpcClientUSubscription : public USubscription{ /// This section for test code only delete later -// protected: + // protected: /// @brief Constructor /// /// @param transport Transport to register with. /// @param subscriber_details Additional details about the subscriber. - explicit RpcClientUSubscription(std::shared_ptr transport, - RpcClientUSubscriptionOptions rpc_client_usubscription_options = {}); + explicit RpcClientUSubscription( + std::shared_ptr transport, + RpcClientUSubscriptionOptions rpc_client_usubscription_options = {}); private: // Transport @@ -198,27 +208,24 @@ struct RpcClientUSubscription : public USubscription{ RpcClientUSubscriptionOptions rpc_client_usubscription_options_; // URI info about the uSubscription service - USubscriptionUUriBuilder uSubscriptionUUriBuilder_; + USubscriptionUUriBuilder uuri_builder_; // Allow the protected constructor for this class to be used in make_unique // inside of create() - friend std::unique_ptr - std::make_unique, - const uprotocol::v1::UUri, - uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions>( - std::shared_ptr&&, - const uprotocol::v1::UUri&&, - uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions&&); + // friend std::unique_ptr std::make_unique< + // RpcClientUSubscription, std::shared_ptr, + // const v1::UUri, RpcClientUSubscriptionOptions>( + // std::shared_ptr&&, const v1::UUri&&, + // RpcClientUSubscriptionOptions&&); /// @brief Build SubscriptionRequest for subscription request SubscriptionRequest buildSubscriptionRequest(); - - /// @brief Build UnsubscriptionRequest for unsubscription request - UnsubscribeRequest buildUnsubscriptionRequest(); - - /// @brief Create a notification sink to receive subscription updates - v1::UStatus createNotificationSink(); - + // + // /// @brief Build UnsubscriptionRequest for unsubscription request + // UnsubscribeRequest buildUnsubscriptionRequest(); + // + // /// @brief Create a notification sink to receive subscription updates + // v1::UStatus createNotificationSink(); }; } // namespace uprotocol::core::usubscription::v3 diff --git a/include/up-cpp/client/usubscription/v3/USubscription.h b/include/up-cpp/client/usubscription/v3/USubscription.h index 9c387039d..b030346ed 100644 --- a/include/up-cpp/client/usubscription/v3/USubscription.h +++ b/include/up-cpp/client/usubscription/v3/USubscription.h @@ -3,31 +3,36 @@ #include #include #include + #include "up-cpp/utils/Expected.h" namespace uprotocol::core::usubscription::v3 { - struct USubscription { - - template - using ResponseOrStatus = utils::Expected; - - virtual ~USubscription() = default; +struct USubscription { + template + using ResponseOrStatus = utils::Expected; - virtual ResponseOrStatus subscribe(const SubscriptionRequest& subscription_request) = 0; + virtual ~USubscription() = default; - // virtual UnsubscribeResponse unsubscribe(const UnsubscribeRequest& unsubscribe_request) = 0; + virtual ResponseOrStatus subscribe( + const SubscriptionRequest& subscription_request) = 0; - // virtual FetchSubscriptionsResponse fetch_subscriptions(const FetchSubscriptionsRequest& fetch_subscribers_request) = 0; + // virtual UnsubscribeResponse unsubscribe(const UnsubscribeRequest& + // unsubscribe_request) = 0; - // virtual NotificationsResponse register_for_notifications(const NotificationsRequest& register_notifications_request) =0 ; + // virtual FetchSubscriptionsResponse fetch_subscriptions(const + // FetchSubscriptionsRequest& fetch_subscribers_request) = 0; - // virtual NotificationsResponse unregister_for_notifications(const NotificationsRequest& unregister_notifications_request) = 0; + // virtual NotificationsResponse register_for_notifications(const + // NotificationsRequest& register_notifications_request) =0 ; - // virtual FetchSubscribersResponse fetch_subscribers(const FetchSubscribersRequest& fetch_subscribers_request) = 0; + // virtual NotificationsResponse unregister_for_notifications(const + // NotificationsRequest& unregister_notifications_request) = 0; - }; + // virtual FetchSubscribersResponse fetch_subscribers(const + // FetchSubscribersRequest& fetch_subscribers_request) = 0; +}; -} // namespace uprotocol::core::usubscription::v3 +} // namespace uprotocol::core::usubscription::v3 -#endif //USUBSCRIPTION_H +#endif // USUBSCRIPTION_H diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index a160f1dce..465478189 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -15,79 +15,31 @@ #include #include + #include "up-cpp/communication/RpcClient.h" +#include "up-cpp/transport/UTransport.h" constexpr uint16_t RESOURCE_ID_SUBSCRIBE = 0x0001; // TODO(lennart) see default_call_options() for the request in Rust -constexpr auto SUBSCRIPTION_REQUEST_TTL = std::chrono::milliseconds(0x0800); // TODO(lennart) change time -auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; // MUST be >= 4 +constexpr auto SUBSCRIPTION_REQUEST_TTL = + std::chrono::milliseconds(0x0800); // TODO(lennart) change time +auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; // MUST be >= 4 namespace uprotocol::core::usubscription::v3 { -RpcClientUSubscription::RpcClientUSubscription(std::shared_ptr transport, - RpcClientUSubscriptionOptions rpc_client_usubscription_options) +RpcClientUSubscription::RpcClientUSubscription( + std::shared_ptr transport, + RpcClientUSubscriptionOptions rpc_client_usubscription_options) : transport_(std::move(transport)), - rpc_client_usubscription_options_(std::move(rpc_client_usubscription_options)) { - // Initialize uSubscriptionUUriBuilder_ - uSubscriptionUUriBuilder_ = USubscriptionUUriBuilder(); + rpc_client_usubscription_options_( + std::move(rpc_client_usubscription_options)) { + uuri_builder_ = USubscriptionUUriBuilder(); } -// [[nodiscard]] RpcClientUSubscription::RpcClientUSubscriptionOrStatus RpcClientUSubscription::create( -// std::shared_ptr transport, -// const v1::UUri& subscription_topic, ListenCallback&& callback, -// RpcClientUSubscriptionOptions rpc_client_usubscription_options) { -// auto rpc_client_usubscription = std::make_unique( -// std::forward>(transport), -// std::forward(rpc_client_usubscription_options)); - -// google::protobuf::RpcController *controller = nullptr; -// ::uprotocol::core::usubscription::v3::SubscriptionRequest const *subscription_request = nullptr; -// SubscriptionResponse *subscription_response = nullptr; - -// // Attempt to connect create notification sink for updates. -// auto status = rpc_client_usubscription->createNotificationSink(); -// if (status.code() == v1::UCode::OK) { -// rpc_client_usubscription->Subscribe(controller, subscription_request, -// subscription_response, nullptr); -// if (controller == nullptr) { -// return RpcClientUSubscriptionOrStatus(std::move(rpc_client_usubscription)); -// } -// return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); -// } -// // If connection fails, return the error status. -// return RpcClientUSubscriptionOrStatus(utils::Unexpected(status)); -// } - -// v1::UStatus RpcClientUSubscription::createNotificationSink() { -// auto notification_sink_callback = [this](const v1::UMessage& update) { -// if (update.has_payload()) { -// Update data; -// if (data.ParseFromString(update.payload())) { -// if (data.topic().SerializeAsString() == -// subscription_topic_.SerializeAsString()) { -// subscription_update_ = std::move(data); -// } -// } -// } -// }; - -// auto notification_topic = uSubscriptionUUriBuilder_.getNotificationUri(); - -// auto result = communication::NotificationSink::create( -// transport_, std::move(notification_sink_callback), notification_topic); - -// if (result.has_value()) { -// noficationSinkHandle_ = std::move(result).value(); -// v1::UStatus status; -// status.set_code(v1::UCode::OK); -// return status; -// } -// return result.error(); -// } - SubscriptionRequest RpcClientUSubscription::buildSubscriptionRequest() { auto attributes = utils::ProtoConverter::BuildSubscribeAttributes( - rpc_client_usubscription_options_.when_expire, rpc_client_usubscription_options_.subscription_details, + rpc_client_usubscription_options_.when_expire, + rpc_client_usubscription_options_.subscription_details, rpc_client_usubscription_options_.sample_period_ms); auto subscription_request = utils::ProtoConverter::BuildSubscriptionRequest( @@ -95,19 +47,21 @@ SubscriptionRequest RpcClientUSubscription::buildSubscriptionRequest() { return subscription_request; } -RpcClientUSubscription::ResponseOrStatus RpcClientUSubscription::subscribe(const SubscriptionRequest& subscription_request) { - +RpcClientUSubscription::ResponseOrStatus +RpcClientUSubscription::subscribe( + const SubscriptionRequest& subscription_request) { communication::RpcClient rpc_client( - transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_SUBSCRIBE), + transport_, + uuri_builder_.getServiceUriWithResourceId( + RESOURCE_ID_SUBSCRIBE), priority, SUBSCRIPTION_REQUEST_TTL); datamodel::builder::Payload payload(subscription_request); - auto invoke_future = - rpc_client.invokeMethod(std::move(payload)); + auto invoke_future = rpc_client.invokeMethod(std::move(payload)); auto message_or_status = invoke_future.get(); - + if (!message_or_status.has_value()) { return ResponseOrStatus( utils::Unexpected(message_or_status.error())); @@ -117,213 +71,12 @@ RpcClientUSubscription::ResponseOrStatus RpcClientUSubscri subscription_response.ParseFromString(message_or_status.value().payload()); if (subscription_response.topic().SerializeAsString() == - subscription_topic_.SerializeAsString()) { + subscription_topic_.SerializeAsString()) { return ResponseOrStatus(subscription_response); } return ResponseOrStatus( - utils::Unexpected(message_or_status.error())); - + utils::Unexpected(message_or_status.error())); } - - - -// UnsubscribeRequest RpcClientUSubscription::buildUnsubscriptionRequest() { -// auto unsubscribe_request = -// utils::ProtoConverter::BuildUnSubscribeRequest(subscription_topic_); -// return unsubscribe_request; -// } - -// void RpcClientUSubscription::Unsubscribe( -// google::protobuf::RpcController* controller, -// const ::uprotocol::core::usubscription::v3::UnsubscribeRequest* request, -// ::uprotocol::core::usubscription::v3::UnsubscribeResponse* response, -// ::google::protobuf::Closure* done) { - -// constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? -// constexpr uint16_t RESOURCE_ID_UNSUBSCRIBE = 0x0002; -// auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); -// auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; - -// rpc_client_ = std::make_unique( -// transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_UNSUBSCRIBE), -// priority, request_ttl); - -// auto on_response = [this, response](const auto& maybe_response) { -// if (maybe_response.has_value() && -// maybe_response.value().has_payload()) { -// if (response->ParseFromString(maybe_response.value().payload())) { -// if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe -// subscription_topic_.SerializeAsString()) { -// unsubscribe_response_ = *response; -// } -// } -// } -// }; - -// // UnsubscribeRequest const unsubscribe_request = buildUnsubscriptionRequest(); -// auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct -// rpc_handle_ = -// rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - -// // TODO(lennart) any handle for the response? - -// subscriber_.reset(); - -// done->Run(); -// } - -// void RpcClientUSubscription::FetchSubscriptions( -// google::protobuf::RpcController* controller, -// const ::uprotocol::core::usubscription::v3::FetchSubscriptionsRequest* request, -// ::uprotocol::core::usubscription::v3::FetchSubscriptionsResponse* response, -// ::google::protobuf::Closure* done) { - -// constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? -// constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIPTIONS = 0x0003; -// auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); -// auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; - -// rpc_client_ = std::make_unique( -// transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_FETCH_SUBSCRIPTIONS), -// priority, request_ttl); - -// auto on_response = [this, response](const auto& maybe_response) { -// if (maybe_response.has_value() && -// maybe_response.value().has_payload()) { -// if (response->ParseFromString(maybe_response.value().payload())) { -// if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe -// subscription_topic_.SerializeAsString()) { -// fetch_subscription_response_ = *response; -// } -// } -// } -// }; - -// // FetchSubscriptionsRequest const fetch_subscriptions_request = buildFetchSubscriptionsRequest(); -// auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct - -// rpc_handle_ = -// rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - -// // TODO(lennart) any handle for the response? - -// done->Run(); -// } - -// void RpcClientUSubscription::RegisterForNotifications( -// google::protobuf::RpcController* controller, -// const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, -// ::uprotocol::core::usubscription::v3::NotificationsResponse* response, -// ::google::protobuf::Closure* done) { - -// constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? -// constexpr uint16_t RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS = 0x0006; -// auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); -// auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; - -// rpc_client_ = std::make_unique( -// transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS), -// priority, request_ttl); - -// auto on_response = [this, response](const auto& maybe_response) { -// if (maybe_response.has_value() && -// maybe_response.value().has_payload()) { -// if (response->ParseFromString(maybe_response.value().payload())) { -// if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe -// subscription_topic_.SerializeAsString()) { -// notification_response_ = *response; -// } -// } -// } -// }; - -// // NotificationsRequest const register_notifications_request = buildRegisterNotificationsRequest(); -// auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct - -// rpc_handle_ = -// rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - -// // TODO(lennart) any handle for the response? - -// done->Run(); -// } - -// void RpcClientUSubscription::UnregisterForNotifications( -// google::protobuf::RpcController* controller, -// const ::uprotocol::core::usubscription::v3::NotificationsRequest* request, -// ::uprotocol::core::usubscription::v3::NotificationsResponse* response, -// ::google::protobuf::Closure* done) { - -// constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? -// constexpr uint16_t RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS = 0x0007; -// auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); -// auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; - -// rpc_client_ = std::make_unique( -// transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS), -// priority, request_ttl); - -// auto on_response = [this, response](const auto& maybe_response) { -// if (maybe_response.has_value() && -// maybe_response.value().has_payload()) { -// if (response->ParseFromString(maybe_response.value().payload())) { -// if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe -// subscription_topic_.SerializeAsString()) { -// notification_response_ = *response; -// } -// } -// } -// }; - -// // NotificationsRequest const unregister_notifications_request = buildUnregisterNotificationsRequest(); -// auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct - -// rpc_handle_ = -// rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - -// // TODO(lennart) any handle for the response? - -// done->Run(); -// } - -// void RpcClientUSubscription::FetchSubscribers( -// google::protobuf::RpcController* controller, -// const ::uprotocol::core::usubscription::v3::FetchSubscribersRequest* request, -// ::uprotocol::core::usubscription::v3::FetchSubscribersResponse* response, -// ::google::protobuf::Closure* done) { - -// constexpr int REQUEST_TTL_TIME = 0x8000; // TODO(lennart) time? -// constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIBERS = 0x0008; -// auto request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); -// auto priority = uprotocol::v1::UPriority::UPRIORITY_UNSPECIFIED; - -// rpc_client_ = std::make_unique( -// transport_, uSubscriptionUUriBuilder_.getServiceUriWithResourceId(RESOURCE_ID_FETCH_SUBSCRIBERS), -// priority, request_ttl); - -// auto on_response = [this, response](const auto& maybe_response) { -// if (maybe_response.has_value() && -// maybe_response.value().has_payload()) { -// if (response->ParseFromString(maybe_response.value().payload())) { -// if (response->SerializeAsString() == // TODO(lennart) topic specific? See subscribe -// subscription_topic_.SerializeAsString()) { -// fetch_subscribers_response_ = *response; -// } -// } -// } -// }; - -// // FetchSubscribersRequest const fetch_subscribers_request = buildFetchSubscribersRequest(); -// auto payload = datamodel::builder::Payload(*request); // TODO(lennart) check if request is correct - -// rpc_handle_ = -// rpc_client_->invokeMethod(std::move(payload), std::move(on_response)); - -// // TODO(lennart) any handle for the response? - -// done->Run(); -// } - } // namespace uprotocol::core::usubscription::v3 diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp index fe6a3ef33..76fa0506c 100644 --- a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -97,30 +97,35 @@ class RpcClientUSubscriptionTest : public testing::Test { // Negative test case with no source filter TEST_F(RpcClientUSubscriptionTest, ConstructorTestSuccess) { // NOLINT - auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); - - auto rpc_client_usubscription = - std::make_unique(getMockTransportClient(), - options); - - // Verify that the RpcClientUSubscription pointer is not null, indicating successful - ASSERT_NE(rpc_client_usubscription, nullptr); + auto options = + uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); + + auto rpc_client_usubscription = std::make_unique< + uprotocol::core::usubscription::v3::RpcClientUSubscription>( + getMockTransportClient(), options); + + // Verify that the RpcClientUSubscription pointer is not null, indicating + // successful + ASSERT_NE(rpc_client_usubscription, nullptr); } TEST_F(RpcClientUSubscriptionTest, SubscribeTestSuccess) { // NOLINT - - auto options = uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); - - uprotocol::core::usubscription::v3::SubscriptionRequest subscription_request = uprotocol::utils::ProtoConverter::BuildSubscriptionRequest( - getSubscriptionUUri(), uprotocol::core::usubscription::v3::SubscribeAttributes()); - - auto rpc_client_usubscription = - std::make_unique(getMockTransportClient(), - options); - - // Verify that the RpcClientUSubscription pointer is not null, indicating successful + + auto options = + uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); + + uprotocol::core::usubscription::v3::SubscriptionRequest + subscription_request = + uprotocol::utils::ProtoConverter::BuildSubscriptionRequest( + getSubscriptionUUri(), + uprotocol::core::usubscription::v3::SubscribeAttributes()); + + auto rpc_client_usubscription = std::make_unique< + uprotocol::core::usubscription::v3::RpcClientUSubscription>( + getMockTransportClient(), options); + + // Verify that the RpcClientUSubscription pointer is not null, indicating + // successful ASSERT_NE(rpc_client_usubscription, nullptr); auto result = rpc_client_usubscription->subscribe(subscription_request); From bf8758b795227116b9fa506ad56efbd32c9d2a33 Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 10 May 2025 11:26:50 +0200 Subject: [PATCH 027/105] changed access modifier for builder to public --- include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index 4835843ac..9168259d4 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -218,6 +218,7 @@ struct RpcClientUSubscription : USubscription { // std::shared_ptr&&, const v1::UUri&&, // RpcClientUSubscriptionOptions&&); +public: /// @brief Build SubscriptionRequest for subscription request SubscriptionRequest buildSubscriptionRequest(); // From de11f6e9bdc5d497144d7b67d56fdcac64d05eba Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 10 May 2025 11:54:25 +0200 Subject: [PATCH 028/105] test name for service --- .../up-cpp/client/usubscription/v3/RpcClientUSubscription.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index 9168259d4..e6c11b8af 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -70,8 +70,8 @@ struct USubscriptionUUriBuilder { const auto& service_options = service->options(); // Get the service options - const auto& service_name = - service_options.GetExtension(uprotocol::service_name); + const auto& service_name = "test.name"; + // service_options.GetExtension(uprotocol::service_name); const auto& service_version_major = service_options.GetExtension(uprotocol::service_version_major); const auto& service_id = From 0e5b7a8a29a710fbfdad24561b54fc14bd8be164 Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 10 May 2025 11:56:50 +0200 Subject: [PATCH 029/105] changed name to usubscription.local --- include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index e6c11b8af..bcf5ddd86 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -70,7 +70,7 @@ struct USubscriptionUUriBuilder { const auto& service_options = service->options(); // Get the service options - const auto& service_name = "test.name"; + const auto& service_name = "usubscription.local"; // service_options.GetExtension(uprotocol::service_name); const auto& service_version_major = service_options.GetExtension(uprotocol::service_version_major); From 2c60ae930d24deb981f81138f9a7d3433dc2896e Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 10 May 2025 13:02:20 +0200 Subject: [PATCH 030/105] changed uauth back --- .../up-cpp/client/usubscription/v3/RpcClientUSubscription.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index bcf5ddd86..9168259d4 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -70,8 +70,8 @@ struct USubscriptionUUriBuilder { const auto& service_options = service->options(); // Get the service options - const auto& service_name = "usubscription.local"; - // service_options.GetExtension(uprotocol::service_name); + const auto& service_name = + service_options.GetExtension(uprotocol::service_name); const auto& service_version_major = service_options.GetExtension(uprotocol::service_version_major); const auto& service_id = From 922ddb4f4f40133ca3903dfe8bc7f37e77a76869 Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 10 May 2025 18:28:50 +0200 Subject: [PATCH 031/105] some refactoring --- CMakeLists.txt | 4 +- .../usubscription/v3/RpcClientUSubscription.h | 111 +----------------- .../v3/USubscriptionUUriBuilder.h | 49 ++++++++ .../v3/RpcClientUSubscription.cpp | 18 +-- .../v3/USubscriptionUUriBuilder.cpp | 34 ++++++ 5 files changed, 98 insertions(+), 118 deletions(-) create mode 100644 include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h create mode 100644 src/client/usubscription/v3/USubscriptionUUriBuilder.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 89528e261..7ecbac5a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,7 +51,9 @@ file(GLOB_RECURSE SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") add_library(${PROJECT_NAME} ${SRC_FILES} src/client/usubscription/v3/RpcClientUSubscription.cpp include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h - include/up-cpp/client/usubscription/v3/USubscription.h) + include/up-cpp/client/usubscription/v3/USubscription.h + src/client/usubscription/v3/USubscriptionUUriBuilder.cpp + include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h) add_library(up-cpp::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) target_include_directories(${PROJECT_NAME} diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index 9168259d4..c829074b6 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -20,6 +20,7 @@ #include #include "up-cpp/client/usubscription/v3/USubscription.h" +#include "up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h" namespace uprotocol::core::usubscription::v3 { using v3::SubscriptionRequest; @@ -48,64 +49,6 @@ struct RpcClientUSubscriptionOptions { std::optional subscription_details; }; -/// @struct uSubscriptionUUriBuilder -/// @brief Structure to build uSubscription request URIs. -/// -/// This structure is used to build URIs for uSubscription service. It uses the -/// service options from uSubscription proto to set the authority name, ue_id, -/// ue_version_major, and the notification topic resource ID in the URI. -struct USubscriptionUUriBuilder { -private: - /// URI for the uSubscription service - v1::UUri uri_; - /// Resource ID of the notification topic - uint32_t sink_resource_id_; - -public: - /// @brief Constructor for USubscriptionUUriBuilder. - USubscriptionUUriBuilder() { - // Get the service descriptor - const google::protobuf::ServiceDescriptor* service = - uSubscription::descriptor(); - const auto& service_options = service->options(); - - // Get the service options - const auto& service_name = - service_options.GetExtension(uprotocol::service_name); - const auto& service_version_major = - service_options.GetExtension(uprotocol::service_version_major); - const auto& service_id = - service_options.GetExtension(uprotocol::service_id); - const auto& notification_topic = - service_options.GetExtension(uprotocol::notification_topic, 0); - - // Set the values in the URI - uri_.set_authority_name(service_name); - uri_.set_ue_id(service_id); - uri_.set_ue_version_major(service_version_major); - sink_resource_id_ = notification_topic.id(); - } - - /// @brief Get the URI with a specific resource ID. - /// - /// @param resource_id The resource ID to set in the URI. - /// - /// @return The URI with the specified resource ID. - v1::UUri getServiceUriWithResourceId(uint32_t resource_id) const { - v1::UUri uri = uri_; // Copy the base URI - uri.set_resource_id(resource_id); - return uri; - } - - /// @brief Get the notification URI. - /// - /// @return The notification URI. - v1::UUri getNotificationUri() const { - v1::UUri uri = uri_; // Copy the base URI - uri.set_resource_id(sink_resource_id_); - return uri; - } -}; /// @brief Interface for uEntities to create subscriptions. /// @@ -136,52 +79,6 @@ struct RpcClientUSubscription : USubscription { /// utils::Expected subscribe( const SubscriptionRequest& subscription_request) override; - // void subscribe(google::protobuf::RpcController* controller, - // const ::uprotocol::core::usubscription::v3::SubscriptionRequest* - // request, - // ::uprotocol::core::usubscription::v3::SubscriptionResponse* response, - // ::google::protobuf::Closure* done) override; - - /// @brief Unsubscribe from the topic and call uSubscription service to - /// close the subscription. - // void Unsubscribe(google::protobuf::RpcController* controller, - // const ::uprotocol::core::usubscription::v3::UnsubscribeRequest* request, - // ::uprotocol::core::usubscription::v3::UnsubscribeResponse* response, - // ::google::protobuf::Closure* done) override; - - // /// @brief Fetch all subscriptions for a given topic or subscriber - // contained inside a [`FetchSubscriptionsRequest`] void - // FetchSubscriptions(google::protobuf::RpcController* controller, const - // ::uprotocol::core::usubscription::v3::FetchSubscriptionsRequest* request, - // ::uprotocol::core::usubscription::v3::FetchSubscriptionsResponse* - // response, - // ::google::protobuf::Closure* done) override; - - // /// @brief Register for notifications relevant to a given topic inside a - // [`NotificationsRequest`] - // /// changing in subscription status. - // void RegisterForNotifications(google::protobuf::RpcController* - // controller, const - // ::uprotocol::core::usubscription::v3::NotificationsRequest* request, - // ::uprotocol::core::usubscription::v3::NotificationsResponse* response, - // ::google::protobuf::Closure* done) override; - - // /// @brief Unregister for notifications relevant to a given topic inside - // a [`NotificationsRequest`] - // /// changing in subscription status. - // void UnregisterForNotifications(google::protobuf::RpcController* - // controller, const - // ::uprotocol::core::usubscription::v3::NotificationsRequest* request, - // ::uprotocol::core::usubscription::v3::NotificationsResponse* response, - // ::google::protobuf::Closure* done) override; - - // /// @brief Fetch a list of subscribers that are currently subscribed to a - // given topic in a [`FetchSubscribersRequest`] void - // FetchSubscribers(google::protobuf::RpcController* controller, const - // ::uprotocol::core::usubscription::v3::FetchSubscribersRequest* request, - // ::uprotocol::core::usubscription::v3::FetchSubscribersResponse* - // response, - // ::google::protobuf::Closure* done) override; /// @brief Destructor ~RpcClientUSubscription() override = default; @@ -201,9 +98,6 @@ struct RpcClientUSubscription : USubscription { // Transport std::shared_ptr transport_; - // Topic to subscribe to - const v1::UUri subscription_topic_; - // Additional details about uSubscription service RpcClientUSubscriptionOptions rpc_client_usubscription_options_; @@ -218,9 +112,8 @@ struct RpcClientUSubscription : USubscription { // std::shared_ptr&&, const v1::UUri&&, // RpcClientUSubscriptionOptions&&); -public: /// @brief Build SubscriptionRequest for subscription request - SubscriptionRequest buildSubscriptionRequest(); + SubscriptionRequest buildSubscriptionRequest(const v1::UUri& subscription_topic); // // /// @brief Build UnsubscriptionRequest for unsubscription request // UnsubscribeRequest buildUnsubscriptionRequest(); diff --git a/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h b/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h new file mode 100644 index 000000000..b91b5f001 --- /dev/null +++ b/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h @@ -0,0 +1,49 @@ +// +// Created by max on 10.05.25. +// + +#ifndef USUBSCRIPTIONUURIBUILDER_H +#define USUBSCRIPTIONUURIBUILDER_H + +#include +#include + +#include "up-cpp/datamodel/validator/UUri.h" + +namespace uprotocol::core::usubscription::v3 { +/// @struct USubscriptionUUriBuilder +/// @brief Structure to build uSubscription request URIs. +/// +/// This structure is used to build URIs for uSubscription service. It uses the +/// service options from uSubscription proto to set the authority name, ue_id, +/// ue_version_major, and the notification topic resource ID in the URI. +struct USubscriptionUUriBuilder { + + /// @brief Constructor for USubscriptionUUriBuilder. + explicit USubscriptionUUriBuilder(); + + /// @brief Get the URI with a specific resource ID. + /// + /// @param resource_id The resource ID to set in the URI. + /// + /// @return The URI with the specified resource ID. + v1::UUri getServiceUriWithResourceId(uint32_t resource_id) const; + + /// @brief Get the notification URI. + /// + /// @return The notification URI. + v1::UUri getNotificationUri() const { + v1::UUri uri = base_uri_; // Copy the base URI + uri.set_resource_id(sink_resource_id_); + return uri; + } + + private: + /// URI for the uSubscription service + v1::UUri base_uri_; + /// Resource ID of the notification topic + uint32_t sink_resource_id_; + }; +} // namespace uprotocol::core::usubscription::v3 + +#endif //USUBSCRIPTIONUURIBUILDER_H diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 465478189..135b27ead 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -14,6 +14,8 @@ #include #include +#include + #include #include "up-cpp/communication/RpcClient.h" @@ -36,14 +38,14 @@ RpcClientUSubscription::RpcClientUSubscription( uuri_builder_ = USubscriptionUUriBuilder(); } -SubscriptionRequest RpcClientUSubscription::buildSubscriptionRequest() { +SubscriptionRequest RpcClientUSubscription::buildSubscriptionRequest(const v1::UUri& subscription_topic) { auto attributes = utils::ProtoConverter::BuildSubscribeAttributes( rpc_client_usubscription_options_.when_expire, rpc_client_usubscription_options_.subscription_details, rpc_client_usubscription_options_.sample_period_ms); auto subscription_request = utils::ProtoConverter::BuildSubscriptionRequest( - subscription_topic_, attributes); + subscription_topic, attributes); return subscription_request; } @@ -64,19 +66,19 @@ RpcClientUSubscription::subscribe( if (!message_or_status.has_value()) { return ResponseOrStatus( - utils::Unexpected(message_or_status.error())); + utils::Unexpected(std::move(message_or_status.error()))); } SubscriptionResponse subscription_response; subscription_response.ParseFromString(message_or_status.value().payload()); - if (subscription_response.topic().SerializeAsString() == - subscription_topic_.SerializeAsString()) { - return ResponseOrStatus(subscription_response); + if (subscription_response.topic().SerializeAsString() != + subscription_request.topic().SerializeAsString()) { + return ResponseOrStatus( + utils::Unexpected(std::move(message_or_status.error()))); } - return ResponseOrStatus( - utils::Unexpected(message_or_status.error())); + return ResponseOrStatus(std::move(subscription_response)); } } // namespace uprotocol::core::usubscription::v3 diff --git a/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp b/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp new file mode 100644 index 000000000..4cdb3ccf8 --- /dev/null +++ b/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp @@ -0,0 +1,34 @@ +#include "up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h" + +namespace uprotocol::core::usubscription::v3 { + +USubscriptionUUriBuilder::USubscriptionUUriBuilder() { + // Get the service descriptor + const google::protobuf::ServiceDescriptor* service = + uSubscription::descriptor(); + const auto& service_options = service->options(); + + // Get the service options + const auto& service_name = + service_options.GetExtension(uprotocol::service_name); + const auto& service_version_major = + service_options.GetExtension(uprotocol::service_version_major); + const auto& service_id = + service_options.GetExtension(uprotocol::service_id); + const auto& notification_topic = + service_options.GetExtension(uprotocol::notification_topic, 0); + + // Set the values in the URI + base_uri_.set_authority_name(service_name); + base_uri_.set_ue_id(service_id); + base_uri_.set_ue_version_major(service_version_major); + sink_resource_id_ = notification_topic.id(); +} + +v1::UUri USubscriptionUUriBuilder::getServiceUriWithResourceId(uint32_t resource_id) const { + v1::UUri uri = base_uri_; // Copy the base URI + uri.set_resource_id(resource_id); + return uri; +} + +} // namespace \ No newline at end of file From e5979fe46fcda87bb0ff9112f1730f8680f31faf Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 10 May 2025 18:32:11 +0200 Subject: [PATCH 032/105] set method public for test --- include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index c829074b6..f093422e6 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -112,6 +112,7 @@ struct RpcClientUSubscription : USubscription { // std::shared_ptr&&, const v1::UUri&&, // RpcClientUSubscriptionOptions&&); +public: /// @brief Build SubscriptionRequest for subscription request SubscriptionRequest buildSubscriptionRequest(const v1::UUri& subscription_topic); // From dbfa4bafada18a8ba929b861bee919a49bdafabf Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 11 May 2025 12:00:58 +0200 Subject: [PATCH 033/105] added RequestBuilder --- CMakeLists.txt | 7 +--- .../client/usubscription/v3/RequestBuilder.h | 42 +++++++++++++++++++ .../usubscription/v3/RpcClientUSubscription.h | 38 +---------------- .../v3/USubscriptionUUriBuilder.h | 4 -- include/up-cpp/utils/ProtoConverter.h | 2 +- .../usubscription/v3/RequestBuilder.cpp | 30 +++++++++++++ .../v3/RpcClientUSubscription.cpp | 17 +------- .../v3/RpcClientUSubscriptionTest.cpp | 9 +--- 8 files changed, 80 insertions(+), 69 deletions(-) create mode 100644 include/up-cpp/client/usubscription/v3/RequestBuilder.h create mode 100644 src/client/usubscription/v3/RequestBuilder.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ecbac5a0..256391aae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,12 +48,7 @@ endif() file(GLOB_RECURSE SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") -add_library(${PROJECT_NAME} ${SRC_FILES} - src/client/usubscription/v3/RpcClientUSubscription.cpp - include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h - include/up-cpp/client/usubscription/v3/USubscription.h - src/client/usubscription/v3/USubscriptionUUriBuilder.cpp - include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h) +add_library(${PROJECT_NAME} ${SRC_FILES}) add_library(up-cpp::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) target_include_directories(${PROJECT_NAME} diff --git a/include/up-cpp/client/usubscription/v3/RequestBuilder.h b/include/up-cpp/client/usubscription/v3/RequestBuilder.h new file mode 100644 index 000000000..b2a4d3f0c --- /dev/null +++ b/include/up-cpp/client/usubscription/v3/RequestBuilder.h @@ -0,0 +1,42 @@ +#ifndef REQUESTBUILDER_H +#define REQUESTBUILDER_H +#include +#include "up-cpp/client/usubscription/v3/RpcClientUSubscription.h" + + +namespace uprotocol::core::usubscription::v3 { +/** + * @struct USubscriptionOptions + * @brief Additional details for uSubscription service. + * + * Each member represents an optional parameter for the uSubscription service. + */ +struct USubscriptionOptions { + /// Permission level of the subscription request + std::optional permission_level; + /// TAP token for access. + std::optional token; + /// Expiration time of the subscription. + std::optional when_expire; + /// Sample period for the subscription messages in milliseconds. + std::optional sample_period_ms; + /// Details of the subscriber. + std::optional subscriber_details; + /// Details of the subscription. + std::optional subscription_details; +}; + + struct RequestBuilder { + explicit RequestBuilder( + const USubscriptionOptions& options) + :options_(options){}; + + SubscriptionRequest buildSubscriptionRequest(const v1::UUri& topic) const; + + UnsubscribeRequest buildUnsubscribeRequest(const v1::UUri& topic); + private: + USubscriptionOptions options_; + }; + +} // namespace uprotocol::core::usubscription::v3 +#endif //REQUESTBUILDER_H diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index f093422e6..e5057a2e9 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -15,9 +15,9 @@ #include #include #include +#include #include #include -#include #include "up-cpp/client/usubscription/v3/USubscription.h" #include "up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h" @@ -28,26 +28,6 @@ using v3::UnsubscribeRequest; using v3::Update; using v3::uSubscription; -/** - * @struct RpcClientUSubscriptionOptions - * @brief Additional details for uSubscription service. - * - * Each member represents an optional parameter for the uSubscription service. - */ -struct RpcClientUSubscriptionOptions { - /// Permission level of the subscription request - std::optional permission_level; - /// TAP token for access. - std::optional token; - /// Expiration time of the subscription. - std::optional when_expire; - /// Sample period for the subscription messages in milliseconds. - std::optional sample_period_ms; - /// Details of the subscriber. - std::optional subscriber_details; - /// Details of the subscription. - std::optional subscription_details; -}; /// @brief Interface for uEntities to create subscriptions. @@ -91,16 +71,12 @@ struct RpcClientUSubscription : USubscription { /// @param transport Transport to register with. /// @param subscriber_details Additional details about the subscriber. explicit RpcClientUSubscription( - std::shared_ptr transport, - RpcClientUSubscriptionOptions rpc_client_usubscription_options = {}); + std::shared_ptr transport); private: // Transport std::shared_ptr transport_; - // Additional details about uSubscription service - RpcClientUSubscriptionOptions rpc_client_usubscription_options_; - // URI info about the uSubscription service USubscriptionUUriBuilder uuri_builder_; @@ -111,16 +87,6 @@ struct RpcClientUSubscription : USubscription { // const v1::UUri, RpcClientUSubscriptionOptions>( // std::shared_ptr&&, const v1::UUri&&, // RpcClientUSubscriptionOptions&&); - -public: - /// @brief Build SubscriptionRequest for subscription request - SubscriptionRequest buildSubscriptionRequest(const v1::UUri& subscription_topic); - // - // /// @brief Build UnsubscriptionRequest for unsubscription request - // UnsubscribeRequest buildUnsubscriptionRequest(); - // - // /// @brief Create a notification sink to receive subscription updates - // v1::UStatus createNotificationSink(); }; } // namespace uprotocol::core::usubscription::v3 diff --git a/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h b/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h index b91b5f001..dee942544 100644 --- a/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h +++ b/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h @@ -1,7 +1,3 @@ -// -// Created by max on 10.05.25. -// - #ifndef USUBSCRIPTIONUURIBUILDER_H #define USUBSCRIPTIONUURIBUILDER_H diff --git a/include/up-cpp/utils/ProtoConverter.h b/include/up-cpp/utils/ProtoConverter.h index ee4123936..d2dbd4291 100644 --- a/include/up-cpp/utils/ProtoConverter.h +++ b/include/up-cpp/utils/ProtoConverter.h @@ -52,7 +52,7 @@ struct ProtoConverter { /// @param subscription_topic the UUri of the topic to unsubscribe from /// @return the built UnsubscribeRequest static UnsubscribeRequest BuildUnSubscribeRequest( - const v1::UUri& subscription_topic); + const v1::UUri& subscription_topic);UnsubscribeRequest BuildUnSubscribeRequest(const v1::UUri& uri, const SubscribeAttributes& attributes); }; }; // namespace uprotocol::utils #endif // UP_CPP_UTILS_PROTOCONVERTER_H diff --git a/src/client/usubscription/v3/RequestBuilder.cpp b/src/client/usubscription/v3/RequestBuilder.cpp new file mode 100644 index 000000000..c46e4ae24 --- /dev/null +++ b/src/client/usubscription/v3/RequestBuilder.cpp @@ -0,0 +1,30 @@ +#include +#include "up-cpp/client/usubscription/v3/RequestBuilder.h" + +namespace uprotocol::core::usubscription::v3 { + + +SubscriptionRequest RequestBuilder::buildSubscriptionRequest( + const v1::UUri& topic) const { + auto attributes = utils::ProtoConverter::BuildSubscribeAttributes( + options_.when_expire, + options_.subscription_details, + options_.sample_period_ms); + + return utils::ProtoConverter::BuildSubscriptionRequest( + topic, attributes); +} + +UnsubscribeRequest RequestBuilder::buildUnsubscribeRequest( + const v1::UUri& topic) { + // auto attributes = utils::ProtoConverter::BuildSubscribeAttributes( + // options_.when_expire, + // options_.subscription_details, + // options_.sample_period_ms); + + return utils::ProtoConverter::BuildUnSubscribeRequest( + topic); +} + + +} // namespace uprotocol::core::usubscription::v3 diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 135b27ead..9acf46b2a 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -30,24 +30,11 @@ auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; // MUST be >= 4 namespace uprotocol::core::usubscription::v3 { RpcClientUSubscription::RpcClientUSubscription( - std::shared_ptr transport, - RpcClientUSubscriptionOptions rpc_client_usubscription_options) - : transport_(std::move(transport)), - rpc_client_usubscription_options_( - std::move(rpc_client_usubscription_options)) { + std::shared_ptr transport) + : transport_(std::move(transport)) { uuri_builder_ = USubscriptionUUriBuilder(); } -SubscriptionRequest RpcClientUSubscription::buildSubscriptionRequest(const v1::UUri& subscription_topic) { - auto attributes = utils::ProtoConverter::BuildSubscribeAttributes( - rpc_client_usubscription_options_.when_expire, - rpc_client_usubscription_options_.subscription_details, - rpc_client_usubscription_options_.sample_period_ms); - - auto subscription_request = utils::ProtoConverter::BuildSubscriptionRequest( - subscription_topic, attributes); - return subscription_request; -} RpcClientUSubscription::ResponseOrStatus RpcClientUSubscription::subscribe( diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp index 76fa0506c..6044df803 100644 --- a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -97,12 +97,10 @@ class RpcClientUSubscriptionTest : public testing::Test { // Negative test case with no source filter TEST_F(RpcClientUSubscriptionTest, ConstructorTestSuccess) { // NOLINT - auto options = - uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); auto rpc_client_usubscription = std::make_unique< uprotocol::core::usubscription::v3::RpcClientUSubscription>( - getMockTransportClient(), options); + getMockTransportClient()); // Verify that the RpcClientUSubscription pointer is not null, indicating // successful @@ -111,9 +109,6 @@ TEST_F(RpcClientUSubscriptionTest, ConstructorTestSuccess) { // NOLINT TEST_F(RpcClientUSubscriptionTest, SubscribeTestSuccess) { // NOLINT - auto options = - uprotocol::core::usubscription::v3::RpcClientUSubscriptionOptions(); - uprotocol::core::usubscription::v3::SubscriptionRequest subscription_request = uprotocol::utils::ProtoConverter::BuildSubscriptionRequest( @@ -122,7 +117,7 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeTestSuccess) { // NOLINT auto rpc_client_usubscription = std::make_unique< uprotocol::core::usubscription::v3::RpcClientUSubscription>( - getMockTransportClient(), options); + getMockTransportClient()); // Verify that the RpcClientUSubscription pointer is not null, indicating // successful From 554cfc9f994363b7db0a138dae3a41f6cfecab8c Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 11 May 2025 12:04:09 +0200 Subject: [PATCH 034/105] added default options to RequestBuilder --- include/up-cpp/client/usubscription/v3/RequestBuilder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/up-cpp/client/usubscription/v3/RequestBuilder.h b/include/up-cpp/client/usubscription/v3/RequestBuilder.h index b2a4d3f0c..fec2cc48f 100644 --- a/include/up-cpp/client/usubscription/v3/RequestBuilder.h +++ b/include/up-cpp/client/usubscription/v3/RequestBuilder.h @@ -28,7 +28,7 @@ struct USubscriptionOptions { struct RequestBuilder { explicit RequestBuilder( - const USubscriptionOptions& options) + const USubscriptionOptions& options = {}) :options_(options){}; SubscriptionRequest buildSubscriptionRequest(const v1::UUri& topic) const; From 52dcb91f56cb39a340f260e99affd3fba95cfef5 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 11 May 2025 12:29:28 +0200 Subject: [PATCH 035/105] did some cleanup --- .../usubscription/v3/RpcClientUSubscription.h | 34 +++---------------- .../v3/USubscriptionUUriBuilder.h | 11 ------ .../v3/USubscriptionUUriBuilder.cpp | 5 +-- 3 files changed, 5 insertions(+), 45 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index e5057a2e9..f8be10437 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -40,53 +40,27 @@ struct RpcClientUSubscription : USubscription { using ListenCallback = transport::UTransport::ListenCallback; using ListenHandle = transport::UTransport::ListenHandle; - /// @brief Create a subscription - /// - /// @param transport Transport to register with. - /// @param subscription_topic Topic to subscribe to. - /// @param callback Function that is called when publish message is - /// received. - /// @param priority Priority of the subscription request. - /// @param subscribe_request_ttl Time to live for the subscription request. - /// @param rpc_client_usubscription_options Additional details for - /// uSubscription service. - // [[nodiscard]] static RpcClientUSubscriptionOrStatus create( - // std::shared_ptr transport, - // const v1::UUri& subscription_topic, ListenCallback&& callback, - // RpcClientUSubscriptionOptions rpc_client_usubscription_options); - /// @brief Subscribe to the topic /// utils::Expected subscribe( const SubscriptionRequest& subscription_request) override; - /// @brief Destructor - ~RpcClientUSubscription() override = default; - - /// This section for test code only delete later - - // protected: /// @brief Constructor /// /// @param transport Transport to register with. - /// @param subscriber_details Additional details about the subscriber. explicit RpcClientUSubscription( std::shared_ptr transport); + /// @brief Destructor + ~RpcClientUSubscription() override = default; + + private: // Transport std::shared_ptr transport_; // URI info about the uSubscription service USubscriptionUUriBuilder uuri_builder_; - - // Allow the protected constructor for this class to be used in make_unique - // inside of create() - // friend std::unique_ptr std::make_unique< - // RpcClientUSubscription, std::shared_ptr, - // const v1::UUri, RpcClientUSubscriptionOptions>( - // std::shared_ptr&&, const v1::UUri&&, - // RpcClientUSubscriptionOptions&&); }; } // namespace uprotocol::core::usubscription::v3 diff --git a/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h b/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h index dee942544..784c21000 100644 --- a/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h +++ b/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h @@ -25,20 +25,9 @@ struct USubscriptionUUriBuilder { /// @return The URI with the specified resource ID. v1::UUri getServiceUriWithResourceId(uint32_t resource_id) const; - /// @brief Get the notification URI. - /// - /// @return The notification URI. - v1::UUri getNotificationUri() const { - v1::UUri uri = base_uri_; // Copy the base URI - uri.set_resource_id(sink_resource_id_); - return uri; - } - private: /// URI for the uSubscription service v1::UUri base_uri_; - /// Resource ID of the notification topic - uint32_t sink_resource_id_; }; } // namespace uprotocol::core::usubscription::v3 diff --git a/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp b/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp index 4cdb3ccf8..61c7d38e5 100644 --- a/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp +++ b/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp @@ -15,14 +15,11 @@ USubscriptionUUriBuilder::USubscriptionUUriBuilder() { service_options.GetExtension(uprotocol::service_version_major); const auto& service_id = service_options.GetExtension(uprotocol::service_id); - const auto& notification_topic = - service_options.GetExtension(uprotocol::notification_topic, 0); // Set the values in the URI base_uri_.set_authority_name(service_name); base_uri_.set_ue_id(service_id); base_uri_.set_ue_version_major(service_version_major); - sink_resource_id_ = notification_topic.id(); } v1::UUri USubscriptionUUriBuilder::getServiceUriWithResourceId(uint32_t resource_id) const { @@ -31,4 +28,4 @@ v1::UUri USubscriptionUUriBuilder::getServiceUriWithResourceId(uint32_t resource return uri; } -} // namespace \ No newline at end of file +} // namespace uprotocol::core::usubscription::v3 \ No newline at end of file From 026b10064d30aae933a38bc9797b25d38539d221 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 11 May 2025 12:34:13 +0200 Subject: [PATCH 036/105] moved constructor --- .../up-cpp/client/usubscription/v3/RpcClientUSubscription.h | 6 ++++-- src/client/usubscription/v3/RpcClientUSubscription.cpp | 6 ------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index f8be10437..67f66e984 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -48,8 +48,10 @@ struct RpcClientUSubscription : USubscription { /// @brief Constructor /// /// @param transport Transport to register with. - explicit RpcClientUSubscription( - std::shared_ptr transport); + explicit RpcClientUSubscription::RpcClientUSubscription( + std::shared_ptr transport) + : transport_(std::move(transport)), uuri_builder_(USubscriptionUUriBuilder()) {} + /// @brief Destructor ~RpcClientUSubscription() override = default; diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 9acf46b2a..ecf41fd58 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -29,12 +29,6 @@ auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; // MUST be >= 4 namespace uprotocol::core::usubscription::v3 { -RpcClientUSubscription::RpcClientUSubscription( - std::shared_ptr transport) - : transport_(std::move(transport)) { - uuri_builder_ = USubscriptionUUriBuilder(); -} - RpcClientUSubscription::ResponseOrStatus RpcClientUSubscription::subscribe( From 77fca3872cc470091a5c99e4088195294089ffa2 Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 12 May 2025 11:04:22 +0200 Subject: [PATCH 037/105] fixed RpcClientUSubscription constructor in header --- include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index 67f66e984..8ff74d445 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -48,7 +48,7 @@ struct RpcClientUSubscription : USubscription { /// @brief Constructor /// /// @param transport Transport to register with. - explicit RpcClientUSubscription::RpcClientUSubscription( + explicit RpcClientUSubscription( std::shared_ptr transport) : transport_(std::move(transport)), uuri_builder_(USubscriptionUUriBuilder()) {} From 8d26515ae7991a6fc3d3713f1cff05b51ed662c0 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 13 May 2025 20:42:38 +0200 Subject: [PATCH 038/105] set ue major version to 3 --- .../up-cpp/client/usubscription/v3/RpcClientUSubscription.h | 2 +- src/client/usubscription/v3/USubscriptionUUriBuilder.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index 8ff74d445..6cf30a767 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -50,7 +50,7 @@ struct RpcClientUSubscription : USubscription { /// @param transport Transport to register with. explicit RpcClientUSubscription( std::shared_ptr transport) - : transport_(std::move(transport)), uuri_builder_(USubscriptionUUriBuilder()) {} + : transport_(std::move(transport)){} /// @brief Destructor diff --git a/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp b/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp index 61c7d38e5..a316ce44e 100644 --- a/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp +++ b/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp @@ -11,8 +11,8 @@ USubscriptionUUriBuilder::USubscriptionUUriBuilder() { // Get the service options const auto& service_name = service_options.GetExtension(uprotocol::service_name); - const auto& service_version_major = - service_options.GetExtension(uprotocol::service_version_major); + const auto& service_version_major =3; + // service_options.GetExtension(uprotocol::service_version_major); const auto& service_id = service_options.GetExtension(uprotocol::service_id); From 83e886df7a732d439cff981c5259a37a244e3eff Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 13 May 2025 20:47:00 +0200 Subject: [PATCH 039/105] Revert "fixed RpcClientUSubscription constructor in header" This reverts commit 51241cd55955dfe0be015803f8cc6a621ac4a59f. --- include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index 6cf30a767..b9f3430ed 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -48,7 +48,7 @@ struct RpcClientUSubscription : USubscription { /// @brief Constructor /// /// @param transport Transport to register with. - explicit RpcClientUSubscription( + explicit RpcClientUSubscription::RpcClientUSubscription( std::shared_ptr transport) : transport_(std::move(transport)){} From 49f61fddf4e0f3f246fe8e9de9173da07b895dd5 Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 17 May 2025 09:06:02 +0200 Subject: [PATCH 040/105] fixed mistake in constructure signature --- include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index b9f3430ed..6cf30a767 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -48,7 +48,7 @@ struct RpcClientUSubscription : USubscription { /// @brief Constructor /// /// @param transport Transport to register with. - explicit RpcClientUSubscription::RpcClientUSubscription( + explicit RpcClientUSubscription( std::shared_ptr transport) : transport_(std::move(transport)){} From 67d94c874411c656ede2671df9ea889ebc639c2e Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 17 May 2025 09:14:30 +0200 Subject: [PATCH 041/105] fix --- include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index 6cf30a767..06f802aec 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -14,9 +14,7 @@ #include #include -#include #include -#include #include #include "up-cpp/client/usubscription/v3/USubscription.h" From 0849974a3fedd423207d33a07bbd232c291aa69f Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 17 May 2025 09:18:34 +0200 Subject: [PATCH 042/105] tmp disabled test for rpcclientusubscription --- .../v3/RpcClientUSubscriptionTest.cpp | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp index 6044df803..4347a4f55 100644 --- a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -107,25 +107,25 @@ TEST_F(RpcClientUSubscriptionTest, ConstructorTestSuccess) { // NOLINT ASSERT_NE(rpc_client_usubscription, nullptr); } -TEST_F(RpcClientUSubscriptionTest, SubscribeTestSuccess) { // NOLINT - - uprotocol::core::usubscription::v3::SubscriptionRequest - subscription_request = - uprotocol::utils::ProtoConverter::BuildSubscriptionRequest( - getSubscriptionUUri(), - uprotocol::core::usubscription::v3::SubscribeAttributes()); - - auto rpc_client_usubscription = std::make_unique< - uprotocol::core::usubscription::v3::RpcClientUSubscription>( - getMockTransportClient()); - - // Verify that the RpcClientUSubscription pointer is not null, indicating - // successful - ASSERT_NE(rpc_client_usubscription, nullptr); - - auto result = rpc_client_usubscription->subscribe(subscription_request); - - ASSERT_NE(&result, nullptr); -} +// TEST_F(RpcClientUSubscriptionTest, SubscribeTestSuccess) { // NOLINT +// +// uprotocol::core::usubscription::v3::SubscriptionRequest +// subscription_request = +// uprotocol::utils::ProtoConverter::BuildSubscriptionRequest( +// getSubscriptionUUri(), +// uprotocol::core::usubscription::v3::SubscribeAttributes()); +// +// auto rpc_client_usubscription = std::make_unique< +// uprotocol::core::usubscription::v3::RpcClientUSubscription>( +// getMockTransportClient()); +// +// // Verify that the RpcClientUSubscription pointer is not null, indicating +// // successful +// ASSERT_NE(rpc_client_usubscription, nullptr); +// +// auto result = rpc_client_usubscription->subscribe(subscription_request); +// +// ASSERT_NE(&result, nullptr); +// } } // namespace From f8fb57d98e4c9944e14876088de5e7e61c427226 Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 17 May 2025 21:43:32 +0200 Subject: [PATCH 043/105] fixed error handling --- src/client/usubscription/v3/RpcClientUSubscription.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index ecf41fd58..525263a7e 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -47,7 +47,7 @@ RpcClientUSubscription::subscribe( if (!message_or_status.has_value()) { return ResponseOrStatus( - utils::Unexpected(std::move(message_or_status.error()))); + utils::Unexpected(message_or_status.error())); } SubscriptionResponse subscription_response; @@ -55,8 +55,9 @@ RpcClientUSubscription::subscribe( if (subscription_response.topic().SerializeAsString() != subscription_request.topic().SerializeAsString()) { + //TODO(max) return correct UStatus return ResponseOrStatus( - utils::Unexpected(std::move(message_or_status.error()))); + utils::Unexpected(v1::UStatus())); } return ResponseOrStatus(std::move(subscription_response)); From 5bcf05befc38f647ce97d1daeab28937d17cb150 Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 17 May 2025 21:53:35 +0200 Subject: [PATCH 044/105] added logging to debug --- src/client/usubscription/v3/RpcClientUSubscription.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 525263a7e..8ae8b10f9 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -56,6 +56,7 @@ RpcClientUSubscription::subscribe( if (subscription_response.topic().SerializeAsString() != subscription_request.topic().SerializeAsString()) { //TODO(max) return correct UStatus + spdlog::debug("topics do not match. response {}, request {}", subscription_response.topic().DebugString(), subscription_request.topic().DebugString()); return ResponseOrStatus( utils::Unexpected(v1::UStatus())); } From 90ab2bb88f5d15dfe8b93e4e947b341e61e73dba Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 17 May 2025 21:57:20 +0200 Subject: [PATCH 045/105] better logging --- src/client/usubscription/v3/RpcClientUSubscription.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 8ae8b10f9..f51feda04 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -56,7 +56,9 @@ RpcClientUSubscription::subscribe( if (subscription_response.topic().SerializeAsString() != subscription_request.topic().SerializeAsString()) { //TODO(max) return correct UStatus - spdlog::debug("topics do not match. response {}, request {}", subscription_response.topic().DebugString(), subscription_request.topic().DebugString()); + spdlog::debug("topics do not match."); + spdlog::debug("subscription_request: {}", subscription_request.topic().DebugString()); + spdlog::debug("subscription_response: {}", subscription_response.topic().DebugString()); return ResponseOrStatus( utils::Unexpected(v1::UStatus())); } From 942e8aca8bc6310bf014352bf0ad06c6554239e0 Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 17 May 2025 22:03:00 +0200 Subject: [PATCH 046/105] test --- src/client/usubscription/v3/RpcClientUSubscription.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index f51feda04..0fd5d4ed3 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -51,7 +51,13 @@ RpcClientUSubscription::subscribe( } SubscriptionResponse subscription_response; - subscription_response.ParseFromString(message_or_status.value().payload()); + if (!subscription_response.ParseFromString(message_or_status.value().payload())) { + spdlog::error("Error parsing response payload."); + return ResponseOrStatus( + utils::Unexpected(v1::UStatus())); + } + + spdlog::debug("response: {}", subscription_response.DebugString()); if (subscription_response.topic().SerializeAsString() != subscription_request.topic().SerializeAsString()) { From 6a96c344628097014739a62d6bddfb816129d5ea Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 18 May 2025 09:58:26 +0200 Subject: [PATCH 047/105] test --- src/client/usubscription/v3/RpcClientUSubscription.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 0fd5d4ed3..b800ac605 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -50,9 +50,10 @@ RpcClientUSubscription::subscribe( utils::Unexpected(message_or_status.error())); } + spdlog::debug("response UMessage: {}", message_or_status.value().DebugString()); SubscriptionResponse subscription_response; if (!subscription_response.ParseFromString(message_or_status.value().payload())) { - spdlog::error("Error parsing response payload."); + spdlog::error("subscribe: Error parsing response payload."); return ResponseOrStatus( utils::Unexpected(v1::UStatus())); } From 5a6ac0841cb3f422edf1c5822767f8c5050b4a04 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 18 May 2025 13:36:41 +0200 Subject: [PATCH 048/105] changed serialization --- src/client/usubscription/v3/RpcClientUSubscription.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index b800ac605..fe1929972 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -52,11 +52,18 @@ RpcClientUSubscription::subscribe( spdlog::debug("response UMessage: {}", message_or_status.value().DebugString()); SubscriptionResponse subscription_response; - if (!subscription_response.ParseFromString(message_or_status.value().payload())) { + const google::protobuf::Any any; + + if (!any.UnpackTo(&subscription_response)) { spdlog::error("subscribe: Error parsing response payload."); return ResponseOrStatus( utils::Unexpected(v1::UStatus())); } + // if (!subscription_response.ParseFromString(message_or_status.value().payload())) { + // spdlog::error("subscribe: Error parsing response payload."); + // return ResponseOrStatus( + // utils::Unexpected(v1::UStatus())); + // } spdlog::debug("response: {}", subscription_response.DebugString()); From 2b1f904377eeb93a2c1d7f5191fcfc949e1d64af Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 18 May 2025 13:58:08 +0200 Subject: [PATCH 049/105] using any type for serialization --- .../v3/RpcClientUSubscription.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index fe1929972..c3c281a9b 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -39,7 +39,15 @@ RpcClientUSubscription::subscribe( RESOURCE_ID_SUBSCRIBE), priority, SUBSCRIPTION_REQUEST_TTL); - datamodel::builder::Payload payload(subscription_request); + google::protobuf::Any any_request; + + if (!any_request.PackFrom(subscription_request)) { + spdlog::error("subscribe: There was an error when serializing the subscription request."); + } + // datamodel::builder::Payload payload; + // any.PackFrom(subscription_request); + // datamodel::builder::Payload payload(subscription_request); + datamodel::builder::Payload payload(any_request); auto invoke_future = rpc_client.invokeMethod(std::move(payload)); @@ -51,11 +59,15 @@ RpcClientUSubscription::subscribe( } spdlog::debug("response UMessage: {}", message_or_status.value().DebugString()); + google::protobuf::Any any_response; SubscriptionResponse subscription_response; - const google::protobuf::Any any; - if (!any.UnpackTo(&subscription_response)) { + if (!any_response.ParseFromString(message_or_status.value().payload())) { spdlog::error("subscribe: Error parsing response payload."); + } + + if (!any_response.UnpackTo(&subscription_response)) { + spdlog::error("subscribe: Error when unpacking any."); return ResponseOrStatus( utils::Unexpected(v1::UStatus())); } From 68d8f92dd8adc8c5ce858e876d48808fa975fbc6 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Mon, 19 May 2025 13:48:07 +0200 Subject: [PATCH 050/105] Added method unsubscribe. Not implemented yet --- .../up-cpp/client/usubscription/v3/RpcClientUSubscription.h | 5 +++++ include/up-cpp/client/usubscription/v3/USubscription.h | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index 06f802aec..c649c95fd 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -42,6 +42,11 @@ struct RpcClientUSubscription : USubscription { /// utils::Expected subscribe( const SubscriptionRequest& subscription_request) override; + + /// @brief Unsubscribe from the topic + /// + utils::Expected unsubscribe( + const UnsubscribeRequest& subscription_request) override; /// @brief Constructor /// diff --git a/include/up-cpp/client/usubscription/v3/USubscription.h b/include/up-cpp/client/usubscription/v3/USubscription.h index b030346ed..7b991c7de 100644 --- a/include/up-cpp/client/usubscription/v3/USubscription.h +++ b/include/up-cpp/client/usubscription/v3/USubscription.h @@ -17,8 +17,8 @@ struct USubscription { virtual ResponseOrStatus subscribe( const SubscriptionRequest& subscription_request) = 0; - // virtual UnsubscribeResponse unsubscribe(const UnsubscribeRequest& - // unsubscribe_request) = 0; + virtual ResponseOrStatus unsubscribe(const UnsubscribeRequest& + unsubscribe_request) = 0; // virtual FetchSubscriptionsResponse fetch_subscriptions(const // FetchSubscriptionsRequest& fetch_subscribers_request) = 0; From 2b7eb13d4f8a2a368a332e0a1bc48b35003f48e5 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Mon, 19 May 2025 13:53:52 +0200 Subject: [PATCH 051/105] Added template to fill with live for unsubscribe method --- src/client/usubscription/v3/RpcClientUSubscription.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index c3c281a9b..85c8d605f 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -92,4 +92,12 @@ RpcClientUSubscription::subscribe( return ResponseOrStatus(std::move(subscription_response)); } +RpcClientUSubscription::ResponseOrStatus +RpcClientUSubscription::unsubscribe( + const UnsubscribeRequest& unsubscribe_request) { + + UnsubscribeResponse unsubscribe_response; + return ResponseOrStatus(std::move(unsubscribe_response)); +} + } // namespace uprotocol::core::usubscription::v3 From 6f6f7aeb83fa6479c07c56838d551bdb964574e1 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Mon, 19 May 2025 13:55:13 +0200 Subject: [PATCH 052/105] Remove one line in subscribe method --- src/client/usubscription/v3/RpcClientUSubscription.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 85c8d605f..7027a9432 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -49,9 +49,7 @@ RpcClientUSubscription::subscribe( // datamodel::builder::Payload payload(subscription_request); datamodel::builder::Payload payload(any_request); - auto invoke_future = rpc_client.invokeMethod(std::move(payload)); - - auto message_or_status = invoke_future.get(); + auto message_or_status = rpc_client.invokeMethod(std::move(payload)).get(); if (!message_or_status.has_value()) { return ResponseOrStatus( From 450a28f54811ccc89b1959076296a72733849f12 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Mon, 19 May 2025 18:30:41 +0200 Subject: [PATCH 053/105] Uncommented RpcClientUSubscription Test. Clean up subscribe method by adding extract proto-method and add protoToPayload-Method. --- .../usubscription/v3/RpcClientUSubscription.h | 5 ++- include/up-cpp/utils/ProtoConverter.h | 11 +++++ .../v3/RpcClientUSubscription.cpp | 39 +++++++--------- src/utils/ProtoConverter.cpp | 44 +++++++++++++++++++ .../v3/RpcClientUSubscriptionTest.cpp | 13 +++--- 5 files changed, 82 insertions(+), 30 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index c649c95fd..e37a7dfbc 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -37,7 +37,10 @@ struct RpcClientUSubscription : USubscription { utils::Expected, v1::UStatus>; using ListenCallback = transport::UTransport::ListenCallback; using ListenHandle = transport::UTransport::ListenHandle; - + + template + Response invokeResponse(communication::RpcClient rpc_client); + /// @brief Subscribe to the topic /// utils::Expected subscribe( diff --git a/include/up-cpp/utils/ProtoConverter.h b/include/up-cpp/utils/ProtoConverter.h index d2dbd4291..eb297a0ad 100644 --- a/include/up-cpp/utils/ProtoConverter.h +++ b/include/up-cpp/utils/ProtoConverter.h @@ -3,9 +3,13 @@ #include #include +#include +#include #include #include +#include "up-cpp/datamodel/builder/Payload.h" +#include "up-cpp/utils/Expected.h" namespace uprotocol::utils { using uprotocol::core::usubscription::v3::SubscribeAttributes; @@ -53,6 +57,13 @@ struct ProtoConverter { /// @return the built UnsubscribeRequest static UnsubscribeRequest BuildUnSubscribeRequest( const v1::UUri& subscription_topic);UnsubscribeRequest BuildUnSubscribeRequest(const v1::UUri& uri, const SubscribeAttributes& attributes); + + template + static utils::Expected extractFromProtobuf(const v1::UMessage& message); + + template + static utils::Expected protoToPayload(const T& proto); + }; }; // namespace uprotocol::utils #endif // UP_CPP_UTILS_PROTOCONVERTER_H diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 7027a9432..d7581867a 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -20,6 +20,7 @@ #include "up-cpp/communication/RpcClient.h" #include "up-cpp/transport/UTransport.h" +#include "up-cpp/utils/ProtoConverter.h" constexpr uint16_t RESOURCE_ID_SUBSCRIBE = 0x0001; // TODO(lennart) see default_call_options() for the request in Rust @@ -29,6 +30,10 @@ auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; // MUST be >= 4 namespace uprotocol::core::usubscription::v3 { +template +Response RpcClientUSubscription::invokeResponse(communication::RpcClient rpc_client){ + +} RpcClientUSubscription::ResponseOrStatus RpcClientUSubscription::subscribe( @@ -44,9 +49,6 @@ RpcClientUSubscription::subscribe( if (!any_request.PackFrom(subscription_request)) { spdlog::error("subscribe: There was an error when serializing the subscription request."); } - // datamodel::builder::Payload payload; - // any.PackFrom(subscription_request); - // datamodel::builder::Payload payload(subscription_request); datamodel::builder::Payload payload(any_request); auto message_or_status = rpc_client.invokeMethod(std::move(payload)).get(); @@ -57,34 +59,27 @@ RpcClientUSubscription::subscribe( } spdlog::debug("response UMessage: {}", message_or_status.value().DebugString()); - google::protobuf::Any any_response; SubscriptionResponse subscription_response; - if (!any_response.ParseFromString(message_or_status.value().payload())) { - spdlog::error("subscribe: Error parsing response payload."); - } - - if (!any_response.UnpackTo(&subscription_response)) { - spdlog::error("subscribe: Error when unpacking any."); + auto response_or_status = utils::ProtoConverter::extractFromProtobuf(message_or_status.value()); + + if (!response_or_status.has_value()){ + spdlog::error("subscribe: Error when extracting response from protobuf."); return ResponseOrStatus( - utils::Unexpected(v1::UStatus())); + utils::Unexpected(response_or_status.error())); } - // if (!subscription_response.ParseFromString(message_or_status.value().payload())) { - // spdlog::error("subscribe: Error parsing response payload."); - // return ResponseOrStatus( - // utils::Unexpected(v1::UStatus())); - // } - spdlog::debug("response: {}", subscription_response.DebugString()); + subscription_response = response_or_status.value(); + + spdlog::debug("subscribe: response: {}", subscription_response.DebugString()); if (subscription_response.topic().SerializeAsString() != subscription_request.topic().SerializeAsString()) { - //TODO(max) return correct UStatus - spdlog::debug("topics do not match."); - spdlog::debug("subscription_request: {}", subscription_request.topic().DebugString()); - spdlog::debug("subscription_response: {}", subscription_response.topic().DebugString()); + v1::UStatus status; + status.set_code(v1::UCode::INTERNAL); + status.set_message("subscribe: topics do not match."); return ResponseOrStatus( - utils::Unexpected(v1::UStatus())); + utils::Unexpected(status)); } return ResponseOrStatus(std::move(subscription_response)); diff --git a/src/utils/ProtoConverter.cpp b/src/utils/ProtoConverter.cpp index c4159ee9f..9726fee3f 100644 --- a/src/utils/ProtoConverter.cpp +++ b/src/utils/ProtoConverter.cpp @@ -1,4 +1,9 @@ #include "up-cpp/utils/ProtoConverter.h" +#include +#include +#include +#include "up-cpp/datamodel/builder/Payload.h" +#include "up-cpp/utils/Expected.h" namespace uprotocol::utils { google::protobuf::Timestamp ProtoConverter::ConvertToProtoTimestamp( @@ -76,4 +81,43 @@ UnsubscribeRequest ProtoConverter::BuildUnSubscribeRequest( return unsubscribe_request; } +template +utils::Expected ProtoConverter::extractFromProtobuf(const v1::UMessage& message) { + google::protobuf::Any any; + + if (!any.ParseFromString(message.payload())) { + spdlog::error("extractFromProtobuf: Error parsing response payload."); + } + + T response; + + if (!any.UnpackTo(&response)) { + v1::UStatus status; + status.set_code(v1::UCode::INTERNAL); + status.set_message("extractFromProtobuf: Error when unpacking any."); + return utils::Expected( + utils::Unexpected(status)); + } + + return response; +} + +template +utils::Expected protoToPayload(const T& proto){ + + google::protobuf::Any any; + + if (!any.PackFrom(proto)) { + v1::UStatus status; + status.set_code(v1::UCode::INTERNAL); + status.set_message("protoToPayload: There was an error when serializing the subscription request."); + return utils::Expected( + utils::Unexpected(status)); + } + + datamodel::builder::Payload payload(any); + + return utils::Expected(payload); +} + } // namespace uprotocol::utils diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp index 4347a4f55..b5290d707 100644 --- a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -95,17 +95,16 @@ class RpcClientUSubscriptionTest : public testing::Test { }; // Negative test case with no source filter -TEST_F(RpcClientUSubscriptionTest, ConstructorTestSuccess) { // NOLINT +// TEST_F(RpcClientUSubscriptionTest, ConstructorTestSuccess) { // NOLINT - - auto rpc_client_usubscription = std::make_unique< - uprotocol::core::usubscription::v3::RpcClientUSubscription>( - getMockTransportClient()); + // auto rpc_client_usubscription = std::make_unique< + // uprotocol::core::usubscription::v3::RpcClientUSubscription>( + // getMockTransportClient()); // Verify that the RpcClientUSubscription pointer is not null, indicating // successful - ASSERT_NE(rpc_client_usubscription, nullptr); -} + // ASSERT_NE(rpc_client_usubscription, nullptr); +// } // TEST_F(RpcClientUSubscriptionTest, SubscribeTestSuccess) { // NOLINT // From d9d129705a163f66ac567cf50b65ed6faf835e34 Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 19 May 2025 22:06:06 +0200 Subject: [PATCH 054/105] fixed linker error --- include/up-cpp/utils/ProtoConverter.h | 46 +++++++++++++++++-- src/utils/ProtoConverter.cpp | 39 ---------------- .../v3/RpcClientUSubscriptionTest.cpp | 14 +++--- 3 files changed, 49 insertions(+), 50 deletions(-) diff --git a/include/up-cpp/utils/ProtoConverter.h b/include/up-cpp/utils/ProtoConverter.h index eb297a0ad..f3ebb1d22 100644 --- a/include/up-cpp/utils/ProtoConverter.h +++ b/include/up-cpp/utils/ProtoConverter.h @@ -56,13 +56,51 @@ struct ProtoConverter { /// @param subscription_topic the UUri of the topic to unsubscribe from /// @return the built UnsubscribeRequest static UnsubscribeRequest BuildUnSubscribeRequest( - const v1::UUri& subscription_topic);UnsubscribeRequest BuildUnSubscribeRequest(const v1::UUri& uri, const SubscribeAttributes& attributes); + const v1::UUri& subscription_topic); + static UnsubscribeRequest BuildUnSubscribeRequest(const v1::UUri& uri, const SubscribeAttributes& attributes); template - static utils::Expected extractFromProtobuf(const v1::UMessage& message); - + static utils::Expected extractFromProtobuf(const v1::UMessage& message) + { + google::protobuf::Any any; + + if (!any.ParseFromString(message.payload())) { + v1::UStatus status; + status.set_code(v1::UCode::INTERNAL); + status.set_message("extractFromProtobuf: Error when parsing payload."); + return utils::Expected( + utils::Unexpected(status)); + } + + T response; + + if (!any.UnpackTo(&response)) { + v1::UStatus status; + status.set_code(v1::UCode::INTERNAL); + status.set_message("extractFromProtobuf: Error when unpacking any."); + return utils::Expected( + utils::Unexpected(status)); + } + + return Expected(response); + } + template - static utils::Expected protoToPayload(const T& proto); + static utils::Expected protoToPayload(const T& proto) { + google::protobuf::Any any; + + if (!any.PackFrom(proto)) { + v1::UStatus status; + status.set_code(v1::UCode::INTERNAL); + status.set_message("protoToPayload: There was an error when serializing the subscription request."); + return utils::Expected( + utils::Unexpected(status)); + } + + const datamodel::builder::Payload payload(any); + + return utils::Expected(payload); + } }; }; // namespace uprotocol::utils diff --git a/src/utils/ProtoConverter.cpp b/src/utils/ProtoConverter.cpp index 9726fee3f..f62e20407 100644 --- a/src/utils/ProtoConverter.cpp +++ b/src/utils/ProtoConverter.cpp @@ -81,43 +81,4 @@ UnsubscribeRequest ProtoConverter::BuildUnSubscribeRequest( return unsubscribe_request; } -template -utils::Expected ProtoConverter::extractFromProtobuf(const v1::UMessage& message) { - google::protobuf::Any any; - - if (!any.ParseFromString(message.payload())) { - spdlog::error("extractFromProtobuf: Error parsing response payload."); - } - - T response; - - if (!any.UnpackTo(&response)) { - v1::UStatus status; - status.set_code(v1::UCode::INTERNAL); - status.set_message("extractFromProtobuf: Error when unpacking any."); - return utils::Expected( - utils::Unexpected(status)); - } - - return response; -} - -template -utils::Expected protoToPayload(const T& proto){ - - google::protobuf::Any any; - - if (!any.PackFrom(proto)) { - v1::UStatus status; - status.set_code(v1::UCode::INTERNAL); - status.set_message("protoToPayload: There was an error when serializing the subscription request."); - return utils::Expected( - utils::Unexpected(status)); - } - - datamodel::builder::Payload payload(any); - - return utils::Expected(payload); -} - } // namespace uprotocol::utils diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp index b5290d707..bdaa2c36a 100644 --- a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -94,17 +94,17 @@ class RpcClientUSubscriptionTest : public testing::Test { ~RpcClientUSubscriptionTest() override = default; }; -// Negative test case with no source filter -// TEST_F(RpcClientUSubscriptionTest, ConstructorTestSuccess) { // NOLINT +//Negative test case with no source filter +TEST_F(RpcClientUSubscriptionTest, ConstructorTestSuccess) { // NOLINT - // auto rpc_client_usubscription = std::make_unique< - // uprotocol::core::usubscription::v3::RpcClientUSubscription>( - // getMockTransportClient()); + auto rpc_client_usubscription = std::make_unique< + uprotocol::core::usubscription::v3::RpcClientUSubscription>( + getMockTransportClient()); // Verify that the RpcClientUSubscription pointer is not null, indicating // successful - // ASSERT_NE(rpc_client_usubscription, nullptr); -// } + ASSERT_NE(rpc_client_usubscription, nullptr); +} // TEST_F(RpcClientUSubscriptionTest, SubscribeTestSuccess) { // NOLINT // From 4a0e4fc1a798d7f4b777dee9fe00d112ad9aee2f Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Tue, 20 May 2025 18:04:50 +0200 Subject: [PATCH 055/105] Include protoToPayload Method in code --- src/client/usubscription/v3/RpcClientUSubscription.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index d7581867a..d2327c2cf 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -44,12 +44,13 @@ RpcClientUSubscription::subscribe( RESOURCE_ID_SUBSCRIBE), priority, SUBSCRIPTION_REQUEST_TTL); - google::protobuf::Any any_request; + auto payload_or_status = utils::ProtoConverter::protoToPayload(subscription_request); - if (!any_request.PackFrom(subscription_request)) { - spdlog::error("subscribe: There was an error when serializing the subscription request."); + if(payload_or_status.has_value()){ + return ResponseOrStatus( + utils::Unexpected(payload_or_status.error())); } - datamodel::builder::Payload payload(any_request); + datamodel::builder::Payload payload(payload_or_status.value()); auto message_or_status = rpc_client.invokeMethod(std::move(payload)).get(); From 1bb9d453ed80b5088d221a2921817c4a60303510 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Tue, 20 May 2025 18:22:11 +0200 Subject: [PATCH 056/105] Added comments in ProtoConverter --- include/up-cpp/utils/ProtoConverter.h | 50 +++++++++++++++++++++------ 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/include/up-cpp/utils/ProtoConverter.h b/include/up-cpp/utils/ProtoConverter.h index f3ebb1d22..a82ad4d82 100644 --- a/include/up-cpp/utils/ProtoConverter.h +++ b/include/up-cpp/utils/ProtoConverter.h @@ -12,6 +12,10 @@ #include "up-cpp/utils/Expected.h" namespace uprotocol::utils { +template +using TOrStatus = utils::Expected; +using UnexpectedStatus = utils::Unexpected; +using PayloadOrStatus = utils::Expected; using uprotocol::core::usubscription::v3::SubscribeAttributes; using uprotocol::core::usubscription::v3::SubscriberInfo; using uprotocol::core::usubscription::v3::SubscriptionRequest; @@ -59,8 +63,20 @@ struct ProtoConverter { const v1::UUri& subscription_topic); static UnsubscribeRequest BuildUnSubscribeRequest(const v1::UUri& uri, const SubscribeAttributes& attributes); + /** + * @brief Deserializes a protobuf message from a given payload. + * + * Parses the payload in `v1::UMessage` using `google::protobuf::Any`, returning a deserialized object of type `T` + * or an error if parsing fails. + * + * @tparam T The type to deserialize the message into. + * + * @param message The `v1::UMessage` containing the payload. + * + * @return `TOrStatus` with the deserialized object or an error status. + */ template - static utils::Expected extractFromProtobuf(const v1::UMessage& message) + static TOrStatus extractFromProtobuf(const v1::UMessage& message) { google::protobuf::Any any; @@ -68,8 +84,8 @@ struct ProtoConverter { v1::UStatus status; status.set_code(v1::UCode::INTERNAL); status.set_message("extractFromProtobuf: Error when parsing payload."); - return utils::Expected( - utils::Unexpected(status)); + return TOrStatus( + UnexpectedStatus(status)); } T response; @@ -78,28 +94,40 @@ struct ProtoConverter { v1::UStatus status; status.set_code(v1::UCode::INTERNAL); status.set_message("extractFromProtobuf: Error when unpacking any."); - return utils::Expected( - utils::Unexpected(status)); + return TOrStatus( + UnexpectedStatus(status)); } - return Expected(response); + return TOrStatus(response); } - + + /** + * @brief Serializes a protobuf object into a payload. + * + * Converts the given `proto` object to a payload using `google::protobuf::Any`. + * Returns the payload or an error status if serialization fails. + * + * @tparam T The type of the protobuf object to serialize. + * + * @param proto The protobuf object to be converted into a payload. + * + * @return `PayloadOrStatus` containing the payload or an error status. + */ template - static utils::Expected protoToPayload(const T& proto) { + static PayloadOrStatus protoToPayload(const T& proto) { google::protobuf::Any any; if (!any.PackFrom(proto)) { v1::UStatus status; status.set_code(v1::UCode::INTERNAL); status.set_message("protoToPayload: There was an error when serializing the subscription request."); - return utils::Expected( - utils::Unexpected(status)); + return PayloadOrStatus( + UnexpectedStatus(status)); } const datamodel::builder::Payload payload(any); - return utils::Expected(payload); + return PayloadOrStatus(payload); } }; From 18d473baa9d948973826aec072c4719d1776b144 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Tue, 20 May 2025 18:34:07 +0200 Subject: [PATCH 057/105] Move ConsumerOptions to USubscriptionOptions in RequestBuilder.h --- .../up-cpp/client/usubscription/v3/Consumer.h | 32 ++++--------------- .../client/usubscription/v3/RequestBuilder.h | 7 ++-- src/client/usubscription/v3/Consumer.cpp | 7 ++-- .../client/usubscription/v3/ConsumerTest.cpp | 7 ++-- 4 files changed, 19 insertions(+), 34 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/Consumer.h b/include/up-cpp/client/usubscription/v3/Consumer.h index 2fed6ab4b..d13cc3ff8 100644 --- a/include/up-cpp/client/usubscription/v3/Consumer.h +++ b/include/up-cpp/client/usubscription/v3/Consumer.h @@ -19,6 +19,7 @@ #include #include #include +#include "RequestBuilder.h" #include @@ -28,27 +29,6 @@ using uprotocol::core::usubscription::v3::UnsubscribeRequest; using uprotocol::core::usubscription::v3::Update; using uprotocol::core::usubscription::v3::uSubscription; -/** - * @struct ConsumerOptions - * @brief Additional details for uSubscription service. - * - * Each member represents an optional parameter for the uSubscription service. - */ -struct ConsumerOptions { - /// Permission level of the subscription request - std::optional permission_level; - /// TAP token for access. - std::optional token; - /// Expiration time of the subscription. - std::optional when_expire; - /// Sample period for the subscription messages in milliseconds. - std::optional sample_period_ms; - /// Details of the subscriber. - std::optional subscriber_details; - /// Details of the subscription. - std::optional subscription_details; -}; - /// @struct uSubscriptionUUriBuilder /// @brief Structure to build uSubscription request URIs. /// @@ -133,7 +113,7 @@ struct Consumer { const v1::UUri& subscription_topic, ListenCallback&& callback, v1::UPriority priority, std::chrono::milliseconds subscription_request_ttl, - ConsumerOptions consumer_options); + core::usubscription::v3::USubscriptionOptions consumer_options); /// @brief Unsubscribe from the topic and call uSubscription service to /// close the subscription. @@ -160,7 +140,7 @@ struct Consumer { /// @param subscriber_details Additional details about the subscriber. Consumer(std::shared_ptr transport, v1::UUri subscription_topic, - ConsumerOptions consumer_options = {}); + core::usubscription::v3::USubscriptionOptions consumer_options = {}); private: // Transport @@ -169,7 +149,7 @@ struct Consumer { // Topic to subscribe to const v1::UUri subscription_topic_; // Additional details about uSubscription service - ConsumerOptions consumer_options_; + core::usubscription::v3::USubscriptionOptions consumer_options_; // URI info about the uSubscription service USubscriptionUUriBuilder uSubscriptionUUriBuilder_; @@ -191,10 +171,10 @@ struct Consumer { friend std::unique_ptr std::make_unique, const uprotocol::v1::UUri, - uprotocol::client::usubscription::v3::ConsumerOptions>( + uprotocol::core::usubscription::v3::USubscriptionOptions>( std::shared_ptr&&, const uprotocol::v1::UUri&&, - uprotocol::client::usubscription::v3::ConsumerOptions&&); + uprotocol::core::usubscription::v3::USubscriptionOptions&&); /// @brief Build SubscriptionRequest for subscription request SubscriptionRequest buildSubscriptionRequest(); diff --git a/include/up-cpp/client/usubscription/v3/RequestBuilder.h b/include/up-cpp/client/usubscription/v3/RequestBuilder.h index fec2cc48f..fb5f00b9f 100644 --- a/include/up-cpp/client/usubscription/v3/RequestBuilder.h +++ b/include/up-cpp/client/usubscription/v3/RequestBuilder.h @@ -1,10 +1,13 @@ #ifndef REQUESTBUILDER_H #define REQUESTBUILDER_H #include + +#include #include "up-cpp/client/usubscription/v3/RpcClientUSubscription.h" namespace uprotocol::core::usubscription::v3 { + /** * @struct USubscriptionOptions * @brief Additional details for uSubscription service. @@ -28,8 +31,8 @@ struct USubscriptionOptions { struct RequestBuilder { explicit RequestBuilder( - const USubscriptionOptions& options = {}) - :options_(options){}; + USubscriptionOptions options = {}) + :options_(std::move(options)){}; SubscriptionRequest buildSubscriptionRequest(const v1::UUri& topic) const; diff --git a/src/client/usubscription/v3/Consumer.cpp b/src/client/usubscription/v3/Consumer.cpp index 0217b63ea..bb9bf4311 100644 --- a/src/client/usubscription/v3/Consumer.cpp +++ b/src/client/usubscription/v3/Consumer.cpp @@ -12,12 +12,13 @@ #include #include +#include "up-cpp/client/usubscription/v3/RequestBuilder.h" namespace uprotocol::client::usubscription::v3 { Consumer::Consumer(std::shared_ptr transport, v1::UUri subscription_topic, - ConsumerOptions consumer_options) + core::usubscription::v3::USubscriptionOptions consumer_options) : transport_(std::move(transport)), subscription_topic_(std::move(subscription_topic)), consumer_options_(std::move(consumer_options)), @@ -30,11 +31,11 @@ Consumer::Consumer(std::shared_ptr transport, std::shared_ptr transport, const v1::UUri& subscription_topic, ListenCallback&& callback, v1::UPriority priority, std::chrono::milliseconds subscription_request_ttl, - ConsumerOptions consumer_options) { + core::usubscription::v3::USubscriptionOptions consumer_options) { auto consumer = std::make_unique( std::forward>(transport), std::forward(subscription_topic), - std::forward(consumer_options)); + std::forward(consumer_options)); // Attempt to connect create notification sink for updates. auto status = consumer->createNotificationSink(); diff --git a/test/coverage/client/usubscription/v3/ConsumerTest.cpp b/test/coverage/client/usubscription/v3/ConsumerTest.cpp index 6c6c133e4..647110d15 100644 --- a/test/coverage/client/usubscription/v3/ConsumerTest.cpp +++ b/test/coverage/client/usubscription/v3/ConsumerTest.cpp @@ -17,6 +17,7 @@ #include #include "UTransportMock.h" +#include "up-cpp/client/usubscription/v3/RequestBuilder.h" namespace { using MsgDiff = google::protobuf::util::MessageDifferencer; @@ -106,7 +107,7 @@ TEST_F(ConsumerTest, ConstructorTestSuccess) { // NOLINT auto subscribe_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; - auto options = uprotocol::client::usubscription::v3::ConsumerOptions(); + auto options = uprotocol::core::usubscription::v3::USubscriptionOptions(); auto consumer_or_status = uprotocol::client::usubscription::v3::Consumer::create( @@ -131,7 +132,7 @@ TEST_F(ConsumerTest, SubscribeTestSuccess) { // NOLINT auto subscribe_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; - auto options = uprotocol::client::usubscription::v3::ConsumerOptions(); + auto options = uprotocol::core::usubscription::v3::USubscriptionOptions(); auto consumer_or_status = uprotocol::client::usubscription::v3::Consumer::create( @@ -177,7 +178,7 @@ TEST_F(ConsumerTest, UnsubscribeTestSuccess) { // NOLINT auto subscribe_request_ttl = std::chrono::milliseconds(REQUEST_TTL_TIME); auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; - auto options = uprotocol::client::usubscription::v3::ConsumerOptions(); + auto options = uprotocol::core::usubscription::v3::USubscriptionOptions(); auto consumer_or_status = uprotocol::client::usubscription::v3::Consumer::create( From f9fa701d683a24aa943c6df996fd4f45c4e0b2ea Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Tue, 20 May 2025 18:39:03 +0200 Subject: [PATCH 058/105] Added comments in RequestBuilder.h --- .../client/usubscription/v3/RequestBuilder.h | 44 +++++++++++++++---- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RequestBuilder.h b/include/up-cpp/client/usubscription/v3/RequestBuilder.h index fb5f00b9f..552816568 100644 --- a/include/up-cpp/client/usubscription/v3/RequestBuilder.h +++ b/include/up-cpp/client/usubscription/v3/RequestBuilder.h @@ -29,17 +29,43 @@ struct USubscriptionOptions { std::optional subscription_details; }; - struct RequestBuilder { - explicit RequestBuilder( - USubscriptionOptions options = {}) - :options_(std::move(options)){}; +/** + * @brief Builds different requests using specified options. + * + * This struct facilitates the construction of requests based on `USubscriptionOptions`, + * providing methods to build different requests. + */ +struct RequestBuilder { + /** + * @brief Constructs a RequestBuilder with the given subscription options. + * + * @param options Subscription options to configure the requests. Defaults to empty options. + */ + explicit RequestBuilder(USubscriptionOptions options = {}) + : options_(std::move(options)) {} - SubscriptionRequest buildSubscriptionRequest(const v1::UUri& topic) const; + /** + * @brief Builds a subscription request for a given topic. + * + * @param topic The `v1::UUri` representing the topic for the subscription. + * + * @return A `SubscriptionRequest` configured for the specified topic. + */ + SubscriptionRequest buildSubscriptionRequest(const v1::UUri& topic) const; + + /** + * @brief Builds an unsubscription request for a given topic. + * + * @param topic The `v1::UUri` representing the topic to unsubscribe from. + * + * @return An `UnsubscribeRequest` configured for the specified topic. + */ + UnsubscribeRequest buildUnsubscribeRequest(const v1::UUri& topic) const; + +private: + USubscriptionOptions options_; ///< Options used to configure the requests. +}; - UnsubscribeRequest buildUnsubscribeRequest(const v1::UUri& topic); - private: - USubscriptionOptions options_; - }; } // namespace uprotocol::core::usubscription::v3 #endif //REQUESTBUILDER_H From 167da8c5f34d8d499b140d10e379c3f34a700bb0 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Tue, 20 May 2025 18:48:02 +0200 Subject: [PATCH 059/105] Small fix to get compiled again. Removed const --- include/up-cpp/client/usubscription/v3/RequestBuilder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/up-cpp/client/usubscription/v3/RequestBuilder.h b/include/up-cpp/client/usubscription/v3/RequestBuilder.h index 552816568..378a8039f 100644 --- a/include/up-cpp/client/usubscription/v3/RequestBuilder.h +++ b/include/up-cpp/client/usubscription/v3/RequestBuilder.h @@ -60,7 +60,7 @@ struct RequestBuilder { * * @return An `UnsubscribeRequest` configured for the specified topic. */ - UnsubscribeRequest buildUnsubscribeRequest(const v1::UUri& topic) const; + static UnsubscribeRequest buildUnsubscribeRequest(const v1::UUri& topic); private: USubscriptionOptions options_; ///< Options used to configure the requests. From 61d9ec49647695228a6f28155aba1bc1c1fc4028 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Tue, 20 May 2025 19:01:04 +0200 Subject: [PATCH 060/105] Remove USubscriptionUUriBuilder from Consumer.h --- .../up-cpp/client/usubscription/v3/Consumer.h | 62 +------------------ .../v3/USubscriptionUUriBuilder.h | 22 ++++--- src/client/usubscription/v3/Consumer.cpp | 2 +- .../v3/USubscriptionUUriBuilder.cpp | 13 +++- 4 files changed, 29 insertions(+), 70 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/Consumer.h b/include/up-cpp/client/usubscription/v3/Consumer.h index d13cc3ff8..2500e60e3 100644 --- a/include/up-cpp/client/usubscription/v3/Consumer.h +++ b/include/up-cpp/client/usubscription/v3/Consumer.h @@ -20,6 +20,7 @@ #include #include #include "RequestBuilder.h" +#include "USubscriptionUUriBuilder.h" #include @@ -29,65 +30,6 @@ using uprotocol::core::usubscription::v3::UnsubscribeRequest; using uprotocol::core::usubscription::v3::Update; using uprotocol::core::usubscription::v3::uSubscription; -/// @struct uSubscriptionUUriBuilder -/// @brief Structure to build uSubscription request URIs. -/// -/// This structure is used to build URIs for uSubscription service. It uses the -/// service options from uSubscription proto to set the authority name, ue_id, -/// ue_version_major, and the notification topic resource ID in the URI. -struct USubscriptionUUriBuilder { -private: - /// URI for the uSubscription service - v1::UUri uri_; - /// Resource ID of the notification topic - uint32_t sink_resource_id_; - -public: - /// @brief Constructor for uSubscriptionUUriBuilder. - USubscriptionUUriBuilder() { - // Get the service descriptor - const google::protobuf::ServiceDescriptor* service = - uSubscription::descriptor(); - const auto& service_options = service->options(); - - // Get the service options - const auto& service_name = - service_options.GetExtension(uprotocol::service_name); - const auto& service_version_major = - service_options.GetExtension(uprotocol::service_version_major); - const auto& service_id = - service_options.GetExtension(uprotocol::service_id); - const auto& notification_topic = - service_options.GetExtension(uprotocol::notification_topic, 0); - - // Set the values in the URI - uri_.set_authority_name(service_name); - uri_.set_ue_id(service_id); - uri_.set_ue_version_major(service_version_major); - sink_resource_id_ = notification_topic.id(); - } - - /// @brief Get the URI with a specific resource ID. - /// - /// @param resource_id The resource ID to set in the URI. - /// - /// @return The URI with the specified resource ID. - v1::UUri getServiceUriWithResourceId(uint32_t resource_id) const { - v1::UUri uri = uri_; // Copy the base URI - uri.set_resource_id(resource_id); - return uri; - } - - /// @brief Get the notification URI. - /// - /// @return The notification URI. - v1::UUri getNotificationUri() const { - v1::UUri uri = uri_; // Copy the base URI - uri.set_resource_id(sink_resource_id_); - return uri; - } -}; - /// @brief Interface for uEntities to create subscriptions. /// /// Like all L3 client APIs, the Consumer is a wrapper on top of the @@ -152,7 +94,7 @@ struct Consumer { core::usubscription::v3::USubscriptionOptions consumer_options_; // URI info about the uSubscription service - USubscriptionUUriBuilder uSubscriptionUUriBuilder_; + core::usubscription::v3::USubscriptionUUriBuilder uSubscriptionUUriBuilder_; // Subscription updates std::unique_ptr noficationSinkHandle_; diff --git a/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h b/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h index 784c21000..22bf3218d 100644 --- a/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h +++ b/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h @@ -7,16 +7,22 @@ #include "up-cpp/datamodel/validator/UUri.h" namespace uprotocol::core::usubscription::v3 { -/// @struct USubscriptionUUriBuilder +/// @struct uSubscriptionUUriBuilder /// @brief Structure to build uSubscription request URIs. /// /// This structure is used to build URIs for uSubscription service. It uses the /// service options from uSubscription proto to set the authority name, ue_id, /// ue_version_major, and the notification topic resource ID in the URI. struct USubscriptionUUriBuilder { +private: + /// URI for the uSubscription service + v1::UUri base_uri_; + /// Resource ID of the notification topic + uint32_t sink_resource_id_; - /// @brief Constructor for USubscriptionUUriBuilder. - explicit USubscriptionUUriBuilder(); +public: + /// @brief Constructor for uSubscriptionUUriBuilder. + USubscriptionUUriBuilder(); /// @brief Get the URI with a specific resource ID. /// @@ -25,10 +31,12 @@ struct USubscriptionUUriBuilder { /// @return The URI with the specified resource ID. v1::UUri getServiceUriWithResourceId(uint32_t resource_id) const; - private: - /// URI for the uSubscription service - v1::UUri base_uri_; - }; + /// @brief Get the notification URI. + /// + /// @return The notification URI. + v1::UUri getNotificationUri(); +}; + } // namespace uprotocol::core::usubscription::v3 #endif //USUBSCRIPTIONUURIBUILDER_H diff --git a/src/client/usubscription/v3/Consumer.cpp b/src/client/usubscription/v3/Consumer.cpp index bb9bf4311..6748ba20a 100644 --- a/src/client/usubscription/v3/Consumer.cpp +++ b/src/client/usubscription/v3/Consumer.cpp @@ -24,7 +24,7 @@ Consumer::Consumer(std::shared_ptr transport, consumer_options_(std::move(consumer_options)), rpc_client_(nullptr) { // Initialize uSubscriptionUUriBuilder_ - uSubscriptionUUriBuilder_ = USubscriptionUUriBuilder(); + uSubscriptionUUriBuilder_ = core::usubscription::v3::USubscriptionUUriBuilder(); } [[nodiscard]] Consumer::ConsumerOrStatus Consumer::create( diff --git a/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp b/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp index a316ce44e..889e0e0fa 100644 --- a/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp +++ b/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp @@ -11,15 +11,18 @@ USubscriptionUUriBuilder::USubscriptionUUriBuilder() { // Get the service options const auto& service_name = service_options.GetExtension(uprotocol::service_name); - const auto& service_version_major =3; - // service_options.GetExtension(uprotocol::service_version_major); + const auto& service_version_major = + service_options.GetExtension(uprotocol::service_version_major); const auto& service_id = service_options.GetExtension(uprotocol::service_id); + const auto& notification_topic = + service_options.GetExtension(uprotocol::notification_topic, 0); // Set the values in the URI base_uri_.set_authority_name(service_name); base_uri_.set_ue_id(service_id); base_uri_.set_ue_version_major(service_version_major); + sink_resource_id_ = notification_topic.id(); } v1::UUri USubscriptionUUriBuilder::getServiceUriWithResourceId(uint32_t resource_id) const { @@ -28,4 +31,10 @@ v1::UUri USubscriptionUUriBuilder::getServiceUriWithResourceId(uint32_t resource return uri; } +v1::UUri USubscriptionUUriBuilder::getNotificationUri(){ + v1::UUri uri = base_uri_; // Copy the base URI + uri.set_resource_id(sink_resource_id_); + return uri; +} + } // namespace uprotocol::core::usubscription::v3 \ No newline at end of file From 275049a66960c2039644e1c32aa6361b6e3145fc Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Tue, 20 May 2025 19:08:10 +0200 Subject: [PATCH 061/105] Remove sink_resource_id_ for test in zenoh example as it failed --- src/client/usubscription/v3/USubscriptionUUriBuilder.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp b/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp index 889e0e0fa..f4f57b448 100644 --- a/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp +++ b/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp @@ -15,14 +15,14 @@ USubscriptionUUriBuilder::USubscriptionUUriBuilder() { service_options.GetExtension(uprotocol::service_version_major); const auto& service_id = service_options.GetExtension(uprotocol::service_id); - const auto& notification_topic = - service_options.GetExtension(uprotocol::notification_topic, 0); + // const auto& notification_topic = + // service_options.GetExtension(uprotocol::notification_topic, 0); // Set the values in the URI base_uri_.set_authority_name(service_name); base_uri_.set_ue_id(service_id); base_uri_.set_ue_version_major(service_version_major); - sink_resource_id_ = notification_topic.id(); + // sink_resource_id_ = notification_topic.id(); } v1::UUri USubscriptionUUriBuilder::getServiceUriWithResourceId(uint32_t resource_id) const { From 3d065f914d92339f123216f4ff15071be445446d Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Tue, 20 May 2025 19:19:25 +0200 Subject: [PATCH 062/105] Readd sink_resource_id_ --- src/client/usubscription/v3/USubscriptionUUriBuilder.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp b/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp index f4f57b448..889e0e0fa 100644 --- a/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp +++ b/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp @@ -15,14 +15,14 @@ USubscriptionUUriBuilder::USubscriptionUUriBuilder() { service_options.GetExtension(uprotocol::service_version_major); const auto& service_id = service_options.GetExtension(uprotocol::service_id); - // const auto& notification_topic = - // service_options.GetExtension(uprotocol::notification_topic, 0); + const auto& notification_topic = + service_options.GetExtension(uprotocol::notification_topic, 0); // Set the values in the URI base_uri_.set_authority_name(service_name); base_uri_.set_ue_id(service_id); base_uri_.set_ue_version_major(service_version_major); - // sink_resource_id_ = notification_topic.id(); + sink_resource_id_ = notification_topic.id(); } v1::UUri USubscriptionUUriBuilder::getServiceUriWithResourceId(uint32_t resource_id) const { From 3b1dbbbf7b6038feb9bb192420844a7c0bcd7092 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Tue, 20 May 2025 19:34:08 +0200 Subject: [PATCH 063/105] Make USubscriptionOptions const with reference for options again. --- include/up-cpp/client/usubscription/v3/RequestBuilder.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RequestBuilder.h b/include/up-cpp/client/usubscription/v3/RequestBuilder.h index 378a8039f..d03f124fe 100644 --- a/include/up-cpp/client/usubscription/v3/RequestBuilder.h +++ b/include/up-cpp/client/usubscription/v3/RequestBuilder.h @@ -1,8 +1,6 @@ #ifndef REQUESTBUILDER_H #define REQUESTBUILDER_H #include - -#include #include "up-cpp/client/usubscription/v3/RpcClientUSubscription.h" @@ -41,7 +39,7 @@ struct RequestBuilder { * * @param options Subscription options to configure the requests. Defaults to empty options. */ - explicit RequestBuilder(USubscriptionOptions options = {}) + explicit RequestBuilder(const USubscriptionOptions& options = {}) : options_(std::move(options)) {} /** From c9fa2c65f846ee866492f736b299d5dcea316f73 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Tue, 20 May 2025 19:46:33 +0200 Subject: [PATCH 064/105] Remove comments in ProtoConverter.h --- include/up-cpp/utils/ProtoConverter.h | 48 ++++++--------------------- 1 file changed, 10 insertions(+), 38 deletions(-) diff --git a/include/up-cpp/utils/ProtoConverter.h b/include/up-cpp/utils/ProtoConverter.h index a82ad4d82..f05a76f6c 100644 --- a/include/up-cpp/utils/ProtoConverter.h +++ b/include/up-cpp/utils/ProtoConverter.h @@ -12,10 +12,6 @@ #include "up-cpp/utils/Expected.h" namespace uprotocol::utils { -template -using TOrStatus = utils::Expected; -using UnexpectedStatus = utils::Unexpected; -using PayloadOrStatus = utils::Expected; using uprotocol::core::usubscription::v3::SubscribeAttributes; using uprotocol::core::usubscription::v3::SubscriberInfo; using uprotocol::core::usubscription::v3::SubscriptionRequest; @@ -63,20 +59,8 @@ struct ProtoConverter { const v1::UUri& subscription_topic); static UnsubscribeRequest BuildUnSubscribeRequest(const v1::UUri& uri, const SubscribeAttributes& attributes); - /** - * @brief Deserializes a protobuf message from a given payload. - * - * Parses the payload in `v1::UMessage` using `google::protobuf::Any`, returning a deserialized object of type `T` - * or an error if parsing fails. - * - * @tparam T The type to deserialize the message into. - * - * @param message The `v1::UMessage` containing the payload. - * - * @return `TOrStatus` with the deserialized object or an error status. - */ template - static TOrStatus extractFromProtobuf(const v1::UMessage& message) + static utils::Expected extractFromProtobuf(const v1::UMessage& message) { google::protobuf::Any any; @@ -84,8 +68,8 @@ struct ProtoConverter { v1::UStatus status; status.set_code(v1::UCode::INTERNAL); status.set_message("extractFromProtobuf: Error when parsing payload."); - return TOrStatus( - UnexpectedStatus(status)); + return utils::Expected( + utils::Unexpected(status)); } T response; @@ -94,40 +78,28 @@ struct ProtoConverter { v1::UStatus status; status.set_code(v1::UCode::INTERNAL); status.set_message("extractFromProtobuf: Error when unpacking any."); - return TOrStatus( - UnexpectedStatus(status)); + return utils::Expected( + utils::Unexpected(status)); } - return TOrStatus(response); + return Expected(response); } - /** - * @brief Serializes a protobuf object into a payload. - * - * Converts the given `proto` object to a payload using `google::protobuf::Any`. - * Returns the payload or an error status if serialization fails. - * - * @tparam T The type of the protobuf object to serialize. - * - * @param proto The protobuf object to be converted into a payload. - * - * @return `PayloadOrStatus` containing the payload or an error status. - */ template - static PayloadOrStatus protoToPayload(const T& proto) { + static utils::Expected protoToPayload(const T& proto) { google::protobuf::Any any; if (!any.PackFrom(proto)) { v1::UStatus status; status.set_code(v1::UCode::INTERNAL); status.set_message("protoToPayload: There was an error when serializing the subscription request."); - return PayloadOrStatus( - UnexpectedStatus(status)); + return utils::Expected( + utils::Unexpected(status)); } const datamodel::builder::Payload payload(any); - return PayloadOrStatus(payload); + return utils::Expected(payload); } }; From 67d6facd2fbad09ee6b796c37705a2e6a002ef77 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Tue, 20 May 2025 19:59:54 +0200 Subject: [PATCH 065/105] Remove notification_topic again. Still searching the error --- src/client/usubscription/v3/USubscriptionUUriBuilder.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp b/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp index 889e0e0fa..f4f57b448 100644 --- a/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp +++ b/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp @@ -15,14 +15,14 @@ USubscriptionUUriBuilder::USubscriptionUUriBuilder() { service_options.GetExtension(uprotocol::service_version_major); const auto& service_id = service_options.GetExtension(uprotocol::service_id); - const auto& notification_topic = - service_options.GetExtension(uprotocol::notification_topic, 0); + // const auto& notification_topic = + // service_options.GetExtension(uprotocol::notification_topic, 0); // Set the values in the URI base_uri_.set_authority_name(service_name); base_uri_.set_ue_id(service_id); base_uri_.set_ue_version_major(service_version_major); - sink_resource_id_ = notification_topic.id(); + // sink_resource_id_ = notification_topic.id(); } v1::UUri USubscriptionUUriBuilder::getServiceUriWithResourceId(uint32_t resource_id) const { From 5dd5f76391f50780862d32b4cdddacfcad47a120 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Tue, 20 May 2025 20:11:42 +0200 Subject: [PATCH 066/105] Readd notification topic --- src/client/usubscription/v3/USubscriptionUUriBuilder.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp b/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp index f4f57b448..889e0e0fa 100644 --- a/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp +++ b/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp @@ -15,14 +15,14 @@ USubscriptionUUriBuilder::USubscriptionUUriBuilder() { service_options.GetExtension(uprotocol::service_version_major); const auto& service_id = service_options.GetExtension(uprotocol::service_id); - // const auto& notification_topic = - // service_options.GetExtension(uprotocol::notification_topic, 0); + const auto& notification_topic = + service_options.GetExtension(uprotocol::notification_topic, 0); // Set the values in the URI base_uri_.set_authority_name(service_name); base_uri_.set_ue_id(service_id); base_uri_.set_ue_version_major(service_version_major); - // sink_resource_id_ = notification_topic.id(); + sink_resource_id_ = notification_topic.id(); } v1::UUri USubscriptionUUriBuilder::getServiceUriWithResourceId(uint32_t resource_id) const { From aac976529cc2c8b6d0ed553a4474b7231bdd2f77 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Tue, 20 May 2025 20:12:36 +0200 Subject: [PATCH 067/105] Readd comments in ProtoConverter.h --- include/up-cpp/utils/ProtoConverter.h | 48 +++++++++++++++++++++------ 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/include/up-cpp/utils/ProtoConverter.h b/include/up-cpp/utils/ProtoConverter.h index f05a76f6c..a82ad4d82 100644 --- a/include/up-cpp/utils/ProtoConverter.h +++ b/include/up-cpp/utils/ProtoConverter.h @@ -12,6 +12,10 @@ #include "up-cpp/utils/Expected.h" namespace uprotocol::utils { +template +using TOrStatus = utils::Expected; +using UnexpectedStatus = utils::Unexpected; +using PayloadOrStatus = utils::Expected; using uprotocol::core::usubscription::v3::SubscribeAttributes; using uprotocol::core::usubscription::v3::SubscriberInfo; using uprotocol::core::usubscription::v3::SubscriptionRequest; @@ -59,8 +63,20 @@ struct ProtoConverter { const v1::UUri& subscription_topic); static UnsubscribeRequest BuildUnSubscribeRequest(const v1::UUri& uri, const SubscribeAttributes& attributes); + /** + * @brief Deserializes a protobuf message from a given payload. + * + * Parses the payload in `v1::UMessage` using `google::protobuf::Any`, returning a deserialized object of type `T` + * or an error if parsing fails. + * + * @tparam T The type to deserialize the message into. + * + * @param message The `v1::UMessage` containing the payload. + * + * @return `TOrStatus` with the deserialized object or an error status. + */ template - static utils::Expected extractFromProtobuf(const v1::UMessage& message) + static TOrStatus extractFromProtobuf(const v1::UMessage& message) { google::protobuf::Any any; @@ -68,8 +84,8 @@ struct ProtoConverter { v1::UStatus status; status.set_code(v1::UCode::INTERNAL); status.set_message("extractFromProtobuf: Error when parsing payload."); - return utils::Expected( - utils::Unexpected(status)); + return TOrStatus( + UnexpectedStatus(status)); } T response; @@ -78,28 +94,40 @@ struct ProtoConverter { v1::UStatus status; status.set_code(v1::UCode::INTERNAL); status.set_message("extractFromProtobuf: Error when unpacking any."); - return utils::Expected( - utils::Unexpected(status)); + return TOrStatus( + UnexpectedStatus(status)); } - return Expected(response); + return TOrStatus(response); } + /** + * @brief Serializes a protobuf object into a payload. + * + * Converts the given `proto` object to a payload using `google::protobuf::Any`. + * Returns the payload or an error status if serialization fails. + * + * @tparam T The type of the protobuf object to serialize. + * + * @param proto The protobuf object to be converted into a payload. + * + * @return `PayloadOrStatus` containing the payload or an error status. + */ template - static utils::Expected protoToPayload(const T& proto) { + static PayloadOrStatus protoToPayload(const T& proto) { google::protobuf::Any any; if (!any.PackFrom(proto)) { v1::UStatus status; status.set_code(v1::UCode::INTERNAL); status.set_message("protoToPayload: There was an error when serializing the subscription request."); - return utils::Expected( - utils::Unexpected(status)); + return PayloadOrStatus( + UnexpectedStatus(status)); } const datamodel::builder::Payload payload(any); - return utils::Expected(payload); + return PayloadOrStatus(payload); } }; From 1b0d0cde550bdebdc2b193144dbf9440d4bae376 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Tue, 20 May 2025 20:14:27 +0200 Subject: [PATCH 068/105] Remove protoToPayload in RpcClientUSubscription to test problem --- src/client/usubscription/v3/RpcClientUSubscription.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index d2327c2cf..d7581867a 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -44,13 +44,12 @@ RpcClientUSubscription::subscribe( RESOURCE_ID_SUBSCRIBE), priority, SUBSCRIPTION_REQUEST_TTL); - auto payload_or_status = utils::ProtoConverter::protoToPayload(subscription_request); + google::protobuf::Any any_request; - if(payload_or_status.has_value()){ - return ResponseOrStatus( - utils::Unexpected(payload_or_status.error())); + if (!any_request.PackFrom(subscription_request)) { + spdlog::error("subscribe: There was an error when serializing the subscription request."); } - datamodel::builder::Payload payload(payload_or_status.value()); + datamodel::builder::Payload payload(any_request); auto message_or_status = rpc_client.invokeMethod(std::move(payload)).get(); From 3643b20b462093537761ca45bde5e078e13d24ca Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Tue, 20 May 2025 20:19:03 +0200 Subject: [PATCH 069/105] Readd protoToPayload in RpcClientUSubscription. Negation was missing --- src/client/usubscription/v3/RpcClientUSubscription.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index d7581867a..0b9defd27 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -44,12 +44,13 @@ RpcClientUSubscription::subscribe( RESOURCE_ID_SUBSCRIBE), priority, SUBSCRIPTION_REQUEST_TTL); - google::protobuf::Any any_request; + auto payload_or_status = utils::ProtoConverter::protoToPayload(subscription_request); - if (!any_request.PackFrom(subscription_request)) { - spdlog::error("subscribe: There was an error when serializing the subscription request."); + if(!payload_or_status.has_value()){ + return ResponseOrStatus( + utils::Unexpected(payload_or_status.error())); } - datamodel::builder::Payload payload(any_request); + datamodel::builder::Payload payload(payload_or_status.value()); auto message_or_status = rpc_client.invokeMethod(std::move(payload)).get(); From 84268eb39d124231d8fb89356b13cce33a66d626 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Wed, 21 May 2025 10:58:41 +0200 Subject: [PATCH 070/105] clang-format --- .../up-cpp/client/usubscription/v3/Consumer.h | 10 +-- .../client/usubscription/v3/RequestBuilder.h | 60 +++++++-------- .../usubscription/v3/RpcClientUSubscription.h | 14 ++-- .../client/usubscription/v3/USubscription.h | 4 +- .../v3/USubscriptionUUriBuilder.h | 8 +- include/up-cpp/utils/ProtoConverter.h | 77 ++++++++++--------- src/client/usubscription/v3/Consumer.cpp | 14 ++-- .../usubscription/v3/RequestBuilder.cpp | 20 ++--- .../v3/RpcClientUSubscription.cpp | 47 +++++------ .../v3/USubscriptionUUriBuilder.cpp | 17 ++-- src/utils/ProtoConverter.cpp | 3 + .../v3/RpcClientUSubscriptionTest.cpp | 2 +- 12 files changed, 140 insertions(+), 136 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/Consumer.h b/include/up-cpp/client/usubscription/v3/Consumer.h index 2500e60e3..2544f4795 100644 --- a/include/up-cpp/client/usubscription/v3/Consumer.h +++ b/include/up-cpp/client/usubscription/v3/Consumer.h @@ -19,11 +19,10 @@ #include #include #include + #include "RequestBuilder.h" #include "USubscriptionUUriBuilder.h" -#include - namespace uprotocol::client::usubscription::v3 { using uprotocol::core::usubscription::v3::SubscriptionRequest; using uprotocol::core::usubscription::v3::UnsubscribeRequest; @@ -80,9 +79,10 @@ struct Consumer { /// /// @param transport Transport to register with. /// @param subscriber_details Additional details about the subscriber. - Consumer(std::shared_ptr transport, - v1::UUri subscription_topic, - core::usubscription::v3::USubscriptionOptions consumer_options = {}); + Consumer( + std::shared_ptr transport, + v1::UUri subscription_topic, + core::usubscription::v3::USubscriptionOptions consumer_options = {}); private: // Transport diff --git a/include/up-cpp/client/usubscription/v3/RequestBuilder.h b/include/up-cpp/client/usubscription/v3/RequestBuilder.h index d03f124fe..fc3034e1f 100644 --- a/include/up-cpp/client/usubscription/v3/RequestBuilder.h +++ b/include/up-cpp/client/usubscription/v3/RequestBuilder.h @@ -1,8 +1,8 @@ #ifndef REQUESTBUILDER_H #define REQUESTBUILDER_H #include -#include "up-cpp/client/usubscription/v3/RpcClientUSubscription.h" +#include namespace uprotocol::core::usubscription::v3 { @@ -30,40 +30,40 @@ struct USubscriptionOptions { /** * @brief Builds different requests using specified options. * - * This struct facilitates the construction of requests based on `USubscriptionOptions`, - * providing methods to build different requests. + * This struct facilitates the construction of requests based on + * `USubscriptionOptions`, providing methods to build different requests. */ struct RequestBuilder { - /** - * @brief Constructs a RequestBuilder with the given subscription options. - * - * @param options Subscription options to configure the requests. Defaults to empty options. - */ - explicit RequestBuilder(const USubscriptionOptions& options = {}) - : options_(std::move(options)) {} + /** + * @brief Constructs a RequestBuilder with the given subscription options. + * + * @param options Subscription options to configure the requests. Defaults + * to empty options. + */ + explicit RequestBuilder(USubscriptionOptions options = {}) + : options_(std::move(options)) {} - /** - * @brief Builds a subscription request for a given topic. - * - * @param topic The `v1::UUri` representing the topic for the subscription. - * - * @return A `SubscriptionRequest` configured for the specified topic. - */ - SubscriptionRequest buildSubscriptionRequest(const v1::UUri& topic) const; + /** + * @brief Builds a subscription request for a given topic. + * + * @param topic The `v1::UUri` representing the topic for the subscription. + * + * @return A `SubscriptionRequest` configured for the specified topic. + */ + SubscriptionRequest buildSubscriptionRequest(const v1::UUri& topic) const; - /** - * @brief Builds an unsubscription request for a given topic. - * - * @param topic The `v1::UUri` representing the topic to unsubscribe from. - * - * @return An `UnsubscribeRequest` configured for the specified topic. - */ - static UnsubscribeRequest buildUnsubscribeRequest(const v1::UUri& topic); + /** + * @brief Builds an unsubscription request for a given topic. + * + * @param topic The `v1::UUri` representing the topic to unsubscribe from. + * + * @return An `UnsubscribeRequest` configured for the specified topic. + */ + static UnsubscribeRequest buildUnsubscribeRequest(const v1::UUri& topic); private: - USubscriptionOptions options_; ///< Options used to configure the requests. + USubscriptionOptions options_; ///< Options used to configure the requests. }; - -} // namespace uprotocol::core::usubscription::v3 -#endif //REQUESTBUILDER_H +} // namespace uprotocol::core::usubscription::v3 +#endif // REQUESTBUILDER_H diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index e37a7dfbc..6c011ff96 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -26,8 +26,6 @@ using v3::UnsubscribeRequest; using v3::Update; using v3::uSubscription; - - /// @brief Interface for uEntities to create subscriptions. /// /// Like all L3 client APIs, the RpcClientUSubscription is a wrapper on top of @@ -37,15 +35,15 @@ struct RpcClientUSubscription : USubscription { utils::Expected, v1::UStatus>; using ListenCallback = transport::UTransport::ListenCallback; using ListenHandle = transport::UTransport::ListenHandle; - + template Response invokeResponse(communication::RpcClient rpc_client); - + /// @brief Subscribe to the topic /// utils::Expected subscribe( const SubscriptionRequest& subscription_request) override; - + /// @brief Unsubscribe from the topic /// utils::Expected unsubscribe( @@ -55,14 +53,12 @@ struct RpcClientUSubscription : USubscription { /// /// @param transport Transport to register with. explicit RpcClientUSubscription( - std::shared_ptr transport) - : transport_(std::move(transport)){} - + std::shared_ptr transport) + : transport_(std::move(transport)) {} /// @brief Destructor ~RpcClientUSubscription() override = default; - private: // Transport std::shared_ptr transport_; diff --git a/include/up-cpp/client/usubscription/v3/USubscription.h b/include/up-cpp/client/usubscription/v3/USubscription.h index 7b991c7de..141fa35e2 100644 --- a/include/up-cpp/client/usubscription/v3/USubscription.h +++ b/include/up-cpp/client/usubscription/v3/USubscription.h @@ -17,8 +17,8 @@ struct USubscription { virtual ResponseOrStatus subscribe( const SubscriptionRequest& subscription_request) = 0; - virtual ResponseOrStatus unsubscribe(const UnsubscribeRequest& - unsubscribe_request) = 0; + virtual ResponseOrStatus unsubscribe( + const UnsubscribeRequest& unsubscribe_request) = 0; // virtual FetchSubscriptionsResponse fetch_subscriptions(const // FetchSubscriptionsRequest& fetch_subscribers_request) = 0; diff --git a/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h b/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h index 22bf3218d..bd1d2ca1c 100644 --- a/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h +++ b/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h @@ -1,10 +1,8 @@ #ifndef USUBSCRIPTIONUURIBUILDER_H #define USUBSCRIPTIONUURIBUILDER_H -#include #include - -#include "up-cpp/datamodel/validator/UUri.h" +#include namespace uprotocol::core::usubscription::v3 { /// @struct uSubscriptionUUriBuilder @@ -37,6 +35,6 @@ struct USubscriptionUUriBuilder { v1::UUri getNotificationUri(); }; -} // namespace uprotocol::core::usubscription::v3 +} // namespace uprotocol::core::usubscription::v3 -#endif //USUBSCRIPTIONUURIBUILDER_H +#endif // USUBSCRIPTIONUURIBUILDER_H diff --git a/include/up-cpp/utils/ProtoConverter.h b/include/up-cpp/utils/ProtoConverter.h index a82ad4d82..529ad6b40 100644 --- a/include/up-cpp/utils/ProtoConverter.h +++ b/include/up-cpp/utils/ProtoConverter.h @@ -8,6 +8,7 @@ #include #include + #include "up-cpp/datamodel/builder/Payload.h" #include "up-cpp/utils/Expected.h" @@ -15,7 +16,8 @@ namespace uprotocol::utils { template using TOrStatus = utils::Expected; using UnexpectedStatus = utils::Unexpected; -using PayloadOrStatus = utils::Expected; +using PayloadOrStatus = + utils::Expected; using uprotocol::core::usubscription::v3::SubscribeAttributes; using uprotocol::core::usubscription::v3::SubscriberInfo; using uprotocol::core::usubscription::v3::SubscriptionRequest; @@ -61,31 +63,31 @@ struct ProtoConverter { /// @return the built UnsubscribeRequest static UnsubscribeRequest BuildUnSubscribeRequest( const v1::UUri& subscription_topic); - static UnsubscribeRequest BuildUnSubscribeRequest(const v1::UUri& uri, const SubscribeAttributes& attributes); + static UnsubscribeRequest BuildUnSubscribeRequest( + const v1::UUri& uri, const SubscribeAttributes& attributes); /** - * @brief Deserializes a protobuf message from a given payload. - * - * Parses the payload in `v1::UMessage` using `google::protobuf::Any`, returning a deserialized object of type `T` - * or an error if parsing fails. - * - * @tparam T The type to deserialize the message into. - * - * @param message The `v1::UMessage` containing the payload. - * - * @return `TOrStatus` with the deserialized object or an error status. - */ + * @brief Deserializes a protobuf message from a given payload. + * + * Parses the payload in `v1::UMessage` using `google::protobuf::Any`, + * returning a deserialized object of type `T` or an error if parsing fails. + * + * @tparam T The type to deserialize the message into. + * + * @param message The `v1::UMessage` containing the payload. + * + * @return `TOrStatus` with the deserialized object or an error status. + */ template - static TOrStatus extractFromProtobuf(const v1::UMessage& message) - { + static TOrStatus extractFromProtobuf(const v1::UMessage& message) { google::protobuf::Any any; if (!any.ParseFromString(message.payload())) { v1::UStatus status; status.set_code(v1::UCode::INTERNAL); - status.set_message("extractFromProtobuf: Error when parsing payload."); - return TOrStatus( - UnexpectedStatus(status)); + status.set_message( + "extractFromProtobuf: Error when parsing payload."); + return TOrStatus(UnexpectedStatus(status)); } T response; @@ -93,26 +95,27 @@ struct ProtoConverter { if (!any.UnpackTo(&response)) { v1::UStatus status; status.set_code(v1::UCode::INTERNAL); - status.set_message("extractFromProtobuf: Error when unpacking any."); - return TOrStatus( - UnexpectedStatus(status)); + status.set_message( + "extractFromProtobuf: Error when unpacking any."); + return TOrStatus(UnexpectedStatus(status)); } return TOrStatus(response); } - + /** - * @brief Serializes a protobuf object into a payload. - * - * Converts the given `proto` object to a payload using `google::protobuf::Any`. - * Returns the payload or an error status if serialization fails. - * - * @tparam T The type of the protobuf object to serialize. - * - * @param proto The protobuf object to be converted into a payload. - * - * @return `PayloadOrStatus` containing the payload or an error status. - */ + * @brief Serializes a protobuf object into a payload. + * + * Converts the given `proto` object to a payload using + * `google::protobuf::Any`. Returns the payload or an error status if + * serialization fails. + * + * @tparam T The type of the protobuf object to serialize. + * + * @param proto The protobuf object to be converted into a payload. + * + * @return `PayloadOrStatus` containing the payload or an error status. + */ template static PayloadOrStatus protoToPayload(const T& proto) { google::protobuf::Any any; @@ -120,16 +123,16 @@ struct ProtoConverter { if (!any.PackFrom(proto)) { v1::UStatus status; status.set_code(v1::UCode::INTERNAL); - status.set_message("protoToPayload: There was an error when serializing the subscription request."); - return PayloadOrStatus( - UnexpectedStatus(status)); + status.set_message( + "protoToPayload: There was an error when serializing the " + "subscription request."); + return PayloadOrStatus(UnexpectedStatus(status)); } const datamodel::builder::Payload payload(any); return PayloadOrStatus(payload); } - }; }; // namespace uprotocol::utils #endif // UP_CPP_UTILS_PROTOCONVERTER_H diff --git a/src/client/usubscription/v3/Consumer.cpp b/src/client/usubscription/v3/Consumer.cpp index 6748ba20a..18a6d1c65 100644 --- a/src/client/usubscription/v3/Consumer.cpp +++ b/src/client/usubscription/v3/Consumer.cpp @@ -12,19 +12,22 @@ #include #include + #include "up-cpp/client/usubscription/v3/RequestBuilder.h" namespace uprotocol::client::usubscription::v3 { -Consumer::Consumer(std::shared_ptr transport, - v1::UUri subscription_topic, - core::usubscription::v3::USubscriptionOptions consumer_options) +Consumer::Consumer( + std::shared_ptr transport, + v1::UUri subscription_topic, + core::usubscription::v3::USubscriptionOptions consumer_options) : transport_(std::move(transport)), subscription_topic_(std::move(subscription_topic)), consumer_options_(std::move(consumer_options)), rpc_client_(nullptr) { // Initialize uSubscriptionUUriBuilder_ - uSubscriptionUUriBuilder_ = core::usubscription::v3::USubscriptionUUriBuilder(); + uSubscriptionUUriBuilder_ = + core::usubscription::v3::USubscriptionUUriBuilder(); } [[nodiscard]] Consumer::ConsumerOrStatus Consumer::create( @@ -35,7 +38,8 @@ Consumer::Consumer(std::shared_ptr transport, auto consumer = std::make_unique( std::forward>(transport), std::forward(subscription_topic), - std::forward(consumer_options)); + std::forward( + consumer_options)); // Attempt to connect create notification sink for updates. auto status = consumer->createNotificationSink(); diff --git a/src/client/usubscription/v3/RequestBuilder.cpp b/src/client/usubscription/v3/RequestBuilder.cpp index c46e4ae24..d11a18688 100644 --- a/src/client/usubscription/v3/RequestBuilder.cpp +++ b/src/client/usubscription/v3/RequestBuilder.cpp @@ -1,18 +1,16 @@ -#include #include "up-cpp/client/usubscription/v3/RequestBuilder.h" -namespace uprotocol::core::usubscription::v3 { +#include +namespace uprotocol::core::usubscription::v3 { SubscriptionRequest RequestBuilder::buildSubscriptionRequest( - const v1::UUri& topic) const { + const v1::UUri& topic) const { auto attributes = utils::ProtoConverter::BuildSubscribeAttributes( - options_.when_expire, - options_.subscription_details, - options_.sample_period_ms); + options_.when_expire, options_.subscription_details, + options_.sample_period_ms); - return utils::ProtoConverter::BuildSubscriptionRequest( - topic, attributes); + return utils::ProtoConverter::BuildSubscriptionRequest(topic, attributes); } UnsubscribeRequest RequestBuilder::buildUnsubscribeRequest( @@ -22,9 +20,7 @@ UnsubscribeRequest RequestBuilder::buildUnsubscribeRequest( // options_.subscription_details, // options_.sample_period_ms); - return utils::ProtoConverter::BuildUnSubscribeRequest( - topic); + return utils::ProtoConverter::BuildUnSubscribeRequest(topic); } - -} // namespace uprotocol::core::usubscription::v3 +} // namespace uprotocol::core::usubscription::v3 diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 0b9defd27..313705215 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -9,17 +9,15 @@ // // SPDX-License-Identifier: Apache-2.0 +#include #include #include #include #include -#include - #include #include "up-cpp/communication/RpcClient.h" -#include "up-cpp/transport/UTransport.h" #include "up-cpp/utils/ProtoConverter.h" constexpr uint16_t RESOURCE_ID_SUBSCRIBE = 0x0001; @@ -30,23 +28,22 @@ auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; // MUST be >= 4 namespace uprotocol::core::usubscription::v3 { -template -Response RpcClientUSubscription::invokeResponse(communication::RpcClient rpc_client){ - -} +template +Response RpcClientUSubscription::invokeResponse( + communication::RpcClient rpc_client) {} RpcClientUSubscription::ResponseOrStatus RpcClientUSubscription::subscribe( const SubscriptionRequest& subscription_request) { communication::RpcClient rpc_client( transport_, - uuri_builder_.getServiceUriWithResourceId( - RESOURCE_ID_SUBSCRIBE), + uuri_builder_.getServiceUriWithResourceId(RESOURCE_ID_SUBSCRIBE), priority, SUBSCRIPTION_REQUEST_TTL); - auto payload_or_status = utils::ProtoConverter::protoToPayload(subscription_request); + auto payload_or_status = + utils::ProtoConverter::protoToPayload(subscription_request); - if(!payload_or_status.has_value()){ + if (!payload_or_status.has_value()) { return ResponseOrStatus( utils::Unexpected(payload_or_status.error())); } @@ -59,20 +56,25 @@ RpcClientUSubscription::subscribe( utils::Unexpected(message_or_status.error())); } - spdlog::debug("response UMessage: {}", message_or_status.value().DebugString()); + spdlog::debug("response UMessage: {}", + message_or_status.value().DebugString()); SubscriptionResponse subscription_response; - auto response_or_status = utils::ProtoConverter::extractFromProtobuf(message_or_status.value()); - - if (!response_or_status.has_value()){ - spdlog::error("subscribe: Error when extracting response from protobuf."); + auto response_or_status = + utils::ProtoConverter::extractFromProtobuf( + message_or_status.value()); + + if (!response_or_status.has_value()) { + spdlog::error( + "subscribe: Error when extracting response from protobuf."); return ResponseOrStatus( utils::Unexpected(response_or_status.error())); } subscription_response = response_or_status.value(); - spdlog::debug("subscribe: response: {}", subscription_response.DebugString()); + spdlog::debug("subscribe: response: {}", + subscription_response.DebugString()); if (subscription_response.topic().SerializeAsString() != subscription_request.topic().SerializeAsString()) { @@ -80,18 +82,19 @@ RpcClientUSubscription::subscribe( status.set_code(v1::UCode::INTERNAL); status.set_message("subscribe: topics do not match."); return ResponseOrStatus( - utils::Unexpected(status)); + utils::Unexpected(status)); } - return ResponseOrStatus(std::move(subscription_response)); + return ResponseOrStatus( + std::move(subscription_response)); } RpcClientUSubscription::ResponseOrStatus RpcClientUSubscription::unsubscribe( - const UnsubscribeRequest& unsubscribe_request) { - + const UnsubscribeRequest& unsubscribe_request) { UnsubscribeResponse unsubscribe_response; - return ResponseOrStatus(std::move(unsubscribe_response)); + return ResponseOrStatus( + std::move(unsubscribe_response)); } } // namespace uprotocol::core::usubscription::v3 diff --git a/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp b/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp index 889e0e0fa..aa050de9c 100644 --- a/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp +++ b/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp @@ -5,18 +5,18 @@ namespace uprotocol::core::usubscription::v3 { USubscriptionUUriBuilder::USubscriptionUUriBuilder() { // Get the service descriptor const google::protobuf::ServiceDescriptor* service = - uSubscription::descriptor(); + uSubscription::descriptor(); const auto& service_options = service->options(); // Get the service options const auto& service_name = - service_options.GetExtension(uprotocol::service_name); + service_options.GetExtension(uprotocol::service_name); const auto& service_version_major = - service_options.GetExtension(uprotocol::service_version_major); + service_options.GetExtension(uprotocol::service_version_major); const auto& service_id = - service_options.GetExtension(uprotocol::service_id); + service_options.GetExtension(uprotocol::service_id); const auto& notification_topic = - service_options.GetExtension(uprotocol::notification_topic, 0); + service_options.GetExtension(uprotocol::notification_topic, 0); // Set the values in the URI base_uri_.set_authority_name(service_name); @@ -25,16 +25,17 @@ USubscriptionUUriBuilder::USubscriptionUUriBuilder() { sink_resource_id_ = notification_topic.id(); } -v1::UUri USubscriptionUUriBuilder::getServiceUriWithResourceId(uint32_t resource_id) const { +v1::UUri USubscriptionUUriBuilder::getServiceUriWithResourceId( + uint32_t resource_id) const { v1::UUri uri = base_uri_; // Copy the base URI uri.set_resource_id(resource_id); return uri; } -v1::UUri USubscriptionUUriBuilder::getNotificationUri(){ +v1::UUri USubscriptionUUriBuilder::getNotificationUri() { v1::UUri uri = base_uri_; // Copy the base URI uri.set_resource_id(sink_resource_id_); return uri; } -} // namespace uprotocol::core::usubscription::v3 \ No newline at end of file +} // namespace uprotocol::core::usubscription::v3 \ No newline at end of file diff --git a/src/utils/ProtoConverter.cpp b/src/utils/ProtoConverter.cpp index f62e20407..a50a74a41 100644 --- a/src/utils/ProtoConverter.cpp +++ b/src/utils/ProtoConverter.cpp @@ -1,7 +1,10 @@ #include "up-cpp/utils/ProtoConverter.h" + #include #include + #include + #include "up-cpp/datamodel/builder/Payload.h" #include "up-cpp/utils/Expected.h" diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp index bdaa2c36a..6136b2016 100644 --- a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -94,7 +94,7 @@ class RpcClientUSubscriptionTest : public testing::Test { ~RpcClientUSubscriptionTest() override = default; }; -//Negative test case with no source filter +// Negative test case with no source filter TEST_F(RpcClientUSubscriptionTest, ConstructorTestSuccess) { // NOLINT auto rpc_client_usubscription = std::make_unique< From 244fca745a26485cfb2aa349c42ee89907bc861f Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Wed, 21 May 2025 11:13:03 +0200 Subject: [PATCH 071/105] Added license. Fixed linter warnings in src --- .../up-cpp/client/usubscription/v3/Consumer.h | 1 - .../client/usubscription/v3/RequestBuilder.h | 17 ++++++++++++++--- .../usubscription/v3/RpcClientUSubscription.h | 8 +++----- .../client/usubscription/v3/USubscription.h | 17 ++++++++++++++--- .../usubscription/v3/USubscriptionUUriBuilder.h | 17 ++++++++++++++--- lint/clang-tidy.sh | 3 ++- src/client/usubscription/v3/RequestBuilder.cpp | 12 +++++++++++- .../v3/USubscriptionUUriBuilder.cpp | 11 +++++++++++ .../v3/RpcClientUSubscriptionTest.cpp | 2 -- 9 files changed, 69 insertions(+), 19 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/Consumer.h b/include/up-cpp/client/usubscription/v3/Consumer.h index 2544f4795..b9678d315 100644 --- a/include/up-cpp/client/usubscription/v3/Consumer.h +++ b/include/up-cpp/client/usubscription/v3/Consumer.h @@ -27,7 +27,6 @@ namespace uprotocol::client::usubscription::v3 { using uprotocol::core::usubscription::v3::SubscriptionRequest; using uprotocol::core::usubscription::v3::UnsubscribeRequest; using uprotocol::core::usubscription::v3::Update; -using uprotocol::core::usubscription::v3::uSubscription; /// @brief Interface for uEntities to create subscriptions. /// diff --git a/include/up-cpp/client/usubscription/v3/RequestBuilder.h b/include/up-cpp/client/usubscription/v3/RequestBuilder.h index fc3034e1f..8d8cd413a 100644 --- a/include/up-cpp/client/usubscription/v3/RequestBuilder.h +++ b/include/up-cpp/client/usubscription/v3/RequestBuilder.h @@ -1,5 +1,16 @@ -#ifndef REQUESTBUILDER_H -#define REQUESTBUILDER_H +// SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: Apache-2.0 + +#ifndef UP_CPP_CLIENT_USUBSCRIPTION_V3_REQUESTBUILDER_H +#define UP_CPP_CLIENT_USUBSCRIPTION_V3_REQUESTBUILDER_H #include #include @@ -66,4 +77,4 @@ struct RequestBuilder { }; } // namespace uprotocol::core::usubscription::v3 -#endif // REQUESTBUILDER_H +#endif // UP_CPP_CLIENT_USUBSCRIPTION_V3_REQUESTBUILDER_H diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index 6c011ff96..9ebf9f82f 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -9,8 +9,8 @@ // // SPDX-License-Identifier: Apache-2.0 -#ifndef RPCCLIENTUSUBSCRIPTION_H -#define RPCCLIENTUSUBSCRIPTION_H +#ifndef UP_CPP_CLIENT_USUBSCRIPTION_V3_RPCCLIENTUSUBSCRIPTION_H +#define UP_CPP_CLIENT_USUBSCRIPTION_V3_RPCCLIENTUSUBSCRIPTION_H #include #include @@ -23,8 +23,6 @@ namespace uprotocol::core::usubscription::v3 { using v3::SubscriptionRequest; using v3::UnsubscribeRequest; -using v3::Update; -using v3::uSubscription; /// @brief Interface for uEntities to create subscriptions. /// @@ -69,4 +67,4 @@ struct RpcClientUSubscription : USubscription { } // namespace uprotocol::core::usubscription::v3 -#endif // RPCCLIENTUSUBSCRIPTION_H \ No newline at end of file +#endif // UP_CPP_CLIENT_USUBSCRIPTION_V3_RPCCLIENTUSUBSCRIPTION_H \ No newline at end of file diff --git a/include/up-cpp/client/usubscription/v3/USubscription.h b/include/up-cpp/client/usubscription/v3/USubscription.h index 141fa35e2..fce671b05 100644 --- a/include/up-cpp/client/usubscription/v3/USubscription.h +++ b/include/up-cpp/client/usubscription/v3/USubscription.h @@ -1,5 +1,16 @@ -#ifndef USUBSCRIPTION_H -#define USUBSCRIPTION_H +// SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: Apache-2.0 + +#ifndef UP_CPP_CLIENT_USUBSCRIPTION_V3_USUBSCRIPTION_H +#define UP_CPP_CLIENT_USUBSCRIPTION_V3_USUBSCRIPTION_H #include #include #include @@ -35,4 +46,4 @@ struct USubscription { } // namespace uprotocol::core::usubscription::v3 -#endif // USUBSCRIPTION_H +#endif // UP_CPP_CLIENT_USUBSCRIPTION_V3_USUBSCRIPTION_H diff --git a/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h b/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h index bd1d2ca1c..63bcdec79 100644 --- a/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h +++ b/include/up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h @@ -1,5 +1,16 @@ -#ifndef USUBSCRIPTIONUURIBUILDER_H -#define USUBSCRIPTIONUURIBUILDER_H +// SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: Apache-2.0 + +#ifndef UP_CPP_CLIENT_USUBSCRIPTION_V3_USUBSCRIPTIONUURIBUILDER_H +#define UP_CPP_CLIENT_USUBSCRIPTION_V3_USUBSCRIPTIONUURIBUILDER_H #include #include @@ -37,4 +48,4 @@ struct USubscriptionUUriBuilder { } // namespace uprotocol::core::usubscription::v3 -#endif // USUBSCRIPTIONUURIBUILDER_H +#endif // UP_CPP_CLIENT_USUBSCRIPTION_V3_USUBSCRIPTIONUURIBUILDER_H diff --git a/lint/clang-tidy.sh b/lint/clang-tidy.sh index 19e9ddc80..1f74b24f4 100755 --- a/lint/clang-tidy.sh +++ b/lint/clang-tidy.sh @@ -58,7 +58,8 @@ if [ -z "$target_source" ]; then shopt -s globstar pushd "$PROJECT_ROOT" > /dev/null - for f in include/**/*.h src/**/*.cpp test/coverage/**/*.cpp test/extra/**/*.cpp test/include/**/*.h; do + # for f in include/**/*.h src/**/*.cpp test/coverage/**/*.cpp test/extra/**/*.cpp test/include/**/*.h; do + for f in include/**/*.h src/**/*.cpp; do if [[ ! ("$f" =~ "build/") ]]; then echo echo "Checking file '$f'" diff --git a/src/client/usubscription/v3/RequestBuilder.cpp b/src/client/usubscription/v3/RequestBuilder.cpp index d11a18688..2340999c1 100644 --- a/src/client/usubscription/v3/RequestBuilder.cpp +++ b/src/client/usubscription/v3/RequestBuilder.cpp @@ -1,5 +1,15 @@ -#include "up-cpp/client/usubscription/v3/RequestBuilder.h" +// SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: Apache-2.0 +#include "up-cpp/client/usubscription/v3/RequestBuilder.h" #include namespace uprotocol::core::usubscription::v3 { diff --git a/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp b/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp index aa050de9c..f2f2ca483 100644 --- a/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp +++ b/src/client/usubscription/v3/USubscriptionUUriBuilder.cpp @@ -1,3 +1,14 @@ +// SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: Apache-2.0 + #include "up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h" namespace uprotocol::core::usubscription::v3 { diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp index 6136b2016..7f4474a91 100644 --- a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -14,8 +14,6 @@ #include #include -#include - #include "UTransportMock.h" namespace { From 9a03dc4cd750c6a7a68117653ecb7f6076448946 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Wed, 21 May 2025 11:23:06 +0200 Subject: [PATCH 072/105] Changed variable name in unsubscribe method signature. Create unsubscribe request in RpcClientUSubscription --- .../usubscription/v3/RpcClientUSubscription.h | 2 +- lint/clang-tidy.sh | 3 +- .../v3/RpcClientUSubscription.cpp | 45 ++++++++++++++++++- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index 9ebf9f82f..9d39ec64d 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -45,7 +45,7 @@ struct RpcClientUSubscription : USubscription { /// @brief Unsubscribe from the topic /// utils::Expected unsubscribe( - const UnsubscribeRequest& subscription_request) override; + const UnsubscribeRequest& unsubscribe_request) override; /// @brief Constructor /// diff --git a/lint/clang-tidy.sh b/lint/clang-tidy.sh index 1f74b24f4..19e9ddc80 100755 --- a/lint/clang-tidy.sh +++ b/lint/clang-tidy.sh @@ -58,8 +58,7 @@ if [ -z "$target_source" ]; then shopt -s globstar pushd "$PROJECT_ROOT" > /dev/null - # for f in include/**/*.h src/**/*.cpp test/coverage/**/*.cpp test/extra/**/*.cpp test/include/**/*.h; do - for f in include/**/*.h src/**/*.cpp; do + for f in include/**/*.h src/**/*.cpp test/coverage/**/*.cpp test/extra/**/*.cpp test/include/**/*.h; do if [[ ! ("$f" =~ "build/") ]]; then echo echo "Checking file '$f'" diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 313705215..f1ead1d60 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -21,8 +21,9 @@ #include "up-cpp/utils/ProtoConverter.h" constexpr uint16_t RESOURCE_ID_SUBSCRIBE = 0x0001; +constexpr uint16_t RESOURCE_ID_UNSUBSCRIBE = 0x0002; // TODO(lennart) see default_call_options() for the request in Rust -constexpr auto SUBSCRIPTION_REQUEST_TTL = +constexpr auto USUBSCRIPTION_REQUEST_TTL = std::chrono::milliseconds(0x0800); // TODO(lennart) change time auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; // MUST be >= 4 @@ -38,7 +39,7 @@ RpcClientUSubscription::subscribe( communication::RpcClient rpc_client( transport_, uuri_builder_.getServiceUriWithResourceId(RESOURCE_ID_SUBSCRIBE), - priority, SUBSCRIPTION_REQUEST_TTL); + priority, USUBSCRIPTION_REQUEST_TTL); auto payload_or_status = utils::ProtoConverter::protoToPayload(subscription_request); @@ -92,7 +93,47 @@ RpcClientUSubscription::subscribe( RpcClientUSubscription::ResponseOrStatus RpcClientUSubscription::unsubscribe( const UnsubscribeRequest& unsubscribe_request) { + communication::RpcClient rpc_client( + transport_, + uuri_builder_.getServiceUriWithResourceId(RESOURCE_ID_UNSUBSCRIBE), + priority, USUBSCRIPTION_REQUEST_TTL); + + auto payload_or_status = + utils::ProtoConverter::protoToPayload(unsubscribe_request); + + if (!payload_or_status.has_value()) { + return ResponseOrStatus( + utils::Unexpected(payload_or_status.error())); + } + datamodel::builder::Payload payload(payload_or_status.value()); + + auto message_or_status = rpc_client.invokeMethod(std::move(payload)).get(); + + if (!message_or_status.has_value()) { + return ResponseOrStatus( + utils::Unexpected(message_or_status.error())); + } + + spdlog::debug("response UMessage: {}", + message_or_status.value().DebugString()); UnsubscribeResponse unsubscribe_response; + + auto response_or_status = + utils::ProtoConverter::extractFromProtobuf( + message_or_status.value()); + + if (!response_or_status.has_value()) { + spdlog::error( + "unsubscribe: Error when extracting response from protobuf."); + return ResponseOrStatus( + utils::Unexpected(response_or_status.error())); + } + + unsubscribe_response = response_or_status.value(); + + spdlog::debug("unsubscribe: response: {}", + unsubscribe_response.DebugString()); + return ResponseOrStatus( std::move(unsubscribe_response)); } From a1ec439439777c0ff1ea901d576e76b09cf4c3aa Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Wed, 21 May 2025 11:44:51 +0200 Subject: [PATCH 073/105] Removed debugging in RpcClientUSubscription --- .../usubscription/v3/RpcClientUSubscription.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index f1ead1d60..041e8a6c6 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -57,8 +57,8 @@ RpcClientUSubscription::subscribe( utils::Unexpected(message_or_status.error())); } - spdlog::debug("response UMessage: {}", - message_or_status.value().DebugString()); + // spdlog::debug("response UMessage: {}", + // message_or_status.value().DebugString()); SubscriptionResponse subscription_response; auto response_or_status = @@ -74,8 +74,8 @@ RpcClientUSubscription::subscribe( subscription_response = response_or_status.value(); - spdlog::debug("subscribe: response: {}", - subscription_response.DebugString()); + // spdlog::debug("subscribe: response: {}", + // subscription_response.DebugString()); if (subscription_response.topic().SerializeAsString() != subscription_request.topic().SerializeAsString()) { @@ -114,8 +114,8 @@ RpcClientUSubscription::unsubscribe( utils::Unexpected(message_or_status.error())); } - spdlog::debug("response UMessage: {}", - message_or_status.value().DebugString()); + // spdlog::debug("response UMessage: {}", + // message_or_status.value().DebugString()); UnsubscribeResponse unsubscribe_response; auto response_or_status = @@ -131,8 +131,8 @@ RpcClientUSubscription::unsubscribe( unsubscribe_response = response_or_status.value(); - spdlog::debug("unsubscribe: response: {}", - unsubscribe_response.DebugString()); + // spdlog::debug("unsubscribe: response: {}", + // unsubscribe_response.DebugString()); return ResponseOrStatus( std::move(unsubscribe_response)); From 7863143e9f00c562583f51ac67ac5a77630b7df9 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Wed, 21 May 2025 14:39:17 +0200 Subject: [PATCH 074/105] Try to build Payload without any --- include/up-cpp/utils/ProtoConverter.h | 3 +++ .../v3/RpcClientUSubscription.cpp | 19 ++++++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/include/up-cpp/utils/ProtoConverter.h b/include/up-cpp/utils/ProtoConverter.h index 529ad6b40..cb257b968 100644 --- a/include/up-cpp/utils/ProtoConverter.h +++ b/include/up-cpp/utils/ProtoConverter.h @@ -80,6 +80,9 @@ struct ProtoConverter { */ template static TOrStatus extractFromProtobuf(const v1::UMessage& message) { + + // auto payload = std::get(message); + google::protobuf::Any any; if (!any.ParseFromString(message.payload())) { diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 041e8a6c6..7efdf783e 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -41,15 +41,16 @@ RpcClientUSubscription::subscribe( uuri_builder_.getServiceUriWithResourceId(RESOURCE_ID_SUBSCRIBE), priority, USUBSCRIPTION_REQUEST_TTL); - auto payload_or_status = - utils::ProtoConverter::protoToPayload(subscription_request); - - if (!payload_or_status.has_value()) { - return ResponseOrStatus( - utils::Unexpected(payload_or_status.error())); - } - datamodel::builder::Payload payload(payload_or_status.value()); - + // auto payload_or_status = + // utils::ProtoConverter::protoToPayload(subscription_request); + + // if (!payload_or_status.has_value()) { + // return ResponseOrStatus( + // utils::Unexpected(payload_or_status.error())); + // } + // datamodel::builder::Payload payload(payload_or_status.value()); + datamodel::builder::Payload payload(subscription_request); + auto message_or_status = rpc_client.invokeMethod(std::move(payload)).get(); if (!message_or_status.has_value()) { From 3d0fefc606d466781e3a49b52eb43780119ec3a5 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Wed, 21 May 2025 15:25:07 +0200 Subject: [PATCH 075/105] handle differnt types of UPayloadFormat in extractFromProtobuf --- include/up-cpp/utils/ProtoConverter.h | 88 ++++++++++++++----- .../v3/RpcClientUSubscription.cpp | 19 ++-- 2 files changed, 75 insertions(+), 32 deletions(-) diff --git a/include/up-cpp/utils/ProtoConverter.h b/include/up-cpp/utils/ProtoConverter.h index cb257b968..8ce0c2782 100644 --- a/include/up-cpp/utils/ProtoConverter.h +++ b/include/up-cpp/utils/ProtoConverter.h @@ -81,29 +81,73 @@ struct ProtoConverter { template static TOrStatus extractFromProtobuf(const v1::UMessage& message) { - // auto payload = std::get(message); + switch (message.attributes().payload_format()) { + + case v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF: { + T response; + if (!response.ParseFromString(message.payload())) { + v1::UStatus status; + status.set_code(v1::UCode::INTERNAL); + status.set_message("extractFromProtobuf: Error when parsing payload from protobuf."); + return TOrStatus(UnexpectedStatus(status)); + } + return TOrStatus(response); //TODO(lennart) UnpackTo not necessary? + } + + case v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY: { + google::protobuf::Any any; + if (!any.ParseFromString(message.payload())) { + v1::UStatus status; + status.set_code(v1::UCode::INTERNAL); + status.set_message( + "extractFromProtobuf: Error when parsing payload from protobuf any."); + return TOrStatus(UnexpectedStatus(status)); + } + T response; + if (!any.UnpackTo(&response)) { + v1::UStatus status; + status.set_code(v1::UCode::INTERNAL); + status.set_message( + "extractFromProtobuf: Error when unpacking any."); + return TOrStatus(UnexpectedStatus(status)); + } + return TOrStatus(response); + } + + case v1::UPayloadFormat::UPAYLOAD_FORMAT_UNSPECIFIED: { + google::protobuf::Any any; + if (!any.ParseFromString(message.payload())) { + v1::UStatus status; + status.set_code(v1::UCode::INTERNAL); + status.set_message("Error when parsing payload from unspecified format."); + return TOrStatus(UnexpectedStatus(status)); + } + T response; + if (!any.UnpackTo(&response)) { + v1::UStatus status; + status.set_code(v1::UCode::INTERNAL); + status.set_message( + "Cannot deserialize payload, message type mismatch."); + return TOrStatus(UnexpectedStatus(status)); + } + return TOrStatus(response); + } + case v1::UPayloadFormat::UPAYLOAD_FORMAT_JSON: + case v1::UPayloadFormat::UPAYLOAD_FORMAT_SOMEIP: + case v1::UPayloadFormat::UPAYLOAD_FORMAT_SOMEIP_TLV: + case v1::UPayloadFormat::UPAYLOAD_FORMAT_RAW: + case v1::UPayloadFormat::UPAYLOAD_FORMAT_TEXT: + case v1::UPayloadFormat::UPAYLOAD_FORMAT_SHM: + case v1::UPayloadFormat::UPayloadFormat_INT_MIN_SENTINEL_DO_NOT_USE_: + case v1::UPayloadFormat::UPayloadFormat_INT_MAX_SENTINEL_DO_NOT_USE_: + default: { + v1::UStatus status; + status.set_code(v1::UCode::INVALID_ARGUMENT); + status.set_message("Unknown/invalid/unsupported payload format."); + return TOrStatus(UnexpectedStatus(status)); + } + } - google::protobuf::Any any; - - if (!any.ParseFromString(message.payload())) { - v1::UStatus status; - status.set_code(v1::UCode::INTERNAL); - status.set_message( - "extractFromProtobuf: Error when parsing payload."); - return TOrStatus(UnexpectedStatus(status)); - } - - T response; - - if (!any.UnpackTo(&response)) { - v1::UStatus status; - status.set_code(v1::UCode::INTERNAL); - status.set_message( - "extractFromProtobuf: Error when unpacking any."); - return TOrStatus(UnexpectedStatus(status)); - } - - return TOrStatus(response); } /** diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 7efdf783e..041e8a6c6 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -41,16 +41,15 @@ RpcClientUSubscription::subscribe( uuri_builder_.getServiceUriWithResourceId(RESOURCE_ID_SUBSCRIBE), priority, USUBSCRIPTION_REQUEST_TTL); - // auto payload_or_status = - // utils::ProtoConverter::protoToPayload(subscription_request); - - // if (!payload_or_status.has_value()) { - // return ResponseOrStatus( - // utils::Unexpected(payload_or_status.error())); - // } - // datamodel::builder::Payload payload(payload_or_status.value()); - datamodel::builder::Payload payload(subscription_request); - + auto payload_or_status = + utils::ProtoConverter::protoToPayload(subscription_request); + + if (!payload_or_status.has_value()) { + return ResponseOrStatus( + utils::Unexpected(payload_or_status.error())); + } + datamodel::builder::Payload payload(payload_or_status.value()); + auto message_or_status = rpc_client.invokeMethod(std::move(payload)).get(); if (!message_or_status.has_value()) { From 4355a101db5d34f04cb9baa43d81b9314d3688c2 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Wed, 21 May 2025 16:50:16 +0200 Subject: [PATCH 076/105] Move handling to invokeProtoMethod ind RpcClient --- include/up-cpp/communication/RpcClient.h | 43 +++++++++++ include/up-cpp/utils/ProtoConverter.h | 23 +----- .../v3/RpcClientUSubscription.cpp | 75 ++----------------- 3 files changed, 51 insertions(+), 90 deletions(-) diff --git a/include/up-cpp/communication/RpcClient.h b/include/up-cpp/communication/RpcClient.h index c78ab5f94..250bc50f8 100644 --- a/include/up-cpp/communication/RpcClient.h +++ b/include/up-cpp/communication/RpcClient.h @@ -12,11 +12,14 @@ #ifndef UP_CPP_COMMUNICATION_RPCCLIENT_H #define UP_CPP_COMMUNICATION_RPCCLIENT_H +#include #include #include #include #include +#include #include +#include #include #include @@ -25,6 +28,9 @@ #include namespace uprotocol::communication { +template +using ResponseOrStatus = utils::Expected; +using UnexpectedStatus = utils::Unexpected; /// @brief Interface for uEntities to invoke RPC methods. /// @@ -161,6 +167,43 @@ struct RpcClient { /// message (if not OK). /// * A UMessage containing the response from the RPC target. [[nodiscard]] InvokeFuture invokeMethod(); + + template + ResponseOrStatus invokeProtoMethod(const R& request_message){ + auto payload_or_status = + uprotocol::utils::ProtoConverter::protoToPayload(request_message); + + if (!payload_or_status.has_value()) { + return ResponseOrStatus( + UnexpectedStatus(payload_or_status.error())); + } + datamodel::builder::Payload payload(payload_or_status.value()); + + auto message_or_status = this->invokeMethod(std::move(payload)).get(); + + if (!message_or_status.has_value()) { + return ResponseOrStatus( + UnexpectedStatus(message_or_status.error())); + } + + T response_message; + + auto response_or_status = + utils::ProtoConverter::extractFromProtobuf( + message_or_status.value()); + + if (!response_or_status.has_value()) { + spdlog::error( + "invokeProtoMethod: Error when extracting response from protobuf."); + return ResponseOrStatus( + UnexpectedStatus(response_or_status.error())); + } + + response_message = response_or_status.value(); + + return ResponseOrStatus( + std::move(response_message)); + } /// @brief Default move constructor (defined in RpcClient.cpp) RpcClient(RpcClient&&) noexcept; diff --git a/include/up-cpp/utils/ProtoConverter.h b/include/up-cpp/utils/ProtoConverter.h index 8ce0c2782..e9fae0afb 100644 --- a/include/up-cpp/utils/ProtoConverter.h +++ b/include/up-cpp/utils/ProtoConverter.h @@ -91,9 +91,9 @@ struct ProtoConverter { status.set_message("extractFromProtobuf: Error when parsing payload from protobuf."); return TOrStatus(UnexpectedStatus(status)); } - return TOrStatus(response); //TODO(lennart) UnpackTo not necessary? + return TOrStatus(response); } - + case v1::UPayloadFormat::UPAYLOAD_FORMAT_UNSPECIFIED: case v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY: { google::protobuf::Any any; if (!any.ParseFromString(message.payload())) { @@ -113,25 +113,6 @@ struct ProtoConverter { } return TOrStatus(response); } - - case v1::UPayloadFormat::UPAYLOAD_FORMAT_UNSPECIFIED: { - google::protobuf::Any any; - if (!any.ParseFromString(message.payload())) { - v1::UStatus status; - status.set_code(v1::UCode::INTERNAL); - status.set_message("Error when parsing payload from unspecified format."); - return TOrStatus(UnexpectedStatus(status)); - } - T response; - if (!any.UnpackTo(&response)) { - v1::UStatus status; - status.set_code(v1::UCode::INTERNAL); - status.set_message( - "Cannot deserialize payload, message type mismatch."); - return TOrStatus(UnexpectedStatus(status)); - } - return TOrStatus(response); - } case v1::UPayloadFormat::UPAYLOAD_FORMAT_JSON: case v1::UPayloadFormat::UPAYLOAD_FORMAT_SOMEIP: case v1::UPayloadFormat::UPAYLOAD_FORMAT_SOMEIP_TLV: diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 041e8a6c6..33d7a96b9 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -18,6 +18,7 @@ #include #include "up-cpp/communication/RpcClient.h" +#include "up-cpp/utils/Expected.h" #include "up-cpp/utils/ProtoConverter.h" constexpr uint16_t RESOURCE_ID_SUBSCRIBE = 0x0001; @@ -41,41 +42,14 @@ RpcClientUSubscription::subscribe( uuri_builder_.getServiceUriWithResourceId(RESOURCE_ID_SUBSCRIBE), priority, USUBSCRIPTION_REQUEST_TTL); - auto payload_or_status = - utils::ProtoConverter::protoToPayload(subscription_request); - - if (!payload_or_status.has_value()) { - return ResponseOrStatus( - utils::Unexpected(payload_or_status.error())); - } - datamodel::builder::Payload payload(payload_or_status.value()); - - auto message_or_status = rpc_client.invokeMethod(std::move(payload)).get(); - - if (!message_or_status.has_value()) { - return ResponseOrStatus( - utils::Unexpected(message_or_status.error())); - } - - // spdlog::debug("response UMessage: {}", - // message_or_status.value().DebugString()); - SubscriptionResponse subscription_response; - auto response_or_status = - utils::ProtoConverter::extractFromProtobuf( - message_or_status.value()); + rpc_client.invokeProtoMethod(subscription_request); if (!response_or_status.has_value()) { - spdlog::error( - "subscribe: Error when extracting response from protobuf."); - return ResponseOrStatus( - utils::Unexpected(response_or_status.error())); + return utils::Expected( + utils::Unexpected(response_or_status.error())); } - - subscription_response = response_or_status.value(); - - // spdlog::debug("subscribe: response: {}", - // subscription_response.DebugString()); + auto subscription_response = response_or_status.value(); if (subscription_response.topic().SerializeAsString() != subscription_request.topic().SerializeAsString()) { @@ -98,44 +72,7 @@ RpcClientUSubscription::unsubscribe( uuri_builder_.getServiceUriWithResourceId(RESOURCE_ID_UNSUBSCRIBE), priority, USUBSCRIPTION_REQUEST_TTL); - auto payload_or_status = - utils::ProtoConverter::protoToPayload(unsubscribe_request); - - if (!payload_or_status.has_value()) { - return ResponseOrStatus( - utils::Unexpected(payload_or_status.error())); - } - datamodel::builder::Payload payload(payload_or_status.value()); - - auto message_or_status = rpc_client.invokeMethod(std::move(payload)).get(); - - if (!message_or_status.has_value()) { - return ResponseOrStatus( - utils::Unexpected(message_or_status.error())); - } - - // spdlog::debug("response UMessage: {}", - // message_or_status.value().DebugString()); - UnsubscribeResponse unsubscribe_response; - - auto response_or_status = - utils::ProtoConverter::extractFromProtobuf( - message_or_status.value()); - - if (!response_or_status.has_value()) { - spdlog::error( - "unsubscribe: Error when extracting response from protobuf."); - return ResponseOrStatus( - utils::Unexpected(response_or_status.error())); - } - - unsubscribe_response = response_or_status.value(); - - // spdlog::debug("unsubscribe: response: {}", - // unsubscribe_response.DebugString()); - - return ResponseOrStatus( - std::move(unsubscribe_response)); + return rpc_client.invokeProtoMethod(unsubscribe_request); } } // namespace uprotocol::core::usubscription::v3 From de6870fdbab3c2b490957a3b3c850b5b38b37972 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Wed, 21 May 2025 16:52:03 +0200 Subject: [PATCH 077/105] Add Debug string --- include/up-cpp/communication/RpcClient.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/up-cpp/communication/RpcClient.h b/include/up-cpp/communication/RpcClient.h index 250bc50f8..e8fe228a0 100644 --- a/include/up-cpp/communication/RpcClient.h +++ b/include/up-cpp/communication/RpcClient.h @@ -201,6 +201,9 @@ struct RpcClient { response_message = response_or_status.value(); + spdlog::debug( + "invokeProtoMethod: Successfully extracted response from protobuf. {}", response_message.DebugString()); + return ResponseOrStatus( std::move(response_message)); } From 63ed549dbb5a3c942dc5e3615a99cd49b815456a Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Wed, 21 May 2025 17:30:21 +0200 Subject: [PATCH 078/105] Removed debugging of response in up-cpp --- include/up-cpp/communication/RpcClient.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/up-cpp/communication/RpcClient.h b/include/up-cpp/communication/RpcClient.h index e8fe228a0..250bc50f8 100644 --- a/include/up-cpp/communication/RpcClient.h +++ b/include/up-cpp/communication/RpcClient.h @@ -201,9 +201,6 @@ struct RpcClient { response_message = response_or_status.value(); - spdlog::debug( - "invokeProtoMethod: Successfully extracted response from protobuf. {}", response_message.DebugString()); - return ResponseOrStatus( std::move(response_message)); } From 677a9bdaf3a804aa4561e68e05331ed1d4f3c537 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Thu, 22 May 2025 11:59:40 +0200 Subject: [PATCH 079/105] Added fetch_subscriptions to USubscription --- .../usubscription/v3/RpcClientUSubscription.h | 5 ++++ .../client/usubscription/v3/USubscription.h | 4 +-- .../v3/RpcClientUSubscription.cpp | 26 +++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index 9d39ec64d..2cb62d54b 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -46,6 +46,11 @@ struct RpcClientUSubscription : USubscription { /// utils::Expected unsubscribe( const UnsubscribeRequest& unsubscribe_request) override; + + /// @brief Fetch all subscriptions + /// + utils::Expected fetch_subscriptions( + const FetchSubscriptionsRequest& fetch_subscribers) override; /// @brief Constructor /// diff --git a/include/up-cpp/client/usubscription/v3/USubscription.h b/include/up-cpp/client/usubscription/v3/USubscription.h index fce671b05..6b89377a8 100644 --- a/include/up-cpp/client/usubscription/v3/USubscription.h +++ b/include/up-cpp/client/usubscription/v3/USubscription.h @@ -31,8 +31,8 @@ struct USubscription { virtual ResponseOrStatus unsubscribe( const UnsubscribeRequest& unsubscribe_request) = 0; - // virtual FetchSubscriptionsResponse fetch_subscriptions(const - // FetchSubscriptionsRequest& fetch_subscribers_request) = 0; + virtual ResponseOrStatus fetch_subscriptions(const + FetchSubscriptionsRequest& fetch_subscribers_request) = 0; // virtual NotificationsResponse register_for_notifications(const // NotificationsRequest& register_notifications_request) =0 ; diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 33d7a96b9..c272f1f45 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -21,8 +21,23 @@ #include "up-cpp/utils/Expected.h" #include "up-cpp/utils/ProtoConverter.h" +/// The uEntity (type) identifier of the uSubscription service. +constexpr uint32_t USUBSCRIPTION_TYPE_ID = 0x00000000; +/// The (latest) major version of the uSubscription service. +constexpr uint8_t USUBSCRIPTION_VERSION_MAJOR = 0x03; +/// The resource identifier of uSubscription's _subscribe_ operation. constexpr uint16_t RESOURCE_ID_SUBSCRIBE = 0x0001; +/// The resource identifier of uSubscription's _unsubscribe_ operation. constexpr uint16_t RESOURCE_ID_UNSUBSCRIBE = 0x0002; +/// The resource identifier of uSubscription's _fetch subscriptions_ operation. +constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIPTIONS = 0x0003; +/// The resource identifier of uSubscription's _register for notifications_ operation. +constexpr uint16_t RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS = 0x0006; +/// The resource identifier of uSubscription's _unregister for notifications_ operation. +constexpr uint16_t RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS = 0x0007; +/// The resource identifier of uSubscription's _fetch subscribers_ operation. +constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIBERS = 0x0008; + // TODO(lennart) see default_call_options() for the request in Rust constexpr auto USUBSCRIPTION_REQUEST_TTL = std::chrono::milliseconds(0x0800); // TODO(lennart) change time @@ -75,4 +90,15 @@ RpcClientUSubscription::unsubscribe( return rpc_client.invokeProtoMethod(unsubscribe_request); } +RpcClientUSubscription::ResponseOrStatus +RpcClientUSubscription::fetch_subscriptions( + const FetchSubscriptionsRequest& fetch_subscribers_request) { + communication::RpcClient rpc_client( + transport_, + uuri_builder_.getServiceUriWithResourceId(RESOURCE_ID_FETCH_SUBSCRIPTIONS), + priority, USUBSCRIPTION_REQUEST_TTL); + + return rpc_client.invokeProtoMethod(fetch_subscribers_request); +} + } // namespace uprotocol::core::usubscription::v3 From 07c678e3e31fdfba3fe4ec9a8bfe6adffed7a746 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Thu, 22 May 2025 12:11:41 +0200 Subject: [PATCH 080/105] Added buildFetchSubscriptionsRequest --- .../up-cpp/client/usubscription/v3/RequestBuilder.h | 10 ++++++++++ src/client/usubscription/v3/RequestBuilder.cpp | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/include/up-cpp/client/usubscription/v3/RequestBuilder.h b/include/up-cpp/client/usubscription/v3/RequestBuilder.h index 8d8cd413a..0e9cb8d75 100644 --- a/include/up-cpp/client/usubscription/v3/RequestBuilder.h +++ b/include/up-cpp/client/usubscription/v3/RequestBuilder.h @@ -12,6 +12,7 @@ #ifndef UP_CPP_CLIENT_USUBSCRIPTION_V3_REQUESTBUILDER_H #define UP_CPP_CLIENT_USUBSCRIPTION_V3_REQUESTBUILDER_H #include +#include #include @@ -72,6 +73,15 @@ struct RequestBuilder { */ static UnsubscribeRequest buildUnsubscribeRequest(const v1::UUri& topic); + /** + * @brief Builds an fetch subscription request for a given topic. + * + * @param topic The `v1::UUri` representing the topic to fetch. + * + * @return An `FetchSubscriptionsRequest` configured for the specified topic. + */ + static FetchSubscriptionsRequest buildFetchSubscriptionsRequest(const v1::UUri& topic); + private: USubscriptionOptions options_; ///< Options used to configure the requests. }; diff --git a/src/client/usubscription/v3/RequestBuilder.cpp b/src/client/usubscription/v3/RequestBuilder.cpp index 2340999c1..3f2f8a975 100644 --- a/src/client/usubscription/v3/RequestBuilder.cpp +++ b/src/client/usubscription/v3/RequestBuilder.cpp @@ -33,4 +33,12 @@ UnsubscribeRequest RequestBuilder::buildUnsubscribeRequest( return utils::ProtoConverter::BuildUnSubscribeRequest(topic); } +FetchSubscriptionsRequest RequestBuilder::buildFetchSubscriptionsRequest( + const v1::UUri& topic) { + FetchSubscriptionsRequest fetch_subscriptions_request; + *fetch_subscriptions_request.mutable_topic() = topic; + + return fetch_subscriptions_request; +} + } // namespace uprotocol::core::usubscription::v3 From 32039ba9aeabab83f7e33e7ccf4a78971fde6670 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Thu, 22 May 2025 17:23:38 +0200 Subject: [PATCH 081/105] Added missing methods for RpcClientUSubscription and RequestBuilder to get the request prepared --- .../client/usubscription/v3/RequestBuilder.h | 30 ++++++++++++++++- .../usubscription/v3/RpcClientUSubscription.h | 17 +++++++++- .../client/usubscription/v3/USubscription.h | 12 +++---- .../usubscription/v3/RequestBuilder.cpp | 24 ++++++++++++++ .../v3/RpcClientUSubscription.cpp | 33 +++++++++++++++++++ 5 files changed, 108 insertions(+), 8 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RequestBuilder.h b/include/up-cpp/client/usubscription/v3/RequestBuilder.h index 0e9cb8d75..a86299abe 100644 --- a/include/up-cpp/client/usubscription/v3/RequestBuilder.h +++ b/include/up-cpp/client/usubscription/v3/RequestBuilder.h @@ -74,7 +74,7 @@ struct RequestBuilder { static UnsubscribeRequest buildUnsubscribeRequest(const v1::UUri& topic); /** - * @brief Builds an fetch subscription request for a given topic. + * @brief Build fetch subscritions request for a given topic. * * @param topic The `v1::UUri` representing the topic to fetch. * @@ -82,6 +82,34 @@ struct RequestBuilder { */ static FetchSubscriptionsRequest buildFetchSubscriptionsRequest(const v1::UUri& topic); + /** + * @brief Build fetch subscritions request for a given subscriber. + * + * @param subscriber The `SubscriberInfo` representing the subscriber to fetch. + * + * @return An `FetchSubscriptionsRequest` configured for the specified subscriber. + */ + static FetchSubscriptionsRequest buildFetchSubscriptionsRequest(const SubscriberInfo& subscriber); + + /** + * @brief Build fetch subscribers request for a given topic. + * + * @param topic The `v1::UUri` representing the topic to fetch. + * + * @return An `FetchSubscribersRequest` configured for the specified topic. + */ + static FetchSubscribersRequest buildFetchSubscribersRequest(const v1::UUri& topic); + + /** + * @brief Build notification request for a given topic. + * + * @param topic The `v1::UUri` representing the topic to (un)register for/from. + * + * @return An `NotificationsRequest` configured for the specified topic. + */ + static NotificationsRequest buildNotificationRequest(const v1::UUri& topic); + + private: USubscriptionOptions options_; ///< Options used to configure the requests. }; diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index 2cb62d54b..a652042c7 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -47,11 +47,26 @@ struct RpcClientUSubscription : USubscription { utils::Expected unsubscribe( const UnsubscribeRequest& unsubscribe_request) override; - /// @brief Fetch all subscriptions + /// @brief Fetch all subscriptions either by topic or subscriber /// utils::Expected fetch_subscriptions( const FetchSubscriptionsRequest& fetch_subscribers) override; + /// @brief Fetch all subscribers + /// + utils::Expected fetch_subscribers( + const FetchSubscribersRequest& fetch_subscribers) override; + + /// @brief Register for notifications + /// + utils::Expected register_for_notifications(const + NotificationsRequest& register_notifications_request) override ; + + /// @brief Unregister for notifications + /// + utils::Expected unregister_for_notifications(const + NotificationsRequest& unregister_notifications_request) override ; + /// @brief Constructor /// /// @param transport Transport to register with. diff --git a/include/up-cpp/client/usubscription/v3/USubscription.h b/include/up-cpp/client/usubscription/v3/USubscription.h index 6b89377a8..e6673588c 100644 --- a/include/up-cpp/client/usubscription/v3/USubscription.h +++ b/include/up-cpp/client/usubscription/v3/USubscription.h @@ -34,14 +34,14 @@ struct USubscription { virtual ResponseOrStatus fetch_subscriptions(const FetchSubscriptionsRequest& fetch_subscribers_request) = 0; - // virtual NotificationsResponse register_for_notifications(const - // NotificationsRequest& register_notifications_request) =0 ; + virtual ResponseOrStatus register_for_notifications(const + NotificationsRequest& register_notifications_request) =0 ; - // virtual NotificationsResponse unregister_for_notifications(const - // NotificationsRequest& unregister_notifications_request) = 0; + virtual ResponseOrStatus unregister_for_notifications(const + NotificationsRequest& unregister_notifications_request) = 0; - // virtual FetchSubscribersResponse fetch_subscribers(const - // FetchSubscribersRequest& fetch_subscribers_request) = 0; + virtual ResponseOrStatus fetch_subscribers(const + FetchSubscribersRequest& fetch_subscribers_request) = 0; }; } // namespace uprotocol::core::usubscription::v3 diff --git a/src/client/usubscription/v3/RequestBuilder.cpp b/src/client/usubscription/v3/RequestBuilder.cpp index 3f2f8a975..39a51f669 100644 --- a/src/client/usubscription/v3/RequestBuilder.cpp +++ b/src/client/usubscription/v3/RequestBuilder.cpp @@ -41,4 +41,28 @@ FetchSubscriptionsRequest RequestBuilder::buildFetchSubscriptionsRequest( return fetch_subscriptions_request; } +FetchSubscriptionsRequest RequestBuilder::buildFetchSubscriptionsRequest( + const SubscriberInfo& subscriber) { + FetchSubscriptionsRequest fetch_subscriptions_request; + *fetch_subscriptions_request.mutable_subscriber() = subscriber; + + return fetch_subscriptions_request; +} + +FetchSubscribersRequest RequestBuilder::buildFetchSubscribersRequest( + const v1::UUri& topic) { + FetchSubscribersRequest fetch_subscribers_request; + *fetch_subscribers_request.mutable_topic() = topic; + + return fetch_subscribers_request; +} + +NotificationsRequest RequestBuilder::buildNotificationRequest( + const v1::UUri& topic) { + NotificationsRequest notification_request; + *notification_request.mutable_topic() = topic; + + return notification_request; +} + } // namespace uprotocol::core::usubscription::v3 diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index c272f1f45..96ee1c472 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -101,4 +101,37 @@ RpcClientUSubscription::fetch_subscriptions( return rpc_client.invokeProtoMethod(fetch_subscribers_request); } +RpcClientUSubscription::ResponseOrStatus +RpcClientUSubscription::fetch_subscribers( + const FetchSubscribersRequest& fetch_subscribers_request) { + communication::RpcClient rpc_client( + transport_, + uuri_builder_.getServiceUriWithResourceId(RESOURCE_ID_FETCH_SUBSCRIBERS), + priority, USUBSCRIPTION_REQUEST_TTL); + + return rpc_client.invokeProtoMethod(fetch_subscribers_request); +} + +RpcClientUSubscription::ResponseOrStatus +RpcClientUSubscription::register_for_notifications( + const NotificationsRequest& register_notifications_request) { + communication::RpcClient rpc_client( + transport_, + uuri_builder_.getServiceUriWithResourceId(RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS), + priority, USUBSCRIPTION_REQUEST_TTL); + + return rpc_client.invokeProtoMethod(register_notifications_request); +} + +RpcClientUSubscription::ResponseOrStatus +RpcClientUSubscription::unregister_for_notifications( + const NotificationsRequest& unregister_notifications_request) { + communication::RpcClient rpc_client( + transport_, + uuri_builder_.getServiceUriWithResourceId(RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS), + priority, USUBSCRIPTION_REQUEST_TTL); + + return rpc_client.invokeProtoMethod(unregister_notifications_request); +} + } // namespace uprotocol::core::usubscription::v3 From 98516fabcd59035764bb7534411bb70b6007e875 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Fri, 23 May 2025 14:45:39 +0200 Subject: [PATCH 082/105] Added comment to clarify topic for notification manager --- include/up-cpp/client/usubscription/v3/RequestBuilder.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/up-cpp/client/usubscription/v3/RequestBuilder.h b/include/up-cpp/client/usubscription/v3/RequestBuilder.h index a86299abe..b87579280 100644 --- a/include/up-cpp/client/usubscription/v3/RequestBuilder.h +++ b/include/up-cpp/client/usubscription/v3/RequestBuilder.h @@ -101,7 +101,8 @@ struct RequestBuilder { static FetchSubscribersRequest buildFetchSubscribersRequest(const v1::UUri& topic); /** - * @brief Build notification request for a given topic. + * @brief Build notification request for a given topic. Subscription change notifications + * MUST use topic SubscriptionChange with resource id 0x8000, as per the protobuf definition. * * @param topic The `v1::UUri` representing the topic to (un)register for/from. * From 9aeab6be1279b90c49a04680dd2b9a543f97590c Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Fri, 23 May 2025 14:55:00 +0200 Subject: [PATCH 083/105] Some cleanup. No change in functionality --- .../usubscription/v3/RpcClientUSubscription.h | 20 ++++++++++++++++ .../v3/RpcClientUSubscription.cpp | 23 +------------------ .../v3/RpcClientUSubscriptionTest.cpp | 6 ++--- 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index a652042c7..56f4ce4e4 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -20,6 +20,26 @@ #include "up-cpp/client/usubscription/v3/USubscription.h" #include "up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h" +/// The uEntity (type) identifier of the uSubscription service. +constexpr uint32_t USUBSCRIPTION_TYPE_ID = 0x00000000; +/// The (latest) major version of the uSubscription service. +constexpr uint8_t USUBSCRIPTION_VERSION_MAJOR = 0x03; +/// The resource identifier of uSubscription's _subscribe_ operation. +constexpr uint16_t RESOURCE_ID_SUBSCRIBE = 0x0001; +/// The resource identifier of uSubscription's _unsubscribe_ operation. +constexpr uint16_t RESOURCE_ID_UNSUBSCRIBE = 0x0002; +/// The resource identifier of uSubscription's _fetch subscriptions_ operation. +constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIPTIONS = 0x0003; +/// The resource identifier of uSubscription's _register for notifications_ operation. +constexpr uint16_t RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS = 0x0006; +/// The resource identifier of uSubscription's _unregister for notifications_ operation. +constexpr uint16_t RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS = 0x0007; +/// The resource identifier of uSubscription's _fetch subscribers_ operation. +constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIBERS = 0x0008; +// TODO(lennart) see default_call_options() for the request in Rust +constexpr auto USUBSCRIPTION_REQUEST_TTL = + std::chrono::milliseconds(0x0800); // TODO(lennart) change time + namespace uprotocol::core::usubscription::v3 { using v3::SubscriptionRequest; using v3::UnsubscribeRequest; diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 96ee1c472..c8351faad 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -19,28 +19,7 @@ #include "up-cpp/communication/RpcClient.h" #include "up-cpp/utils/Expected.h" -#include "up-cpp/utils/ProtoConverter.h" - -/// The uEntity (type) identifier of the uSubscription service. -constexpr uint32_t USUBSCRIPTION_TYPE_ID = 0x00000000; -/// The (latest) major version of the uSubscription service. -constexpr uint8_t USUBSCRIPTION_VERSION_MAJOR = 0x03; -/// The resource identifier of uSubscription's _subscribe_ operation. -constexpr uint16_t RESOURCE_ID_SUBSCRIBE = 0x0001; -/// The resource identifier of uSubscription's _unsubscribe_ operation. -constexpr uint16_t RESOURCE_ID_UNSUBSCRIBE = 0x0002; -/// The resource identifier of uSubscription's _fetch subscriptions_ operation. -constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIPTIONS = 0x0003; -/// The resource identifier of uSubscription's _register for notifications_ operation. -constexpr uint16_t RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS = 0x0006; -/// The resource identifier of uSubscription's _unregister for notifications_ operation. -constexpr uint16_t RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS = 0x0007; -/// The resource identifier of uSubscription's _fetch subscribers_ operation. -constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIBERS = 0x0008; - -// TODO(lennart) see default_call_options() for the request in Rust -constexpr auto USUBSCRIPTION_REQUEST_TTL = - std::chrono::milliseconds(0x0800); // TODO(lennart) change time + auto priority = uprotocol::v1::UPriority::UPRIORITY_CS4; // MUST be >= 4 namespace uprotocol::core::usubscription::v3 { diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp index 7f4474a91..d87ee1e5d 100644 --- a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -51,7 +51,7 @@ class RpcClientUSubscriptionTest : public testing::Test { // Create a generic transport uri client_uuri.set_authority_name("random_string"); client_uuri.set_ue_id(TEST_UE_ID); - client_uuri.set_ue_version_major(3); + client_uuri.set_ue_version_major(USUBSCRIPTION_VERSION_MAJOR); client_uuri.set_resource_id(0); // Set up a transport @@ -61,7 +61,7 @@ class RpcClientUSubscriptionTest : public testing::Test { // Craete server default uri and set up a transport server_uuri.set_authority_name("core.usubscription"); server_uuri.set_ue_id(0); - server_uuri.set_ue_version_major(3); + server_uuri.set_ue_version_major(USUBSCRIPTION_VERSION_MAJOR); server_uuri.set_resource_id(0); mockTransportServer_ = @@ -70,7 +70,7 @@ class RpcClientUSubscriptionTest : public testing::Test { // Create a generic subscription uri subscription_uuri.set_authority_name("10.0.0.2"); subscription_uuri.set_ue_id(TEST_UE_ID); - subscription_uuri.set_ue_version_major(3); + subscription_uuri.set_ue_version_major(USUBSCRIPTION_VERSION_MAJOR); subscription_uuri.set_resource_id(DEFAULT_RESOURCE_ID); }; void TearDown() override {} From da3b5dc8cb66ee0f26639be98c240e91ba425930 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Fri, 23 May 2025 16:07:52 +0200 Subject: [PATCH 084/105] Added RequestBuilderTest --- test/CMakeLists.txt | 1 + .../usubscription/v3/RequestBuilderTest.cpp | 96 +++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 test/coverage/client/usubscription/v3/RequestBuilderTest.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 56c122710..3f3adc32b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -86,6 +86,7 @@ add_coverage_test("ConsumerTest" coverage/client/usubscription/v3/ConsumerTest.c # core add_coverage_test("RpcClientUSubscriptionTest" coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp) +add_coverage_test("RequestBuilderTest" coverage/client/usubscription/v3/RequestBuilderTest.cpp) ########################## EXTRAS ############################################# add_extra_test("PublisherSubscriberTest" extra/PublisherSubscriberTest.cpp) diff --git a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp new file mode 100644 index 000000000..656a1cd54 --- /dev/null +++ b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp @@ -0,0 +1,96 @@ +// SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: Apache-2.0 + +#include +#include "up-cpp/client/usubscription/v3/RequestBuilder.h" +#include +#include +#include +#include +#include +#include + +constexpr uint32_t SOURCE_UE_ID = 0x00011101; +constexpr uint32_t SOURCE_UE_VERSION_MAJOR = 0xF8; +constexpr uint32_t SOURCE_RESOURCE_ID = 0x8101; + +namespace uprotocol::core::usubscription::v3 { + +class RequestBuilderTest : public ::testing::Test { + +private: + v1::UUri source_; + +protected: + USubscriptionOptions options_; + const v1::UUri& getSource() const { return source_; } + + void SetUp() override { + // Create a UUri object for testing + source_.set_authority_name("10.0.0.1"); + source_.set_ue_id(SOURCE_UE_ID); + source_.set_ue_version_major(SOURCE_UE_VERSION_MAJOR); + source_.set_resource_id(SOURCE_RESOURCE_ID); + + options_.permission_level = 2; + options_.token = "sample_token"; + options_.when_expire = std::chrono::system_clock::now() + std::chrono::milliseconds(1000); + options_.sample_period_ms = std::chrono::milliseconds(1000); + options_.subscriber_details = google::protobuf::Any(); + options_.subscription_details = google::protobuf::Any(); + } + void TearDown() override {} + + // Run once per execution of the test application. + // Used for setup of all tests. Has access to this instance. + RequestBuilderTest() = default; + + // Run once per execution of the test application. + // Used only for global setup outside of tests. + static void SetUpTestSuite() {} + static void TearDownTestSuite() {} + +public: + ~RequestBuilderTest() override = default; +}; + +TEST_F(RequestBuilderTest, BuildSubscriptionRequestWithOptions) { + v1::UUri topic = getSource(); + RequestBuilder builder(options_); + + SubscriptionRequest request = builder.buildSubscriptionRequest(topic); + + // Verify the attributes in the request + EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); + std::cout<< "request.SerializeAsString(): " << request.SerializeAsString() << std::endl; + std::cout<< "request.attributes: " << request.attributes().SerializeAsString() << std::endl; + +} + +TEST_F(RequestBuilderTest, BuildSubscriptionRequestWrongTopic) { + v1::UUri topic = getSource(); + RequestBuilder builder(options_); + + v1::UUri wrong_topic; + + wrong_topic.set_authority_name("10.0.0.2"); // random different authority + wrong_topic.set_ue_id(SOURCE_UE_ID); + wrong_topic.set_ue_version_major(SOURCE_UE_VERSION_MAJOR); + wrong_topic.set_resource_id(SOURCE_RESOURCE_ID); + + SubscriptionRequest request = builder.buildSubscriptionRequest(topic); + + // Verify the attributes in the request + EXPECT_NE(request.topic().SerializeAsString(), wrong_topic.SerializeAsString()); + +} + +} // namespace uprotocol::core::usubscription::v3 \ No newline at end of file From df7ce2b263b12220ea3f1aae80608bcab271389d Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 25 May 2025 22:16:04 +0200 Subject: [PATCH 085/105] added first test for subscribe method --- CMakeLists.txt | 3 +- .../usubscription/v3/RpcClientUSubscription.h | 2 +- test/CMakeLists.txt | 4 +- .../v3/RpcClientUSubscriptionTest.cpp | 208 ++++++++++-------- 4 files changed, 118 insertions(+), 99 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 89528e261..051776efa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,7 +51,8 @@ file(GLOB_RECURSE SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") add_library(${PROJECT_NAME} ${SRC_FILES} src/client/usubscription/v3/RpcClientUSubscription.cpp include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h - include/up-cpp/client/usubscription/v3/USubscription.h) + include/up-cpp/client/usubscription/v3/USubscription.h +) add_library(up-cpp::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) target_include_directories(${PROJECT_NAME} diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index 56f4ce4e4..3e09cd42e 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -23,7 +23,7 @@ /// The uEntity (type) identifier of the uSubscription service. constexpr uint32_t USUBSCRIPTION_TYPE_ID = 0x00000000; /// The (latest) major version of the uSubscription service. -constexpr uint8_t USUBSCRIPTION_VERSION_MAJOR = 0x03; +constexpr uint8_t UE_VERSION_MAJOR = 0x03; /// The resource identifier of uSubscription's _subscribe_ operation. constexpr uint16_t RESOURCE_ID_SUBSCRIBE = 0x0001; /// The resource identifier of uSubscription's _unsubscribe_ operation. diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3f3adc32b..0cad1d346 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -83,10 +83,10 @@ add_coverage_test("NotificationSourceTest" coverage/communication/NotificationSo # client add_coverage_test("ConsumerTest" coverage/client/usubscription/v3/ConsumerTest.cpp) +add_coverage_test("RequestBuilderTest" coverage/client/usubscription/v3/RequestBuilderTest.cpp) +add_coverage_test("RpcClientUSubscriptionTest" coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp) # core -add_coverage_test("RpcClientUSubscriptionTest" coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp) -add_coverage_test("RequestBuilderTest" coverage/client/usubscription/v3/RequestBuilderTest.cpp) ########################## EXTRAS ############################################# add_extra_test("PublisherSubscriberTest" extra/PublisherSubscriberTest.cpp) diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp index d87ee1e5d..660329018 100644 --- a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -1,128 +1,146 @@ -// SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation -// -// See the NOTICE file(s) distributed with this work for additional -// information regarding copyright ownership. -// -// This program and the accompanying materials are made available under the -// terms of the Apache License Version 2.0 which is available at -// https://www.apache.org/licenses/LICENSE-2.0 -// -// SPDX-License-Identifier: Apache-2.0 - -#include #include -#include -#include #include "UTransportMock.h" +#include "up-cpp/client/usubscription/v3/RequestBuilder.h" +#include "up-cpp/client/usubscription/v3/RpcClientUSubscription.h" +#include "up-cpp/communication/RpcServer.h" +#include "up-cpp/utils/ProtoConverter.h" +#include "uprotocol/v1/uri.pb.h" + +using UMessage = uprotocol::v1::UMessage; +using Payload = uprotocol::datamodel::builder::Payload; +using ProtoConverter = uprotocol::utils::ProtoConverter; namespace { -using MsgDiff = google::protobuf::util::MessageDifferencer; -class RpcClientUSubscriptionTest : public testing::Test { -private: - std::shared_ptr mockTransportClient_; - std::shared_ptr mockTransportServer_; - uprotocol::v1::UUri client_uuri; - uprotocol::v1::UUri server_uuri; - uprotocol::v1::UUri subscription_uuri; +constexpr uint32_t UE_VERSION_MAJOR = 3; +constexpr uint32_t CLIENT_UE_ID = 23492; +class RpcClientUSubscriptionTest : public testing::Test { protected: - // Run once per TEST_F. + // Run once per TEST_F.s // Used to set up clean environments per test. - - std::shared_ptr getMockTransportClient() - const { - return mockTransportClient_; - } - std::shared_ptr getMockTransportServer() - const { - return mockTransportServer_; - } - uprotocol::v1::UUri& getClientUUri() { return client_uuri; } - const uprotocol::v1::UUri& getServerUUri() const { return server_uuri; } - const uprotocol::v1::UUri& getSubscriptionUUri() const { - return subscription_uuri; - } - void SetUp() override { - constexpr uint32_t TEST_UE_ID = 0x18000; - constexpr uint32_t DEFAULT_RESOURCE_ID = 0x8000; - // Create a generic transport uri - client_uuri.set_authority_name("random_string"); - client_uuri.set_ue_id(TEST_UE_ID); - client_uuri.set_ue_version_major(USUBSCRIPTION_VERSION_MAJOR); + uprotocol::v1::UUri client_uuri; + client_uuri.set_authority_name("client.usubscription"); + client_uuri.set_ue_id(CLIENT_UE_ID); + client_uuri.set_ue_version_major(UE_VERSION_MAJOR); client_uuri.set_resource_id(0); - // Set up a transport - mockTransportClient_ = - std::make_shared(client_uuri); + client_transport_ = std::make_shared(client_uuri); - // Craete server default uri and set up a transport + uprotocol::v1::UUri server_uuri; server_uuri.set_authority_name("core.usubscription"); - server_uuri.set_ue_id(0); - server_uuri.set_ue_version_major(USUBSCRIPTION_VERSION_MAJOR); + server_uuri.set_ue_id(1); + server_uuri.set_ue_version_major(UE_VERSION_MAJOR); server_uuri.set_resource_id(0); - mockTransportServer_ = - std::make_shared(server_uuri); + server_transport_ = std::make_shared(server_uuri); + + constexpr uint32_t SERVER_RESOURCE_ID = 32600; + server_method_uuri_.set_authority_name("core.usubscription"); + server_method_uuri_.set_ue_id(1); + server_method_uuri_.set_ue_version_major(UE_VERSION_MAJOR); + server_method_uuri_.set_resource_id(SERVER_RESOURCE_ID); + + constexpr uint32_t TOPIC_UE = 2342; + constexpr uint32_t TOPIC_RESOURCE_ID = 12340; + subscription_topic_.set_authority_name("topic.usubscription"); + subscription_topic_.set_ue_id(TOPIC_UE); + subscription_topic_.set_ue_version_major(UE_VERSION_MAJOR); + subscription_topic_.set_resource_id(TOPIC_RESOURCE_ID); + } - // Create a generic subscription uri - subscription_uuri.set_authority_name("10.0.0.2"); - subscription_uuri.set_ue_id(TEST_UE_ID); - subscription_uuri.set_ue_version_major(USUBSCRIPTION_VERSION_MAJOR); - subscription_uuri.set_resource_id(DEFAULT_RESOURCE_ID); - }; void TearDown() override {} // Run once per execution of the test application. // Used for setup of all tests. Has access to this instance. RpcClientUSubscriptionTest() = default; - void buildDefaultSourceURI(); - void buildValidNotificationURI(); - void buildInValidNotificationURI(); - // Run once per execution of the test application. // Used only for global setup outside of tests. static void SetUpTestSuite() {} static void TearDownTestSuite() {} + std::shared_ptr getClientTransport() { + return client_transport_; + } + + std::shared_ptr getServerTransport() { + return server_transport_; + } + + uprotocol::v1::UUri getServerMethodUuri() { + return server_method_uuri_; + } + + uprotocol::v1::UUri getSubscriptionTopic() { + return subscription_topic_; + } + + uprotocol::core::usubscription::v3::RequestBuilder getRequestBuilder() { + return request_builder_; + } + +private: + std::shared_ptr client_transport_; + std::shared_ptr server_transport_; + uprotocol::core::usubscription::v3::RequestBuilder request_builder_; + uprotocol::v1::UUri server_method_uuri_; + uprotocol::v1::UUri subscription_topic_; + public: ~RpcClientUSubscriptionTest() override = default; }; -// Negative test case with no source filter -TEST_F(RpcClientUSubscriptionTest, ConstructorTestSuccess) { // NOLINT - - auto rpc_client_usubscription = std::make_unique< - uprotocol::core::usubscription::v3::RpcClientUSubscription>( - getMockTransportClient()); - - // Verify that the RpcClientUSubscription pointer is not null, indicating - // successful - ASSERT_NE(rpc_client_usubscription, nullptr); +TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoPayload) { + bool server_callback_executed = false; + uprotocol::core::usubscription::v3::SubscriptionRequest server_capture; + uprotocol::core::usubscription::v3::SubscriptionResponse server_response; + *server_response.mutable_topic() = getSubscriptionTopic(); + auto server_or_status = uprotocol::communication::RpcServer::create(getServerTransport(),getServerMethodUuri(), + [&server_callback_executed,&server_capture,&server_response](const UMessage& message)->std::optional { + server_callback_executed = true; + auto request_or_status = ProtoConverter::extractFromProtobuf(message); + if (!request_or_status.has_value()) { + return std::nullopt; + } + server_capture = request_or_status.value(); + Payload response_payload(server_response); + return response_payload; + }, uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF); + + ASSERT_TRUE(server_or_status.has_value()); + ASSERT_NE(server_or_status.value(), nullptr); + EXPECT_TRUE(getServerTransport()->getListener()); + + auto client = uprotocol::core::usubscription::v3::RpcClientUSubscription(getClientTransport()); + + const auto subscription_request = getRequestBuilder().buildSubscriptionRequest(getSubscriptionTopic()); + + auto response_or_status_future = std::async(std::launch::async, [&client,&subscription_request]()-> + uprotocol::utils::Expected{ + return client.subscribe(subscription_request); + }); + + //wait to give the client time to send the request. There is currently a race condition + sleep(0.5); + (*getServerTransport()->getListener())(getClientTransport()->getMessage()); + EXPECT_TRUE(server_callback_executed); + EXPECT_EQ(server_capture.SerializeAsString(), subscription_request.SerializeAsString()); + + getClientTransport()->mockMessage(getServerTransport()->getMessage()); + EXPECT_TRUE(getClientTransport()->getListener()); + EXPECT_EQ(getClientTransport()->getSendCount(),1); + auto response_or_status = response_or_status_future.get(); + ASSERT_TRUE(response_or_status.has_value()); + EXPECT_EQ(response_or_status.value().SerializeAsString(),server_response.SerializeAsString()); } - -// TEST_F(RpcClientUSubscriptionTest, SubscribeTestSuccess) { // NOLINT -// -// uprotocol::core::usubscription::v3::SubscriptionRequest -// subscription_request = -// uprotocol::utils::ProtoConverter::BuildSubscriptionRequest( -// getSubscriptionUUri(), -// uprotocol::core::usubscription::v3::SubscribeAttributes()); -// -// auto rpc_client_usubscription = std::make_unique< -// uprotocol::core::usubscription::v3::RpcClientUSubscription>( -// getMockTransportClient()); -// -// // Verify that the RpcClientUSubscription pointer is not null, indicating -// // successful -// ASSERT_NE(rpc_client_usubscription, nullptr); -// -// auto result = rpc_client_usubscription->subscribe(subscription_request); -// -// ASSERT_NE(&result, nullptr); -// } - -} // namespace +TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoAnyPayload) { +} +TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithInvalidPayload) { +} +TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithInvalidResponse) { +} +}; \ No newline at end of file From 2916c0dedb379159011ff61fe17af78840f527a3 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 25 May 2025 22:29:05 +0200 Subject: [PATCH 086/105] small refactor and format --- .../client/usubscription/v3/RequestBuilder.h | 27 ++++-- .../usubscription/v3/RpcClientUSubscription.h | 21 ++-- .../client/usubscription/v3/USubscription.h | 17 ++-- include/up-cpp/communication/RpcClient.h | 25 +++-- include/up-cpp/utils/ProtoConverter.h | 23 +++-- .../usubscription/v3/RequestBuilder.cpp | 1 + .../v3/RpcClientUSubscription.cpp | 30 ++++-- .../usubscription/v3/RequestBuilderTest.cpp | 81 ++++++++-------- .../v3/RpcClientUSubscriptionTest.cpp | 97 +++++++++++-------- 9 files changed, 185 insertions(+), 137 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RequestBuilder.h b/include/up-cpp/client/usubscription/v3/RequestBuilder.h index b87579280..9b4adc871 100644 --- a/include/up-cpp/client/usubscription/v3/RequestBuilder.h +++ b/include/up-cpp/client/usubscription/v3/RequestBuilder.h @@ -78,18 +78,23 @@ struct RequestBuilder { * * @param topic The `v1::UUri` representing the topic to fetch. * - * @return An `FetchSubscriptionsRequest` configured for the specified topic. + * @return An `FetchSubscriptionsRequest` configured for the specified + * topic. */ - static FetchSubscriptionsRequest buildFetchSubscriptionsRequest(const v1::UUri& topic); + static FetchSubscriptionsRequest buildFetchSubscriptionsRequest( + const v1::UUri& topic); /** * @brief Build fetch subscritions request for a given subscriber. * - * @param subscriber The `SubscriberInfo` representing the subscriber to fetch. + * @param subscriber The `SubscriberInfo` representing the subscriber to + * fetch. * - * @return An `FetchSubscriptionsRequest` configured for the specified subscriber. + * @return An `FetchSubscriptionsRequest` configured for the specified + * subscriber. */ - static FetchSubscriptionsRequest buildFetchSubscriptionsRequest(const SubscriberInfo& subscriber); + static FetchSubscriptionsRequest buildFetchSubscriptionsRequest( + const SubscriberInfo& subscriber); /** * @brief Build fetch subscribers request for a given topic. @@ -98,18 +103,20 @@ struct RequestBuilder { * * @return An `FetchSubscribersRequest` configured for the specified topic. */ - static FetchSubscribersRequest buildFetchSubscribersRequest(const v1::UUri& topic); + static FetchSubscribersRequest buildFetchSubscribersRequest( + const v1::UUri& topic); /** - * @brief Build notification request for a given topic. Subscription change notifications - * MUST use topic SubscriptionChange with resource id 0x8000, as per the protobuf definition. + * @brief Build notification request for a given topic. Subscription change + *notifications MUST use topic SubscriptionChange with resource id 0x8000, + *as per the protobuf definition. * - * @param topic The `v1::UUri` representing the topic to (un)register for/from. + * @param topic The `v1::UUri` representing the topic to (un)register + *for/from. * * @return An `NotificationsRequest` configured for the specified topic. */ static NotificationsRequest buildNotificationRequest(const v1::UUri& topic); - private: USubscriptionOptions options_; ///< Options used to configure the requests. diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index 3e09cd42e..de7afd84b 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -30,9 +30,11 @@ constexpr uint16_t RESOURCE_ID_SUBSCRIBE = 0x0001; constexpr uint16_t RESOURCE_ID_UNSUBSCRIBE = 0x0002; /// The resource identifier of uSubscription's _fetch subscriptions_ operation. constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIPTIONS = 0x0003; -/// The resource identifier of uSubscription's _register for notifications_ operation. +/// The resource identifier of uSubscription's _register for notifications_ +/// operation. constexpr uint16_t RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS = 0x0006; -/// The resource identifier of uSubscription's _unregister for notifications_ operation. +/// The resource identifier of uSubscription's _unregister for notifications_ +/// operation. constexpr uint16_t RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS = 0x0007; /// The resource identifier of uSubscription's _fetch subscribers_ operation. constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIBERS = 0x0008; @@ -66,10 +68,11 @@ struct RpcClientUSubscription : USubscription { /// utils::Expected unsubscribe( const UnsubscribeRequest& unsubscribe_request) override; - + /// @brief Fetch all subscriptions either by topic or subscriber /// - utils::Expected fetch_subscriptions( + utils::Expected + fetch_subscriptions( const FetchSubscriptionsRequest& fetch_subscribers) override; /// @brief Fetch all subscribers @@ -79,13 +82,15 @@ struct RpcClientUSubscription : USubscription { /// @brief Register for notifications /// - utils::Expected register_for_notifications(const - NotificationsRequest& register_notifications_request) override ; + utils::Expected + register_for_notifications( + const NotificationsRequest& register_notifications_request) override; /// @brief Unregister for notifications /// - utils::Expected unregister_for_notifications(const - NotificationsRequest& unregister_notifications_request) override ; + utils::Expected + unregister_for_notifications( + const NotificationsRequest& unregister_notifications_request) override; /// @brief Constructor /// diff --git a/include/up-cpp/client/usubscription/v3/USubscription.h b/include/up-cpp/client/usubscription/v3/USubscription.h index e6673588c..e417de0a3 100644 --- a/include/up-cpp/client/usubscription/v3/USubscription.h +++ b/include/up-cpp/client/usubscription/v3/USubscription.h @@ -31,17 +31,18 @@ struct USubscription { virtual ResponseOrStatus unsubscribe( const UnsubscribeRequest& unsubscribe_request) = 0; - virtual ResponseOrStatus fetch_subscriptions(const - FetchSubscriptionsRequest& fetch_subscribers_request) = 0; + virtual ResponseOrStatus fetch_subscriptions( + const FetchSubscriptionsRequest& fetch_subscribers_request) = 0; - virtual ResponseOrStatus register_for_notifications(const - NotificationsRequest& register_notifications_request) =0 ; + virtual ResponseOrStatus register_for_notifications( + const NotificationsRequest& register_notifications_request) = 0; - virtual ResponseOrStatus unregister_for_notifications(const - NotificationsRequest& unregister_notifications_request) = 0; + virtual ResponseOrStatus + unregister_for_notifications( + const NotificationsRequest& unregister_notifications_request) = 0; - virtual ResponseOrStatus fetch_subscribers(const - FetchSubscribersRequest& fetch_subscribers_request) = 0; + virtual ResponseOrStatus fetch_subscribers( + const FetchSubscribersRequest& fetch_subscribers_request) = 0; }; } // namespace uprotocol::core::usubscription::v3 diff --git a/include/up-cpp/communication/RpcClient.h b/include/up-cpp/communication/RpcClient.h index 250bc50f8..46dbc140b 100644 --- a/include/up-cpp/communication/RpcClient.h +++ b/include/up-cpp/communication/RpcClient.h @@ -167,15 +167,15 @@ struct RpcClient { /// message (if not OK). /// * A UMessage containing the response from the RPC target. [[nodiscard]] InvokeFuture invokeMethod(); - - template - ResponseOrStatus invokeProtoMethod(const R& request_message){ + + template + ResponseOrStatus invokeProtoMethod(const R& request_message) { auto payload_or_status = - uprotocol::utils::ProtoConverter::protoToPayload(request_message); + uprotocol::utils::ProtoConverter::protoToPayload(request_message); if (!payload_or_status.has_value()) { return ResponseOrStatus( - UnexpectedStatus(payload_or_status.error())); + UnexpectedStatus(payload_or_status.error())); } datamodel::builder::Payload payload(payload_or_status.value()); @@ -183,26 +183,25 @@ struct RpcClient { if (!message_or_status.has_value()) { return ResponseOrStatus( - UnexpectedStatus(message_or_status.error())); + UnexpectedStatus(message_or_status.error())); } T response_message; - auto response_or_status = - utils::ProtoConverter::extractFromProtobuf( - message_or_status.value()); + auto response_or_status = utils::ProtoConverter::extractFromProtobuf( + message_or_status.value()); if (!response_or_status.has_value()) { spdlog::error( - "invokeProtoMethod: Error when extracting response from protobuf."); + "invokeProtoMethod: Error when extracting response from " + "protobuf."); return ResponseOrStatus( - UnexpectedStatus(response_or_status.error())); + UnexpectedStatus(response_or_status.error())); } response_message = response_or_status.value(); - return ResponseOrStatus( - std::move(response_message)); + return ResponseOrStatus(std::move(response_message)); } /// @brief Default move constructor (defined in RpcClient.cpp) diff --git a/include/up-cpp/utils/ProtoConverter.h b/include/up-cpp/utils/ProtoConverter.h index e9fae0afb..f444750b9 100644 --- a/include/up-cpp/utils/ProtoConverter.h +++ b/include/up-cpp/utils/ProtoConverter.h @@ -80,15 +80,15 @@ struct ProtoConverter { */ template static TOrStatus extractFromProtobuf(const v1::UMessage& message) { - switch (message.attributes().payload_format()) { - case v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF: { T response; if (!response.ParseFromString(message.payload())) { v1::UStatus status; status.set_code(v1::UCode::INTERNAL); - status.set_message("extractFromProtobuf: Error when parsing payload from protobuf."); + status.set_message( + "extractFromProtobuf: Error when parsing payload from " + "protobuf."); return TOrStatus(UnexpectedStatus(status)); } return TOrStatus(response); @@ -100,7 +100,8 @@ struct ProtoConverter { v1::UStatus status; status.set_code(v1::UCode::INTERNAL); status.set_message( - "extractFromProtobuf: Error when parsing payload from protobuf any."); + "extractFromProtobuf: Error when parsing payload from " + "protobuf any."); return TOrStatus(UnexpectedStatus(status)); } T response; @@ -108,7 +109,7 @@ struct ProtoConverter { v1::UStatus status; status.set_code(v1::UCode::INTERNAL); status.set_message( - "extractFromProtobuf: Error when unpacking any."); + "extractFromProtobuf: Error when unpacking any."); return TOrStatus(UnexpectedStatus(status)); } return TOrStatus(response); @@ -119,16 +120,18 @@ struct ProtoConverter { case v1::UPayloadFormat::UPAYLOAD_FORMAT_RAW: case v1::UPayloadFormat::UPAYLOAD_FORMAT_TEXT: case v1::UPayloadFormat::UPAYLOAD_FORMAT_SHM: - case v1::UPayloadFormat::UPayloadFormat_INT_MIN_SENTINEL_DO_NOT_USE_: - case v1::UPayloadFormat::UPayloadFormat_INT_MAX_SENTINEL_DO_NOT_USE_: + case v1::UPayloadFormat:: + UPayloadFormat_INT_MIN_SENTINEL_DO_NOT_USE_: + case v1::UPayloadFormat:: + UPayloadFormat_INT_MAX_SENTINEL_DO_NOT_USE_: default: { v1::UStatus status; status.set_code(v1::UCode::INVALID_ARGUMENT); - status.set_message("Unknown/invalid/unsupported payload format."); + status.set_message( + "Unknown/invalid/unsupported payload format."); return TOrStatus(UnexpectedStatus(status)); } - } - + } } /** diff --git a/src/client/usubscription/v3/RequestBuilder.cpp b/src/client/usubscription/v3/RequestBuilder.cpp index 39a51f669..556122910 100644 --- a/src/client/usubscription/v3/RequestBuilder.cpp +++ b/src/client/usubscription/v3/RequestBuilder.cpp @@ -10,6 +10,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "up-cpp/client/usubscription/v3/RequestBuilder.h" + #include namespace uprotocol::core::usubscription::v3 { diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index c8351faad..04a9d77bb 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -37,7 +37,8 @@ RpcClientUSubscription::subscribe( priority, USUBSCRIPTION_REQUEST_TTL); auto response_or_status = - rpc_client.invokeProtoMethod(subscription_request); + rpc_client.invokeProtoMethod( + subscription_request); if (!response_or_status.has_value()) { return utils::Expected( @@ -66,7 +67,8 @@ RpcClientUSubscription::unsubscribe( uuri_builder_.getServiceUriWithResourceId(RESOURCE_ID_UNSUBSCRIBE), priority, USUBSCRIPTION_REQUEST_TTL); - return rpc_client.invokeProtoMethod(unsubscribe_request); + return rpc_client.invokeProtoMethod( + unsubscribe_request); } RpcClientUSubscription::ResponseOrStatus @@ -74,10 +76,12 @@ RpcClientUSubscription::fetch_subscriptions( const FetchSubscriptionsRequest& fetch_subscribers_request) { communication::RpcClient rpc_client( transport_, - uuri_builder_.getServiceUriWithResourceId(RESOURCE_ID_FETCH_SUBSCRIPTIONS), + uuri_builder_.getServiceUriWithResourceId( + RESOURCE_ID_FETCH_SUBSCRIPTIONS), priority, USUBSCRIPTION_REQUEST_TTL); - return rpc_client.invokeProtoMethod(fetch_subscribers_request); + return rpc_client.invokeProtoMethod( + fetch_subscribers_request); } RpcClientUSubscription::ResponseOrStatus @@ -85,10 +89,12 @@ RpcClientUSubscription::fetch_subscribers( const FetchSubscribersRequest& fetch_subscribers_request) { communication::RpcClient rpc_client( transport_, - uuri_builder_.getServiceUriWithResourceId(RESOURCE_ID_FETCH_SUBSCRIBERS), + uuri_builder_.getServiceUriWithResourceId( + RESOURCE_ID_FETCH_SUBSCRIBERS), priority, USUBSCRIPTION_REQUEST_TTL); - return rpc_client.invokeProtoMethod(fetch_subscribers_request); + return rpc_client.invokeProtoMethod( + fetch_subscribers_request); } RpcClientUSubscription::ResponseOrStatus @@ -96,10 +102,12 @@ RpcClientUSubscription::register_for_notifications( const NotificationsRequest& register_notifications_request) { communication::RpcClient rpc_client( transport_, - uuri_builder_.getServiceUriWithResourceId(RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS), + uuri_builder_.getServiceUriWithResourceId( + RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS), priority, USUBSCRIPTION_REQUEST_TTL); - return rpc_client.invokeProtoMethod(register_notifications_request); + return rpc_client.invokeProtoMethod( + register_notifications_request); } RpcClientUSubscription::ResponseOrStatus @@ -107,10 +115,12 @@ RpcClientUSubscription::unregister_for_notifications( const NotificationsRequest& unregister_notifications_request) { communication::RpcClient rpc_client( transport_, - uuri_builder_.getServiceUriWithResourceId(RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS), + uuri_builder_.getServiceUriWithResourceId( + RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS), priority, USUBSCRIPTION_REQUEST_TTL); - return rpc_client.invokeProtoMethod(unregister_notifications_request); + return rpc_client.invokeProtoMethod( + unregister_notifications_request); } } // namespace uprotocol::core::usubscription::v3 diff --git a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp index 656a1cd54..4aad8d30a 100644 --- a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp +++ b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp @@ -9,14 +9,16 @@ // // SPDX-License-Identifier: Apache-2.0 +#include #include -#include "up-cpp/client/usubscription/v3/RequestBuilder.h" #include + +#include #include #include -#include #include -#include + +#include "up-cpp/client/usubscription/v3/RequestBuilder.h" constexpr uint32_t SOURCE_UE_ID = 0x00011101; constexpr uint32_t SOURCE_UE_VERSION_MAJOR = 0xF8; @@ -25,35 +27,35 @@ constexpr uint32_t SOURCE_RESOURCE_ID = 0x8101; namespace uprotocol::core::usubscription::v3 { class RequestBuilderTest : public ::testing::Test { - private: v1::UUri source_; protected: - USubscriptionOptions options_; - const v1::UUri& getSource() const { return source_; } + USubscriptionOptions options_; + const v1::UUri& getSource() const { return source_; } - void SetUp() override { - // Create a UUri object for testing + void SetUp() override { + // Create a UUri object for testing source_.set_authority_name("10.0.0.1"); source_.set_ue_id(SOURCE_UE_ID); source_.set_ue_version_major(SOURCE_UE_VERSION_MAJOR); source_.set_resource_id(SOURCE_RESOURCE_ID); - options_.permission_level = 2; - options_.token = "sample_token"; - options_.when_expire = std::chrono::system_clock::now() + std::chrono::milliseconds(1000); - options_.sample_period_ms = std::chrono::milliseconds(1000); - options_.subscriber_details = google::protobuf::Any(); - options_.subscription_details = google::protobuf::Any(); - } - void TearDown() override {} - - // Run once per execution of the test application. + options_.permission_level = 2; + options_.token = "sample_token"; + options_.when_expire = + std::chrono::system_clock::now() + std::chrono::milliseconds(1000); + options_.sample_period_ms = std::chrono::milliseconds(1000); + options_.subscriber_details = google::protobuf::Any(); + options_.subscription_details = google::protobuf::Any(); + } + void TearDown() override {} + + // Run once per execution of the test application. // Used for setup of all tests. Has access to this instance. RequestBuilderTest() = default; - // Run once per execution of the test application. + // Run once per execution of the test application. // Used only for global setup outside of tests. static void SetUpTestSuite() {} static void TearDownTestSuite() {} @@ -63,34 +65,35 @@ class RequestBuilderTest : public ::testing::Test { }; TEST_F(RequestBuilderTest, BuildSubscriptionRequestWithOptions) { - v1::UUri topic = getSource(); - RequestBuilder builder(options_); - - SubscriptionRequest request = builder.buildSubscriptionRequest(topic); + v1::UUri topic = getSource(); + RequestBuilder builder(options_); - // Verify the attributes in the request - EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); - std::cout<< "request.SerializeAsString(): " << request.SerializeAsString() << std::endl; - std::cout<< "request.attributes: " << request.attributes().SerializeAsString() << std::endl; + SubscriptionRequest request = builder.buildSubscriptionRequest(topic); + // Verify the attributes in the request + EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); + std::cout << "request.SerializeAsString(): " << request.SerializeAsString() + << std::endl; + std::cout << "request.attributes: " + << request.attributes().SerializeAsString() << std::endl; } TEST_F(RequestBuilderTest, BuildSubscriptionRequestWrongTopic) { - v1::UUri topic = getSource(); - RequestBuilder builder(options_); - - v1::UUri wrong_topic; + v1::UUri topic = getSource(); + RequestBuilder builder(options_); - wrong_topic.set_authority_name("10.0.0.2"); // random different authority - wrong_topic.set_ue_id(SOURCE_UE_ID); - wrong_topic.set_ue_version_major(SOURCE_UE_VERSION_MAJOR); - wrong_topic.set_resource_id(SOURCE_RESOURCE_ID); + v1::UUri wrong_topic; - SubscriptionRequest request = builder.buildSubscriptionRequest(topic); + wrong_topic.set_authority_name("10.0.0.2"); // random different authority + wrong_topic.set_ue_id(SOURCE_UE_ID); + wrong_topic.set_ue_version_major(SOURCE_UE_VERSION_MAJOR); + wrong_topic.set_resource_id(SOURCE_RESOURCE_ID); - // Verify the attributes in the request - EXPECT_NE(request.topic().SerializeAsString(), wrong_topic.SerializeAsString()); + SubscriptionRequest request = builder.buildSubscriptionRequest(topic); + // Verify the attributes in the request + EXPECT_NE(request.topic().SerializeAsString(), + wrong_topic.SerializeAsString()); } -} // namespace uprotocol::core::usubscription::v3 \ No newline at end of file +} // namespace uprotocol::core::usubscription::v3 \ No newline at end of file diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp index 660329018..47ee17313 100644 --- a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -27,7 +27,8 @@ class RpcClientUSubscriptionTest : public testing::Test { client_uuri.set_ue_version_major(UE_VERSION_MAJOR); client_uuri.set_resource_id(0); - client_transport_ = std::make_shared(client_uuri); + client_transport_ = + std::make_shared(client_uuri); uprotocol::v1::UUri server_uuri; server_uuri.set_authority_name("core.usubscription"); @@ -35,9 +36,10 @@ class RpcClientUSubscriptionTest : public testing::Test { server_uuri.set_ue_version_major(UE_VERSION_MAJOR); server_uuri.set_resource_id(0); - server_transport_ = std::make_shared(server_uuri); + server_transport_ = + std::make_shared(server_uuri); - constexpr uint32_t SERVER_RESOURCE_ID = 32600; + constexpr uint32_t SERVER_RESOURCE_ID = 32600; server_method_uuri_.set_authority_name("core.usubscription"); server_method_uuri_.set_ue_id(1); server_method_uuri_.set_ue_version_major(UE_VERSION_MAJOR); @@ -70,13 +72,9 @@ class RpcClientUSubscriptionTest : public testing::Test { return server_transport_; } - uprotocol::v1::UUri getServerMethodUuri() { - return server_method_uuri_; - } + uprotocol::v1::UUri getServerMethodUuri() { return server_method_uuri_; } - uprotocol::v1::UUri getSubscriptionTopic() { - return subscription_topic_; - } + uprotocol::v1::UUri getSubscriptionTopic() { return subscription_topic_; } uprotocol::core::usubscription::v3::RequestBuilder getRequestBuilder() { return request_builder_; @@ -98,49 +96,70 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoPayload) { uprotocol::core::usubscription::v3::SubscriptionRequest server_capture; uprotocol::core::usubscription::v3::SubscriptionResponse server_response; *server_response.mutable_topic() = getSubscriptionTopic(); - auto server_or_status = uprotocol::communication::RpcServer::create(getServerTransport(),getServerMethodUuri(), - [&server_callback_executed,&server_capture,&server_response](const UMessage& message)->std::optional { - server_callback_executed = true; - auto request_or_status = ProtoConverter::extractFromProtobuf(message); - if (!request_or_status.has_value()) { - return std::nullopt; - } - server_capture = request_or_status.value(); - Payload response_payload(server_response); - return response_payload; - }, uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF); + auto server_or_status = uprotocol::communication::RpcServer::create( + getServerTransport(), getServerMethodUuri(), + [&server_callback_executed, &server_capture, + &server_response](const UMessage& message) -> std::optional { + server_callback_executed = true; + auto request_or_status = ProtoConverter::extractFromProtobuf< + uprotocol::core::usubscription::v3::SubscriptionRequest>( + message); + if (!request_or_status.has_value()) { + return std::nullopt; + } + server_capture = request_or_status.value(); + Payload response_payload(server_response); + return response_payload; + }, + uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF); ASSERT_TRUE(server_or_status.has_value()); ASSERT_NE(server_or_status.value(), nullptr); EXPECT_TRUE(getServerTransport()->getListener()); - auto client = uprotocol::core::usubscription::v3::RpcClientUSubscription(getClientTransport()); - - const auto subscription_request = getRequestBuilder().buildSubscriptionRequest(getSubscriptionTopic()); - - auto response_or_status_future = std::async(std::launch::async, [&client,&subscription_request]()-> - uprotocol::utils::Expected{ - return client.subscribe(subscription_request); - }); + auto client = uprotocol::core::usubscription::v3::RpcClientUSubscription( + getClientTransport()); + + const auto subscription_request = + getRequestBuilder().buildSubscriptionRequest(getSubscriptionTopic()); + + auto response_or_status_future = std::async( + std::launch::async, + [&client, &subscription_request]() + -> uprotocol::utils::Expected< + uprotocol::core::usubscription::v3::SubscriptionResponse, + uprotocol::v1::UStatus> { + return client.subscribe(subscription_request); + }); + + // wait to give the client time to send the request. Otherwise this would + // cause a race condition + constexpr int ITERATIONS_TILL_TIMEOUT = 10; + constexpr std::chrono::milliseconds MILLISECONDS_PER_ITERATION = + std::chrono::milliseconds(100); + int counter = ITERATIONS_TILL_TIMEOUT; + while (counter > 0 && getClientTransport()->getSendCount() == 0) { + counter--; + std::this_thread::sleep_for(MILLISECONDS_PER_ITERATION); + } + ASSERT_EQ(getClientTransport()->getSendCount(), 1); + EXPECT_TRUE(getClientTransport()->getListener()); - //wait to give the client time to send the request. There is currently a race condition - sleep(0.5); (*getServerTransport()->getListener())(getClientTransport()->getMessage()); EXPECT_TRUE(server_callback_executed); - EXPECT_EQ(server_capture.SerializeAsString(), subscription_request.SerializeAsString()); + EXPECT_EQ(server_capture.SerializeAsString(), + subscription_request.SerializeAsString()); getClientTransport()->mockMessage(getServerTransport()->getMessage()); EXPECT_TRUE(getClientTransport()->getListener()); - EXPECT_EQ(getClientTransport()->getSendCount(),1); + EXPECT_EQ(getClientTransport()->getSendCount(), 1); auto response_or_status = response_or_status_future.get(); ASSERT_TRUE(response_or_status.has_value()); - EXPECT_EQ(response_or_status.value().SerializeAsString(),server_response.SerializeAsString()); + EXPECT_EQ(response_or_status.value().SerializeAsString(), + server_response.SerializeAsString()); } TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoAnyPayload) { } -TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithInvalidPayload) { -} -TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithInvalidResponse) { -} -}; \ No newline at end of file +TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithInvalidPayload) {} +TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithInvalidResponse) {} +}; // namespace \ No newline at end of file From 7ccc381122d4ec688a595dab7ad37598d7bb51ef Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Mon, 26 May 2025 14:20:33 +0200 Subject: [PATCH 087/105] Some renaming in Signature and adding Test in RpcClientUSubscription --- .../usubscription/v3/RpcClientUSubscription.h | 4 +- .../client/usubscription/v3/USubscription.h | 2 +- .../v3/RpcClientUSubscription.cpp | 7 +- .../v3/RpcClientUSubscriptionTest.cpp | 141 +++++++++++++++++- 4 files changed, 145 insertions(+), 9 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index de7afd84b..aa7b4c003 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -73,12 +73,12 @@ struct RpcClientUSubscription : USubscription { /// utils::Expected fetch_subscriptions( - const FetchSubscriptionsRequest& fetch_subscribers) override; + const FetchSubscriptionsRequest& fetch_subscriptions_request) override; /// @brief Fetch all subscribers /// utils::Expected fetch_subscribers( - const FetchSubscribersRequest& fetch_subscribers) override; + const FetchSubscribersRequest& fetch_subscribers_request) override; /// @brief Register for notifications /// diff --git a/include/up-cpp/client/usubscription/v3/USubscription.h b/include/up-cpp/client/usubscription/v3/USubscription.h index e417de0a3..7ad69e8d4 100644 --- a/include/up-cpp/client/usubscription/v3/USubscription.h +++ b/include/up-cpp/client/usubscription/v3/USubscription.h @@ -32,7 +32,7 @@ struct USubscription { const UnsubscribeRequest& unsubscribe_request) = 0; virtual ResponseOrStatus fetch_subscriptions( - const FetchSubscriptionsRequest& fetch_subscribers_request) = 0; + const FetchSubscriptionsRequest& fetch_subscriptions_request) = 0; virtual ResponseOrStatus register_for_notifications( const NotificationsRequest& register_notifications_request) = 0; diff --git a/src/client/usubscription/v3/RpcClientUSubscription.cpp b/src/client/usubscription/v3/RpcClientUSubscription.cpp index 04a9d77bb..5f459de31 100644 --- a/src/client/usubscription/v3/RpcClientUSubscription.cpp +++ b/src/client/usubscription/v3/RpcClientUSubscription.cpp @@ -41,8 +41,7 @@ RpcClientUSubscription::subscribe( subscription_request); if (!response_or_status.has_value()) { - return utils::Expected( - utils::Unexpected(response_or_status.error())); + return response_or_status; } auto subscription_response = response_or_status.value(); @@ -73,7 +72,7 @@ RpcClientUSubscription::unsubscribe( RpcClientUSubscription::ResponseOrStatus RpcClientUSubscription::fetch_subscriptions( - const FetchSubscriptionsRequest& fetch_subscribers_request) { + const FetchSubscriptionsRequest& fetch_subscriptions_request) { communication::RpcClient rpc_client( transport_, uuri_builder_.getServiceUriWithResourceId( @@ -81,7 +80,7 @@ RpcClientUSubscription::fetch_subscriptions( priority, USUBSCRIPTION_REQUEST_TTL); return rpc_client.invokeProtoMethod( - fetch_subscribers_request); + fetch_subscriptions_request); } RpcClientUSubscription::ResponseOrStatus diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp index 47ee17313..47607fc55 100644 --- a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -158,8 +158,145 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoPayload) { EXPECT_EQ(response_or_status.value().SerializeAsString(), server_response.SerializeAsString()); } + TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoAnyPayload) { + bool server_callback_executed = false; + uprotocol::core::usubscription::v3::SubscriptionRequest server_capture; + uprotocol::core::usubscription::v3::SubscriptionResponse server_response; + *server_response.mutable_topic() = getSubscriptionTopic(); + auto server_or_status = uprotocol::communication::RpcServer::create( + getServerTransport(), getServerMethodUuri(), + [&server_callback_executed, &server_capture, + &server_response](const UMessage& message) -> std::optional { + server_callback_executed = true; + auto request_or_status = ProtoConverter::extractFromProtobuf< + uprotocol::core::usubscription::v3::SubscriptionRequest>( + message); + if (!request_or_status.has_value()) { + return std::nullopt; + } + server_capture = request_or_status.value(); + google::protobuf::Any any; + if(!any.PackFrom(server_response)) { + return std::nullopt; + } + Payload response_payload(any); + return response_payload; + }, + uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY); + + ASSERT_TRUE(server_or_status.has_value()); + ASSERT_NE(server_or_status.value(), nullptr); + EXPECT_TRUE(getServerTransport()->getListener()); + + auto client = uprotocol::core::usubscription::v3::RpcClientUSubscription( + getClientTransport()); + + const auto subscription_request = + getRequestBuilder().buildSubscriptionRequest(getSubscriptionTopic()); + + auto response_or_status_future = std::async( + std::launch::async, + [&client, &subscription_request]() + -> uprotocol::utils::Expected< + uprotocol::core::usubscription::v3::SubscriptionResponse, + uprotocol::v1::UStatus> { + return client.subscribe(subscription_request); + }); + + // wait to give the client time to send the request. Otherwise this would + // cause a race condition + constexpr int ITERATIONS_TILL_TIMEOUT = 10; + constexpr std::chrono::milliseconds MILLISECONDS_PER_ITERATION = + std::chrono::milliseconds(100); + int counter = ITERATIONS_TILL_TIMEOUT; + while (counter > 0 && getClientTransport()->getSendCount() == 0) { + counter--; + std::this_thread::sleep_for(MILLISECONDS_PER_ITERATION); + } + ASSERT_EQ(getClientTransport()->getSendCount(), 1); + EXPECT_TRUE(getClientTransport()->getListener()); + + (*getServerTransport()->getListener())(getClientTransport()->getMessage()); + EXPECT_TRUE(server_callback_executed); + EXPECT_EQ(server_capture.SerializeAsString(), + subscription_request.SerializeAsString()); + + getClientTransport()->mockMessage(getServerTransport()->getMessage()); + EXPECT_TRUE(getClientTransport()->getListener()); + EXPECT_EQ(getClientTransport()->getSendCount(), 1); + auto response_or_status = response_or_status_future.get(); + ASSERT_TRUE(response_or_status.has_value()); + EXPECT_EQ(response_or_status.value().SerializeAsString(), + server_response.SerializeAsString()); +} + +TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithInvalidPayload) { + bool server_callback_executed = false; + uprotocol::core::usubscription::v3::SubscriptionRequest server_capture; + uprotocol::core::usubscription::v3::SubscriptionResponse server_response; + *server_response.mutable_topic() = getSubscriptionTopic(); + auto server_or_status = uprotocol::communication::RpcServer::create( + getServerTransport(), getServerMethodUuri(), + [&server_callback_executed, &server_capture, + &server_response](const UMessage& message) -> std::optional { + server_callback_executed = true; + auto request_or_status = ProtoConverter::extractFromProtobuf< + uprotocol::core::usubscription::v3::SubscriptionRequest>( + message); + if (!request_or_status.has_value()) { + return std::nullopt; + } + server_capture = request_or_status.value(); + Payload response_payload(server_response); + return response_payload; + }, + uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF); + + ASSERT_TRUE(server_or_status.has_value()); + ASSERT_NE(server_or_status.value(), nullptr); + EXPECT_TRUE(getServerTransport()->getListener()); + + auto client = uprotocol::core::usubscription::v3::RpcClientUSubscription( + getClientTransport()); + + const auto subscription_request = + getRequestBuilder().buildSubscriptionRequest(getSubscriptionTopic()); + + auto response_or_status_future = std::async( + std::launch::async, + [&client, &subscription_request]() + -> uprotocol::utils::Expected< + uprotocol::core::usubscription::v3::SubscriptionResponse, + uprotocol::v1::UStatus> { + return client.subscribe(subscription_request); + }); + + // wait to give the client time to send the request. Otherwise this would + // cause a race condition + constexpr int ITERATIONS_TILL_TIMEOUT = 10; + constexpr std::chrono::milliseconds MILLISECONDS_PER_ITERATION = + std::chrono::milliseconds(100); + int counter = ITERATIONS_TILL_TIMEOUT; + while (counter > 0 && getClientTransport()->getSendCount() == 0) { + counter--; + std::this_thread::sleep_for(MILLISECONDS_PER_ITERATION); + } + ASSERT_EQ(getClientTransport()->getSendCount(), 1); + EXPECT_TRUE(getClientTransport()->getListener()); + + (*getServerTransport()->getListener())(getClientTransport()->getMessage()); + EXPECT_TRUE(server_callback_executed); + EXPECT_EQ(server_capture.SerializeAsString(), + subscription_request.SerializeAsString()); + + getClientTransport()->mockMessage(getServerTransport()->getMessage()); + EXPECT_TRUE(getClientTransport()->getListener()); + EXPECT_EQ(getClientTransport()->getSendCount(), 1); + auto response_or_status = response_or_status_future.get(); + ASSERT_TRUE(response_or_status.has_value()); + EXPECT_EQ(response_or_status.value().SerializeAsString(), + server_response.SerializeAsString()); } -TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithInvalidPayload) {} TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithInvalidResponse) {} -}; // namespace \ No newline at end of file +}; // namespace From f1d2a883b1d73c7ad6e1c0d8fa2dcf6a22de2e59 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Mon, 26 May 2025 14:40:42 +0200 Subject: [PATCH 088/105] Added missing RequestBuilder in ProtoConverter first to have it analog to subscribe and unsubscribe --- .../client/usubscription/v3/RequestBuilder.h | 6 ++-- include/up-cpp/utils/ProtoConverter.h | 29 +++++++++++++++++-- .../usubscription/v3/RequestBuilder.cpp | 27 ++++------------- src/utils/ProtoConverter.cpp | 28 ++++++++++++++++++ 4 files changed, 63 insertions(+), 27 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RequestBuilder.h b/include/up-cpp/client/usubscription/v3/RequestBuilder.h index 9b4adc871..c51c82652 100644 --- a/include/up-cpp/client/usubscription/v3/RequestBuilder.h +++ b/include/up-cpp/client/usubscription/v3/RequestBuilder.h @@ -107,8 +107,8 @@ struct RequestBuilder { const v1::UUri& topic); /** - * @brief Build notification request for a given topic. Subscription change - *notifications MUST use topic SubscriptionChange with resource id 0x8000, + * @brief Build notifications request for a given topic. Subscription change + *notifications MUST use topic SubscriptionsChange with resource id 0x8000, *as per the protobuf definition. * * @param topic The `v1::UUri` representing the topic to (un)register @@ -116,7 +116,7 @@ struct RequestBuilder { * * @return An `NotificationsRequest` configured for the specified topic. */ - static NotificationsRequest buildNotificationRequest(const v1::UUri& topic); + static NotificationsRequest buildNotificationsRequest(const v1::UUri& topic); private: USubscriptionOptions options_; ///< Options used to configure the requests. diff --git a/include/up-cpp/utils/ProtoConverter.h b/include/up-cpp/utils/ProtoConverter.h index f444750b9..eb6141d37 100644 --- a/include/up-cpp/utils/ProtoConverter.h +++ b/include/up-cpp/utils/ProtoConverter.h @@ -22,6 +22,9 @@ using uprotocol::core::usubscription::v3::SubscribeAttributes; using uprotocol::core::usubscription::v3::SubscriberInfo; using uprotocol::core::usubscription::v3::SubscriptionRequest; using uprotocol::core::usubscription::v3::UnsubscribeRequest; +using core::usubscription::v3::FetchSubscriptionsRequest; +using core::usubscription::v3::FetchSubscribersRequest; +using core::usubscription::v3::NotificationsRequest; struct ProtoConverter { /// @brief Converts std::chrono::time_point to google::protobuf::Timestamp @@ -63,8 +66,30 @@ struct ProtoConverter { /// @return the built UnsubscribeRequest static UnsubscribeRequest BuildUnSubscribeRequest( const v1::UUri& subscription_topic); - static UnsubscribeRequest BuildUnSubscribeRequest( - const v1::UUri& uri, const SubscribeAttributes& attributes); + + /// @brief Builds a FetchSubscriptionsRequest from the given topic + /// + /// @param topic the UUri of the topic to fetch subscriptions for + /// @return the built FetchSubscriptionsRequest + static FetchSubscriptionsRequest BuildFetchSubscriptionsRequest(const v1::UUri& topic); + + /// @brief Builds a FetchSubscriptionsRequest from the given subscriber information + /// + /// @param subscriber the SubscriberInfo containing details of the subscriber + /// @return the built FetchSubscriptionsRequest + static FetchSubscriptionsRequest BuildFetchSubscriptionsRequest(const SubscriberInfo& subscriber); + + /// @brief Builds a FetchSubscribersRequest from the given topic + /// + /// @param topic the UUri of the topic to fetch subscribers for + /// @return the built FetchSubscribersRequest + static FetchSubscribersRequest BuildFetchSubscribersRequest(const v1::UUri& topic); + + /// @brief Builds a NotificationsRequest from the given topic + /// + /// @param topic the UUri of the topic to build a notification request for + /// @return the built NotificationsRequest + static NotificationsRequest BuildNotificationsRequest(const v1::UUri& topic); /** * @brief Deserializes a protobuf message from a given payload. diff --git a/src/client/usubscription/v3/RequestBuilder.cpp b/src/client/usubscription/v3/RequestBuilder.cpp index 556122910..cbdfb4af7 100644 --- a/src/client/usubscription/v3/RequestBuilder.cpp +++ b/src/client/usubscription/v3/RequestBuilder.cpp @@ -26,44 +26,27 @@ SubscriptionRequest RequestBuilder::buildSubscriptionRequest( UnsubscribeRequest RequestBuilder::buildUnsubscribeRequest( const v1::UUri& topic) { - // auto attributes = utils::ProtoConverter::BuildSubscribeAttributes( - // options_.when_expire, - // options_.subscription_details, - // options_.sample_period_ms); - return utils::ProtoConverter::BuildUnSubscribeRequest(topic); } FetchSubscriptionsRequest RequestBuilder::buildFetchSubscriptionsRequest( const v1::UUri& topic) { - FetchSubscriptionsRequest fetch_subscriptions_request; - *fetch_subscriptions_request.mutable_topic() = topic; - - return fetch_subscriptions_request; + return utils::ProtoConverter::BuildFetchSubscriptionsRequest(topic); } FetchSubscriptionsRequest RequestBuilder::buildFetchSubscriptionsRequest( const SubscriberInfo& subscriber) { - FetchSubscriptionsRequest fetch_subscriptions_request; - *fetch_subscriptions_request.mutable_subscriber() = subscriber; - - return fetch_subscriptions_request; + return utils::ProtoConverter::BuildFetchSubscriptionsRequest(subscriber); } FetchSubscribersRequest RequestBuilder::buildFetchSubscribersRequest( const v1::UUri& topic) { - FetchSubscribersRequest fetch_subscribers_request; - *fetch_subscribers_request.mutable_topic() = topic; - - return fetch_subscribers_request; + return utils::ProtoConverter::BuildFetchSubscribersRequest(topic); } -NotificationsRequest RequestBuilder::buildNotificationRequest( +NotificationsRequest RequestBuilder::buildNotificationsRequest( const v1::UUri& topic) { - NotificationsRequest notification_request; - *notification_request.mutable_topic() = topic; - - return notification_request; + return utils::ProtoConverter::BuildNotificationsRequest(topic); } } // namespace uprotocol::core::usubscription::v3 diff --git a/src/utils/ProtoConverter.cpp b/src/utils/ProtoConverter.cpp index a50a74a41..2f0cc378f 100644 --- a/src/utils/ProtoConverter.cpp +++ b/src/utils/ProtoConverter.cpp @@ -84,4 +84,32 @@ UnsubscribeRequest ProtoConverter::BuildUnSubscribeRequest( return unsubscribe_request; } +FetchSubscriptionsRequest ProtoConverter::BuildFetchSubscriptionsRequest(const v1::UUri& topic) { + FetchSubscriptionsRequest fetch_subscriptions_request; + *fetch_subscriptions_request.mutable_topic() = topic; + + return fetch_subscriptions_request; +} + +FetchSubscriptionsRequest ProtoConverter::BuildFetchSubscriptionsRequest(const SubscriberInfo& subscriber) { + FetchSubscriptionsRequest fetch_subscriptions_request; + *fetch_subscriptions_request.mutable_subscriber() = subscriber; + + return fetch_subscriptions_request; +} + +FetchSubscribersRequest ProtoConverter::BuildFetchSubscribersRequest(const v1::UUri& topic) { + FetchSubscribersRequest fetch_subscribers_request; + *fetch_subscribers_request.mutable_topic() = topic; + + return fetch_subscribers_request; +} + +NotificationsRequest ProtoConverter::BuildNotificationsRequest(const v1::UUri& topic) { + NotificationsRequest notifications_request; + *notifications_request.mutable_topic() = topic; + + return notifications_request; +} + } // namespace uprotocol::utils From 05df8de2de2739f564d45c34109e35aa3507865d Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Tue, 27 May 2025 12:52:36 +0200 Subject: [PATCH 089/105] Add Tests --- include/up-cpp/communication/RpcClient.h | 7 +- test/CMakeLists.txt | 1 + .../usubscription/v3/RequestBuilderTest.cpp | 85 +++++++++++--- .../v3/RpcClientUSubscriptionTest.cpp | 110 +++++++++++++++--- 4 files changed, 164 insertions(+), 39 deletions(-) diff --git a/include/up-cpp/communication/RpcClient.h b/include/up-cpp/communication/RpcClient.h index 46dbc140b..0239cdb7a 100644 --- a/include/up-cpp/communication/RpcClient.h +++ b/include/up-cpp/communication/RpcClient.h @@ -185,9 +185,7 @@ struct RpcClient { return ResponseOrStatus( UnexpectedStatus(message_or_status.error())); } - - T response_message; - + std::cout << "message_or_status.value().GetTypeName(): "<< message_or_status.value().GetTypeName() << std::endl; auto response_or_status = utils::ProtoConverter::extractFromProtobuf( message_or_status.value()); @@ -198,8 +196,7 @@ struct RpcClient { return ResponseOrStatus( UnexpectedStatus(response_or_status.error())); } - - response_message = response_or_status.value(); + T response_message = response_or_status.value(); return ResponseOrStatus(std::move(response_message)); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0cad1d346..e9059a45a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -85,6 +85,7 @@ add_coverage_test("NotificationSourceTest" coverage/communication/NotificationSo add_coverage_test("ConsumerTest" coverage/client/usubscription/v3/ConsumerTest.cpp) add_coverage_test("RequestBuilderTest" coverage/client/usubscription/v3/RequestBuilderTest.cpp) add_coverage_test("RpcClientUSubscriptionTest" coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp) +add_coverage_test("USubscriptionUUriBuilderTest" coverage/client/usubscription/v3/USubscriptionUUriBuilderTest.cpp) # core diff --git a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp index 4aad8d30a..2de6e0a82 100644 --- a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp +++ b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp @@ -29,10 +29,12 @@ namespace uprotocol::core::usubscription::v3 { class RequestBuilderTest : public ::testing::Test { private: v1::UUri source_; + v1::UUri wrong_topic_; protected: USubscriptionOptions options_; const v1::UUri& getSource() const { return source_; } + const v1::UUri& getWrongTopic() const { return wrong_topic_; } void SetUp() override { // Create a UUri object for testing @@ -41,6 +43,11 @@ class RequestBuilderTest : public ::testing::Test { source_.set_ue_version_major(SOURCE_UE_VERSION_MAJOR); source_.set_resource_id(SOURCE_RESOURCE_ID); + wrong_topic_.set_authority_name("10.0.0.2"); // random different authority + wrong_topic_.set_ue_id(SOURCE_UE_ID); + wrong_topic_.set_ue_version_major(SOURCE_UE_VERSION_MAJOR); + wrong_topic_.set_resource_id(SOURCE_RESOURCE_ID); + options_.permission_level = 2; options_.token = "sample_token"; options_.when_expire = @@ -71,29 +78,75 @@ TEST_F(RequestBuilderTest, BuildSubscriptionRequestWithOptions) { SubscriptionRequest request = builder.buildSubscriptionRequest(topic); // Verify the attributes in the request + EXPECT_TRUE(request.has_topic()); + EXPECT_TRUE(request.has_attributes()); EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); - std::cout << "request.SerializeAsString(): " << request.SerializeAsString() - << std::endl; - std::cout << "request.attributes: " - << request.attributes().SerializeAsString() << std::endl; + EXPECT_NE(request.topic().SerializeAsString(), + getWrongTopic().SerializeAsString()); + EXPECT_EQ(request.GetTypeName(), "uprotocol.core.usubscription.v3.SubscriptionRequest"); } -TEST_F(RequestBuilderTest, BuildSubscriptionRequestWrongTopic) { - v1::UUri topic = getSource(); +TEST_F(RequestBuilderTest, BuildUnsubscribeRequest) { + v1::UUri topic = getSource(); + RequestBuilder builder(options_); + + UnsubscribeRequest request = builder.buildUnsubscribeRequest(topic); + + // Verify the attributes in the request + EXPECT_TRUE(request.has_topic()); + EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); + EXPECT_NE(request.topic().SerializeAsString(), getWrongTopic().SerializeAsString()); + EXPECT_EQ(request.GetTypeName(), "uprotocol.core.usubscription.v3.UnsubscribeRequest"); +} + +TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithTopic) { + v1::UUri topic = getSource(); RequestBuilder builder(options_); - v1::UUri wrong_topic; + FetchSubscriptionsRequest request = builder.buildFetchSubscriptionsRequest(topic); - wrong_topic.set_authority_name("10.0.0.2"); // random different authority - wrong_topic.set_ue_id(SOURCE_UE_ID); - wrong_topic.set_ue_version_major(SOURCE_UE_VERSION_MAJOR); - wrong_topic.set_resource_id(SOURCE_RESOURCE_ID); + // Verify the attributes in the request + EXPECT_TRUE(request.has_topic()); + EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); + EXPECT_NE(request.topic().SerializeAsString(), getWrongTopic().SerializeAsString()); + EXPECT_EQ(request.GetTypeName(), "uprotocol.core.usubscription.v3.FetchSubscriptionsRequest"); +} - SubscriptionRequest request = builder.buildSubscriptionRequest(topic); +TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithSubscriberInfo) { + SubscriberInfo subscriber; + RequestBuilder builder(options_); - // Verify the attributes in the request - EXPECT_NE(request.topic().SerializeAsString(), - wrong_topic.SerializeAsString()); + FetchSubscriptionsRequest request = builder.buildFetchSubscriptionsRequest(subscriber); + + // Verify the attributes in the request + EXPECT_FALSE(request.has_topic()); + EXPECT_EQ(request.GetTypeName(), "uprotocol.core.usubscription.v3.FetchSubscriptionsRequest"); +} + +TEST_F(RequestBuilderTest, BuildFetchSubscribersRequest) { + v1::UUri topic = getSource(); + RequestBuilder builder(options_); + + FetchSubscribersRequest request = builder.buildFetchSubscribersRequest(topic); + + // Verify the attributes in the request + EXPECT_TRUE(request.has_topic()); + EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); + EXPECT_NE(request.topic().SerializeAsString(), getWrongTopic().SerializeAsString()); + EXPECT_EQ(request.GetTypeName(), "uprotocol.core.usubscription.v3.FetchSubscribersRequest"); +} + +TEST_F(RequestBuilderTest, BuildNotificationsRequest) { + v1::UUri topic = getSource(); + RequestBuilder builder(options_); + + NotificationsRequest request = builder.buildNotificationsRequest(topic); + + // Verify the attributes in the request + EXPECT_TRUE(request.has_topic()); + EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); + EXPECT_NE(request.topic().SerializeAsString(), getWrongTopic().SerializeAsString()); + EXPECT_EQ(request.GetTypeName(), "uprotocol.core.usubscription.v3.NotificationsRequest"); } -} // namespace uprotocol::core::usubscription::v3 \ No newline at end of file +} // namespace uprotocol::core::usubscription::v3 diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp index 47607fc55..2a7c1d90d 100644 --- a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -1,4 +1,5 @@ #include +#include #include "UTransportMock.h" #include "up-cpp/client/usubscription/v3/RequestBuilder.h" @@ -10,6 +11,8 @@ using UMessage = uprotocol::v1::UMessage; using Payload = uprotocol::datamodel::builder::Payload; using ProtoConverter = uprotocol::utils::ProtoConverter; +using SubscriptionRequest = uprotocol::core::usubscription::v3::SubscriptionRequest; +using SubscriptionResponse = uprotocol::core::usubscription::v3::SubscriptionResponse; namespace { @@ -93,8 +96,8 @@ class RpcClientUSubscriptionTest : public testing::Test { TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoPayload) { bool server_callback_executed = false; - uprotocol::core::usubscription::v3::SubscriptionRequest server_capture; - uprotocol::core::usubscription::v3::SubscriptionResponse server_response; + SubscriptionRequest server_capture; + SubscriptionResponse server_response; *server_response.mutable_topic() = getSubscriptionTopic(); auto server_or_status = uprotocol::communication::RpcServer::create( getServerTransport(), getServerMethodUuri(), @@ -102,7 +105,7 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoPayload) { &server_response](const UMessage& message) -> std::optional { server_callback_executed = true; auto request_or_status = ProtoConverter::extractFromProtobuf< - uprotocol::core::usubscription::v3::SubscriptionRequest>( + SubscriptionRequest>( message); if (!request_or_status.has_value()) { return std::nullopt; @@ -127,7 +130,7 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoPayload) { std::launch::async, [&client, &subscription_request]() -> uprotocol::utils::Expected< - uprotocol::core::usubscription::v3::SubscriptionResponse, + SubscriptionResponse, uprotocol::v1::UStatus> { return client.subscribe(subscription_request); }); @@ -161,8 +164,8 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoPayload) { TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoAnyPayload) { bool server_callback_executed = false; - uprotocol::core::usubscription::v3::SubscriptionRequest server_capture; - uprotocol::core::usubscription::v3::SubscriptionResponse server_response; + SubscriptionRequest server_capture; + SubscriptionResponse server_response; *server_response.mutable_topic() = getSubscriptionTopic(); auto server_or_status = uprotocol::communication::RpcServer::create( getServerTransport(), getServerMethodUuri(), @@ -170,7 +173,7 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoAnyPayload) { &server_response](const UMessage& message) -> std::optional { server_callback_executed = true; auto request_or_status = ProtoConverter::extractFromProtobuf< - uprotocol::core::usubscription::v3::SubscriptionRequest>( + SubscriptionRequest>( message); if (!request_or_status.has_value()) { return std::nullopt; @@ -199,7 +202,7 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoAnyPayload) { std::launch::async, [&client, &subscription_request]() -> uprotocol::utils::Expected< - uprotocol::core::usubscription::v3::SubscriptionResponse, + SubscriptionResponse, uprotocol::v1::UStatus> { return client.subscribe(subscription_request); }); @@ -231,18 +234,27 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoAnyPayload) { server_response.SerializeAsString()); } -TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithInvalidPayload) { +TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoPayloadDifferentTopic) { bool server_callback_executed = false; - uprotocol::core::usubscription::v3::SubscriptionRequest server_capture; - uprotocol::core::usubscription::v3::SubscriptionResponse server_response; - *server_response.mutable_topic() = getSubscriptionTopic(); + SubscriptionRequest server_capture; + SubscriptionResponse server_response; + + constexpr uint32_t TOPIC_UE = 4321; + constexpr uint32_t TOPIC_RESOURCE_ID = 54321; + uprotocol::v1::UUri wrong_subscription_topic; + wrong_subscription_topic.set_authority_name("topic.usubscription.wrong"); + wrong_subscription_topic.set_ue_id(TOPIC_UE); + wrong_subscription_topic.set_ue_version_major(UE_VERSION_MAJOR); + wrong_subscription_topic.set_resource_id(TOPIC_RESOURCE_ID); + *server_response.mutable_topic() = wrong_subscription_topic; + auto server_or_status = uprotocol::communication::RpcServer::create( getServerTransport(), getServerMethodUuri(), [&server_callback_executed, &server_capture, &server_response](const UMessage& message) -> std::optional { server_callback_executed = true; auto request_or_status = ProtoConverter::extractFromProtobuf< - uprotocol::core::usubscription::v3::SubscriptionRequest>( + SubscriptionRequest>( message); if (!request_or_status.has_value()) { return std::nullopt; @@ -267,7 +279,7 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithInvalidPayload) { std::launch::async, [&client, &subscription_request]() -> uprotocol::utils::Expected< - uprotocol::core::usubscription::v3::SubscriptionResponse, + SubscriptionResponse, uprotocol::v1::UStatus> { return client.subscribe(subscription_request); }); @@ -294,9 +306,71 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithInvalidPayload) { EXPECT_TRUE(getClientTransport()->getListener()); EXPECT_EQ(getClientTransport()->getSendCount(), 1); auto response_or_status = response_or_status_future.get(); - ASSERT_TRUE(response_or_status.has_value()); - EXPECT_EQ(response_or_status.value().SerializeAsString(), - server_response.SerializeAsString()); + ASSERT_FALSE(response_or_status.has_value()); // Should fail because the topics do not match +} + +TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithWrongResponse) { + bool server_callback_executed = false; + SubscriptionRequest server_capture; + uprotocol::core::usubscription::v3::NotificationsRequest wrong_server_response; + *wrong_server_response.mutable_topic() = getSubscriptionTopic(); + auto server_or_status = uprotocol::communication::RpcServer::create( + getServerTransport(), getServerMethodUuri(), + [&server_callback_executed, &server_capture, + &wrong_server_response](const UMessage& message) -> std::optional { + server_callback_executed = true; + auto request_or_status = ProtoConverter::extractFromProtobuf(message); + if (!request_or_status.has_value()) { + return std::nullopt; + } + server_capture = request_or_status.value(); + Payload response_payload(wrong_server_response); + return response_payload; + }, + uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF); + + ASSERT_TRUE(server_or_status.has_value()); + ASSERT_NE(server_or_status.value(), nullptr); + EXPECT_TRUE(getServerTransport()->getListener()); + + auto client = uprotocol::core::usubscription::v3::RpcClientUSubscription( + getClientTransport()); + + const auto subscription_request = + getRequestBuilder().buildSubscriptionRequest(getSubscriptionTopic()); + + auto response_or_status_future = std::async( + std::launch::async, + [&client, &subscription_request]() + -> uprotocol::utils::Expected< + SubscriptionResponse, + uprotocol::v1::UStatus> { + return client.subscribe(subscription_request); + }); + + // wait to give the client time to send the request. Otherwise this would + // cause a race condition + constexpr int ITERATIONS_TILL_TIMEOUT = 10; + constexpr std::chrono::milliseconds MILLISECONDS_PER_ITERATION = + std::chrono::milliseconds(100); + int counter = ITERATIONS_TILL_TIMEOUT; + while (counter > 0 && getClientTransport()->getSendCount() == 0) { + counter--; + std::this_thread::sleep_for(MILLISECONDS_PER_ITERATION); + } + ASSERT_EQ(getClientTransport()->getSendCount(), 1); + EXPECT_TRUE(getClientTransport()->getListener()); + + (*getServerTransport()->getListener())(getClientTransport()->getMessage()); + EXPECT_TRUE(server_callback_executed); + EXPECT_EQ(server_capture.SerializeAsString(), + subscription_request.SerializeAsString()); + + getClientTransport()->mockMessage(getServerTransport()->getMessage()); + EXPECT_TRUE(getClientTransport()->getListener()); + EXPECT_EQ(getClientTransport()->getSendCount(), 1); + auto response_or_status = response_or_status_future.get(); + ASSERT_TRUE(response_or_status.has_value()); // Should fail because the response is not a SubscriptionResponse } -TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithInvalidResponse) {} +// TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithInvalidResponse) {} }; // namespace From 76a84b74ad3c662da4a176ed474b54f3ae362fff Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Tue, 27 May 2025 13:47:36 +0200 Subject: [PATCH 090/105] Added USubscriptionUUriBuilderTests --- .../v3/USubscriptionUUriBuilderTest.cpp | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 test/coverage/client/usubscription/v3/USubscriptionUUriBuilderTest.cpp diff --git a/test/coverage/client/usubscription/v3/USubscriptionUUriBuilderTest.cpp b/test/coverage/client/usubscription/v3/USubscriptionUUriBuilderTest.cpp new file mode 100644 index 000000000..b62ef5a85 --- /dev/null +++ b/test/coverage/client/usubscription/v3/USubscriptionUUriBuilderTest.cpp @@ -0,0 +1,70 @@ +// SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include "up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h" + +constexpr uint16_t RESOURCE_ID_TEST = 0x0001; +constexpr uint16_t RESOURCE_ID_NOTIFICATION_ID = 0x8000; + +namespace uprotocol::core::usubscription::v3 { +class USubscriptionUUriBuilderTest : public ::testing::Test { +private: + v1::UUri expected_uri_; + v1::UUri wrong_uri_; +protected: + v1::UUri getExpectedUri() const { + return expected_uri_; + } + v1::UUri getWrongUri() const { + return wrong_uri_; + } + void SetUp() override { + expected_uri_.set_authority_name("core.usubscription"); + expected_uri_.set_ue_id(0); + expected_uri_.set_ue_version_major(3); + + wrong_uri_.set_authority_name("core.usubscription_wrong"); + wrong_uri_.set_ue_id(1); + wrong_uri_.set_ue_version_major(1); + wrong_uri_.set_resource_id(1); + } + + void TearDown() override {} + +}; + +TEST_F(USubscriptionUUriBuilderTest, GetServiceUriWithResourceId) { + // Example test case for building a subscription UUri + auto expected_uri = getExpectedUri(); + expected_uri.set_resource_id(RESOURCE_ID_TEST); + USubscriptionUUriBuilder builder; + v1::UUri actual_uri = builder.getServiceUriWithResourceId(RESOURCE_ID_TEST); + + EXPECT_TRUE(actual_uri.IsInitialized()); + EXPECT_EQ(actual_uri.GetTypeName(), "uprotocol.v1.UUri"); + EXPECT_EQ(actual_uri.SerializeAsString(), expected_uri.SerializeAsString()); + EXPECT_NE(actual_uri.SerializeAsString(), getWrongUri().SerializeAsString()); +} + +TEST_F(USubscriptionUUriBuilderTest, GetNotificationUri){ + auto expected_uri = getExpectedUri(); + expected_uri.set_resource_id(RESOURCE_ID_NOTIFICATION_ID); + USubscriptionUUriBuilder builder; + v1::UUri actual_uri = builder.getNotificationUri(); + EXPECT_TRUE(actual_uri.IsInitialized()); + EXPECT_EQ(actual_uri.GetTypeName(), "uprotocol.v1.UUri"); + EXPECT_EQ(actual_uri.SerializeAsString(), expected_uri.SerializeAsString()); + EXPECT_NE(actual_uri.SerializeAsString(), getWrongUri().SerializeAsString()); +} + +} // namespace uprotocol::core::usubscription::v3 From 1cf8f74b3c12fac47794cce9195646e680937058 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Wed, 28 May 2025 09:13:25 +0200 Subject: [PATCH 091/105] Removed debeugging. Removed Payload Test. Added unimplemented in ProtoConverter --- include/up-cpp/communication/RpcClient.h | 2 +- include/up-cpp/utils/ProtoConverter.h | 8 ++- .../v3/RpcClientUSubscriptionTest.cpp | 64 ------------------- 3 files changed, 8 insertions(+), 66 deletions(-) diff --git a/include/up-cpp/communication/RpcClient.h b/include/up-cpp/communication/RpcClient.h index 0239cdb7a..d36f0c77a 100644 --- a/include/up-cpp/communication/RpcClient.h +++ b/include/up-cpp/communication/RpcClient.h @@ -185,7 +185,7 @@ struct RpcClient { return ResponseOrStatus( UnexpectedStatus(message_or_status.error())); } - std::cout << "message_or_status.value().GetTypeName(): "<< message_or_status.value().GetTypeName() << std::endl; + auto response_or_status = utils::ProtoConverter::extractFromProtobuf( message_or_status.value()); diff --git a/include/up-cpp/utils/ProtoConverter.h b/include/up-cpp/utils/ProtoConverter.h index eb6141d37..93a4471db 100644 --- a/include/up-cpp/utils/ProtoConverter.h +++ b/include/up-cpp/utils/ProtoConverter.h @@ -148,7 +148,13 @@ struct ProtoConverter { case v1::UPayloadFormat:: UPayloadFormat_INT_MIN_SENTINEL_DO_NOT_USE_: case v1::UPayloadFormat:: - UPayloadFormat_INT_MAX_SENTINEL_DO_NOT_USE_: + UPayloadFormat_INT_MAX_SENTINEL_DO_NOT_USE_: { + v1::UStatus status; + status.set_code(v1::UCode::UNIMPLEMENTED); + status.set_message( + "Unimplemented payload format."); + return TOrStatus(UnexpectedStatus(status)); + } default: { v1::UStatus status; status.set_code(v1::UCode::INVALID_ARGUMENT); diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp index 2a7c1d90d..2eb6f9bf9 100644 --- a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -309,68 +309,4 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoPayloadDiffer ASSERT_FALSE(response_or_status.has_value()); // Should fail because the topics do not match } -TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithWrongResponse) { - bool server_callback_executed = false; - SubscriptionRequest server_capture; - uprotocol::core::usubscription::v3::NotificationsRequest wrong_server_response; - *wrong_server_response.mutable_topic() = getSubscriptionTopic(); - auto server_or_status = uprotocol::communication::RpcServer::create( - getServerTransport(), getServerMethodUuri(), - [&server_callback_executed, &server_capture, - &wrong_server_response](const UMessage& message) -> std::optional { - server_callback_executed = true; - auto request_or_status = ProtoConverter::extractFromProtobuf(message); - if (!request_or_status.has_value()) { - return std::nullopt; - } - server_capture = request_or_status.value(); - Payload response_payload(wrong_server_response); - return response_payload; - }, - uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF); - - ASSERT_TRUE(server_or_status.has_value()); - ASSERT_NE(server_or_status.value(), nullptr); - EXPECT_TRUE(getServerTransport()->getListener()); - - auto client = uprotocol::core::usubscription::v3::RpcClientUSubscription( - getClientTransport()); - - const auto subscription_request = - getRequestBuilder().buildSubscriptionRequest(getSubscriptionTopic()); - - auto response_or_status_future = std::async( - std::launch::async, - [&client, &subscription_request]() - -> uprotocol::utils::Expected< - SubscriptionResponse, - uprotocol::v1::UStatus> { - return client.subscribe(subscription_request); - }); - - // wait to give the client time to send the request. Otherwise this would - // cause a race condition - constexpr int ITERATIONS_TILL_TIMEOUT = 10; - constexpr std::chrono::milliseconds MILLISECONDS_PER_ITERATION = - std::chrono::milliseconds(100); - int counter = ITERATIONS_TILL_TIMEOUT; - while (counter > 0 && getClientTransport()->getSendCount() == 0) { - counter--; - std::this_thread::sleep_for(MILLISECONDS_PER_ITERATION); - } - ASSERT_EQ(getClientTransport()->getSendCount(), 1); - EXPECT_TRUE(getClientTransport()->getListener()); - - (*getServerTransport()->getListener())(getClientTransport()->getMessage()); - EXPECT_TRUE(server_callback_executed); - EXPECT_EQ(server_capture.SerializeAsString(), - subscription_request.SerializeAsString()); - - getClientTransport()->mockMessage(getServerTransport()->getMessage()); - EXPECT_TRUE(getClientTransport()->getListener()); - EXPECT_EQ(getClientTransport()->getSendCount(), 1); - auto response_or_status = response_or_status_future.get(); - ASSERT_TRUE(response_or_status.has_value()); // Should fail because the response is not a SubscriptionResponse -} -// TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithInvalidResponse) {} }; // namespace From fc2b24518367a7abc735cf105ff2c1da0582d27d Mon Sep 17 00:00:00 2001 From: Max Date: Wed, 28 May 2025 19:11:11 +0200 Subject: [PATCH 092/105] merge with add tests and changed description style --- include/up-cpp/utils/ProtoConverter.h | 37 ++++++++------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/include/up-cpp/utils/ProtoConverter.h b/include/up-cpp/utils/ProtoConverter.h index 93a4471db..20b0a181c 100644 --- a/include/up-cpp/utils/ProtoConverter.h +++ b/include/up-cpp/utils/ProtoConverter.h @@ -66,7 +66,7 @@ struct ProtoConverter { /// @return the built UnsubscribeRequest static UnsubscribeRequest BuildUnSubscribeRequest( const v1::UUri& subscription_topic); - + /// @brief Builds a FetchSubscriptionsRequest from the given topic /// /// @param topic the UUri of the topic to fetch subscriptions for @@ -91,18 +91,11 @@ struct ProtoConverter { /// @return the built NotificationsRequest static NotificationsRequest BuildNotificationsRequest(const v1::UUri& topic); - /** - * @brief Deserializes a protobuf message from a given payload. - * - * Parses the payload in `v1::UMessage` using `google::protobuf::Any`, - * returning a deserialized object of type `T` or an error if parsing fails. - * - * @tparam T The type to deserialize the message into. - * - * @param message The `v1::UMessage` containing the payload. - * - * @return `TOrStatus` with the deserialized object or an error status. - */ + /// @brief Deserializes a protobuf message from a given payload. + /// + /// @tparam T The type to deserialize the message into. + /// @param message The `v1::UMessage` containing the payload. + /// @return `TOrStatus` with the deserialized object or an error status. template static TOrStatus extractFromProtobuf(const v1::UMessage& message) { switch (message.attributes().payload_format()) { @@ -165,19 +158,11 @@ struct ProtoConverter { } } - /** - * @brief Serializes a protobuf object into a payload. - * - * Converts the given `proto` object to a payload using - * `google::protobuf::Any`. Returns the payload or an error status if - * serialization fails. - * - * @tparam T The type of the protobuf object to serialize. - * - * @param proto The protobuf object to be converted into a payload. - * - * @return `PayloadOrStatus` containing the payload or an error status. - */ + /// @brief Serializes a protobuf object into a payload. + /// + /// @tparam T The type of the protobuf object to serialize. + /// @param proto The protobuf object to be converted into a payload. + /// @return `PayloadOrStatus` containing the payload or an error status. template static PayloadOrStatus protoToPayload(const T& proto) { google::protobuf::Any any; From d521cf3b82072a7517fa35913f9e23bb39c89008 Mon Sep 17 00:00:00 2001 From: Max Date: Wed, 28 May 2025 19:24:44 +0200 Subject: [PATCH 093/105] added documentation to USubscription.h --- .../client/usubscription/v3/USubscription.h | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/include/up-cpp/client/usubscription/v3/USubscription.h b/include/up-cpp/client/usubscription/v3/USubscription.h index 7ad69e8d4..e3e4a676c 100644 --- a/include/up-cpp/client/usubscription/v3/USubscription.h +++ b/include/up-cpp/client/usubscription/v3/USubscription.h @@ -19,28 +19,58 @@ namespace uprotocol::core::usubscription::v3 { +/** + * + */ struct USubscription { + template using ResponseOrStatus = utils::Expected; virtual ~USubscription() = default; + /// @brief sends a subscription request to a USubscription backend and a + /// response on success or else a status code + /// + /// @param subscription_request containing a topic to subscribe to + /// @return SubscriptionReponse on success and UStatus else virtual ResponseOrStatus subscribe( const SubscriptionRequest& subscription_request) = 0; + /// @brief sends an unsubscribe request to a USubscription backend and a + /// response on success or else a status code + /// + /// @param unsubscribe_request containing a topic to unsubscribe + /// @return UnsubscribeResponse on success and UStatus else virtual ResponseOrStatus unsubscribe( const UnsubscribeRequest& unsubscribe_request) = 0; + /// @brief fetches all topic the client is subscribed to from the backend + /// + /// @param fetch_subscriptions_request + /// @return FetchSubscriptionsResponse on success and UStatus else virtual ResponseOrStatus fetch_subscriptions( const FetchSubscriptionsRequest& fetch_subscriptions_request) = 0; + /// @brief registers for notifications to a USubscription backend + /// + /// @param register_notifications_request + /// @return NotificationResponse on success and UStatus else virtual ResponseOrStatus register_for_notifications( const NotificationsRequest& register_notifications_request) = 0; + /// @brief unregisters for notifications to a USubscription backend + /// + /// @param unregister_notifications_request + /// @return NotificationResponse on success and UStatus else virtual ResponseOrStatus unregister_for_notifications( const NotificationsRequest& unregister_notifications_request) = 0; + /// @brief fetches all subscribers for a given topic from the backend + /// + /// @param fetch_subscriptions_request containing the topic for which the subscribers are fetched + /// @return FetchSubscriptionsResponse on success and UStatus else virtual ResponseOrStatus fetch_subscribers( const FetchSubscribersRequest& fetch_subscribers_request) = 0; }; From 9891c9326a0f5a01b0d229d36f975eeb3d8dfcec Mon Sep 17 00:00:00 2001 From: Max Date: Wed, 28 May 2025 19:27:48 +0200 Subject: [PATCH 094/105] changed comment style in RequestBuilder.h --- .../client/usubscription/v3/RequestBuilder.h | 115 ++++++++---------- 1 file changed, 49 insertions(+), 66 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RequestBuilder.h b/include/up-cpp/client/usubscription/v3/RequestBuilder.h index c51c82652..6dcd2a45e 100644 --- a/include/up-cpp/client/usubscription/v3/RequestBuilder.h +++ b/include/up-cpp/client/usubscription/v3/RequestBuilder.h @@ -18,12 +18,10 @@ namespace uprotocol::core::usubscription::v3 { -/** - * @struct USubscriptionOptions - * @brief Additional details for uSubscription service. - * - * Each member represents an optional parameter for the uSubscription service. - */ +/// @struct USubscriptionOptions +/// @brief Additional details for uSubscription service. +/// +/// Each member represents an optional parameter for the uSubscription service. struct USubscriptionOptions { /// Permission level of the subscription request std::optional permission_level; @@ -39,83 +37,68 @@ struct USubscriptionOptions { std::optional subscription_details; }; -/** - * @brief Builds different requests using specified options. - * - * This struct facilitates the construction of requests based on - * `USubscriptionOptions`, providing methods to build different requests. - */ +/// @brief Builds different requests using specified options. +/// +/// This struct facilitates the construction of requests based on +/// `USubscriptionOptions`, providing methods to build different requests. struct RequestBuilder { - /** - * @brief Constructs a RequestBuilder with the given subscription options. - * - * @param options Subscription options to configure the requests. Defaults - * to empty options. - */ + + /// @brief Constructs a RequestBuilder with the given subscription options. + /// + /// @param options Subscription options to configure the requests. Defaults + /// to empty options. explicit RequestBuilder(USubscriptionOptions options = {}) : options_(std::move(options)) {} - /** - * @brief Builds a subscription request for a given topic. - * - * @param topic The `v1::UUri` representing the topic for the subscription. - * - * @return A `SubscriptionRequest` configured for the specified topic. - */ + /// @brief Builds a subscription request for a given topic. + /// + /// @param topic The `v1::UUri` representing the topic for the subscription. + /// + /// @return A `SubscriptionRequest` configured for the specified topic. SubscriptionRequest buildSubscriptionRequest(const v1::UUri& topic) const; - /** - * @brief Builds an unsubscription request for a given topic. - * - * @param topic The `v1::UUri` representing the topic to unsubscribe from. - * - * @return An `UnsubscribeRequest` configured for the specified topic. - */ + /// @brief Builds an unsubscription request for a given topic. + /// + /// @param topic The `v1::UUri` representing the topic to unsubscribe from. + /// + /// @return An `UnsubscribeRequest` configured for the specified topic. static UnsubscribeRequest buildUnsubscribeRequest(const v1::UUri& topic); - /** - * @brief Build fetch subscritions request for a given topic. - * - * @param topic The `v1::UUri` representing the topic to fetch. - * - * @return An `FetchSubscriptionsRequest` configured for the specified - * topic. - */ + /// @brief Build fetch subscritions request for a given topic. + /// + /// @param topic The `v1::UUri` representing the topic to fetch. + /// + /// @return An `FetchSubscriptionsRequest` configured for the specified + /// topic. static FetchSubscriptionsRequest buildFetchSubscriptionsRequest( const v1::UUri& topic); - /** - * @brief Build fetch subscritions request for a given subscriber. - * - * @param subscriber The `SubscriberInfo` representing the subscriber to - * fetch. - * - * @return An `FetchSubscriptionsRequest` configured for the specified - * subscriber. - */ + /// @brief Build fetch subscritions request for a given subscriber. + /// + /// @param subscriber The `SubscriberInfo` representing the subscriber to + /// fetch. + /// + /// @return An `FetchSubscriptionsRequest` configured for the specified + /// subscriber. static FetchSubscriptionsRequest buildFetchSubscriptionsRequest( const SubscriberInfo& subscriber); - /** - * @brief Build fetch subscribers request for a given topic. - * - * @param topic The `v1::UUri` representing the topic to fetch. - * - * @return An `FetchSubscribersRequest` configured for the specified topic. - */ + /// @brief Build fetch subscribers request for a given topic. + /// + /// @param topic The `v1::UUri` representing the topic to fetch. + /// + /// @return An `FetchSubscribersRequest` configured for the specified topic. static FetchSubscribersRequest buildFetchSubscribersRequest( const v1::UUri& topic); - /** - * @brief Build notifications request for a given topic. Subscription change - *notifications MUST use topic SubscriptionsChange with resource id 0x8000, - *as per the protobuf definition. - * - * @param topic The `v1::UUri` representing the topic to (un)register - *for/from. - * - * @return An `NotificationsRequest` configured for the specified topic. - */ + /// @brief Build notifications request for a given topic. Subscription change + ///notifications MUST use topic SubscriptionsChange with resource id 0x8000, + ///as per the protobuf definition. + /// + /// @param topic The `v1::UUri` representing the topic to (un)register + ///for/from. + /// + /// @return An `NotificationsRequest` configured for the specified topic. static NotificationsRequest buildNotificationsRequest(const v1::UUri& topic); private: From d137c7881d71c55e5ef7a4489e7c9afb76704319 Mon Sep 17 00:00:00 2001 From: Max Date: Wed, 28 May 2025 19:44:36 +0200 Subject: [PATCH 095/105] more documentation --- .../client/usubscription/v3/RequestBuilder.h | 13 +-- .../usubscription/v3/RpcClientUSubscription.h | 40 ++++++--- .../client/usubscription/v3/USubscription.h | 13 +-- include/up-cpp/communication/RpcClient.h | 2 +- include/up-cpp/utils/ProtoConverter.h | 27 +++--- src/utils/ProtoConverter.cpp | 36 ++++---- .../usubscription/v3/RequestBuilderTest.cpp | 88 ++++++++++-------- .../v3/RpcClientUSubscriptionTest.cpp | 90 ++++++++++--------- .../v3/USubscriptionUUriBuilderTest.cpp | 75 ++++++++-------- 9 files changed, 211 insertions(+), 173 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RequestBuilder.h b/include/up-cpp/client/usubscription/v3/RequestBuilder.h index 6dcd2a45e..31402c086 100644 --- a/include/up-cpp/client/usubscription/v3/RequestBuilder.h +++ b/include/up-cpp/client/usubscription/v3/RequestBuilder.h @@ -42,7 +42,6 @@ struct USubscriptionOptions { /// This struct facilitates the construction of requests based on /// `USubscriptionOptions`, providing methods to build different requests. struct RequestBuilder { - /// @brief Constructs a RequestBuilder with the given subscription options. /// /// @param options Subscription options to configure the requests. Defaults @@ -91,15 +90,17 @@ struct RequestBuilder { static FetchSubscribersRequest buildFetchSubscribersRequest( const v1::UUri& topic); - /// @brief Build notifications request for a given topic. Subscription change - ///notifications MUST use topic SubscriptionsChange with resource id 0x8000, - ///as per the protobuf definition. + /// @brief Build notifications request for a given topic. Subscription + /// change + /// notifications MUST use topic SubscriptionsChange with resource id + /// 0x8000, as per the protobuf definition. /// /// @param topic The `v1::UUri` representing the topic to (un)register - ///for/from. + /// for/from. /// /// @return An `NotificationsRequest` configured for the specified topic. - static NotificationsRequest buildNotificationsRequest(const v1::UUri& topic); + static NotificationsRequest buildNotificationsRequest( + const v1::UUri& topic); private: USubscriptionOptions options_; ///< Options used to configure the requests. diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index aa7b4c003..70a34d697 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -46,10 +46,7 @@ namespace uprotocol::core::usubscription::v3 { using v3::SubscriptionRequest; using v3::UnsubscribeRequest; -/// @brief Interface for uEntities to create subscriptions. -/// -/// Like all L3 client APIs, the RpcClientUSubscription is a wrapper on top of -/// the L2 Communication APIs and USubscription service. +/// @brief Client which implements the USubscription interface struct RpcClientUSubscription : USubscription { using RpcClientUSubscriptionOrStatus = utils::Expected, v1::UStatus>; @@ -59,54 +56,69 @@ struct RpcClientUSubscription : USubscription { template Response invokeResponse(communication::RpcClient rpc_client); - /// @brief Subscribe to the topic + /// @brief Subscribes from a given topic /// + /// @param subscription_request The request object containing the topic to + /// subscribe to + /// @return Returns a SubscriptionResponse on success and a UStatus else utils::Expected subscribe( const SubscriptionRequest& subscription_request) override; - /// @brief Unsubscribe from the topic + /// @brief Unsubscribes from a given topic /// + /// @param unsubscribe_request The request object containing the topic to + /// unsubscribe from + /// @return Returns an UnsubscribeResponse on success and a UStatus else utils::Expected unsubscribe( const UnsubscribeRequest& unsubscribe_request) override; - /// @brief Fetch all subscriptions either by topic or subscriber + /// @brief Fetches the list of topics the client is subscribed to /// + /// @param fetch_subscriptions_request The request object + /// @return Returns a FetchSubscriptionsResponse on success and a UStatus + /// else utils::Expected fetch_subscriptions( const FetchSubscriptionsRequest& fetch_subscriptions_request) override; - /// @brief Fetch all subscribers + /// @brief Fetches the list of subscribers for a given topic /// + /// @param fetch_subscribers_request The request object containing the topic + /// for which the subscribers are to be fetched + /// @return Returns a FetchSubscribersResponse on success and a UStatus else utils::Expected fetch_subscribers( const FetchSubscribersRequest& fetch_subscribers_request) override; - /// @brief Register for notifications + /// @brief Registers to receive notifications /// + /// @param register_notifications_request The request object containing + /// the details to register for notifications + /// @return Returns a NotificationResponse on success and a UStatus else utils::Expected register_for_notifications( const NotificationsRequest& register_notifications_request) override; - /// @brief Unregister for notifications + /// @brief Unregisters from receiving notifications. /// + /// @param unregister_notifications_request The request object containing + /// the details needed to stop receiving notifications. + /// @return Returns a NotificationResponse on success and a UStatus else utils::Expected unregister_for_notifications( const NotificationsRequest& unregister_notifications_request) override; /// @brief Constructor /// - /// @param transport Transport to register with. + /// @param transport Transport used to send messages explicit RpcClientUSubscription( std::shared_ptr transport) : transport_(std::move(transport)) {} - /// @brief Destructor ~RpcClientUSubscription() override = default; private: - // Transport std::shared_ptr transport_; - // URI info about the uSubscription service USubscriptionUUriBuilder uuri_builder_; }; diff --git a/include/up-cpp/client/usubscription/v3/USubscription.h b/include/up-cpp/client/usubscription/v3/USubscription.h index e3e4a676c..8d0e4a092 100644 --- a/include/up-cpp/client/usubscription/v3/USubscription.h +++ b/include/up-cpp/client/usubscription/v3/USubscription.h @@ -19,11 +19,11 @@ namespace uprotocol::core::usubscription::v3 { -/** - * - */ +/// @brief Interface for uEntities to create subscriptions. +/// +/// Like all L3 client APIs, the RpcClientUSubscription is a wrapper on top of +/// the L2 Communication APIs and USubscription service. struct USubscription { - template using ResponseOrStatus = utils::Expected; @@ -45,7 +45,7 @@ struct USubscription { virtual ResponseOrStatus unsubscribe( const UnsubscribeRequest& unsubscribe_request) = 0; - /// @brief fetches all topic the client is subscribed to from the backend + /// @brief fetches all topics the client is subscribed to from the backend /// /// @param fetch_subscriptions_request /// @return FetchSubscriptionsResponse on success and UStatus else @@ -69,7 +69,8 @@ struct USubscription { /// @brief fetches all subscribers for a given topic from the backend /// - /// @param fetch_subscriptions_request containing the topic for which the subscribers are fetched + /// @param fetch_subscriptions_request containing the topic for which the + /// subscribers are fetched /// @return FetchSubscriptionsResponse on success and UStatus else virtual ResponseOrStatus fetch_subscribers( const FetchSubscribersRequest& fetch_subscribers_request) = 0; diff --git a/include/up-cpp/communication/RpcClient.h b/include/up-cpp/communication/RpcClient.h index d36f0c77a..07ee17711 100644 --- a/include/up-cpp/communication/RpcClient.h +++ b/include/up-cpp/communication/RpcClient.h @@ -185,7 +185,7 @@ struct RpcClient { return ResponseOrStatus( UnexpectedStatus(message_or_status.error())); } - + auto response_or_status = utils::ProtoConverter::extractFromProtobuf( message_or_status.value()); diff --git a/include/up-cpp/utils/ProtoConverter.h b/include/up-cpp/utils/ProtoConverter.h index 20b0a181c..8f5c3deaa 100644 --- a/include/up-cpp/utils/ProtoConverter.h +++ b/include/up-cpp/utils/ProtoConverter.h @@ -18,13 +18,13 @@ using TOrStatus = utils::Expected; using UnexpectedStatus = utils::Unexpected; using PayloadOrStatus = utils::Expected; +using core::usubscription::v3::FetchSubscribersRequest; +using core::usubscription::v3::FetchSubscriptionsRequest; +using core::usubscription::v3::NotificationsRequest; using uprotocol::core::usubscription::v3::SubscribeAttributes; using uprotocol::core::usubscription::v3::SubscriberInfo; using uprotocol::core::usubscription::v3::SubscriptionRequest; using uprotocol::core::usubscription::v3::UnsubscribeRequest; -using core::usubscription::v3::FetchSubscriptionsRequest; -using core::usubscription::v3::FetchSubscribersRequest; -using core::usubscription::v3::NotificationsRequest; struct ProtoConverter { /// @brief Converts std::chrono::time_point to google::protobuf::Timestamp @@ -71,25 +71,31 @@ struct ProtoConverter { /// /// @param topic the UUri of the topic to fetch subscriptions for /// @return the built FetchSubscriptionsRequest - static FetchSubscriptionsRequest BuildFetchSubscriptionsRequest(const v1::UUri& topic); + static FetchSubscriptionsRequest BuildFetchSubscriptionsRequest( + const v1::UUri& topic); - /// @brief Builds a FetchSubscriptionsRequest from the given subscriber information + /// @brief Builds a FetchSubscriptionsRequest from the given subscriber + /// information /// - /// @param subscriber the SubscriberInfo containing details of the subscriber + /// @param subscriber the SubscriberInfo containing details of the + /// subscriber /// @return the built FetchSubscriptionsRequest - static FetchSubscriptionsRequest BuildFetchSubscriptionsRequest(const SubscriberInfo& subscriber); + static FetchSubscriptionsRequest BuildFetchSubscriptionsRequest( + const SubscriberInfo& subscriber); /// @brief Builds a FetchSubscribersRequest from the given topic /// /// @param topic the UUri of the topic to fetch subscribers for /// @return the built FetchSubscribersRequest - static FetchSubscribersRequest BuildFetchSubscribersRequest(const v1::UUri& topic); + static FetchSubscribersRequest BuildFetchSubscribersRequest( + const v1::UUri& topic); /// @brief Builds a NotificationsRequest from the given topic /// /// @param topic the UUri of the topic to build a notification request for /// @return the built NotificationsRequest - static NotificationsRequest BuildNotificationsRequest(const v1::UUri& topic); + static NotificationsRequest BuildNotificationsRequest( + const v1::UUri& topic); /// @brief Deserializes a protobuf message from a given payload. /// @@ -144,8 +150,7 @@ struct ProtoConverter { UPayloadFormat_INT_MAX_SENTINEL_DO_NOT_USE_: { v1::UStatus status; status.set_code(v1::UCode::UNIMPLEMENTED); - status.set_message( - "Unimplemented payload format."); + status.set_message("Unimplemented payload format."); return TOrStatus(UnexpectedStatus(status)); } default: { diff --git a/src/utils/ProtoConverter.cpp b/src/utils/ProtoConverter.cpp index 2f0cc378f..b6ee5403a 100644 --- a/src/utils/ProtoConverter.cpp +++ b/src/utils/ProtoConverter.cpp @@ -84,32 +84,36 @@ UnsubscribeRequest ProtoConverter::BuildUnSubscribeRequest( return unsubscribe_request; } -FetchSubscriptionsRequest ProtoConverter::BuildFetchSubscriptionsRequest(const v1::UUri& topic) { - FetchSubscriptionsRequest fetch_subscriptions_request; - *fetch_subscriptions_request.mutable_topic() = topic; +FetchSubscriptionsRequest ProtoConverter::BuildFetchSubscriptionsRequest( + const v1::UUri& topic) { + FetchSubscriptionsRequest fetch_subscriptions_request; + *fetch_subscriptions_request.mutable_topic() = topic; - return fetch_subscriptions_request; + return fetch_subscriptions_request; } -FetchSubscriptionsRequest ProtoConverter::BuildFetchSubscriptionsRequest(const SubscriberInfo& subscriber) { - FetchSubscriptionsRequest fetch_subscriptions_request; - *fetch_subscriptions_request.mutable_subscriber() = subscriber; +FetchSubscriptionsRequest ProtoConverter::BuildFetchSubscriptionsRequest( + const SubscriberInfo& subscriber) { + FetchSubscriptionsRequest fetch_subscriptions_request; + *fetch_subscriptions_request.mutable_subscriber() = subscriber; - return fetch_subscriptions_request; + return fetch_subscriptions_request; } -FetchSubscribersRequest ProtoConverter::BuildFetchSubscribersRequest(const v1::UUri& topic) { - FetchSubscribersRequest fetch_subscribers_request; - *fetch_subscribers_request.mutable_topic() = topic; +FetchSubscribersRequest ProtoConverter::BuildFetchSubscribersRequest( + const v1::UUri& topic) { + FetchSubscribersRequest fetch_subscribers_request; + *fetch_subscribers_request.mutable_topic() = topic; - return fetch_subscribers_request; + return fetch_subscribers_request; } -NotificationsRequest ProtoConverter::BuildNotificationsRequest(const v1::UUri& topic) { - NotificationsRequest notifications_request; - *notifications_request.mutable_topic() = topic; +NotificationsRequest ProtoConverter::BuildNotificationsRequest( + const v1::UUri& topic) { + NotificationsRequest notifications_request; + *notifications_request.mutable_topic() = topic; - return notifications_request; + return notifications_request; } } // namespace uprotocol::utils diff --git a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp index 2de6e0a82..c5b28646c 100644 --- a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp +++ b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp @@ -43,7 +43,8 @@ class RequestBuilderTest : public ::testing::Test { source_.set_ue_version_major(SOURCE_UE_VERSION_MAJOR); source_.set_resource_id(SOURCE_RESOURCE_ID); - wrong_topic_.set_authority_name("10.0.0.2"); // random different authority + wrong_topic_.set_authority_name( + "10.0.0.2"); // random different authority wrong_topic_.set_ue_id(SOURCE_UE_ID); wrong_topic_.set_ue_version_major(SOURCE_UE_VERSION_MAJOR); wrong_topic_.set_resource_id(SOURCE_RESOURCE_ID); @@ -83,70 +84,83 @@ TEST_F(RequestBuilderTest, BuildSubscriptionRequestWithOptions) { EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); EXPECT_NE(request.topic().SerializeAsString(), getWrongTopic().SerializeAsString()); - EXPECT_EQ(request.GetTypeName(), "uprotocol.core.usubscription.v3.SubscriptionRequest"); + EXPECT_EQ(request.GetTypeName(), + "uprotocol.core.usubscription.v3.SubscriptionRequest"); } TEST_F(RequestBuilderTest, BuildUnsubscribeRequest) { - v1::UUri topic = getSource(); - RequestBuilder builder(options_); + v1::UUri topic = getSource(); + RequestBuilder builder(options_); - UnsubscribeRequest request = builder.buildUnsubscribeRequest(topic); + UnsubscribeRequest request = builder.buildUnsubscribeRequest(topic); - // Verify the attributes in the request - EXPECT_TRUE(request.has_topic()); - EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); - EXPECT_NE(request.topic().SerializeAsString(), getWrongTopic().SerializeAsString()); - EXPECT_EQ(request.GetTypeName(), "uprotocol.core.usubscription.v3.UnsubscribeRequest"); + // Verify the attributes in the request + EXPECT_TRUE(request.has_topic()); + EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); + EXPECT_NE(request.topic().SerializeAsString(), + getWrongTopic().SerializeAsString()); + EXPECT_EQ(request.GetTypeName(), + "uprotocol.core.usubscription.v3.UnsubscribeRequest"); } TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithTopic) { - v1::UUri topic = getSource(); + v1::UUri topic = getSource(); RequestBuilder builder(options_); - FetchSubscriptionsRequest request = builder.buildFetchSubscriptionsRequest(topic); + FetchSubscriptionsRequest request = + builder.buildFetchSubscriptionsRequest(topic); - // Verify the attributes in the request - EXPECT_TRUE(request.has_topic()); + // Verify the attributes in the request + EXPECT_TRUE(request.has_topic()); EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); - EXPECT_NE(request.topic().SerializeAsString(), getWrongTopic().SerializeAsString()); - EXPECT_EQ(request.GetTypeName(), "uprotocol.core.usubscription.v3.FetchSubscriptionsRequest"); + EXPECT_NE(request.topic().SerializeAsString(), + getWrongTopic().SerializeAsString()); + EXPECT_EQ(request.GetTypeName(), + "uprotocol.core.usubscription.v3.FetchSubscriptionsRequest"); } TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithSubscriberInfo) { - SubscriberInfo subscriber; + SubscriberInfo subscriber; RequestBuilder builder(options_); - FetchSubscriptionsRequest request = builder.buildFetchSubscriptionsRequest(subscriber); + FetchSubscriptionsRequest request = + builder.buildFetchSubscriptionsRequest(subscriber); - // Verify the attributes in the request - EXPECT_FALSE(request.has_topic()); - EXPECT_EQ(request.GetTypeName(), "uprotocol.core.usubscription.v3.FetchSubscriptionsRequest"); + // Verify the attributes in the request + EXPECT_FALSE(request.has_topic()); + EXPECT_EQ(request.GetTypeName(), + "uprotocol.core.usubscription.v3.FetchSubscriptionsRequest"); } TEST_F(RequestBuilderTest, BuildFetchSubscribersRequest) { - v1::UUri topic = getSource(); - RequestBuilder builder(options_); + v1::UUri topic = getSource(); + RequestBuilder builder(options_); - FetchSubscribersRequest request = builder.buildFetchSubscribersRequest(topic); + FetchSubscribersRequest request = + builder.buildFetchSubscribersRequest(topic); - // Verify the attributes in the request - EXPECT_TRUE(request.has_topic()); - EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); - EXPECT_NE(request.topic().SerializeAsString(), getWrongTopic().SerializeAsString()); - EXPECT_EQ(request.GetTypeName(), "uprotocol.core.usubscription.v3.FetchSubscribersRequest"); + // Verify the attributes in the request + EXPECT_TRUE(request.has_topic()); + EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); + EXPECT_NE(request.topic().SerializeAsString(), + getWrongTopic().SerializeAsString()); + EXPECT_EQ(request.GetTypeName(), + "uprotocol.core.usubscription.v3.FetchSubscribersRequest"); } TEST_F(RequestBuilderTest, BuildNotificationsRequest) { - v1::UUri topic = getSource(); - RequestBuilder builder(options_); + v1::UUri topic = getSource(); + RequestBuilder builder(options_); - NotificationsRequest request = builder.buildNotificationsRequest(topic); + NotificationsRequest request = builder.buildNotificationsRequest(topic); - // Verify the attributes in the request - EXPECT_TRUE(request.has_topic()); - EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); - EXPECT_NE(request.topic().SerializeAsString(), getWrongTopic().SerializeAsString()); - EXPECT_EQ(request.GetTypeName(), "uprotocol.core.usubscription.v3.NotificationsRequest"); + // Verify the attributes in the request + EXPECT_TRUE(request.has_topic()); + EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); + EXPECT_NE(request.topic().SerializeAsString(), + getWrongTopic().SerializeAsString()); + EXPECT_EQ(request.GetTypeName(), + "uprotocol.core.usubscription.v3.NotificationsRequest"); } } // namespace uprotocol::core::usubscription::v3 diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp index 2eb6f9bf9..c01703a78 100644 --- a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -11,8 +11,10 @@ using UMessage = uprotocol::v1::UMessage; using Payload = uprotocol::datamodel::builder::Payload; using ProtoConverter = uprotocol::utils::ProtoConverter; -using SubscriptionRequest = uprotocol::core::usubscription::v3::SubscriptionRequest; -using SubscriptionResponse = uprotocol::core::usubscription::v3::SubscriptionResponse; +using SubscriptionRequest = + uprotocol::core::usubscription::v3::SubscriptionRequest; +using SubscriptionResponse = + uprotocol::core::usubscription::v3::SubscriptionResponse; namespace { @@ -104,9 +106,9 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoPayload) { [&server_callback_executed, &server_capture, &server_response](const UMessage& message) -> std::optional { server_callback_executed = true; - auto request_or_status = ProtoConverter::extractFromProtobuf< - SubscriptionRequest>( - message); + auto request_or_status = + ProtoConverter::extractFromProtobuf( + message); if (!request_or_status.has_value()) { return std::nullopt; } @@ -126,14 +128,13 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoPayload) { const auto subscription_request = getRequestBuilder().buildSubscriptionRequest(getSubscriptionTopic()); - auto response_or_status_future = std::async( - std::launch::async, - [&client, &subscription_request]() - -> uprotocol::utils::Expected< - SubscriptionResponse, - uprotocol::v1::UStatus> { - return client.subscribe(subscription_request); - }); + auto response_or_status_future = + std::async(std::launch::async, + [&client, &subscription_request]() + -> uprotocol::utils::Expected { + return client.subscribe(subscription_request); + }); // wait to give the client time to send the request. Otherwise this would // cause a race condition @@ -172,19 +173,19 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoAnyPayload) { [&server_callback_executed, &server_capture, &server_response](const UMessage& message) -> std::optional { server_callback_executed = true; - auto request_or_status = ProtoConverter::extractFromProtobuf< - SubscriptionRequest>( - message); + auto request_or_status = + ProtoConverter::extractFromProtobuf( + message); if (!request_or_status.has_value()) { return std::nullopt; } server_capture = request_or_status.value(); - google::protobuf::Any any; - if(!any.PackFrom(server_response)) { - return std::nullopt; - } - Payload response_payload(any); - return response_payload; + google::protobuf::Any any; + if (!any.PackFrom(server_response)) { + return std::nullopt; + } + Payload response_payload(any); + return response_payload; }, uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY); @@ -198,14 +199,13 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoAnyPayload) { const auto subscription_request = getRequestBuilder().buildSubscriptionRequest(getSubscriptionTopic()); - auto response_or_status_future = std::async( - std::launch::async, - [&client, &subscription_request]() - -> uprotocol::utils::Expected< - SubscriptionResponse, - uprotocol::v1::UStatus> { - return client.subscribe(subscription_request); - }); + auto response_or_status_future = + std::async(std::launch::async, + [&client, &subscription_request]() + -> uprotocol::utils::Expected { + return client.subscribe(subscription_request); + }); // wait to give the client time to send the request. Otherwise this would // cause a race condition @@ -234,11 +234,12 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoAnyPayload) { server_response.SerializeAsString()); } -TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoPayloadDifferentTopic) { +TEST_F(RpcClientUSubscriptionTest, + SubscribeRoundtripWithValidProtoPayloadDifferentTopic) { bool server_callback_executed = false; SubscriptionRequest server_capture; SubscriptionResponse server_response; - + constexpr uint32_t TOPIC_UE = 4321; constexpr uint32_t TOPIC_RESOURCE_ID = 54321; uprotocol::v1::UUri wrong_subscription_topic; @@ -253,9 +254,9 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoPayloadDiffer [&server_callback_executed, &server_capture, &server_response](const UMessage& message) -> std::optional { server_callback_executed = true; - auto request_or_status = ProtoConverter::extractFromProtobuf< - SubscriptionRequest>( - message); + auto request_or_status = + ProtoConverter::extractFromProtobuf( + message); if (!request_or_status.has_value()) { return std::nullopt; } @@ -275,14 +276,13 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoPayloadDiffer const auto subscription_request = getRequestBuilder().buildSubscriptionRequest(getSubscriptionTopic()); - auto response_or_status_future = std::async( - std::launch::async, - [&client, &subscription_request]() - -> uprotocol::utils::Expected< - SubscriptionResponse, - uprotocol::v1::UStatus> { - return client.subscribe(subscription_request); - }); + auto response_or_status_future = + std::async(std::launch::async, + [&client, &subscription_request]() + -> uprotocol::utils::Expected { + return client.subscribe(subscription_request); + }); // wait to give the client time to send the request. Otherwise this would // cause a race condition @@ -306,7 +306,9 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoPayloadDiffer EXPECT_TRUE(getClientTransport()->getListener()); EXPECT_EQ(getClientTransport()->getSendCount(), 1); auto response_or_status = response_or_status_future.get(); - ASSERT_FALSE(response_or_status.has_value()); // Should fail because the topics do not match + ASSERT_FALSE( + response_or_status + .has_value()); // Should fail because the topics do not match } }; // namespace diff --git a/test/coverage/client/usubscription/v3/USubscriptionUUriBuilderTest.cpp b/test/coverage/client/usubscription/v3/USubscriptionUUriBuilderTest.cpp index b62ef5a85..fd623bc58 100644 --- a/test/coverage/client/usubscription/v3/USubscriptionUUriBuilderTest.cpp +++ b/test/coverage/client/usubscription/v3/USubscriptionUUriBuilderTest.cpp @@ -11,6 +11,7 @@ #include #include + #include "up-cpp/client/usubscription/v3/USubscriptionUUriBuilder.h" constexpr uint16_t RESOURCE_ID_TEST = 0x0001; @@ -19,52 +20,50 @@ constexpr uint16_t RESOURCE_ID_NOTIFICATION_ID = 0x8000; namespace uprotocol::core::usubscription::v3 { class USubscriptionUUriBuilderTest : public ::testing::Test { private: - v1::UUri expected_uri_; - v1::UUri wrong_uri_; -protected: - v1::UUri getExpectedUri() const { - return expected_uri_; - } - v1::UUri getWrongUri() const { - return wrong_uri_; - } - void SetUp() override { - expected_uri_.set_authority_name("core.usubscription"); - expected_uri_.set_ue_id(0); - expected_uri_.set_ue_version_major(3); + v1::UUri expected_uri_; + v1::UUri wrong_uri_; - wrong_uri_.set_authority_name("core.usubscription_wrong"); - wrong_uri_.set_ue_id(1); - wrong_uri_.set_ue_version_major(1); - wrong_uri_.set_resource_id(1); - } +protected: + v1::UUri getExpectedUri() const { return expected_uri_; } + v1::UUri getWrongUri() const { return wrong_uri_; } + void SetUp() override { + expected_uri_.set_authority_name("core.usubscription"); + expected_uri_.set_ue_id(0); + expected_uri_.set_ue_version_major(3); - void TearDown() override {} + wrong_uri_.set_authority_name("core.usubscription_wrong"); + wrong_uri_.set_ue_id(1); + wrong_uri_.set_ue_version_major(1); + wrong_uri_.set_resource_id(1); + } + void TearDown() override {} }; TEST_F(USubscriptionUUriBuilderTest, GetServiceUriWithResourceId) { - // Example test case for building a subscription UUri - auto expected_uri = getExpectedUri(); - expected_uri.set_resource_id(RESOURCE_ID_TEST); - USubscriptionUUriBuilder builder; - v1::UUri actual_uri = builder.getServiceUriWithResourceId(RESOURCE_ID_TEST); + // Example test case for building a subscription UUri + auto expected_uri = getExpectedUri(); + expected_uri.set_resource_id(RESOURCE_ID_TEST); + USubscriptionUUriBuilder builder; + v1::UUri actual_uri = builder.getServiceUriWithResourceId(RESOURCE_ID_TEST); - EXPECT_TRUE(actual_uri.IsInitialized()); - EXPECT_EQ(actual_uri.GetTypeName(), "uprotocol.v1.UUri"); - EXPECT_EQ(actual_uri.SerializeAsString(), expected_uri.SerializeAsString()); - EXPECT_NE(actual_uri.SerializeAsString(), getWrongUri().SerializeAsString()); + EXPECT_TRUE(actual_uri.IsInitialized()); + EXPECT_EQ(actual_uri.GetTypeName(), "uprotocol.v1.UUri"); + EXPECT_EQ(actual_uri.SerializeAsString(), expected_uri.SerializeAsString()); + EXPECT_NE(actual_uri.SerializeAsString(), + getWrongUri().SerializeAsString()); } -TEST_F(USubscriptionUUriBuilderTest, GetNotificationUri){ - auto expected_uri = getExpectedUri(); - expected_uri.set_resource_id(RESOURCE_ID_NOTIFICATION_ID); - USubscriptionUUriBuilder builder; - v1::UUri actual_uri = builder.getNotificationUri(); - EXPECT_TRUE(actual_uri.IsInitialized()); - EXPECT_EQ(actual_uri.GetTypeName(), "uprotocol.v1.UUri"); - EXPECT_EQ(actual_uri.SerializeAsString(), expected_uri.SerializeAsString()); - EXPECT_NE(actual_uri.SerializeAsString(), getWrongUri().SerializeAsString()); +TEST_F(USubscriptionUUriBuilderTest, GetNotificationUri) { + auto expected_uri = getExpectedUri(); + expected_uri.set_resource_id(RESOURCE_ID_NOTIFICATION_ID); + USubscriptionUUriBuilder builder; + v1::UUri actual_uri = builder.getNotificationUri(); + EXPECT_TRUE(actual_uri.IsInitialized()); + EXPECT_EQ(actual_uri.GetTypeName(), "uprotocol.v1.UUri"); + EXPECT_EQ(actual_uri.SerializeAsString(), expected_uri.SerializeAsString()); + EXPECT_NE(actual_uri.SerializeAsString(), + getWrongUri().SerializeAsString()); } -} // namespace uprotocol::core::usubscription::v3 +} // namespace uprotocol::core::usubscription::v3 From b2441d0c9f852b056cee6f55d07638a8a412875f Mon Sep 17 00:00:00 2001 From: Max Date: Wed, 28 May 2025 21:54:52 +0200 Subject: [PATCH 096/105] some test refactoring --- .../client/usubscription/v3/RequestBuilder.h | 18 ++--- .../usubscription/v3/RequestBuilder.cpp | 10 +-- .../usubscription/v3/RequestBuilderTest.cpp | 68 ++++++++----------- .../v3/USubscriptionUUriBuilderTest.cpp | 16 +---- 4 files changed, 44 insertions(+), 68 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RequestBuilder.h b/include/up-cpp/client/usubscription/v3/RequestBuilder.h index 31402c086..ed75df836 100644 --- a/include/up-cpp/client/usubscription/v3/RequestBuilder.h +++ b/include/up-cpp/client/usubscription/v3/RequestBuilder.h @@ -61,7 +61,7 @@ struct RequestBuilder { /// @param topic The `v1::UUri` representing the topic to unsubscribe from. /// /// @return An `UnsubscribeRequest` configured for the specified topic. - static UnsubscribeRequest buildUnsubscribeRequest(const v1::UUri& topic); + UnsubscribeRequest buildUnsubscribeRequest(const v1::UUri& topic) const; /// @brief Build fetch subscritions request for a given topic. /// @@ -69,8 +69,8 @@ struct RequestBuilder { /// /// @return An `FetchSubscriptionsRequest` configured for the specified /// topic. - static FetchSubscriptionsRequest buildFetchSubscriptionsRequest( - const v1::UUri& topic); + FetchSubscriptionsRequest buildFetchSubscriptionsRequest( + const v1::UUri& topic) const; /// @brief Build fetch subscritions request for a given subscriber. /// @@ -79,16 +79,16 @@ struct RequestBuilder { /// /// @return An `FetchSubscriptionsRequest` configured for the specified /// subscriber. - static FetchSubscriptionsRequest buildFetchSubscriptionsRequest( - const SubscriberInfo& subscriber); + FetchSubscriptionsRequest buildFetchSubscriptionsRequest( + const SubscriberInfo& subscriber) const; /// @brief Build fetch subscribers request for a given topic. /// /// @param topic The `v1::UUri` representing the topic to fetch. /// /// @return An `FetchSubscribersRequest` configured for the specified topic. - static FetchSubscribersRequest buildFetchSubscribersRequest( - const v1::UUri& topic); + FetchSubscribersRequest buildFetchSubscribersRequest( + const v1::UUri& topic) const ; /// @brief Build notifications request for a given topic. Subscription /// change @@ -99,8 +99,8 @@ struct RequestBuilder { /// for/from. /// /// @return An `NotificationsRequest` configured for the specified topic. - static NotificationsRequest buildNotificationsRequest( - const v1::UUri& topic); + NotificationsRequest buildNotificationsRequest( + const v1::UUri& topic) const; private: USubscriptionOptions options_; ///< Options used to configure the requests. diff --git a/src/client/usubscription/v3/RequestBuilder.cpp b/src/client/usubscription/v3/RequestBuilder.cpp index cbdfb4af7..3e36c3b8c 100644 --- a/src/client/usubscription/v3/RequestBuilder.cpp +++ b/src/client/usubscription/v3/RequestBuilder.cpp @@ -25,27 +25,27 @@ SubscriptionRequest RequestBuilder::buildSubscriptionRequest( } UnsubscribeRequest RequestBuilder::buildUnsubscribeRequest( - const v1::UUri& topic) { + const v1::UUri& topic) const { return utils::ProtoConverter::BuildUnSubscribeRequest(topic); } FetchSubscriptionsRequest RequestBuilder::buildFetchSubscriptionsRequest( - const v1::UUri& topic) { + const v1::UUri& topic) const { return utils::ProtoConverter::BuildFetchSubscriptionsRequest(topic); } FetchSubscriptionsRequest RequestBuilder::buildFetchSubscriptionsRequest( - const SubscriberInfo& subscriber) { + const SubscriberInfo& subscriber) const { return utils::ProtoConverter::BuildFetchSubscriptionsRequest(subscriber); } FetchSubscribersRequest RequestBuilder::buildFetchSubscribersRequest( - const v1::UUri& topic) { + const v1::UUri& topic) const { return utils::ProtoConverter::BuildFetchSubscribersRequest(topic); } NotificationsRequest RequestBuilder::buildNotificationsRequest( - const v1::UUri& topic) { + const v1::UUri& topic) const { return utils::ProtoConverter::BuildNotificationsRequest(topic); } diff --git a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp index c5b28646c..d30013735 100644 --- a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp +++ b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp @@ -29,12 +29,10 @@ namespace uprotocol::core::usubscription::v3 { class RequestBuilderTest : public ::testing::Test { private: v1::UUri source_; - v1::UUri wrong_topic_; protected: USubscriptionOptions options_; const v1::UUri& getSource() const { return source_; } - const v1::UUri& getWrongTopic() const { return wrong_topic_; } void SetUp() override { // Create a UUri object for testing @@ -43,17 +41,11 @@ class RequestBuilderTest : public ::testing::Test { source_.set_ue_version_major(SOURCE_UE_VERSION_MAJOR); source_.set_resource_id(SOURCE_RESOURCE_ID); - wrong_topic_.set_authority_name( - "10.0.0.2"); // random different authority - wrong_topic_.set_ue_id(SOURCE_UE_ID); - wrong_topic_.set_ue_version_major(SOURCE_UE_VERSION_MAJOR); - wrong_topic_.set_resource_id(SOURCE_RESOURCE_ID); - options_.permission_level = 2; options_.token = "sample_token"; options_.when_expire = - std::chrono::system_clock::now() + std::chrono::milliseconds(1000); - options_.sample_period_ms = std::chrono::milliseconds(1000); + std::chrono::system_clock::now() + std::chrono::milliseconds(1); + options_.sample_period_ms = std::chrono::seconds(1); options_.subscriber_details = google::protobuf::Any(); options_.subscription_details = google::protobuf::Any(); } @@ -73,58 +65,55 @@ class RequestBuilderTest : public ::testing::Test { }; TEST_F(RequestBuilderTest, BuildSubscriptionRequestWithOptions) { - v1::UUri topic = getSource(); - RequestBuilder builder(options_); + const v1::UUri topic = getSource(); + const RequestBuilder builder(options_); - SubscriptionRequest request = builder.buildSubscriptionRequest(topic); + SubscriptionRequest request; + ASSERT_NO_THROW(request = builder.buildSubscriptionRequest(topic)); // Verify the attributes in the request + //TODO(max) there should probably be some test that explicitely checks data from the options EXPECT_TRUE(request.has_topic()); EXPECT_TRUE(request.has_attributes()); EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); - EXPECT_NE(request.topic().SerializeAsString(), - getWrongTopic().SerializeAsString()); EXPECT_EQ(request.GetTypeName(), "uprotocol.core.usubscription.v3.SubscriptionRequest"); } TEST_F(RequestBuilderTest, BuildUnsubscribeRequest) { - v1::UUri topic = getSource(); - RequestBuilder builder(options_); + const v1::UUri topic = getSource(); + const RequestBuilder builder(options_); - UnsubscribeRequest request = builder.buildUnsubscribeRequest(topic); + UnsubscribeRequest request; + ASSERT_NO_THROW(request = builder.buildUnsubscribeRequest(topic)); // Verify the attributes in the request EXPECT_TRUE(request.has_topic()); EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); - EXPECT_NE(request.topic().SerializeAsString(), - getWrongTopic().SerializeAsString()); EXPECT_EQ(request.GetTypeName(), "uprotocol.core.usubscription.v3.UnsubscribeRequest"); } TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithTopic) { - v1::UUri topic = getSource(); - RequestBuilder builder(options_); + const v1::UUri topic = getSource(); + const RequestBuilder builder(options_); - FetchSubscriptionsRequest request = - builder.buildFetchSubscriptionsRequest(topic); + FetchSubscriptionsRequest request; + ASSERT_NO_THROW(request = builder.buildFetchSubscriptionsRequest(topic)); // Verify the attributes in the request EXPECT_TRUE(request.has_topic()); EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); - EXPECT_NE(request.topic().SerializeAsString(), - getWrongTopic().SerializeAsString()); EXPECT_EQ(request.GetTypeName(), "uprotocol.core.usubscription.v3.FetchSubscriptionsRequest"); } TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithSubscriberInfo) { - SubscriberInfo subscriber; - RequestBuilder builder(options_); + const SubscriberInfo subscriber; + const RequestBuilder builder(options_); - FetchSubscriptionsRequest request = - builder.buildFetchSubscriptionsRequest(subscriber); + FetchSubscriptionsRequest request; + ASSERT_NO_THROW(request =builder.buildFetchSubscriptionsRequest(subscriber)); // Verify the attributes in the request EXPECT_FALSE(request.has_topic()); @@ -133,32 +122,29 @@ TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithSubscriberInfo) { } TEST_F(RequestBuilderTest, BuildFetchSubscribersRequest) { - v1::UUri topic = getSource(); - RequestBuilder builder(options_); + const v1::UUri topic = getSource(); + const RequestBuilder builder(options_); - FetchSubscribersRequest request = - builder.buildFetchSubscribersRequest(topic); + FetchSubscribersRequest request; + ASSERT_NO_THROW(request = builder.buildFetchSubscribersRequest(topic)); // Verify the attributes in the request EXPECT_TRUE(request.has_topic()); EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); - EXPECT_NE(request.topic().SerializeAsString(), - getWrongTopic().SerializeAsString()); EXPECT_EQ(request.GetTypeName(), "uprotocol.core.usubscription.v3.FetchSubscribersRequest"); } TEST_F(RequestBuilderTest, BuildNotificationsRequest) { - v1::UUri topic = getSource(); - RequestBuilder builder(options_); + const v1::UUri topic = getSource(); + const RequestBuilder builder(options_); - NotificationsRequest request = builder.buildNotificationsRequest(topic); + NotificationsRequest request; + ASSERT_NO_THROW(request = builder.buildNotificationsRequest(topic)); // Verify the attributes in the request EXPECT_TRUE(request.has_topic()); EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); - EXPECT_NE(request.topic().SerializeAsString(), - getWrongTopic().SerializeAsString()); EXPECT_EQ(request.GetTypeName(), "uprotocol.core.usubscription.v3.NotificationsRequest"); } diff --git a/test/coverage/client/usubscription/v3/USubscriptionUUriBuilderTest.cpp b/test/coverage/client/usubscription/v3/USubscriptionUUriBuilderTest.cpp index fd623bc58..082d16d1d 100644 --- a/test/coverage/client/usubscription/v3/USubscriptionUUriBuilderTest.cpp +++ b/test/coverage/client/usubscription/v3/USubscriptionUUriBuilderTest.cpp @@ -21,20 +21,14 @@ namespace uprotocol::core::usubscription::v3 { class USubscriptionUUriBuilderTest : public ::testing::Test { private: v1::UUri expected_uri_; - v1::UUri wrong_uri_; protected: v1::UUri getExpectedUri() const { return expected_uri_; } - v1::UUri getWrongUri() const { return wrong_uri_; } + void SetUp() override { expected_uri_.set_authority_name("core.usubscription"); expected_uri_.set_ue_id(0); expected_uri_.set_ue_version_major(3); - - wrong_uri_.set_authority_name("core.usubscription_wrong"); - wrong_uri_.set_ue_id(1); - wrong_uri_.set_ue_version_major(1); - wrong_uri_.set_resource_id(1); } void TearDown() override {} @@ -44,14 +38,12 @@ TEST_F(USubscriptionUUriBuilderTest, GetServiceUriWithResourceId) { // Example test case for building a subscription UUri auto expected_uri = getExpectedUri(); expected_uri.set_resource_id(RESOURCE_ID_TEST); - USubscriptionUUriBuilder builder; - v1::UUri actual_uri = builder.getServiceUriWithResourceId(RESOURCE_ID_TEST); + const USubscriptionUUriBuilder builder; + const v1::UUri actual_uri = builder.getServiceUriWithResourceId(RESOURCE_ID_TEST); EXPECT_TRUE(actual_uri.IsInitialized()); EXPECT_EQ(actual_uri.GetTypeName(), "uprotocol.v1.UUri"); EXPECT_EQ(actual_uri.SerializeAsString(), expected_uri.SerializeAsString()); - EXPECT_NE(actual_uri.SerializeAsString(), - getWrongUri().SerializeAsString()); } TEST_F(USubscriptionUUriBuilderTest, GetNotificationUri) { @@ -62,8 +54,6 @@ TEST_F(USubscriptionUUriBuilderTest, GetNotificationUri) { EXPECT_TRUE(actual_uri.IsInitialized()); EXPECT_EQ(actual_uri.GetTypeName(), "uprotocol.v1.UUri"); EXPECT_EQ(actual_uri.SerializeAsString(), expected_uri.SerializeAsString()); - EXPECT_NE(actual_uri.SerializeAsString(), - getWrongUri().SerializeAsString()); } } // namespace uprotocol::core::usubscription::v3 From 584fac6a634f1b5ec350b8d8c973399c1313b2bd Mon Sep 17 00:00:00 2001 From: Max Date: Thu, 29 May 2025 13:59:46 +0200 Subject: [PATCH 097/105] added more tests --- .../client/usubscription/v3/RequestBuilder.h | 8 + .../usubscription/v3/RequestBuilder.cpp | 6 + .../v3/RpcClientUSubscriptionTest.cpp | 290 +++++++++++++++++- 3 files changed, 295 insertions(+), 9 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RequestBuilder.h b/include/up-cpp/client/usubscription/v3/RequestBuilder.h index ed75df836..f07ba1b53 100644 --- a/include/up-cpp/client/usubscription/v3/RequestBuilder.h +++ b/include/up-cpp/client/usubscription/v3/RequestBuilder.h @@ -42,6 +42,8 @@ struct USubscriptionOptions { /// This struct facilitates the construction of requests based on /// `USubscriptionOptions`, providing methods to build different requests. struct RequestBuilder { + + /// @brief Constructs a RequestBuilder with the given subscription options. /// /// @param options Subscription options to configure the requests. Defaults @@ -49,6 +51,12 @@ struct RequestBuilder { explicit RequestBuilder(USubscriptionOptions options = {}) : options_(std::move(options)) {} + /// @brief Sets the permission level for the requests build by the builder + /// + /// @param permission_level to be set + /// @return returns a reference to the builder struct to allow chaining + RequestBuilder& setPremissionLevel(uint32_t permission_level); + /// @brief Builds a subscription request for a given topic. /// /// @param topic The `v1::UUri` representing the topic for the subscription. diff --git a/src/client/usubscription/v3/RequestBuilder.cpp b/src/client/usubscription/v3/RequestBuilder.cpp index 3e36c3b8c..c0cf1084b 100644 --- a/src/client/usubscription/v3/RequestBuilder.cpp +++ b/src/client/usubscription/v3/RequestBuilder.cpp @@ -24,6 +24,12 @@ SubscriptionRequest RequestBuilder::buildSubscriptionRequest( return utils::ProtoConverter::BuildSubscriptionRequest(topic, attributes); } +RequestBuilder& RequestBuilder::setPremissionLevel(uint32_t permission_level) { + options_.permission_level = permission_level; + return *this; +} + + UnsubscribeRequest RequestBuilder::buildUnsubscribeRequest( const v1::UUri& topic) const { return utils::ProtoConverter::BuildUnSubscribeRequest(topic); diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp index c01703a78..718d5d167 100644 --- a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -21,6 +21,10 @@ namespace { constexpr uint32_t UE_VERSION_MAJOR = 3; constexpr uint32_t CLIENT_UE_ID = 23492; +constexpr int ITERATIONS_TILL_TIMEOUT = 10; +constexpr std::chrono::milliseconds MILLISECONDS_PER_ITERATION = + std::chrono::milliseconds(50); + class RpcClientUSubscriptionTest : public testing::Test { protected: // Run once per TEST_F.s @@ -96,6 +100,10 @@ class RpcClientUSubscriptionTest : public testing::Test { ~RpcClientUSubscriptionTest() override = default; }; +// +//Tests for subscribe method +// + TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoPayload) { bool server_callback_executed = false; SubscriptionRequest server_capture; @@ -138,9 +146,6 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoPayload) { // wait to give the client time to send the request. Otherwise this would // cause a race condition - constexpr int ITERATIONS_TILL_TIMEOUT = 10; - constexpr std::chrono::milliseconds MILLISECONDS_PER_ITERATION = - std::chrono::milliseconds(100); int counter = ITERATIONS_TILL_TIMEOUT; while (counter > 0 && getClientTransport()->getSendCount() == 0) { counter--; @@ -209,9 +214,6 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoAnyPayload) { // wait to give the client time to send the request. Otherwise this would // cause a race condition - constexpr int ITERATIONS_TILL_TIMEOUT = 10; - constexpr std::chrono::milliseconds MILLISECONDS_PER_ITERATION = - std::chrono::milliseconds(100); int counter = ITERATIONS_TILL_TIMEOUT; while (counter > 0 && getClientTransport()->getSendCount() == 0) { counter--; @@ -286,9 +288,6 @@ TEST_F(RpcClientUSubscriptionTest, // wait to give the client time to send the request. Otherwise this would // cause a race condition - constexpr int ITERATIONS_TILL_TIMEOUT = 10; - constexpr std::chrono::milliseconds MILLISECONDS_PER_ITERATION = - std::chrono::milliseconds(100); int counter = ITERATIONS_TILL_TIMEOUT; while (counter > 0 && getClientTransport()->getSendCount() == 0) { counter--; @@ -311,4 +310,277 @@ TEST_F(RpcClientUSubscriptionTest, .has_value()); // Should fail because the topics do not match } +//////////////////////////////// +//Tests for unsubscribe method// +//////////////////////////////// + +using UnsubscibeRequest = uprotocol::core::usubscription::v3::UnsubscribeRequest; +using UnsubscribeResponse = uprotocol::core::usubscription::v3::UnsubscribeResponse; + +TEST_F(RpcClientUSubscriptionTest, UnsubscribeRoundtripWithValidProtoPayload) { + bool server_callback_executed = false; + UnsubscibeRequest server_capture; + UnsubscribeResponse server_response; + auto server_or_status = uprotocol::communication::RpcServer::create( + getServerTransport(), getServerMethodUuri(), + [&server_callback_executed, &server_capture, + &server_response](const UMessage& message) -> std::optional { + server_callback_executed = true; + auto request_or_status = + ProtoConverter::extractFromProtobuf( + message); + if (!request_or_status.has_value()) { + return std::nullopt; + } + server_capture = request_or_status.value(); + Payload response_payload(server_response); + return response_payload; + }, + uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF); + + ASSERT_TRUE(server_or_status.has_value()); + ASSERT_NE(server_or_status.value(), nullptr); + EXPECT_TRUE(getServerTransport()->getListener()); + + auto client = uprotocol::core::usubscription::v3::RpcClientUSubscription( + getClientTransport()); + + const auto unsubscribe_request = + getRequestBuilder().buildUnsubscribeRequest(getSubscriptionTopic()); + + auto response_or_status_future = + std::async(std::launch::async, + [&client, &unsubscribe_request]() + -> uprotocol::utils::Expected { + return client.unsubscribe(unsubscribe_request); + }); + + // wait to give the client time to send the request. Otherwise this would + // cause a race condition + int counter = ITERATIONS_TILL_TIMEOUT; + while (counter > 0 && getClientTransport()->getSendCount() == 0) { + counter--; + std::this_thread::sleep_for(MILLISECONDS_PER_ITERATION); + } + ASSERT_EQ(getClientTransport()->getSendCount(), 1); + EXPECT_TRUE(getClientTransport()->getListener()); + + (*getServerTransport()->getListener())(getClientTransport()->getMessage()); + EXPECT_TRUE(server_callback_executed); + EXPECT_EQ(server_capture.SerializeAsString(), + unsubscribe_request.SerializeAsString()); + + getClientTransport()->mockMessage(getServerTransport()->getMessage()); + EXPECT_TRUE(getClientTransport()->getListener()); + EXPECT_EQ(getClientTransport()->getSendCount(), 1); + auto response_or_status = response_or_status_future.get(); + ASSERT_TRUE(response_or_status.has_value()); + EXPECT_EQ(response_or_status.value().SerializeAsString(), + server_response.SerializeAsString()); +} + +TEST_F(RpcClientUSubscriptionTest, UnsubscribeRoundtripWithValidProtoAnyPayload) { + bool server_callback_executed = false; + UnsubscibeRequest server_capture; + UnsubscribeResponse server_response; + auto server_or_status = uprotocol::communication::RpcServer::create( + getServerTransport(), getServerMethodUuri(), + [&server_callback_executed, &server_capture, + &server_response](const UMessage& message) -> std::optional { + server_callback_executed = true; + auto request_or_status = + ProtoConverter::extractFromProtobuf( + message); + if (!request_or_status.has_value()) { + return std::nullopt; + } + server_capture = request_or_status.value(); + google::protobuf::Any any; + if (!any.PackFrom(server_response)) { + return std::nullopt; + } + Payload response_payload(any); + return response_payload; + }, + uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY); + + ASSERT_TRUE(server_or_status.has_value()); + ASSERT_NE(server_or_status.value(), nullptr); + EXPECT_TRUE(getServerTransport()->getListener()); + + auto client = uprotocol::core::usubscription::v3::RpcClientUSubscription( + getClientTransport()); + + const auto unsubscribe_request = + getRequestBuilder().buildUnsubscribeRequest(getSubscriptionTopic()); + + auto response_or_status_future = + std::async(std::launch::async, + [&client, &unsubscribe_request]() + -> uprotocol::utils::Expected { + return client.unsubscribe(unsubscribe_request); + }); + + // wait to give the client time to send the request. Otherwise this would + // cause a race condition + int counter = ITERATIONS_TILL_TIMEOUT; + while (counter > 0 && getClientTransport()->getSendCount() == 0) { + counter--; + std::this_thread::sleep_for(MILLISECONDS_PER_ITERATION); + } + ASSERT_EQ(getClientTransport()->getSendCount(), 1); + EXPECT_TRUE(getClientTransport()->getListener()); + + (*getServerTransport()->getListener())(getClientTransport()->getMessage()); + EXPECT_TRUE(server_callback_executed); + EXPECT_EQ(server_capture.SerializeAsString(), + unsubscribe_request.SerializeAsString()); + + getClientTransport()->mockMessage(getServerTransport()->getMessage()); + EXPECT_TRUE(getClientTransport()->getListener()); + EXPECT_EQ(getClientTransport()->getSendCount(), 1); + auto response_or_status = response_or_status_future.get(); + ASSERT_TRUE(response_or_status.has_value()); + EXPECT_EQ(response_or_status.value().SerializeAsString(), + server_response.SerializeAsString()); +} + +//////////////////////////////// +//Tests for fetch_subscribers method// +//////////////////////////////// + +using FetchSubscribersRequest = uprotocol::core::usubscription::v3::FetchSubscribersRequest; +using FetchSubscribersResponse = uprotocol::core::usubscription::v3::FetchSubscribersResponse; + +TEST_F(RpcClientUSubscriptionTest, fetchSubscriberRoundtripWithValidProtoPayload) { + bool server_callback_executed = false; + FetchSubscribersRequest server_capture; + FetchSubscribersResponse server_response; + auto server_or_status = uprotocol::communication::RpcServer::create( + getServerTransport(), getServerMethodUuri(), + [&server_callback_executed, &server_capture, + &server_response](const UMessage& message) -> std::optional { + server_callback_executed = true; + auto request_or_status = + ProtoConverter::extractFromProtobuf( + message); + if (!request_or_status.has_value()) { + return std::nullopt; + } + server_capture = request_or_status.value(); + Payload response_payload(server_response); + return response_payload; + }, + uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF); + + ASSERT_TRUE(server_or_status.has_value()); + ASSERT_NE(server_or_status.value(), nullptr); + EXPECT_TRUE(getServerTransport()->getListener()); + + auto client = uprotocol::core::usubscription::v3::RpcClientUSubscription( + getClientTransport()); + + const auto fetch_subscribers_request = + getRequestBuilder().buildFetchSubscribersRequest(getSubscriptionTopic()); + + auto response_or_status_future = + std::async(std::launch::async, + [&client, &fetch_subscribers_request]() + -> uprotocol::utils::Expected { + return client.fetch_subscribers(fetch_subscribers_request); + }); + + // wait to give the client time to send the request. Otherwise this would + // cause a race condition + int counter = ITERATIONS_TILL_TIMEOUT; + while (counter > 0 && getClientTransport()->getSendCount() == 0) { + counter--; + std::this_thread::sleep_for(MILLISECONDS_PER_ITERATION); + } + ASSERT_EQ(getClientTransport()->getSendCount(), 1); + EXPECT_TRUE(getClientTransport()->getListener()); + + (*getServerTransport()->getListener())(getClientTransport()->getMessage()); + EXPECT_TRUE(server_callback_executed); + EXPECT_EQ(server_capture.SerializeAsString(), + fetch_subscribers_request.SerializeAsString()); + + getClientTransport()->mockMessage(getServerTransport()->getMessage()); + EXPECT_TRUE(getClientTransport()->getListener()); + EXPECT_EQ(getClientTransport()->getSendCount(), 1); + auto response_or_status = response_or_status_future.get(); + ASSERT_TRUE(response_or_status.has_value()); + EXPECT_EQ(response_or_status.value().SerializeAsString(), + server_response.SerializeAsString()); +} + +TEST_F(RpcClientUSubscriptionTest, FetchSubscriberRoundtripWithValidProtoAnyPayload) { + bool server_callback_executed = false; + FetchSubscribersRequest server_capture; + FetchSubscribersResponse server_response; + auto server_or_status = uprotocol::communication::RpcServer::create( + getServerTransport(), getServerMethodUuri(), + [&server_callback_executed, &server_capture, + &server_response](const UMessage& message) -> std::optional { + server_callback_executed = true; + auto request_or_status = + ProtoConverter::extractFromProtobuf( + message); + if (!request_or_status.has_value()) { + return std::nullopt; + } + server_capture = request_or_status.value(); + google::protobuf::Any any; + if (!any.PackFrom(server_response)) { + return std::nullopt; + } + Payload response_payload(any); + return response_payload; + }, + uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY); + + ASSERT_TRUE(server_or_status.has_value()); + ASSERT_NE(server_or_status.value(), nullptr); + EXPECT_TRUE(getServerTransport()->getListener()); + + auto client = uprotocol::core::usubscription::v3::RpcClientUSubscription( + getClientTransport()); + + const auto fetch_subscribers_request = + getRequestBuilder().buildFetchSubscribersRequest(getSubscriptionTopic()); + + auto response_or_status_future = + std::async(std::launch::async, + [&client, &fetch_subscribers_request]() + -> uprotocol::utils::Expected { + return client.fetch_subscribers(fetch_subscribers_request); + }); + + // wait to give the client time to send the request. Otherwise this would + // cause a race condition + int counter = ITERATIONS_TILL_TIMEOUT; + while (counter > 0 && getClientTransport()->getSendCount() == 0) { + counter--; + std::this_thread::sleep_for(MILLISECONDS_PER_ITERATION); + } + ASSERT_EQ(getClientTransport()->getSendCount(), 1); + EXPECT_TRUE(getClientTransport()->getListener()); + + (*getServerTransport()->getListener())(getClientTransport()->getMessage()); + EXPECT_TRUE(server_callback_executed); + EXPECT_EQ(server_capture.SerializeAsString(), + fetch_subscribers_request.SerializeAsString()); + + getClientTransport()->mockMessage(getServerTransport()->getMessage()); + EXPECT_TRUE(getClientTransport()->getListener()); + EXPECT_EQ(getClientTransport()->getSendCount(), 1); + auto response_or_status = response_or_status_future.get(); + ASSERT_TRUE(response_or_status.has_value()); + EXPECT_EQ(response_or_status.value().SerializeAsString(), + server_response.SerializeAsString()); +} }; // namespace From 0c60d3fd12b216b4d6d4517934ccac3eea7e33eb Mon Sep 17 00:00:00 2001 From: Max Date: Thu, 29 May 2025 14:28:05 +0200 Subject: [PATCH 098/105] added more tests --- .../client/usubscription/v3/RequestBuilder.h | 7 +- .../usubscription/v3/RequestBuilder.cpp | 1 - .../usubscription/v3/RequestBuilderTest.cpp | 6 +- .../v3/RpcClientUSubscriptionTest.cpp | 495 ++++++++++++++++-- .../v3/USubscriptionUUriBuilderTest.cpp | 3 +- 5 files changed, 472 insertions(+), 40 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RequestBuilder.h b/include/up-cpp/client/usubscription/v3/RequestBuilder.h index f07ba1b53..ad16392d8 100644 --- a/include/up-cpp/client/usubscription/v3/RequestBuilder.h +++ b/include/up-cpp/client/usubscription/v3/RequestBuilder.h @@ -42,8 +42,6 @@ struct USubscriptionOptions { /// This struct facilitates the construction of requests based on /// `USubscriptionOptions`, providing methods to build different requests. struct RequestBuilder { - - /// @brief Constructs a RequestBuilder with the given subscription options. /// /// @param options Subscription options to configure the requests. Defaults @@ -96,7 +94,7 @@ struct RequestBuilder { /// /// @return An `FetchSubscribersRequest` configured for the specified topic. FetchSubscribersRequest buildFetchSubscribersRequest( - const v1::UUri& topic) const ; + const v1::UUri& topic) const; /// @brief Build notifications request for a given topic. Subscription /// change @@ -107,8 +105,7 @@ struct RequestBuilder { /// for/from. /// /// @return An `NotificationsRequest` configured for the specified topic. - NotificationsRequest buildNotificationsRequest( - const v1::UUri& topic) const; + NotificationsRequest buildNotificationsRequest(const v1::UUri& topic) const; private: USubscriptionOptions options_; ///< Options used to configure the requests. diff --git a/src/client/usubscription/v3/RequestBuilder.cpp b/src/client/usubscription/v3/RequestBuilder.cpp index c0cf1084b..7e30b4cbc 100644 --- a/src/client/usubscription/v3/RequestBuilder.cpp +++ b/src/client/usubscription/v3/RequestBuilder.cpp @@ -29,7 +29,6 @@ RequestBuilder& RequestBuilder::setPremissionLevel(uint32_t permission_level) { return *this; } - UnsubscribeRequest RequestBuilder::buildUnsubscribeRequest( const v1::UUri& topic) const { return utils::ProtoConverter::BuildUnSubscribeRequest(topic); diff --git a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp index d30013735..6b5c0d50e 100644 --- a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp +++ b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp @@ -72,7 +72,8 @@ TEST_F(RequestBuilderTest, BuildSubscriptionRequestWithOptions) { ASSERT_NO_THROW(request = builder.buildSubscriptionRequest(topic)); // Verify the attributes in the request - //TODO(max) there should probably be some test that explicitely checks data from the options + // TODO(max) there should probably be some test that explicitely checks data + // from the options EXPECT_TRUE(request.has_topic()); EXPECT_TRUE(request.has_attributes()); EXPECT_EQ(request.topic().SerializeAsString(), topic.SerializeAsString()); @@ -113,7 +114,8 @@ TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithSubscriberInfo) { const RequestBuilder builder(options_); FetchSubscriptionsRequest request; - ASSERT_NO_THROW(request =builder.buildFetchSubscriptionsRequest(subscriber)); + ASSERT_NO_THROW(request = + builder.buildFetchSubscriptionsRequest(subscriber)); // Verify the attributes in the request EXPECT_FALSE(request.has_topic()); diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp index 718d5d167..2703f459a 100644 --- a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -23,7 +23,7 @@ constexpr uint32_t CLIENT_UE_ID = 23492; constexpr int ITERATIONS_TILL_TIMEOUT = 10; constexpr std::chrono::milliseconds MILLISECONDS_PER_ITERATION = - std::chrono::milliseconds(50); + std::chrono::milliseconds(50); class RpcClientUSubscriptionTest : public testing::Test { protected: @@ -101,7 +101,7 @@ class RpcClientUSubscriptionTest : public testing::Test { }; // -//Tests for subscribe method +// Tests for subscribe method // TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoPayload) { @@ -311,11 +311,13 @@ TEST_F(RpcClientUSubscriptionTest, } //////////////////////////////// -//Tests for unsubscribe method// +// Tests for unsubscribe method// //////////////////////////////// -using UnsubscibeRequest = uprotocol::core::usubscription::v3::UnsubscribeRequest; -using UnsubscribeResponse = uprotocol::core::usubscription::v3::UnsubscribeResponse; +using UnsubscibeRequest = + uprotocol::core::usubscription::v3::UnsubscribeRequest; +using UnsubscribeResponse = + uprotocol::core::usubscription::v3::UnsubscribeResponse; TEST_F(RpcClientUSubscriptionTest, UnsubscribeRoundtripWithValidProtoPayload) { bool server_callback_executed = false; @@ -327,8 +329,7 @@ TEST_F(RpcClientUSubscriptionTest, UnsubscribeRoundtripWithValidProtoPayload) { &server_response](const UMessage& message) -> std::optional { server_callback_executed = true; auto request_or_status = - ProtoConverter::extractFromProtobuf( - message); + ProtoConverter::extractFromProtobuf(message); if (!request_or_status.has_value()) { return std::nullopt; } @@ -380,7 +381,8 @@ TEST_F(RpcClientUSubscriptionTest, UnsubscribeRoundtripWithValidProtoPayload) { server_response.SerializeAsString()); } -TEST_F(RpcClientUSubscriptionTest, UnsubscribeRoundtripWithValidProtoAnyPayload) { +TEST_F(RpcClientUSubscriptionTest, + UnsubscribeRoundtripWithValidProtoAnyPayload) { bool server_callback_executed = false; UnsubscibeRequest server_capture; UnsubscribeResponse server_response; @@ -390,8 +392,7 @@ TEST_F(RpcClientUSubscriptionTest, UnsubscribeRoundtripWithValidProtoAnyPayload) &server_response](const UMessage& message) -> std::optional { server_callback_executed = true; auto request_or_status = - ProtoConverter::extractFromProtobuf( - message); + ProtoConverter::extractFromProtobuf(message); if (!request_or_status.has_value()) { return std::nullopt; } @@ -448,13 +449,16 @@ TEST_F(RpcClientUSubscriptionTest, UnsubscribeRoundtripWithValidProtoAnyPayload) } //////////////////////////////// -//Tests for fetch_subscribers method// +// Tests for fetch_subscribers method// //////////////////////////////// -using FetchSubscribersRequest = uprotocol::core::usubscription::v3::FetchSubscribersRequest; -using FetchSubscribersResponse = uprotocol::core::usubscription::v3::FetchSubscribersResponse; +using FetchSubscribersRequest = + uprotocol::core::usubscription::v3::FetchSubscribersRequest; +using FetchSubscribersResponse = + uprotocol::core::usubscription::v3::FetchSubscribersResponse; -TEST_F(RpcClientUSubscriptionTest, fetchSubscriberRoundtripWithValidProtoPayload) { +TEST_F(RpcClientUSubscriptionTest, + fetchSubscriberRoundtripWithValidProtoPayload) { bool server_callback_executed = false; FetchSubscribersRequest server_capture; FetchSubscribersResponse server_response; @@ -483,15 +487,16 @@ TEST_F(RpcClientUSubscriptionTest, fetchSubscriberRoundtripWithValidProtoPayload getClientTransport()); const auto fetch_subscribers_request = - getRequestBuilder().buildFetchSubscribersRequest(getSubscriptionTopic()); + getRequestBuilder().buildFetchSubscribersRequest( + getSubscriptionTopic()); - auto response_or_status_future = - std::async(std::launch::async, - [&client, &fetch_subscribers_request]() - -> uprotocol::utils::Expected { - return client.fetch_subscribers(fetch_subscribers_request); - }); + auto response_or_status_future = std::async( + std::launch::async, + [&client, &fetch_subscribers_request]() + -> uprotocol::utils::Expected { + return client.fetch_subscribers(fetch_subscribers_request); + }); // wait to give the client time to send the request. Otherwise this would // cause a race condition @@ -517,7 +522,8 @@ TEST_F(RpcClientUSubscriptionTest, fetchSubscriberRoundtripWithValidProtoPayload server_response.SerializeAsString()); } -TEST_F(RpcClientUSubscriptionTest, FetchSubscriberRoundtripWithValidProtoAnyPayload) { +TEST_F(RpcClientUSubscriptionTest, + FetchSubscriberRoundtripWithValidProtoAnyPayload) { bool server_callback_executed = false; FetchSubscribersRequest server_capture; FetchSubscribersResponse server_response; @@ -550,15 +556,159 @@ TEST_F(RpcClientUSubscriptionTest, FetchSubscriberRoundtripWithValidProtoAnyPayl getClientTransport()); const auto fetch_subscribers_request = - getRequestBuilder().buildFetchSubscribersRequest(getSubscriptionTopic()); + getRequestBuilder().buildFetchSubscribersRequest( + getSubscriptionTopic()); - auto response_or_status_future = - std::async(std::launch::async, - [&client, &fetch_subscribers_request]() - -> uprotocol::utils::Expected { - return client.fetch_subscribers(fetch_subscribers_request); - }); + auto response_or_status_future = std::async( + std::launch::async, + [&client, &fetch_subscribers_request]() + -> uprotocol::utils::Expected { + return client.fetch_subscribers(fetch_subscribers_request); + }); + + // wait to give the client time to send the request. Otherwise this would + // cause a race condition + int counter = ITERATIONS_TILL_TIMEOUT; + while (counter > 0 && getClientTransport()->getSendCount() == 0) { + counter--; + std::this_thread::sleep_for(MILLISECONDS_PER_ITERATION); + } + ASSERT_EQ(getClientTransport()->getSendCount(), 1); + EXPECT_TRUE(getClientTransport()->getListener()); + + (*getServerTransport()->getListener())(getClientTransport()->getMessage()); + EXPECT_TRUE(server_callback_executed); + EXPECT_EQ(server_capture.SerializeAsString(), + fetch_subscribers_request.SerializeAsString()); + + getClientTransport()->mockMessage(getServerTransport()->getMessage()); + EXPECT_TRUE(getClientTransport()->getListener()); + EXPECT_EQ(getClientTransport()->getSendCount(), 1); + auto response_or_status = response_or_status_future.get(); + ASSERT_TRUE(response_or_status.has_value()); + EXPECT_EQ(response_or_status.value().SerializeAsString(), + server_response.SerializeAsString()); +} + +//////////////////////////////// +// Tests for fetch_subscriptions method// +//////////////////////////////// + +using FetchSubscriptionsRequest = + uprotocol::core::usubscription::v3::FetchSubscriptionsRequest; +using FetchSubscriptionsResponse = + uprotocol::core::usubscription::v3::FetchSubscriptionsResponse; + +TEST_F(RpcClientUSubscriptionTest, + fetchSubscriptionsRoundtripWithValidProtoPayload) { + bool server_callback_executed = false; + FetchSubscriptionsRequest server_capture; + FetchSubscriptionsResponse server_response; + auto server_or_status = uprotocol::communication::RpcServer::create( + getServerTransport(), getServerMethodUuri(), + [&server_callback_executed, &server_capture, + &server_response](const UMessage& message) -> std::optional { + server_callback_executed = true; + auto request_or_status = + ProtoConverter::extractFromProtobuf( + message); + if (!request_or_status.has_value()) { + return std::nullopt; + } + server_capture = request_or_status.value(); + Payload response_payload(server_response); + return response_payload; + }, + uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF); + + ASSERT_TRUE(server_or_status.has_value()); + ASSERT_NE(server_or_status.value(), nullptr); + EXPECT_TRUE(getServerTransport()->getListener()); + + auto client = uprotocol::core::usubscription::v3::RpcClientUSubscription( + getClientTransport()); + + const uprotocol::core::usubscription::v3::SubscriberInfo subscriber_info; + const auto fetch_subscriptions_request = + getRequestBuilder().buildFetchSubscriptionsRequest(subscriber_info); + + auto response_or_status_future = std::async( + std::launch::async, + [&client, &fetch_subscriptions_request]() + -> uprotocol::utils::Expected { + return client.fetch_subscriptions(fetch_subscriptions_request); + }); + + // wait to give the client time to send the request. Otherwise this would + // cause a race condition + int counter = ITERATIONS_TILL_TIMEOUT; + while (counter > 0 && getClientTransport()->getSendCount() == 0) { + counter--; + std::this_thread::sleep_for(MILLISECONDS_PER_ITERATION); + } + ASSERT_EQ(getClientTransport()->getSendCount(), 1); + EXPECT_TRUE(getClientTransport()->getListener()); + + (*getServerTransport()->getListener())(getClientTransport()->getMessage()); + EXPECT_TRUE(server_callback_executed); + EXPECT_EQ(server_capture.SerializeAsString(), + fetch_subscriptions_request.SerializeAsString()); + + getClientTransport()->mockMessage(getServerTransport()->getMessage()); + EXPECT_TRUE(getClientTransport()->getListener()); + EXPECT_EQ(getClientTransport()->getSendCount(), 1); + auto response_or_status = response_or_status_future.get(); + ASSERT_TRUE(response_or_status.has_value()); + EXPECT_EQ(response_or_status.value().SerializeAsString(), + server_response.SerializeAsString()); +} + +TEST_F(RpcClientUSubscriptionTest, + fetchSubscriptionRoundtripWithValidProtoAnyPayload) { + bool server_callback_executed = false; + FetchSubscriptionsRequest server_capture; + FetchSubscriptionsResponse server_response; + auto server_or_status = uprotocol::communication::RpcServer::create( + getServerTransport(), getServerMethodUuri(), + [&server_callback_executed, &server_capture, + &server_response](const UMessage& message) -> std::optional { + server_callback_executed = true; + auto request_or_status = + ProtoConverter::extractFromProtobuf( + message); + if (!request_or_status.has_value()) { + return std::nullopt; + } + server_capture = request_or_status.value(); + google::protobuf::Any any; + if (!any.PackFrom(server_response)) { + return std::nullopt; + } + Payload response_payload(any); + return response_payload; + }, + uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY); + + ASSERT_TRUE(server_or_status.has_value()); + ASSERT_NE(server_or_status.value(), nullptr); + EXPECT_TRUE(getServerTransport()->getListener()); + + auto client = uprotocol::core::usubscription::v3::RpcClientUSubscription( + getClientTransport()); + + const uprotocol::core::usubscription::v3::SubscriberInfo subscriber_info; + const auto fetch_subscribers_request = + getRequestBuilder().buildFetchSubscriptionsRequest(subscriber_info); + + auto response_or_status_future = std::async( + std::launch::async, + [&client, &fetch_subscribers_request]() + -> uprotocol::utils::Expected { + return client.fetch_subscriptions(fetch_subscribers_request); + }); // wait to give the client time to send the request. Otherwise this would // cause a race condition @@ -583,4 +733,287 @@ TEST_F(RpcClientUSubscriptionTest, FetchSubscriberRoundtripWithValidProtoAnyPayl EXPECT_EQ(response_or_status.value().SerializeAsString(), server_response.SerializeAsString()); } + +//////////////////////////////// +// Tests for register_for_notification method// +//////////////////////////////// + +using NotificationsRequest = + uprotocol::core::usubscription::v3::NotificationsRequest; +using NotificationsResponse = + uprotocol::core::usubscription::v3::NotificationsResponse; + +TEST_F(RpcClientUSubscriptionTest, + registerNotificationRoundtripWithValidProtoPayload) { + bool server_callback_executed = false; + NotificationsRequest server_capture; + NotificationsResponse server_response; + auto server_or_status = uprotocol::communication::RpcServer::create( + getServerTransport(), getServerMethodUuri(), + [&server_callback_executed, &server_capture, + &server_response](const UMessage& message) -> std::optional { + server_callback_executed = true; + auto request_or_status = + ProtoConverter::extractFromProtobuf( + message); + if (!request_or_status.has_value()) { + return std::nullopt; + } + server_capture = request_or_status.value(); + Payload response_payload(server_response); + return response_payload; + }, + uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF); + + ASSERT_TRUE(server_or_status.has_value()); + ASSERT_NE(server_or_status.value(), nullptr); + EXPECT_TRUE(getServerTransport()->getListener()); + + auto client = uprotocol::core::usubscription::v3::RpcClientUSubscription( + getClientTransport()); + + const auto notifications_request = + getRequestBuilder().buildNotificationsRequest(getSubscriptionTopic()); + + auto response_or_status_future = std::async( + std::launch::async, + [&client, ¬ifications_request]() + -> uprotocol::utils::Expected { + return client.register_for_notifications(notifications_request); + }); + + // wait to give the client time to send the request. Otherwise this would + // cause a race condition + int counter = ITERATIONS_TILL_TIMEOUT; + while (counter > 0 && getClientTransport()->getSendCount() == 0) { + counter--; + std::this_thread::sleep_for(MILLISECONDS_PER_ITERATION); + } + ASSERT_EQ(getClientTransport()->getSendCount(), 1); + EXPECT_TRUE(getClientTransport()->getListener()); + + (*getServerTransport()->getListener())(getClientTransport()->getMessage()); + EXPECT_TRUE(server_callback_executed); + EXPECT_EQ(server_capture.SerializeAsString(), + notifications_request.SerializeAsString()); + + getClientTransport()->mockMessage(getServerTransport()->getMessage()); + EXPECT_TRUE(getClientTransport()->getListener()); + EXPECT_EQ(getClientTransport()->getSendCount(), 1); + auto response_or_status = response_or_status_future.get(); + ASSERT_TRUE(response_or_status.has_value()); + EXPECT_EQ(response_or_status.value().SerializeAsString(), + server_response.SerializeAsString()); +} + +TEST_F(RpcClientUSubscriptionTest, + registerNotificationRoundtripWithValidProtoAnyPayload) { + bool server_callback_executed = false; + NotificationsRequest server_capture; + NotificationsResponse server_response; + auto server_or_status = uprotocol::communication::RpcServer::create( + getServerTransport(), getServerMethodUuri(), + [&server_callback_executed, &server_capture, + &server_response](const UMessage& message) -> std::optional { + server_callback_executed = true; + auto request_or_status = + ProtoConverter::extractFromProtobuf( + message); + if (!request_or_status.has_value()) { + return std::nullopt; + } + server_capture = request_or_status.value(); + google::protobuf::Any any; + if (!any.PackFrom(server_response)) { + return std::nullopt; + } + Payload response_payload(any); + return response_payload; + }, + uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY); + + ASSERT_TRUE(server_or_status.has_value()); + ASSERT_NE(server_or_status.value(), nullptr); + EXPECT_TRUE(getServerTransport()->getListener()); + + auto client = uprotocol::core::usubscription::v3::RpcClientUSubscription( + getClientTransport()); + + const auto notifications_request = + getRequestBuilder().buildNotificationsRequest(getSubscriptionTopic()); + + auto response_or_status_future = std::async( + std::launch::async, + [&client, ¬ifications_request]() + -> uprotocol::utils::Expected { + return client.register_for_notifications(notifications_request); + }); + + // wait to give the client time to send the request. Otherwise this would + // cause a race condition + int counter = ITERATIONS_TILL_TIMEOUT; + while (counter > 0 && getClientTransport()->getSendCount() == 0) { + counter--; + std::this_thread::sleep_for(MILLISECONDS_PER_ITERATION); + } + ASSERT_EQ(getClientTransport()->getSendCount(), 1); + EXPECT_TRUE(getClientTransport()->getListener()); + + (*getServerTransport()->getListener())(getClientTransport()->getMessage()); + EXPECT_TRUE(server_callback_executed); + EXPECT_EQ(server_capture.SerializeAsString(), + notifications_request.SerializeAsString()); + + getClientTransport()->mockMessage(getServerTransport()->getMessage()); + EXPECT_TRUE(getClientTransport()->getListener()); + EXPECT_EQ(getClientTransport()->getSendCount(), 1); + auto response_or_status = response_or_status_future.get(); + ASSERT_TRUE(response_or_status.has_value()); + EXPECT_EQ(response_or_status.value().SerializeAsString(), + server_response.SerializeAsString()); +} + +//////////////////////////////// +// Tests for unregister_for_notification method// +//////////////////////////////// + +using NotificationsRequest = + uprotocol::core::usubscription::v3::NotificationsRequest; +using NotificationsResponse = + uprotocol::core::usubscription::v3::NotificationsResponse; + +TEST_F(RpcClientUSubscriptionTest, + unregisterNotificationRoundtripWithValidProtoPayload) { + bool server_callback_executed = false; + NotificationsRequest server_capture; + NotificationsResponse server_response; + auto server_or_status = uprotocol::communication::RpcServer::create( + getServerTransport(), getServerMethodUuri(), + [&server_callback_executed, &server_capture, + &server_response](const UMessage& message) -> std::optional { + server_callback_executed = true; + auto request_or_status = + ProtoConverter::extractFromProtobuf( + message); + if (!request_or_status.has_value()) { + return std::nullopt; + } + server_capture = request_or_status.value(); + Payload response_payload(server_response); + return response_payload; + }, + uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF); + + ASSERT_TRUE(server_or_status.has_value()); + ASSERT_NE(server_or_status.value(), nullptr); + EXPECT_TRUE(getServerTransport()->getListener()); + + auto client = uprotocol::core::usubscription::v3::RpcClientUSubscription( + getClientTransport()); + + const auto notifications_request = + getRequestBuilder().buildNotificationsRequest(getSubscriptionTopic()); + + auto response_or_status_future = std::async( + std::launch::async, + [&client, ¬ifications_request]() + -> uprotocol::utils::Expected { + return client.unregister_for_notifications(notifications_request); + }); + + // wait to give the client time to send the request. Otherwise this would + // cause a race condition + int counter = ITERATIONS_TILL_TIMEOUT; + while (counter > 0 && getClientTransport()->getSendCount() == 0) { + counter--; + std::this_thread::sleep_for(MILLISECONDS_PER_ITERATION); + } + ASSERT_EQ(getClientTransport()->getSendCount(), 1); + EXPECT_TRUE(getClientTransport()->getListener()); + + (*getServerTransport()->getListener())(getClientTransport()->getMessage()); + EXPECT_TRUE(server_callback_executed); + EXPECT_EQ(server_capture.SerializeAsString(), + notifications_request.SerializeAsString()); + + getClientTransport()->mockMessage(getServerTransport()->getMessage()); + EXPECT_TRUE(getClientTransport()->getListener()); + EXPECT_EQ(getClientTransport()->getSendCount(), 1); + auto response_or_status = response_or_status_future.get(); + ASSERT_TRUE(response_or_status.has_value()); + EXPECT_EQ(response_or_status.value().SerializeAsString(), + server_response.SerializeAsString()); +} + +TEST_F(RpcClientUSubscriptionTest, + unregisterNotificationRoundtripWithValidProtoAnyPayload) { + bool server_callback_executed = false; + NotificationsRequest server_capture; + NotificationsResponse server_response; + auto server_or_status = uprotocol::communication::RpcServer::create( + getServerTransport(), getServerMethodUuri(), + [&server_callback_executed, &server_capture, + &server_response](const UMessage& message) -> std::optional { + server_callback_executed = true; + auto request_or_status = + ProtoConverter::extractFromProtobuf( + message); + if (!request_or_status.has_value()) { + return std::nullopt; + } + server_capture = request_or_status.value(); + google::protobuf::Any any; + if (!any.PackFrom(server_response)) { + return std::nullopt; + } + Payload response_payload(any); + return response_payload; + }, + uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY); + + ASSERT_TRUE(server_or_status.has_value()); + ASSERT_NE(server_or_status.value(), nullptr); + EXPECT_TRUE(getServerTransport()->getListener()); + + auto client = uprotocol::core::usubscription::v3::RpcClientUSubscription( + getClientTransport()); + + const auto notifications_request = + getRequestBuilder().buildNotificationsRequest(getSubscriptionTopic()); + + auto response_or_status_future = std::async( + std::launch::async, + [&client, ¬ifications_request]() + -> uprotocol::utils::Expected { + return client.unregister_for_notifications(notifications_request); + }); + + // wait to give the client time to send the request. Otherwise this would + // cause a race condition + int counter = ITERATIONS_TILL_TIMEOUT; + while (counter > 0 && getClientTransport()->getSendCount() == 0) { + counter--; + std::this_thread::sleep_for(MILLISECONDS_PER_ITERATION); + } + ASSERT_EQ(getClientTransport()->getSendCount(), 1); + EXPECT_TRUE(getClientTransport()->getListener()); + + (*getServerTransport()->getListener())(getClientTransport()->getMessage()); + EXPECT_TRUE(server_callback_executed); + EXPECT_EQ(server_capture.SerializeAsString(), + notifications_request.SerializeAsString()); + + getClientTransport()->mockMessage(getServerTransport()->getMessage()); + EXPECT_TRUE(getClientTransport()->getListener()); + EXPECT_EQ(getClientTransport()->getSendCount(), 1); + auto response_or_status = response_or_status_future.get(); + ASSERT_TRUE(response_or_status.has_value()); + EXPECT_EQ(response_or_status.value().SerializeAsString(), + server_response.SerializeAsString()); +} + }; // namespace diff --git a/test/coverage/client/usubscription/v3/USubscriptionUUriBuilderTest.cpp b/test/coverage/client/usubscription/v3/USubscriptionUUriBuilderTest.cpp index 082d16d1d..c27a62cbb 100644 --- a/test/coverage/client/usubscription/v3/USubscriptionUUriBuilderTest.cpp +++ b/test/coverage/client/usubscription/v3/USubscriptionUUriBuilderTest.cpp @@ -39,7 +39,8 @@ TEST_F(USubscriptionUUriBuilderTest, GetServiceUriWithResourceId) { auto expected_uri = getExpectedUri(); expected_uri.set_resource_id(RESOURCE_ID_TEST); const USubscriptionUUriBuilder builder; - const v1::UUri actual_uri = builder.getServiceUriWithResourceId(RESOURCE_ID_TEST); + const v1::UUri actual_uri = + builder.getServiceUriWithResourceId(RESOURCE_ID_TEST); EXPECT_TRUE(actual_uri.IsInitialized()); EXPECT_EQ(actual_uri.GetTypeName(), "uprotocol.v1.UUri"); From 11b3f2702da42f69574a67121c56fc637bb003eb Mon Sep 17 00:00:00 2001 From: Max Date: Thu, 29 May 2025 22:10:45 +0200 Subject: [PATCH 099/105] small cleanup --- include/up-cpp/communication/RpcClient.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/up-cpp/communication/RpcClient.h b/include/up-cpp/communication/RpcClient.h index 07ee17711..ef218e04e 100644 --- a/include/up-cpp/communication/RpcClient.h +++ b/include/up-cpp/communication/RpcClient.h @@ -177,9 +177,11 @@ struct RpcClient { return ResponseOrStatus( UnexpectedStatus(payload_or_status.error())); } - datamodel::builder::Payload payload(payload_or_status.value()); - auto message_or_status = this->invokeMethod(std::move(payload)).get(); + datamodel::builder::Payload tmp_payload(payload_or_status.value()); + + auto message_or_status = + this->invokeMethod(std::move(tmp_payload)).get(); if (!message_or_status.has_value()) { return ResponseOrStatus( @@ -193,12 +195,10 @@ struct RpcClient { spdlog::error( "invokeProtoMethod: Error when extracting response from " "protobuf."); - return ResponseOrStatus( - UnexpectedStatus(response_or_status.error())); + return response_or_status; } - T response_message = response_or_status.value(); - return ResponseOrStatus(std::move(response_message)); + return ResponseOrStatus(response_or_status.value()); } /// @brief Default move constructor (defined in RpcClient.cpp) From 814eb88624bbb6a40f8990ee101026295ddf6404 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Fri, 30 May 2025 08:35:20 +0200 Subject: [PATCH 100/105] Moved options_ in RequestBuilderTest to be private --- .../usubscription/v3/RequestBuilderTest.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp index 6b5c0d50e..30a71710a 100644 --- a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp +++ b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp @@ -14,9 +14,7 @@ #include #include -#include #include -#include #include "up-cpp/client/usubscription/v3/RequestBuilder.h" @@ -29,10 +27,10 @@ namespace uprotocol::core::usubscription::v3 { class RequestBuilderTest : public ::testing::Test { private: v1::UUri source_; - -protected: USubscriptionOptions options_; +protected: const v1::UUri& getSource() const { return source_; } + const USubscriptionOptions& getOptions() const { return options_; } void SetUp() override { // Create a UUri object for testing @@ -66,7 +64,7 @@ class RequestBuilderTest : public ::testing::Test { TEST_F(RequestBuilderTest, BuildSubscriptionRequestWithOptions) { const v1::UUri topic = getSource(); - const RequestBuilder builder(options_); + const RequestBuilder builder(getOptions()); SubscriptionRequest request; ASSERT_NO_THROW(request = builder.buildSubscriptionRequest(topic)); @@ -83,7 +81,7 @@ TEST_F(RequestBuilderTest, BuildSubscriptionRequestWithOptions) { TEST_F(RequestBuilderTest, BuildUnsubscribeRequest) { const v1::UUri topic = getSource(); - const RequestBuilder builder(options_); + const RequestBuilder builder(getOptions()); UnsubscribeRequest request; ASSERT_NO_THROW(request = builder.buildUnsubscribeRequest(topic)); @@ -97,7 +95,7 @@ TEST_F(RequestBuilderTest, BuildUnsubscribeRequest) { TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithTopic) { const v1::UUri topic = getSource(); - const RequestBuilder builder(options_); + const RequestBuilder builder(getOptions()); FetchSubscriptionsRequest request; ASSERT_NO_THROW(request = builder.buildFetchSubscriptionsRequest(topic)); @@ -111,7 +109,7 @@ TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithTopic) { TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithSubscriberInfo) { const SubscriberInfo subscriber; - const RequestBuilder builder(options_); + const RequestBuilder builder(getOptions()); FetchSubscriptionsRequest request; ASSERT_NO_THROW(request = @@ -125,7 +123,7 @@ TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithSubscriberInfo) { TEST_F(RequestBuilderTest, BuildFetchSubscribersRequest) { const v1::UUri topic = getSource(); - const RequestBuilder builder(options_); + const RequestBuilder builder(getOptions()); FetchSubscribersRequest request; ASSERT_NO_THROW(request = builder.buildFetchSubscribersRequest(topic)); @@ -139,7 +137,7 @@ TEST_F(RequestBuilderTest, BuildFetchSubscribersRequest) { TEST_F(RequestBuilderTest, BuildNotificationsRequest) { const v1::UUri topic = getSource(); - const RequestBuilder builder(options_); + const RequestBuilder builder(getOptions()); NotificationsRequest request; ASSERT_NO_THROW(request = builder.buildNotificationsRequest(topic)); From ec4b7e75bff99dd087da71b41b85ac81d90cd8ec Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Fri, 30 May 2025 10:02:47 +0200 Subject: [PATCH 101/105] Remove options_ field in RequestBuilder. Make Methods static --- .../client/usubscription/v3/RequestBuilder.h | 35 ++++++------------- .../usubscription/v3/RequestBuilder.cpp | 21 +++++------ .../usubscription/v3/RequestBuilderTest.cpp | 18 ++++------ 3 files changed, 24 insertions(+), 50 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RequestBuilder.h b/include/up-cpp/client/usubscription/v3/RequestBuilder.h index ad16392d8..4d813c301 100644 --- a/include/up-cpp/client/usubscription/v3/RequestBuilder.h +++ b/include/up-cpp/client/usubscription/v3/RequestBuilder.h @@ -42,32 +42,20 @@ struct USubscriptionOptions { /// This struct facilitates the construction of requests based on /// `USubscriptionOptions`, providing methods to build different requests. struct RequestBuilder { - /// @brief Constructs a RequestBuilder with the given subscription options. - /// - /// @param options Subscription options to configure the requests. Defaults - /// to empty options. - explicit RequestBuilder(USubscriptionOptions options = {}) - : options_(std::move(options)) {} - - /// @brief Sets the permission level for the requests build by the builder - /// - /// @param permission_level to be set - /// @return returns a reference to the builder struct to allow chaining - RequestBuilder& setPremissionLevel(uint32_t permission_level); - /// @brief Builds a subscription request for a given topic. /// /// @param topic The `v1::UUri` representing the topic for the subscription. /// /// @return A `SubscriptionRequest` configured for the specified topic. - SubscriptionRequest buildSubscriptionRequest(const v1::UUri& topic) const; + static SubscriptionRequest buildSubscriptionRequest(const v1::UUri& topic, + const USubscriptionOptions& options = {}); /// @brief Builds an unsubscription request for a given topic. /// /// @param topic The `v1::UUri` representing the topic to unsubscribe from. /// /// @return An `UnsubscribeRequest` configured for the specified topic. - UnsubscribeRequest buildUnsubscribeRequest(const v1::UUri& topic) const; + static UnsubscribeRequest buildUnsubscribeRequest(const v1::UUri& topic); /// @brief Build fetch subscritions request for a given topic. /// @@ -75,8 +63,8 @@ struct RequestBuilder { /// /// @return An `FetchSubscriptionsRequest` configured for the specified /// topic. - FetchSubscriptionsRequest buildFetchSubscriptionsRequest( - const v1::UUri& topic) const; + static FetchSubscriptionsRequest buildFetchSubscriptionsRequest( + const v1::UUri& topic); /// @brief Build fetch subscritions request for a given subscriber. /// @@ -85,16 +73,16 @@ struct RequestBuilder { /// /// @return An `FetchSubscriptionsRequest` configured for the specified /// subscriber. - FetchSubscriptionsRequest buildFetchSubscriptionsRequest( - const SubscriberInfo& subscriber) const; + static FetchSubscriptionsRequest buildFetchSubscriptionsRequest( + const SubscriberInfo& subscriber); /// @brief Build fetch subscribers request for a given topic. /// /// @param topic The `v1::UUri` representing the topic to fetch. /// /// @return An `FetchSubscribersRequest` configured for the specified topic. - FetchSubscribersRequest buildFetchSubscribersRequest( - const v1::UUri& topic) const; + static FetchSubscribersRequest buildFetchSubscribersRequest( + const v1::UUri& topic); /// @brief Build notifications request for a given topic. Subscription /// change @@ -105,10 +93,7 @@ struct RequestBuilder { /// for/from. /// /// @return An `NotificationsRequest` configured for the specified topic. - NotificationsRequest buildNotificationsRequest(const v1::UUri& topic) const; - -private: - USubscriptionOptions options_; ///< Options used to configure the requests. + static NotificationsRequest buildNotificationsRequest(const v1::UUri& topic); }; } // namespace uprotocol::core::usubscription::v3 diff --git a/src/client/usubscription/v3/RequestBuilder.cpp b/src/client/usubscription/v3/RequestBuilder.cpp index 7e30b4cbc..0409c1a24 100644 --- a/src/client/usubscription/v3/RequestBuilder.cpp +++ b/src/client/usubscription/v3/RequestBuilder.cpp @@ -16,41 +16,36 @@ namespace uprotocol::core::usubscription::v3 { SubscriptionRequest RequestBuilder::buildSubscriptionRequest( - const v1::UUri& topic) const { + const v1::UUri& topic, const USubscriptionOptions& options) { auto attributes = utils::ProtoConverter::BuildSubscribeAttributes( - options_.when_expire, options_.subscription_details, - options_.sample_period_ms); + options.when_expire, options.subscription_details, + options.sample_period_ms); return utils::ProtoConverter::BuildSubscriptionRequest(topic, attributes); } -RequestBuilder& RequestBuilder::setPremissionLevel(uint32_t permission_level) { - options_.permission_level = permission_level; - return *this; -} - UnsubscribeRequest RequestBuilder::buildUnsubscribeRequest( - const v1::UUri& topic) const { + const v1::UUri& topic) { return utils::ProtoConverter::BuildUnSubscribeRequest(topic); } FetchSubscriptionsRequest RequestBuilder::buildFetchSubscriptionsRequest( - const v1::UUri& topic) const { + const v1::UUri& topic) { return utils::ProtoConverter::BuildFetchSubscriptionsRequest(topic); } FetchSubscriptionsRequest RequestBuilder::buildFetchSubscriptionsRequest( - const SubscriberInfo& subscriber) const { + const SubscriberInfo& subscriber) { return utils::ProtoConverter::BuildFetchSubscriptionsRequest(subscriber); } FetchSubscribersRequest RequestBuilder::buildFetchSubscribersRequest( - const v1::UUri& topic) const { + const v1::UUri& topic) { return utils::ProtoConverter::BuildFetchSubscribersRequest(topic); } NotificationsRequest RequestBuilder::buildNotificationsRequest( - const v1::UUri& topic) const { + const v1::UUri& topic) { return utils::ProtoConverter::BuildNotificationsRequest(topic); } diff --git a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp index 30a71710a..98c2ec374 100644 --- a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp +++ b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp @@ -64,10 +64,9 @@ class RequestBuilderTest : public ::testing::Test { TEST_F(RequestBuilderTest, BuildSubscriptionRequestWithOptions) { const v1::UUri topic = getSource(); - const RequestBuilder builder(getOptions()); SubscriptionRequest request; - ASSERT_NO_THROW(request = builder.buildSubscriptionRequest(topic)); + ASSERT_NO_THROW(request = RequestBuilder::buildSubscriptionRequest(topic)); // Verify the attributes in the request // TODO(max) there should probably be some test that explicitely checks data @@ -81,10 +80,9 @@ TEST_F(RequestBuilderTest, BuildSubscriptionRequestWithOptions) { TEST_F(RequestBuilderTest, BuildUnsubscribeRequest) { const v1::UUri topic = getSource(); - const RequestBuilder builder(getOptions()); UnsubscribeRequest request; - ASSERT_NO_THROW(request = builder.buildUnsubscribeRequest(topic)); + ASSERT_NO_THROW(request = RequestBuilder::buildUnsubscribeRequest(topic)); // Verify the attributes in the request EXPECT_TRUE(request.has_topic()); @@ -95,10 +93,9 @@ TEST_F(RequestBuilderTest, BuildUnsubscribeRequest) { TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithTopic) { const v1::UUri topic = getSource(); - const RequestBuilder builder(getOptions()); FetchSubscriptionsRequest request; - ASSERT_NO_THROW(request = builder.buildFetchSubscriptionsRequest(topic)); + ASSERT_NO_THROW(request = RequestBuilder::buildFetchSubscriptionsRequest(topic)); // Verify the attributes in the request EXPECT_TRUE(request.has_topic()); @@ -109,11 +106,10 @@ TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithTopic) { TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithSubscriberInfo) { const SubscriberInfo subscriber; - const RequestBuilder builder(getOptions()); FetchSubscriptionsRequest request; ASSERT_NO_THROW(request = - builder.buildFetchSubscriptionsRequest(subscriber)); + RequestBuilder::buildFetchSubscriptionsRequest(subscriber)); // Verify the attributes in the request EXPECT_FALSE(request.has_topic()); @@ -123,10 +119,9 @@ TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithSubscriberInfo) { TEST_F(RequestBuilderTest, BuildFetchSubscribersRequest) { const v1::UUri topic = getSource(); - const RequestBuilder builder(getOptions()); FetchSubscribersRequest request; - ASSERT_NO_THROW(request = builder.buildFetchSubscribersRequest(topic)); + ASSERT_NO_THROW(request = RequestBuilder::buildFetchSubscribersRequest(topic)); // Verify the attributes in the request EXPECT_TRUE(request.has_topic()); @@ -137,10 +132,9 @@ TEST_F(RequestBuilderTest, BuildFetchSubscribersRequest) { TEST_F(RequestBuilderTest, BuildNotificationsRequest) { const v1::UUri topic = getSource(); - const RequestBuilder builder(getOptions()); NotificationsRequest request; - ASSERT_NO_THROW(request = builder.buildNotificationsRequest(topic)); + ASSERT_NO_THROW(request = RequestBuilder::buildNotificationsRequest(topic)); // Verify the attributes in the request EXPECT_TRUE(request.has_topic()); From 4215a39fb9b9a674e868c87b2e79ba196a183366 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Fri, 30 May 2025 10:55:47 +0200 Subject: [PATCH 102/105] Formatted code. Resolved missing clang-tidy warnings, that by main parts come from TEST_F --- .../client/usubscription/v3/RequestBuilder.h | 7 ++- .../usubscription/v3/RequestBuilder.cpp | 2 +- .../usubscription/v3/RequestBuilderTest.cpp | 30 +++++---- .../v3/RpcClientUSubscriptionTest.cpp | 63 +++++++++---------- .../v3/USubscriptionUUriBuilderTest.cpp | 4 +- 5 files changed, 54 insertions(+), 52 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RequestBuilder.h b/include/up-cpp/client/usubscription/v3/RequestBuilder.h index 4d813c301..e1c7d099d 100644 --- a/include/up-cpp/client/usubscription/v3/RequestBuilder.h +++ b/include/up-cpp/client/usubscription/v3/RequestBuilder.h @@ -47,8 +47,8 @@ struct RequestBuilder { /// @param topic The `v1::UUri` representing the topic for the subscription. /// /// @return A `SubscriptionRequest` configured for the specified topic. - static SubscriptionRequest buildSubscriptionRequest(const v1::UUri& topic, - const USubscriptionOptions& options = {}); + static SubscriptionRequest buildSubscriptionRequest( + const v1::UUri& topic, const USubscriptionOptions& options = {}); /// @brief Builds an unsubscription request for a given topic. /// @@ -93,7 +93,8 @@ struct RequestBuilder { /// for/from. /// /// @return An `NotificationsRequest` configured for the specified topic. - static NotificationsRequest buildNotificationsRequest(const v1::UUri& topic); + static NotificationsRequest buildNotificationsRequest( + const v1::UUri& topic); }; } // namespace uprotocol::core::usubscription::v3 diff --git a/src/client/usubscription/v3/RequestBuilder.cpp b/src/client/usubscription/v3/RequestBuilder.cpp index 0409c1a24..ea383d697 100644 --- a/src/client/usubscription/v3/RequestBuilder.cpp +++ b/src/client/usubscription/v3/RequestBuilder.cpp @@ -30,7 +30,7 @@ UnsubscribeRequest RequestBuilder::buildUnsubscribeRequest( } FetchSubscriptionsRequest RequestBuilder::buildFetchSubscriptionsRequest( - const v1::UUri& topic) { + const v1::UUri& topic) { return utils::ProtoConverter::BuildFetchSubscriptionsRequest(topic); } diff --git a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp index 98c2ec374..8b6fc4c40 100644 --- a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp +++ b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp @@ -28,6 +28,7 @@ class RequestBuilderTest : public ::testing::Test { private: v1::UUri source_; USubscriptionOptions options_; + protected: const v1::UUri& getSource() const { return source_; } const USubscriptionOptions& getOptions() const { return options_; } @@ -62,11 +63,11 @@ class RequestBuilderTest : public ::testing::Test { ~RequestBuilderTest() override = default; }; -TEST_F(RequestBuilderTest, BuildSubscriptionRequestWithOptions) { +TEST_F(RequestBuilderTest, BuildSubscriptionRequestWithOptions) { // NOLINT const v1::UUri topic = getSource(); SubscriptionRequest request; - ASSERT_NO_THROW(request = RequestBuilder::buildSubscriptionRequest(topic)); + ASSERT_NO_THROW(request = RequestBuilder::buildSubscriptionRequest(topic)); // NOLINT // Verify the attributes in the request // TODO(max) there should probably be some test that explicitely checks data @@ -78,11 +79,11 @@ TEST_F(RequestBuilderTest, BuildSubscriptionRequestWithOptions) { "uprotocol.core.usubscription.v3.SubscriptionRequest"); } -TEST_F(RequestBuilderTest, BuildUnsubscribeRequest) { +TEST_F(RequestBuilderTest, BuildUnsubscribeRequest) { // NOLINT const v1::UUri topic = getSource(); UnsubscribeRequest request; - ASSERT_NO_THROW(request = RequestBuilder::buildUnsubscribeRequest(topic)); + ASSERT_NO_THROW(request = RequestBuilder::buildUnsubscribeRequest(topic)); // NOLINT // Verify the attributes in the request EXPECT_TRUE(request.has_topic()); @@ -91,11 +92,12 @@ TEST_F(RequestBuilderTest, BuildUnsubscribeRequest) { "uprotocol.core.usubscription.v3.UnsubscribeRequest"); } -TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithTopic) { +TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithTopic) { // NOLINT const v1::UUri topic = getSource(); FetchSubscriptionsRequest request; - ASSERT_NO_THROW(request = RequestBuilder::buildFetchSubscriptionsRequest(topic)); + ASSERT_NO_THROW(request = // NOLINT + RequestBuilder::buildFetchSubscriptionsRequest(topic)); // Verify the attributes in the request EXPECT_TRUE(request.has_topic()); @@ -104,12 +106,13 @@ TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithTopic) { "uprotocol.core.usubscription.v3.FetchSubscriptionsRequest"); } -TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithSubscriberInfo) { +TEST_F(RequestBuilderTest, // NOLINT + BuildFetchSubscriptionsRequestWithSubscriberInfo) { const SubscriberInfo subscriber; FetchSubscriptionsRequest request; - ASSERT_NO_THROW(request = - RequestBuilder::buildFetchSubscriptionsRequest(subscriber)); + ASSERT_NO_THROW( // NOLINT + request = RequestBuilder::buildFetchSubscriptionsRequest(subscriber)); // Verify the attributes in the request EXPECT_FALSE(request.has_topic()); @@ -117,11 +120,12 @@ TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithSubscriberInfo) { "uprotocol.core.usubscription.v3.FetchSubscriptionsRequest"); } -TEST_F(RequestBuilderTest, BuildFetchSubscribersRequest) { +TEST_F(RequestBuilderTest, BuildFetchSubscribersRequest) { // NOLINT const v1::UUri topic = getSource(); FetchSubscribersRequest request; - ASSERT_NO_THROW(request = RequestBuilder::buildFetchSubscribersRequest(topic)); + ASSERT_NO_THROW(request = // NOLINT + RequestBuilder::buildFetchSubscribersRequest(topic)); // Verify the attributes in the request EXPECT_TRUE(request.has_topic()); @@ -130,11 +134,11 @@ TEST_F(RequestBuilderTest, BuildFetchSubscribersRequest) { "uprotocol.core.usubscription.v3.FetchSubscribersRequest"); } -TEST_F(RequestBuilderTest, BuildNotificationsRequest) { +TEST_F(RequestBuilderTest, BuildNotificationsRequest) { // NOLINT const v1::UUri topic = getSource(); NotificationsRequest request; - ASSERT_NO_THROW(request = RequestBuilder::buildNotificationsRequest(topic)); + ASSERT_NO_THROW(request = RequestBuilder::buildNotificationsRequest(topic)); // NOLINT // Verify the attributes in the request EXPECT_TRUE(request.has_topic()); diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp index 2703f459a..2f14753c9 100644 --- a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -15,6 +15,7 @@ using SubscriptionRequest = uprotocol::core::usubscription::v3::SubscriptionRequest; using SubscriptionResponse = uprotocol::core::usubscription::v3::SubscriptionResponse; +using RequestBuilder = uprotocol::core::usubscription::v3::RequestBuilder; namespace { @@ -85,14 +86,9 @@ class RpcClientUSubscriptionTest : public testing::Test { uprotocol::v1::UUri getSubscriptionTopic() { return subscription_topic_; } - uprotocol::core::usubscription::v3::RequestBuilder getRequestBuilder() { - return request_builder_; - } - private: std::shared_ptr client_transport_; std::shared_ptr server_transport_; - uprotocol::core::usubscription::v3::RequestBuilder request_builder_; uprotocol::v1::UUri server_method_uuri_; uprotocol::v1::UUri subscription_topic_; @@ -104,7 +100,8 @@ class RpcClientUSubscriptionTest : public testing::Test { // Tests for subscribe method // -TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoPayload) { +TEST_F(RpcClientUSubscriptionTest, // NOLINT + SubscribeRoundtripWithValidProtoPayload) { bool server_callback_executed = false; SubscriptionRequest server_capture; SubscriptionResponse server_response; @@ -134,7 +131,7 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoPayload) { getClientTransport()); const auto subscription_request = - getRequestBuilder().buildSubscriptionRequest(getSubscriptionTopic()); + RequestBuilder::buildSubscriptionRequest(getSubscriptionTopic()); auto response_or_status_future = std::async(std::launch::async, @@ -168,7 +165,8 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoPayload) { server_response.SerializeAsString()); } -TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoAnyPayload) { +TEST_F(RpcClientUSubscriptionTest, // NOLINT + SubscribeRoundtripWithValidProtoAnyPayload) { bool server_callback_executed = false; SubscriptionRequest server_capture; SubscriptionResponse server_response; @@ -202,7 +200,7 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoAnyPayload) { getClientTransport()); const auto subscription_request = - getRequestBuilder().buildSubscriptionRequest(getSubscriptionTopic()); + RequestBuilder::buildSubscriptionRequest(getSubscriptionTopic()); auto response_or_status_future = std::async(std::launch::async, @@ -236,7 +234,7 @@ TEST_F(RpcClientUSubscriptionTest, SubscribeRoundtripWithValidProtoAnyPayload) { server_response.SerializeAsString()); } -TEST_F(RpcClientUSubscriptionTest, +TEST_F(RpcClientUSubscriptionTest, // NOLINT SubscribeRoundtripWithValidProtoPayloadDifferentTopic) { bool server_callback_executed = false; SubscriptionRequest server_capture; @@ -276,7 +274,7 @@ TEST_F(RpcClientUSubscriptionTest, getClientTransport()); const auto subscription_request = - getRequestBuilder().buildSubscriptionRequest(getSubscriptionTopic()); + RequestBuilder::buildSubscriptionRequest(getSubscriptionTopic()); auto response_or_status_future = std::async(std::launch::async, @@ -319,7 +317,8 @@ using UnsubscibeRequest = using UnsubscribeResponse = uprotocol::core::usubscription::v3::UnsubscribeResponse; -TEST_F(RpcClientUSubscriptionTest, UnsubscribeRoundtripWithValidProtoPayload) { +TEST_F(RpcClientUSubscriptionTest, // NOLINT + UnsubscribeRoundtripWithValidProtoPayload) { bool server_callback_executed = false; UnsubscibeRequest server_capture; UnsubscribeResponse server_response; @@ -347,7 +346,7 @@ TEST_F(RpcClientUSubscriptionTest, UnsubscribeRoundtripWithValidProtoPayload) { getClientTransport()); const auto unsubscribe_request = - getRequestBuilder().buildUnsubscribeRequest(getSubscriptionTopic()); + RequestBuilder::buildUnsubscribeRequest(getSubscriptionTopic()); auto response_or_status_future = std::async(std::launch::async, @@ -381,7 +380,7 @@ TEST_F(RpcClientUSubscriptionTest, UnsubscribeRoundtripWithValidProtoPayload) { server_response.SerializeAsString()); } -TEST_F(RpcClientUSubscriptionTest, +TEST_F(RpcClientUSubscriptionTest, // NOLINT UnsubscribeRoundtripWithValidProtoAnyPayload) { bool server_callback_executed = false; UnsubscibeRequest server_capture; @@ -414,7 +413,7 @@ TEST_F(RpcClientUSubscriptionTest, getClientTransport()); const auto unsubscribe_request = - getRequestBuilder().buildUnsubscribeRequest(getSubscriptionTopic()); + RequestBuilder::buildUnsubscribeRequest(getSubscriptionTopic()); auto response_or_status_future = std::async(std::launch::async, @@ -457,7 +456,7 @@ using FetchSubscribersRequest = using FetchSubscribersResponse = uprotocol::core::usubscription::v3::FetchSubscribersResponse; -TEST_F(RpcClientUSubscriptionTest, +TEST_F(RpcClientUSubscriptionTest, // NOLINT fetchSubscriberRoundtripWithValidProtoPayload) { bool server_callback_executed = false; FetchSubscribersRequest server_capture; @@ -487,8 +486,7 @@ TEST_F(RpcClientUSubscriptionTest, getClientTransport()); const auto fetch_subscribers_request = - getRequestBuilder().buildFetchSubscribersRequest( - getSubscriptionTopic()); + RequestBuilder::buildFetchSubscribersRequest(getSubscriptionTopic()); auto response_or_status_future = std::async( std::launch::async, @@ -522,7 +520,7 @@ TEST_F(RpcClientUSubscriptionTest, server_response.SerializeAsString()); } -TEST_F(RpcClientUSubscriptionTest, +TEST_F(RpcClientUSubscriptionTest, // NOLINT FetchSubscriberRoundtripWithValidProtoAnyPayload) { bool server_callback_executed = false; FetchSubscribersRequest server_capture; @@ -556,8 +554,7 @@ TEST_F(RpcClientUSubscriptionTest, getClientTransport()); const auto fetch_subscribers_request = - getRequestBuilder().buildFetchSubscribersRequest( - getSubscriptionTopic()); + RequestBuilder::buildFetchSubscribersRequest(getSubscriptionTopic()); auto response_or_status_future = std::async( std::launch::async, @@ -600,7 +597,7 @@ using FetchSubscriptionsRequest = using FetchSubscriptionsResponse = uprotocol::core::usubscription::v3::FetchSubscriptionsResponse; -TEST_F(RpcClientUSubscriptionTest, +TEST_F(RpcClientUSubscriptionTest, // NOLINT fetchSubscriptionsRoundtripWithValidProtoPayload) { bool server_callback_executed = false; FetchSubscriptionsRequest server_capture; @@ -631,7 +628,7 @@ TEST_F(RpcClientUSubscriptionTest, const uprotocol::core::usubscription::v3::SubscriberInfo subscriber_info; const auto fetch_subscriptions_request = - getRequestBuilder().buildFetchSubscriptionsRequest(subscriber_info); + RequestBuilder::buildFetchSubscriptionsRequest(subscriber_info); auto response_or_status_future = std::async( std::launch::async, @@ -665,7 +662,7 @@ TEST_F(RpcClientUSubscriptionTest, server_response.SerializeAsString()); } -TEST_F(RpcClientUSubscriptionTest, +TEST_F(RpcClientUSubscriptionTest, // NOLINT fetchSubscriptionRoundtripWithValidProtoAnyPayload) { bool server_callback_executed = false; FetchSubscriptionsRequest server_capture; @@ -700,7 +697,7 @@ TEST_F(RpcClientUSubscriptionTest, const uprotocol::core::usubscription::v3::SubscriberInfo subscriber_info; const auto fetch_subscribers_request = - getRequestBuilder().buildFetchSubscriptionsRequest(subscriber_info); + RequestBuilder::buildFetchSubscriptionsRequest(subscriber_info); auto response_or_status_future = std::async( std::launch::async, @@ -743,7 +740,7 @@ using NotificationsRequest = using NotificationsResponse = uprotocol::core::usubscription::v3::NotificationsResponse; -TEST_F(RpcClientUSubscriptionTest, +TEST_F(RpcClientUSubscriptionTest, // NOLINT registerNotificationRoundtripWithValidProtoPayload) { bool server_callback_executed = false; NotificationsRequest server_capture; @@ -773,7 +770,7 @@ TEST_F(RpcClientUSubscriptionTest, getClientTransport()); const auto notifications_request = - getRequestBuilder().buildNotificationsRequest(getSubscriptionTopic()); + RequestBuilder::buildNotificationsRequest(getSubscriptionTopic()); auto response_or_status_future = std::async( std::launch::async, @@ -807,7 +804,7 @@ TEST_F(RpcClientUSubscriptionTest, server_response.SerializeAsString()); } -TEST_F(RpcClientUSubscriptionTest, +TEST_F(RpcClientUSubscriptionTest, // NOLINT registerNotificationRoundtripWithValidProtoAnyPayload) { bool server_callback_executed = false; NotificationsRequest server_capture; @@ -841,7 +838,7 @@ TEST_F(RpcClientUSubscriptionTest, getClientTransport()); const auto notifications_request = - getRequestBuilder().buildNotificationsRequest(getSubscriptionTopic()); + RequestBuilder::buildNotificationsRequest(getSubscriptionTopic()); auto response_or_status_future = std::async( std::launch::async, @@ -884,7 +881,7 @@ using NotificationsRequest = using NotificationsResponse = uprotocol::core::usubscription::v3::NotificationsResponse; -TEST_F(RpcClientUSubscriptionTest, +TEST_F(RpcClientUSubscriptionTest, // NOLINT unregisterNotificationRoundtripWithValidProtoPayload) { bool server_callback_executed = false; NotificationsRequest server_capture; @@ -914,7 +911,7 @@ TEST_F(RpcClientUSubscriptionTest, getClientTransport()); const auto notifications_request = - getRequestBuilder().buildNotificationsRequest(getSubscriptionTopic()); + RequestBuilder::buildNotificationsRequest(getSubscriptionTopic()); auto response_or_status_future = std::async( std::launch::async, @@ -948,7 +945,7 @@ TEST_F(RpcClientUSubscriptionTest, server_response.SerializeAsString()); } -TEST_F(RpcClientUSubscriptionTest, +TEST_F(RpcClientUSubscriptionTest, // NOLINT unregisterNotificationRoundtripWithValidProtoAnyPayload) { bool server_callback_executed = false; NotificationsRequest server_capture; @@ -982,7 +979,7 @@ TEST_F(RpcClientUSubscriptionTest, getClientTransport()); const auto notifications_request = - getRequestBuilder().buildNotificationsRequest(getSubscriptionTopic()); + RequestBuilder::buildNotificationsRequest(getSubscriptionTopic()); auto response_or_status_future = std::async( std::launch::async, diff --git a/test/coverage/client/usubscription/v3/USubscriptionUUriBuilderTest.cpp b/test/coverage/client/usubscription/v3/USubscriptionUUriBuilderTest.cpp index c27a62cbb..3958861d8 100644 --- a/test/coverage/client/usubscription/v3/USubscriptionUUriBuilderTest.cpp +++ b/test/coverage/client/usubscription/v3/USubscriptionUUriBuilderTest.cpp @@ -34,7 +34,7 @@ class USubscriptionUUriBuilderTest : public ::testing::Test { void TearDown() override {} }; -TEST_F(USubscriptionUUriBuilderTest, GetServiceUriWithResourceId) { +TEST_F(USubscriptionUUriBuilderTest, GetServiceUriWithResourceId) { // NOLINT // Example test case for building a subscription UUri auto expected_uri = getExpectedUri(); expected_uri.set_resource_id(RESOURCE_ID_TEST); @@ -47,7 +47,7 @@ TEST_F(USubscriptionUUriBuilderTest, GetServiceUriWithResourceId) { EXPECT_EQ(actual_uri.SerializeAsString(), expected_uri.SerializeAsString()); } -TEST_F(USubscriptionUUriBuilderTest, GetNotificationUri) { +TEST_F(USubscriptionUUriBuilderTest, GetNotificationUri) { // NOLINT auto expected_uri = getExpectedUri(); expected_uri.set_resource_id(RESOURCE_ID_NOTIFICATION_ID); USubscriptionUUriBuilder builder; From e281151cb9b93f6aafadcadbcd662311ad2d8143 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Fri, 30 May 2025 11:42:34 +0200 Subject: [PATCH 103/105] Formatted code again. --- .../usubscription/v3/RequestBuilderTest.cpp | 23 +++++++++++-------- .../v3/RpcClientUSubscriptionTest.cpp | 12 +++++----- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp index 8b6fc4c40..79e19ee03 100644 --- a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp +++ b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp @@ -67,7 +67,8 @@ TEST_F(RequestBuilderTest, BuildSubscriptionRequestWithOptions) { // NOLINT const v1::UUri topic = getSource(); SubscriptionRequest request; - ASSERT_NO_THROW(request = RequestBuilder::buildSubscriptionRequest(topic)); // NOLINT + ASSERT_NO_THROW( + request = RequestBuilder::buildSubscriptionRequest(topic)); // NOLINT // Verify the attributes in the request // TODO(max) there should probably be some test that explicitely checks data @@ -83,7 +84,8 @@ TEST_F(RequestBuilderTest, BuildUnsubscribeRequest) { // NOLINT const v1::UUri topic = getSource(); UnsubscribeRequest request; - ASSERT_NO_THROW(request = RequestBuilder::buildUnsubscribeRequest(topic)); // NOLINT + ASSERT_NO_THROW( // NOLINT + request = RequestBuilder::buildUnsubscribeRequest(topic)); // Verify the attributes in the request EXPECT_TRUE(request.has_topic()); @@ -96,8 +98,8 @@ TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithTopic) { // NOLINT const v1::UUri topic = getSource(); FetchSubscriptionsRequest request; - ASSERT_NO_THROW(request = // NOLINT - RequestBuilder::buildFetchSubscriptionsRequest(topic)); + ASSERT_NO_THROW(request = // NOLINT + RequestBuilder::buildFetchSubscriptionsRequest(topic)); // Verify the attributes in the request EXPECT_TRUE(request.has_topic()); @@ -106,12 +108,12 @@ TEST_F(RequestBuilderTest, BuildFetchSubscriptionsRequestWithTopic) { // NOLINT "uprotocol.core.usubscription.v3.FetchSubscriptionsRequest"); } -TEST_F(RequestBuilderTest, // NOLINT - BuildFetchSubscriptionsRequestWithSubscriberInfo) { +TEST_F(RequestBuilderTest, // NOLINT + BuildFetchSubscriptionsRequestWithSubscriberInfo) { const SubscriberInfo subscriber; FetchSubscriptionsRequest request; - ASSERT_NO_THROW( // NOLINT + ASSERT_NO_THROW( // NOLINT request = RequestBuilder::buildFetchSubscriptionsRequest(subscriber)); // Verify the attributes in the request @@ -124,8 +126,8 @@ TEST_F(RequestBuilderTest, BuildFetchSubscribersRequest) { // NOLINT const v1::UUri topic = getSource(); FetchSubscribersRequest request; - ASSERT_NO_THROW(request = // NOLINT - RequestBuilder::buildFetchSubscribersRequest(topic)); + ASSERT_NO_THROW(request = // NOLINT + RequestBuilder::buildFetchSubscribersRequest(topic)); // Verify the attributes in the request EXPECT_TRUE(request.has_topic()); @@ -138,7 +140,8 @@ TEST_F(RequestBuilderTest, BuildNotificationsRequest) { // NOLINT const v1::UUri topic = getSource(); NotificationsRequest request; - ASSERT_NO_THROW(request = RequestBuilder::buildNotificationsRequest(topic)); // NOLINT + ASSERT_NO_THROW( // NOLINT + request = RequestBuilder::buildNotificationsRequest(topic)); // Verify the attributes in the request EXPECT_TRUE(request.has_topic()); diff --git a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp index 2f14753c9..1e7b1adc6 100644 --- a/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp +++ b/test/coverage/client/usubscription/v3/RpcClientUSubscriptionTest.cpp @@ -100,8 +100,8 @@ class RpcClientUSubscriptionTest : public testing::Test { // Tests for subscribe method // -TEST_F(RpcClientUSubscriptionTest, // NOLINT - SubscribeRoundtripWithValidProtoPayload) { +TEST_F(RpcClientUSubscriptionTest, // NOLINT + SubscribeRoundtripWithValidProtoPayload) { bool server_callback_executed = false; SubscriptionRequest server_capture; SubscriptionResponse server_response; @@ -165,8 +165,8 @@ TEST_F(RpcClientUSubscriptionTest, // NOLINT server_response.SerializeAsString()); } -TEST_F(RpcClientUSubscriptionTest, // NOLINT - SubscribeRoundtripWithValidProtoAnyPayload) { +TEST_F(RpcClientUSubscriptionTest, // NOLINT + SubscribeRoundtripWithValidProtoAnyPayload) { bool server_callback_executed = false; SubscriptionRequest server_capture; SubscriptionResponse server_response; @@ -317,8 +317,8 @@ using UnsubscibeRequest = using UnsubscribeResponse = uprotocol::core::usubscription::v3::UnsubscribeResponse; -TEST_F(RpcClientUSubscriptionTest, // NOLINT - UnsubscribeRoundtripWithValidProtoPayload) { +TEST_F(RpcClientUSubscriptionTest, // NOLINT + UnsubscribeRoundtripWithValidProtoPayload) { bool server_callback_executed = false; UnsubscibeRequest server_capture; UnsubscribeResponse server_response; From 5cefcb69a2a640228830b60994d364ac2e5c7469 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Fri, 30 May 2025 11:43:30 +0200 Subject: [PATCH 104/105] Formatted code again --- .../client/usubscription/v3/RequestBuilderTest.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp index 79e19ee03..f7212ed5d 100644 --- a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp +++ b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp @@ -84,8 +84,8 @@ TEST_F(RequestBuilderTest, BuildUnsubscribeRequest) { // NOLINT const v1::UUri topic = getSource(); UnsubscribeRequest request; - ASSERT_NO_THROW( // NOLINT - request = RequestBuilder::buildUnsubscribeRequest(topic)); + ASSERT_NO_THROW( // NOLINT + request = RequestBuilder::buildUnsubscribeRequest(topic)); // Verify the attributes in the request EXPECT_TRUE(request.has_topic()); @@ -140,8 +140,8 @@ TEST_F(RequestBuilderTest, BuildNotificationsRequest) { // NOLINT const v1::UUri topic = getSource(); NotificationsRequest request; - ASSERT_NO_THROW( // NOLINT - request = RequestBuilder::buildNotificationsRequest(topic)); + ASSERT_NO_THROW( // NOLINT + request = RequestBuilder::buildNotificationsRequest(topic)); // Verify the attributes in the request EXPECT_TRUE(request.has_topic()); From 7ce19a43ce9cc69a6272215d0f5087a46c0cf9e0 Mon Sep 17 00:00:00 2001 From: Lennart Becker Date: Fri, 30 May 2025 11:56:48 +0200 Subject: [PATCH 105/105] Resolved todo(lennart). Formatted code again --- .../up-cpp/client/usubscription/v3/RpcClientUSubscription.h | 5 ++--- test/coverage/client/usubscription/v3/RequestBuilderTest.cpp | 5 +++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h index 70a34d697..6f7663d55 100644 --- a/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h +++ b/include/up-cpp/client/usubscription/v3/RpcClientUSubscription.h @@ -38,9 +38,8 @@ constexpr uint16_t RESOURCE_ID_REGISTER_FOR_NOTIFICATIONS = 0x0006; constexpr uint16_t RESOURCE_ID_UNREGISTER_FOR_NOTIFICATIONS = 0x0007; /// The resource identifier of uSubscription's _fetch subscribers_ operation. constexpr uint16_t RESOURCE_ID_FETCH_SUBSCRIBERS = 0x0008; -// TODO(lennart) see default_call_options() for the request in Rust -constexpr auto USUBSCRIPTION_REQUEST_TTL = - std::chrono::milliseconds(0x0800); // TODO(lennart) change time + +constexpr auto USUBSCRIPTION_REQUEST_TTL = std::chrono::milliseconds(5000); namespace uprotocol::core::usubscription::v3 { using v3::SubscriptionRequest; diff --git a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp index f7212ed5d..a255355fd 100644 --- a/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp +++ b/test/coverage/client/usubscription/v3/RequestBuilderTest.cpp @@ -67,8 +67,9 @@ TEST_F(RequestBuilderTest, BuildSubscriptionRequestWithOptions) { // NOLINT const v1::UUri topic = getSource(); SubscriptionRequest request; - ASSERT_NO_THROW( - request = RequestBuilder::buildSubscriptionRequest(topic)); // NOLINT + ASSERT_NO_THROW( // NOLINT + request = + RequestBuilder::buildSubscriptionRequest(topic, getOptions())); // Verify the attributes in the request // TODO(max) there should probably be some test that explicitely checks data