a12e2ea3943494ce03819c06391fd2f294f6a323
[public/netxms.git] / src / server / core / zone.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003-2017 Victor Kirhenshtein
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (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
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 **
19 ** File: zone.cpp
20 **
21 **/
22
23 #include "nxcore.h"
24
25 /**
26 * Dump index to console
27 */
28 void DumpIndex(CONSOLE_CTX pCtx, InetAddressIndex *index);
29
30 /**
31 * Zone class default constructor
32 */
33 Zone::Zone() : NetObj()
34 {
35 m_id = 0;
36 m_uin = 0;
37 _tcscpy(m_name, _T("Default"));
38 m_proxyNodeId = 0;
39 m_idxNodeByAddr = new InetAddressIndex;
40 m_idxInterfaceByAddr = new InetAddressIndex;
41 m_idxSubnetByAddr = new InetAddressIndex;
42 }
43
44 /**
45 * Constructor for new zone object
46 */
47 Zone::Zone(UINT32 uin, const TCHAR *name) : NetObj()
48 {
49 m_id = 0;
50 m_uin = uin;
51 nx_strncpy(m_name, name, MAX_OBJECT_NAME);
52 m_proxyNodeId = 0;
53 m_idxNodeByAddr = new InetAddressIndex;
54 m_idxInterfaceByAddr = new InetAddressIndex;
55 m_idxSubnetByAddr = new InetAddressIndex;
56 }
57
58 /**
59 * Zone class destructor
60 */
61 Zone::~Zone()
62 {
63 delete m_idxNodeByAddr;
64 delete m_idxInterfaceByAddr;
65 delete m_idxSubnetByAddr;
66 }
67
68 /**
69 * Create object from database data
70 */
71 bool Zone::loadFromDatabase(DB_HANDLE hdb, UINT32 dwId)
72 {
73 m_id = dwId;
74
75 if (!loadCommonProperties(hdb))
76 return false;
77
78 TCHAR szQuery[256];
79 _sntprintf(szQuery, 256, _T("SELECT zone_guid,proxy_node FROM zones WHERE id=%d"), dwId);
80 DB_RESULT hResult = DBSelect(hdb, szQuery);
81 if (hResult == NULL)
82 return false; // Query failed
83
84 if (DBGetNumRows(hResult) == 0)
85 {
86 DBFreeResult(hResult);
87 if (dwId == BUILTIN_OID_ZONE0)
88 {
89 m_uin = 0;
90 return true;
91 }
92 else
93 {
94 DbgPrintf(4, _T("Cannot load zone object %ld - missing record in \"zones\" table"), (long)m_id);
95 return false;
96 }
97 }
98
99 m_uin = DBGetFieldULong(hResult, 0, 0);
100 m_proxyNodeId = DBGetFieldULong(hResult, 0, 1);
101
102 DBFreeResult(hResult);
103
104 // Load access list
105 loadACLFromDB(hdb);
106
107 return true;
108 }
109
110 /**
111 * Save object to database
112 */
113 bool Zone::saveToDatabase(DB_HANDLE hdb)
114 {
115 lockProperties();
116
117 bool success = saveCommonProperties(hdb);
118 if (success)
119 {
120 DB_STATEMENT hStmt;
121 if (IsDatabaseRecordExist(hdb, _T("zones"), _T("id"), m_id))
122 {
123 hStmt = DBPrepare(hdb, _T("UPDATE zones SET zone_guid=?,proxy_node=? WHERE id=?"));
124 }
125 else
126 {
127 hStmt = DBPrepare(hdb, _T("INSERT INTO zones (zone_guid,proxy_node,id) VALUES (?,?,?)"));
128 }
129 if (hStmt != NULL)
130 {
131 DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, m_uin);
132 DBBind(hStmt, 2, DB_SQLTYPE_INTEGER, m_proxyNodeId);
133 DBBind(hStmt, 3, DB_SQLTYPE_INTEGER, m_id);
134 success = DBExecute(hStmt);
135 DBFreeStatement(hStmt);
136 }
137 else
138 {
139 success = false;
140 }
141
142 if (success)
143 success = saveACLToDB(hdb);
144 }
145 // Unlock object and clear modification flag
146 m_isModified = false;
147 unlockProperties();
148 return success;
149 }
150
151 /**
152 * Delete zone object from database
153 */
154 bool Zone::deleteFromDatabase(DB_HANDLE hdb)
155 {
156 bool success = NetObj::deleteFromDatabase(hdb);
157 if (success)
158 success = executeQueryOnObject(hdb, _T("DELETE FROM zones WHERE id=?"));
159 return success;
160 }
161
162 /**
163 * Create NXCP message with object's data
164 */
165 void Zone::fillMessageInternal(NXCPMessage *msg)
166 {
167 NetObj::fillMessageInternal(msg);
168 msg->setField(VID_ZONE_UIN, m_uin);
169 msg->setField(VID_ZONE_PROXY, m_proxyNodeId);
170 }
171
172 /**
173 * Modify object from message
174 */
175 UINT32 Zone::modifyFromMessageInternal(NXCPMessage *request)
176 {
177 if (request->isFieldExist(VID_ZONE_PROXY))
178 m_proxyNodeId = request->getFieldAsUInt32(VID_ZONE_PROXY);
179
180 return NetObj::modifyFromMessageInternal(request);
181 }
182
183 /**
184 * Update interface index
185 */
186 void Zone::updateInterfaceIndex(const InetAddress& oldIp, const InetAddress& newIp, Interface *iface)
187 {
188 m_idxInterfaceByAddr->remove(oldIp);
189 m_idxInterfaceByAddr->put(newIp, iface);
190 }
191
192 /**
193 * Called by client session handler to check if threshold summary should be shown for this object.
194 */
195 bool Zone::showThresholdSummary()
196 {
197 return true;
198 }
199
200 /**
201 * Remove interface from index
202 */
203 void Zone::removeFromIndex(Interface *iface)
204 {
205 const ObjectArray<InetAddress> *list = iface->getIpAddressList()->getList();
206 for(int i = 0; i < list->size(); i++)
207 {
208 InetAddress *addr = list->get(i);
209 if (addr->isValidUnicast())
210 {
211 NetObj *o = m_idxInterfaceByAddr->get(*addr);
212 if ((o != NULL) && (o->getId() == iface->getId()))
213 {
214 m_idxInterfaceByAddr->remove(*addr);
215 }
216 }
217 }
218 }
219
220 /**
221 * Create NXSL object for this object
222 */
223 NXSL_Value *Zone::createNXSLObject()
224 {
225 return new NXSL_Value(new NXSL_Object(&g_nxslZoneClass, this));
226 }
227
228 /**
229 * Dump interface index to console
230 */
231 void Zone::dumpInterfaceIndex(CONSOLE_CTX console)
232 {
233 DumpIndex(console, m_idxInterfaceByAddr);
234 }
235
236 /**
237 * Dump node index to console
238 */
239 void Zone::dumpNodeIndex(CONSOLE_CTX console)
240 {
241 DumpIndex(console, m_idxNodeByAddr);
242 }
243
244 /**
245 * Dump subnet index to console
246 */
247 void Zone::dumpSubnetIndex(CONSOLE_CTX console)
248 {
249 DumpIndex(console, m_idxSubnetByAddr);
250 }
251
252 /**
253 * Serialize object to JSON
254 */
255 json_t *Zone::toJson()
256 {
257 json_t *root = NetObj::toJson();
258 json_object_set_new(root, "uin", json_integer(m_uin));
259 json_object_set_new(root, "proxyNodeId", json_integer(m_proxyNodeId));
260 return root;
261 }