-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathDDSRouterImpl.hpp
More file actions
365 lines (317 loc) · 11.4 KB
/
DDSRouterImpl.hpp
File metadata and controls
365 lines (317 loc) · 11.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
// Copyright 2021 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @file DDSRouterImpl.hpp
*/
#ifndef __SRC__SRC_DDSROUTERCORE_CORE_DDSROUTERIMPL_HPP_
#define __SRC__SRC_DDSROUTERCORE_CORE_DDSROUTERIMPL_HPP_
#include <atomic>
#include <map>
#include <mutex>
#include <ddsrouter_utils/ReturnCode.hpp>
#include <ddsrouter_utils/thread/manager/IManager.hpp>
#include <ddsrouter_utils/thread/manager/StdThreadPool.hpp>
#include <communication/DDSBridge.hpp>
#include <communication/rpc/RPCBridge.hpp>
#include <dynamic/AllowedTopicList.hpp>
#include <dynamic/DiscoveryDatabase.hpp>
#include <library/library_dll.h>
#include <participant/IParticipant.hpp>
#include <core/ParticipantsDatabase.hpp>
#include <core/ParticipantFactory.hpp>
#include <ddsrouter_core/configuration/DDSRouterConfiguration.hpp>
#include <ddsrouter_core/configuration/DDSRouterReloadConfiguration.hpp>
#include <ddsrouter_core/types/endpoint/Endpoint.hpp>
namespace eprosima {
namespace ddsrouter {
namespace core {
/**
* TODO
*/
class DDSRouterImpl
{
public:
/**
* @brief Construct a new DDSRouterImpl object
*
* Initialize a whole DDSRouterImpl:
* - Create its associated AllowedTopicList
* - Create Participants and add them to \c ParticipantsDatabase
* - Create the Bridges for RealTopics as disabled (TODO: remove when discovery is ready)
*
* @param [in] configuration : Configuration for the new DDS Router
*
* @throw \c ConfigurationException in case the yaml inside allowlist is not well-formed
* @throw \c InitializationException in case \c IParticipants , \c IWriters or \c IReaders creation fails.
*/
DDSRouterImpl(
const configuration::DDSRouterConfiguration& configuration);
/**
* @brief Destroy the DDSRouterImpl object
*
* Stop the DDSRouterImpl
* Destroy all Bridges
* Destroy all Participants
*/
virtual ~DDSRouterImpl();
// EVENTS
/**
* @brief Reload the allowed topic configuration
*
* @param [in] configuration : new configuration
*
* @return \c RETCODE_OK if configuration has been updated correctly
* @return \c RETCODE_NO_DATA if new configuration has not changed
* @return \c RETCODE_ERROR if any other error has occurred
*
* @throw \c ConfigurationException in case the new yaml is not well-formed
*/
utils::ReturnCode reload_configuration(
const configuration::DDSRouterReloadConfiguration& configuration);
/**
* @brief Start communication in DDS Router
*
* Enable every topic Bridge.
*
* @note this method returns a ReturnCode for future possible errors
*
* @return \c RETCODE_OK always
*/
utils::ReturnCode start() noexcept;
/**
* @brief Stop communication in DDS Router
*
* Disable every topic Bridge.
*
* @note this method returns a ReturnCode for future possible errors
*
* @return \c RETCODE_OK always
*/
utils::ReturnCode stop() noexcept;
protected:
/**
* @brief Internal Start method
*
* Enable every topic Bridge.
*
* @note this method returns a ReturnCode for future possible errors
*
* @return \c RETCODE_OK if ok
* @return \c RETCODE_PRECONDITION_NOT_MET if Router was not disabled
*/
utils::ReturnCode start_() noexcept;
/**
* @brief Internal Stop method
*
* Disable every topic Bridge.
*
* @note this method returns a ReturnCode for future possible errors
*
* @return \c RETCODE_OK if ok
* @return \c RETCODE_PRECONDITION_NOT_MET if Router was not enabled
*/
utils::ReturnCode stop_() noexcept;
/////
// INTERNAL INITIALIZATION METHODS
/**
* @brief Load allowed topics from configuration
*
* @throw \c ConfigurationException in case the yaml inside allowlist is not well-formed
*/
void init_allowed_topics_();
/**
* @brief Create participants and add them to the participants database
*
* @throw \c ConfigurationException in case a Participant is not well configured (e.g. No kind)
* @throw \c InitializationException in case \c IParticipants creation fails.
*/
void init_participants_();
/**
* @brief Create a disabled bridge for every real topic
*/
void init_bridges_();
/////
// INTERNAL AUXILIAR METHODS
/**
* @brief Method called every time a new endpoint has been discovered/updated
*
* This method is called with the topic of a new/updated \c Endpoint discovered.
* If the DDSRouterImpl is enabled, the new Bridge is created and enabled.
*
* @note This is the only method that adds topics to \c current_topics_
*
* @param [in] topic : topic discovered
*/
void discovered_topic_(
const types::RealTopic& topic) noexcept;
/**
* @brief Method called every time a new endpoint (corresponding to a server) has been discovered/updated
*
* This method is called with the topic of a new/updated \c Endpoint discovered.
* If the DDSRouterImpl is enabled and no bridge exists, the new RPCBridge is created (and enabled if allowed).
*
* @note This is the only method that adds topics to \c current_services_
*
* @param [in] topic : topic discovered
* @param [in] server_participant_id : id of participant discovering server
* @param [in] server_guid_prefix : GUID Prefix of discovered server
*/
void discovered_service_(
const types::RPCTopic& topic,
const types::ParticipantId& server_participant_id,
const types::GuidPrefix& server_guid_prefix) noexcept;
/**
* @brief Method called every time a new endpoint (corresponding to a server) has been removed/dropped
*
* This method is called with the topic of a removed/dropped \c Endpoint.
*
* @param [in] topic : topic discovered
* @param [in] server_participant_id : id of participant discovering server
* @param [in] server_guid_prefix : GUID Prefix of discovered server
*/
void removed_service_(
const types::RPCTopic& topic,
const types::ParticipantId& server_participant_id,
const types::GuidPrefix& server_guid_prefix) noexcept;
/**
* @brief Method called every time a new endpoint has been discovered/updated
*
* This method calls \c discovered_topic_ with the topic of \c endpoint as parameter.
*
* @param [in] endpoint : endpoint discovered
*/
void discovered_endpoint_(
const types::Endpoint& endpoint) noexcept;
/**
* @brief Method called every time a new endpoint has been removed/dropped
*
* @param [in] endpoint : endpoint removed/dropped
*/
void removed_endpoint_(
const types::Endpoint& endpoint) noexcept;
/**
* @brief Create a new \c DDSBridge object
*
* It is created enabled if the DDSRouterImpl is enabled.
*
* @param [in] topic : new topic
*/
void create_new_bridge(
const types::RealTopic& topic,
bool enabled = false) noexcept;
/**
* @brief Create a new \c RPCBridge object
*
* It is always created disabled.
*
* @param [in] topic : new topic
*/
void create_new_service(
const types::RPCTopic& topic) noexcept;
/**
* @brief Enable a specific topic
*
* If the topic did not exist before, the Bridge is created.
*
* @param [in] topic : Topic to be enabled
*/
void activate_topic_(
const types::RealTopic& topic) noexcept;
/**
* @brief Disable a specific topic.
*
* If the Bridge of the topic does not exist, do nothing.
*
* @param [in] topic : Topic to be disabled
*/
void deactivate_topic_(
const types::RealTopic& topic) noexcept;
/**
* @brief Activate all Topics that are allowed by the allowed topics list
*/
void activate_all_topics_() noexcept;
/**
* @brief Disable all Bridges
*/
void deactivate_all_topics_() noexcept;
/////
// DATA STORAGE
/**
* @brief Common payload pool where every payload will be stored
*
* This payload will be shared by every endpoint.
* Every reader will store its data in the pool, the track will pass this
* data to the writers, that will release it after used.
*/
std::shared_ptr<PayloadPool> payload_pool_;
/**
* @brief Object that stores every Participant running in the DDSRouterImpl
*/
std::shared_ptr<ParticipantsDatabase> participants_database_;
/**
* @brief Common discovery database
*
* This object is shared by every Participant.
* Every time an endpoint is discovered by any Participant, it should be
* added to the database.
*/
std::shared_ptr<DiscoveryDatabase> discovery_database_;
//! Map of bridges indexed by their topic
std::map<types::RealTopic, std::unique_ptr<DDSBridge>> bridges_;
//! Map of RPC bridges indexed by their topic
std::map<types::RPCTopic, std::unique_ptr<RPCBridge>> rpc_bridges_;
/**
* @brief List of topics discovered
*
* Every topic discovered would be added to this map.
* If the value is true, it means this topic is currently activated.
*/
std::map<types::RealTopic, bool> current_topics_;
/**
* @brief List of RPC topics discovered
*
* Every RPC topic discovered would is added to this map.
* If the value is true, it means this service is allowed.
*/
std::map<types::RPCTopic, bool> current_services_;
//! DDSRouterImpl configuration
configuration::DDSRouterConfiguration configuration_;
//! List of allowed and blocked topics
AllowedTopicList allowed_topics_;
//! Participant factory instance
ParticipantFactory participant_factory_;
/////
// AUXILIAR VARIABLES
//! Whether the DDSRouterImpl is currently communicating data or not
std::atomic<bool> enabled_;
//! Internal mutex for concurrent calls
std::recursive_mutex mutex_;
/**
* @warning \c thread_manager_ and \c thread_pool_ reference the same object.
*
* @brief Couple of variables that reference the same object StdThreadPool.
*
* While \c thread_pool_ is used internally to start and stop Thread Pool (and methods specific from ThreadPool
* and not from IManager) \c thread_manager_ is used to pass it to other entities as a shared entity that need
* to use a IManager.
*
* The use of both variables is just to avoid the casting when using StdThreadPool specific methods.
*/
utils::thread::StdThreadPool* thread_pool_;
std::shared_ptr<utils::thread::IManager> thread_manager_;
};
} /* namespace core */
} /* namespace ddsrouter */
} /* namespace eprosima */
#endif /* __SRC__SRC_DDSROUTERCORE_CORE_DDSROUTERIMPL_HPP_ */