]> granicus.if.org Git - icinga2/blob - components/configrpc/configrpccomponent.cpp
2504510ce2d0dd494b5e440707da1d715cfb0581
[icinga2] / components / configrpc / configrpccomponent.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-configrpc.h"
21
22 using namespace icinga;
23
24 string ConfigRpcComponent::GetName(void) const
25 {
26         return "configcomponent";
27 }
28
29 void ConfigRpcComponent::Start(void)
30 {
31         EndpointManager::Ptr endpointManager = GetEndpointManager();
32
33         m_ConfigRpcEndpoint = make_shared<VirtualEndpoint>();
34
35         long configSource;
36         if (GetConfig()->GetProperty("configSource", &configSource) && configSource != 0) {
37                 m_ConfigRpcEndpoint->RegisterTopicHandler("config::FetchObjects",
38                     bind_weak(&ConfigRpcComponent::FetchObjectsHandler, shared_from_this()));
39
40                 ConfigObject::GetAllObjects()->OnObjectAdded += bind_weak(&ConfigRpcComponent::LocalObjectCommittedHandler, shared_from_this());
41                 ConfigObject::GetAllObjects()->OnObjectCommitted += bind_weak(&ConfigRpcComponent::LocalObjectCommittedHandler, shared_from_this());
42                 ConfigObject::GetAllObjects()->OnObjectRemoved += bind_weak(&ConfigRpcComponent::LocalObjectRemovedHandler, shared_from_this());
43
44                 m_ConfigRpcEndpoint->RegisterPublication("config::ObjectCommitted");
45                 m_ConfigRpcEndpoint->RegisterPublication("config::ObjectRemoved");
46         }
47
48         endpointManager->OnNewEndpoint += bind_weak(&ConfigRpcComponent::NewEndpointHandler, shared_from_this());
49
50         m_ConfigRpcEndpoint->RegisterPublication("config::FetchObjects");
51         m_ConfigRpcEndpoint->RegisterTopicHandler("config::ObjectCommitted",
52             bind_weak(&ConfigRpcComponent::RemoteObjectCommittedHandler, shared_from_this()));
53         m_ConfigRpcEndpoint->RegisterTopicHandler("config::ObjectRemoved",
54             bind_weak(&ConfigRpcComponent::RemoteObjectRemovedHandler, shared_from_this()));
55
56         endpointManager->RegisterEndpoint(m_ConfigRpcEndpoint);
57 }
58
59 void ConfigRpcComponent::Stop(void)
60 {
61         EndpointManager::Ptr mgr = GetEndpointManager();
62
63         if (mgr)
64                 mgr->UnregisterEndpoint(m_ConfigRpcEndpoint);
65 }
66
67 int ConfigRpcComponent::NewEndpointHandler(const NewEndpointEventArgs& ea)
68 {
69         ea.Endpoint->OnSessionEstablished += bind_weak(&ConfigRpcComponent::SessionEstablishedHandler, shared_from_this());
70
71         return 0;
72 }
73
74 int ConfigRpcComponent::SessionEstablishedHandler(const EventArgs& ea)
75 {
76         RequestMessage request;
77         request.SetMethod("config::FetchObjects");
78
79         Endpoint::Ptr endpoint = static_pointer_cast<Endpoint>(ea.Source);
80         GetEndpointManager()->SendUnicastMessage(m_ConfigRpcEndpoint, endpoint, request);
81
82         return 0;
83 }
84
85 RequestMessage ConfigRpcComponent::MakeObjectMessage(const ConfigObject::Ptr& object, string method, bool includeProperties)
86 {
87         RequestMessage msg;
88         msg.SetMethod(method);
89
90         MessagePart params;
91         msg.SetParams(params);
92
93         params.SetProperty("name", object->GetName());
94         params.SetProperty("type", object->GetType());
95
96         if (includeProperties)
97                 params.SetProperty("properties", object->GetProperties());
98
99         return msg;
100 }
101
102 bool ConfigRpcComponent::ShouldReplicateObject(const ConfigObject::Ptr& object)
103 {
104         return (!object->IsLocal());
105 }
106
107 int ConfigRpcComponent::FetchObjectsHandler(const NewRequestEventArgs& ea)
108 {
109         Endpoint::Ptr client = ea.Sender;
110         ConfigObject::Set::Ptr allObjects = ConfigObject::GetAllObjects();
111
112         for (ConfigObject::Set::Iterator ci = allObjects->Begin(); ci != allObjects->End(); ci++) {
113                 ConfigObject::Ptr object = *ci;
114
115                 if (!ShouldReplicateObject(object))
116                         continue;
117
118                 RequestMessage request = MakeObjectMessage(object, "config::ObjectCreated", true);
119
120                 GetEndpointManager()->SendUnicastMessage(m_ConfigRpcEndpoint, client, request);
121         }
122
123         return 0;
124 }
125
126 int ConfigRpcComponent::LocalObjectCommittedHandler(const ObjectSetEventArgs<ConfigObject::Ptr>& ea)
127 {
128         ConfigObject::Ptr object = ea.Target;
129         
130         if (!ShouldReplicateObject(object))
131                 return 0;
132
133         GetEndpointManager()->SendMulticastMessage(m_ConfigRpcEndpoint,
134             MakeObjectMessage(object, "config::ObjectCreated", true));
135
136         return 0;
137 }
138
139 int ConfigRpcComponent::LocalObjectRemovedHandler(const ObjectSetEventArgs<ConfigObject::Ptr>& ea)
140 {
141         ConfigObject::Ptr object = ea.Target;
142         
143         if (!ShouldReplicateObject(object))
144                 return 0;
145
146         GetEndpointManager()->SendMulticastMessage(m_ConfigRpcEndpoint,
147             MakeObjectMessage(object, "config::ObjectRemoved", false));
148
149         return 0;
150 }
151
152 int ConfigRpcComponent::RemoteObjectCommittedHandler(const NewRequestEventArgs& ea)
153 {
154         RequestMessage message = ea.Request;
155
156         MessagePart params;
157         if (!message.GetParams(&params))
158                 return 0;
159
160         string name;
161         if (!params.GetProperty("name", &name))
162                 return 0;
163
164         string type;
165         if (!params.GetProperty("type", &type))
166                 return 0;
167
168         MessagePart properties;
169         if (!params.GetProperty("properties", &properties))
170                 return 0;
171
172         ConfigObject::Ptr object = ConfigObject::GetObject(type, name);
173
174         if (!object)
175                 object = make_shared<ConfigObject>(properties.GetDictionary());
176         else
177                 object->SetProperties(properties.GetDictionary());
178
179         object->Commit();
180
181         return 0;
182 }
183
184 int ConfigRpcComponent::RemoteObjectRemovedHandler(const NewRequestEventArgs& ea)
185 {
186         RequestMessage message = ea.Request;
187         
188         MessagePart params;
189         if (!message.GetParams(&params))
190                 return 0;
191
192         string name;
193         if (!params.GetProperty("name", &name))
194                 return 0;
195
196         string type;
197         if (!params.GetProperty("type", &type))
198                 return 0;
199
200         ConfigObject::Ptr object = ConfigObject::GetObject(type, name);
201
202         if (!object)
203                 return 0;
204
205         if (!object->IsLocal())
206                 object->Unregister();
207
208         return 0;
209 }
210
211 EXPORT_COMPONENT(configrpc, ConfigRpcComponent);