]> granicus.if.org Git - icinga2/blob - lib/icinga/servicegroup.cpp
Even more code refactoring.
[icinga2] / lib / icinga / servicegroup.cpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/)        *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (at your option) any later version.                     *
9  *                                                                            *
10  * This program is distributed in the hope that it will be useful,            *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13  * GNU General Public License for more details.                               *
14  *                                                                            *
15  * You should have received a copy of the GNU General Public License          *
16  * along with this program; if not, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19
20 #include "i2-icinga.h"
21
22 using namespace icinga;
23
24 boost::mutex ServiceGroup::m_Mutex;
25 map<String, vector<Service::WeakPtr> > ServiceGroup::m_MembersCache;
26 bool ServiceGroup::m_MembersCacheValid = true;
27
28 REGISTER_TYPE(ServiceGroup);
29
30 ServiceGroup::ServiceGroup(const Dictionary::Ptr& properties)
31         : DynamicObject(properties)
32 {
33         RegisterAttribute("display_name", Attribute_Config, &m_DisplayName);
34         RegisterAttribute("notes_url", Attribute_Config, &m_NotesUrl);
35         RegisterAttribute("action_url", Attribute_Config, &m_ActionUrl);
36 }
37
38 ServiceGroup::~ServiceGroup(void)
39 {
40         InvalidateMembersCache();
41 }
42
43 /**
44  * @threadsafety Always.
45  */
46 void ServiceGroup::OnRegistrationCompleted(void)
47 {
48         assert(!OwnsLock());
49
50         InvalidateMembersCache();
51 }
52
53 /**
54  * @threadsafety Always.
55  */
56 String ServiceGroup::GetDisplayName(void) const
57 {
58         if (!m_DisplayName.Get().IsEmpty())
59                 return m_DisplayName;
60         else
61                 return GetName();
62 }
63
64 /**
65  * @threadsafety Always.
66  */
67 String ServiceGroup::GetNotesUrl(void) const
68 {
69         return m_NotesUrl;
70 }
71
72 /**
73  * @threadsafety Always.
74  */
75 String ServiceGroup::GetActionUrl(void) const
76 {
77         return m_ActionUrl;
78 }
79
80 /**
81  * @threadsafety Always.
82  */
83 ServiceGroup::Ptr ServiceGroup::GetByName(const String& name)
84 {
85         DynamicObject::Ptr configObject = DynamicObject::GetObject("ServiceGroup", name);
86
87         if (!configObject)
88                 BOOST_THROW_EXCEPTION(invalid_argument("ServiceGroup '" + name + "' does not exist."));
89
90         return dynamic_pointer_cast<ServiceGroup>(configObject);
91 }
92
93 /**
94  * @threadsafety Always.
95  */
96 set<Service::Ptr> ServiceGroup::GetMembers(void) const
97 {
98         set<Service::Ptr> services;
99
100         {
101                 boost::mutex::scoped_lock lock(m_Mutex);
102
103                 BOOST_FOREACH(const Service::WeakPtr& wservice, m_MembersCache[GetName()]) {
104                         Service::Ptr service = wservice.lock();
105
106                         if (!service)
107                                 continue;
108
109                         services.insert(service);
110                 }
111         }
112
113         return services;
114 }
115
116 /**
117  * @threadsafety Always.
118  */
119 void ServiceGroup::InvalidateMembersCache(void)
120 {
121         boost::mutex::scoped_lock lock(m_Mutex);
122
123         if (m_MembersCacheValid)
124                 Utility::QueueAsyncCallback(boost::bind(&ServiceGroup::RefreshMembersCache));
125
126         m_MembersCacheValid = false;
127 }
128
129 /**
130  * @threadsafety Always.
131  */
132 void ServiceGroup::RefreshMembersCache(void)
133 {
134         {
135                 boost::mutex::scoped_lock lock(m_Mutex);
136
137                 if (m_MembersCacheValid)
138                         return;
139
140                 m_MembersCacheValid = true;
141         }
142
143         map<String, vector<Service::WeakPtr> > newMembersCache;
144
145         BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
146                 const Service::Ptr& service = static_pointer_cast<Service>(object);
147
148                 Dictionary::Ptr dict;
149                 dict = service->GetGroups();
150
151                 if (dict) {
152                         ObjectLock mlock(dict);
153                         Value servicegroup;
154                         BOOST_FOREACH(tie(tuples::ignore, servicegroup), dict) {
155                                 newMembersCache[servicegroup].push_back(service);
156                         }
157                 }
158         }
159
160         boost::mutex::scoped_lock lock(m_Mutex);
161         m_MembersCache.swap(newMembersCache);
162 }