Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter
- CitrineOS core extracted (CSMS OCPP 2.0.1) - OpenOCPP extracted (firmware OCPP 1.6J/2.0.1) - ShapeShifter library installed (pip install -e) - ShapeShifter specification extracted - EVerest extracted TODO updated with progress
This commit is contained in:
119
tools/EVerest-main/lib/everest/framework/lib/error/error.cpp
Normal file
119
tools/EVerest-main/lib/everest/framework/lib/error/error.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
#include <utils/error.hpp>
|
||||
|
||||
#include <everest/helpers/helpers.hpp>
|
||||
|
||||
#include <everest/logging.hpp>
|
||||
|
||||
namespace Everest {
|
||||
namespace error {
|
||||
|
||||
UUID::UUID() {
|
||||
uuid = everest::helpers::get_uuid();
|
||||
}
|
||||
|
||||
UUID::UUID(const std::string& uuid_) : uuid(uuid_) {
|
||||
}
|
||||
|
||||
bool UUID::operator<(const UUID& other) const {
|
||||
return uuid < other.uuid;
|
||||
}
|
||||
|
||||
bool UUID::operator==(const UUID& other) const {
|
||||
return this->uuid == other.uuid;
|
||||
}
|
||||
|
||||
bool UUID::operator!=(const UUID& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
std::string UUID::to_string() const {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
Error::Error(const ErrorType& type_, const ErrorSubType& sub_type_, const std::string& message_,
|
||||
const std::string& description_, const ImplementationIdentifier& origin_, const std::string& vendor_id_,
|
||||
const Severity& severity_, const time_point& timestamp_, const UUID& uuid_, const State& state_) :
|
||||
type(type_),
|
||||
sub_type(sub_type_),
|
||||
message(message_),
|
||||
description(description_),
|
||||
origin(origin_),
|
||||
vendor_id(vendor_id_),
|
||||
severity(severity_),
|
||||
timestamp(timestamp_),
|
||||
uuid(uuid_),
|
||||
state(state_) {
|
||||
}
|
||||
|
||||
Error::Error(const ErrorType& type_, const ErrorSubType& sub_type_, const std::string& message_,
|
||||
const std::string& description_, const ImplementationIdentifier& origin_, const Severity& severity_) :
|
||||
Error(type_, sub_type_, message_, description_, origin_, UTILS_ERROR_DEFAULTS_VENDOR_ID, severity_,
|
||||
UTILS_ERROR_DEFAULTS_TIMESTAMP, UTILS_ERROR_DEFAULTS_UUID) {
|
||||
}
|
||||
|
||||
Error::Error(const ErrorType& type_, const ErrorSubType& sub_type_, const std::string& message_,
|
||||
const std::string& description_, const std::string& origin_module_,
|
||||
const std::string& origin_implementation_, const Severity& severity_) :
|
||||
Error(type_, sub_type_, message_, description_,
|
||||
ImplementationIdentifier(origin_module_, origin_implementation_, std::nullopt), severity_) {
|
||||
}
|
||||
|
||||
Error::Error() :
|
||||
Error(UTILS_ERROR_DEFAULTS_TYPE, UTILS_ERROR_DEFAULTS_SUB_TYPE, UTILS_ERROR_DEFAULTS_MESSAGE,
|
||||
UTILS_ERROR_DEFAULTS_DESCRIPTION, UTILS_ERROR_DEFAULTS_ORIGIN, UTILS_ERROR_DEFAULTS_SEVERITY) {
|
||||
}
|
||||
|
||||
std::string severity_to_string(const Severity& s) {
|
||||
switch (s) {
|
||||
case Severity::Low:
|
||||
return "Low";
|
||||
case Severity::Medium:
|
||||
return "Medium";
|
||||
case Severity::High:
|
||||
return "High";
|
||||
}
|
||||
EVLOG_error << "No known string conversion for provided enum of type Severity. Defaulting to High.";
|
||||
return "High";
|
||||
}
|
||||
|
||||
Severity string_to_severity(const std::string& s) {
|
||||
if (s == "Low") {
|
||||
return Severity::Low;
|
||||
} else if (s == "Medium") {
|
||||
return Severity::Medium;
|
||||
} else if (s == "High") {
|
||||
return Severity::High;
|
||||
}
|
||||
EVLOG_error << "Provided string " << s << " could not be converted to enum of type Severity. Defaulting to High.";
|
||||
return Severity::High;
|
||||
}
|
||||
|
||||
std::string state_to_string(const State& s) {
|
||||
switch (s) {
|
||||
case State::Active:
|
||||
return "Active";
|
||||
case State::ClearedByModule:
|
||||
return "ClearedByModule";
|
||||
case State::ClearedByReboot:
|
||||
return "ClearedByReboot";
|
||||
}
|
||||
EVLOG_error << "No known string conversion for provided enum of type State. Defaulting to Active.";
|
||||
return "Active";
|
||||
}
|
||||
|
||||
State string_to_state(const std::string& s) {
|
||||
if (s == "Active") {
|
||||
return State::Active;
|
||||
} else if (s == "ClearedByModule") {
|
||||
return State::ClearedByModule;
|
||||
} else if (s == "ClearedByReboot") {
|
||||
return State::ClearedByReboot;
|
||||
}
|
||||
EVLOG_error << "Provided string " << s << " could not be converted to enum of type State. Defaulting to Active.";
|
||||
return State::Active;
|
||||
}
|
||||
|
||||
} // namespace error
|
||||
} // namespace Everest
|
||||
@@ -0,0 +1,110 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#include <utils/error/error_database_map.hpp>
|
||||
|
||||
#include <everest/logging.hpp>
|
||||
#include <utils/error.hpp>
|
||||
#include <utils/error/error_json.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace Everest {
|
||||
namespace error {
|
||||
|
||||
void ErrorDatabaseMap::add_error(ErrorPtr error) {
|
||||
const std::lock_guard<std::mutex> lock(this->errors_mutex);
|
||||
if (this->errors.find(error->uuid) != this->errors.end()) {
|
||||
std::stringstream ss;
|
||||
ss << "Error with handle " << error->uuid.to_string() << " already exists in ErrorDatabaseMap." << std::endl;
|
||||
ss << "Error object: " << nlohmann::json(*error).dump(2);
|
||||
EVLOG_error << ss.str();
|
||||
return;
|
||||
}
|
||||
this->errors[error->uuid] = error;
|
||||
}
|
||||
|
||||
std::list<ErrorPtr> ErrorDatabaseMap::get_errors(const std::list<ErrorFilter>& filters) const {
|
||||
const std::lock_guard<std::mutex> lock(this->errors_mutex);
|
||||
return this->get_errors_no_mutex(filters);
|
||||
}
|
||||
|
||||
std::list<ErrorPtr> ErrorDatabaseMap::get_errors_no_mutex(const std::list<ErrorFilter>& filters) const {
|
||||
BOOST_LOG_FUNCTION();
|
||||
|
||||
std::list<ErrorPtr> result;
|
||||
std::transform(this->errors.begin(), this->errors.end(), std::back_inserter(result),
|
||||
[](const std::pair<ErrorHandle, ErrorPtr>& entry) { return entry.second; });
|
||||
|
||||
for (const ErrorFilter& filter : filters) {
|
||||
std::function<bool(const ErrorPtr&)> pred;
|
||||
switch (filter.get_filter_type()) {
|
||||
case FilterType::State: {
|
||||
pred = []([[maybe_unused]] const ErrorPtr& error) { return false; };
|
||||
EVLOG_error << "ErrorDatabaseMap does not support StateFilter. Ignoring.";
|
||||
} break;
|
||||
case FilterType::Origin: {
|
||||
pred = [&filter](const ErrorPtr& error) { return error->origin != filter.get_origin_filter(); };
|
||||
} break;
|
||||
case FilterType::Type: {
|
||||
pred = [&filter](const ErrorPtr& error) { return error->type != filter.get_type_filter().value; };
|
||||
} break;
|
||||
case FilterType::Severity: {
|
||||
pred = [&filter](const ErrorPtr& error) {
|
||||
switch (filter.get_severity_filter()) {
|
||||
case SeverityFilter::LOW_GE: {
|
||||
return error->severity < Severity::Low;
|
||||
} break;
|
||||
case SeverityFilter::MEDIUM_GE: {
|
||||
return error->severity < Severity::Medium;
|
||||
} break;
|
||||
case SeverityFilter::HIGH_GE: {
|
||||
return error->severity < Severity::High;
|
||||
} break;
|
||||
}
|
||||
EVLOG_error << "No known condition for provided enum of type SeverityFilter.";
|
||||
return false;
|
||||
};
|
||||
} break;
|
||||
case FilterType::TimePeriod: {
|
||||
pred = [&filter](const ErrorPtr& error) {
|
||||
return error->timestamp < filter.get_time_period_filter().from ||
|
||||
error->timestamp > filter.get_time_period_filter().to;
|
||||
};
|
||||
} break;
|
||||
case FilterType::Handle: {
|
||||
pred = [&filter](const ErrorPtr& error) { return error->uuid != filter.get_handle_filter(); };
|
||||
} break;
|
||||
case FilterType::SubType: {
|
||||
pred = [&filter](const ErrorPtr& error) { return error->sub_type != filter.get_sub_type_filter().value; };
|
||||
} break;
|
||||
case FilterType::VendorId: {
|
||||
pred = [&filter](const ErrorPtr& error) { return error->vendor_id != filter.get_vendor_id_filter().value; };
|
||||
} break;
|
||||
default:
|
||||
EVLOG_error << "No known pred for provided enum of type FilterType. Ignoring.";
|
||||
return result;
|
||||
}
|
||||
result.remove_if(pred);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::list<ErrorPtr> ErrorDatabaseMap::edit_errors(const std::list<ErrorFilter>& filters, EditErrorFunc edit_func) {
|
||||
const std::lock_guard<std::mutex> lock(this->errors_mutex);
|
||||
std::list<ErrorPtr> result = this->get_errors_no_mutex(filters);
|
||||
for (const ErrorPtr& error : result) {
|
||||
edit_func(error);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::list<ErrorPtr> ErrorDatabaseMap::remove_errors(const std::list<ErrorFilter>& filters) {
|
||||
BOOST_LOG_FUNCTION();
|
||||
const EditErrorFunc remove_func = [this](const ErrorPtr& error) { this->errors.erase(error->uuid); };
|
||||
return this->edit_errors(filters, remove_func);
|
||||
}
|
||||
|
||||
} // namespace error
|
||||
} // namespace Everest
|
||||
@@ -0,0 +1,185 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
#include <utility>
|
||||
|
||||
#include <utils/error/error_factory.hpp>
|
||||
#include <utils/error/error_type_map.hpp>
|
||||
|
||||
namespace Everest {
|
||||
namespace error {
|
||||
|
||||
ErrorFactory::ErrorFactory(std::shared_ptr<ErrorTypeMap> error_type_map_) :
|
||||
ErrorFactory(error_type_map_, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt,
|
||||
std::nullopt) {
|
||||
}
|
||||
|
||||
ErrorFactory::ErrorFactory(std::shared_ptr<ErrorTypeMap> error_type_map_, ImplementationIdentifier default_origin_) :
|
||||
ErrorFactory(error_type_map_, default_origin_, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt,
|
||||
std::nullopt) {
|
||||
}
|
||||
|
||||
ErrorFactory::ErrorFactory(std::shared_ptr<ErrorTypeMap> error_type_map_, ImplementationIdentifier default_origin_,
|
||||
Severity default_severity_) :
|
||||
ErrorFactory(error_type_map_, default_origin_, default_severity_, std::nullopt, std::nullopt, std::nullopt,
|
||||
std::nullopt, std::nullopt) {
|
||||
}
|
||||
|
||||
ErrorFactory::ErrorFactory(std::shared_ptr<ErrorTypeMap> error_type_map_,
|
||||
std::optional<ImplementationIdentifier> default_origin_,
|
||||
std::optional<Severity> default_severity_, std::optional<State> default_state_,
|
||||
std::optional<ErrorType> default_type_, std::optional<ErrorSubType> default_sub_type_,
|
||||
std::optional<std::string> default_message_, std::optional<std::string> default_vendor_id_) :
|
||||
error_type_map(error_type_map_),
|
||||
default_origin(std::move(default_origin_)),
|
||||
default_severity(default_severity_),
|
||||
default_state(default_state_),
|
||||
default_type(std::move(default_type_)),
|
||||
default_sub_type(std::move(default_sub_type_)),
|
||||
default_message(std::move(default_message_)),
|
||||
default_vendor_id(std::move(default_vendor_id_)) {
|
||||
}
|
||||
|
||||
Error ErrorFactory::create_error() const {
|
||||
Error error;
|
||||
if (default_origin.has_value()) {
|
||||
error.origin = default_origin.value();
|
||||
}
|
||||
if (default_severity.has_value()) {
|
||||
error.severity = default_severity.value();
|
||||
}
|
||||
if (default_state.has_value()) {
|
||||
error.state = default_state.value();
|
||||
}
|
||||
if (default_type.has_value()) {
|
||||
error.type = default_type.value();
|
||||
}
|
||||
if (default_sub_type.has_value()) {
|
||||
error.sub_type = default_sub_type.value();
|
||||
}
|
||||
if (default_message.has_value()) {
|
||||
error.message = default_message.value();
|
||||
}
|
||||
if (default_vendor_id.has_value()) {
|
||||
error.vendor_id = default_vendor_id.value();
|
||||
}
|
||||
set_description(error);
|
||||
return error;
|
||||
}
|
||||
|
||||
Error ErrorFactory::create_error(const ErrorType& type, const ErrorSubType& sub_type,
|
||||
const std::string& message) const {
|
||||
Error error;
|
||||
error.type = type;
|
||||
error.sub_type = sub_type;
|
||||
error.message = message;
|
||||
if (default_origin.has_value()) {
|
||||
error.origin = default_origin.value();
|
||||
}
|
||||
if (default_severity.has_value()) {
|
||||
error.severity = default_severity.value();
|
||||
}
|
||||
if (default_state.has_value()) {
|
||||
error.state = default_state.value();
|
||||
}
|
||||
if (default_vendor_id.has_value()) {
|
||||
error.vendor_id = default_vendor_id.value();
|
||||
}
|
||||
set_description(error);
|
||||
return error;
|
||||
}
|
||||
|
||||
Error ErrorFactory::create_error(const ErrorType& type, const ErrorSubType& sub_type, const std::string& message,
|
||||
const Severity severity) const {
|
||||
Error error;
|
||||
error.type = type;
|
||||
error.sub_type = sub_type;
|
||||
error.message = message;
|
||||
error.severity = severity;
|
||||
if (default_origin.has_value()) {
|
||||
error.origin = default_origin.value();
|
||||
}
|
||||
if (default_state.has_value()) {
|
||||
error.state = default_state.value();
|
||||
}
|
||||
if (default_vendor_id.has_value()) {
|
||||
error.vendor_id = default_vendor_id.value();
|
||||
}
|
||||
set_description(error);
|
||||
return error;
|
||||
}
|
||||
|
||||
Error ErrorFactory::create_error(const ErrorType& type, const ErrorSubType& sub_type, const std::string& message,
|
||||
const State state) const {
|
||||
Error error;
|
||||
error.type = type;
|
||||
error.sub_type = sub_type;
|
||||
error.message = message;
|
||||
error.state = state;
|
||||
if (default_origin.has_value()) {
|
||||
error.origin = default_origin.value();
|
||||
}
|
||||
if (default_severity.has_value()) {
|
||||
error.severity = default_severity.value();
|
||||
}
|
||||
if (default_vendor_id.has_value()) {
|
||||
error.vendor_id = default_vendor_id.value();
|
||||
}
|
||||
set_description(error);
|
||||
return error;
|
||||
}
|
||||
|
||||
Error ErrorFactory::create_error(const ErrorType& type, const ErrorSubType& sub_type, const std::string& message,
|
||||
const Severity severity, const State state) const {
|
||||
Error error;
|
||||
error.type = type;
|
||||
error.sub_type = sub_type;
|
||||
error.message = message;
|
||||
error.severity = severity;
|
||||
error.state = state;
|
||||
if (default_origin.has_value()) {
|
||||
error.origin = default_origin.value();
|
||||
}
|
||||
if (default_vendor_id.has_value()) {
|
||||
error.vendor_id = default_vendor_id.value();
|
||||
}
|
||||
set_description(error);
|
||||
return error;
|
||||
}
|
||||
|
||||
void ErrorFactory::set_default_origin(const ImplementationIdentifier& origin) {
|
||||
default_origin = origin;
|
||||
}
|
||||
|
||||
void ErrorFactory::set_default_severity(Severity severity) {
|
||||
default_severity = severity;
|
||||
}
|
||||
|
||||
void ErrorFactory::set_default_state(State state) {
|
||||
default_state = state;
|
||||
}
|
||||
|
||||
void ErrorFactory::set_default_type(const ErrorType& type) {
|
||||
default_type = type;
|
||||
}
|
||||
|
||||
void ErrorFactory::set_default_sub_type(const ErrorSubType& sub_type) {
|
||||
default_sub_type = sub_type;
|
||||
}
|
||||
|
||||
void ErrorFactory::set_default_message(const std::string& message) {
|
||||
default_message = message;
|
||||
}
|
||||
|
||||
void ErrorFactory::set_default_vendor_id(const std::string& vendor_id) {
|
||||
default_vendor_id = vendor_id;
|
||||
}
|
||||
|
||||
void ErrorFactory::set_description(Error& error) const {
|
||||
if (error.type == "") {
|
||||
return;
|
||||
}
|
||||
error.description = error_type_map->get_description(error.type);
|
||||
}
|
||||
|
||||
} // namespace error
|
||||
} // namespace Everest
|
||||
@@ -0,0 +1,181 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#include <utils/error/error_filter.hpp>
|
||||
|
||||
#include <everest/exceptions.hpp>
|
||||
#include <everest/logging.hpp>
|
||||
|
||||
namespace Everest {
|
||||
namespace error {
|
||||
|
||||
std::string state_filter_to_string(const StateFilter& f) {
|
||||
return state_to_string(f);
|
||||
}
|
||||
|
||||
StateFilter string_to_state_filter(const std::string& s) {
|
||||
return string_to_state(s);
|
||||
}
|
||||
|
||||
std::string severity_filter_to_string(const SeverityFilter& f) {
|
||||
switch (f) {
|
||||
case SeverityFilter::LOW_GE:
|
||||
return "LOW_GE";
|
||||
case SeverityFilter::MEDIUM_GE:
|
||||
return "MEDIUM_GE";
|
||||
case SeverityFilter::HIGH_GE:
|
||||
return "HIGH_GE";
|
||||
}
|
||||
EVLOG_error << "No known string conversion for provided enum of type SeverityFilter. Defaulting to HIGH_GE";
|
||||
return "HIGH_GE";
|
||||
}
|
||||
|
||||
SeverityFilter string_to_severity_filter(const std::string& s) {
|
||||
if (s == "LOW_GE") {
|
||||
return SeverityFilter::LOW_GE;
|
||||
} else if (s == "MEDIUM_GE") {
|
||||
return SeverityFilter::MEDIUM_GE;
|
||||
} else if (s == "HIGH_GE") {
|
||||
return SeverityFilter::HIGH_GE;
|
||||
}
|
||||
EVLOG_error << "Provided string " << s
|
||||
<< " could not be converted to enum of type SeverityFilter. Defaulting to HIGH_GE";
|
||||
return SeverityFilter::HIGH_GE;
|
||||
}
|
||||
|
||||
TypeFilter::TypeFilter(const ErrorType& value_) : value(value_) {
|
||||
}
|
||||
|
||||
SubTypeFilter::SubTypeFilter(const ErrorSubType& value_) : value(value_) {
|
||||
}
|
||||
|
||||
VendorIdFilter::VendorIdFilter(const std::string& value_) : value(value_) {
|
||||
}
|
||||
|
||||
std::string filter_type_to_string(const FilterType& f) {
|
||||
switch (f) {
|
||||
case FilterType::State:
|
||||
return "State";
|
||||
case FilterType::Origin:
|
||||
return "Origin";
|
||||
case FilterType::Type:
|
||||
return "Type";
|
||||
case FilterType::Severity:
|
||||
return "Severity";
|
||||
case FilterType::TimePeriod:
|
||||
return "TimePeriod";
|
||||
case FilterType::Handle:
|
||||
return "Handle";
|
||||
case FilterType::SubType:
|
||||
return "SubType";
|
||||
case FilterType::VendorId:
|
||||
return "VendorId";
|
||||
}
|
||||
EVLOG_error << "No known string conversion for provided enum of type FilterType. Defaulting to Type";
|
||||
return "Type";
|
||||
}
|
||||
|
||||
FilterType string_to_filter_type(const std::string& s) {
|
||||
if (s == "State") {
|
||||
return FilterType::State;
|
||||
} else if (s == "Origin") {
|
||||
return FilterType::Origin;
|
||||
} else if (s == "Type") {
|
||||
return FilterType::Type;
|
||||
} else if (s == "Severity") {
|
||||
return FilterType::Severity;
|
||||
} else if (s == "TimePeriod") {
|
||||
return FilterType::TimePeriod;
|
||||
} else if (s == "Handle") {
|
||||
return FilterType::Handle;
|
||||
} else if (s == "SubType") {
|
||||
return FilterType::SubType;
|
||||
} else if (s == "VendorId") {
|
||||
return FilterType::VendorId;
|
||||
}
|
||||
EVLOG_error << "Provided string " << s << " could not be converted to enum of type FilterType. Deafulting to Type.";
|
||||
return FilterType::Type;
|
||||
}
|
||||
|
||||
ErrorFilter::ErrorFilter() = default;
|
||||
|
||||
ErrorFilter::ErrorFilter(const FilterVariant& filter_) : filter(filter_) {
|
||||
}
|
||||
|
||||
FilterType ErrorFilter::get_filter_type() const {
|
||||
if (filter.index() == 0) {
|
||||
EVLOG_error << "Filter type is not set. Defaulting to 'FilterType::State'.";
|
||||
return FilterType::State;
|
||||
}
|
||||
return static_cast<FilterType>(filter.index());
|
||||
}
|
||||
|
||||
StateFilter ErrorFilter::get_state_filter() const {
|
||||
if (this->get_filter_type() != FilterType::State) {
|
||||
EVLOG_error << "Filter type is not StateFilter. Defaulting to 'StateFilter::Active'.";
|
||||
return StateFilter::Active;
|
||||
}
|
||||
return std::get<StateFilter>(filter);
|
||||
}
|
||||
|
||||
OriginFilter ErrorFilter::get_origin_filter() const {
|
||||
if (this->get_filter_type() != FilterType::Origin) {
|
||||
EVLOG_error << "Filter type is not OriginFilter. Defaulting to "
|
||||
"'OriginFilter::ImplementationIdentifier(\"no-module-id-provided\", "
|
||||
"\"no-implementation-id-provided\")'.";
|
||||
return OriginFilter(
|
||||
ImplementationIdentifier("no-module-id-provided", "no-implementation-id-provided", std::nullopt));
|
||||
}
|
||||
return std::get<OriginFilter>(filter);
|
||||
}
|
||||
|
||||
TypeFilter ErrorFilter::get_type_filter() const {
|
||||
if (this->get_filter_type() != FilterType::Type) {
|
||||
EVLOG_error << "Filter type is not TypeFilter. Defaulting to 'TypeFilter(\"no-type-provided\")'.";
|
||||
return TypeFilter("no-type-provided");
|
||||
}
|
||||
return std::get<TypeFilter>(filter);
|
||||
}
|
||||
|
||||
SeverityFilter ErrorFilter::get_severity_filter() const {
|
||||
if (this->get_filter_type() != FilterType::Severity) {
|
||||
EVLOG_error << "Filter type is not SeverityFilter. Defaulting to 'SeverityFilter::HIGH_GE'.";
|
||||
return SeverityFilter::HIGH_GE;
|
||||
}
|
||||
return std::get<SeverityFilter>(filter);
|
||||
}
|
||||
|
||||
TimePeriodFilter ErrorFilter::get_time_period_filter() const {
|
||||
if (this->get_filter_type() != FilterType::TimePeriod) {
|
||||
EVLOG_error << "Filter type is not TimePeriodFilter. Defaulting to 'TimePeriodFilter{Error::time_point(), "
|
||||
"Error::time_point()}'.";
|
||||
return TimePeriodFilter{Error::time_point(), Error::time_point()};
|
||||
}
|
||||
return std::get<TimePeriodFilter>(filter);
|
||||
}
|
||||
|
||||
HandleFilter ErrorFilter::get_handle_filter() const {
|
||||
if (this->get_filter_type() != FilterType::Handle) {
|
||||
EVLOG_error << "Filter type is not HandleFilter. Defaulting to 'HandleFilter()'.";
|
||||
return HandleFilter();
|
||||
}
|
||||
return std::get<HandleFilter>(filter);
|
||||
}
|
||||
|
||||
SubTypeFilter ErrorFilter::get_sub_type_filter() const {
|
||||
if (this->get_filter_type() != FilterType::SubType) {
|
||||
EVLOG_error << "Filter type is not SubTypeFilter. Defaulting to 'SubTypeFilter(\"no-sub-type-provided\")'.";
|
||||
return SubTypeFilter("no-sub-type-provided");
|
||||
}
|
||||
return std::get<SubTypeFilter>(filter);
|
||||
}
|
||||
|
||||
VendorIdFilter ErrorFilter::get_vendor_id_filter() const {
|
||||
if (this->get_filter_type() != FilterType::VendorId) {
|
||||
throw EverestBaseLogicError("Filter type is not VendorIdFilter.");
|
||||
}
|
||||
return std::get<VendorIdFilter>(filter);
|
||||
}
|
||||
|
||||
} // namespace error
|
||||
} // namespace Everest
|
||||
@@ -0,0 +1,151 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#include <utility>
|
||||
#include <utils/error/error_manager_impl.hpp>
|
||||
|
||||
#include <utils/error.hpp>
|
||||
#include <utils/error/error_database.hpp>
|
||||
#include <utils/error/error_json.hpp>
|
||||
#include <utils/error/error_type_map.hpp>
|
||||
|
||||
#include <everest/logging.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
namespace Everest {
|
||||
namespace error {
|
||||
|
||||
ErrorManagerImpl::ErrorManagerImpl(std::shared_ptr<ErrorTypeMap> error_type_map_,
|
||||
std::shared_ptr<ErrorDatabase> error_database_,
|
||||
std::list<ErrorType> allowed_error_types_,
|
||||
ErrorManagerImpl::PublishErrorFunc publish_raised_error_,
|
||||
ErrorManagerImpl::PublishErrorFunc publish_cleared_error_,
|
||||
const bool validate_error_types_) :
|
||||
error_type_map(error_type_map_),
|
||||
database(error_database_),
|
||||
allowed_error_types(std::move(allowed_error_types_)),
|
||||
publish_raised_error(std::move(publish_raised_error_)),
|
||||
publish_cleared_error(std::move(publish_cleared_error_)),
|
||||
validate_error_types(validate_error_types_) {
|
||||
if (validate_error_types) {
|
||||
for (const ErrorType& type : allowed_error_types) {
|
||||
if (!error_type_map->has(type)) {
|
||||
EVLOG_error << "Error type '" << type << "' in allowed_error_types is not defined, ignored.";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ErrorManagerImpl::raise_error(const Error& error) {
|
||||
if (validate_error_types) {
|
||||
if (std::find(allowed_error_types.begin(), allowed_error_types.end(), error.type) ==
|
||||
allowed_error_types.end()) {
|
||||
std::stringstream ss;
|
||||
ss << "Error type " << error.type << " is not allowed to be raised. Ignoring.";
|
||||
ss << std::endl << "Error object: " << nlohmann::json(error).dump(2);
|
||||
EVLOG_error << ss.str();
|
||||
return;
|
||||
}
|
||||
}
|
||||
const std::lock_guard<std::mutex> lock(mutex);
|
||||
if (!can_be_raised(error.type, error.sub_type)) {
|
||||
std::stringstream ss;
|
||||
ss << "Error can't be raised, because type " << error.type << ", sub_type " << error.sub_type
|
||||
<< " is already active.";
|
||||
ss << std::endl << "Error object: " << nlohmann::json(error).dump(2);
|
||||
EVLOG_debug << ss.str();
|
||||
return;
|
||||
}
|
||||
database->add_error(std::make_shared<Error>(error));
|
||||
this->publish_raised_error(error);
|
||||
EVLOG_error << "Error raised, type: " << error.type << ", sub_type: " << error.sub_type
|
||||
<< ", message: " << error.message;
|
||||
}
|
||||
|
||||
std::list<ErrorPtr> ErrorManagerImpl::clear_error(const ErrorType& type) {
|
||||
const ErrorSubType sub_type("");
|
||||
return clear_error(type, sub_type);
|
||||
}
|
||||
|
||||
std::list<ErrorPtr> ErrorManagerImpl::clear_error(const ErrorType& type, const ErrorSubType& sub_type) {
|
||||
const std::lock_guard<std::mutex> lock(mutex);
|
||||
if (!can_be_cleared(type, sub_type)) {
|
||||
EVLOG_debug << "Error can't be cleared, because type " << type << ", sub_type " << sub_type
|
||||
<< " is not active.";
|
||||
return {};
|
||||
}
|
||||
const std::list<ErrorFilter> filters = {ErrorFilter(TypeFilter(type)), ErrorFilter(SubTypeFilter(sub_type))};
|
||||
std::list<ErrorPtr> res = database->remove_errors(filters);
|
||||
if (res.size() > 1) {
|
||||
std::stringstream ss;
|
||||
ss << "There are more than one matching error, this is not valid:" << std::endl;
|
||||
for (const ErrorPtr& error : res) {
|
||||
ss << nlohmann::json(*error).dump(2) << std::endl;
|
||||
}
|
||||
EVLOG_error << ss.str();
|
||||
return {};
|
||||
}
|
||||
const ErrorPtr error = res.front();
|
||||
error->state = State::ClearedByModule;
|
||||
this->publish_cleared_error(*error);
|
||||
EVLOG_info << "Cleared error of type " << type << " with sub_type " << sub_type;
|
||||
return res;
|
||||
}
|
||||
|
||||
std::list<ErrorPtr> ErrorManagerImpl::clear_all_errors() {
|
||||
const std::lock_guard<std::mutex> lock(mutex);
|
||||
const std::list<ErrorFilter> filters = {};
|
||||
std::list<ErrorPtr> res = database->remove_errors(filters);
|
||||
if (res.empty()) {
|
||||
EVLOG_debug << "No errors can be cleared, because no errors are active";
|
||||
return res;
|
||||
}
|
||||
std::stringstream ss;
|
||||
ss << "Cleared " << res.size() << " errors:" << std::endl;
|
||||
for (const ErrorPtr& error : res) {
|
||||
error->state = State::ClearedByModule;
|
||||
this->publish_cleared_error(*error);
|
||||
ss << " - type: " << error->type << ", sub_type: " << error->sub_type << std::endl;
|
||||
}
|
||||
EVLOG_info << ss.str();
|
||||
return res;
|
||||
}
|
||||
|
||||
std::list<ErrorPtr> ErrorManagerImpl::clear_all_errors(const ErrorType& error_type) {
|
||||
const std::lock_guard<std::mutex> lock(mutex);
|
||||
if (!can_be_cleared(error_type)) {
|
||||
EVLOG_debug << "Errors can't be cleared, because type " << error_type << " is not active.";
|
||||
return {};
|
||||
}
|
||||
const std::list<ErrorFilter> filters = {ErrorFilter(TypeFilter(error_type))};
|
||||
std::list<ErrorPtr> res = database->remove_errors(filters);
|
||||
std::stringstream ss;
|
||||
ss << "Cleared " << res.size() << " errors of type " << error_type << " with sub_types:" << std::endl;
|
||||
for (const ErrorPtr& error : res) {
|
||||
error->state = State::ClearedByModule;
|
||||
this->publish_cleared_error(*error);
|
||||
ss << " - " << error->sub_type << std::endl;
|
||||
}
|
||||
EVLOG_info << ss.str();
|
||||
return res;
|
||||
}
|
||||
|
||||
bool ErrorManagerImpl::can_be_raised(const ErrorType& type, const ErrorSubType& sub_type) const {
|
||||
const std::list<ErrorFilter> filters = {ErrorFilter(TypeFilter(type)), ErrorFilter(SubTypeFilter(sub_type))};
|
||||
return database->get_errors(filters).empty();
|
||||
}
|
||||
|
||||
bool ErrorManagerImpl::can_be_cleared(const ErrorType& type, const ErrorSubType& sub_type) const {
|
||||
const std::list<ErrorFilter> filters = {ErrorFilter(TypeFilter(type)), ErrorFilter(SubTypeFilter(sub_type))};
|
||||
return !database->get_errors(filters).empty();
|
||||
}
|
||||
|
||||
bool ErrorManagerImpl::can_be_cleared(const ErrorType& type) const {
|
||||
const std::list<ErrorFilter> filters = {ErrorFilter(TypeFilter(type))};
|
||||
return !database->get_errors(filters).empty();
|
||||
}
|
||||
|
||||
} // namespace error
|
||||
} // namespace Everest
|
||||
@@ -0,0 +1,125 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#include <utility>
|
||||
#include <utils/error/error_manager_req.hpp>
|
||||
|
||||
#include <utils/error.hpp>
|
||||
#include <utils/error/error_database.hpp>
|
||||
#include <utils/error/error_filter.hpp>
|
||||
#include <utils/error/error_json.hpp>
|
||||
#include <utils/error/error_type_map.hpp>
|
||||
|
||||
#include <everest/logging.hpp>
|
||||
|
||||
namespace Everest {
|
||||
namespace error {
|
||||
|
||||
ErrorManagerReq::ErrorManagerReq(std::shared_ptr<ErrorTypeMap> error_type_map_,
|
||||
std::shared_ptr<ErrorDatabase> error_database_,
|
||||
std::list<ErrorType> allowed_error_types_, SubscribeErrorFunc subscribe_error_func_) :
|
||||
error_type_map(error_type_map_),
|
||||
database(error_database_),
|
||||
allowed_error_types(std::move(allowed_error_types_)),
|
||||
subscribe_error_func(std::move(subscribe_error_func_)) {
|
||||
|
||||
for (const ErrorType& type : allowed_error_types) {
|
||||
if (!error_type_map->has(type)) {
|
||||
EVLOG_error << "Error type '" << type << "' in allowed_error_types is not defined, ignored.";
|
||||
}
|
||||
}
|
||||
const ErrorCallback on_raise = [this](const Error& error) { this->on_error_raised(error); };
|
||||
const ErrorCallback on_clear = [this](const Error& error) { this->on_error_cleared(error); };
|
||||
for (const ErrorType& type : allowed_error_types) {
|
||||
subscribe_error_func(type, on_raise, on_clear);
|
||||
error_subscriptions[type] = {};
|
||||
}
|
||||
}
|
||||
|
||||
ErrorManagerReq::Subscription::Subscription(const ErrorType& type_, const ErrorCallback& callback_,
|
||||
const ErrorCallback& clear_callback_) :
|
||||
type(type_), callback(callback_), clear_callback(clear_callback_) {
|
||||
}
|
||||
|
||||
void ErrorManagerReq::subscribe_error(const ErrorType& type, const ErrorCallback& callback,
|
||||
const ErrorCallback& clear_callback) {
|
||||
if (error_subscriptions.count(type) != 1) {
|
||||
EVLOG_error << "Tpye " << type << " is not known, ignore subscription";
|
||||
return;
|
||||
}
|
||||
const Subscription sub(type, callback, clear_callback);
|
||||
error_subscriptions.at(type).push_back(sub);
|
||||
}
|
||||
|
||||
void ErrorManagerReq::subscribe_all_errors(const ErrorCallback& callback, const ErrorCallback& clear_callback) {
|
||||
for (const ErrorType& type : allowed_error_types) {
|
||||
const Subscription sub(type, callback, clear_callback);
|
||||
error_subscriptions.at(type).push_back(sub);
|
||||
}
|
||||
}
|
||||
|
||||
void ErrorManagerReq::on_error_raised(const Error& error) {
|
||||
if (std::find(allowed_error_types.begin(), allowed_error_types.end(), error.type) == allowed_error_types.end()) {
|
||||
std::stringstream ss;
|
||||
ss << "Error can't be raised by module_id " << error.origin.module_id << " and implemenetation_id "
|
||||
<< error.origin.implementation_id << ", ignored.";
|
||||
ss << std::endl << "Error object: " << nlohmann::json(error).dump(2);
|
||||
EVLOG_error << ss.str();
|
||||
return;
|
||||
}
|
||||
if (!error_type_map->has(error.type)) {
|
||||
std::stringstream ss;
|
||||
ss << "Error type '" << error.type << "' is not defined, ignored.";
|
||||
ss << std::endl << "Error object: " << nlohmann::json(error).dump(2);
|
||||
EVLOG_error << ss.str();
|
||||
return;
|
||||
}
|
||||
std::list<ErrorPtr> errors =
|
||||
database->get_errors({ErrorFilter(TypeFilter(error.type)), ErrorFilter(SubTypeFilter(error.sub_type)),
|
||||
ErrorFilter(OriginFilter(error.origin))});
|
||||
if (!errors.empty()) {
|
||||
// Error is already raised, ignoring identical new error
|
||||
// FIXME: can we prevent this from happening in the first place?
|
||||
return;
|
||||
}
|
||||
database->add_error(std::make_shared<Error>(error));
|
||||
on_error(error, true);
|
||||
}
|
||||
|
||||
void ErrorManagerReq::on_error_cleared(const Error& error) {
|
||||
const std::list<ErrorFilter> filters = {ErrorFilter(TypeFilter(error.type)),
|
||||
ErrorFilter(SubTypeFilter(error.sub_type))};
|
||||
const std::list<ErrorPtr> res = database->remove_errors(filters);
|
||||
if (res.size() < 1) {
|
||||
std::stringstream ss;
|
||||
ss << "Error wasn't raised, type: " << error.type << ", sub_type: " << error.sub_type << ", ignored.";
|
||||
ss << std::endl << "Error object: " << nlohmann::json(error).dump(2);
|
||||
EVLOG_error << ss.str();
|
||||
return;
|
||||
}
|
||||
if (res.size() > 1) {
|
||||
std::stringstream ss;
|
||||
ss << "More than one error is cleared, type: " << error.type << ", sub_type: " << error.sub_type
|
||||
<< ", ignored.";
|
||||
for (const ErrorPtr& error : res) {
|
||||
ss << std::endl << "Error object: " << nlohmann::json(*error).dump(2);
|
||||
}
|
||||
EVLOG_error << ss.str();
|
||||
return;
|
||||
}
|
||||
|
||||
on_error(error, false);
|
||||
}
|
||||
|
||||
void ErrorManagerReq::on_error(const Error& error, const bool raised) const {
|
||||
for (const Subscription& sub : error_subscriptions.at(error.type)) {
|
||||
if (raised) {
|
||||
sub.callback(error);
|
||||
} else {
|
||||
sub.clear_callback(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace error
|
||||
} // namespace Everest
|
||||
@@ -0,0 +1,112 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#include <utility>
|
||||
#include <utils/error/error_manager_req_global.hpp>
|
||||
|
||||
#include <everest/logging.hpp>
|
||||
#include <utils/error/error_database.hpp>
|
||||
#include <utils/error/error_json.hpp>
|
||||
#include <utils/error/error_type_map.hpp>
|
||||
|
||||
namespace Everest {
|
||||
namespace error {
|
||||
|
||||
ErrorManagerReqGlobal::ErrorManagerReqGlobal(std::shared_ptr<ErrorTypeMap> error_type_map_,
|
||||
std::shared_ptr<ErrorDatabase> error_database_,
|
||||
SubscribeGlobalAllErrorsFunc subscribe_global_all_errors_func_) :
|
||||
error_type_map(error_type_map_),
|
||||
database(error_database_),
|
||||
subscribe_global_all_errors_func(std::move(subscribe_global_all_errors_func_)),
|
||||
subscriptions({}) {
|
||||
this->subscribe_global_all_errors_func([this](const Error& error) { this->on_error_raised(error); },
|
||||
[this](const Error& error) { this->on_error_cleared(error); });
|
||||
}
|
||||
|
||||
void ErrorManagerReqGlobal::subscribe_global_all_errors(const ErrorCallback& callback,
|
||||
const ErrorCallback& clear_callback) {
|
||||
const Subscription sub(callback, clear_callback);
|
||||
subscriptions.push_back(sub);
|
||||
}
|
||||
|
||||
ErrorManagerReqGlobal::Subscription::Subscription(const ErrorCallback& callback_,
|
||||
const ErrorCallback& clear_callback_) :
|
||||
callback(callback_), clear_callback(clear_callback_) {
|
||||
}
|
||||
|
||||
void ErrorManagerReqGlobal::on_error_raised(const Error& error) {
|
||||
if (!error_type_map->has(error.type)) {
|
||||
std::stringstream ss;
|
||||
ss << "Error type '" << error.type << "' is not defined, ignoring error";
|
||||
ss << std::endl << "Error object: " << nlohmann::json(error).dump(2);
|
||||
EVLOG_error << ss.str();
|
||||
return;
|
||||
}
|
||||
std::list<ErrorPtr> errors =
|
||||
database->get_errors({ErrorFilter(TypeFilter(error.type)), ErrorFilter(SubTypeFilter(error.sub_type)),
|
||||
ErrorFilter(OriginFilter(error.origin))});
|
||||
if (!errors.empty()) {
|
||||
std::stringstream ss;
|
||||
ss << "Error of type '" << error.type << "' and sub type '" << error.sub_type
|
||||
<< "' is already raised, ignoring new error";
|
||||
ss << std::endl << "Error object: " << nlohmann::json(error).dump(2);
|
||||
EVLOG_error << ss.str();
|
||||
return;
|
||||
}
|
||||
database->add_error(std::make_shared<Error>(error));
|
||||
errors = database->get_errors({ErrorFilter(TypeFilter(error.type)), ErrorFilter(SubTypeFilter(error.sub_type)),
|
||||
ErrorFilter(OriginFilter(error.origin))});
|
||||
if (errors.size() != 1) {
|
||||
EVLOG_error << "Error wasn't added, type: " << error.type << ", sub type: " << error.sub_type;
|
||||
return;
|
||||
}
|
||||
for (const Subscription& sub : subscriptions) {
|
||||
sub.callback(error);
|
||||
}
|
||||
}
|
||||
|
||||
void ErrorManagerReqGlobal::on_error_cleared(const Error& error) {
|
||||
if (!error_type_map->has(error.type)) {
|
||||
std::stringstream ss;
|
||||
ss << "Error type '" << error.type << "' is not defined, ignoring error";
|
||||
ss << std::endl << "Error object: " << nlohmann::json(error).dump(2);
|
||||
EVLOG_error << ss.str();
|
||||
return;
|
||||
}
|
||||
const std::list<ErrorPtr> errors =
|
||||
database->get_errors({ErrorFilter(TypeFilter(error.type)), ErrorFilter(SubTypeFilter(error.sub_type)),
|
||||
ErrorFilter(OriginFilter(error.origin))});
|
||||
if (errors.empty()) {
|
||||
std::stringstream ss;
|
||||
ss << "Error of type '" << error.type << "' and sub type '" << error.sub_type
|
||||
<< "' is not raised, ignoring clear error";
|
||||
ss << std::endl << "Error object: " << nlohmann::json(error).dump(2);
|
||||
EVLOG_error << ss.str();
|
||||
return;
|
||||
}
|
||||
const std::list<ErrorPtr> res =
|
||||
database->remove_errors({ErrorFilter(TypeFilter(error.type)), ErrorFilter(SubTypeFilter(error.sub_type)),
|
||||
ErrorFilter(OriginFilter(error.origin))});
|
||||
if (res.size() > 1) {
|
||||
std::stringstream ss;
|
||||
ss << "More than one error is cleared, type: " << error.type << ", sub type: " << error.sub_type;
|
||||
for (const ErrorPtr& error : res) {
|
||||
ss << std::endl << "Error object: " << nlohmann::json(*error).dump(2);
|
||||
}
|
||||
EVLOG_error << ss.str();
|
||||
return;
|
||||
}
|
||||
if (res.empty()) {
|
||||
std::stringstream ss;
|
||||
ss << "Error wasn't removed, type: " << error.type << ", sub type: " << error.sub_type;
|
||||
ss << std::endl << "Error object: " << nlohmann::json(error).dump(2);
|
||||
EVLOG_error << ss.str();
|
||||
return;
|
||||
}
|
||||
for (const Subscription& sub : subscriptions) {
|
||||
sub.clear_callback(error);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace error
|
||||
} // namespace Everest
|
||||
@@ -0,0 +1,46 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#include <utility>
|
||||
#include <utils/error/error_state_monitor.hpp>
|
||||
|
||||
#include <utils/error/error_database.hpp>
|
||||
#include <utils/error/error_filter.hpp>
|
||||
|
||||
#include <everest/logging.hpp>
|
||||
|
||||
namespace Everest {
|
||||
namespace error {
|
||||
|
||||
ErrorStateMonitor::StateCondition::StateCondition(ErrorType type_, ErrorSubType sub_type_, bool active_) :
|
||||
type(std::move(type_)), sub_type(std::move(sub_type_)), active(active_) {
|
||||
}
|
||||
|
||||
ErrorStateMonitor::ErrorStateMonitor(std::shared_ptr<ErrorDatabase> error_database_) : database(error_database_) {
|
||||
}
|
||||
|
||||
bool ErrorStateMonitor::is_error_active(const ErrorType& type, const ErrorSubType& sub_type) const {
|
||||
const std::list<ErrorFilter> filters = {ErrorFilter(TypeFilter(type)), ErrorFilter(SubTypeFilter(sub_type))};
|
||||
return database->get_errors(filters).size() > 0;
|
||||
}
|
||||
|
||||
std::list<ErrorPtr> ErrorStateMonitor::get_active_errors() const {
|
||||
return database->get_errors({});
|
||||
}
|
||||
|
||||
bool ErrorStateMonitor::is_condition_satisfied(const StateCondition& condition) const {
|
||||
const bool res = is_error_active(condition.type, condition.sub_type);
|
||||
return res == condition.active;
|
||||
}
|
||||
|
||||
bool ErrorStateMonitor::is_condition_satisfied(const std::list<StateCondition>& condition) const {
|
||||
for (const auto& cond : condition) {
|
||||
if (!is_condition_satisfied(cond)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace error
|
||||
} // namespace Everest
|
||||
@@ -0,0 +1,94 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#include <utility>
|
||||
#include <utils/error/error_type_map.hpp>
|
||||
|
||||
#include <utils/error.hpp>
|
||||
#include <utils/yaml_loader.hpp>
|
||||
|
||||
#include <everest/logging.hpp>
|
||||
|
||||
namespace Everest {
|
||||
namespace error {
|
||||
|
||||
ErrorTypeMap::ErrorTypeMap(const std::filesystem::path& error_types_dir) {
|
||||
load_error_types(error_types_dir);
|
||||
}
|
||||
|
||||
void ErrorTypeMap::load_error_types(const std::filesystem::path& error_types_dir) {
|
||||
BOOST_LOG_FUNCTION();
|
||||
|
||||
if (!std::filesystem::is_directory(error_types_dir) || !std::filesystem::exists(error_types_dir)) {
|
||||
EVLOG_error << "Error types directory '" << error_types_dir.string()
|
||||
<< "' does not exist, error types not loaded.";
|
||||
return;
|
||||
}
|
||||
for (const auto& entry : std::filesystem::directory_iterator(error_types_dir)) {
|
||||
if (!entry.is_regular_file()) {
|
||||
continue;
|
||||
}
|
||||
if (entry.path().extension() != ".yaml") {
|
||||
continue;
|
||||
}
|
||||
const std::string prefix = entry.path().stem().string();
|
||||
json error_type_file = Everest::load_yaml(entry.path());
|
||||
if (!error_type_file.contains("errors")) {
|
||||
EVLOG_warning << "Error type file '" << entry.path().string() << "' does not contain 'errors' key.";
|
||||
continue;
|
||||
}
|
||||
if (!error_type_file.at("errors").is_array()) {
|
||||
EVLOG_error << "Error type file '" << entry.path().string()
|
||||
<< "' does not contain an array with key 'errors', skipped.";
|
||||
continue;
|
||||
}
|
||||
for (const auto& error : error_type_file["errors"]) {
|
||||
if (!error.contains("name")) {
|
||||
EVLOG_error << "Error type file '" << entry.path().string()
|
||||
<< "' contains an error without a 'name' key, skipped.";
|
||||
continue;
|
||||
}
|
||||
std::string description;
|
||||
if (!error.contains("description")) {
|
||||
EVLOG_error << "Error type file '" << entry.path().string()
|
||||
<< "' contains an error without a 'description' key, using default description";
|
||||
description = "No description found";
|
||||
} else {
|
||||
description = error.at("description").get<std::string>();
|
||||
}
|
||||
ErrorType complete_name = prefix + "/" + error.at("name").get<std::string>();
|
||||
if (this->has(complete_name)) {
|
||||
EVLOG_error << "Error type file '" << entry.path().string() << "' contains an error with the name '"
|
||||
<< complete_name << "' which is already defined, skipped.";
|
||||
continue;
|
||||
}
|
||||
error_types[complete_name] = description;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ErrorTypeMap::load_error_types_map(std::map<ErrorType, std::string> error_types_map) {
|
||||
this->error_types = std::move(error_types_map);
|
||||
}
|
||||
|
||||
std::string ErrorTypeMap::get_description(const ErrorType& error_type) const {
|
||||
std::string description;
|
||||
try {
|
||||
description = error_types.at(error_type);
|
||||
} catch (...) {
|
||||
EVLOG_error << "Error type '" << error_type << "' is not defined, returning default description.";
|
||||
description = "No description found";
|
||||
}
|
||||
return description;
|
||||
}
|
||||
|
||||
bool ErrorTypeMap::has(const ErrorType& error_type) const {
|
||||
return error_types.find(error_type) != error_types.end();
|
||||
}
|
||||
|
||||
const ErrorTypes& ErrorTypeMap::get_error_types() const {
|
||||
return error_types;
|
||||
}
|
||||
|
||||
} // namespace error
|
||||
} // namespace Everest
|
||||
Reference in New Issue
Block a user