]> granicus.if.org Git - icinga2/commitdiff
Make sure that Notification objects are activated after Host/Service objects
authorGunnar Beutner <gunnar@beutner.name>
Wed, 25 Feb 2015 11:43:03 +0000 (12:43 +0100)
committerGunnar Beutner <gunnar@beutner.name>
Wed, 25 Feb 2015 11:43:38 +0000 (12:43 +0100)
fixes #8517

lib/base/type.cpp
lib/base/type.hpp
lib/config/configitem.cpp
lib/icinga/dependency.ti
lib/icinga/notification.ti
lib/icinga/scheduleddowntime.ti
lib/icinga/service.ti
tools/mkclass/class_lexer.ll
tools/mkclass/class_parser.yy
tools/mkclass/classcompiler.cpp
tools/mkclass/classcompiler.hpp

index d330e52aaceddae59f0f1232921e5077fa3d24bd..95bc97412c75276046bfc4ab4cf7533651d447c1 100644 (file)
@@ -106,6 +106,11 @@ Value Type::GetField(int id) const
        return Object::GetField(id);
 }
 
+std::vector<String> Type::GetLoadDependencies(void) const
+{
+       return std::vector<String>();
+}
+
 String TypeType::GetName(void) const
 {
        return "Type";
index fb25d05ce605451a4605b70442a21e58df572fb3..e8ae7e87d68c182e0a01bac42cd0df81062694df 100644 (file)
@@ -84,6 +84,8 @@ public:
        virtual void SetField(int id, const Value& value);
        virtual Value GetField(int id) const;
 
+       virtual std::vector<String> GetLoadDependencies(void) const;
+
 protected:
        virtual ObjectFactory GetFactory(void) const = 0;
 
index 69e7e2d1be4fd37ad8f5f2af2171917554013fdd..6cb4c8ae820d2677bf48bca73c957b2f7ad834f1 100644 (file)
@@ -326,11 +326,43 @@ bool ConfigItem::CommitNewItems(WorkQueue& upq)
                        new_items.swap(m_CommittedItems);
                }
 
+               std::set<String> types;
+
                BOOST_FOREACH(const ConfigItem::Ptr& item, new_items) {
-                       upq.Enqueue(boost::bind(&DynamicObject::OnAllConfigLoaded, item->m_Object));
+                       types.insert(item->m_Type);
                }
 
-               upq.Join();
+               std::set<String> completed_types;
+
+               while (types.size() != completed_types.size()) {
+                       std::set<String> current_types;
+
+                       BOOST_FOREACH(const String& type, types) {
+                               if (completed_types.find(type) != completed_types.end())
+                                       continue;
+
+                               Type::Ptr ptype = Type::GetByName(type);
+                               bool unresolved_dep = false;
+
+                               BOOST_FOREACH(const String& loadDep, ptype->GetLoadDependencies()) {
+                                       if (types.find(loadDep) != types.end() && completed_types.find(loadDep) == completed_types.end()) {
+                                               unresolved_dep = true;
+                                               break;
+                                       }
+                               }
+
+                               if (!unresolved_dep) {
+                                       BOOST_FOREACH(const ConfigItem::Ptr& item, new_items) {
+                                               if (item->m_Type == type)
+                                                       upq.Enqueue(boost::bind(&DynamicObject::OnAllConfigLoaded, item->m_Object));
+                                       }
+
+                                       completed_types.insert(type);
+                               }
+                       }
+
+                       upq.Join();
+               }
        } while (!items.empty());
 
        return true;
index 244877c342122fb22b0e709b0b18ec106703f7b3..d89e046f1b8cae9e82fcc519949f1b3e13691f24 100644 (file)
@@ -33,6 +33,9 @@ public:
 
 class Dependency : CustomVarObject < DependencyNameComposer
 {
+       load_after Host;
+       load_after Service;
+
        [config] String child_host_name;
        [config] String child_service_name;
 
index ba40b8422ad00149c451bf62d822f589a97890d3..dbb19a1d0a21133254f3b1ea7e7d0336ab12e679 100644 (file)
@@ -32,6 +32,9 @@ public:
 
 class Notification : CustomVarObject < NotificationNameComposer
 {
+       load_after Host;
+       load_after Service;
+
        [config, protected] String command (CommandRaw);
        [config] double interval {
                default {{{ return 1800; }}}
index 27a75b65c75eadac8715dcbeedf579cf0dbbe394..e2a68c57900f60fd450a2374f9a0825d342808e9 100644 (file)
@@ -32,6 +32,9 @@ public:
 
 class ScheduledDowntime : CustomVarObject < ScheduledDowntimeNameComposer
 {
+       load_after Host;
+       load_after Service;
+
        [config, protected] String host_name;
        [config, protected] String service_name;
 
index 4533403f5c8720a74cf4ec41900b3c240d44c8cb..8f524006d48b749250a01ee96af3182d15bcdefd 100644 (file)
@@ -35,6 +35,8 @@ public:
 
 class Service : Checkable < ServiceNameComposer
 {
+       load_after Host;
+
        [config] String display_name {
                get {{{
                        if (m_DisplayName.IsEmpty())
index 2d74276c3400e9eb1745fbc14b09644735635216..7c59cf62c4ff0f0f7cb650aeb55664f7aeab38bf 100644 (file)
@@ -133,6 +133,7 @@ static char *lb_steal(lex_buf *lb)
 class                          { return T_CLASS; }
 namespace                      { return T_NAMESPACE; }
 code                           { return T_CODE; }
+load_after                     { return T_LOAD_AFTER; }
 abstract                       { yylval->num = TAAbstract; return T_CLASS_ATTRIBUTE; }
 config                         { yylval->num = FAConfig; return T_FIELD_ATTRIBUTE; }
 state                          { yylval->num = FAState; return T_FIELD_ATTRIBUTE; }
index 5f60d92b3b0c180f2c11aef4fd8db39c74854945..59e9147d34a9caf839fbc225e96837576142a5fc 100644 (file)
@@ -55,6 +55,7 @@ using namespace icinga;
 %token T_INCLUDE "include (T_INCLUDE)"
 %token T_CLASS "class (T_CLASS)"
 %token T_CODE "code (T_CODE)"
+%token T_LOAD_AFTER "load_after (T_LOAD_AFTER)"
 %token T_NAMESPACE "namespace (T_NAMESPACE)"
 %token T_STRING "string (T_STRING)"
 %token T_ANGLE_STRING "angle_string (T_ANGLE_STRING)"
@@ -192,7 +193,13 @@ class: class_attribute_list T_CLASS T_IDENTIFIER inherits_specifier type_base_sp
 
                $$->Attributes = $1;
 
-               $$->Fields = *$7;
+               for (std::vector<Field>::iterator it = $7->begin(); it != $7->end(); it++) {
+                       if (it->Attributes & FALoadDependency) {
+                               $$->LoadDependencies.push_back(it->Name);
+                       } else
+                               $$->Fields.push_back(*it);
+               }
+
                delete $7;
 
                ClassCompiler::OptimizeStructLayout($$->Fields);
@@ -281,6 +288,14 @@ class_field: field_attribute_list identifier identifier alternative_name_specifi
 
                $$ = field;
        }
+       | T_LOAD_AFTER identifier ';'
+       {
+               Field *field = new Field();
+               field->Attributes = FALoadDependency;
+               field->Name = $2;
+               std::free($2);
+               $$ = field;
+       }
        ;
 
 alternative_name_specifier: /* empty */
index 7dc7b1580b2b60b5ba13327fda95a74e12cdd854..fa0c8d395496a681899ab86bdaec1c855a604bf0 100644 (file)
@@ -349,6 +349,17 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
                  << "\t\t" << "return TypeHelper<" << klass.Name << ">::GetFactory();" << std::endl
                  << "\t" << "}" << std::endl << std::endl;
 
+       /* GetLoadDependencies */
+       std::cout << "\t" << "virtual std::vector<String> GetLoadDependencies(void) const" << std::endl
+                 << "\t" << "{" << std::endl
+                 << "\t\t" << "std::vector<String> deps;" << std::endl;
+
+       for (std::vector<std::string>::const_iterator itd = klass.LoadDependencies.begin(); itd != klass.LoadDependencies.end(); itd++)
+               std::cout << "\t\t" << "deps.push_back(\"" << *itd << "\");" << std::endl;
+
+       std::cout << "\t\t" << "return deps;" << std::endl
+                 << "\t" << "}" << std::endl;
+
        std::cout << "};" << std::endl << std::endl;
 
        /* ObjectImpl */
index 3b9844853db7235a6f77350d0132ab8592780379..28df74c00ac4c4243c41f8862a05c0489110ac37 100644 (file)
@@ -63,7 +63,8 @@ enum FieldAttribute
        FAGetProtected = 8,
        FASetProtected = 16,
        FAInternal = 32,
-       FANoStorage = 64
+       FANoStorage = 64,
+       FALoadDependency = 128
 };
 
 struct Field
@@ -124,6 +125,7 @@ struct Klass
        std::string TypeBase;
        int Attributes;
        std::vector<Field> Fields;
+       std::vector<std::string> LoadDependencies;
 };
 
 class ClassCompiler