64cceffd032866ec7908d1255794ecafba1f0fe1
[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 && (m_modified & MODIFY_OTHER))
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
143 if (success)
144 success = saveACLToDB(hdb);
145
146 // Unlock object and clear modification flag
147 m_modified = 0;
148 unlockProperties();
149 return success;
150 }
151
152 /**
153 * Delete zone object from database
154 */
155 bool Zone::deleteFromDatabase(DB_HANDLE hdb)
156 {
157 bool success = NetObj::deleteFromDatabase(hdb);
158 if (success)
159 success = executeQueryOnObject(hdb, _T("DELETE FROM zones WHERE id=?"));
160 return success;
161 }
162
163 /**
164 * Create NXCP message with object's data
165 */
166 void Zone::fillMessageInternal(NXCPMessage *msg)
167 {
168 NetObj::fillMessageInternal(msg);
169 msg->setField(VID_ZONE_UIN, m_uin);
170 msg->setField(VID_ZONE_PROXY, m_proxyNodeId);
171 }
172
173 /**
174 * Modify object from message
175 */
176 UINT32 Zone::modifyFromMessageInternal(NXCPMessage *request)
177 {
178 if (request->isFieldExist(VID_ZONE_PROXY))
179 m_proxyNodeId = request->getFieldAsUInt32(VID_ZONE_PROXY);
180
181 return NetObj::modifyFromMessageInternal(request);
182 }
183
184 /**
185 * Update interface index
186 */
187 void Zone::updateInterfaceIndex(const InetAddress& oldIp, const InetAddress& newIp, Interface *iface)
188 {
189 m_idxInterfaceByAddr->remove(oldIp);
190 m_idxInterfaceByAddr->put(newIp, iface);
191 }
192
193 /**
194 * Called by client session handler to check if threshold summary should be shown for this object.
195 */
196 bool Zone::showThresholdSummary()
197 {
198 return true;
199 }
200
201 /**
202 * Remove interface from index
203 */
204 void Zone::removeFromIndex(Interface *iface)
205 {
206 const ObjectArray<InetAddress> *list = iface->getIpAddressList()->getList();
207 for(int i = 0; i < list->size(); i++)
208 {
209 InetAddress *addr = list->get(i);
210 if (addr->isValidUnicast())
211 {
212 NetObj *o = m_idxInterfaceByAddr->get(*addr);
213 if ((o != NULL) && (o->getId() == iface->getId()))
214 {
215 m_idxInterfaceByAddr->remove(*addr);
216 }
217 }
218 }
219 }
220
221 /**
222 * Create NXSL object for this object
223 */
224 NXSL_Value *Zone::createNXSLObject()
225 {
226 return new NXSL_Value(new NXSL_Object(&g_nxslZoneClass, this));
227 }
228
229 /**
230 * Dump interface index to console
231 */
232 void Zone::dumpInterfaceIndex(CONSOLE_CTX console)
233 {
234 DumpIndex(console, m_idxInterfaceByAddr);
235 }
236
237 /**
238 * Dump node index to console
239 */
240 void Zone::dumpNodeIndex(CONSOLE_CTX console)
241 {
242 DumpIndex(console, m_idxNodeByAddr);
243 }
244
245 /**
246 * Dump subnet index to console
247 */
248 void Zone::dumpSubnetIndex(CONSOLE_CTX console)
249 {
250 DumpIndex(console, m_idxSubnetByAddr);
251 }
252
253 /**
254 * Serialize object to JSON
255 */
256 json_t *Zone::toJson()
257 {
258 json_t *root = NetObj::toJson();
259 json_object_set_new(root, "uin", json_integer(m_uin));
260 json_object_set_new(root, "proxyNodeId", json_integer(m_proxyNodeId));
261 return root;
262 }