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'."));
}
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. */
}
ModAttrValidationUtils utils;
- ValidateField(fid, newValue, utils);
+ ValidateField(fid, Lazy<Value>{newValue}, utils);
SetField(fid, newValue);
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()));
}
}
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;
/* 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. */
}
}
};
+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.
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;
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."));
}
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;
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."));
}
}
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;
}
}
-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 |
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;
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."));
}
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();
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)
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);
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."));
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);
}
}
-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."));
}
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;
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());
}
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();
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."));
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 |
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);
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 */
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;
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;
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 */
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;
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);
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 |
/* 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;
}
-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."));
}
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;
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() + "'."));
}
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;
}
}
-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) {
}
}
-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) {
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;
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() + "'."));
}
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;
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 "'";
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;
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"
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;
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;
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;
}
/* 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 (";
<< "\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 << "))";
/* 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 */
<< "\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;
}
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;
}
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;
}