Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[20274] Validate the YAML configuration file on parsing #69

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 54 additions & 39 deletions fastddsspy_tool/src/cpp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <cpp_utils/types/Fuzzy.hpp>
#include <cpp_utils/utils.hpp>

#include <ddspipe_core/configuration/DdsPipeLogConfiguration.hpp>
#include <ddspipe_core/core/DdsPipe.hpp>
#include <ddspipe_core/dynamic/ParticipantsDatabase.hpp>
#include <ddspipe_core/dynamic/DiscoveryDatabase.hpp>
Expand All @@ -47,6 +48,11 @@
#include "user_interface/ProcessReturnCode.hpp"
#include "tool/Controller.hpp"


int exit(const eprosima::spy::ProcessReturnCode& code);
void register_log_consumers(const eprosima::ddspipe::core::DdsPipeLogConfiguration& configuration);


int main(
int argc,
char** argv)
Expand All @@ -60,15 +66,15 @@ int main(

if (arg_parse_result == eprosima::spy::ProcessReturnCode::help_argument)
{
return static_cast<int>(eprosima::spy::ProcessReturnCode::success);
return exit(eprosima::spy::ProcessReturnCode::success);
}
else if (arg_parse_result == eprosima::spy::ProcessReturnCode::version_argument)
{
return static_cast<int>(eprosima::spy::ProcessReturnCode::success);
return exit(eprosima::spy::ProcessReturnCode::success);
}
else if (arg_parse_result != eprosima::spy::ProcessReturnCode::success)
{
return static_cast<int>(arg_parse_result);
return exit(arg_parse_result);
}

// Check file is in args, else get the default file
Expand All @@ -95,6 +101,12 @@ int main(
// Encapsulating execution in block to erase all memory correctly before closing process
try
{
// Register the LogConsumers to log the YAML configuration errors
eprosima::ddspipe::core::DdsPipeLogConfiguration log_configuration;
log_configuration.set(eprosima::utils::VerbosityKind::Warning);

register_log_consumers(log_configuration);

/////
// Fast DDS Spy Initialization

Expand All @@ -109,37 +121,8 @@ int main(
eprosima::spy::yaml::Configuration configuration = eprosima::spy::yaml::Configuration(
commandline_args.file_path, &commandline_args);

// Debug
{
const auto log_configuration = configuration.ddspipe_configuration.log_configuration;

// Remove every consumer
eprosima::utils::Log::ClearConsumers();

// Activate log with verbosity, as this will avoid running log thread with not desired kind
eprosima::utils::Log::SetVerbosity(configuration.ddspipe_configuration.log_configuration.verbosity);

// Stdout Log Consumer
if (log_configuration.stdout_enable)
{
eprosima::utils::Log::RegisterConsumer(
std::make_unique<eprosima::utils::StdLogConsumer>(&log_configuration));
}

// DDS Log Consumer
if (log_configuration.publish.enable)
{
eprosima::utils::Log::RegisterConsumer(
std::make_unique<eprosima::ddspipe::core::DdsLogConsumer>(&log_configuration));
}

// NOTE:
// It will not filter any log, so Fast DDS logs will be visible unless Fast DDS is compiled
// in non debug or with LOG_NO_INFO=ON.
// This is the easiest way to allow to see Warnings and Errors from Fast DDS.
// Change it when Log Module is independent and with more extensive API.
// eprosima::utils::Log::SetCategoryFilter(std::regex("(ddspipe|FASTDDSSPY)"));
}
register_log_consumers(configuration.ddspipe_configuration.log_configuration);

// Create the Spy
eprosima::spy::Controller spy(configuration);

Expand Down Expand Up @@ -236,21 +219,53 @@ int main(
"Error Loading Fast DDS Spy Configuration from file " << commandline_args.file_path <<
". Error message:\n " <<
e.what());
return static_cast<int>(eprosima::spy::ProcessReturnCode::execution_failed);
return exit(eprosima::spy::ProcessReturnCode::execution_failed);
}
catch (const eprosima::utils::InitializationException& e)
{
EPROSIMA_LOG_ERROR(FASTDDSSPY_TOOL,
"Error Initializing Fast DDS Spy. Error message:\n " <<
e.what());
return static_cast<int>(eprosima::spy::ProcessReturnCode::execution_failed);
return exit(eprosima::spy::ProcessReturnCode::execution_failed);
}

// Force print every log before closing
eprosima::utils::Log::Flush();
return exit(eprosima::spy::ProcessReturnCode::success);
}

int exit(const eprosima::spy::ProcessReturnCode& code)
{
// Delete the consumers before closing
eprosima::utils::Log::ClearConsumers();

return static_cast<int>(eprosima::spy::ProcessReturnCode::success);
return static_cast<int>(code);
}

void register_log_consumers(const eprosima::ddspipe::core::DdsPipeLogConfiguration& configuration)
{
// Remove every consumer
eprosima::utils::Log::ClearConsumers();

// Activate log with verbosity, as this will avoid running log thread with not desired kind
eprosima::utils::Log::SetVerbosity(configuration.verbosity);

// Stdout Log Consumer
if (configuration.stdout_enable)
{
eprosima::utils::Log::RegisterConsumer(
std::make_unique<eprosima::utils::StdLogConsumer>(&configuration));
}

// DDS Log Consumer
if (configuration.publish.enable)
{
eprosima::utils::Log::RegisterConsumer(
std::make_unique<eprosima::ddspipe::core::DdsLogConsumer>(&configuration));
}

// NOTE:
// It will not filter any log, so Fast DDS logs will be visible unless Fast DDS is compiled
// in non debug or with LOG_NO_INFO=ON.
// This is the easiest way to allow to see Warnings and Errors from Fast DDS.
// Change it when Log Module is independent and with more extensive API.
// utils::Log::SetCategoryFilter(std::regex("(FASTDDSSPY)"));
}
31 changes: 30 additions & 1 deletion fastddsspy_yaml/src/cpp/YamlReaderConfiguration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include <set>

#include <ddspipe_core/configuration/DdsPipeConfiguration.hpp>
#include <ddspipe_core/types/dds/TopicQoS.hpp>
#include <ddspipe_core/types/dynamic_types/types.hpp>
Expand All @@ -24,6 +26,7 @@
#include <ddspipe_yaml/Yaml.hpp>
#include <ddspipe_yaml/YamlManager.hpp>
#include <ddspipe_yaml/YamlReader.hpp>
#include <ddspipe_yaml/YamlValidator.hpp>

#include <fastddsspy_yaml/yaml_configuration_tags.hpp>

Expand Down Expand Up @@ -77,6 +80,12 @@ void Configuration::load_configuration_(
{
YamlReaderVersion version = LATEST;

static const std::set<TagType> tags{
SPECS_TAG,
DDS_TAG};

YamlValidator::validate_tags(yml, tags);

/////
// Get optional specs configuration options
if (YamlReader::is_tag_present(yml, SPECS_TAG))
Expand Down Expand Up @@ -142,6 +151,18 @@ void Configuration::load_dds_configuration_(
const Yaml& yml,
const ddspipe::yaml::YamlReaderVersion& version)
{
static const std::set<TagType> tags{
ALLOWLIST_TAG,
BLOCKLIST_TAG,
TOPICS_TAG,
DOMAIN_ID_TAG,
WHITELIST_INTERFACES_TAG,
TRANSPORT_DESCRIPTORS_TRANSPORT_TAG,
IGNORE_PARTICIPANT_FLAGS_TAG,
ROS2_TYPES_TAG};

YamlValidator::validate_tags(yml, tags);

/////
// Get optional allowlist
if (YamlReader::is_tag_present(yml, ALLOWLIST_TAG))
Expand Down Expand Up @@ -217,6 +238,14 @@ void Configuration::load_specs_configuration_(
const Yaml& yml,
const ddspipe::yaml::YamlReaderVersion& version)
{
static const std::set<TagType> tags{
NUMBER_THREADS_TAG,
SPECS_QOS_TAG,
GATHERING_TIME_TAG,
LOG_CONFIGURATION_TAG};

YamlValidator::validate_tags(yml, tags);

// Get optional number of threads
if (YamlReader::is_tag_present(yml, NUMBER_THREADS_TAG))
{
Expand All @@ -227,7 +256,7 @@ void Configuration::load_specs_configuration_(
// Get optional Topic QoS
if (YamlReader::is_tag_present(yml, SPECS_QOS_TAG))
{
YamlReader::fill<TopicQoS>(topic_qos, YamlReader::get_value_in_tag(yml, SPECS_QOS_TAG), version);
topic_qos = YamlReader::get<TopicQoS>(yml, SPECS_QOS_TAG, version);
TopicQoS::default_topic_qos.set_value(topic_qos);
}

Expand Down
54 changes: 54 additions & 0 deletions fastddsspy_yaml/src/cpp/YamlReader_configuration.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2024 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 YamlReader_configuration.cpp
*
* File to redefine the validate function for the types that are different in the Fast-DDS Spy.
*/

#include <set>

#include <ddspipe_core/types/dds/TopicQoS.hpp>

#include <ddspipe_yaml/yaml_configuration_tags.hpp>
#include <ddspipe_yaml/YamlValidator.hpp>

namespace eprosima {
namespace ddspipe {
namespace yaml {

template <>
DDSPIPE_YAML_DllAPI
bool YamlValidator::validate<core::types::TopicQoS>(
const Yaml& yml,
const YamlReaderVersion& /* version */)
{
// The QOS_MAX_TX_RATE_TAG is not a valid TopicQoS
static const std::set<TagType> tags{
QOS_TRANSIENT_TAG,
QOS_RELIABLE_TAG,
QOS_OWNERSHIP_TAG,
QOS_PARTITION_TAG,
QOS_HISTORY_DEPTH_TAG,
QOS_KEYED_TAG,
QOS_MAX_RX_RATE_TAG,
QOS_DOWNSAMPLING_TAG};

return YamlValidator::validate_tags(yml, tags);
}

} /* namespace yaml */
} /* namespace ddspipe */
} /* namespace eprosima */
Loading