Skip to content

Commit 00b9d0a

Browse files
authored
add clients & services count (#2072)
* add clients & services count * add count clients,services tests Signed-off-by: leeminju531 <[email protected]>
1 parent 77c7aaf commit 00b9d0a

File tree

11 files changed

+166
-0
lines changed

11 files changed

+166
-0
lines changed

rclcpp/include/rclcpp/node.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,6 +1314,26 @@ class Node : public std::enable_shared_from_this<Node>
13141314
size_t
13151315
count_subscribers(const std::string & topic_name) const;
13161316

1317+
/// Return the number of clients created for a given service.
1318+
/**
1319+
* \param[in] service_name the actual service name used; it will not be automatically remapped.
1320+
* \return number of clients that have been created for the given service.
1321+
* \throws std::runtime_error if clients could not be counted
1322+
*/
1323+
RCLCPP_PUBLIC
1324+
size_t
1325+
count_clients(const std::string & service_name) const;
1326+
1327+
/// Return the number of services created for a given service.
1328+
/**
1329+
* \param[in] service_name the actual service name used; it will not be automatically remapped.
1330+
* \return number of services that have been created for the given service.
1331+
* \throws std::runtime_error if services could not be counted
1332+
*/
1333+
RCLCPP_PUBLIC
1334+
size_t
1335+
count_services(const std::string & service_name) const;
1336+
13171337
/// Return the topic endpoint information about publishers on a given topic.
13181338
/**
13191339
* The returned parameter is a list of topic endpoint information, where each item will contain

rclcpp/include/rclcpp/node_interfaces/node_graph.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,14 @@ class NodeGraph : public NodeGraphInterface
113113
size_t
114114
count_subscribers(const std::string & topic_name) const override;
115115

116+
RCLCPP_PUBLIC
117+
size_t
118+
count_clients(const std::string & service_name) const override;
119+
120+
RCLCPP_PUBLIC
121+
size_t
122+
count_services(const std::string & service_name) const override;
123+
116124
RCLCPP_PUBLIC
117125
const rcl_guard_condition_t *
118126
get_graph_guard_condition() const override;

rclcpp/include/rclcpp/node_interfaces/node_graph_interface.hpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,24 @@ class NodeGraphInterface
305305
size_t
306306
count_subscribers(const std::string & topic_name) const = 0;
307307

308+
/// Return the number of clients created for a given service.
309+
/*
310+
* \param[in] service_name the actual service name used; it will not be automatically remapped.
311+
*/
312+
RCLCPP_PUBLIC
313+
virtual
314+
size_t
315+
count_clients(const std::string & service_name) const = 0;
316+
317+
/// Return the number of services created for a given service.
318+
/*
319+
* \param[in] service_name the actual service name used; it will not be automatically remapped.
320+
*/
321+
RCLCPP_PUBLIC
322+
virtual
323+
size_t
324+
count_services(const std::string & service_name) const = 0;
325+
308326
/// Return the rcl guard condition which is triggered when the ROS graph changes.
309327
RCLCPP_PUBLIC
310328
virtual

rclcpp/include/rclcpp/rclcpp.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@
9696
* - Get the number of publishers or subscribers on a topic:
9797
* - rclcpp::Node::count_publishers()
9898
* - rclcpp::Node::count_subscribers()
99+
* - Get the number of clients or servers on a service:
100+
* - rclcpp::Node::count_clients()
101+
* - rclcpp::Node::count_services()
99102
*
100103
* And components related to logging:
101104
*

rclcpp/src/rclcpp/node.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,18 @@ Node::count_subscribers(const std::string & topic_name) const
522522
return node_graph_->count_subscribers(topic_name);
523523
}
524524

525+
size_t
526+
Node::count_clients(const std::string & service_name) const
527+
{
528+
return node_graph_->count_clients(service_name);
529+
}
530+
531+
size_t
532+
Node::count_services(const std::string & service_name) const
533+
{
534+
return node_graph_->count_services(service_name);
535+
}
536+
525537
std::vector<rclcpp::TopicEndpointInfo>
526538
Node::get_publishers_info_by_topic(const std::string & topic_name, bool no_mangle) const
527539
{

rclcpp/src/rclcpp/node_interfaces/node_graph.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,50 @@ NodeGraph::count_subscribers(const std::string & topic_name) const
498498
return count;
499499
}
500500

501+
size_t
502+
NodeGraph::count_clients(const std::string & service_name) const
503+
{
504+
auto rcl_node_handle = node_base_->get_rcl_node_handle();
505+
506+
auto fqdn = rclcpp::expand_topic_or_service_name(
507+
service_name,
508+
rcl_node_get_name(rcl_node_handle),
509+
rcl_node_get_namespace(rcl_node_handle),
510+
true);
511+
512+
size_t count;
513+
auto ret = rcl_count_clients(rcl_node_handle, fqdn.c_str(), &count);
514+
if (ret != RMW_RET_OK) {
515+
// *INDENT-OFF*
516+
throw std::runtime_error(
517+
std::string("could not count clients: ") + rmw_get_error_string().str);
518+
// *INDENT-ON*
519+
}
520+
return count;
521+
}
522+
523+
size_t
524+
NodeGraph::count_services(const std::string & service_name) const
525+
{
526+
auto rcl_node_handle = node_base_->get_rcl_node_handle();
527+
528+
auto fqdn = rclcpp::expand_topic_or_service_name(
529+
service_name,
530+
rcl_node_get_name(rcl_node_handle),
531+
rcl_node_get_namespace(rcl_node_handle),
532+
true);
533+
534+
size_t count;
535+
auto ret = rcl_count_services(rcl_node_handle, fqdn.c_str(), &count);
536+
if (ret != RMW_RET_OK) {
537+
// *INDENT-OFF*
538+
throw std::runtime_error(
539+
std::string("could not count services: ") + rmw_get_error_string().str);
540+
// *INDENT-ON*
541+
}
542+
return count;
543+
}
544+
501545
const rcl_guard_condition_t *
502546
NodeGraph::get_graph_guard_condition() const
503547
{

rclcpp/test/rclcpp/node_interfaces/test_node_graph.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ TEST_F(TestNodeGraph, construct_from_node)
129129

130130
EXPECT_EQ(0u, node_graph()->count_publishers("not_a_topic"));
131131
EXPECT_EQ(0u, node_graph()->count_subscribers("not_a_topic"));
132+
EXPECT_EQ(0u, node_graph()->count_clients("not_a_service"));
133+
EXPECT_EQ(0u, node_graph()->count_services("not_a_service"));
134+
132135
EXPECT_NE(nullptr, node_graph()->get_graph_guard_condition());
133136

134137
// get_graph_event is non-const
@@ -534,6 +537,22 @@ TEST_F(TestNodeGraph, count_subscribers_rcl_error)
534537
std::runtime_error("could not count subscribers: error not set"));
535538
}
536539

540+
TEST_F(TestNodeGraph, count_clients_rcl_error)
541+
{
542+
auto mock = mocking_utils::patch_and_return("lib:rclcpp", rcl_count_clients, RCL_RET_ERROR);
543+
RCLCPP_EXPECT_THROW_EQ(
544+
node_graph()->count_clients("service"),
545+
std::runtime_error("could not count clients: error not set"));
546+
}
547+
548+
TEST_F(TestNodeGraph, count_services_rcl_error)
549+
{
550+
auto mock = mocking_utils::patch_and_return("lib:rclcpp", rcl_count_services, RCL_RET_ERROR);
551+
RCLCPP_EXPECT_THROW_EQ(
552+
node_graph()->count_services("service"),
553+
std::runtime_error("could not count services: error not set"));
554+
}
555+
537556
TEST_F(TestNodeGraph, notify_shutdown)
538557
{
539558
EXPECT_NO_THROW(node()->get_node_graph_interface()->notify_shutdown());

rclcpp/test/rclcpp/test_node.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3311,6 +3311,9 @@ TEST_F(TestNode, get_entity_names) {
33113311
const auto service_names_and_types = node->get_service_names_and_types();
33123312
EXPECT_EQ(service_names_and_types.end(), service_names_and_types.find("service"));
33133313

3314+
EXPECT_EQ(0u, node->count_clients("service"));
3315+
EXPECT_EQ(0u, node->count_services("service"));
3316+
33143317
const auto service_names_and_types_by_node =
33153318
node->get_service_names_and_types_by_node("node", "/ns");
33163319
EXPECT_EQ(

rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,22 @@ class LifecycleNode : public node_interfaces::LifecycleNodeInterface,
690690
size_t
691691
count_subscribers(const std::string & topic_name) const;
692692

693+
/// Return the number of clients created for a given service.
694+
/**
695+
* \sa rclcpp::Node::count_clients
696+
*/
697+
RCLCPP_LIFECYCLE_PUBLIC
698+
size_t
699+
count_clients(const std::string & service_name) const;
700+
701+
/// Return the number of services created for a given service.
702+
/**
703+
* \sa rclcpp::Node::count_services
704+
*/
705+
RCLCPP_LIFECYCLE_PUBLIC
706+
size_t
707+
count_services(const std::string & service_name) const;
708+
693709
/// Return the topic endpoint information about publishers on a given topic.
694710
/**
695711
* \sa rclcpp::Node::get_publishers_info_by_topic

rclcpp_lifecycle/src/lifecycle_node.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,18 @@ LifecycleNode::count_subscribers(const std::string & topic_name) const
386386
return node_graph_->count_subscribers(topic_name);
387387
}
388388

389+
size_t
390+
LifecycleNode::count_clients(const std::string & service_name) const
391+
{
392+
return node_graph_->count_clients(service_name);
393+
}
394+
395+
size_t
396+
LifecycleNode::count_services(const std::string & service_name) const
397+
{
398+
return node_graph_->count_services(service_name);
399+
}
400+
389401
std::vector<rclcpp::TopicEndpointInfo>
390402
LifecycleNode::get_publishers_info_by_topic(const std::string & topic_name, bool no_mangle) const
391403
{

0 commit comments

Comments
 (0)