Avoid accessing attributes for validators where not necessary

This commit is contained in:
Gunnar Beutner 2018-01-11 07:08:09 +01:00
parent e26494bf08
commit 21254fb610
44 changed files with 222 additions and 162 deletions

View File

@ -1564,10 +1564,10 @@ void Application::SetLastReloadFailed(double ts)
m_LastReloadFailed = ts;
}
void Application::ValidateName(const String& value, const ValidationUtils& utils)
void Application::ValidateName(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<Application>::ValidateName(value, utils);
ObjectImpl<Application>::ValidateName(lvalue, utils);
if (value != "app")
if (lvalue() != "app")
BOOST_THROW_EXCEPTION(ValidationError(this, { "name" }, "Application object must be named 'app'."));
}

View File

@ -174,7 +174,7 @@ protected:
virtual void OnShutdown();
void ValidateName(const String& value, const ValidationUtils& utils) final;
void ValidateName(const Lazy<String>& lvalue, const ValidationUtils& utils) final;
private:
static Application::Ptr m_Instance; /**< The application instance. */

View File

@ -210,7 +210,7 @@ void ConfigObject::ModifyAttribute(const String& attr, const Value& value, bool
}
ModAttrValidationUtils utils;
ValidateField(fid, newValue, utils);
ValidateField(fid, Lazy<Value>{newValue}, utils);
SetField(fid, newValue);

View File

@ -183,14 +183,14 @@ bool Logger::IsTimestampEnabled()
return m_TimestampEnabled;
}
void Logger::ValidateSeverity(const String& value, const ValidationUtils& utils)
void Logger::ValidateSeverity(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<Logger>::ValidateSeverity(value, utils);
ObjectImpl<Logger>::ValidateSeverity(lvalue, utils);
try {
StringToSeverity(value);
StringToSeverity(lvalue());
} catch (...) {
BOOST_THROW_EXCEPTION(ValidationError(this, { "severity" }, "Invalid severity specified: " + value));
BOOST_THROW_EXCEPTION(ValidationError(this, { "severity" }, "Invalid severity specified: " + lvalue()));
}
}

View File

@ -90,7 +90,7 @@ public:
static void SetConsoleLogSeverity(LogSeverity logSeverity);
static LogSeverity GetConsoleLogSeverity();
void ValidateSeverity(const String& value, const ValidationUtils& utils) final;
void ValidateSeverity(const Lazy<String>& lvalue, const ValidationUtils& utils) final;
protected:
void Start(bool runtimeCreated) override;

View File

@ -168,7 +168,7 @@ void Object::Validate(int types, const ValidationUtils& utils)
/* Nothing to do here. */
}
void Object::ValidateField(int id, const Value& value, const ValidationUtils& utils)
void Object::ValidateField(int id, const Lazy<Value>& lvalue, const ValidationUtils& utils)
{
/* Nothing to do here. */
}

View File

@ -98,6 +98,63 @@ struct TypeHelper<T, true>
}
};
template<typename T>
struct Lazy
{
using Accessor = std::function<T ()>;
explicit Lazy(T value)
: m_Cached(true), m_Value(value)
{ }
explicit Lazy(Accessor accessor)
: m_Accessor(accessor)
{ }
template<typename U>
explicit Lazy(const Lazy<U>& other)
{
if (other.m_Cached) {
m_Accessor = Accessor();
m_Value = static_cast<T>(other.m_Value);
m_Cached = true;
} else {
auto accessor = other.m_Accessor;
m_Accessor = [accessor]() { return static_cast<T>(accessor()); };
m_Cached = false;
}
}
template<typename U>
operator Lazy<U>() const
{
if (m_Cached)
return Lazy<U>(m_Value);
else {
Accessor accessor = m_Accessor;
return Lazy<U>([accessor]() { return static_cast<U>(accessor()); });
}
}
const T& operator()() const
{
if (!m_Cached) {
m_Value = m_Accessor();
m_Cached = true;
}
return m_Value;
}
private:
Accessor m_Accessor;
mutable bool m_Cached{false};
mutable T m_Value;
template<typename U>
friend struct Lazy;
};
/**
* Base class for all heap-allocated objects. At least one of its methods
* has to be virtual for RTTI to work.
@ -124,7 +181,7 @@ public:
virtual void SetFieldByName(const String& field, const Value& value, const DebugInfo& debugInfo);
virtual bool HasOwnField(const String& field) const;
virtual bool GetOwnField(const String& field, Value *result) const;
virtual void ValidateField(int id, const Value& value, const ValidationUtils& utils);
virtual void ValidateField(int id, const Lazy<Value>& lvalue, const ValidationUtils& utils);
virtual void NotifyField(int id, const Value& cookie = Empty);
virtual Object::Ptr NavigateField(int id) const;

View File

@ -103,13 +103,13 @@ void SyslogLogger::OnConfigLoaded()
m_Facility = Convert::ToLong(facilityString);
}
void SyslogLogger::ValidateFacility(const String& value, const ValidationUtils& utils)
void SyslogLogger::ValidateFacility(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<SyslogLogger>::ValidateFacility(value, utils);
ObjectImpl<SyslogLogger>::ValidateFacility(lvalue, utils);
if (m_FacilityMap.find(value) == m_FacilityMap.end()) {
if (m_FacilityMap.find(lvalue()) == m_FacilityMap.end()) {
try {
Convert::ToLong(value);
Convert::ToLong(lvalue());
} catch (const std::exception&) {
BOOST_THROW_EXCEPTION(ValidationError(this, { "facility" }, "Invalid facility specified."));
}

View File

@ -42,7 +42,7 @@ public:
static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);
void OnConfigLoaded() override;
void ValidateFacility(const String& value, const ValidationUtils& utils) override;
void ValidateFacility(const Lazy<String>& lvalue, const ValidationUtils& utils) override;
protected:
static std::map<String, int> m_FacilityMap;

View File

@ -598,12 +598,12 @@ void CompatLogger::RotationTimerHandler()
ScheduleNextRotation();
}
void CompatLogger::ValidateRotationMethod(const String& value, const ValidationUtils& utils)
void CompatLogger::ValidateRotationMethod(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<CompatLogger>::ValidateRotationMethod(value, utils);
ObjectImpl<CompatLogger>::ValidateRotationMethod(lvalue, utils);
if (value != "HOURLY" && value != "DAILY" &&
value != "WEEKLY" && value != "MONTHLY" && value != "NONE") {
BOOST_THROW_EXCEPTION(ValidationError(this, { "rotation_method" }, "Rotation method '" + value + "' is invalid."));
if (lvalue() != "HOURLY" && lvalue() != "DAILY" &&
lvalue() != "WEEKLY" && lvalue() != "MONTHLY" && lvalue() != "NONE") {
BOOST_THROW_EXCEPTION(ValidationError(this, { "rotation_method" }, "Rotation method '" + lvalue() + "' is invalid."));
}
}

View File

@ -41,7 +41,7 @@ public:
static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);
void ValidateRotationMethod(const String& value, const ValidationUtils& utils) override;
void ValidateRotationMethod(const Lazy<String>& lvalue, const ValidationUtils& utils) override;
protected:
void Start(bool runtimeCreated) override;

View File

@ -440,19 +440,19 @@ void DbConnection::PrepareDatabase()
}
}
void DbConnection::ValidateFailoverTimeout(double value, const ValidationUtils& utils)
void DbConnection::ValidateFailoverTimeout(const Lazy<double>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<DbConnection>::ValidateFailoverTimeout(value, utils);
ObjectImpl<DbConnection>::ValidateFailoverTimeout(lvalue, utils);
if (value < 60)
if (lvalue() < 60)
BOOST_THROW_EXCEPTION(ValidationError(this, { "failover_timeout" }, "Failover timeout minimum is 60s."));
}
void DbConnection::ValidateCategories(const Array::Ptr& value, const ValidationUtils& utils)
void DbConnection::ValidateCategories(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<DbConnection>::ValidateCategories(value, utils);
ObjectImpl<DbConnection>::ValidateCategories(lvalue, utils);
int filter = FilterArrayToInt(value, DbQuery::GetCategoryFilterMap(), 0);
int filter = FilterArrayToInt(lvalue(), DbQuery::GetCategoryFilterMap(), 0);
if (filter != DbCatEverything && (filter & ~(DbCatInvalid | DbCatEverything | DbCatConfig | DbCatState |
DbCatAcknowledgement | DbCatComment | DbCatDowntime | DbCatEventHandler | DbCatExternalCommand |

View File

@ -74,8 +74,8 @@ public:
int GetQueryCount(RingBuffer::SizeType span);
virtual int GetPendingQueryCount() const = 0;
void ValidateFailoverTimeout(double value, const ValidationUtils& utils) final;
void ValidateCategories(const Array::Ptr& value, const ValidationUtils& utils) final;
void ValidateFailoverTimeout(const Lazy<double>& lvalue, const ValidationUtils& utils) final;
void ValidateCategories(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils) final;
protected:
void OnConfigLoaded() override;

View File

@ -187,18 +187,18 @@ void Checkable::NotifyDowntimeEnd(const Downtime::Ptr& downtime)
OnNotificationsRequested(checkable, NotificationDowntimeEnd, checkable->GetLastCheckResult(), downtime->GetAuthor(), downtime->GetComment(), nullptr);
}
void Checkable::ValidateCheckInterval(double value, const ValidationUtils& utils)
void Checkable::ValidateCheckInterval(const Lazy<double>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<Checkable>::ValidateCheckInterval(value, utils);
ObjectImpl<Checkable>::ValidateCheckInterval(lvalue, utils);
if (value <= 0)
if (lvalue() <= 0)
BOOST_THROW_EXCEPTION(ValidationError(this, { "check_interval" }, "Interval must be greater than 0."));
}
void Checkable::ValidateMaxCheckAttempts(int value, const ValidationUtils& utils)
void Checkable::ValidateMaxCheckAttempts(const Lazy<int>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<Checkable>::ValidateMaxCheckAttempts(value, utils);
ObjectImpl<Checkable>::ValidateMaxCheckAttempts(lvalue, utils);
if (value <= 0)
if (lvalue() <= 0)
BOOST_THROW_EXCEPTION(ValidationError(this, { "max_check_attempts" }, "Value must be greater than 0."));
}

View File

@ -191,8 +191,8 @@ public:
void RemoveReverseDependency(const intrusive_ptr<Dependency>& dep);
std::vector<intrusive_ptr<Dependency> > GetReverseDependencies() const;
void ValidateCheckInterval(double value, const ValidationUtils& utils) final;
void ValidateMaxCheckAttempts(int value, const ValidationUtils& utils) final;
void ValidateCheckInterval(const Lazy<double>& lvalue, const ValidationUtils& value) final;
void ValidateMaxCheckAttempts(const Lazy<int>& lvalue, const ValidationUtils& value) final;
static void IncreasePendingChecks();
static void DecreasePendingChecks();

View File

@ -29,9 +29,9 @@ using namespace icinga;
REGISTER_TYPE(CustomVarObject);
void CustomVarObject::ValidateVars(const Dictionary::Ptr& value, const ValidationUtils& utils)
void CustomVarObject::ValidateVars(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils)
{
MacroProcessor::ValidateCustomVars(this, value);
MacroProcessor::ValidateCustomVars(this, lvalue());
}
int icinga::FilterArrayToInt(const Array::Ptr& typeFilters, const std::map<String, int>& filterMap, int defaultValue)

View File

@ -38,7 +38,7 @@ class CustomVarObject : public ObjectImpl<CustomVarObject>
public:
DECLARE_OBJECT(CustomVarObject);
void ValidateVars(const Dictionary::Ptr& value, const ValidationUtils& utils) final;
void ValidateVars(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils) final;
};
int FilterArrayToInt(const Array::Ptr& typeFilters, const std::map<String, int>& filterMap, int defaultValue);

View File

@ -209,11 +209,11 @@ TimePeriod::Ptr Dependency::GetPeriod() const
return TimePeriod::GetByName(GetPeriodRaw());
}
void Dependency::ValidateStates(const Array::Ptr& value, const ValidationUtils& utils)
void Dependency::ValidateStates(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<Dependency>::ValidateStates(value, utils);
ObjectImpl<Dependency>::ValidateStates(lvalue, utils);
int sfilter = FilterArrayToInt(value, Notification::GetStateFilterMap(), 0);
int sfilter = FilterArrayToInt(lvalue(), Notification::GetStateFilterMap(), 0);
if (GetParentServiceName().IsEmpty() && (sfilter & ~(StateFilterUp | StateFilterDown)) != 0)
BOOST_THROW_EXCEPTION(ValidationError(this, { "states" }, "State filter is invalid for host dependency."));

View File

@ -49,7 +49,7 @@ public:
bool IsAvailable(DependencyType dt) const;
void ValidateStates(const Array::Ptr& value, const ValidationUtils& utils) override;
void ValidateStates(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils) override;
static void EvaluateApplyRules(const intrusive_ptr<Host>& host);
static void EvaluateApplyRules(const intrusive_ptr<Service>& service);

View File

@ -409,18 +409,18 @@ void Downtime::DowntimesExpireTimerHandler()
}
}
void Downtime::ValidateStartTime(const Timestamp& value, const ValidationUtils& utils)
void Downtime::ValidateStartTime(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<Downtime>::ValidateStartTime(value, utils);
ObjectImpl<Downtime>::ValidateStartTime(lvalue, utils);
if (value <= 0)
if (lvalue() <= 0)
BOOST_THROW_EXCEPTION(ValidationError(this, { "start_time" }, "Start time must be greater than 0."));
}
void Downtime::ValidateEndTime(const Timestamp& value, const ValidationUtils& utils)
void Downtime::ValidateEndTime(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<Downtime>::ValidateEndTime(value, utils);
ObjectImpl<Downtime>::ValidateEndTime(lvalue, utils);
if (value <= 0)
if (lvalue() <= 0)
BOOST_THROW_EXCEPTION(ValidationError(this, { "end_time" }, "End time must be greater than 0."));
}

View File

@ -70,8 +70,8 @@ protected:
void Start(bool runtimeCreated) override;
void Stop(bool runtimeRemoved) override;
void ValidateStartTime(const Timestamp& value, const ValidationUtils& utils) override;
void ValidateEndTime(const Timestamp& value, const ValidationUtils& utils) override;
void ValidateStartTime(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils) override;
void ValidateEndTime(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils) override;
private:
ObjectImpl<Checkable>::Ptr m_Checkable;

View File

@ -289,7 +289,7 @@ String IcingaApplication::GetNodeName() const
return ScriptGlobal::Get("NodeName");
}
void IcingaApplication::ValidateVars(const Dictionary::Ptr& value, const ValidationUtils& utils)
void IcingaApplication::ValidateVars(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils)
{
MacroProcessor::ValidateCustomVars(this, value);
MacroProcessor::ValidateCustomVars(this, lvalue());
}

View File

@ -52,7 +52,7 @@ public:
String GetNodeName() const;
void ValidateVars(const Dictionary::Ptr& value, const ValidationUtils& utils) override;
void ValidateVars(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils) override;
private:
void DumpProgramState();

View File

@ -642,11 +642,11 @@ void Notification::Validate(int types, const ValidationUtils& utils)
BOOST_THROW_EXCEPTION(ValidationError(this, std::vector<String>(), "Validation failed: No users/user_groups specified."));
}
void Notification::ValidateStates(const Array::Ptr& value, const ValidationUtils& utils)
void Notification::ValidateStates(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<Notification>::ValidateStates(value, utils);
ObjectImpl<Notification>::ValidateStates(lvalue, utils);
int filter = FilterArrayToInt(value, GetStateFilterMap(), 0);
int filter = FilterArrayToInt(lvalue(), GetStateFilterMap(), 0);
if (GetServiceName().IsEmpty() && (filter == -1 || (filter & ~(StateFilterUp | StateFilterDown)) != 0))
BOOST_THROW_EXCEPTION(ValidationError(this, { "states" }, "State filter is invalid."));
@ -655,11 +655,11 @@ void Notification::ValidateStates(const Array::Ptr& value, const ValidationUtils
BOOST_THROW_EXCEPTION(ValidationError(this, { "states" }, "State filter is invalid."));
}
void Notification::ValidateTypes(const Array::Ptr& value, const ValidationUtils& utils)
void Notification::ValidateTypes(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<Notification>::ValidateTypes(value, utils);
ObjectImpl<Notification>::ValidateTypes(lvalue, utils);
int filter = FilterArrayToInt(value, GetTypeFilterMap(), 0);
int filter = FilterArrayToInt(lvalue(), GetTypeFilterMap(), 0);
if (filter == -1 || (filter & ~(NotificationDowntimeStart | NotificationDowntimeEnd | NotificationDowntimeRemoved |
NotificationCustom | NotificationAcknowledgement | NotificationProblem | NotificationRecovery |

View File

@ -106,8 +106,8 @@ public:
void Validate(int types, const ValidationUtils& utils) override;
void ValidateStates(const Array::Ptr& value, const ValidationUtils& utils) override;
void ValidateTypes(const Array::Ptr& value, const ValidationUtils& utils) override;
void ValidateStates(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils) override;
void ValidateTypes(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils) override;
static void EvaluateApplyRules(const intrusive_ptr<Host>& host);
static void EvaluateApplyRules(const intrusive_ptr<Service>& service);

View File

@ -196,11 +196,11 @@ void ScheduledDowntime::CreateNextDowntime()
GetFixed(), String(), GetDuration(), GetName(), GetName());
}
void ScheduledDowntime::ValidateRanges(const Dictionary::Ptr& value, const ValidationUtils& utils)
void ScheduledDowntime::ValidateRanges(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<ScheduledDowntime>::ValidateRanges(value, utils);
ObjectImpl<ScheduledDowntime>::ValidateRanges(lvalue, utils);
if (!value)
if (!lvalue())
return;
/* create a fake time environment to validate the definitions */
@ -208,8 +208,8 @@ void ScheduledDowntime::ValidateRanges(const Dictionary::Ptr& value, const Valid
tm reference = Utility::LocalTime(refts);
Array::Ptr segments = new Array();
ObjectLock olock(value);
for (const Dictionary::Pair& kv : value) {
ObjectLock olock(lvalue());
for (const Dictionary::Pair& kv : lvalue()) {
try {
tm begin_tm, end_tm;
int stride;

View File

@ -48,7 +48,7 @@ public:
static void EvaluateApplyRules(const intrusive_ptr<Host>& host);
static void EvaluateApplyRules(const intrusive_ptr<Service>& service);
void ValidateRanges(const Dictionary::Ptr& value, const ValidationUtils& utils) override;
void ValidateRanges(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils) override;
protected:
void OnAllConfigLoaded() override;

View File

@ -381,9 +381,9 @@ void TimePeriod::Dump()
Log(LogDebug, "TimePeriod", "---");
}
void TimePeriod::ValidateRanges(const Dictionary::Ptr& value, const ValidationUtils& utils)
void TimePeriod::ValidateRanges(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils)
{
if (!value)
if (!lvalue())
return;
/* create a fake time environment to validate the definitions */
@ -391,8 +391,8 @@ void TimePeriod::ValidateRanges(const Dictionary::Ptr& value, const ValidationUt
tm reference = Utility::LocalTime(refts);
Array::Ptr segments = new Array();
ObjectLock olock(value);
for (const Dictionary::Pair& kv : value) {
ObjectLock olock(lvalue());
for (const Dictionary::Pair& kv : lvalue()) {
try {
tm begin_tm, end_tm;
int stride;

View File

@ -46,7 +46,7 @@ public:
bool IsInside(double ts) const;
double FindNextTransition(double begin);
void ValidateRanges(const Dictionary::Ptr& value, const ValidationUtils& utils) override;
void ValidateRanges(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils) override;
private:
void AddSegment(double s, double end);

View File

@ -97,21 +97,21 @@ TimePeriod::Ptr User::GetPeriod() const
return TimePeriod::GetByName(GetPeriodRaw());
}
void User::ValidateStates(const Array::Ptr& value, const ValidationUtils& utils)
void User::ValidateStates(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<User>::ValidateStates(value, utils);
ObjectImpl<User>::ValidateStates(lvalue, utils);
int filter = FilterArrayToInt(value, Notification::GetStateFilterMap(), 0);
int filter = FilterArrayToInt(lvalue(), Notification::GetStateFilterMap(), 0);
if (filter == -1 || (filter & ~(StateFilterUp | StateFilterDown | StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0)
BOOST_THROW_EXCEPTION(ValidationError(this, { "states" }, "State filter is invalid."));
}
void User::ValidateTypes(const Array::Ptr& value, const ValidationUtils& utils)
void User::ValidateTypes(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<User>::ValidateTypes(value, utils);
ObjectImpl<User>::ValidateTypes(lvalue, utils);
int filter = FilterArrayToInt(value, Notification::GetTypeFilterMap(), 0);
int filter = FilterArrayToInt(lvalue(), Notification::GetTypeFilterMap(), 0);
if (filter == -1 || (filter & ~(NotificationDowntimeStart | NotificationDowntimeEnd | NotificationDowntimeRemoved |
NotificationCustom | NotificationAcknowledgement | NotificationProblem | NotificationRecovery |

View File

@ -44,8 +44,8 @@ public:
/* Notifications */
TimePeriod::Ptr GetPeriod() const;
void ValidateStates(const Array::Ptr& value, const ValidationUtils& utils) override;
void ValidateTypes(const Array::Ptr& value, const ValidationUtils& utils) override;
void ValidateStates(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils) override;
void ValidateTypes(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils) override;
protected:
void Stop(bool runtimeRemoved) override;

View File

@ -220,10 +220,10 @@ void LivestatusListener::ClientHandler(const Socket::Ptr& client)
}
void LivestatusListener::ValidateSocketType(const String& value, const ValidationUtils& utils)
void LivestatusListener::ValidateSocketType(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<LivestatusListener>::ValidateSocketType(value, utils);
ObjectImpl<LivestatusListener>::ValidateSocketType(lvalue, utils);
if (value != "unix" && value != "tcp")
BOOST_THROW_EXCEPTION(ValidationError(this, { "socket_type" }, "Socket type '" + value + "' is invalid."));
if (lvalue() != "unix" && lvalue() != "tcp")
BOOST_THROW_EXCEPTION(ValidationError(this, { "socket_type" }, "Socket type '" + lvalue() + "' is invalid."));
}

View File

@ -45,7 +45,7 @@ public:
static int GetClientsConnected();
static int GetConnections();
void ValidateSocketType(const String& value, const ValidationUtils& utils) override;
void ValidateSocketType(const Lazy<String>& lvalue, const ValidationUtils& utils) override;
protected:
void Start(bool runtimeCreated) override;

View File

@ -342,18 +342,18 @@ Value GraphiteWriter::EscapeMacroMetric(const Value& value)
return EscapeMetric(value);
}
void GraphiteWriter::ValidateHostNameTemplate(const String& value, const ValidationUtils& utils)
void GraphiteWriter::ValidateHostNameTemplate(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<GraphiteWriter>::ValidateHostNameTemplate(value, utils);
ObjectImpl<GraphiteWriter>::ValidateHostNameTemplate(lvalue, utils);
if (!MacroProcessor::ValidateMacroString(value))
BOOST_THROW_EXCEPTION(ValidationError(this, { "host_name_template" }, "Closing $ not found in macro format string '" + value + "'."));
if (!MacroProcessor::ValidateMacroString(lvalue()))
BOOST_THROW_EXCEPTION(ValidationError(this, { "host_name_template" }, "Closing $ not found in macro format string '" + lvalue() + "'."));
}
void GraphiteWriter::ValidateServiceNameTemplate(const String& value, const ValidationUtils& utils)
void GraphiteWriter::ValidateServiceNameTemplate(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<GraphiteWriter>::ValidateServiceNameTemplate(value, utils);
ObjectImpl<GraphiteWriter>::ValidateServiceNameTemplate(lvalue, utils);
if (!MacroProcessor::ValidateMacroString(value))
BOOST_THROW_EXCEPTION(ValidationError(this, { "service_name_template" }, "Closing $ not found in macro format string '" + value + "'."));
if (!MacroProcessor::ValidateMacroString(lvalue()))
BOOST_THROW_EXCEPTION(ValidationError(this, { "service_name_template" }, "Closing $ not found in macro format string '" + lvalue() + "'."));
}

View File

@ -44,8 +44,8 @@ public:
static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);
void ValidateHostNameTemplate(const String& value, const ValidationUtils& utils) override;
void ValidateServiceNameTemplate(const String& value, const ValidationUtils& utils) override;
void ValidateHostNameTemplate(const Lazy<String>& lvalue, const ValidationUtils& utils) override;
void ValidateServiceNameTemplate(const Lazy<String>& lvalue, const ValidationUtils& utils) override;
protected:
void OnConfigLoaded() override;

View File

@ -494,15 +494,15 @@ void InfluxdbWriter::Flush()
}
}
void InfluxdbWriter::ValidateHostTemplate(const Dictionary::Ptr& value, const ValidationUtils& utils)
void InfluxdbWriter::ValidateHostTemplate(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<InfluxdbWriter>::ValidateHostTemplate(value, utils);
ObjectImpl<InfluxdbWriter>::ValidateHostTemplate(lvalue, utils);
String measurement = value->Get("measurement");
String measurement = lvalue()->Get("measurement");
if (!MacroProcessor::ValidateMacroString(measurement))
BOOST_THROW_EXCEPTION(ValidationError(this, { "host_template", "measurement" }, "Closing $ not found in macro format string '" + measurement + "'."));
Dictionary::Ptr tags = value->Get("tags");
Dictionary::Ptr tags = lvalue()->Get("tags");
if (tags) {
ObjectLock olock(tags);
for (const Dictionary::Pair& pair : tags) {
@ -512,15 +512,15 @@ void InfluxdbWriter::ValidateHostTemplate(const Dictionary::Ptr& value, const Va
}
}
void InfluxdbWriter::ValidateServiceTemplate(const Dictionary::Ptr& value, const ValidationUtils& utils)
void InfluxdbWriter::ValidateServiceTemplate(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<InfluxdbWriter>::ValidateServiceTemplate(value, utils);
ObjectImpl<InfluxdbWriter>::ValidateServiceTemplate(lvalue, utils);
String measurement = value->Get("measurement");
String measurement = lvalue()->Get("measurement");
if (!MacroProcessor::ValidateMacroString(measurement))
BOOST_THROW_EXCEPTION(ValidationError(this, { "service_template", "measurement" }, "Closing $ not found in macro format string '" + measurement + "'."));
Dictionary::Ptr tags = value->Get("tags");
Dictionary::Ptr tags = lvalue()->Get("tags");
if (tags) {
ObjectLock olock(tags);
for (const Dictionary::Pair& pair : tags) {

View File

@ -44,8 +44,8 @@ public:
static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);
void ValidateHostTemplate(const Dictionary::Ptr& value, const ValidationUtils& utils) override;
void ValidateServiceTemplate(const Dictionary::Ptr& value, const ValidationUtils& utils) override;
void ValidateHostTemplate(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils) override;
void ValidateServiceTemplate(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils) override;
protected:
void OnConfigLoaded() override;

View File

@ -158,18 +158,18 @@ void PerfdataWriter::RotationTimerHandler()
RotateFile(m_HostOutputFile, GetHostTempPath(), GetHostPerfdataPath());
}
void PerfdataWriter::ValidateHostFormatTemplate(const String& value, const ValidationUtils& utils)
void PerfdataWriter::ValidateHostFormatTemplate(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<PerfdataWriter>::ValidateHostFormatTemplate(value, utils);
ObjectImpl<PerfdataWriter>::ValidateHostFormatTemplate(lvalue, utils);
if (!MacroProcessor::ValidateMacroString(value))
BOOST_THROW_EXCEPTION(ValidationError(this, { "host_format_template" }, "Closing $ not found in macro format string '" + value + "'."));
if (!MacroProcessor::ValidateMacroString(lvalue()))
BOOST_THROW_EXCEPTION(ValidationError(this, { "host_format_template" }, "Closing $ not found in macro format string '" + lvalue() + "'."));
}
void PerfdataWriter::ValidateServiceFormatTemplate(const String& value, const ValidationUtils& utils)
void PerfdataWriter::ValidateServiceFormatTemplate(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<PerfdataWriter>::ValidateServiceFormatTemplate(value, utils);
ObjectImpl<PerfdataWriter>::ValidateServiceFormatTemplate(lvalue, utils);
if (!MacroProcessor::ValidateMacroString(value))
BOOST_THROW_EXCEPTION(ValidationError(this, { "service_format_template" }, "Closing $ not found in macro format string '" + value + "'."));
if (!MacroProcessor::ValidateMacroString(lvalue()))
BOOST_THROW_EXCEPTION(ValidationError(this, { "service_format_template" }, "Closing $ not found in macro format string '" + lvalue() + "'."));
}

View File

@ -42,8 +42,8 @@ public:
static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);
void ValidateHostFormatTemplate(const String& value, const ValidationUtils& utils) override;
void ValidateServiceFormatTemplate(const String& value, const ValidationUtils& utils) override;
void ValidateHostFormatTemplate(const Lazy<String>& lvalue, const ValidationUtils& utils) override;
void ValidateServiceFormatTemplate(const Lazy<String>& lvalue, const ValidationUtils& utils) override;
protected:
void Start(bool runtimeCreated) override;

View File

@ -1399,14 +1399,14 @@ Endpoint::Ptr ApiListener::GetLocalEndpoint() const
return m_LocalEndpoint;
}
void ApiListener::ValidateTlsProtocolmin(const String& value, const ValidationUtils& utils)
void ApiListener::ValidateTlsProtocolmin(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<ApiListener>::ValidateTlsProtocolmin(value, utils);
ObjectImpl<ApiListener>::ValidateTlsProtocolmin(lvalue, utils);
if (value != SSL_TXT_TLSV1
if (lvalue() != SSL_TXT_TLSV1
#ifdef SSL_TXT_TLSV1_1
&& value != SSL_TXT_TLSV1_1 &&
value != SSL_TXT_TLSV1_2
&& lvalue() != SSL_TXT_TLSV1_1 &&
lvalue() != SSL_TXT_TLSV1_2
#endif /* SSL_TXT_TLSV1_1 */
) {
String message = "Invalid TLS version. Must be one of '" SSL_TXT_TLSV1 "'";

View File

@ -114,7 +114,7 @@ protected:
void Start(bool runtimeCreated) override;
void Stop(bool runtimeDeleted) override;
void ValidateTlsProtocolmin(const String& value, const ValidationUtils& utils) override;
void ValidateTlsProtocolmin(const Lazy<String>& lvalue, const ValidationUtils& utils) override;
private:
std::shared_ptr<SSL_CTX> m_SSLContext;

View File

@ -144,11 +144,11 @@ Zone::Ptr Zone::GetLocalZone()
return local->GetZone();
}
void Zone::ValidateEndpointsRaw(const Array::Ptr& value, const ValidationUtils& utils)
void Zone::ValidateEndpointsRaw(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<Zone>::ValidateEndpointsRaw(value, utils);
ObjectImpl<Zone>::ValidateEndpointsRaw(lvalue, utils);
if (value && value->GetLength() > 2) {
if (lvalue() && lvalue()->GetLength() > 2) {
Log(LogWarning, "Zone")
<< "The Zone object '" << GetName() << "' has more than two endpoints."
<< " Due to a known issue this type of configuration is strongly"

View File

@ -50,7 +50,7 @@ public:
static Zone::Ptr GetLocalZone();
protected:
void ValidateEndpointsRaw(const Array::Ptr& value, const ValidationUtils& utils) override;
void ValidateEndpointsRaw(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils) override;
private:
Zone::Ptr m_Parent;

View File

@ -470,53 +470,56 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
for (const Field& field : klass.Fields) {
m_Impl << "\t" << "if (" << (field.Attributes & (FAEphemeral|FAConfig|FAState)) << " & types)" << std::endl
<< "\t\t" << "Validate" << field.GetFriendlyName() << "(Get" << field.GetFriendlyName() << "(), utils);" << std::endl;
<< "\t\t" << "Validate" << field.GetFriendlyName() << "(Lazy<" << field.Type.GetRealType() << ">([this]() { return Get" << field.GetFriendlyName() << "(); }), utils);" << std::endl;
}
m_Impl << "}" << std::endl << std::endl;
for (const Field& field : klass.Fields) {
std::string argName;
std::string argName, valName;
if (field.Type.ArrayRank > 0)
if (field.Type.ArrayRank > 0) {
argName = "avalue";
else
valName = "value";
} else {
argName = "value";
valName = "value()";
}
m_Header << "\t" << "void SimpleValidate" << field.GetFriendlyName() << "(" << field.Type.GetArgumentType() << " " << argName << ", const ValidationUtils& utils);" << std::endl;
m_Header << "\t" << "void SimpleValidate" << field.GetFriendlyName() << "(const Lazy<" << field.Type.GetRealType() << ">& " << argName << ", const ValidationUtils& utils);" << std::endl;
m_Impl << "void ObjectImpl<" << klass.Name << ">::SimpleValidate" << field.GetFriendlyName() << "(" << field.Type.GetArgumentType() << " " << argName << ", const ValidationUtils& utils)" << std::endl
m_Impl << "void ObjectImpl<" << klass.Name << ">::SimpleValidate" << field.GetFriendlyName() << "(const Lazy<" << field.Type.GetRealType() << ">& " << argName << ", const ValidationUtils& utils)" << std::endl
<< "{" << std::endl;
if (field.Attributes & FARequired) {
if (field.Type.GetRealType().find("::Ptr") != std::string::npos)
m_Impl << "\t" << "if (!" << argName << ")" << std::endl;
m_Impl << "\t" << "if (!" << argName << "())" << std::endl;
else
m_Impl << "\t" << "if (" << argName << ".IsEmpty())" << std::endl;
m_Impl << "\t" << "if (" << argName << "().IsEmpty())" << std::endl;
m_Impl << "\t\t" << "BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { \"" << field.Name << R"(" }, "Attribute must not be empty."));)" << std::endl << std::endl;
}
if (field.Attributes & FADeprecated) {
if (field.Type.GetRealType().find("::Ptr") != std::string::npos)
m_Impl << "\t" << "if (" << argName << ")" << std::endl;
m_Impl << "\t" << "if (" << argName << "())" << std::endl;
else
m_Impl << "\t" << "if (" << argName << " != GetDefault" << field.GetFriendlyName() << "())" << std::endl;
m_Impl << "\t" << "if (" << argName << "() != GetDefault" << field.GetFriendlyName() << "())" << std::endl;
m_Impl << "\t\t" << "Log(LogWarning, \"" << klass.Name << "\") << \"Attribute '" << field.Name << R"(' for object '" << dynamic_cast<ConfigObject *>(this)->GetName() << "' of type '" << dynamic_cast<ConfigObject *>(this)->GetReflectionType()->GetName() << "' is deprecated and should not be used.";)" << std::endl;
}
if (field.Type.ArrayRank > 0) {
m_Impl << "\t" << "if (avalue) {" << std::endl
<< "\t\t" << "ObjectLock olock(avalue);" << std::endl
<< "\t\t" << "for (const Value& value : avalue) {" << std::endl;
m_Impl << "\t" << "if (avalue()) {" << std::endl
<< "\t\t" << "ObjectLock olock(avalue());" << std::endl
<< "\t\t" << "for (const Value& value : avalue()) {" << std::endl;
}
std::string ftype = FieldTypeToIcingaName(field, true);
if (ftype == "Value") {
m_Impl << "\t" << "if (value.IsObjectType<Function>()) {" << std::endl
<< "\t\t" << "Function::Ptr func = value;" << std::endl
m_Impl << "\t" << "if (" << valName << ".IsObjectType<Function>()) {" << std::endl
<< "\t\t" << "Function::Ptr func = " << valName << ";" << std::endl
<< "\t\t" << "if (func->IsDeprecated())" << std::endl
<< "\t\t\t" << "Log(LogWarning, \"" << klass.Name << "\") << \"Attribute '" << field.Name << R"(' for object '" << dynamic_cast<ConfigObject *>(this)->GetName() << "' of type '" << dynamic_cast<ConfigObject *>(this)->GetReflectionType()->GetName() << "' is set to a deprecated function: " << func->GetName();)" << std::endl
<< "\t" << "}" << std::endl << std::endl;
@ -526,18 +529,18 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
m_Impl << "\t" << "if (";
if (field.Type.ArrayRank > 0)
m_Impl << "value.IsEmpty() || ";
m_Impl << valName << ".IsEmpty() || ";
else
m_Impl << "!value.IsEmpty() && ";
m_Impl << "!" << valName << ".IsEmpty() && ";
m_Impl << "!utils.ValidateName(\"" << field.Type.TypeName << "\", value))" << std::endl
<< "\t\t" << "BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { \"" << field.Name << R"(" }, "Object '" + value + "' of type ')" << field.Type.TypeName
m_Impl << "!utils.ValidateName(\"" << field.Type.TypeName << "\", " << valName << "))" << std::endl
<< "\t\t" << "BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { \"" << field.Name << R"(" }, "Object '" + )" << valName << R"( + "' of type ')" << field.Type.TypeName
<< "' does not exist.\"));" << std::endl;
} else if (field.Type.ArrayRank > 0 && (ftype == "Number" || ftype == "Boolean")) {
m_Impl << "\t" << "try {" << std::endl
<< "\t\t" << "Convert::ToDouble(value);" << std::endl
<< "\t\t" << "Convert::ToDouble(" << valName << ");" << std::endl
<< "\t" << "} catch (const std::invalid_argument&) {" << std::endl
<< "\t\t" << "BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { \"" << field.Name << R"(", "Array element '" + value + "' of type '" + value.GetReflectionType()->GetName() + "' is not valid here; expected type ')" << ftype << "'.\"));" << std::endl
<< "\t\t" << "BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { \"" << field.Name << R"(", "Array element '" + " << valName << " + "' of type '" + " << valName << ".GetReflectionType()->GetName() + "' is not valid here; expected type ')" << ftype << "'.\"));" << std::endl
<< "\t" << "}" << std::endl;
}
@ -649,14 +652,14 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
/* ValidateField */
m_Header << "public:" << std::endl
<< "\t" << "void ValidateField(int id, const Value& value, const ValidationUtils& utils) override;" << std::endl;
<< "\t" << "void ValidateField(int id, const Lazy<Value>& lvalue, const ValidationUtils& utils) override;" << std::endl;
m_Impl << "void ObjectImpl<" << klass.Name << ">::ValidateField(int id, const Value& value, const ValidationUtils& utils)" << std::endl
m_Impl << "void ObjectImpl<" << klass.Name << ">::ValidateField(int id, const Lazy<Value>& lvalue, const ValidationUtils& utils)" << std::endl
<< "{" << std::endl;
if (!klass.Parent.empty())
m_Impl << "\t" << "int real_id = id - " << klass.Parent << "::TypeInstance->GetFieldCount(); " << std::endl
<< "\t" << "if (real_id < 0) { " << klass.Parent << "::ValidateField(id, value, utils); return; }" << std::endl;
<< "\t" << "if (real_id < 0) { " << klass.Parent << "::ValidateField(id, lvalue, utils); return; }" << std::endl;
m_Impl << "\t" << "switch (";
@ -673,9 +676,9 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
<< "\t\t\t" << "Validate" << field.GetFriendlyName() << "(";
if (field.Attributes & FAEnum)
m_Impl << "static_cast<" << field.Type.GetRealType() << ">(static_cast<int>(";
m_Impl << "static_cast<Lazy<" << field.Type.GetRealType() << "> >(static_cast<Lazy<int> >(";
m_Impl << "value";
m_Impl << "lvalue";
if (field.Attributes & FAEnum)
m_Impl << "))";
@ -1039,7 +1042,7 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
/* validators */
for (const Field& field : klass.Fields) {
m_Header << "protected:" << std::endl
<< "\t" << "virtual void Validate" << field.GetFriendlyName() << "(" << field.Type.GetArgumentType() << " value, const ValidationUtils& utils);" << std::endl;
<< "\t" << "virtual void Validate" << field.GetFriendlyName() << "(const Lazy<" << field.Type.GetRealType() << ">& lvalue, const ValidationUtils& utils);" << std::endl;
}
/* instance variables */
@ -1144,7 +1147,7 @@ void ClassCompiler::CodeGenValidator(const std::string& name, const std::string&
<< "\t\t\t" << "if (utils.ValidateName(\"" << rule.Type << "\", value))" << std::endl
<< "\t\t\t\t" << "return;" << std::endl
<< "\t\t\t" << "else" << std::endl
<< "\t\t\t\t" << R"(BOOST_THROW_EXCEPTION(ValidationError(dynamic_pointer_cast<ConfigObject>(object), location, "Object '" + value + "' of type ')" << rule.Type << "' does not exist.\"));" << std::endl
<< "\t\t\t\t" << R"(BOOST_THROW_EXCEPTION(ValidationError(dynamic_pointer_cast<ConfigObject>(object), location, "Object '" + ")" << "xxx" << R"( + "' of type ')" << rule.Type << "' does not exist.\"));" << std::endl
<< "\t\t" << "}" << std::endl;
}
@ -1309,12 +1312,12 @@ void ClassCompiler::HandleValidator(const Validator& validator, const ClassDebug
CodeGenValidator(it.first.first + it.first.second, it.first.first, validator.Rules, it.second.Name, it.second.Type, ValidatorField);
for (const auto& it : m_MissingValidators) {
m_Impl << "void ObjectImpl<" << it.first.first << ">::Validate" << it.first.second << "(" << it.second.Type.GetArgumentType() << " value, const ValidationUtils& utils)" << std::endl
m_Impl << "void ObjectImpl<" << it.first.first << ">::Validate" << it.first.second << "(const Lazy<" << it.second.Type.GetRealType() << ">& lvalue, const ValidationUtils& utils)" << std::endl
<< "{" << std::endl
<< "\t" << "SimpleValidate" << it.first.second << "(value, utils);" << std::endl
<< "\t" << "SimpleValidate" << it.first.second << "(lvalue, utils);" << std::endl
<< "\t" << "std::vector<String> location;" << std::endl
<< "\t" << "location.emplace_back(\"" << it.second.Name << "\");" << std::endl
<< "\t" << "TIValidate" << it.first.first << it.first.second << "(this, value, location, utils);" << std::endl
<< "\t" << "TIValidate" << it.first.first << it.first.second << "(this, lvalue(), location, utils);" << std::endl
<< "\t" << "location.pop_back();" << std::endl
<< "}" << std::endl << std::endl;
}
@ -1325,9 +1328,9 @@ void ClassCompiler::HandleValidator(const Validator& validator, const ClassDebug
void ClassCompiler::HandleMissingValidators()
{
for (const auto& it : m_MissingValidators) {
m_Impl << "void ObjectImpl<" << it.first.first << ">::Validate" << it.first.second << "(" << it.second.Type.GetArgumentType() << " value, const ValidationUtils& utils)" << std::endl
m_Impl << "void ObjectImpl<" << it.first.first << ">::Validate" << it.first.second << "(const Lazy<" << it.second.Type.GetRealType() << ">& lvalue, const ValidationUtils& utils)" << std::endl
<< "{" << std::endl
<< "\t" << "SimpleValidate" << it.first.second << "(value, utils);" << std::endl
<< "\t" << "SimpleValidate" << it.first.second << "(lvalue, utils);" << std::endl
<< "}" << std::endl << std::endl;
}