Coverage Report

Created: 2026-09-14 06:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/Fast-DDS/src/cpp/statistics/fastdds/domain/DomainParticipantImpl.cpp
Line
Count
Source
1
// Copyright 2021 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
/**
16
 * @file DomainParticipantImpl.cpp
17
 */
18
19
#include <statistics/fastdds/domain/DomainParticipantImpl.hpp>
20
21
#include <sstream>
22
#include <string>
23
#include <vector>
24
25
#include "../../../rtps/network/asio.hpp"
26
27
#include <fastdds/core/policy/QosPolicyUtils.hpp>
28
#include <fastdds/dds/core/ReturnCode.hpp>
29
#include <fastdds/dds/log/Log.hpp>
30
#include <fastdds/dds/publisher/DataWriter.hpp>
31
#include <fastdds/dds/publisher/qos/DataWriterQos.hpp>
32
#include <fastdds/dds/publisher/qos/PublisherQos.hpp>
33
#include <fastdds/dds/topic/qos/TopicQos.hpp>
34
#include <fastdds/dds/topic/Topic.hpp>
35
#include <fastdds/dds/topic/TopicDescription.hpp>
36
#include <fastdds/dds/topic/TypeSupport.hpp>
37
#include <fastdds/rtps/attributes/PropertyPolicy.hpp>
38
#include <fastdds/rtps/participant/RTPSParticipant.hpp>
39
#include <fastdds/statistics/dds/publisher/qos/DataWriterQos.hpp>
40
#include <fastdds/statistics/topic_names.hpp>
41
42
#include <fastdds/publisher/DataWriterImpl.hpp>
43
#include <fastdds/utils/QosConverters.hpp>
44
#include <statistics/fastdds/publisher/PublisherImpl.hpp>
45
#include <statistics/fastdds/subscriber/SubscriberImpl.hpp>
46
#include <statistics/rtps/GuidUtils.hpp>
47
#include <statistics/types/types.hpp>
48
#include <statistics/types/typesPubSubTypes.hpp>
49
#include <utils/SystemInfo.hpp>
50
#include <xmlparser/attributes/PublisherAttributes.hpp>
51
#include <xmlparser/XMLParserCommon.h>
52
#include <xmlparser/XMLProfileManager.h>
53
54
namespace eprosima {
55
namespace fastdds {
56
namespace statistics {
57
namespace dds {
58
59
using xmlparser::XMLProfileManager;
60
using xmlparser::XMLP_ret;
61
using xmlparser::DEFAULT_STATISTICS_DATAWRITER_PROFILE;
62
63
constexpr const char* HISTORY_LATENCY_TOPIC_ALIAS = "HISTORY_LATENCY_TOPIC";
64
constexpr const char* NETWORK_LATENCY_TOPIC_ALIAS = "NETWORK_LATENCY_TOPIC";
65
constexpr const char* PUBLICATION_THROUGHPUT_TOPIC_ALIAS = "PUBLICATION_THROUGHPUT_TOPIC";
66
constexpr const char* SUBSCRIPTION_THROUGHPUT_TOPIC_ALIAS = "SUBSCRIPTION_THROUGHPUT_TOPIC";
67
constexpr const char* RTPS_SENT_TOPIC_ALIAS = "RTPS_SENT_TOPIC";
68
constexpr const char* RTPS_LOST_TOPIC_ALIAS = "RTPS_LOST_TOPIC";
69
constexpr const char* RESENT_DATAS_TOPIC_ALIAS = "RESENT_DATAS_TOPIC";
70
constexpr const char* HEARTBEAT_COUNT_TOPIC_ALIAS = "HEARTBEAT_COUNT_TOPIC";
71
constexpr const char* ACKNACK_COUNT_TOPIC_ALIAS = "ACKNACK_COUNT_TOPIC";
72
constexpr const char* NACKFRAG_COUNT_TOPIC_ALIAS = "NACKFRAG_COUNT_TOPIC";
73
constexpr const char* GAP_COUNT_TOPIC_ALIAS = "GAP_COUNT_TOPIC";
74
constexpr const char* DATA_COUNT_TOPIC_ALIAS = "DATA_COUNT_TOPIC";
75
constexpr const char* PDP_PACKETS_TOPIC_ALIAS = "PDP_PACKETS_TOPIC";
76
constexpr const char* EDP_PACKETS_TOPIC_ALIAS = "EDP_PACKETS_TOPIC";
77
constexpr const char* DISCOVERY_TOPIC_ALIAS = "DISCOVERY_TOPIC";
78
constexpr const char* SAMPLE_DATAS_TOPIC_ALIAS = "SAMPLE_DATAS_TOPIC";
79
constexpr const char* PHYSICAL_DATA_TOPIC_ALIAS = "PHYSICAL_DATA_TOPIC";
80
constexpr const char* MONITOR_SERVICE_TOPIC_ALIAS = "MONITOR_SERVICE_TOPIC";
81
82
static constexpr uint32_t participant_statistics_mask =
83
        EventKind::RTPS_SENT | EventKind::RTPS_LOST | EventKind::NETWORK_LATENCY |
84
        EventKind::EDP_PACKETS | EventKind::PDP_PACKETS |
85
        EventKind::PHYSICAL_DATA | EventKind::DISCOVERED_ENTITY;
86
87
struct ValidEntry
88
{
89
    const char* alias;
90
    const char* name;
91
    uint32_t event_kind;
92
};
93
94
static const ValidEntry valid_entries[] =
95
{
96
    {HISTORY_LATENCY_TOPIC_ALIAS,         HISTORY_LATENCY_TOPIC,         EventKind::HISTORY2HISTORY_LATENCY},
97
    {NETWORK_LATENCY_TOPIC_ALIAS,         NETWORK_LATENCY_TOPIC,         EventKind::NETWORK_LATENCY},
98
    {PUBLICATION_THROUGHPUT_TOPIC_ALIAS,  PUBLICATION_THROUGHPUT_TOPIC,  EventKind::PUBLICATION_THROUGHPUT},
99
    {SUBSCRIPTION_THROUGHPUT_TOPIC_ALIAS, SUBSCRIPTION_THROUGHPUT_TOPIC, EventKind::SUBSCRIPTION_THROUGHPUT},
100
    {RTPS_SENT_TOPIC_ALIAS,               RTPS_SENT_TOPIC,               EventKind::RTPS_SENT},
101
    {RTPS_LOST_TOPIC_ALIAS,               RTPS_LOST_TOPIC,               EventKind::RTPS_LOST},
102
    {RESENT_DATAS_TOPIC_ALIAS,            RESENT_DATAS_TOPIC,            EventKind::RESENT_DATAS},
103
    {HEARTBEAT_COUNT_TOPIC_ALIAS,         HEARTBEAT_COUNT_TOPIC,         EventKind::HEARTBEAT_COUNT},
104
    {ACKNACK_COUNT_TOPIC_ALIAS,           ACKNACK_COUNT_TOPIC,           EventKind::ACKNACK_COUNT},
105
    {NACKFRAG_COUNT_TOPIC_ALIAS,          NACKFRAG_COUNT_TOPIC,          EventKind::NACKFRAG_COUNT},
106
    {GAP_COUNT_TOPIC_ALIAS,               GAP_COUNT_TOPIC,               EventKind::GAP_COUNT},
107
    {DATA_COUNT_TOPIC_ALIAS,              DATA_COUNT_TOPIC,              EventKind::DATA_COUNT},
108
    {PDP_PACKETS_TOPIC_ALIAS,             PDP_PACKETS_TOPIC,             EventKind::PDP_PACKETS},
109
    {EDP_PACKETS_TOPIC_ALIAS,             EDP_PACKETS_TOPIC,             EventKind::EDP_PACKETS},
110
    {DISCOVERY_TOPIC_ALIAS,               DISCOVERY_TOPIC,               EventKind::DISCOVERED_ENTITY},
111
    {SAMPLE_DATAS_TOPIC_ALIAS,            SAMPLE_DATAS_TOPIC,            EventKind::SAMPLE_DATAS},
112
    {PHYSICAL_DATA_TOPIC_ALIAS,           PHYSICAL_DATA_TOPIC,           EventKind::PHYSICAL_DATA}
113
};
114
115
ReturnCode_t DomainParticipantImpl::enable_statistics_datawriter(
116
        const std::string& topic_name,
117
        const efd::DataWriterQos& dwqos)
118
0
{
119
0
    std::string use_topic_name;
120
0
    uint32_t event_kind;
121
0
    if (!transform_and_check_topic_name(topic_name, use_topic_name, event_kind))
122
0
    {
123
0
        return efd::RETCODE_BAD_PARAMETER;
124
0
    }
125
126
0
    if (efd::RETCODE_OK != efd::DataWriterImpl::check_qos(dwqos))
127
0
    {
128
0
        return efd::RETCODE_INCONSISTENT_POLICY;
129
0
    }
130
131
    // Register type and topic
132
0
    efd::Topic* topic = nullptr;
133
0
    if (register_statistics_type_and_topic(&topic, use_topic_name))
134
0
    {
135
        // Check if the statistics DataWriter already exists and create statistics DataWriter if it does not.
136
0
        if (nullptr == builtin_publisher_->lookup_datawriter(use_topic_name))
137
0
        {
138
0
            fastdds::rtps::EntityId_t entity_id;
139
0
            set_statistics_entity_id(event_kind, entity_id);
140
0
            efd::TypeSupport type = participant_->find_type(topic->get_type_name());
141
0
            auto writer_impl = builtin_publisher_impl_->create_datawriter_impl(type, topic, dwqos, entity_id);
142
0
            auto data_writer = builtin_publisher_impl_->create_datawriter(topic, writer_impl, efd::StatusMask::all());
143
0
            if (nullptr == data_writer)
144
0
            {
145
                // Remove already created Impl
146
0
                delete writer_impl;
147
                // Remove topic and type
148
0
                delete_topic_and_type(use_topic_name);
149
0
                EPROSIMA_LOG_ERROR(STATISTICS_DOMAIN_PARTICIPANT, topic_name << " DataWriter creation has failed");
150
0
                return efd::RETCODE_ERROR;
151
0
            }
152
153
0
            if (PHYSICAL_DATA_TOPIC == use_topic_name)
154
0
            {
155
0
                PhysicalData notification;
156
0
                notification.participant_guid(*reinterpret_cast<const detail::GUID_s*>(&guid()));
157
0
                if (SystemInfo::instance().machine_id().size() > 0)
158
0
                {
159
0
                    notification.host(SystemInfo::instance().machine_id().to_string());
160
0
                }
161
0
                else
162
0
                {
163
0
                    notification.host(asio::ip::host_name() + ":" + std::to_string(efd::utils::default_domain_id()));
164
0
                }
165
0
                std::string username;
166
0
                if (efd::RETCODE_OK == SystemInfo::get_username(username))
167
0
                {
168
0
                    notification.user(username);
169
0
                }
170
0
                notification.process(std::to_string(SystemInfo::instance().process_id()));
171
172
0
                const void* data_sample = nullptr;
173
0
                data_sample = &notification;
174
175
0
                data_writer->write(const_cast<void*>(data_sample));
176
0
            }
177
0
            else
178
0
            {
179
0
                statistics_listener_->set_datawriter(event_kind, data_writer);
180
0
                rtps_participant_->set_enabled_statistics_writers_mask(statistics_listener_->enabled_writers_mask());
181
0
            }
182
0
        }
183
0
        return efd::RETCODE_OK;
184
0
    }
185
0
    return efd::RETCODE_ERROR;
186
0
}
187
188
ReturnCode_t DomainParticipantImpl::enable_statistics_datawriter_with_profile(
189
        const std::string& profile_name,
190
        const std::string& topic_name)
191
0
{
192
0
    DataWriterQos datawriter_qos;
193
0
    xmlparser::PublisherAttributes attr;
194
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fillPublisherAttributes(profile_name, attr, false))
195
0
    {
196
0
        efd::utils::set_qos_from_attributes(datawriter_qos, attr);
197
198
0
        ReturnCode_t ret = enable_statistics_datawriter(topic_name, datawriter_qos);
199
        // case efd::RETCODE_ERROR is checked and logged in enable_statistics_datawriter.
200
        // case efd::RETCODE_INCONSISTENT_POLICY could happen if profile defined in XML is inconsistent.
201
        // case efd::RETCODE_UNSUPPORTED cannot happen because this method is only called if FASTDDS_STATISTICS
202
        // CMake option is enabled
203
0
        if (ret == efd::RETCODE_INCONSISTENT_POLICY)
204
0
        {
205
0
            EPROSIMA_LOG_ERROR(STATISTICS_DOMAIN_PARTICIPANT,
206
0
                    "Statistics DataWriter QoS from profile name " << profile_name << " are not consistent/compatible");
207
0
        }
208
0
        assert(ret != efd::RETCODE_UNSUPPORTED);
209
0
        if (ret == efd::RETCODE_BAD_PARAMETER)
210
0
        {
211
0
            EPROSIMA_LOG_ERROR(STATISTICS_DOMAIN_PARTICIPANT,
212
0
                    "Profile name " << profile_name << " is not a valid statistics topic name/alias");
213
0
        }
214
0
        return ret;
215
0
    }
216
0
    EPROSIMA_LOG_ERROR(STATISTICS_DOMAIN_PARTICIPANT,
217
0
            "Profile name " << profile_name << " has not been found");
218
0
    return efd::RETCODE_ERROR;
219
0
}
220
221
ReturnCode_t DomainParticipantImpl::disable_statistics_datawriter(
222
        const std::string& topic_name)
223
0
{
224
0
    ReturnCode_t ret = efd::RETCODE_OK;
225
0
    std::string use_topic_name;
226
0
    uint32_t event_kind;
227
0
    if (!transform_and_check_topic_name(topic_name, use_topic_name, event_kind))
228
0
    {
229
0
        return efd::RETCODE_BAD_PARAMETER;
230
0
    }
231
232
    // Delete statistics DataWriter
233
    // delete_datawriter does not check that the provided argument is not nullptr (safety check)
234
0
    efd::DataWriter* writer = builtin_publisher_->lookup_datawriter(use_topic_name);
235
0
    if (nullptr != writer)
236
0
    {
237
        // Avoid calling DataWriter from listener callback
238
0
        statistics_listener_->set_datawriter(event_kind, nullptr);
239
0
        rtps_participant_->set_enabled_statistics_writers_mask(statistics_listener_->enabled_writers_mask());
240
241
        // Delete the DataWriter
242
0
        if (efd::RETCODE_OK != builtin_publisher_->delete_datawriter(writer))
243
0
        {
244
            // Restore writer on listener before returning the error
245
0
            statistics_listener_->set_datawriter(event_kind, writer);
246
0
            rtps_participant_->set_enabled_statistics_writers_mask(statistics_listener_->enabled_writers_mask());
247
0
            ret = efd::RETCODE_ERROR;
248
0
        }
249
250
        // Deregister type and delete topic
251
0
        if (!delete_topic_and_type(use_topic_name))
252
0
        {
253
0
            ret = efd::RETCODE_ERROR;
254
0
        }
255
0
    }
256
0
    return ret;
257
0
}
258
259
ReturnCode_t DomainParticipantImpl::enable()
260
0
{
261
0
    ReturnCode_t ret = efd::DomainParticipantImpl::enable();
262
263
0
    if (efd::RETCODE_OK == ret)
264
0
    {
265
0
        rtps_participant_->add_statistics_listener(statistics_listener_, participant_statistics_mask);
266
0
        create_statistics_builtin_entities();
267
268
0
        if (!rtps_participant_->is_monitor_service_created())
269
0
        {
270
0
            auto enable_ms_property_value = fastdds::rtps::PropertyPolicyHelper::find_property(
271
0
                qos_.properties(), fastdds::dds::parameter_enable_monitor_service);
272
273
0
            if (nullptr != enable_ms_property_value && *enable_ms_property_value == "true")
274
0
            {
275
0
                if (enable_monitor_service() != efd::RETCODE_OK)
276
0
                {
277
0
                    EPROSIMA_LOG_ERROR(STATISTICS_DOMAIN_PARTICIPANT, "Could not enable the Monitor Service");
278
0
                }
279
0
            }
280
0
        }
281
0
    }
282
283
0
    return ret;
284
0
}
285
286
void DomainParticipantImpl::disable()
287
0
{
288
0
    if (nullptr != rtps_participant_)
289
0
    {
290
0
        rtps_participant_->remove_statistics_listener(statistics_listener_, participant_statistics_mask);
291
0
    }
292
0
    efd::DomainParticipantImpl::disable();
293
0
}
294
295
ReturnCode_t DomainParticipantImpl::delete_contained_entities()
296
0
{
297
0
    delete_statistics_builtin_entities();
298
0
    return efd::DomainParticipantImpl::delete_contained_entities();
299
0
}
300
301
ReturnCode_t DomainParticipantImpl::enable_monitor_service()
302
0
{
303
0
    ReturnCode_t ret = efd::RETCODE_OK;
304
305
0
    if (!rtps_participant_->is_monitor_service_created())
306
0
    {
307
0
        status_observer_.store(rtps_participant_->create_monitor_service(*this));
308
0
    }
309
310
0
    if (!rtps_participant_->enable_monitor_service() ||
311
0
            nullptr == status_observer_)
312
0
    {
313
0
        ret = efd::RETCODE_ERROR;
314
0
    }
315
316
0
    return ret;
317
0
}
318
319
ReturnCode_t DomainParticipantImpl::disable_monitor_service()
320
0
{
321
0
    ReturnCode_t ret = efd::RETCODE_OK;
322
323
0
    if (!rtps_participant_->is_monitor_service_created() ||
324
0
            !rtps_participant_->disable_monitor_service())
325
0
    {
326
0
        ret = efd::RETCODE_NOT_ENABLED;
327
0
    }
328
329
0
    return ret;
330
0
}
331
332
ReturnCode_t DomainParticipantImpl::fill_discovery_data_from_cdr_message(
333
        fastdds::rtps::ParticipantBuiltinTopicData& data,
334
        const fastdds::statistics::MonitorServiceStatusData& msg)
335
0
{
336
0
    ReturnCode_t ret{efd::RETCODE_OK};
337
338
0
    if (!get_rtps_participant()->fill_discovery_data_from_cdr_message(data, msg))
339
0
    {
340
0
        ret = efd::RETCODE_ERROR;
341
0
    }
342
343
0
    return ret;
344
0
}
345
346
ReturnCode_t DomainParticipantImpl::fill_discovery_data_from_cdr_message(
347
        fastdds::dds::PublicationBuiltinTopicData& data,
348
        const fastdds::statistics::MonitorServiceStatusData& msg)
349
0
{
350
0
    ReturnCode_t ret{efd::RETCODE_OK};
351
352
0
    if (!get_rtps_participant()->fill_discovery_data_from_cdr_message(data, msg))
353
0
    {
354
0
        ret = efd::RETCODE_ERROR;
355
0
    }
356
357
0
    return ret;
358
0
}
359
360
ReturnCode_t DomainParticipantImpl::fill_discovery_data_from_cdr_message(
361
        fastdds::dds::SubscriptionBuiltinTopicData& data,
362
        const fastdds::statistics::MonitorServiceStatusData& msg)
363
0
{
364
0
    ReturnCode_t ret{efd::RETCODE_OK};
365
366
0
    if (!get_rtps_participant()->fill_discovery_data_from_cdr_message(data, msg))
367
0
    {
368
0
        ret = efd::RETCODE_ERROR;
369
0
    }
370
371
0
    return ret;
372
0
}
373
374
efd::PublisherImpl* DomainParticipantImpl::create_publisher_impl(
375
        const efd::PublisherQos& qos,
376
        efd::PublisherListener* listener)
377
0
{
378
0
    return new PublisherImpl(this, qos, listener, statistics_listener_);
379
0
}
380
381
efd::SubscriberImpl* DomainParticipantImpl::create_subscriber_impl(
382
        const efd::SubscriberQos& qos,
383
        efd::SubscriberListener* listener)
384
0
{
385
0
    return new SubscriberImpl(this, qos, listener, statistics_listener_);
386
0
}
387
388
void DomainParticipantImpl::create_statistics_builtin_entities()
389
0
{
390
0
    efd::PublisherImpl* builtin_publisher_impl = nullptr;
391
392
    // Builtin publisher
393
0
    builtin_publisher_ = create_publisher(efd::PUBLISHER_QOS_DEFAULT, &builtin_publisher_impl);
394
395
0
    builtin_publisher_impl_ = dynamic_cast<PublisherImpl*>(builtin_publisher_impl);
396
0
    assert(nullptr != builtin_publisher_impl_);
397
398
    // Enable statistics datawriters
399
    // 1. Find fastdds_statistics PropertyPolicyQos
400
0
    const std::string* property_topic_list = eprosima::fastdds::rtps::PropertyPolicyHelper::find_property(
401
0
        get_qos().properties(), "fastdds.statistics");
402
403
0
    if (nullptr != property_topic_list)
404
0
    {
405
0
        enable_statistics_builtin_datawriters(*property_topic_list);
406
0
    }
407
408
    // 2. FASTDDS_STATISTICS environment variable
409
0
    std::string env_topic_list;
410
0
    SystemInfo::get_env(FASTDDS_STATISTICS_ENVIRONMENT_VARIABLE, env_topic_list);
411
412
0
    if (!env_topic_list.empty())
413
0
    {
414
0
        enable_statistics_builtin_datawriters(env_topic_list);
415
0
    }
416
0
}
417
418
void DomainParticipantImpl::enable_statistics_builtin_datawriters(
419
        const std::string& topic_list)
420
0
{
421
    // Parse list and call enable_statistics_datawriter
422
0
    std::stringstream topics(topic_list);
423
0
    std::string topic;
424
0
    while (std::getline(topics, topic, ';'))
425
0
    {
426
0
        if (MONITOR_SERVICE_TOPIC_ALIAS == topic)
427
0
        {
428
0
            if (!rtps_participant_->is_monitor_service_created() &&
429
0
                    enable_monitor_service() != efd::RETCODE_OK)
430
0
            {
431
0
                EPROSIMA_LOG_ERROR(STATISTICS_DOMAIN_PARTICIPANT, "Could not enable the Monitor Service");
432
0
            }
433
0
            continue;
434
0
        }
435
436
0
        DataWriterQos datawriter_qos;
437
0
        xmlparser::PublisherAttributes attr;
438
0
        if (XMLP_ret::XML_OK == XMLProfileManager::fillPublisherAttributes(topic, attr, false))
439
0
        {
440
0
            efd::utils::set_qos_from_attributes(datawriter_qos, attr);
441
0
        }
442
0
        else if (XMLP_ret::XML_OK ==
443
0
                XMLProfileManager::fillPublisherAttributes(DEFAULT_STATISTICS_DATAWRITER_PROFILE, attr, false))
444
0
        {
445
0
            efd::utils::set_qos_from_attributes(datawriter_qos, attr);
446
0
        }
447
448
0
        ReturnCode_t ret = enable_statistics_datawriter(topic, datawriter_qos);
449
        // case efd::RETCODE_ERROR is checked and logged in enable_statistics_datawriter.
450
        // case efd::RETCODE_INCONSISTENT_POLICY could happen if profile defined in XML is inconsistent.
451
        // case efd::RETCODE_UNSUPPORTED cannot happen because this method is only called if FASTDDS_STATISTICS
452
        // CMake option is enabled
453
0
        if (ret == efd::RETCODE_INCONSISTENT_POLICY)
454
0
        {
455
0
            EPROSIMA_LOG_ERROR(STATISTICS_DOMAIN_PARTICIPANT,
456
0
                    "Statistics DataWriter QoS from topic " << topic << " are not consistent/compatible");
457
0
        }
458
0
        assert(ret != efd::RETCODE_UNSUPPORTED);
459
0
        if (ret == efd::RETCODE_BAD_PARAMETER)
460
0
        {
461
0
            EPROSIMA_LOG_ERROR(STATISTICS_DOMAIN_PARTICIPANT,
462
0
                    "Topic " << topic << " is not a valid statistics topic name/alias");
463
0
        }
464
0
    }
465
0
}
466
467
void DomainParticipantImpl::delete_statistics_builtin_entities()
468
0
{
469
0
    if (nullptr != builtin_publisher_)
470
0
    {
471
0
        std::vector<efd::DataWriter*> builtin_writers;
472
0
        builtin_publisher_->get_datawriters(builtin_writers);
473
0
        for (auto writer : builtin_writers)
474
0
        {
475
0
            std::string topic_name = writer->get_topic()->get_name();
476
0
            disable_statistics_datawriter(topic_name);
477
0
        }
478
479
        // Delete builtin_publisher
480
0
        delete_publisher(builtin_publisher_);
481
0
        builtin_publisher_ = nullptr;
482
0
        builtin_publisher_impl_ = nullptr;
483
0
    }
484
0
}
485
486
bool DomainParticipantImpl::is_statistics_topic_name(
487
        const std::string& topic_name) noexcept
488
0
{
489
0
    for (const ValidEntry& entry : valid_entries)
490
0
    {
491
0
        if (entry.name == topic_name)
492
0
        {
493
0
            return true;
494
0
        }
495
0
    }
496
497
0
    return false;
498
0
}
499
500
bool DomainParticipantImpl::transform_and_check_topic_name(
501
        const std::string& topic_name_or_alias,
502
        std::string& topic_name,
503
        uint32_t& event_kind) noexcept
504
0
{
505
0
    for (const ValidEntry& entry : valid_entries)
506
0
    {
507
0
        if ((entry.alias == topic_name_or_alias) || (entry.name == topic_name_or_alias))
508
0
        {
509
0
            topic_name = entry.name;
510
0
            event_kind = entry.event_kind;
511
0
            return true;
512
0
        }
513
0
    }
514
515
0
    return false;
516
0
}
517
518
bool DomainParticipantImpl::register_statistics_type_and_topic(
519
        efd::Topic** topic,
520
        const std::string& topic_name) noexcept
521
0
{
522
0
    bool return_code = false;
523
0
    if (HISTORY_LATENCY_TOPIC == topic_name)
524
0
    {
525
0
        efd::TypeSupport history_latency_type(new WriterReaderDataPubSubType);
526
0
        history_latency_type->register_type_object_representation();
527
0
        return_code = find_or_create_topic_and_type(topic, topic_name, history_latency_type);
528
0
    }
529
0
    else if (NETWORK_LATENCY_TOPIC == topic_name)
530
0
    {
531
0
        efd::TypeSupport network_latency_type(new Locator2LocatorDataPubSubType);
532
0
        network_latency_type->register_type_object_representation();
533
0
        return_code = find_or_create_topic_and_type(topic, topic_name, network_latency_type);
534
0
    }
535
0
    else if (PUBLICATION_THROUGHPUT_TOPIC == topic_name || SUBSCRIPTION_THROUGHPUT_TOPIC == topic_name)
536
0
    {
537
0
        efd::TypeSupport throughput_type(new EntityDataPubSubType);
538
0
        throughput_type->register_type_object_representation();
539
0
        return_code = find_or_create_topic_and_type(topic, topic_name, throughput_type);
540
0
    }
541
0
    else if (RTPS_SENT_TOPIC == topic_name || RTPS_LOST_TOPIC == topic_name)
542
0
    {
543
0
        efd::TypeSupport rtps_traffic_type(new Entity2LocatorTrafficPubSubType);
544
0
        rtps_traffic_type->register_type_object_representation();
545
0
        return_code = find_or_create_topic_and_type(topic, topic_name, rtps_traffic_type);
546
0
    }
547
0
    else if (RESENT_DATAS_TOPIC == topic_name || HEARTBEAT_COUNT_TOPIC == topic_name ||
548
0
            ACKNACK_COUNT_TOPIC == topic_name || NACKFRAG_COUNT_TOPIC == topic_name || GAP_COUNT_TOPIC == topic_name ||
549
0
            DATA_COUNT_TOPIC == topic_name || PDP_PACKETS_TOPIC == topic_name || EDP_PACKETS_TOPIC == topic_name)
550
0
    {
551
0
        efd::TypeSupport count_type(new EntityCountPubSubType);
552
0
        count_type->register_type_object_representation();
553
0
        return_code = find_or_create_topic_and_type(topic, topic_name, count_type);
554
0
    }
555
0
    else if (DISCOVERY_TOPIC == topic_name)
556
0
    {
557
0
        efd::TypeSupport discovery_type(new DiscoveryTimePubSubType);
558
0
        discovery_type->register_type_object_representation();
559
0
        return_code = find_or_create_topic_and_type(topic, topic_name, discovery_type);
560
0
    }
561
0
    else if (SAMPLE_DATAS_TOPIC == topic_name)
562
0
    {
563
0
        efd::TypeSupport sample_identity_count_type(new SampleIdentityCountPubSubType);
564
0
        sample_identity_count_type->register_type_object_representation();
565
0
        return_code = find_or_create_topic_and_type(topic, topic_name, sample_identity_count_type);
566
0
    }
567
0
    else if (PHYSICAL_DATA_TOPIC == topic_name)
568
0
    {
569
0
        efd::TypeSupport physical_data_type(new PhysicalDataPubSubType);
570
0
        physical_data_type->register_type_object_representation();
571
0
        return_code = find_or_create_topic_and_type(topic, topic_name, physical_data_type);
572
0
    }
573
0
    return return_code;
574
0
}
575
576
bool DomainParticipantImpl::find_or_create_topic_and_type(
577
        efd::Topic** topic,
578
        const std::string& topic_name,
579
        const efd::TypeSupport& type) noexcept
580
0
{
581
    // Find if the topic has been already created and if the associated type is correct
582
0
    efd::TopicDescription* topic_desc = lookup_topicdescription(topic_name);
583
0
    if (nullptr != topic_desc)
584
0
    {
585
0
        if (topic_desc->get_type_name() != type->get_name())
586
0
        {
587
0
            EPROSIMA_LOG_ERROR(STATISTICS_DOMAIN_PARTICIPANT,
588
0
                    topic_name << " is not using expected type " << type->get_name()
589
0
                               << " and is using instead type " << topic_desc->get_type_name());
590
0
            return false;
591
0
        }
592
0
        else
593
0
        {
594
            // TODO(jlbueno) This casting should be checked after other TopicDescription implementations are
595
            // included: ContentFilteredTopic, MultiTopic.
596
0
            *topic = dynamic_cast<efd::Topic*>(topic_desc);
597
0
        }
598
0
    }
599
0
    else
600
0
    {
601
0
        if (efd::RETCODE_PRECONDITION_NOT_MET == register_type(type, type->get_name()))
602
0
        {
603
            // No log because it is already logged within register_type
604
0
            return false;
605
0
        }
606
        // Create topic. No need to check return pointer. It fails if the topic already exists, if the QoS is
607
        // inconsistent or if the type is not registered.
608
0
        *topic = create_topic(topic_name, type->get_name(), efd::TOPIC_QOS_DEFAULT);
609
0
    }
610
0
    assert(nullptr != *topic);
611
0
    return true;
612
0
}
613
614
bool DomainParticipantImpl::delete_topic_and_type(
615
        const std::string& topic_name) noexcept
616
0
{
617
0
    efd::TopicDescription* topic_desc = lookup_topicdescription(topic_name);
618
0
    assert(nullptr != topic_desc);
619
620
0
    if (topic_desc)
621
0
    {
622
0
        efd::Topic* topic = dynamic_cast<efd::Topic*>(topic_desc);
623
624
0
        if (topic)
625
0
        {
626
0
            std::string type_name = topic->get_type_name();
627
            // delete_topic can fail if the topic is referenced by any other entity. This case could happen even if
628
            // it should not. It also fails if topic is a nullptr (dynamic_cast failure).
629
0
            if (efd::RETCODE_OK != delete_topic(topic))
630
0
            {
631
0
                return false;
632
0
            }
633
            // unregister_type failures are of no concern here. It will fail if the type is still in use (something
634
            // expected) and if the type_name is empty (which is not going to happen).
635
0
            unregister_type(type_name);
636
0
            return true;
637
0
        }
638
0
    }
639
640
0
    return false;
641
0
}
642
643
bool DomainParticipantImpl::get_monitoring_status(
644
        const fastdds::rtps::GUID_t& entity_guid,
645
        eprosima::fastdds::statistics::MonitorServiceData& status)
646
0
{
647
0
    ReturnCode_t ret = efd::RETCODE_ERROR;
648
649
0
    if (entity_guid.entityId.is_reader())
650
0
    {
651
0
        std::lock_guard<std::mutex> lock(mtx_subs_);
652
0
        for (auto& sub : subscribers_)
653
0
        {
654
0
            if (sub.second->get_monitoring_status(status, entity_guid))
655
0
            {
656
0
                ret = efd::RETCODE_OK;
657
0
                break;
658
0
            }
659
0
        }
660
0
    }
661
0
    else if (entity_guid.entityId.is_writer())
662
0
    {
663
0
        std::lock_guard<std::mutex> lock(mtx_pubs_);
664
0
        for (auto& pub : publishers_)
665
0
        {
666
0
            if (pub.second->get_monitoring_status(status, entity_guid))
667
0
            {
668
0
                ret = efd::RETCODE_OK;
669
0
                break;
670
0
            }
671
0
        }
672
0
    }
673
0
    else
674
0
    {
675
0
        EPROSIMA_LOG_ERROR(STATISTICS_DOMAIN_PARTICIPANT,
676
0
                "Unknown entity type to get the status from " << entity_guid.entityId);
677
0
    }
678
679
0
    return (ret == efd::RETCODE_OK);
680
0
}
681
682
} // dds
683
} // statistics
684
} // fastdds
685
} // eprosima