mirror of https://github.com/Icinga/icinga2.git
Improve config compiler's memory usage
This commit is contained in:
parent
85a380c443
commit
e1c95d4fa0
|
@ -29,12 +29,14 @@ enum HAMode
|
|||
|
||||
class NameComposer {
|
||||
public:
|
||||
virtual String MakeName(const String& shortName, const Dictionary::Ptr& props) const = 0;
|
||||
virtual String MakeName(const String& shortName, const Object::Ptr& context) const = 0;
|
||||
};
|
||||
}}}
|
||||
|
||||
abstract class DynamicObject
|
||||
{
|
||||
[protected] Object::Ptr __parent (ParentScope);
|
||||
|
||||
[config, internal] String __name (Name);
|
||||
[config] String name (ShortName) {
|
||||
get {{{
|
||||
|
|
|
@ -123,19 +123,6 @@ DynamicObject::Ptr DynamicType::GetObject(const String& name) const
|
|||
return nt->second;
|
||||
}
|
||||
|
||||
DynamicObject::Ptr DynamicType::CreateObject(const Dictionary::Ptr& serializedUpdate)
|
||||
{
|
||||
ASSERT(!OwnsLock());
|
||||
|
||||
Type::Ptr type = Type::GetByName(m_Name);
|
||||
|
||||
Object::Ptr object = type->Instantiate();
|
||||
|
||||
Deserialize(object, serializedUpdate, true, FAConfig);
|
||||
|
||||
return static_pointer_cast<DynamicObject>(object);
|
||||
}
|
||||
|
||||
boost::mutex& DynamicType::GetStaticMutex(void)
|
||||
{
|
||||
static boost::mutex mutex;
|
||||
|
|
|
@ -44,7 +44,6 @@ public:
|
|||
|
||||
static DynamicType::Ptr GetByName(const String& name);
|
||||
|
||||
DynamicObject::Ptr CreateObject(const Dictionary::Ptr& serializedUpdate);
|
||||
DynamicObject::Ptr GetObject(const String& name) const;
|
||||
|
||||
void RegisterObject(const DynamicObject::Ptr& object);
|
||||
|
|
|
@ -97,6 +97,9 @@ public:
|
|||
if (IsEmpty())
|
||||
return shared_ptr<T>();
|
||||
|
||||
if (!IsObject())
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Cannot convert value to object."));
|
||||
|
||||
Object::Ptr object = boost::get<Object::Ptr>(m_Value);
|
||||
|
||||
ASSERT(object);
|
||||
|
|
|
@ -81,6 +81,9 @@ static bool LoadConfigFiles(const boost::program_options::variables_map& vm, con
|
|||
{
|
||||
ConfigCompilerContext::GetInstance()->Reset();
|
||||
|
||||
if (!objectsFile.IsEmpty())
|
||||
ConfigCompilerContext::GetInstance()->OpenObjectsFile(objectsFile);
|
||||
|
||||
if (vm.count("config") > 0) {
|
||||
BOOST_FOREACH(const String& configPath, vm["config"].as<std::vector<std::string> >()) {
|
||||
ConfigCompiler::CompileFile(configPath);
|
||||
|
@ -109,7 +112,7 @@ static bool LoadConfigFiles(const boost::program_options::variables_map& vm, con
|
|||
ConfigItem::Ptr item = builder->Compile();
|
||||
item->Register();
|
||||
|
||||
bool result = ConfigItem::ValidateItems(objectsFile);
|
||||
bool result = ConfigItem::ValidateItems();
|
||||
|
||||
int warnings = 0, errors = 0;
|
||||
|
||||
|
@ -149,6 +152,8 @@ static bool LoadConfigFiles(const boost::program_options::variables_map& vm, con
|
|||
if (!result)
|
||||
return false;
|
||||
|
||||
ConfigCompilerContext::GetInstance()->FinishObjectsFile();
|
||||
|
||||
ScriptVariable::WriteVariablesFile(varsfile);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -29,7 +29,7 @@ ApplyRule::CallbackMap ApplyRule::m_Callbacks;
|
|||
|
||||
ApplyRule::ApplyRule(const String& targetType, const String& name, const Expression::Ptr& expression,
|
||||
const Expression::Ptr& filter, const String& fkvar, const String& fvvar, const Expression::Ptr& fterm,
|
||||
const DebugInfo& di, const Dictionary::Ptr& scope)
|
||||
const DebugInfo& di, const Object::Ptr& scope)
|
||||
: m_TargetType(targetType), m_Name(name), m_Expression(expression), m_Filter(filter), m_FKVar(fkvar),
|
||||
m_FVVar(fvvar), m_FTerm(fterm), m_DebugInfo(di), m_Scope(scope)
|
||||
{ }
|
||||
|
@ -74,19 +74,19 @@ DebugInfo ApplyRule::GetDebugInfo(void) const
|
|||
return m_DebugInfo;
|
||||
}
|
||||
|
||||
Dictionary::Ptr ApplyRule::GetScope(void) const
|
||||
Object::Ptr ApplyRule::GetScope(void) const
|
||||
{
|
||||
return m_Scope;
|
||||
}
|
||||
|
||||
void ApplyRule::AddRule(const String& sourceType, const String& targetType, const String& name,
|
||||
const Expression::Ptr& expression, const Expression::Ptr& filter, const String& fkvar,
|
||||
const String& fvvar, const Expression::Ptr& fterm, const DebugInfo& di, const Dictionary::Ptr& scope)
|
||||
const String& fvvar, const Expression::Ptr& fterm, const DebugInfo& di, const Object::Ptr& scope)
|
||||
{
|
||||
m_Rules[sourceType].push_back(ApplyRule(targetType, name, expression, filter, fkvar, fvvar, fterm, di, scope));
|
||||
}
|
||||
|
||||
bool ApplyRule::EvaluateFilter(const Dictionary::Ptr& scope) const
|
||||
bool ApplyRule::EvaluateFilter(const Object::Ptr& scope) const
|
||||
{
|
||||
return m_Filter->Evaluate(scope);
|
||||
}
|
||||
|
|
|
@ -46,12 +46,12 @@ public:
|
|||
String GetFVVar(void) const;
|
||||
Expression::Ptr GetFTerm(void) const;
|
||||
DebugInfo GetDebugInfo(void) const;
|
||||
Dictionary::Ptr GetScope(void) const;
|
||||
Object::Ptr GetScope(void) const;
|
||||
|
||||
bool EvaluateFilter(const Dictionary::Ptr& scope) const;
|
||||
bool EvaluateFilter(const Object::Ptr& scope) const;
|
||||
|
||||
static void AddRule(const String& sourceType, const String& targetType, const String& name, const Expression::Ptr& expression,
|
||||
const Expression::Ptr& filter, const String& fkvar, const String& fvvar, const Expression::Ptr& fterm, const DebugInfo& di, const Dictionary::Ptr& scope);
|
||||
const Expression::Ptr& filter, const String& fkvar, const String& fvvar, const Expression::Ptr& fterm, const DebugInfo& di, const Object::Ptr& scope);
|
||||
static void EvaluateRules(bool clear);
|
||||
|
||||
static void RegisterType(const String& sourceType, const std::vector<String>& targetTypes, const ApplyRule::Callback& callback);
|
||||
|
@ -68,14 +68,14 @@ private:
|
|||
String m_FVVar;
|
||||
Expression::Ptr m_FTerm;
|
||||
DebugInfo m_DebugInfo;
|
||||
Dictionary::Ptr m_Scope;
|
||||
Object::Ptr m_Scope;
|
||||
|
||||
static CallbackMap m_Callbacks;
|
||||
static RuleMap m_Rules;
|
||||
|
||||
ApplyRule(const String& targetType, const String& name, const Expression::Ptr& expression,
|
||||
const Expression::Ptr& filter, const String& fkvar, const String& fvvar, const Expression::Ptr& fterm,
|
||||
const DebugInfo& di, const Dictionary::Ptr& scope);
|
||||
const DebugInfo& di, const Object::Ptr& scope);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -19,7 +19,10 @@
|
|||
|
||||
#include "config/configcompilercontext.hpp"
|
||||
#include "base/singleton.hpp"
|
||||
#include "base/json.hpp"
|
||||
#include "base/netstring.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
#include <fstream>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
|
@ -61,3 +64,50 @@ ConfigCompilerContext *ConfigCompilerContext::GetInstance(void)
|
|||
return Singleton<ConfigCompilerContext>::GetInstance();
|
||||
}
|
||||
|
||||
void ConfigCompilerContext::OpenObjectsFile(const String& filename)
|
||||
{
|
||||
m_ObjectsPath = filename;
|
||||
|
||||
String tempFilename = m_ObjectsPath + ".tmp";
|
||||
|
||||
std::fstream *fp = new std::fstream();
|
||||
fp->open(tempFilename.CStr(), std::ios_base::out);
|
||||
|
||||
if (!*fp)
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Could not open '" + tempFilename + "' file"));
|
||||
|
||||
m_ObjectsFP = make_shared<StdioStream>(fp, true);
|
||||
}
|
||||
|
||||
void ConfigCompilerContext::WriteObject(const Dictionary::Ptr& object)
|
||||
{
|
||||
if (!m_ObjectsFP)
|
||||
return;
|
||||
|
||||
String json = JsonEncode(object);
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
NetString::WriteStringToStream(m_ObjectsFP, json);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigCompilerContext::FinishObjectsFile(void)
|
||||
{
|
||||
m_ObjectsFP->Close();
|
||||
|
||||
String tempFilename = m_ObjectsPath + ".tmp";
|
||||
|
||||
#ifdef _WIN32
|
||||
_unlink(m_ObjectsPath.CStr());
|
||||
#endif /* _WIN32 */
|
||||
|
||||
if (rename(tempFilename.CStr(), m_ObjectsPath.CStr()) < 0) {
|
||||
BOOST_THROW_EXCEPTION(posix_error()
|
||||
<< boost::errinfo_api_function("rename")
|
||||
<< boost::errinfo_errno(errno)
|
||||
<< boost::errinfo_file_name(tempFilename));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
#include "config/i2-config.hpp"
|
||||
#include "base/debuginfo.hpp"
|
||||
#include "base/stdiostream.hpp"
|
||||
#include "base/dictionary.hpp"
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <vector>
|
||||
|
||||
|
@ -51,10 +53,16 @@ public:
|
|||
|
||||
void Reset(void);
|
||||
|
||||
void OpenObjectsFile(const String& filename);
|
||||
void WriteObject(const Dictionary::Ptr& object);
|
||||
void FinishObjectsFile(void);
|
||||
|
||||
static ConfigCompilerContext *GetInstance(void);
|
||||
|
||||
private:
|
||||
std::vector<ConfigCompilerMessage> m_Messages;
|
||||
String m_ObjectsPath;
|
||||
StdioStream::Ptr m_ObjectsFP;
|
||||
|
||||
mutable boost::mutex m_Mutex;
|
||||
};
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "base/exception.hpp"
|
||||
#include "base/stdiostream.hpp"
|
||||
#include "base/netstring.hpp"
|
||||
#include "base/serializer.hpp"
|
||||
#include "base/json.hpp"
|
||||
#include "base/configerror.hpp"
|
||||
#include <sstream>
|
||||
|
@ -55,9 +56,9 @@ ConfigItem::ItemMap ConfigItem::m_Items;
|
|||
*/
|
||||
ConfigItem::ConfigItem(const String& type, const String& name,
|
||||
bool abstract, const Expression::Ptr& exprl,
|
||||
const DebugInfo& debuginfo, const Dictionary::Ptr& scope,
|
||||
const DebugInfo& debuginfo, const Object::Ptr& scope,
|
||||
const String& zone)
|
||||
: m_Type(type), m_Name(name), m_Abstract(abstract), m_Validated(false),
|
||||
: m_Type(type), m_Name(name), m_Abstract(abstract),
|
||||
m_ExpressionList(exprl), m_DebugInfo(debuginfo),
|
||||
m_Scope(scope), m_Zone(zone)
|
||||
{
|
||||
|
@ -103,7 +104,7 @@ DebugInfo ConfigItem::GetDebugInfo(void) const
|
|||
return m_DebugInfo;
|
||||
}
|
||||
|
||||
Dictionary::Ptr ConfigItem::GetScope(void) const
|
||||
Object::Ptr ConfigItem::GetScope(void) const
|
||||
{
|
||||
return m_Scope;
|
||||
}
|
||||
|
@ -118,62 +119,13 @@ Expression::Ptr ConfigItem::GetExpressionList(void) const
|
|||
return m_ExpressionList;
|
||||
}
|
||||
|
||||
Dictionary::Ptr ConfigItem::GetProperties(void)
|
||||
{
|
||||
ASSERT(!OwnsLock());
|
||||
VERIFY(!IsAbstract());
|
||||
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (!m_Properties) {
|
||||
Dictionary::Ptr locals = make_shared<Dictionary>();
|
||||
locals->Set("__parent", m_Scope);
|
||||
locals->Set("name", m_Name);
|
||||
|
||||
m_Properties = make_shared<Dictionary>();
|
||||
m_Properties->Set("type", m_Type);
|
||||
if (!m_Zone.IsEmpty())
|
||||
m_Properties->Set("zone", m_Zone);
|
||||
m_Properties->Set("__parent", locals);
|
||||
GetExpressionList()->Evaluate(m_Properties, &m_DebugHints);
|
||||
m_Properties->Remove("__parent");
|
||||
|
||||
String name = m_Name;
|
||||
|
||||
if (!m_Abstract) {
|
||||
shared_ptr<NameComposer> nc = dynamic_pointer_cast<NameComposer>(Type::GetByName(m_Type));
|
||||
|
||||
if (nc) {
|
||||
name = nc->MakeName(m_Name, m_Properties);
|
||||
|
||||
if (name.IsEmpty())
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Could not determine name for object"));
|
||||
}
|
||||
}
|
||||
|
||||
if (name != m_Name)
|
||||
m_Properties->Set("name", m_Name);
|
||||
|
||||
m_Properties->Set("__name", name);
|
||||
|
||||
VERIFY(m_Properties->Get("type") == GetType());
|
||||
}
|
||||
|
||||
return m_Properties;
|
||||
}
|
||||
|
||||
const DebugHint& ConfigItem::GetDebugHints(void) const
|
||||
{
|
||||
return m_DebugHints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits the configuration item by creating a DynamicObject
|
||||
* object.
|
||||
*
|
||||
* @returns The DynamicObject that was created/updated.
|
||||
*/
|
||||
DynamicObject::Ptr ConfigItem::Commit(void)
|
||||
DynamicObject::Ptr ConfigItem::Commit(bool discard)
|
||||
{
|
||||
ASSERT(!OwnsLock());
|
||||
|
||||
|
@ -183,16 +135,88 @@ DynamicObject::Ptr ConfigItem::Commit(void)
|
|||
#endif /* _DEBUG */
|
||||
|
||||
/* Make sure the type is valid. */
|
||||
DynamicType::Ptr dtype = DynamicType::GetByName(GetType());
|
||||
Type::Ptr type = Type::GetByName(GetType());
|
||||
|
||||
if (!dtype)
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Type '" + GetType() + "' does not exist."));
|
||||
if (!type || !Type::GetByName("DynamicObject")->IsAssignableFrom(type))
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Type '" + GetType() + "' does not exist."));
|
||||
|
||||
if (IsAbstract())
|
||||
return DynamicObject::Ptr();
|
||||
|
||||
DynamicObject::Ptr dobj = dtype->CreateObject(GetProperties());
|
||||
DynamicObject::Ptr dobj = static_pointer_cast<DynamicObject>(type->Instantiate());
|
||||
|
||||
dobj->SetDebugInfo(m_DebugInfo);
|
||||
dobj->SetTypeName(m_Type);
|
||||
dobj->SetZone(m_Zone);
|
||||
|
||||
Dictionary::Ptr locals = make_shared<Dictionary>();
|
||||
locals->Set("__parent", m_Scope);
|
||||
m_Scope.reset();
|
||||
locals->Set("name", m_Name);
|
||||
|
||||
dobj->SetParentScope(locals);
|
||||
|
||||
DebugHint debugHints;
|
||||
|
||||
try {
|
||||
m_ExpressionList->Evaluate(dobj, &debugHints);
|
||||
} catch (const ConfigError& ex) {
|
||||
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
|
||||
} catch (const std::exception& ex) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
|
||||
}
|
||||
|
||||
if (discard)
|
||||
m_ExpressionList.reset();
|
||||
|
||||
dobj->SetParentScope(Dictionary::Ptr());
|
||||
|
||||
String name = m_Name;
|
||||
|
||||
shared_ptr<NameComposer> nc = dynamic_pointer_cast<NameComposer>(type);
|
||||
|
||||
if (nc) {
|
||||
name = nc->MakeName(m_Name, dobj);
|
||||
|
||||
if (name.IsEmpty())
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Could not determine name for object"));
|
||||
}
|
||||
|
||||
if (name != m_Name)
|
||||
dobj->SetShortName(m_Name);
|
||||
|
||||
dobj->SetName(name);
|
||||
|
||||
Dictionary::Ptr attrs = Serialize(dobj, FAConfig);
|
||||
|
||||
Dictionary::Ptr persistentItem = make_shared<Dictionary>();
|
||||
|
||||
persistentItem->Set("type", GetType());
|
||||
persistentItem->Set("name", GetName());
|
||||
persistentItem->Set("properties", attrs);
|
||||
persistentItem->Set("debug_hints", debugHints.ToDictionary());
|
||||
|
||||
ConfigCompilerContext::GetInstance()->WriteObject(persistentItem);
|
||||
|
||||
ConfigType::Ptr ctype = ConfigType::GetByName(GetType());
|
||||
|
||||
if (!ctype)
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(false, "No validation type found for object '" + GetName() + "' of type '" + GetType() + "'");
|
||||
else {
|
||||
TypeRuleUtilities utils;
|
||||
|
||||
try {
|
||||
attrs->Remove("name");
|
||||
ctype->ValidateItem(GetName(), attrs, GetDebugInfo(), &utils);
|
||||
} catch (const ConfigError& ex) {
|
||||
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
|
||||
} catch (const std::exception& ex) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
|
||||
}
|
||||
}
|
||||
|
||||
dobj->Register();
|
||||
|
||||
m_Object = dobj;
|
||||
|
@ -207,20 +231,11 @@ void ConfigItem::Register(void)
|
|||
{
|
||||
String name = m_Name;
|
||||
|
||||
/* If this is a non-abstract object we need to figure out
|
||||
* its real name now - or assign it a temporary name. */
|
||||
if (!m_Abstract) {
|
||||
shared_ptr<NameComposer> nc = dynamic_pointer_cast<NameComposer>(Type::GetByName(m_Type));
|
||||
|
||||
if (nc) {
|
||||
name = nc->MakeName(m_Name, Dictionary::Ptr());
|
||||
|
||||
ASSERT(name.IsEmpty() || name == m_Name);
|
||||
|
||||
if (name.IsEmpty())
|
||||
name = Utility::NewUniqueID();
|
||||
}
|
||||
}
|
||||
/* If this is a non-abstract object with a composite name we don't register it. */
|
||||
if (!m_Abstract && nc)
|
||||
return;
|
||||
|
||||
std::pair<String, String> key = std::make_pair(m_Type, name);
|
||||
ConfigItem::Ptr self = GetSelf();
|
||||
|
@ -254,104 +269,17 @@ ConfigItem::Ptr ConfigItem::GetObject(const String& type, const String& name)
|
|||
return ConfigItem::Ptr();
|
||||
}
|
||||
|
||||
void ConfigItem::ValidateItem(void)
|
||||
{
|
||||
if (m_Validated || IsAbstract())
|
||||
return;
|
||||
|
||||
ConfigType::Ptr ctype = ConfigType::GetByName(GetType());
|
||||
|
||||
if (!ctype) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(false, "No validation type found for object '" + GetName() + "' of type '" + GetType() + "'");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
TypeRuleUtilities utils;
|
||||
|
||||
try {
|
||||
ctype->ValidateItem(GetName(), GetProperties(), GetDebugInfo(), &utils);
|
||||
} catch (const ConfigError& ex) {
|
||||
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
|
||||
} catch (const std::exception& ex) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
|
||||
}
|
||||
|
||||
m_Validated = true;
|
||||
}
|
||||
|
||||
void ConfigItem::WriteObjectsFile(const String& filename)
|
||||
{
|
||||
Log(LogInformation, "ConfigItem")
|
||||
<< "Dumping config items to file '" << filename << "'";
|
||||
|
||||
String tempFilename = filename + ".tmp";
|
||||
|
||||
std::fstream fp;
|
||||
fp.open(tempFilename.CStr(), std::ios_base::out);
|
||||
|
||||
if (!fp)
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Could not open '" + tempFilename + "' file"));
|
||||
|
||||
StdioStream::Ptr sfp = make_shared<StdioStream>(&fp, false);
|
||||
|
||||
BOOST_FOREACH(const ItemMap::value_type& kv, m_Items) {
|
||||
ConfigItem::Ptr item = kv.second;
|
||||
|
||||
if (item->IsAbstract())
|
||||
continue;
|
||||
|
||||
Dictionary::Ptr persistentItem = make_shared<Dictionary>();
|
||||
|
||||
persistentItem->Set("type", item->GetType());
|
||||
persistentItem->Set("name", item->GetName());
|
||||
persistentItem->Set("properties", item->GetProperties());
|
||||
persistentItem->Set("debug_hints", item->GetDebugHints().ToDictionary());
|
||||
|
||||
String json = JsonEncode(persistentItem);
|
||||
|
||||
NetString::WriteStringToStream(sfp, json);
|
||||
}
|
||||
|
||||
sfp->Close();
|
||||
|
||||
fp.close();
|
||||
|
||||
#ifdef _WIN32
|
||||
_unlink(filename.CStr());
|
||||
#endif /* _WIN32 */
|
||||
|
||||
if (rename(tempFilename.CStr(), filename.CStr()) < 0) {
|
||||
BOOST_THROW_EXCEPTION(posix_error()
|
||||
<< boost::errinfo_api_function("rename")
|
||||
<< boost::errinfo_errno(errno)
|
||||
<< boost::errinfo_file_name(tempFilename));
|
||||
}
|
||||
}
|
||||
|
||||
bool ConfigItem::ValidateItems(const String& objectsFile)
|
||||
bool ConfigItem::ValidateItems(void)
|
||||
{
|
||||
if (ConfigCompilerContext::GetInstance()->HasErrors())
|
||||
return false;
|
||||
|
||||
ParallelWorkQueue upq;
|
||||
|
||||
Log(LogInformation, "ConfigItem", "Validating config items (step 1)...");
|
||||
|
||||
BOOST_FOREACH(const ItemMap::value_type& kv, m_Items) {
|
||||
upq.Enqueue(boost::bind(&ConfigItem::ValidateItem, kv.second));
|
||||
}
|
||||
|
||||
upq.Join();
|
||||
|
||||
if (ConfigCompilerContext::GetInstance()->HasErrors())
|
||||
return false;
|
||||
|
||||
Log(LogInformation, "ConfigItem", "Committing config items");
|
||||
|
||||
BOOST_FOREACH(const ItemMap::value_type& kv, m_Items) {
|
||||
upq.Enqueue(boost::bind(&ConfigItem::Commit, kv.second));
|
||||
upq.Enqueue(boost::bind(&ConfigItem::Commit, kv.second, false));
|
||||
}
|
||||
|
||||
upq.Join();
|
||||
|
@ -381,17 +309,8 @@ bool ConfigItem::ValidateItems(const String& objectsFile)
|
|||
Log(LogInformation, "ConfigItem", "Evaluating 'object' rules (step 2)...");
|
||||
ObjectRule::EvaluateRules(true);
|
||||
|
||||
Log(LogInformation, "ConfigItem", "Validating config items (step 2)...");
|
||||
|
||||
BOOST_FOREACH(const ItemMap::value_type& kv, m_Items) {
|
||||
upq.Enqueue(boost::bind(&ConfigItem::ValidateItem, kv.second));
|
||||
}
|
||||
|
||||
upq.Join();
|
||||
|
||||
if (!objectsFile.IsEmpty())
|
||||
ConfigItem::WriteObjectsFile(objectsFile);
|
||||
|
||||
ConfigItem::DiscardItems();
|
||||
ConfigType::DiscardTypes();
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
|
||||
ConfigItem(const String& type, const String& name, bool abstract,
|
||||
const Expression::Ptr& exprl, const DebugInfo& debuginfo,
|
||||
const Dictionary::Ptr& scope, const String& zone);
|
||||
const Object::Ptr& scope, const String& zone);
|
||||
|
||||
String GetType(void) const;
|
||||
String GetName(void) const;
|
||||
|
@ -48,42 +48,33 @@ public:
|
|||
std::vector<ConfigItem::Ptr> GetParents(void) const;
|
||||
|
||||
Expression::Ptr GetExpressionList(void) const;
|
||||
Dictionary::Ptr GetProperties(void);
|
||||
const DebugHint& GetDebugHints(void) const;
|
||||
|
||||
DynamicObject::Ptr Commit(void);
|
||||
DynamicObject::Ptr Commit(bool discard = true);
|
||||
void Register(void);
|
||||
|
||||
DebugInfo GetDebugInfo(void) const;
|
||||
|
||||
Dictionary::Ptr GetScope(void) const;
|
||||
Object::Ptr GetScope(void) const;
|
||||
|
||||
String GetZone(void) const;
|
||||
|
||||
static ConfigItem::Ptr GetObject(const String& type,
|
||||
const String& name);
|
||||
|
||||
void ValidateItem(void);
|
||||
|
||||
static bool ValidateItems(const String& objectsFile = String());
|
||||
static bool ValidateItems(void);
|
||||
static bool ActivateItems(void);
|
||||
static void DiscardItems(void);
|
||||
|
||||
static void WriteObjectsFile(const String& filename);
|
||||
|
||||
private:
|
||||
String m_Type; /**< The object type. */
|
||||
String m_Name; /**< The name. */
|
||||
bool m_Abstract; /**< Whether this is a template. */
|
||||
bool m_Validated; /** Whether this object has been validated. */
|
||||
|
||||
Expression::Ptr m_ExpressionList;
|
||||
Dictionary::Ptr m_Properties;
|
||||
DebugHint m_DebugHints;
|
||||
std::vector<String> m_ParentNames; /**< The names of parent configuration
|
||||
items. */
|
||||
DebugInfo m_DebugInfo; /**< Debug information. */
|
||||
Dictionary::Ptr m_Scope; /**< variable scope. */
|
||||
Object::Ptr m_Scope; /**< variable scope. */
|
||||
String m_Zone; /**< The zone. */
|
||||
|
||||
DynamicObject::Ptr m_Object;
|
||||
|
|
|
@ -54,7 +54,7 @@ void ConfigItemBuilder::SetAbstract(bool abstract)
|
|||
m_Abstract = abstract;
|
||||
}
|
||||
|
||||
void ConfigItemBuilder::SetScope(const Dictionary::Ptr& scope)
|
||||
void ConfigItemBuilder::SetScope(const Object::Ptr& scope)
|
||||
{
|
||||
m_Scope = scope;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
void SetType(const String& type);
|
||||
void SetName(const String& name);
|
||||
void SetAbstract(bool abstract);
|
||||
void SetScope(const Dictionary::Ptr& scope);
|
||||
void SetScope(const Object::Ptr& scope);
|
||||
void SetZone(const String& zone);
|
||||
|
||||
void AddExpression(const Expression::Ptr& expr);
|
||||
|
@ -58,7 +58,7 @@ private:
|
|||
bool m_Abstract; /**< Whether the item is abstract. */
|
||||
Array::Ptr m_Expressions; /**< Expressions for this item. */
|
||||
DebugInfo m_DebugInfo; /**< Debug information. */
|
||||
Dictionary::Ptr m_Scope; /**< variable scope. */
|
||||
Object::Ptr m_Scope; /**< variable scope. */
|
||||
String m_Zone; /**< The zone. */
|
||||
};
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "base/configerror.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/exception_ptr.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/exception/errinfo_nested_exception.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
@ -45,7 +46,7 @@ Expression::Expression(OpCallback op, const Value& operand1, const Value& operan
|
|||
: m_Operator(op), m_Operand1(operand1), m_Operand2(operand2), m_DebugInfo(di)
|
||||
{ }
|
||||
|
||||
Value Expression::Evaluate(const Dictionary::Ptr& locals, DebugHint *dhint) const
|
||||
Value Expression::Evaluate(const Object::Ptr& context, DebugHint *dhint) const
|
||||
{
|
||||
try {
|
||||
#ifdef _DEBUG
|
||||
|
@ -57,7 +58,7 @@ Value Expression::Evaluate(const Dictionary::Ptr& locals, DebugHint *dhint) cons
|
|||
}
|
||||
#endif /* _DEBUG */
|
||||
|
||||
return m_Operator(this, locals, dhint);
|
||||
return m_Operator(this, context, dhint);
|
||||
} catch (const std::exception& ex) {
|
||||
if (boost::get_error_info<boost::errinfo_nested_exception>(ex))
|
||||
throw;
|
||||
|
@ -99,125 +100,125 @@ void Expression::Dump(std::ostream& stream, int indent) const
|
|||
DumpOperand(stream, m_Operand2, indent + 1);
|
||||
}
|
||||
|
||||
Value Expression::EvaluateOperand1(const Dictionary::Ptr& locals, DebugHint *dhint) const
|
||||
Value Expression::EvaluateOperand1(const Object::Ptr& context, DebugHint *dhint) const
|
||||
{
|
||||
return static_cast<Expression::Ptr>(m_Operand1)->Evaluate(locals, dhint);
|
||||
return static_cast<Expression::Ptr>(m_Operand1)->Evaluate(context, dhint);
|
||||
}
|
||||
|
||||
Value Expression::EvaluateOperand2(const Dictionary::Ptr& locals, DebugHint *dhint) const
|
||||
Value Expression::EvaluateOperand2(const Object::Ptr& context, DebugHint *dhint) const
|
||||
{
|
||||
return static_cast<Expression::Ptr>(m_Operand2)->Evaluate(locals, dhint);
|
||||
return static_cast<Expression::Ptr>(m_Operand2)->Evaluate(context, dhint);
|
||||
}
|
||||
|
||||
Value Expression::OpLiteral(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpLiteral(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
return expr->m_Operand1;
|
||||
}
|
||||
|
||||
Value Expression::OpVariable(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpVariable(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
Dictionary::Ptr scope = locals;
|
||||
Object::Ptr scope = context;
|
||||
|
||||
while (scope) {
|
||||
if (scope->Contains(expr->m_Operand1))
|
||||
return scope->Get(expr->m_Operand1);
|
||||
if (HasField(scope, expr->m_Operand1))
|
||||
return GetField(scope, expr->m_Operand1);
|
||||
|
||||
scope = scope->Get("__parent");
|
||||
scope = GetField(scope, "__parent");
|
||||
}
|
||||
|
||||
return ScriptVariable::Get(expr->m_Operand1);
|
||||
}
|
||||
|
||||
Value Expression::OpNegate(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpNegate(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
return ~(long)expr->EvaluateOperand1(locals);
|
||||
return ~(long)expr->EvaluateOperand1(context);
|
||||
}
|
||||
|
||||
Value Expression::OpLogicalNegate(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpLogicalNegate(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
return !expr->EvaluateOperand1(locals).ToBool();
|
||||
return !expr->EvaluateOperand1(context).ToBool();
|
||||
}
|
||||
|
||||
Value Expression::OpAdd(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpAdd(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
return expr->EvaluateOperand1(locals) + expr->EvaluateOperand2(locals);
|
||||
return expr->EvaluateOperand1(context) + expr->EvaluateOperand2(context);
|
||||
}
|
||||
|
||||
Value Expression::OpSubtract(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpSubtract(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
return expr->EvaluateOperand1(locals) - expr->EvaluateOperand2(locals);
|
||||
return expr->EvaluateOperand1(context) - expr->EvaluateOperand2(context);
|
||||
}
|
||||
|
||||
Value Expression::OpMultiply(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpMultiply(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
return expr->EvaluateOperand1(locals) * expr->EvaluateOperand2(locals);
|
||||
return expr->EvaluateOperand1(context) * expr->EvaluateOperand2(context);
|
||||
}
|
||||
|
||||
Value Expression::OpDivide(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpDivide(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
return expr->EvaluateOperand1(locals) / expr->EvaluateOperand2(locals);
|
||||
return expr->EvaluateOperand1(context) / expr->EvaluateOperand2(context);
|
||||
}
|
||||
|
||||
Value Expression::OpBinaryAnd(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpBinaryAnd(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
return expr->EvaluateOperand1(locals) & expr->EvaluateOperand2(locals);
|
||||
return expr->EvaluateOperand1(context) & expr->EvaluateOperand2(context);
|
||||
}
|
||||
|
||||
Value Expression::OpBinaryOr(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpBinaryOr(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
return expr->EvaluateOperand1(locals) | expr->EvaluateOperand2(locals);
|
||||
return expr->EvaluateOperand1(context) | expr->EvaluateOperand2(context);
|
||||
}
|
||||
|
||||
Value Expression::OpShiftLeft(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpShiftLeft(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
return expr->EvaluateOperand1(locals) << expr->EvaluateOperand2(locals);
|
||||
return expr->EvaluateOperand1(context) << expr->EvaluateOperand2(context);
|
||||
}
|
||||
|
||||
Value Expression::OpShiftRight(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpShiftRight(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
return expr->EvaluateOperand1(locals) >> expr->EvaluateOperand2(locals);
|
||||
return expr->EvaluateOperand1(context) >> expr->EvaluateOperand2(context);
|
||||
}
|
||||
|
||||
Value Expression::OpEqual(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
return expr->EvaluateOperand1(locals) == expr->EvaluateOperand2(locals);
|
||||
return expr->EvaluateOperand1(context) == expr->EvaluateOperand2(context);
|
||||
}
|
||||
|
||||
Value Expression::OpNotEqual(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpNotEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
return expr->EvaluateOperand1(locals) != expr->EvaluateOperand2(locals);
|
||||
return expr->EvaluateOperand1(context) != expr->EvaluateOperand2(context);
|
||||
}
|
||||
|
||||
Value Expression::OpLessThan(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpLessThan(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
return expr->EvaluateOperand1(locals) < expr->EvaluateOperand2(locals);
|
||||
return expr->EvaluateOperand1(context) < expr->EvaluateOperand2(context);
|
||||
}
|
||||
|
||||
Value Expression::OpGreaterThan(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpGreaterThan(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
return expr->EvaluateOperand1(locals) > expr->EvaluateOperand2(locals);
|
||||
return expr->EvaluateOperand1(context) > expr->EvaluateOperand2(context);
|
||||
}
|
||||
|
||||
Value Expression::OpLessThanOrEqual(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpLessThanOrEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
return expr->EvaluateOperand1(locals) <= expr->EvaluateOperand2(locals);
|
||||
return expr->EvaluateOperand1(context) <= expr->EvaluateOperand2(context);
|
||||
}
|
||||
|
||||
Value Expression::OpGreaterThanOrEqual(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpGreaterThanOrEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
return expr->EvaluateOperand1(locals) >= expr->EvaluateOperand2(locals);
|
||||
return expr->EvaluateOperand1(context) >= expr->EvaluateOperand2(context);
|
||||
}
|
||||
|
||||
Value Expression::OpIn(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpIn(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
Value right = expr->EvaluateOperand2(locals);
|
||||
Value right = expr->EvaluateOperand2(context);
|
||||
|
||||
if (right.IsEmpty())
|
||||
return false;
|
||||
else if (!right.IsObjectType<Array>())
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Invalid right side argument for 'in' operator: " + JsonEncode(right)));
|
||||
|
||||
Value left = expr->EvaluateOperand1(locals);
|
||||
Value left = expr->EvaluateOperand1(context);
|
||||
|
||||
Array::Ptr arr = right;
|
||||
bool found = false;
|
||||
|
@ -232,24 +233,24 @@ Value Expression::OpIn(const Expression *expr, const Dictionary::Ptr& locals, De
|
|||
return found;
|
||||
}
|
||||
|
||||
Value Expression::OpNotIn(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpNotIn(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
return !OpIn(expr, locals, dhint);
|
||||
return !OpIn(expr, context, dhint);
|
||||
}
|
||||
|
||||
Value Expression::OpLogicalAnd(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpLogicalAnd(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
return expr->EvaluateOperand1(locals).ToBool() && expr->EvaluateOperand2(locals).ToBool();
|
||||
return expr->EvaluateOperand1(context).ToBool() && expr->EvaluateOperand2(context).ToBool();
|
||||
}
|
||||
|
||||
Value Expression::OpLogicalOr(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpLogicalOr(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
return expr->EvaluateOperand1(locals).ToBool() || expr->EvaluateOperand2(locals).ToBool();
|
||||
return expr->EvaluateOperand1(context).ToBool() || expr->EvaluateOperand2(context).ToBool();
|
||||
}
|
||||
|
||||
Value Expression::OpFunctionCall(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpFunctionCall(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
Value funcName = expr->EvaluateOperand1(locals);
|
||||
Value funcName = expr->EvaluateOperand1(context);
|
||||
|
||||
ScriptFunction::Ptr func;
|
||||
|
||||
|
@ -261,17 +262,17 @@ Value Expression::OpFunctionCall(const Expression *expr, const Dictionary::Ptr&
|
|||
if (!func)
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Function '" + funcName + "' does not exist."));
|
||||
|
||||
Array::Ptr arr = expr->EvaluateOperand2(locals);
|
||||
Array::Ptr arr = expr->EvaluateOperand2(context);
|
||||
std::vector<Value> arguments;
|
||||
for (Array::SizeType index = 0; index < arr->GetLength(); index++) {
|
||||
const Expression::Ptr& aexpr = arr->Get(index);
|
||||
arguments.push_back(aexpr->Evaluate(locals));
|
||||
arguments.push_back(aexpr->Evaluate(context));
|
||||
}
|
||||
|
||||
return func->Invoke(arguments);
|
||||
}
|
||||
|
||||
Value Expression::OpArray(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpArray(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
Array::Ptr arr = expr->m_Operand1;
|
||||
Array::Ptr result = make_shared<Array>();
|
||||
|
@ -279,28 +280,28 @@ Value Expression::OpArray(const Expression *expr, const Dictionary::Ptr& locals,
|
|||
if (arr) {
|
||||
for (Array::SizeType index = 0; index < arr->GetLength(); index++) {
|
||||
const Expression::Ptr& aexpr = arr->Get(index);
|
||||
result->Add(aexpr->Evaluate(locals));
|
||||
result->Add(aexpr->Evaluate(context));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Value Expression::OpDict(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpDict(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
Array::Ptr arr = expr->m_Operand1;
|
||||
bool in_place = expr->m_Operand2;
|
||||
Dictionary::Ptr result = make_shared<Dictionary>();
|
||||
|
||||
result->Set("__parent", locals);
|
||||
result->Set("__parent", context);
|
||||
|
||||
if (arr) {
|
||||
for (Array::SizeType index = 0; index < arr->GetLength(); index++) {
|
||||
const Expression::Ptr& aexpr = arr->Get(index);
|
||||
Dictionary::Ptr alocals = in_place ? locals : result;
|
||||
aexpr->Evaluate(alocals, dhint);
|
||||
Object::Ptr acontext = in_place ? context : result;
|
||||
aexpr->Evaluate(acontext, dhint);
|
||||
|
||||
if (alocals->Contains("__result"))
|
||||
if (HasField(acontext, "__result"))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -310,7 +311,7 @@ Value Expression::OpDict(const Expression *expr, const Dictionary::Ptr& locals,
|
|||
return xresult;
|
||||
}
|
||||
|
||||
Value Expression::OpSet(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpSet(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
Array::Ptr left = expr->m_Operand1;
|
||||
Array::Ptr indexer = left->Get(0);
|
||||
|
@ -323,14 +324,14 @@ Value Expression::OpSet(const Expression *expr, const Dictionary::Ptr& locals, D
|
|||
|
||||
for (Array::SizeType i = 0; i < indexer->GetLength(); i++) {
|
||||
Expression::Ptr indexExpr = indexer->Get(i);
|
||||
String tempindex = indexExpr->Evaluate(locals, dhint);
|
||||
String tempindex = indexExpr->Evaluate(context, dhint);
|
||||
|
||||
if (i == indexer->GetLength() - 1)
|
||||
index = tempindex;
|
||||
|
||||
if (i == 0) {
|
||||
parent = locals;
|
||||
object = locals->Get(tempindex);
|
||||
parent = context;
|
||||
object = GetField(context, tempindex);
|
||||
} else {
|
||||
parent = object;
|
||||
|
||||
|
@ -338,7 +339,7 @@ Value Expression::OpSet(const Expression *expr, const Dictionary::Ptr& locals, D
|
|||
Expression::Ptr eindex = make_shared<Expression>(&Expression::OpLiteral, tempindex, expr->m_DebugInfo);
|
||||
|
||||
Expression::Ptr eip = make_shared<Expression>(&Expression::OpIndexer, eparent, eindex, expr->m_DebugInfo);
|
||||
object = eip->Evaluate(locals, dhint);
|
||||
object = eip->Evaluate(context, dhint);
|
||||
}
|
||||
|
||||
if (sdhint)
|
||||
|
@ -347,12 +348,11 @@ Value Expression::OpSet(const Expression *expr, const Dictionary::Ptr& locals, D
|
|||
if (i != indexer->GetLength() - 1 && object.IsEmpty()) {
|
||||
object = make_shared<Dictionary>();
|
||||
|
||||
Dictionary::Ptr pdict = parent;
|
||||
pdict->Set(tempindex, object);
|
||||
SetField(parent, tempindex, object);
|
||||
}
|
||||
}
|
||||
|
||||
Value right = expr->EvaluateOperand2(locals, dhint);
|
||||
Value right = expr->EvaluateOperand2(context, dhint);
|
||||
|
||||
if (csop != OpSetLiteral) {
|
||||
Expression::OpCallback op;
|
||||
|
@ -379,11 +379,10 @@ Value Expression::OpSet(const Expression *expr, const Dictionary::Ptr& locals, D
|
|||
make_shared<Expression>(&Expression::OpLiteral, right, expr->m_DebugInfo),
|
||||
expr->m_DebugInfo);
|
||||
|
||||
right = ecp->Evaluate(locals, dhint);
|
||||
right = ecp->Evaluate(context, dhint);
|
||||
}
|
||||
|
||||
Dictionary::Ptr pdict = parent;
|
||||
pdict->Set(index, right);
|
||||
SetField(parent, index, right);
|
||||
|
||||
if (sdhint)
|
||||
sdhint->AddMessage("=", expr->m_DebugInfo);
|
||||
|
@ -391,10 +390,10 @@ Value Expression::OpSet(const Expression *expr, const Dictionary::Ptr& locals, D
|
|||
return right;
|
||||
}
|
||||
|
||||
Value Expression::OpIndexer(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpIndexer(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
Value value = expr->EvaluateOperand1(locals);
|
||||
Value index = expr->EvaluateOperand2(locals);
|
||||
Value value = expr->EvaluateOperand1(context);
|
||||
Value index = expr->EvaluateOperand2(context);
|
||||
|
||||
if (value.IsObjectType<Dictionary>()) {
|
||||
Dictionary::Ptr dict = value;
|
||||
|
@ -422,44 +421,44 @@ Value Expression::OpIndexer(const Expression *expr, const Dictionary::Ptr& local
|
|||
}
|
||||
}
|
||||
|
||||
Value Expression::OpImport(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpImport(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
Value type = expr->EvaluateOperand1(locals);
|
||||
Value name = expr->EvaluateOperand2(locals);
|
||||
Value type = expr->EvaluateOperand1(context);
|
||||
Value name = expr->EvaluateOperand2(context);
|
||||
|
||||
ConfigItem::Ptr item = ConfigItem::GetObject(type, name);
|
||||
|
||||
if (!item)
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Import references unknown template: '" + name + "'"));
|
||||
|
||||
item->GetExpressionList()->Evaluate(locals, dhint);
|
||||
item->GetExpressionList()->Evaluate(context, dhint);
|
||||
|
||||
return Empty;
|
||||
}
|
||||
|
||||
Value Expression::FunctionWrapper(const std::vector<Value>& arguments, const Array::Ptr& funcargs, const Expression::Ptr& expr, const Dictionary::Ptr& scope)
|
||||
Value Expression::FunctionWrapper(const std::vector<Value>& arguments, const Array::Ptr& funcargs, const Expression::Ptr& expr, const Object::Ptr& scope)
|
||||
{
|
||||
if (arguments.size() < funcargs->GetLength())
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Too few arguments for function"));
|
||||
|
||||
Dictionary::Ptr locals = make_shared<Dictionary>();
|
||||
locals->Set("__parent", scope);
|
||||
Dictionary::Ptr context = make_shared<Dictionary>();
|
||||
context->Set("__parent", scope);
|
||||
|
||||
for (std::vector<Value>::size_type i = 0; i < std::min(arguments.size(), funcargs->GetLength()); i++)
|
||||
locals->Set(funcargs->Get(i), arguments[i]);
|
||||
context->Set(funcargs->Get(i), arguments[i]);
|
||||
|
||||
expr->Evaluate(locals);
|
||||
return locals->Get("__result");
|
||||
expr->Evaluate(context);
|
||||
return context->Get("__result");
|
||||
}
|
||||
|
||||
Value Expression::OpFunction(const Expression* expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpFunction(const Expression* expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
Array::Ptr left = expr->m_Operand1;
|
||||
Expression::Ptr aexpr = left->Get(1);
|
||||
String name = left->Get(0);
|
||||
|
||||
Array::Ptr funcargs = expr->m_Operand2;
|
||||
ScriptFunction::Ptr func = make_shared<ScriptFunction>(boost::bind(&Expression::FunctionWrapper, _1, funcargs, aexpr, locals));
|
||||
ScriptFunction::Ptr func = make_shared<ScriptFunction>(boost::bind(&Expression::FunctionWrapper, _1, funcargs, aexpr, context));
|
||||
|
||||
if (!name.IsEmpty())
|
||||
ScriptFunction::Register(name, func);
|
||||
|
@ -467,7 +466,7 @@ Value Expression::OpFunction(const Expression* expr, const Dictionary::Ptr& loca
|
|||
return func;
|
||||
}
|
||||
|
||||
Value Expression::OpApply(const Expression* expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpApply(const Expression* expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
Array::Ptr left = expr->m_Operand1;
|
||||
Expression::Ptr exprl = expr->m_Operand2;
|
||||
|
@ -479,14 +478,14 @@ Value Expression::OpApply(const Expression* expr, const Dictionary::Ptr& locals,
|
|||
String fvvar = left->Get(5);
|
||||
Expression::Ptr fterm = left->Get(6);
|
||||
|
||||
String name = aname->Evaluate(locals, dhint);
|
||||
String name = aname->Evaluate(context, dhint);
|
||||
|
||||
ApplyRule::AddRule(type, target, name, exprl, filter, fkvar, fvvar, fterm, expr->m_DebugInfo, locals);
|
||||
ApplyRule::AddRule(type, target, name, exprl, filter, fkvar, fvvar, fterm, expr->m_DebugInfo, context);
|
||||
|
||||
return Empty;
|
||||
}
|
||||
|
||||
Value Expression::OpObject(const Expression* expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpObject(const Expression* expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
Array::Ptr left = expr->m_Operand1;
|
||||
Expression::Ptr exprl = expr->m_Operand2;
|
||||
|
@ -496,7 +495,7 @@ Value Expression::OpObject(const Expression* expr, const Dictionary::Ptr& locals
|
|||
Expression::Ptr filter = left->Get(3);
|
||||
String zone = left->Get(4);
|
||||
|
||||
String name = aname->Evaluate(locals, dhint);
|
||||
String name = aname->Evaluate(context, dhint);
|
||||
|
||||
ConfigItemBuilder::Ptr item = make_shared<ConfigItemBuilder>(expr->m_DebugInfo);
|
||||
|
||||
|
@ -531,16 +530,16 @@ Value Expression::OpObject(const Expression* expr, const Dictionary::Ptr& locals
|
|||
|
||||
item->AddExpression(exprl);
|
||||
item->SetAbstract(abstract);
|
||||
item->SetScope(locals);
|
||||
item->SetScope(context);
|
||||
item->SetZone(zone);
|
||||
item->Compile()->Register();
|
||||
|
||||
ObjectRule::AddRule(type, name, exprl, filter, expr->m_DebugInfo, locals);
|
||||
ObjectRule::AddRule(type, name, exprl, filter, expr->m_DebugInfo, context);
|
||||
|
||||
return Empty;
|
||||
}
|
||||
|
||||
Value Expression::OpFor(const Expression* expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
Value Expression::OpFor(const Expression* expr, const Object::Ptr& context, DebugHint *dhint)
|
||||
{
|
||||
Array::Ptr left = expr->m_Operand1;
|
||||
String kvar = left->Get(0);
|
||||
|
@ -548,7 +547,7 @@ Value Expression::OpFor(const Expression* expr, const Dictionary::Ptr& locals, D
|
|||
Expression::Ptr aexpr = left->Get(2);
|
||||
Expression::Ptr ascope = expr->m_Operand2;
|
||||
|
||||
Value value = aexpr->Evaluate(locals, dhint);
|
||||
Value value = aexpr->Evaluate(context, dhint);
|
||||
|
||||
if (value.IsObjectType<Array>()) {
|
||||
if (!vvar.IsEmpty())
|
||||
|
@ -558,11 +557,11 @@ Value Expression::OpFor(const Expression* expr, const Dictionary::Ptr& locals, D
|
|||
|
||||
ObjectLock olock(arr);
|
||||
BOOST_FOREACH(const Value& value, arr) {
|
||||
Dictionary::Ptr xlocals = make_shared<Dictionary>();
|
||||
xlocals->Set("__parent", locals);
|
||||
xlocals->Set(kvar, value);
|
||||
Dictionary::Ptr xcontext = make_shared<Dictionary>();
|
||||
xcontext->Set("__parent", context);
|
||||
xcontext->Set(kvar, value);
|
||||
|
||||
ascope->Evaluate(xlocals, dhint);
|
||||
ascope->Evaluate(xcontext, dhint);
|
||||
}
|
||||
} else if (value.IsObjectType<Dictionary>()) {
|
||||
if (vvar.IsEmpty())
|
||||
|
@ -572,12 +571,12 @@ Value Expression::OpFor(const Expression* expr, const Dictionary::Ptr& locals, D
|
|||
|
||||
ObjectLock olock(dict);
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, dict) {
|
||||
Dictionary::Ptr xlocals = make_shared<Dictionary>();
|
||||
xlocals->Set("__parent", locals);
|
||||
xlocals->Set(kvar, kv.first);
|
||||
xlocals->Set(vvar, kv.second);
|
||||
Dictionary::Ptr xcontext = make_shared<Dictionary>();
|
||||
xcontext->Set("__parent", context);
|
||||
xcontext->Set(kvar, kv.first);
|
||||
xcontext->Set(vvar, kv.second);
|
||||
|
||||
ascope->Evaluate(xlocals, dhint);
|
||||
ascope->Evaluate(xcontext, dhint);
|
||||
}
|
||||
} else
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Invalid type in __for expression: " + value.GetTypeName()) << errinfo_debuginfo(expr->m_DebugInfo));
|
||||
|
@ -620,3 +619,68 @@ Expression::Ptr icinga::MakeLiteral(const Value& lit)
|
|||
{
|
||||
return make_shared<Expression>(&Expression::OpLiteral, lit, DebugInfo());
|
||||
}
|
||||
|
||||
bool Expression::HasField(const Object::Ptr& context, const String& field)
|
||||
{
|
||||
Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(context);
|
||||
|
||||
if (dict)
|
||||
return dict->Contains(field);
|
||||
else {
|
||||
Type::Ptr type = context->GetReflectionType();
|
||||
|
||||
if (!type)
|
||||
return false;
|
||||
|
||||
return type->GetFieldId(field) != -1;
|
||||
}
|
||||
}
|
||||
|
||||
Value Expression::GetField(const Object::Ptr& context, const String& field)
|
||||
{
|
||||
Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(context);
|
||||
|
||||
if (dict)
|
||||
return dict->Get(field);
|
||||
else {
|
||||
Type::Ptr type = context->GetReflectionType();
|
||||
|
||||
if (!type)
|
||||
return Empty;
|
||||
|
||||
int fid = type->GetFieldId(field);
|
||||
|
||||
if (fid == -1)
|
||||
return Empty;
|
||||
|
||||
return context->GetField(fid);
|
||||
}
|
||||
}
|
||||
|
||||
void Expression::SetField(const Object::Ptr& context, const String& field, const Value& value)
|
||||
{
|
||||
Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(context);
|
||||
|
||||
if (dict)
|
||||
dict->Set(field, value);
|
||||
else {
|
||||
Type::Ptr type = context->GetReflectionType();
|
||||
|
||||
if (!type)
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Cannot set field on object."));
|
||||
|
||||
int fid = type->GetFieldId(field);
|
||||
|
||||
if (fid == -1)
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Attribute '" + field + "' does not exist."));
|
||||
|
||||
try {
|
||||
context->SetField(fid, value);
|
||||
} catch (const boost::bad_lexical_cast&) {
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Attribute '" + field + "' cannot be set to value of type '" + value.GetTypeName() + "'"));
|
||||
} catch (const std::bad_cast&) {
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Attribute '" + field + "' cannot be set to value of type '" + value.GetTypeName() + "'"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,49 +63,49 @@ class I2_CONFIG_API Expression : public Object
|
|||
public:
|
||||
DECLARE_PTR_TYPEDEFS(Expression);
|
||||
|
||||
typedef Value (*OpCallback)(const Expression *, const Dictionary::Ptr&, DebugHint *dhint);
|
||||
typedef Value (*OpCallback)(const Expression *, const Object::Ptr&, DebugHint *dhint);
|
||||
|
||||
Expression(OpCallback op, const Value& operand1, const DebugInfo& di);
|
||||
Expression(OpCallback op, const Value& operand1, const Value& operand2, const DebugInfo& di);
|
||||
|
||||
Value Evaluate(const Dictionary::Ptr& locals, DebugHint *dhint = NULL) const;
|
||||
Value Evaluate(const Object::Ptr& context, DebugHint *dhint = NULL) const;
|
||||
|
||||
void MakeInline(void);
|
||||
|
||||
void Dump(std::ostream& stream, int indent = 0) const;
|
||||
|
||||
static Value OpLiteral(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpVariable(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpNegate(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpLogicalNegate(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpAdd(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpSubtract(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpMultiply(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpDivide(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpBinaryAnd(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpBinaryOr(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpShiftLeft(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpShiftRight(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpEqual(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpNotEqual(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpLessThan(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpGreaterThan(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpLessThanOrEqual(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpGreaterThanOrEqual(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpIn(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpNotIn(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpLogicalAnd(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpLogicalOr(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpFunctionCall(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpArray(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpDict(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpSet(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpIndexer(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpImport(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpFunction(const Expression* expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpApply(const Expression* expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpObject(const Expression* expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpFor(const Expression* expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
||||
static Value OpLiteral(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpVariable(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpNegate(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpLogicalNegate(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpAdd(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpSubtract(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpMultiply(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpDivide(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpBinaryAnd(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpBinaryOr(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpShiftLeft(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpShiftRight(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpNotEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpLessThan(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpGreaterThan(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpLessThanOrEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpGreaterThanOrEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpIn(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpNotIn(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpLogicalAnd(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpLogicalOr(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpFunctionCall(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpArray(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpDict(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpSet(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpIndexer(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpImport(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpFunction(const Expression* expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpApply(const Expression* expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpObject(const Expression* expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
static Value OpFor(const Expression* expr, const Object::Ptr& context, DebugHint *dhint);
|
||||
|
||||
private:
|
||||
OpCallback m_Operator;
|
||||
|
@ -113,13 +113,17 @@ private:
|
|||
Value m_Operand2;
|
||||
DebugInfo m_DebugInfo;
|
||||
|
||||
Value EvaluateOperand1(const Dictionary::Ptr& locals, DebugHint *dhint = NULL) const;
|
||||
Value EvaluateOperand2(const Dictionary::Ptr& locals, DebugHint *dhint = NULL) const;
|
||||
Value EvaluateOperand1(const Object::Ptr& context, DebugHint *dhint = NULL) const;
|
||||
Value EvaluateOperand2(const Object::Ptr& context, DebugHint *dhint = NULL) const;
|
||||
|
||||
static void DumpOperand(std::ostream& stream, const Value& operand, int indent);
|
||||
|
||||
static Value FunctionWrapper(const std::vector<Value>& arguments, const Array::Ptr& funcargs,
|
||||
const Expression::Ptr& expr, const Dictionary::Ptr& scope);
|
||||
const Expression::Ptr& expr, const Object::Ptr& scope);
|
||||
|
||||
static bool HasField(const Object::Ptr& context, const String& field);
|
||||
static Value GetField(const Object::Ptr& context, const String& field);
|
||||
static void SetField(const Object::Ptr& context, const String& field, const Value& value);
|
||||
};
|
||||
|
||||
I2_CONFIG_API Expression::Ptr MakeLiteral(const Value& lit = Value());
|
||||
|
|
|
@ -27,7 +27,7 @@ ObjectRule::RuleMap ObjectRule::m_Rules;
|
|||
ObjectRule::CallbackMap ObjectRule::m_Callbacks;
|
||||
|
||||
ObjectRule::ObjectRule(const String& name, const Expression::Ptr& expression,
|
||||
const Expression::Ptr& filter, const DebugInfo& di, const Dictionary::Ptr& scope)
|
||||
const Expression::Ptr& filter, const DebugInfo& di, const Object::Ptr& scope)
|
||||
: m_Name(name), m_Expression(expression), m_Filter(filter), m_DebugInfo(di), m_Scope(scope)
|
||||
{ }
|
||||
|
||||
|
@ -51,19 +51,19 @@ DebugInfo ObjectRule::GetDebugInfo(void) const
|
|||
return m_DebugInfo;
|
||||
}
|
||||
|
||||
Dictionary::Ptr ObjectRule::GetScope(void) const
|
||||
Object::Ptr ObjectRule::GetScope(void) const
|
||||
{
|
||||
return m_Scope;
|
||||
}
|
||||
|
||||
void ObjectRule::AddRule(const String& sourceType, const String& name,
|
||||
const Expression::Ptr& expression, const Expression::Ptr& filter,
|
||||
const DebugInfo& di, const Dictionary::Ptr& scope)
|
||||
const DebugInfo& di, const Object::Ptr& scope)
|
||||
{
|
||||
m_Rules[sourceType].push_back(ObjectRule(name, expression, filter, di, scope));
|
||||
}
|
||||
|
||||
bool ObjectRule::EvaluateFilter(const Dictionary::Ptr& scope) const
|
||||
bool ObjectRule::EvaluateFilter(const Object::Ptr& scope) const
|
||||
{
|
||||
return m_Filter->Evaluate(scope);
|
||||
}
|
||||
|
|
|
@ -42,12 +42,12 @@ public:
|
|||
Expression::Ptr GetExpression(void) const;
|
||||
Expression::Ptr GetFilter(void) const;
|
||||
DebugInfo GetDebugInfo(void) const;
|
||||
Dictionary::Ptr GetScope(void) const;
|
||||
Object::Ptr GetScope(void) const;
|
||||
|
||||
bool EvaluateFilter(const Dictionary::Ptr& scope) const;
|
||||
bool EvaluateFilter(const Object::Ptr& scope) const;
|
||||
|
||||
static void AddRule(const String& sourceType, const String& name, const Expression::Ptr& expression,
|
||||
const Expression::Ptr& filter, const DebugInfo& di, const Dictionary::Ptr& scope);
|
||||
const Expression::Ptr& filter, const DebugInfo& di, const Object::Ptr& scope);
|
||||
static void EvaluateRules(bool clear);
|
||||
|
||||
static void RegisterType(const String& sourceType, const ObjectRule::Callback& callback);
|
||||
|
@ -58,13 +58,13 @@ private:
|
|||
Expression::Ptr m_Expression;
|
||||
Expression::Ptr m_Filter;
|
||||
DebugInfo m_DebugInfo;
|
||||
Dictionary::Ptr m_Scope;
|
||||
Object::Ptr m_Scope;
|
||||
|
||||
static CallbackMap m_Callbacks;
|
||||
static RuleMap m_Rules;
|
||||
|
||||
ObjectRule(const String& name, const Expression::Ptr& expression,
|
||||
const Expression::Ptr& filter, const DebugInfo& di, const Dictionary::Ptr& scope);
|
||||
const Expression::Ptr& filter, const DebugInfo& di, const Object::Ptr& scope);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -86,6 +86,9 @@ bool TypeRule::MatchValue(const Value& value, String *hint, const TypeRuleUtilit
|
|||
|
||||
bool TypeRuleUtilities::ValidateName(const String& type, const String& name, String *hint) const
|
||||
{
|
||||
if (name.IsEmpty())
|
||||
return true;
|
||||
|
||||
ConfigItem::Ptr item = ConfigItem::GetObject(type, name);
|
||||
|
||||
if (!item) {
|
||||
|
|
|
@ -46,7 +46,7 @@ void Command::SetModifiedAttributes(int flags, const MessageOrigin& origin)
|
|||
|
||||
void Command::ValidateAttributes(const String& location, const Dictionary::Ptr& attrs)
|
||||
{
|
||||
if (attrs->Contains("arguments") && !attrs->Get("command").IsObjectType<Array>()) {
|
||||
if (attrs->Get("arguments") != Empty && !attrs->Get("command").IsObjectType<Array>()) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||
location + ": Attribute 'command' must be an array if the 'arguments' attribute is set.");
|
||||
}
|
||||
|
|
|
@ -87,7 +87,6 @@ void Dependency::EvaluateApplyRuleOneInstance(const Checkable::Ptr& checkable, c
|
|||
builder->AddExpression(rule.GetExpression());
|
||||
|
||||
ConfigItem::Ptr dependencyItem = builder->Compile();
|
||||
dependencyItem->Register();
|
||||
DynamicObject::Ptr dobj = dependencyItem->Commit();
|
||||
dobj->OnConfigLoaded();
|
||||
|
||||
|
|
|
@ -29,15 +29,17 @@ using namespace icinga;
|
|||
REGISTER_TYPE(Dependency);
|
||||
REGISTER_SCRIPTFUNCTION(ValidateDependencyFilters, &Dependency::ValidateFilters);
|
||||
|
||||
String DependencyNameComposer::MakeName(const String& shortName, const Dictionary::Ptr& props) const
|
||||
String DependencyNameComposer::MakeName(const String& shortName, const Object::Ptr& context) const
|
||||
{
|
||||
if (!props)
|
||||
Dependency::Ptr dependency = dynamic_pointer_cast<Dependency>(context);
|
||||
|
||||
if (!dependency)
|
||||
return "";
|
||||
|
||||
String name = props->Get("child_host_name");
|
||||
String name = dependency->GetChildHostName();
|
||||
|
||||
if (props->Contains("child_service_name"))
|
||||
name += "!" + props->Get("child_service_name");
|
||||
if (!dependency->GetChildServiceName().IsEmpty())
|
||||
name += "!" + dependency->GetChildServiceName();
|
||||
|
||||
name += "!" + shortName;
|
||||
|
||||
|
@ -205,12 +207,12 @@ void Dependency::ValidateFilters(const String& location, const Dictionary::Ptr&
|
|||
{
|
||||
int sfilter = FilterArrayToInt(attrs->Get("state_filter"), 0);
|
||||
|
||||
if (!attrs->Contains("parent_service_name") && (sfilter & ~(StateFilterUp | StateFilterDown)) != 0) {
|
||||
if (attrs->Get("parent_service_name") == Empty && (sfilter & ~(StateFilterUp | StateFilterDown)) != 0) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||
location + ": State filter is invalid for host dependency.");
|
||||
}
|
||||
|
||||
if (attrs->Contains("parent_service_name") && (sfilter & ~(StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0) {
|
||||
if (attrs->Get("parent_service_name") != Empty && (sfilter & ~(StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||
location + ": State filter is invalid for service dependency.");
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ code {{{
|
|||
class I2_ICINGA_API DependencyNameComposer : public NameComposer
|
||||
{
|
||||
public:
|
||||
virtual String MakeName(const String& shortName, const Dictionary::Ptr& props) const;
|
||||
virtual String MakeName(const String& shortName, const Object::Ptr& context) const;
|
||||
};
|
||||
}}}
|
||||
|
||||
|
|
|
@ -82,7 +82,6 @@ void Notification::EvaluateApplyRuleOneInstance(const Checkable::Ptr& checkable,
|
|||
builder->AddExpression(rule.GetExpression());
|
||||
|
||||
ConfigItem::Ptr notificationItem = builder->Compile();
|
||||
notificationItem->Register();
|
||||
DynamicObject::Ptr dobj = notificationItem->Commit();
|
||||
dobj->OnConfigLoaded();
|
||||
|
||||
|
|
|
@ -39,15 +39,17 @@ INITIALIZE_ONCE(&Notification::StaticInitialize);
|
|||
|
||||
boost::signals2::signal<void (const Notification::Ptr&, double, const MessageOrigin&)> Notification::OnNextNotificationChanged;
|
||||
|
||||
String NotificationNameComposer::MakeName(const String& shortName, const Dictionary::Ptr& props) const
|
||||
String NotificationNameComposer::MakeName(const String& shortName, const Object::Ptr& context) const
|
||||
{
|
||||
if (!props)
|
||||
Notification::Ptr notification = dynamic_pointer_cast<Notification>(context);
|
||||
|
||||
if (!notification)
|
||||
return "";
|
||||
|
||||
String name = props->Get("host_name");
|
||||
String name = notification->GetHostName();
|
||||
|
||||
if (props->Contains("service_name"))
|
||||
name += "!" + props->Get("service_name");
|
||||
if (!notification->GetServiceName().IsEmpty())
|
||||
name += "!" + notification->GetServiceName();
|
||||
|
||||
name += "!" + shortName;
|
||||
|
||||
|
@ -450,12 +452,12 @@ void Notification::ValidateFilters(const String& location, const Dictionary::Ptr
|
|||
{
|
||||
int sfilter = FilterArrayToInt(attrs->Get("states"), 0);
|
||||
|
||||
if (!attrs->Contains("service_name") && (sfilter & ~(StateFilterUp | StateFilterDown)) != 0) {
|
||||
if (attrs->Get("service_name") == Empty && (sfilter & ~(StateFilterUp | StateFilterDown)) != 0) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||
location + ": State filter is invalid.");
|
||||
}
|
||||
|
||||
if (attrs->Contains("service_name") && (sfilter & ~(StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0) {
|
||||
if (attrs->Get("service_name") != Empty && (sfilter & ~(StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||
location + ": State filter is invalid.");
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ code {{{
|
|||
class I2_ICINGA_API NotificationNameComposer : public NameComposer
|
||||
{
|
||||
public:
|
||||
virtual String MakeName(const String& shortName, const Dictionary::Ptr& props) const;
|
||||
virtual String MakeName(const String& shortName, const Object::Ptr& context) const;
|
||||
};
|
||||
}}}
|
||||
|
||||
|
|
|
@ -81,7 +81,6 @@ void ScheduledDowntime::EvaluateApplyRuleOneInstance(const Checkable::Ptr& check
|
|||
builder->AddExpression(rule.GetExpression());
|
||||
|
||||
ConfigItem::Ptr downtimeItem = builder->Compile();
|
||||
downtimeItem->Register();
|
||||
DynamicObject::Ptr dobj = downtimeItem->Commit();
|
||||
dobj->OnConfigLoaded();
|
||||
}
|
||||
|
|
|
@ -39,15 +39,17 @@ INITIALIZE_ONCE(&ScheduledDowntime::StaticInitialize);
|
|||
|
||||
static Timer::Ptr l_Timer;
|
||||
|
||||
String ScheduledDowntimeNameComposer::MakeName(const String& shortName, const Dictionary::Ptr& props) const
|
||||
String ScheduledDowntimeNameComposer::MakeName(const String& shortName, const Object::Ptr& context) const
|
||||
{
|
||||
if (!props)
|
||||
ScheduledDowntime::Ptr downtime = dynamic_pointer_cast<ScheduledDowntime>(context);
|
||||
|
||||
if (!downtime)
|
||||
return "";
|
||||
|
||||
String name = props->Get("host_name");
|
||||
String name = downtime->GetHostName();
|
||||
|
||||
if (props->Contains("service_name"))
|
||||
name += "!" + props->Get("service_name");
|
||||
if (!downtime->GetServiceName().IsEmpty())
|
||||
name += "!" + downtime->GetServiceName();
|
||||
|
||||
name += "!" + shortName;
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ code {{{
|
|||
class I2_ICINGA_API ScheduledDowntimeNameComposer : public NameComposer
|
||||
{
|
||||
public:
|
||||
virtual String MakeName(const String& shortName, const Dictionary::Ptr& props) const;
|
||||
virtual String MakeName(const String& shortName, const Object::Ptr& context) const;
|
||||
};
|
||||
}}}
|
||||
|
||||
|
|
|
@ -74,7 +74,6 @@ void Service::EvaluateApplyRuleOneInstance(const Host::Ptr& host, const String&
|
|||
builder->AddExpression(rule.GetExpression());
|
||||
|
||||
ConfigItem::Ptr serviceItem = builder->Compile();
|
||||
serviceItem->Register();
|
||||
DynamicObject::Ptr dobj = serviceItem->Commit();
|
||||
dobj->OnConfigLoaded();
|
||||
}
|
||||
|
|
|
@ -30,11 +30,14 @@ using namespace icinga;
|
|||
|
||||
REGISTER_TYPE(Service);
|
||||
|
||||
String ServiceNameComposer::MakeName(const String& shortName, const Dictionary::Ptr& props) const {
|
||||
if (!props)
|
||||
String ServiceNameComposer::MakeName(const String& shortName, const Object::Ptr& context) const
|
||||
{
|
||||
Service::Ptr service = dynamic_pointer_cast<Service>(context);
|
||||
|
||||
if (!service)
|
||||
return "";
|
||||
|
||||
return props->Get("host_name") + "!" + shortName;
|
||||
return service->GetHostName() + "!" + shortName;
|
||||
}
|
||||
|
||||
void Service::OnConfigLoaded(void)
|
||||
|
|
|
@ -29,7 +29,7 @@ code {{{
|
|||
class I2_ICINGA_API ServiceNameComposer : public NameComposer
|
||||
{
|
||||
public:
|
||||
virtual String MakeName(const String& shortName, const Dictionary::Ptr& props) const;
|
||||
virtual String MakeName(const String& shortName, const Object::Ptr& context) const;
|
||||
};
|
||||
}}}
|
||||
|
||||
|
|
|
@ -514,6 +514,12 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
|
|||
}
|
||||
}
|
||||
|
||||
if (klass.Name == "DynamicObject")
|
||||
std::cout << "\t" << "friend class ConfigItem;" << std::endl;
|
||||
|
||||
if (!klass.TypeBase.empty())
|
||||
std::cout << "\t" << "friend class " << klass.TypeBase << ";" << std::endl;
|
||||
|
||||
std::cout << "};" << std::endl << std::endl;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue