Coverage Report

Created: 2025-06-13 06:46

/src/Fast-DDS/src/cpp/fastdds/rpc/ServiceImpl.hpp
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2025 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#ifndef FASTDDS_RPC__SERVICEIMPL_HPP
16
#define FASTDDS_RPC__SERVICEIMPL_HPP
17
18
#include <mutex>
19
20
#include <fastdds/dds/domain/qos/ReplierQos.hpp>
21
#include <fastdds/dds/domain/qos/RequesterQos.hpp>
22
#include <fastdds/dds/rpc/Service.hpp>
23
#include <fastdds/dds/topic/ContentFilteredTopic.hpp>
24
#include <fastdds/dds/topic/Topic.hpp>
25
26
#include "../domain/DomainParticipantImpl.hpp"
27
#include "../publisher/PublisherImpl.hpp"
28
#include "../subscriber/SubscriberImpl.hpp"
29
30
namespace eprosima {
31
namespace fastdds {
32
namespace dds {
33
namespace rpc {
34
35
class ReplierImpl;
36
class RequesterImpl;
37
38
/**
39
 * @brief Class that represents the implementation of a Service entity
40
 */
41
class ServiceImpl : public Service
42
{
43
44
public:
45
46
    /**
47
     * @brief Constructor
48
     * Don't use it directly, use create_service from DomainParticipant instead
49
     */
50
    ServiceImpl(
51
            const std::string& service_name,
52
            const std::string& service_type_name,
53
            DomainParticipantImpl* participant,
54
            PublisherImpl* service_publisher,
55
            SubscriberImpl* service_subscriber);
56
57
    /**
58
     * @brief Destructor
59
     */
60
    virtual ~ServiceImpl();
61
62
    /**
63
     * @brief Get the service name
64
     *
65
     * @return Service name
66
     */
67
    const std::string& get_service_name() const override
68
0
    {
69
0
        return service_name_;
70
0
    }
71
72
    /**
73
     * @brief Get the service type name
74
     *
75
     * @return Service type name
76
     */
77
    const std::string& get_service_type_name() const override
78
0
    {
79
0
        return service_type_name_;
80
0
    }
81
82
    /**
83
     * @brief Remove a requester from the service
84
     *
85
     * @param requester Requester to remove
86
     * @return RETCODE_OK if the requester was removed successfully, an specific error code otherwise
87
     */
88
    ReturnCode_t remove_requester(
89
            RequesterImpl* requester);
90
91
    /**
92
     * @brief Remove a replier from the service
93
     *
94
     * @param replier replier to remove
95
     * @return RETCODE_OK if the requester was removed successfully, an specific error code otherwise
96
     */
97
    ReturnCode_t remove_replier(
98
            ReplierImpl* replier);
99
100
    /**
101
     * @brief Create a requester for the service
102
     *
103
     * @param qos Requester QoS
104
     * @return A pointer to the created requester or nullptr if an error occurred
105
     */
106
    RequesterImpl* create_requester(
107
            const RequesterQos& qos);
108
109
    /**
110
     * @brief Create a replier for the service
111
     *
112
     * @param qos Replier QoS
113
     * @return A pointer to the created replier or nullptr if an error occurred
114
     */
115
    ReplierImpl* create_replier(
116
            const ReplierQos& qos);
117
118
    /**
119
     * @brief Enable the service
120
     *
121
     * @return RETCODE_OK if the topics were created successfully, an specific error code otherwise
122
     * It will also try to enable all internal Requesters and Repliers
123
     */
124
    ReturnCode_t enable() override;
125
126
    /**
127
     * @brief Disable the service
128
     *
129
     * @return RETCODE_OK if all topics were deleted and all internal requesters/repliers were disabled,
130
     * an specific error code otherwise
131
     */
132
    ReturnCode_t close() override;
133
134
    /**
135
     * @brief Check if the service is enabled
136
     */
137
    inline bool is_enabled() const override
138
0
    {
139
0
        return enabled_;
140
0
    }
141
142
    bool service_type_in_use(
143
            const std::string& service_type_name) const
144
0
    {
145
0
        return service_type_name_ == service_type_name;
146
0
    }
147
148
    /**
149
     * @brief Check if the service is empty (i.e: it has neither requesters nor repliers)
150
     */
151
    inline bool is_empty() const
152
0
    {
153
0
        return repliers_.empty() && requesters_.empty();
154
0
    }
155
156
    /**
157
     * @brief Validate the requester/replier's QoS. They should be consistent with the service configuration
158
     *
159
     * @param qos QoS to validate
160
     * @return True if the parameters are valid, false otherwise
161
     */
162
    template <typename T>
163
    bool validate_qos(
164
            const T& qos)
165
0
    {
166
167
0
        bool valid = true;
168
169
0
        if (qos.writer_qos.reliability().kind != RELIABLE_RELIABILITY_QOS)
170
0
        {
171
0
            EPROSIMA_LOG_ERROR(SERVICE, "Writer QoS reliability must be RELIABLE_RELIABILITY_QOS");
172
0
            valid = false;
173
0
        }
174
175
0
        if (qos.reader_qos.reliability().kind != RELIABLE_RELIABILITY_QOS)
176
0
        {
177
0
            EPROSIMA_LOG_ERROR(SERVICE, "Reader QoS reliability must be RELIABLE_RELIABILITY_QOS");
178
0
            valid = false;
179
0
        }
180
181
0
        return valid;
182
0
    }
Unexecuted instantiation: bool eprosima::fastdds::dds::rpc::ServiceImpl::validate_qos<eprosima::fastdds::dds::RequesterQos>(eprosima::fastdds::dds::RequesterQos const&)
Unexecuted instantiation: bool eprosima::fastdds::dds::rpc::ServiceImpl::validate_qos<eprosima::fastdds::dds::ReplierQos>(eprosima::fastdds::dds::ReplierQos const&)
183
184
    DomainParticipantImpl* get_participant()
185
0
    {
186
0
        return participant_;
187
0
    }
188
189
    PublisherImpl* get_publisher()
190
0
    {
191
0
        return service_publisher_;
192
0
    }
193
194
    SubscriberImpl* get_subscriber()
195
0
    {
196
0
        return service_subscriber_;
197
0
    }
198
199
    Topic* get_request_topic()
200
0
    {
201
0
        return request_topic_;
202
0
    }
203
204
    Topic* get_reply_topic()
205
0
    {
206
0
        return reply_topic_;
207
0
    }
208
209
    ContentFilteredTopic* get_reply_filtered_topic()
210
0
    {
211
0
        return reply_filtered_topic_;
212
0
    }
213
214
private:
215
216
    /**
217
     * @brief Create request and reply topics for the service
218
     *
219
     * @return RETCODE_OK if request/reply topics were created successfully, an specific error code otherwise
220
     */
221
    ReturnCode_t create_request_reply_topics();
222
223
    /**
224
     * @brief Delete all internal Requester and Replier entities
225
     *
226
     * @return RETCODE_OK if all entities were deleted successfully, an specific error code otherwise
227
     */
228
    ReturnCode_t delete_contained_entities();
229
230
    //! Service name
231
    std::string service_name_;
232
233
    //! Service type name
234
    std::string service_type_name_;
235
236
    //! Request topic info
237
    std::string request_topic_name_;
238
    std::string request_type_name_;
239
240
    //! Reply topic info
241
    std::string reply_topic_name_;
242
    std::string reply_type_name_;
243
    std::string reply_filtered_topic_name_;
244
245
    //! DDS Participant associated with the service
246
    DomainParticipantImpl* participant_;
247
248
    //! DDS Publisher used to create DataWriters for Requesters and Repliers
249
    PublisherImpl* service_publisher_;
250
251
    //! DDS Subscriber used to create DataReaders for Requesters and Repliers
252
    SubscriberImpl* service_subscriber_;
253
254
    //! Vector of repliers attached to the service
255
    std::vector<ReplierImpl*> repliers_;
256
257
    //! Mutex to protect the repliers list
258
    std::mutex mtx_repliers_;
259
260
    //! Vector of requesters attached to the service
261
    std::vector<RequesterImpl*> requesters_;
262
263
    //! Mutex to protect the requesters list
264
    std::mutex mtx_requesters_;
265
266
    //! Request and Reply topics associated with the service
267
    // NOTE: These topics do not filter samples. They are used to create the content filtered topics
268
    // If we use these topics to publish/subscribe in a multiple requester - single replier service scenario,
269
    // The requesters will receive all the replies, not only the ones that match their requests
270
    Topic* request_topic_;
271
    Topic* reply_topic_;
272
273
    //! Request and Reply filtered topics associated with the service.
274
    // In a multiple requester - single replier service scenario, each requester will discard the received replies destinated to another requester
275
    ContentFilteredTopic* reply_filtered_topic_;
276
277
    bool enabled_;
278
279
};
280
281
} // namespace rpc
282
} // namespace dds
283
} // namespace fastdds
284
} // namespace eprosima
285
286
#endif // FASTDDS_RPC__SERVICEIMPL_HPP