minor refactoring
[public/netxms.git] / src / server / core / objects.cpp
CommitLineData
5039dede
AK
1/*
2** NetXMS - Network Management System
9dea3344 3** Copyright (C) 2003-2014 Victor Kirhenshtein
5039dede
AK
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: objects.cpp
20**
21**/
22
23#include "nxcore.h"
24
496390c2
VK
25/**
26 * Global data
27 */
5039dede
AK
28BOOL g_bModificationsLocked = FALSE;
29
fb05c05b
VK
30Network NXCORE_EXPORTABLE *g_pEntireNet = NULL;
31ServiceRoot NXCORE_EXPORTABLE *g_pServiceRoot = NULL;
32TemplateRoot NXCORE_EXPORTABLE *g_pTemplateRoot = NULL;
33PolicyRoot NXCORE_EXPORTABLE *g_pPolicyRoot = NULL;
021dcda7 34NetworkMapRoot NXCORE_EXPORTABLE *g_pMapRoot = NULL;
926e8ce7 35DashboardRoot NXCORE_EXPORTABLE *g_pDashboardRoot = NULL;
1621a079 36BusinessServiceRoot NXCORE_EXPORTABLE *g_pBusinessServiceRoot = NULL;
5039dede 37
967893bb
VK
38UINT32 NXCORE_EXPORTABLE g_dwMgmtNode = 0;
39UINT32 g_dwNumCategories = 0;
5039dede
AK
40CONTAINER_CATEGORY *g_pContainerCatList = NULL;
41
42Queue *g_pTemplateUpdateQueue = NULL;
43
9d605305 44ObjectIndex g_idxObjectById;
c75e9ee4
VK
45InetAddressIndex g_idxSubnetByAddr;
46InetAddressIndex g_idxInterfaceByAddr;
9d605305
VK
47ObjectIndex g_idxZoneByGUID;
48ObjectIndex g_idxNodeById;
c75e9ee4 49InetAddressIndex g_idxNodeByAddr;
85ae39bc 50ObjectIndex g_idxClusterById;
9aa67910 51ObjectIndex g_idxMobileDeviceById;
c6afd26a 52ObjectIndex g_idxAccessPointById;
9d605305 53ObjectIndex g_idxConditionById;
6ff21d27 54ObjectIndex g_idxServiceCheckById;
dba7a1a8 55ObjectIndex g_idxNetMapById;
9d605305 56
35f836fe
VK
57const TCHAR *g_szClassName[]={ _T("Generic"), _T("Subnet"), _T("Node"), _T("Interface"),
58 _T("Network"), _T("Container"), _T("Zone"), _T("ServiceRoot"),
59 _T("Template"), _T("TemplateGroup"), _T("TemplateRoot"),
60 _T("NetworkService"), _T("VPNConnector"), _T("Condition"),
61 _T("Cluster"), _T("PolicyGroup"), _T("PolicyRoot"),
62 _T("AgentPolicy"), _T("AgentPolicyConfig"), _T("NetworkMapRoot"),
27f9598d 63 _T("NetworkMapGroup"), _T("NetworkMap"), _T("DashboardRoot"),
fc958888 64 _T("Dashboard"), _T("ReportRoot"), _T("ReportGroup"), _T("Report"),
9aa67910 65 _T("BusinessServiceRoot"), _T("BusinessService"), _T("NodeLink"),
8715a84c 66 _T("ServiceCheck"), _T("MobileDevice"), _T("Rack"), _T("AccessPoint")
fc958888 67};
5039dede 68
496390c2
VK
69/**
70 * Static data
71 */
5039dede
AK
72static int m_iStatusCalcAlg = SA_CALCULATE_MOST_CRITICAL;
73static int m_iStatusPropAlg = SA_PROPAGATE_UNCHANGED;
74static int m_iFixedStatus; // Status if propagation is "Fixed"
75static int m_iStatusShift; // Shift value for "shifted" status propagation
76static int m_iStatusTranslation[4];
77static int m_iStatusSingleThreshold;
78static int m_iStatusThresholds[4];
dba7a1a8 79static CONDITION s_condUpdateMaps = INVALID_CONDITION_HANDLE;
5039dede 80
dba7a1a8
VK
81/**
82 * Thread which apply template updates
83 */
5039dede
AK
84static THREAD_RESULT THREAD_CALL ApplyTemplateThread(void *pArg)
85{
17b055bb 86 DbgPrintf(1, _T("Apply template thread started"));
5039dede
AK
87 while(1)
88 {
19dbc8ef 89 TEMPLATE_UPDATE_INFO *pInfo = (TEMPLATE_UPDATE_INFO *)g_pTemplateUpdateQueue->getOrBlock();
5039dede
AK
90 if (pInfo == INVALID_POINTER_VALUE)
91 break;
92
d140955e
VK
93 DbgPrintf(5, _T("ApplyTemplateThread: template=%d(%s) updateType=%d target=%d removeDci=%s"),
94 pInfo->pTemplate->getId(), pInfo->pTemplate->getName(), pInfo->updateType, pInfo->targetId, pInfo->removeDCI ? _T("true") : _T("false"));
95 BOOL bSuccess = FALSE;
96 NetObj *dcTarget = FindObjectById(pInfo->targetId);
6fd6de0a 97 if (dcTarget != NULL)
5039dede 98 {
c42b4551 99 if ((dcTarget->getObjectClass() == OBJECT_NODE) || (dcTarget->getObjectClass() == OBJECT_CLUSTER) || (dcTarget->getObjectClass() == OBJECT_MOBILEDEVICE))
5039dede 100 {
d140955e
VK
101 BOOL lock1, lock2;
102
103 switch(pInfo->updateType)
5039dede
AK
104 {
105 case APPLY_TEMPLATE:
d140955e
VK
106 lock1 = pInfo->pTemplate->lockDCIList(0x7FFFFFFF, _T("SYSTEM"), NULL);
107 lock2 = ((DataCollectionTarget *)dcTarget)->lockDCIList(0x7FFFFFFF, _T("SYSTEM"), NULL);
108 if (lock1 && lock2)
5039dede 109 {
6fd6de0a 110 pInfo->pTemplate->applyToTarget((DataCollectionTarget *)dcTarget);
5039dede
AK
111 bSuccess = TRUE;
112 }
d140955e 113 if (lock1)
6fd6de0a 114 pInfo->pTemplate->unlockDCIList(0x7FFFFFFF);
d140955e 115 if (lock2)
6fd6de0a 116 ((DataCollectionTarget *)dcTarget)->unlockDCIList(0x7FFFFFFF);
5039dede
AK
117 break;
118 case REMOVE_TEMPLATE:
6fd6de0a 119 if (((DataCollectionTarget *)dcTarget)->lockDCIList(0x7FFFFFFF, _T("SYSTEM"), NULL))
5039dede 120 {
d140955e 121 ((DataCollectionTarget *)dcTarget)->unbindFromTemplate(pInfo->pTemplate->getId(), pInfo->removeDCI);
6fd6de0a 122 ((DataCollectionTarget *)dcTarget)->unlockDCIList(0x7FFFFFFF);
5039dede
AK
123 bSuccess = TRUE;
124 }
125 break;
126 default:
127 bSuccess = TRUE;
128 break;
129 }
130 }
131 }
132
133 if (bSuccess)
134 {
17b055bb 135 DbgPrintf(8, _T("ApplyTemplateThread: success"));
21c9acce 136 pInfo->pTemplate->decRefCount();
5039dede
AK
137 free(pInfo);
138 }
139 else
140 {
17b055bb 141 DbgPrintf(8, _T("ApplyTemplateThread: failed"));
19dbc8ef 142 g_pTemplateUpdateQueue->put(pInfo); // Requeue
5039dede
AK
143 ThreadSleepMs(500);
144 }
145 }
146
17b055bb 147 DbgPrintf(1, _T("Apply template thread stopped"));
5039dede
AK
148 return THREAD_OK;
149}
150
da9cf449
VK
151/**
152 * Update DCI cache for all data collection targets referenced by given index
153 */
154static void UpdateDataCollectionCache(ObjectIndex *idx)
155{
156 ObjectArray<NetObj> *objects = idx->getObjects(true);
157 for(int i = 0; i < objects->size(); i++)
158 {
159 DataCollectionTarget *t = (DataCollectionTarget *)objects->get(i);
160 t->updateDciCache();
161 t->decRefCount();
162 }
163 delete objects;
164}
165
dba7a1a8
VK
166/**
167 * DCI cache loading thread
168 */
5039dede
AK
169static THREAD_RESULT THREAD_CALL CacheLoadingThread(void *pArg)
170{
5039dede 171 DbgPrintf(1, _T("Started caching of DCI values"));
171c2fd6 172
da9cf449
VK
173 UpdateDataCollectionCache(&g_idxNodeById);
174 UpdateDataCollectionCache(&g_idxClusterById);
175 UpdateDataCollectionCache(&g_idxMobileDeviceById);
176 UpdateDataCollectionCache(&g_idxAccessPointById);
c6afd26a 177
5039dede
AK
178 DbgPrintf(1, _T("Finished caching of DCI values"));
179 return THREAD_OK;
180}
181
dba7a1a8
VK
182/**
183 * Callback for map update thread
184 */
185static void UpdateMapCallback(NetObj *object, void *data)
186{
ba8bae74 187 ((NetworkMap *)object)->updateContent();
274e4b5b 188 ((NetworkMap *)object)->calculateCompoundStatus();
dba7a1a8 189}
5039dede 190
dba7a1a8
VK
191/**
192 * Map update thread
193 */
ba8bae74 194static THREAD_RESULT THREAD_CALL MapUpdateThread(void *pArg)
dba7a1a8
VK
195{
196 DbgPrintf(2, _T("Map update thread started"));
ba8bae74 197 while(!SleepAndCheckForShutdown(60))
dba7a1a8 198 {
ccb55c1d 199 DbgPrintf(5, _T("Updating maps..."));
dba7a1a8 200 g_idxNetMapById.forEach(UpdateMapCallback, NULL);
ccb55c1d 201 DbgPrintf(5, _T("Map update completed"));
dba7a1a8
VK
202 }
203 DbgPrintf(2, _T("Map update thread stopped"));
204 return THREAD_OK;
205}
5039dede 206
dba7a1a8
VK
207/**
208 * Initialize objects infrastructure
209 */
bc980b27 210void ObjectsInit()
5039dede
AK
211{
212 // Load default status calculation info
35f836fe
VK
213 m_iStatusCalcAlg = ConfigReadInt(_T("StatusCalculationAlgorithm"), SA_CALCULATE_MOST_CRITICAL);
214 m_iStatusPropAlg = ConfigReadInt(_T("StatusPropagationAlgorithm"), SA_PROPAGATE_UNCHANGED);
215 m_iFixedStatus = ConfigReadInt(_T("FixedStatusValue"), STATUS_NORMAL);
216 m_iStatusShift = ConfigReadInt(_T("StatusShift"), 0);
217 ConfigReadByteArray(_T("StatusTranslation"), m_iStatusTranslation, 4, STATUS_WARNING);
218 m_iStatusSingleThreshold = ConfigReadInt(_T("StatusSingleThreshold"), 75);
219 ConfigReadByteArray(_T("StatusThresholds"), m_iStatusThresholds, 4, 50);
5039dede
AK
220
221 g_pTemplateUpdateQueue = new Queue;
222
dba7a1a8
VK
223 s_condUpdateMaps = ConditionCreate(FALSE);
224
926e8ce7 225 // Create "Entire Network" object
5039dede
AK
226 g_pEntireNet = new Network;
227 NetObjInsert(g_pEntireNet, FALSE);
228
926e8ce7 229 // Create "Service Root" object
5039dede
AK
230 g_pServiceRoot = new ServiceRoot;
231 NetObjInsert(g_pServiceRoot, FALSE);
232
926e8ce7 233 // Create "Template Root" object
5039dede
AK
234 g_pTemplateRoot = new TemplateRoot;
235 NetObjInsert(g_pTemplateRoot, FALSE);
a6d66d3a 236
926e8ce7 237 // Create "Policy Root" object
a6d66d3a
VK
238 g_pPolicyRoot = new PolicyRoot;
239 NetObjInsert(g_pPolicyRoot, FALSE);
240
926e8ce7 241 // Create "Network Maps Root" object
8a9913fa
VK
242 g_pMapRoot = new NetworkMapRoot;
243 NetObjInsert(g_pMapRoot, FALSE);
244
926e8ce7
VK
245 // Create "Dashboard Root" object
246 g_pDashboardRoot = new DashboardRoot;
247 NetObjInsert(g_pDashboardRoot, FALSE);
248
140b8ada 249 // Create "Business Service Root" object
1621a079
VK
250 g_pBusinessServiceRoot = new BusinessServiceRoot;
251 NetObjInsert(g_pBusinessServiceRoot, FALSE);
845b8121 252
35f836fe 253 DbgPrintf(1, _T("Built-in objects created"));
5039dede 254
140b8ada
VK
255 // Initialize service checks
256 SlmCheck::init();
257
5039dede
AK
258 // Start template update applying thread
259 ThreadCreate(ApplyTemplateThread, 0, NULL);
260}
261
dba7a1a8
VK
262/**
263 * Insert new object into network
264 */
5039dede
AK
265void NetObjInsert(NetObj *pObject, BOOL bNewObject)
266{
267 if (bNewObject)
268 {
269 // Assign unique ID to new object
eec253a8 270 pObject->setId(CreateUniqueId(IDG_NETWORK_OBJECT));
3f7c0fe4 271 pObject->generateGuid();
5039dede 272
d6124fa0 273 // Create tables for storing data collection values
c42b4551
VK
274 if ((pObject->getObjectClass() == OBJECT_NODE) ||
275 (pObject->getObjectClass() == OBJECT_MOBILEDEVICE) ||
276 (pObject->getObjectClass() == OBJECT_CLUSTER) ||
277 (pObject->getObjectClass() == OBJECT_ACCESSPOINT))
5039dede 278 {
35f836fe 279 TCHAR szQuery[256], szQueryTemplate[256];
967893bb 280 UINT32 i;
5039dede 281
35f836fe 282 MetaDataReadStr(_T("IDataTableCreationCommand"), szQueryTemplate, 255, _T(""));
c42b4551 283 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), szQueryTemplate, pObject->getId());
5039dede
AK
284 DBQuery(g_hCoreDB, szQuery);
285
286 for(i = 0; i < 10; i++)
287 {
35f836fe
VK
288 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("IDataIndexCreationCommand_%d"), i);
289 MetaDataReadStr(szQuery, szQueryTemplate, 255, _T(""));
5039dede
AK
290 if (szQueryTemplate[0] != 0)
291 {
c42b4551 292 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), szQueryTemplate, pObject->getId(), pObject->getId());
5039dede
AK
293 DBQuery(g_hCoreDB, szQuery);
294 }
295 }
d6124fa0 296
22aaa779
VK
297 for(i = 0; i < 10; i++)
298 {
299 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("TDataTableCreationCommand_%d"), i);
300 MetaDataReadStr(szQuery, szQueryTemplate, 255, _T(""));
301 if (szQueryTemplate[0] != 0)
302 {
c42b4551 303 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), szQueryTemplate, pObject->getId(), pObject->getId());
22aaa779
VK
304 DBQuery(g_hCoreDB, szQuery);
305 }
306 }
d6124fa0
VK
307
308 for(i = 0; i < 10; i++)
309 {
310 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("TDataIndexCreationCommand_%d"), i);
311 MetaDataReadStr(szQuery, szQueryTemplate, 255, _T(""));
312 if (szQueryTemplate[0] != 0)
313 {
c42b4551 314 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), szQueryTemplate, pObject->getId(), pObject->getId());
d6124fa0
VK
315 DBQuery(g_hCoreDB, szQuery);
316 }
317 }
318 }
5039dede 319 }
c42b4551 320 g_idxObjectById.put(pObject->getId(), pObject);
6ff21d27 321 if (!pObject->isDeleted())
5039dede 322 {
c42b4551 323 switch(pObject->getObjectClass())
5039dede
AK
324 {
325 case OBJECT_GENERIC:
326 case OBJECT_NETWORK:
327 case OBJECT_CONTAINER:
328 case OBJECT_SERVICEROOT:
329 case OBJECT_NETWORKSERVICE:
330 case OBJECT_TEMPLATE:
331 case OBJECT_TEMPLATEGROUP:
332 case OBJECT_TEMPLATEROOT:
bc980b27 333 case OBJECT_VPNCONNECTOR:
a6d66d3a
VK
334 case OBJECT_POLICYGROUP:
335 case OBJECT_POLICYROOT:
6d3ab9d2
VK
336 case OBJECT_AGENTPOLICY:
337 case OBJECT_AGENTPOLICY_CONFIG:
021dcda7
VK
338 case OBJECT_NETWORKMAPROOT:
339 case OBJECT_NETWORKMAPGROUP:
926e8ce7
VK
340 case OBJECT_DASHBOARDROOT:
341 case OBJECT_DASHBOARD:
1621a079
VK
342 case OBJECT_BUSINESSSERVICEROOT:
343 case OBJECT_BUSINESSSERVICE:
fc958888 344 case OBJECT_NODELINK:
8715a84c 345 case OBJECT_RACK:
9d605305 346 break;
889d7ff7 347 case OBJECT_NODE:
c42b4551 348 g_idxNodeById.put(pObject->getId(), pObject);
dbe28185
VK
349 if (!(((Node *)pObject)->getFlags() & NF_REMOTE_AGENT))
350 {
351 if (IsZoningEnabled())
352 {
353 Zone *zone = (Zone *)g_idxZoneByGUID.get(((Node *)pObject)->getZoneId());
354 if (zone != NULL)
355 {
356 zone->addToIndex((Node *)pObject);
357 }
358 else
359 {
360 DbgPrintf(2, _T("Cannot find zone object with GUID=%d for node object %s [%d]"),
c42b4551 361 (int)((Node *)pObject)->getZoneId(), pObject->getName(), (int)pObject->getId());
dbe28185
VK
362 }
363 }
364 else
365 {
c30c0c0f
VK
366 if (((Node *)pObject)->getIpAddress().isValidUnicast())
367 g_idxNodeByAddr.put(((Node *)pObject)->getIpAddress(), pObject);
dbe28185
VK
368 }
369 }
85ae39bc
VK
370 break;
371 case OBJECT_CLUSTER:
c42b4551 372 g_idxClusterById.put(pObject->getId(), pObject);
9aa67910
VK
373 break;
374 case OBJECT_MOBILEDEVICE:
c42b4551 375 g_idxMobileDeviceById.put(pObject->getId(), pObject);
c6afd26a
VK
376 break;
377 case OBJECT_ACCESSPOINT:
c42b4551 378 g_idxAccessPointById.put(pObject->getId(), pObject);
edecb8ef 379 MacDbAddAccessPoint((AccessPoint *)pObject);
5039dede
AK
380 break;
381 case OBJECT_SUBNET:
c30c0c0f 382 if (((Subnet *)pObject)->getIpAddress().isValidUnicast())
5039dede 383 {
89135050 384 if (IsZoningEnabled())
5e39b8a3
VK
385 {
386 Zone *zone = (Zone *)g_idxZoneByGUID.get(((Subnet *)pObject)->getZoneId());
387 if (zone != NULL)
388 {
389 zone->addToIndex((Subnet *)pObject);
390 }
391 else
392 {
393 DbgPrintf(2, _T("Cannot find zone object with GUID=%d for subnet object %s [%d]"),
c42b4551 394 (int)((Subnet *)pObject)->getZoneId(), pObject->getName(), (int)pObject->getId());
5e39b8a3
VK
395 }
396 }
397 else
398 {
c30c0c0f 399 g_idxSubnetByAddr.put(((Subnet *)pObject)->getIpAddress(), pObject);
5e39b8a3 400 }
5039dede 401 if (bNewObject)
c30c0c0f
VK
402 {
403 PostEvent(EVENT_SUBNET_ADDED, g_dwMgmtNode, "isAd", pObject->getId(), pObject->getName(),
404 &((Subnet *)pObject)->getIpAddress(), ((Subnet *)pObject)->getIpAddress().getMaskBits());
405 }
5039dede
AK
406 }
407 break;
5039dede 408 case OBJECT_INTERFACE:
c30c0c0f 409 if (!((Interface *)pObject)->isExcludedFromTopology())
5039dede 410 {
89135050 411 if (IsZoningEnabled())
4ecd55b3
VK
412 {
413 Zone *zone = (Zone *)g_idxZoneByGUID.get(((Interface *)pObject)->getZoneId());
414 if (zone != NULL)
415 {
416 zone->addToIndex((Interface *)pObject);
417 }
418 else
419 {
420 DbgPrintf(2, _T("Cannot find zone object with GUID=%d for interface object %s [%d]"),
c42b4551 421 (int)((Interface *)pObject)->getZoneId(), pObject->getName(), (int)pObject->getId());
4ecd55b3
VK
422 }
423 }
424 else
425 {
c30c0c0f 426 g_idxInterfaceByAddr.put(((Interface *)pObject)->getIpAddressList(), pObject);
4ecd55b3 427 }
5039dede 428 }
edecb8ef 429 MacDbAddInterface((Interface *)pObject);
5039dede
AK
430 break;
431 case OBJECT_ZONE:
9d605305 432 g_idxZoneByGUID.put(((Zone *)pObject)->getZoneId(), pObject);
5039dede
AK
433 break;
434 case OBJECT_CONDITION:
c42b4551 435 g_idxConditionById.put(pObject->getId(), pObject);
6ff21d27
VK
436 break;
437 case OBJECT_SLMCHECK:
c42b4551 438 g_idxServiceCheckById.put(pObject->getId(), pObject);
dba7a1a8
VK
439 break;
440 case OBJECT_NETWORKMAP:
c42b4551 441 g_idxNetMapById.put(pObject->getId(), pObject);
5039dede
AK
442 break;
443 default:
496390c2
VK
444 {
445 bool processed = false;
967893bb 446 for(UINT32 i = 0; i < g_dwNumModules; i++)
496390c2
VK
447 {
448 if (g_pModuleList[i].pfNetObjInsert != NULL)
449 {
450 if (g_pModuleList[i].pfNetObjInsert(pObject))
451 processed = true;
452 }
453 }
454 if (!processed)
c42b4551 455 nxlog_write(MSG_BAD_NETOBJ_TYPE, EVENTLOG_ERROR_TYPE, "d", pObject->getObjectClass());
496390c2 456 }
5039dede
AK
457 break;
458 }
459 }
5039dede 460
95171c4b 461 // Notify modules about object creation
dba7a1a8
VK
462 if (bNewObject)
463 {
a0efa7b5 464 CALL_ALL_MODULES(pfPostObjectCreate, (pObject));
dba7a1a8 465 }
3ef332c7
VK
466 else
467 {
468 CALL_ALL_MODULES(pfPostObjectLoad, (pObject));
469 }
dba7a1a8 470}
5039dede 471
dba7a1a8
VK
472/**
473 * Delete object from indexes
474 * If object has an IP address, this function will delete it from
475 * appropriate index. Normally this function should be called from
98de9b1f 476 * NetObj::deleteObject() method.
dba7a1a8 477 */
5039dede
AK
478void NetObjDeleteFromIndexes(NetObj *pObject)
479{
c42b4551 480 switch(pObject->getObjectClass())
5039dede
AK
481 {
482 case OBJECT_GENERIC:
483 case OBJECT_NETWORK:
484 case OBJECT_CONTAINER:
485 case OBJECT_SERVICEROOT:
486 case OBJECT_NETWORKSERVICE:
487 case OBJECT_TEMPLATE:
488 case OBJECT_TEMPLATEGROUP:
489 case OBJECT_TEMPLATEROOT:
bc980b27 490 case OBJECT_VPNCONNECTOR:
a6d66d3a
VK
491 case OBJECT_POLICYGROUP:
492 case OBJECT_POLICYROOT:
6d3ab9d2
VK
493 case OBJECT_AGENTPOLICY:
494 case OBJECT_AGENTPOLICY_CONFIG:
021dcda7
VK
495 case OBJECT_NETWORKMAPROOT:
496 case OBJECT_NETWORKMAPGROUP:
926e8ce7
VK
497 case OBJECT_DASHBOARDROOT:
498 case OBJECT_DASHBOARD:
1621a079
VK
499 case OBJECT_BUSINESSSERVICEROOT:
500 case OBJECT_BUSINESSSERVICE:
fc958888 501 case OBJECT_NODELINK:
8715a84c 502 case OBJECT_RACK:
9d605305 503 break;
889d7ff7 504 case OBJECT_NODE:
c42b4551 505 g_idxNodeById.remove(pObject->getId());
dbe28185
VK
506 if (!(((Node *)pObject)->getFlags() & NF_REMOTE_AGENT))
507 {
508 if (IsZoningEnabled())
509 {
510 Zone *zone = (Zone *)g_idxZoneByGUID.get(((Node *)pObject)->getZoneId());
511 if (zone != NULL)
512 {
513 zone->removeFromIndex((Node *)pObject);
514 }
515 else
516 {
517 DbgPrintf(2, _T("Cannot find zone object with GUID=%d for node object %s [%d]"),
c42b4551 518 (int)((Node *)pObject)->getZoneId(), pObject->getName(), (int)pObject->getId());
dbe28185
VK
519 }
520 }
521 else
522 {
c30c0c0f
VK
523 if (((Node *)pObject)->getIpAddress().isValidUnicast())
524 g_idxNodeByAddr.remove(((Node *)pObject)->getIpAddress());
dbe28185
VK
525 }
526 }
85ae39bc
VK
527 break;
528 case OBJECT_CLUSTER:
c42b4551 529 g_idxClusterById.remove(pObject->getId());
5039dede 530 break;
9aa67910 531 case OBJECT_MOBILEDEVICE:
c42b4551 532 g_idxMobileDeviceById.remove(pObject->getId());
c6afd26a
VK
533 break;
534 case OBJECT_ACCESSPOINT:
c42b4551 535 g_idxAccessPointById.remove(pObject->getId());
edecb8ef 536 MacDbRemove(((AccessPoint *)pObject)->getMacAddr());
9aa67910 537 break;
5039dede 538 case OBJECT_SUBNET:
c30c0c0f 539 if (((Subnet *)pObject)->getIpAddress().isValidUnicast())
5039dede 540 {
89135050 541 if (IsZoningEnabled())
4ecd55b3
VK
542 {
543 Zone *zone = (Zone *)g_idxZoneByGUID.get(((Subnet *)pObject)->getZoneId());
544 if (zone != NULL)
545 {
546 zone->removeFromIndex((Subnet *)pObject);
547 }
548 else
549 {
550 DbgPrintf(2, _T("Cannot find zone object with GUID=%d for subnet object %s [%d]"),
c42b4551 551 (int)((Subnet *)pObject)->getZoneId(), pObject->getName(), (int)pObject->getId());
4ecd55b3
VK
552 }
553 }
554 else
555 {
c30c0c0f 556 g_idxSubnetByAddr.remove(((Subnet *)pObject)->getIpAddress());
4ecd55b3 557 }
5039dede
AK
558 }
559 break;
5039dede 560 case OBJECT_INTERFACE:
c30c0c0f
VK
561 if (IsZoningEnabled())
562 {
563 Zone *zone = (Zone *)g_idxZoneByGUID.get(((Interface *)pObject)->getZoneId());
564 if (zone != NULL)
9d605305 565 {
c30c0c0f 566 zone->removeFromIndex((Interface *)pObject);
4ecd55b3
VK
567 }
568 else
569 {
c30c0c0f
VK
570 DbgPrintf(2, _T("Cannot find zone object with GUID=%d for interface object %s [%d]"),
571 (int)((Interface *)pObject)->getZoneId(), pObject->getName(), (int)pObject->getId());
9d605305 572 }
c30c0c0f
VK
573 }
574 else
575 {
576 const ObjectArray<InetAddress> *list = ((Interface *)pObject)->getIpAddressList()->getList();
577 for(int i = 0; i < list->size(); i++)
578 {
579 InetAddress *addr = list->get(i);
580 if (addr->isValidUnicast())
581 {
582 NetObj *o = g_idxInterfaceByAddr.get(*addr);
583 if ((o != NULL) && (o->getId() == pObject->getId()))
584 {
585 g_idxInterfaceByAddr.remove(*addr);
586 }
587 }
588 }
589 }
edecb8ef 590 MacDbRemove(((Interface *)pObject)->getMacAddr());
5039dede
AK
591 break;
592 case OBJECT_ZONE:
9d605305 593 g_idxZoneByGUID.remove(((Zone *)pObject)->getZoneId());
5039dede
AK
594 break;
595 case OBJECT_CONDITION:
c42b4551 596 g_idxConditionById.remove(pObject->getId());
5039dede 597 break;
6ff21d27 598 case OBJECT_SLMCHECK:
c42b4551 599 g_idxServiceCheckById.remove(pObject->getId());
dba7a1a8
VK
600 break;
601 case OBJECT_NETWORKMAP:
c42b4551 602 g_idxNetMapById.remove(pObject->getId());
6ff21d27 603 break;
5039dede 604 default:
496390c2
VK
605 {
606 bool processed = false;
967893bb 607 for(UINT32 i = 0; i < g_dwNumModules; i++)
496390c2
VK
608 {
609 if (g_pModuleList[i].pfNetObjDelete != NULL)
610 {
611 if (g_pModuleList[i].pfNetObjDelete(pObject))
612 processed = true;
613 }
614 }
615 if (!processed)
c42b4551 616 nxlog_write(MSG_BAD_NETOBJ_TYPE, EVENTLOG_ERROR_TYPE, "d", pObject->getObjectClass());
496390c2 617 }
5039dede
AK
618 break;
619 }
620}
621
c6afd26a
VK
622/**
623 * Find access point by MAC address
624 */
625AccessPoint NXCORE_EXPORTABLE *FindAccessPointByMAC(const BYTE *macAddr)
626{
627 if (!memcmp(macAddr, "\x00\x00\x00\x00\x00\x00", 6))
628 return NULL;
629
edecb8ef 630 NetObj *object = MacDbFind(macAddr);
c42b4551 631 return ((object != NULL) && (object->getObjectClass() == OBJECT_ACCESSPOINT)) ? (AccessPoint *)object : NULL;
c6afd26a
VK
632}
633
634/**
635 * Mobile device id comparator
534e1b83
VK
636 */
637static bool DeviceIdComparator(NetObj *object, void *deviceId)
638{
c42b4551 639 return ((object->getObjectClass() == OBJECT_MOBILEDEVICE) && !object->isDeleted() &&
534e1b83
VK
640 !_tcscmp((const TCHAR *)deviceId, ((MobileDevice *)object)->getDeviceId()));
641}
5039dede 642
c6afd26a
VK
643/**
644 * Find mobile device by device ID
645 */
534e1b83
VK
646MobileDevice NXCORE_EXPORTABLE *FindMobileDeviceByDeviceID(const TCHAR *deviceId)
647{
648 if ((deviceId == NULL) || (*deviceId == 0))
649 return NULL;
650
651 return (MobileDevice *)g_idxMobileDeviceById.find(DeviceIdComparator, (void *)deviceId);
652}
5039dede 653
534e1b83
VK
654/**
655 * Find node by IP address
656 */
c75e9ee4 657Node NXCORE_EXPORTABLE *FindNodeByIP(UINT32 zoneId, const InetAddress& ipAddr)
5039dede 658{
c75e9ee4 659 if (!ipAddr.isValidUnicast())
5039dede
AK
660 return NULL;
661
16d6f798
VK
662 Zone *zone = IsZoningEnabled() ? (Zone *)g_idxZoneByGUID.get(zoneId) : NULL;
663
664 Node *node = NULL;
665 if (IsZoningEnabled())
666 {
667 if (zone != NULL)
668 {
669 node = zone->getNodeByAddr(ipAddr);
670 }
671 }
672 else
673 {
674 node = (Node *)g_idxNodeByAddr.get(ipAddr);
675 }
676 if (node != NULL)
677 return node;
678
89135050
VK
679 Interface *iface = NULL;
680 if (IsZoningEnabled())
681 {
89135050
VK
682 if (zone != NULL)
683 {
684 iface = zone->getInterfaceByAddr(ipAddr);
685 }
686 }
687 else
688 {
689 iface = (Interface *)g_idxInterfaceByAddr.get(ipAddr);
690 }
9d605305 691 return (iface != NULL) ? iface->getParentNode() : NULL;
5039dede
AK
692}
693
c30c0c0f
VK
694/**
695 * Find node by IP address using first match from IP address list
696 */
697Node NXCORE_EXPORTABLE *FindNodeByIP(UINT32 zoneId, const InetAddressList *ipAddrList)
698{
699 for(int i = 0; i < ipAddrList->size(); i++)
700 {
701 Node *node = FindNodeByIP(zoneId, ipAddrList->get(i));
702 if (node != NULL)
703 return node;
704 }
705 return NULL;
706}
707
534e1b83
VK
708/**
709 * Find interface by IP address
710 */
c75e9ee4 711Interface NXCORE_EXPORTABLE *FindInterfaceByIP(UINT32 zoneId, const InetAddress& ipAddr)
80e0db05 712{
c75e9ee4 713 if (!ipAddr.isValidUnicast())
80e0db05
VK
714 return NULL;
715
716 Zone *zone = IsZoningEnabled() ? (Zone *)g_idxZoneByGUID.get(zoneId) : NULL;
717
718 Interface *iface = NULL;
719 if (IsZoningEnabled())
720 {
721 if (zone != NULL)
722 {
723 iface = zone->getInterfaceByAddr(ipAddr);
724 }
725 }
726 else
727 {
728 iface = (Interface *)g_idxInterfaceByAddr.get(ipAddr);
729 }
730 return iface;
731}
732
534e1b83
VK
733/**
734 * Find node by MAC address
735 */
06a93345
VK
736Node NXCORE_EXPORTABLE *FindNodeByMAC(const BYTE *macAddr)
737{
738 Interface *pInterface = FindInterfaceByMAC(macAddr);
739 return (pInterface != NULL) ? pInterface->getParentNode() : NULL;
740}
741
c6afd26a
VK
742/**
743 * Find interface by MAC address
744 */
06a93345 745Interface NXCORE_EXPORTABLE *FindInterfaceByMAC(const BYTE *macAddr)
630e15d6
VK
746{
747 if (!memcmp(macAddr, "\x00\x00\x00\x00\x00\x00", 6))
748 return NULL;
749
edecb8ef 750 NetObj *object = MacDbFind(macAddr);
c42b4551 751 return ((object != NULL) && (object->getObjectClass() == OBJECT_INTERFACE)) ? (Interface *)object : NULL;
630e15d6
VK
752}
753
534e1b83 754/**
c6afd26a 755 * Interface description comparator
534e1b83 756 */
9d605305
VK
757static bool DescriptionComparator(NetObj *object, void *description)
758{
c42b4551 759 return ((object->getObjectClass() == OBJECT_INTERFACE) && !object->isDeleted() &&
9d605305
VK
760 !_tcscmp((const TCHAR *)description, ((Interface *)object)->getDescription()));
761}
762
c6afd26a
VK
763/**
764 * Find interface by description
765 */
478d4ff4
VK
766Interface NXCORE_EXPORTABLE *FindInterfaceByDescription(const TCHAR *description)
767{
9d605305 768 return (Interface *)g_idxObjectById.find(DescriptionComparator, (void *)description);
478d4ff4
VK
769}
770
c6afd26a
VK
771/**
772 * LLDP ID comparator
773 */
9d605305
VK
774static bool LldpIdComparator(NetObj *object, void *lldpId)
775{
776 const TCHAR *id = ((Node *)object)->getLLDPNodeId();
777 return (id != NULL) && !_tcscmp(id, (const TCHAR *)lldpId);
778}
779
c6afd26a
VK
780/**
781 * Find node by LLDP ID
782 */
eec253a8
VK
783Node NXCORE_EXPORTABLE *FindNodeByLLDPId(const TCHAR *lldpId)
784{
9d605305 785 return (Node *)g_idxNodeById.find(LldpIdComparator, (void *)lldpId);
eec253a8
VK
786}
787
4005181b
VK
788/**
789 * Bridge ID comparator
790 */
791static bool BridgeIdComparator(NetObj *object, void *bridgeId)
792{
793 return ((Node *)object)->isBridge() && !memcmp(((Node *)object)->getBridgeId(), bridgeId, MAC_ADDR_LENGTH);
794}
795
796/**
797 * Find node by bridge ID (bridge base address)
798 */
799Node NXCORE_EXPORTABLE *FindNodeByBridgeId(const BYTE *bridgeId)
800{
801 return (Node *)g_idxNodeById.find(BridgeIdComparator, (void *)bridgeId);
802}
803
70ffb771
VK
804/**
805 * Find subnet by IP address
806 */
c75e9ee4 807Subnet NXCORE_EXPORTABLE *FindSubnetByIP(UINT32 zoneId, const InetAddress& ipAddr)
5039dede 808{
c75e9ee4 809 if (!ipAddr.isValidUnicast())
5039dede 810 return NULL;
89135050
VK
811
812 Subnet *subnet = NULL;
813 if (IsZoningEnabled())
814 {
815 Zone *zone = (Zone *)g_idxZoneByGUID.get(zoneId);
816 if (zone != NULL)
817 {
818 subnet = zone->getSubnetByAddr(ipAddr);
819 }
820 }
821 else
822 {
823 subnet = (Subnet *)g_idxSubnetByAddr.get(ipAddr);
824 }
825 return subnet;
5039dede
AK
826}
827
8715a84c 828/**
c77af5aa 829 * Subnet matching data
8715a84c 830 */
c77af5aa 831struct SUBNET_MATCHING_DATA
5039dede 832{
c75e9ee4
VK
833 InetAddress ipAddr; // IP address to find subnet for
834 int maskLen; // Current match mask length
835 Subnet *subnet; // search result
c77af5aa
VK
836};
837
838/**
839 * Subnet matching callback
840 */
c30c0c0f 841static void SubnetMatchCallback(const InetAddress& addr, NetObj *object, void *arg)
c77af5aa
VK
842{
843 SUBNET_MATCHING_DATA *data = (SUBNET_MATCHING_DATA *)arg;
c75e9ee4 844 if (((Subnet *)object)->getIpAddress().contain(data->ipAddr))
c77af5aa 845 {
c75e9ee4 846 int maskLen = ((Subnet *)object)->getIpAddress().getMaskBits();
c77af5aa
VK
847 if (maskLen > data->maskLen)
848 {
849 data->maskLen = maskLen;
850 data->subnet = (Subnet *)object;
851 }
852 }
9d605305 853}
5039dede 854
8715a84c
VK
855/**
856 * Find subnet for given IP address
857 */
c75e9ee4 858Subnet NXCORE_EXPORTABLE *FindSubnetForNode(UINT32 zoneId, const InetAddress& nodeAddr)
9d605305 859{
c75e9ee4 860 if (!nodeAddr.isValidUnicast())
5039dede 861 return NULL;
89135050 862
c77af5aa 863 SUBNET_MATCHING_DATA matchData;
c75e9ee4 864 matchData.ipAddr = nodeAddr;
c77af5aa
VK
865 matchData.maskLen = -1;
866 matchData.subnet = NULL;
89135050
VK
867 if (IsZoningEnabled())
868 {
869 Zone *zone = (Zone *)g_idxZoneByGUID.get(zoneId);
870 if (zone != NULL)
871 {
c77af5aa 872 zone->forEachSubnet(SubnetMatchCallback, &matchData);
89135050
VK
873 }
874 }
875 else
876 {
c77af5aa 877 g_idxSubnetByAddr.forEach(SubnetMatchCallback, &matchData);
89135050 878 }
c77af5aa 879 return matchData.subnet;
5039dede
AK
880}
881
5db0d494
VK
882/**
883 * Find object by ID
884 */
967893bb 885NetObj NXCORE_EXPORTABLE *FindObjectById(UINT32 dwId, int objClass)
5039dede 886{
6adc4a1a
VK
887 NetObj *object = g_idxObjectById.get(dwId);
888 if ((object == NULL) || (objClass == -1))
889 return object;
c42b4551 890 return (objClass == object->getObjectClass()) ? object : NULL;
5039dede
AK
891}
892
fffcff95
VK
893/**
894 * Get object name by ID
895 */
896const TCHAR NXCORE_EXPORTABLE *GetObjectName(DWORD id, const TCHAR *defaultName)
897{
898 NetObj *object = g_idxObjectById.get(id);
c42b4551 899 return (object != NULL) ? object->getName() : defaultName;
fffcff95
VK
900}
901
5db0d494
VK
902/**
903 * Callback data for FindObjectByName
904 */
6aba3998 905struct __find_object_data
5039dede 906{
6aba3998
VK
907 int objClass;
908 const TCHAR *name;
909};
5039dede 910
5db0d494
VK
911/**
912 * Object name comparator for FindObjectByName
913 */
6aba3998
VK
914static bool ObjectNameComparator(NetObj *object, void *data)
915{
916 struct __find_object_data *fd = (struct __find_object_data *)data;
c42b4551
VK
917 return ((fd->objClass == -1) || (fd->objClass == object->getObjectClass())) &&
918 !object->isDeleted() && !_tcsicmp(object->getName(), fd->name);
6aba3998 919}
5039dede 920
5db0d494
VK
921/**
922 * Find object by name
923 */
6aba3998
VK
924NetObj NXCORE_EXPORTABLE *FindObjectByName(const TCHAR *name, int objClass)
925{
926 struct __find_object_data data;
927
928 data.objClass = objClass;
929 data.name = name;
930 return g_idxObjectById.find(ObjectNameComparator, &data);
5039dede
AK
931}
932
5db0d494
VK
933/**
934 * GUID comparator for FindObjectByGUID
935 */
6aba3998 936static bool ObjectGuidComparator(NetObj *object, void *data)
1f385e47 937{
4e5e861c 938 return !object->isDeleted() && object->getGuid().equals(*((const uuid *)data));
6aba3998 939}
1f385e47 940
5db0d494
VK
941/**
942 * Find object by GUID
943 */
de4af576 944NetObj NXCORE_EXPORTABLE *FindObjectByGUID(const uuid& guid, int objClass)
6aba3998 945{
de4af576 946 NetObj *object = g_idxObjectById.find(ObjectGuidComparator, (void *)&guid);
c42b4551 947 return (object != NULL) ? (((objClass == -1) || (objClass == object->getObjectClass())) ? object : NULL) : NULL;
1f385e47
VK
948}
949
5db0d494
VK
950/**
951 * Template name comparator for FindTemplateByName
952 */
9d605305 953static bool TemplateNameComparator(NetObj *object, void *name)
5039dede 954{
c42b4551 955 return (object->getObjectClass() == OBJECT_TEMPLATE) && !object->isDeleted() && !_tcsicmp(object->getName(), (const TCHAR *)name);
9d605305 956}
5039dede 957
5db0d494
VK
958/**
959 * Find template object by name
960 */
9d605305
VK
961Template NXCORE_EXPORTABLE *FindTemplateByName(const TCHAR *pszName)
962{
963 return (Template *)g_idxObjectById.find(TemplateNameComparator, (void *)pszName);
5039dede
AK
964}
965
c75e9ee4
VK
966/**
967 * Callback for FindClusterByResourceIP
968 */
9d605305
VK
969static bool ClusterResourceIPComparator(NetObj *object, void *ipAddr)
970{
c75e9ee4 971 return (object->getObjectClass() == OBJECT_CLUSTER) && !object->isDeleted() && ((Cluster *)object)->isVirtualAddr(*((const InetAddress *)ipAddr));
9d605305
VK
972}
973
c75e9ee4
VK
974/**
975 * Find cluster by resource IP
976 */
977Cluster NXCORE_EXPORTABLE *FindClusterByResourceIP(const InetAddress& ipAddr)
85f1fea1 978{
c75e9ee4 979 return (Cluster *)g_idxObjectById.find(ClusterResourceIPComparator, (void *)&ipAddr);
85f1fea1
VK
980}
981
c6afd26a
VK
982/**
983 * Data structure for IsClusterIP callback
984 */
89135050
VK
985struct __cluster_ip_data
986{
c75e9ee4 987 InetAddress ipAddr;
967893bb 988 UINT32 zoneId;
89135050
VK
989};
990
c6afd26a
VK
991/**
992 * Cluster IP comparator - returns true if given address in given zone is cluster IP address
993 */
89135050 994static bool ClusterIPComparator(NetObj *object, void *data)
9d605305 995{
89135050 996 struct __cluster_ip_data *d = (struct __cluster_ip_data *)data;
c42b4551 997 return (object->getObjectClass() == OBJECT_CLUSTER) && !object->isDeleted() &&
89135050
VK
998 (((Cluster *)object)->getZoneId() == d->zoneId) &&
999 (((Cluster *)object)->isVirtualAddr(d->ipAddr) ||
1000 ((Cluster *)object)->isSyncAddr(d->ipAddr));
9d605305
VK
1001}
1002
c6afd26a
VK
1003/**
1004 * Check if given IP address is used by cluster (it's either
1005 * resource IP or located on one of sync subnets)
1006 */
c75e9ee4 1007bool NXCORE_EXPORTABLE IsClusterIP(UINT32 zoneId, const InetAddress& ipAddr)
85f1fea1 1008{
89135050
VK
1009 struct __cluster_ip_data data;
1010 data.zoneId = zoneId;
1011 data.ipAddr = ipAddr;
1012 return g_idxObjectById.find(ClusterIPComparator, &data) != NULL;
85f1fea1
VK
1013}
1014
8715a84c
VK
1015/**
1016 * Find zone object by GUID
1017 */
967893bb 1018Zone NXCORE_EXPORTABLE *FindZoneByGUID(UINT32 dwZoneGUID)
5039dede 1019{
9d605305 1020 return (Zone *)g_idxZoneByGUID.get(dwZoneGUID);
5039dede
AK
1021}
1022
8715a84c
VK
1023/**
1024 * Object comparator for FindLocalMgmtNode()
1025 */
9d605305
VK
1026static bool LocalMgmtNodeComparator(NetObj *object, void *data)
1027{
1028 return (((Node *)object)->getFlags() & NF_IS_LOCAL_MGMT) ? true : false;
1029}
1030
8715a84c
VK
1031/**
1032 * Find local management node ID
1033 */
967893bb 1034UINT32 FindLocalMgmtNode()
5039dede 1035{
9d605305 1036 NetObj *object = g_idxNodeById.find(LocalMgmtNodeComparator, NULL);
c42b4551 1037 return (object != NULL) ? object->getId() : 0;
9d605305 1038}
5039dede 1039
8715a84c
VK
1040/**
1041 * ObjectIndex::forEach callback which recalculates object's status
1042 */
9d605305
VK
1043static void RecalcStatusCallback(NetObj *object, void *data)
1044{
27f9598d 1045 object->calculateCompoundStatus();
9d605305
VK
1046}
1047
8715a84c
VK
1048/**
1049 * ObjectIndex::forEach callback which links container child objects
1050 */
9d605305
VK
1051static void LinkChildObjectsCallback(NetObj *object, void *data)
1052{
c42b4551
VK
1053 if ((object->getObjectClass() == OBJECT_CONTAINER) ||
1054 (object->getObjectClass() == OBJECT_RACK) ||
1055 (object->getObjectClass() == OBJECT_TEMPLATEGROUP) ||
1056 (object->getObjectClass() == OBJECT_POLICYGROUP) ||
1057 (object->getObjectClass() == OBJECT_NETWORKMAPGROUP) ||
1058 (object->getObjectClass() == OBJECT_DASHBOARD) ||
1059 (object->getObjectClass() == OBJECT_BUSINESSSERVICE) ||
1060 (object->getObjectClass() == OBJECT_NODELINK))
9d605305 1061 {
926e8ce7 1062 ((Container *)object)->linkChildObjects();
9d605305 1063 }
5039dede
AK
1064}
1065
496390c2
VK
1066/**
1067 * Load objects from database at stratup
1068 */
bc980b27 1069BOOL LoadObjects()
5039dede
AK
1070{
1071 DB_RESULT hResult;
967893bb
VK
1072 UINT32 i, dwNumRows;
1073 UINT32 dwId;
5039dede 1074 Template *pTemplate;
35f836fe 1075 TCHAR szQuery[256];
5039dede
AK
1076
1077 // Prevent objects to change it's modification flag
1078 g_bModificationsLocked = TRUE;
1079
1080 // Load container categories
35f836fe
VK
1081 DbgPrintf(2, _T("Loading container categories..."));
1082 hResult = DBSelect(g_hCoreDB, _T("SELECT category,name,image_id,description FROM container_categories"));
5039dede
AK
1083 if (hResult != NULL)
1084 {
1085 g_dwNumCategories = DBGetNumRows(hResult);
1086 g_pContainerCatList = (CONTAINER_CATEGORY *)malloc(sizeof(CONTAINER_CATEGORY) * g_dwNumCategories);
1087 for(i = 0; i < (int)g_dwNumCategories; i++)
1088 {
1089 g_pContainerCatList[i].dwCatId = DBGetFieldULong(hResult, i, 0);
1090 DBGetField(hResult, i, 1, g_pContainerCatList[i].szName, MAX_OBJECT_NAME);
1091 g_pContainerCatList[i].dwImageId = DBGetFieldULong(hResult, i, 2);
1092 g_pContainerCatList[i].pszDescription = DBGetField(hResult, i, 3, NULL, 0);
1093 DecodeSQLString(g_pContainerCatList[i].pszDescription);
1094 }
1095 DBFreeResult(hResult);
1096 }
1097
1098 // Load built-in object properties
35f836fe 1099 DbgPrintf(2, _T("Loading built-in object properties..."));
5039dede
AK
1100 g_pEntireNet->LoadFromDB();
1101 g_pServiceRoot->LoadFromDB();
1102 g_pTemplateRoot->LoadFromDB();
a6d66d3a 1103 g_pPolicyRoot->LoadFromDB();
8a9913fa 1104 g_pMapRoot->LoadFromDB();
926e8ce7 1105 g_pDashboardRoot->LoadFromDB();
1621a079 1106 g_pBusinessServiceRoot->LoadFromDB();
5039dede
AK
1107
1108 // Load zones
c8076b19 1109 if (g_flags & AF_ENABLE_ZONING)
5039dede
AK
1110 {
1111 Zone *pZone;
1112
35f836fe 1113 DbgPrintf(2, _T("Loading zones..."));
5039dede
AK
1114
1115 // Load (or create) default zone
1116 pZone = new Zone;
fe400f32 1117 pZone->generateGuid();
c42b4551 1118 pZone->loadFromDatabase(BUILTIN_OID_ZONE0);
5039dede
AK
1119 NetObjInsert(pZone, FALSE);
1120 g_pEntireNet->AddZone(pZone);
1121
35f836fe 1122 hResult = DBSelect(g_hCoreDB, _T("SELECT id FROM zones WHERE id<>4"));
5039dede
AK
1123 if (hResult != 0)
1124 {
1125 dwNumRows = DBGetNumRows(hResult);
1126 for(i = 0; i < dwNumRows; i++)
1127 {
1128 dwId = DBGetFieldULong(hResult, i, 0);
1129 pZone = new Zone;
c42b4551 1130 if (pZone->loadFromDatabase(dwId))
5039dede 1131 {
6ff21d27 1132 if (!pZone->isDeleted())
5039dede
AK
1133 g_pEntireNet->AddZone(pZone);
1134 NetObjInsert(pZone, FALSE); // Insert into indexes
1135 }
1136 else // Object load failed
1137 {
1138 delete pZone;
1139 nxlog_write(MSG_ZONE_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
1140 }
1141 }
1142 DBFreeResult(hResult);
1143 }
1144 }
1145
1146 // Load conditions
1147 // We should load conditions before nodes because
1148 // DCI cache size calculation uses information from condition objects
35f836fe
VK
1149 DbgPrintf(2, _T("Loading conditions..."));
1150 hResult = DBSelect(g_hCoreDB, _T("SELECT id FROM conditions"));
5039dede
AK
1151 if (hResult != NULL)
1152 {
1153 Condition *pCondition;
1154
1155 dwNumRows = DBGetNumRows(hResult);
1156 for(i = 0; i < dwNumRows; i++)
1157 {
1158 dwId = DBGetFieldULong(hResult, i, 0);
1159 pCondition = new Condition;
c42b4551 1160 if (pCondition->loadFromDatabase(dwId))
5039dede
AK
1161 {
1162 NetObjInsert(pCondition, FALSE); // Insert into indexes
1163 }
1164 else // Object load failed
1165 {
1166 delete pCondition;
1167 nxlog_write(MSG_CONDITION_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
1168 }
1169 }
1170 DBFreeResult(hResult);
1171 }
1172
1173 // Load subnets
35f836fe
VK
1174 DbgPrintf(2, _T("Loading subnets..."));
1175 hResult = DBSelect(g_hCoreDB, _T("SELECT id FROM subnets"));
5039dede
AK
1176 if (hResult != 0)
1177 {
1178 Subnet *pSubnet;
1179
1180 dwNumRows = DBGetNumRows(hResult);
1181 for(i = 0; i < dwNumRows; i++)
1182 {
1183 dwId = DBGetFieldULong(hResult, i, 0);
1184 pSubnet = new Subnet;
c42b4551 1185 if (pSubnet->loadFromDatabase(dwId))
5039dede 1186 {
6ff21d27 1187 if (!pSubnet->isDeleted())
5039dede 1188 {
c8076b19 1189 if (g_flags & AF_ENABLE_ZONING)
5039dede
AK
1190 {
1191 Zone *pZone;
1192
52c31148 1193 pZone = FindZoneByGUID(pSubnet->getZoneId());
5039dede 1194 if (pZone != NULL)
52c31148 1195 pZone->addSubnet(pSubnet);
5039dede
AK
1196 }
1197 else
1198 {
1199 g_pEntireNet->AddSubnet(pSubnet);
1200 }
1201 }
1202 NetObjInsert(pSubnet, FALSE); // Insert into indexes
1203 }
1204 else // Object load failed
1205 {
1206 delete pSubnet;
1207 nxlog_write(MSG_SUBNET_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
1208 }
1209 }
1210 DBFreeResult(hResult);
1211 }
1212
9aa67910
VK
1213 // Load mobile devices
1214 DbgPrintf(2, _T("Loading mobile devices..."));
1215 hResult = DBSelect(g_hCoreDB, _T("SELECT id FROM mobile_devices"));
1216 if (hResult != 0)
1217 {
1218 MobileDevice *md;
1219
1220 dwNumRows = DBGetNumRows(hResult);
1221 for(i = 0; i < dwNumRows; i++)
1222 {
1223 dwId = DBGetFieldULong(hResult, i, 0);
1224 md = new MobileDevice;
c42b4551 1225 if (md->loadFromDatabase(dwId))
9aa67910
VK
1226 {
1227 NetObjInsert(md, FALSE); // Insert into indexes
1228 }
1229 else // Object load failed
1230 {
1231 delete md;
1232 nxlog_write(MSG_MOBILEDEVICE_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
1233 }
1234 }
1235 DBFreeResult(hResult);
1236 }
1237
5039dede 1238 // Load nodes
35f836fe
VK
1239 DbgPrintf(2, _T("Loading nodes..."));
1240 hResult = DBSelect(g_hCoreDB, _T("SELECT id FROM nodes"));
85ae39bc 1241 if (hResult != NULL)
5039dede
AK
1242 {
1243 Node *pNode;
1244
1245 dwNumRows = DBGetNumRows(hResult);
1246 for(i = 0; i < dwNumRows; i++)
1247 {
1248 dwId = DBGetFieldULong(hResult, i, 0);
1249 pNode = new Node;
c42b4551 1250 if (pNode->loadFromDatabase(dwId))
5039dede
AK
1251 {
1252 NetObjInsert(pNode, FALSE); // Insert into indexes
1253 }
1254 else // Object load failed
1255 {
1256 delete pNode;
1257 nxlog_write(MSG_NODE_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
1258 }
1259 }
1260 DBFreeResult(hResult);
5039dede
AK
1261 }
1262
8715a84c
VK
1263 // Load access points
1264 DbgPrintf(2, _T("Loading access points..."));
1265 hResult = DBSelect(g_hCoreDB, _T("SELECT id FROM access_points"));
85ae39bc 1266 if (hResult != NULL)
8715a84c
VK
1267 {
1268 AccessPoint *ap;
1269
1270 dwNumRows = DBGetNumRows(hResult);
1271 for(i = 0; i < dwNumRows; i++)
1272 {
1273 dwId = DBGetFieldULong(hResult, i, 0);
1274 ap = new AccessPoint;
c42b4551 1275 if (ap->loadFromDatabase(dwId))
8715a84c
VK
1276 {
1277 NetObjInsert(ap, FALSE); // Insert into indexes
1278 }
1279 else // Object load failed
1280 {
1281 nxlog_write(MSG_AP_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
1282 delete ap;
1283 }
1284 }
1285 DBFreeResult(hResult);
1286 }
1287
5039dede 1288 // Load interfaces
35f836fe
VK
1289 DbgPrintf(2, _T("Loading interfaces..."));
1290 hResult = DBSelect(g_hCoreDB, _T("SELECT id FROM interfaces"));
5039dede
AK
1291 if (hResult != 0)
1292 {
1293 Interface *pInterface;
1294
1295 dwNumRows = DBGetNumRows(hResult);
1296 for(i = 0; i < dwNumRows; i++)
1297 {
1298 dwId = DBGetFieldULong(hResult, i, 0);
1299 pInterface = new Interface;
c42b4551 1300 if (pInterface->loadFromDatabase(dwId))
5039dede
AK
1301 {
1302 NetObjInsert(pInterface, FALSE); // Insert into indexes
1303 }
1304 else // Object load failed
1305 {
5039dede 1306 nxlog_write(MSG_INTERFACE_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
478d4ff4 1307 delete pInterface;
5039dede
AK
1308 }
1309 }
1310 DBFreeResult(hResult);
1311 }
1312
1313 // Load network services
35f836fe
VK
1314 DbgPrintf(2, _T("Loading network services..."));
1315 hResult = DBSelect(g_hCoreDB, _T("SELECT id FROM network_services"));
5039dede
AK
1316 if (hResult != 0)
1317 {
1318 NetworkService *pService;
1319
1320 dwNumRows = DBGetNumRows(hResult);
1321 for(i = 0; i < dwNumRows; i++)
1322 {
1323 dwId = DBGetFieldULong(hResult, i, 0);
1324 pService = new NetworkService;
c42b4551 1325 if (pService->loadFromDatabase(dwId))
5039dede
AK
1326 {
1327 NetObjInsert(pService, FALSE); // Insert into indexes
1328 }
1329 else // Object load failed
1330 {
1331 delete pService;
1332 nxlog_write(MSG_NETSRV_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
1333 }
1334 }
1335 DBFreeResult(hResult);
1336 }
1337
1338 // Load VPN connectors
35f836fe
VK
1339 DbgPrintf(2, _T("Loading VPN connectors..."));
1340 hResult = DBSelect(g_hCoreDB, _T("SELECT id FROM vpn_connectors"));
5039dede
AK
1341 if (hResult != NULL)
1342 {
1343 VPNConnector *pConnector;
1344
1345 dwNumRows = DBGetNumRows(hResult);
1346 for(i = 0; i < dwNumRows; i++)
1347 {
1348 dwId = DBGetFieldULong(hResult, i, 0);
1349 pConnector = new VPNConnector;
c42b4551 1350 if (pConnector->loadFromDatabase(dwId))
5039dede
AK
1351 {
1352 NetObjInsert(pConnector, FALSE); // Insert into indexes
1353 }
1354 else // Object load failed
1355 {
1356 delete pConnector;
1357 nxlog_write(MSG_VPNC_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
1358 }
1359 }
1360 DBFreeResult(hResult);
1361 }
1362
1363 // Load clusters
35f836fe
VK
1364 DbgPrintf(2, _T("Loading clusters..."));
1365 hResult = DBSelect(g_hCoreDB, _T("SELECT id FROM clusters"));
5039dede
AK
1366 if (hResult != NULL)
1367 {
1368 Cluster *pCluster;
1369
1370 dwNumRows = DBGetNumRows(hResult);
1371 for(i = 0; i < dwNumRows; i++)
1372 {
1373 dwId = DBGetFieldULong(hResult, i, 0);
1374 pCluster = new Cluster;
c42b4551 1375 if (pCluster->loadFromDatabase(dwId))
5039dede
AK
1376 {
1377 NetObjInsert(pCluster, FALSE); // Insert into indexes
1378 }
1379 else // Object load failed
1380 {
1381 delete pCluster;
1382 nxlog_write(MSG_CLUSTER_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
1383 }
1384 }
1385 DBFreeResult(hResult);
1386 }
1387
85ae39bc
VK
1388 // Start cache loading thread.
1389 // All data collection targets must be loaded at this point.
1390 ThreadCreate(CacheLoadingThread, 0, NULL);
1391
5039dede 1392 // Load templates
35f836fe
VK
1393 DbgPrintf(2, _T("Loading templates..."));
1394 hResult = DBSelect(g_hCoreDB, _T("SELECT id FROM templates"));
5039dede
AK
1395 if (hResult != NULL)
1396 {
1397 dwNumRows = DBGetNumRows(hResult);
1398 for(i = 0; i < dwNumRows; i++)
1399 {
1400 dwId = DBGetFieldULong(hResult, i, 0);
1401 pTemplate = new Template;
c42b4551 1402 if (pTemplate->loadFromDatabase(dwId))
5039dede
AK
1403 {
1404 NetObjInsert(pTemplate, FALSE); // Insert into indexes
27f9598d 1405 pTemplate->calculateCompoundStatus(); // Force status change to NORMAL
5039dede
AK
1406 }
1407 else // Object load failed
1408 {
1409 delete pTemplate;
1410 nxlog_write(MSG_TEMPLATE_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
1411 }
1412 }
1413 DBFreeResult(hResult);
1414 }
1415
f2bb4aa1 1416 // Load agent policies
35f836fe
VK
1417 DbgPrintf(2, _T("Loading agent policies..."));
1418 hResult = DBSelect(g_hCoreDB, _T("SELECT id,policy_type FROM ap_common"));
f2bb4aa1
VK
1419 if (hResult != NULL)
1420 {
1421 dwNumRows = DBGetNumRows(hResult);
1422 for(i = 0; i < dwNumRows; i++)
1423 {
6d3ab9d2
VK
1424 AgentPolicy *policy;
1425
1426 dwId = DBGetFieldULong(hResult, i, 0);
1427 int type = DBGetFieldLong(hResult, i, 1);
1428 switch(type)
1429 {
1430 case AGENT_POLICY_CONFIG:
1431 policy = new AgentPolicyConfig();
1432 break;
1433 default:
1434 policy = new AgentPolicy(type);
1435 break;
1436 }
c42b4551 1437 if (policy->loadFromDatabase(dwId))
f2bb4aa1
VK
1438 {
1439 NetObjInsert(policy, FALSE); // Insert into indexes
27f9598d 1440 policy->calculateCompoundStatus(); // Force status change to NORMAL
f2bb4aa1
VK
1441 }
1442 else // Object load failed
1443 {
1444 delete policy;
1445 nxlog_write(MSG_AGENTPOLICY_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
1446 }
1447 }
1448 DBFreeResult(hResult);
1449 }
1450
fc958888 1451 // Load network maps
35f836fe
VK
1452 DbgPrintf(2, _T("Loading network maps..."));
1453 hResult = DBSelect(g_hCoreDB, _T("SELECT id FROM network_maps"));
021dcda7
VK
1454 if (hResult != NULL)
1455 {
1456 dwNumRows = DBGetNumRows(hResult);
1457 for(i = 0; i < dwNumRows; i++)
1458 {
1459 dwId = DBGetFieldULong(hResult, i, 0);
1460 NetworkMap *map = new NetworkMap;
c42b4551 1461 if (map->loadFromDatabase(dwId))
021dcda7
VK
1462 {
1463 NetObjInsert(map, FALSE); // Insert into indexes
1464 }
1465 else // Object load failed
1466 {
1467 delete map;
1468 nxlog_write(MSG_NETMAP_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
1469 }
1470 }
1471 DBFreeResult(hResult);
1472 }
1473
5039dede 1474 // Load container objects
35f836fe
VK
1475 DbgPrintf(2, _T("Loading containers..."));
1476 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("SELECT id FROM containers WHERE object_class=%d"), OBJECT_CONTAINER);
5039dede
AK
1477 hResult = DBSelect(g_hCoreDB, szQuery);
1478 if (hResult != 0)
1479 {
1480 Container *pContainer;
1481
1482 dwNumRows = DBGetNumRows(hResult);
1483 for(i = 0; i < dwNumRows; i++)
1484 {
1485 dwId = DBGetFieldULong(hResult, i, 0);
1486 pContainer = new Container;
c42b4551 1487 if (pContainer->loadFromDatabase(dwId))
5039dede
AK
1488 {
1489 NetObjInsert(pContainer, FALSE); // Insert into indexes
1490 }
1491 else // Object load failed
1492 {
1493 delete pContainer;
1494 nxlog_write(MSG_CONTAINER_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
1495 }
1496 }
1497 DBFreeResult(hResult);
1498 }
1499
8715a84c
VK
1500 // Load racks
1501 DbgPrintf(2, _T("Loading racks..."));
1502 hResult = DBSelect(g_hCoreDB, _T("SELECT id FROM racks"));
1503 if (hResult != 0)
1504 {
1505 Rack *rack;
1506
1507 dwNumRows = DBGetNumRows(hResult);
1508 for(i = 0; i < dwNumRows; i++)
1509 {
1510 dwId = DBGetFieldULong(hResult, i, 0);
1511 rack = new Rack;
c42b4551 1512 if (rack->loadFromDatabase(dwId))
8715a84c
VK
1513 {
1514 NetObjInsert(rack, FALSE); // Insert into indexes
1515 }
1516 else // Object load failed
1517 {
1518 nxlog_write(MSG_RACK_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
1519 delete rack;
1520 }
1521 }
1522 DBFreeResult(hResult);
1523 }
1524
5039dede 1525 // Load template group objects
35f836fe 1526 DbgPrintf(2, _T("Loading template groups..."));
9f24efb3 1527 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("SELECT id FROM containers WHERE object_class=%d"), OBJECT_TEMPLATEGROUP);
5039dede
AK
1528 hResult = DBSelect(g_hCoreDB, szQuery);
1529 if (hResult != 0)
1530 {
1531 TemplateGroup *pGroup;
1532
1533 dwNumRows = DBGetNumRows(hResult);
1534 for(i = 0; i < dwNumRows; i++)
1535 {
1536 dwId = DBGetFieldULong(hResult, i, 0);
1537 pGroup = new TemplateGroup;
c42b4551 1538 if (pGroup->loadFromDatabase(dwId))
5039dede
AK
1539 {
1540 NetObjInsert(pGroup, FALSE); // Insert into indexes
1541 }
1542 else // Object load failed
1543 {
1544 delete pGroup;
1545 nxlog_write(MSG_TG_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
1546 }
1547 }
1548 DBFreeResult(hResult);
1549 }
1550
f2bb4aa1 1551 // Load policy group objects
35f836fe
VK
1552 DbgPrintf(2, _T("Loading policy groups..."));
1553 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("SELECT id FROM containers WHERE object_class=%d"), OBJECT_POLICYGROUP);
f2bb4aa1
VK
1554 hResult = DBSelect(g_hCoreDB, szQuery);
1555 if (hResult != 0)
1556 {
1557 PolicyGroup *pGroup;
1558
1559 dwNumRows = DBGetNumRows(hResult);
1560 for(i = 0; i < dwNumRows; i++)
1561 {
1562 dwId = DBGetFieldULong(hResult, i, 0);
1563 pGroup = new PolicyGroup;
c42b4551 1564 if (pGroup->loadFromDatabase(dwId))
f2bb4aa1
VK
1565 {
1566 NetObjInsert(pGroup, FALSE); // Insert into indexes
1567 }
1568 else // Object load failed
1569 {
1570 delete pGroup;
1571 nxlog_write(MSG_PG_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
1572 }
1573 }
1574 DBFreeResult(hResult);
1575 }
1576
021dcda7 1577 // Load map group objects
35f836fe
VK
1578 DbgPrintf(2, _T("Loading map groups..."));
1579 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("SELECT id FROM containers WHERE object_class=%d"), OBJECT_NETWORKMAPGROUP);
021dcda7
VK
1580 hResult = DBSelect(g_hCoreDB, szQuery);
1581 if (hResult != 0)
1582 {
1583 NetworkMapGroup *pGroup;
1584
1585 dwNumRows = DBGetNumRows(hResult);
1586 for(i = 0; i < dwNumRows; i++)
1587 {
1588 dwId = DBGetFieldULong(hResult, i, 0);
1589 pGroup = new NetworkMapGroup;
c42b4551 1590 if (pGroup->loadFromDatabase(dwId))
021dcda7
VK
1591 {
1592 NetObjInsert(pGroup, FALSE); // Insert into indexes
1593 }
1594 else // Object load failed
1595 {
1596 delete pGroup;
1597 nxlog_write(MSG_MG_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
1598 }
1599 }
1600 DBFreeResult(hResult);
1601 }
1602
926e8ce7
VK
1603 // Load dashboard objects
1604 DbgPrintf(2, _T("Loading dashboards..."));
1605 hResult = DBSelect(g_hCoreDB, _T("SELECT id FROM dashboards"));
1606 if (hResult != 0)
1607 {
1608 Dashboard *pd;
1609
1610 dwNumRows = DBGetNumRows(hResult);
1611 for(i = 0; i < dwNumRows; i++)
1612 {
1613 dwId = DBGetFieldULong(hResult, i, 0);
1614 pd = new Dashboard;
c42b4551 1615 if (pd->loadFromDatabase(dwId))
926e8ce7
VK
1616 {
1617 NetObjInsert(pd, FALSE); // Insert into indexes
1618 }
1619 else // Object load failed
1620 {
1621 delete pd;
1622 nxlog_write(MSG_DASHBOARD_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
1623 }
1624 }
1625 DBFreeResult(hResult);
1626 }
1627
5f591e92 1628 // Loading business service objects
fc958888 1629 DbgPrintf(2, _T("Loading business services..."));
1621a079 1630 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("SELECT id FROM containers WHERE object_class=%d"), OBJECT_BUSINESSSERVICE);
fc958888
AK
1631 hResult = DBSelect(g_hCoreDB, szQuery);
1632 if (hResult != 0)
1633 {
1634 dwNumRows = DBGetNumRows(hResult);
1635 for(i = 0; i < dwNumRows; i++)
1636 {
1637 dwId = DBGetFieldULong(hResult, i, 0);
5f591e92 1638 BusinessService *service = new BusinessService;
c42b4551 1639 if (service->loadFromDatabase(dwId))
fc958888 1640 {
5f591e92 1641 NetObjInsert(service, FALSE); // Insert into indexes
fc958888
AK
1642 }
1643 else // Object load failed
1644 {
5f591e92
VK
1645 delete service;
1646 nxlog_write(MSG_BUSINESS_SERVICE_LOAD_FAILED, NXLOG_ERROR, "d", dwId);
1647 }
1648 }
1649 DBFreeResult(hResult);
1650 }
1651
1652 // Loading business service objects
1653 DbgPrintf(2, _T("Loading node links..."));
1654 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("SELECT id FROM containers WHERE object_class=%d"), OBJECT_NODELINK);
1655 hResult = DBSelect(g_hCoreDB, szQuery);
1656 if (hResult != 0)
1657 {
1658 dwNumRows = DBGetNumRows(hResult);
1659 for(i = 0; i < dwNumRows; i++)
1660 {
1661 dwId = DBGetFieldULong(hResult, i, 0);
1662 NodeLink *nl = new NodeLink;
c42b4551 1663 if (nl->loadFromDatabase(dwId))
5f591e92
VK
1664 {
1665 NetObjInsert(nl, FALSE); // Insert into indexes
1666 }
1667 else // Object load failed
1668 {
1669 delete nl;
1670 nxlog_write(MSG_NODE_LINK_LOAD_FAILED, NXLOG_ERROR, "d", dwId);
fc958888
AK
1671 }
1672 }
1673 DBFreeResult(hResult);
1674 }
1675
0cc347d7
VK
1676 // Load service check objects
1677 DbgPrintf(2, _T("Loading service checks..."));
1678 hResult = DBSelect(g_hCoreDB, _T("SELECT id FROM slm_checks"));
1679 if (hResult != 0)
1680 {
1681 dwNumRows = DBGetNumRows(hResult);
1682 for(i = 0; i < dwNumRows; i++)
1683 {
1684 dwId = DBGetFieldULong(hResult, i, 0);
1685 SlmCheck *check = new SlmCheck;
c42b4551 1686 if (check->loadFromDatabase(dwId))
0cc347d7
VK
1687 {
1688 NetObjInsert(check, FALSE); // Insert into indexes
1689 }
1690 else // Object load failed
1691 {
1692 delete check;
1693 nxlog_write(MSG_SERVICE_CHECK_LOAD_FAILED, NXLOG_ERROR, "d", dwId);
1694 }
1695 }
1696 DBFreeResult(hResult);
1697 }
1698
496390c2 1699 // Load custom object classes provided by modules
a0efa7b5 1700 CALL_ALL_MODULES(pfLoadObjects, ());
496390c2 1701
5039dede 1702 // Link childs to container and template group objects
35f836fe 1703 DbgPrintf(2, _T("Linking objects..."));
9d605305 1704 g_idxObjectById.forEach(LinkChildObjectsCallback, NULL);
5039dede 1705
8c5b6ed3 1706 // Link childs to root objects
5039dede
AK
1707 g_pServiceRoot->LinkChildObjects();
1708 g_pTemplateRoot->LinkChildObjects();
f2bb4aa1 1709 g_pPolicyRoot->LinkChildObjects();
021dcda7 1710 g_pMapRoot->LinkChildObjects();
926e8ce7 1711 g_pDashboardRoot->LinkChildObjects();
1621a079 1712 g_pBusinessServiceRoot->LinkChildObjects();
5039dede 1713
496390c2 1714 // Link custom object classes provided by modules
a0efa7b5 1715 CALL_ALL_MODULES(pfLinkObjects, ());
496390c2 1716
5039dede
AK
1717 // Allow objects to change it's modification flag
1718 g_bModificationsLocked = FALSE;
1719
1720 // Recalculate status for built-in objects
27f9598d
VK
1721 g_pEntireNet->calculateCompoundStatus();
1722 g_pServiceRoot->calculateCompoundStatus();
1723 g_pTemplateRoot->calculateCompoundStatus();
1724 g_pPolicyRoot->calculateCompoundStatus();
1725 g_pMapRoot->calculateCompoundStatus();
1621a079 1726 g_pBusinessServiceRoot->calculateCompoundStatus();
5039dede
AK
1727
1728 // Recalculate status for zone objects
c8076b19 1729 if (g_flags & AF_ENABLE_ZONING)
5039dede 1730 {
9d605305 1731 g_idxZoneByGUID.forEach(RecalcStatusCallback, NULL);
5039dede
AK
1732 }
1733
ba8bae74
VK
1734 // Start map update thread
1735 ThreadCreate(MapUpdateThread, 0, NULL);
1736
5039dede
AK
1737 return TRUE;
1738}
1739
6b8e9f96
VK
1740/**
1741 * Callback for DeleteUserFromAllObjects
1742 */
9d605305 1743static void DropUserAccess(NetObj *object, void *userId)
5039dede 1744{
967893bb 1745 object->dropUserAccess(CAST_FROM_POINTER(userId, UINT32));
9d605305 1746}
5039dede 1747
6b8e9f96
VK
1748/**
1749 * Delete user or group from all objects' ACLs
1750 */
967893bb 1751void DeleteUserFromAllObjects(UINT32 dwUserId)
9d605305
VK
1752{
1753 g_idxObjectById.forEach(DropUserAccess, CAST_TO_POINTER(dwUserId, void *));
5039dede
AK
1754}
1755
6b8e9f96
VK
1756/**
1757 * User data for DumpObjectCallback
1758 */
6aba3998
VK
1759struct __dump_objects_data
1760{
1761 CONSOLE_CTX console;
1762 TCHAR *buffer;
01ca557f 1763 const TCHAR *filter;
6aba3998
VK
1764};
1765
6b8e9f96
VK
1766/**
1767 * Enumeration callback for DumpObjects
1768 */
6aba3998 1769static void DumpObjectCallback(NetObj *object, void *data)
5039dede 1770{
6aba3998 1771 struct __dump_objects_data *dd = (struct __dump_objects_data *)data;
01ca557f
VK
1772
1773 // Apply name filter
1774 if ((dd->filter != NULL) && !MatchString(dd->filter, object->getName(), false))
1775 return;
1776
6aba3998 1777 CONSOLE_CTX pCtx = dd->console;
5039dede 1778 CONTAINER_CATEGORY *pCat;
5039dede 1779
6aba3998 1780 ConsolePrintf(pCtx, _T("Object ID %d \"%s\"\n")
c30c0c0f 1781 _T(" Class: %s Status: %s IsModified: %d IsDeleted: %d\n"),
c42b4551 1782 object->getId(), object->getName(), (object->getObjectClass() < OBJECT_CUSTOM) ? g_szClassName[object->getObjectClass()] : _T("Custom"),
6fec127d 1783 GetStatusAsText(object->Status(), true),
6ff21d27 1784 object->isModified(), object->isDeleted());
6aba3998 1785 ConsolePrintf(pCtx, _T(" Parents: <%s>\n Childs: <%s>\n"),
fca08da9 1786 object->dbgGetParentList(dd->buffer), object->dbgGetChildList(&dd->buffer[4096]));
6b8e9f96 1787 time_t t = object->getTimeStamp();
6aba3998
VK
1788 struct tm *ltm = localtime(&t);
1789 _tcsftime(dd->buffer, 256, _T("%d.%b.%Y %H:%M:%S"), ltm);
1790 ConsolePrintf(pCtx, _T(" Last change: %s\n"), dd->buffer);
c42b4551 1791 switch(object->getObjectClass())
5039dede 1792 {
6aba3998 1793 case OBJECT_NODE:
c30c0c0f
VK
1794 ConsolePrintf(pCtx, _T(" Primary IP: %s\n IsSNMP: %d IsAgent: %d IsLocal: %d OID: %s\n"),
1795 ((Node *)object)->getIpAddress().toString(dd->buffer),
6aba3998
VK
1796 ((Node *)object)->isSNMPSupported(),
1797 ((Node *)object)->isNativeAgent(),
1798 ((Node *)object)->isLocalManagement(),
1799 ((Node *)object)->getObjectId());
1800 break;
1801 case OBJECT_SUBNET:
c30c0c0f
VK
1802 ConsolePrintf(pCtx, _T(" IP address: %s/%d\n"), ((Subnet *)object)->getIpAddress().toString(dd->buffer), ((Subnet *)object)->getIpAddress().getMaskBits());
1803 break;
1804 case OBJECT_ACCESSPOINT:
1805 ConsolePrintf(pCtx, _T(" IP address: %s\n"), ((AccessPoint *)object)->getIpAddress().toString(dd->buffer));
1806 break;
1807 case OBJECT_INTERFACE:
1808 ConsolePrintf(pCtx, _T(" MAC address: %s\n"), MACToStr(((Interface *)object)->getMacAddr(), dd->buffer));
1809 for(int n = 0; n < ((Interface *)object)->getIpAddressList()->size(); n++)
1810 {
1811 const InetAddress& a = ((Interface *)object)->getIpAddressList()->get(n);
1812 ConsolePrintf(pCtx, _T(" IP address: %s/%d\n"), a.toString(dd->buffer), a.getMaskBits());
1813 }
6aba3998
VK
1814 break;
1815 case OBJECT_CONTAINER:
926e8ce7 1816 pCat = FindContainerCategory(((Container *)object)->getCategory());
6aba3998
VK
1817 ConsolePrintf(pCtx, _T(" Category: %s\n"), pCat ? pCat->szName : _T("<unknown>"));
1818 break;
1819 case OBJECT_TEMPLATE:
1820 ConsolePrintf(pCtx, _T(" Version: %d.%d\n"),
1821 ((Template *)(object))->getVersionMajor(),
1822 ((Template *)(object))->getVersionMinor());
1823 break;
5039dede 1824 }
6aba3998
VK
1825}
1826
6b8e9f96
VK
1827/**
1828 * Dump objects to debug console
1829 */
01ca557f 1830void DumpObjects(CONSOLE_CTX pCtx, const TCHAR *filter)
6aba3998
VK
1831{
1832 struct __dump_objects_data data;
1833
1834 data.buffer = (TCHAR *)malloc(128000 * sizeof(TCHAR));
1835 data.console = pCtx;
01ca557f 1836 data.filter = filter;
6aba3998
VK
1837 g_idxObjectById.forEach(DumpObjectCallback, &data);
1838 free(data.buffer);
5039dede
AK
1839}
1840
69bb7f47
VK
1841/**
1842 * Check is given object class is a valid parent class for other object
1843 * This function is used to check manually created bindings, so it won't
1844 * return TRUE for node -- subnet for example
1845 */
fc381a38 1846bool IsValidParentClass(int iChildClass, int iParentClass)
5039dede
AK
1847{
1848 switch(iParentClass)
1849 {
dc25b21c 1850 case OBJECT_NETWORK:
c8076b19 1851 if ((iChildClass == OBJECT_ZONE) && (g_flags & AF_ENABLE_ZONING))
fc381a38 1852 return true;
dc25b21c 1853 break;
5039dede
AK
1854 case OBJECT_SERVICEROOT:
1855 case OBJECT_CONTAINER:
1856 if ((iChildClass == OBJECT_CONTAINER) ||
8715a84c 1857 (iChildClass == OBJECT_RACK) ||
5039dede
AK
1858 (iChildClass == OBJECT_NODE) ||
1859 (iChildClass == OBJECT_CLUSTER) ||
9aa67910 1860 (iChildClass == OBJECT_MOBILEDEVICE) ||
261b89df
VK
1861 (iChildClass == OBJECT_CONDITION) ||
1862 (iChildClass == OBJECT_SUBNET))
fc381a38 1863 return true;
5039dede 1864 break;
8715a84c
VK
1865 case OBJECT_RACK:
1866 if (iChildClass == OBJECT_NODE)
1867 return true;
1868 break;
5039dede
AK
1869 case OBJECT_TEMPLATEROOT:
1870 case OBJECT_TEMPLATEGROUP:
1871 if ((iChildClass == OBJECT_TEMPLATEGROUP) ||
1872 (iChildClass == OBJECT_TEMPLATE))
fc381a38 1873 return true;
5039dede 1874 break;
c1bedb50
VK
1875 case OBJECT_TEMPLATE:
1876 if ((iChildClass == OBJECT_NODE) ||
1877 (iChildClass == OBJECT_CLUSTER) ||
1878 (iChildClass == OBJECT_MOBILEDEVICE))
1879 return true;
1880 break;
06e691dd
VK
1881 case OBJECT_NETWORKMAPROOT:
1882 case OBJECT_NETWORKMAPGROUP:
1883 if ((iChildClass == OBJECT_NETWORKMAPGROUP) ||
1884 (iChildClass == OBJECT_NETWORKMAP))
fc381a38 1885 return true;
06e691dd 1886 break;
926e8ce7
VK
1887 case OBJECT_DASHBOARDROOT:
1888 case OBJECT_DASHBOARD:
1889 if (iChildClass == OBJECT_DASHBOARD)
fc381a38 1890 return true;
926e8ce7 1891 break;
45d84f8a
VK
1892 case OBJECT_POLICYROOT:
1893 case OBJECT_POLICYGROUP:
1894 if ((iChildClass == OBJECT_POLICYGROUP) ||
1895 (iChildClass == OBJECT_AGENTPOLICY) ||
1896 (iChildClass == OBJECT_AGENTPOLICY_CONFIG))
fc381a38 1897 return true;
45d84f8a 1898 break;
5039dede
AK
1899 case OBJECT_NODE:
1900 if ((iChildClass == OBJECT_NETWORKSERVICE) ||
9214177b
VK
1901 (iChildClass == OBJECT_VPNCONNECTOR) ||
1902 (iChildClass == OBJECT_INTERFACE))
fc381a38 1903 return true;
5039dede
AK
1904 break;
1905 case OBJECT_CLUSTER:
1906 if (iChildClass == OBJECT_NODE)
fc381a38 1907 return true;
1621a079
VK
1908 break;
1909 case OBJECT_BUSINESSSERVICEROOT:
1910 if ((iChildClass == OBJECT_BUSINESSSERVICE) ||
1911 (iChildClass == OBJECT_NODELINK))
fc381a38 1912 return true;
1621a079
VK
1913 break;
1914 case OBJECT_BUSINESSSERVICE:
1915 if ((iChildClass == OBJECT_BUSINESSSERVICE) ||
1916 (iChildClass == OBJECT_NODELINK) ||
1917 (iChildClass == OBJECT_SLMCHECK))
fc381a38 1918 return true;
1621a079
VK
1919 break;
1920 case OBJECT_NODELINK:
1921 if (iChildClass == OBJECT_SLMCHECK)
fc381a38 1922 return true;
668f315c 1923 break;
5039dede
AK
1924 case -1: // Creating object without parent
1925 if (iChildClass == OBJECT_NODE)
fc381a38 1926 return true; // OK only for nodes, because parent subnet will be created automatically
5039dede
AK
1927 break;
1928 }
496390c2
VK
1929
1930 // Additional check by loaded modules
967893bb 1931 for(UINT32 i = 0; i < g_dwNumModules; i++)
496390c2
VK
1932 {
1933 if (g_pModuleList[i].pfIsValidParentClass != NULL)
1934 {
1935 if (g_pModuleList[i].pfIsValidParentClass(iChildClass, iParentClass))
fc381a38 1936 return true; // accepted by module
496390c2
VK
1937 }
1938 }
1939
fc381a38 1940 return false;
5039dede
AK
1941}
1942
69bb7f47
VK
1943/**
1944 * Delete object (final step)
1945 * This function should be called ONLY from syncer thread
1946 * Object will be removed from index by ID and destroyed.
1947 */
5039dede
AK
1948void NetObjDelete(NetObj *pObject)
1949{
c42b4551 1950 DbgPrintf(4, _T("Final delete step for object %s [%d]"), pObject->getName(), pObject->getId());
5039dede
AK
1951
1952 // Delete object from index by ID and object itself
c42b4551 1953 g_idxObjectById.remove(pObject->getId());
5039dede
AK
1954 delete pObject;
1955}
1956
69bb7f47
VK
1957/**
1958 * Update interface index when IP address changes
1959 */
c75e9ee4 1960void UpdateInterfaceIndex(const InetAddress& oldIpAddr, const InetAddress& newIpAddr, Interface *iface)
5039dede 1961{
89135050
VK
1962 if (IsZoningEnabled())
1963 {
1964 Zone *zone = (Zone *)g_idxZoneByGUID.get(iface->getZoneId());
1965 if (zone != NULL)
1966 {
c75e9ee4 1967 zone->updateInterfaceIndex(oldIpAddr, newIpAddr, iface);
89135050
VK
1968 }
1969 else
1970 {
1971 DbgPrintf(1, _T("UpdateInterfaceIndex: Cannot find zone object for interface %s [%d] (zone id %d)"),
c42b4551 1972 iface->getName(), (int)iface->getId(), (int)iface->getZoneId());
89135050
VK
1973 }
1974 }
1975 else
1976 {
c75e9ee4
VK
1977 g_idxInterfaceByAddr.remove(oldIpAddr);
1978 g_idxInterfaceByAddr.put(newIpAddr, iface);
89135050 1979 }
5039dede
AK
1980}
1981
69bb7f47
VK
1982/**
1983 * Calculate propagated status for object using default algorithm
1984 */
5039dede
AK
1985int DefaultPropagatedStatus(int iObjectStatus)
1986{
1987 int iStatus;
1988
1989 switch(m_iStatusPropAlg)
1990 {
1991 case SA_PROPAGATE_UNCHANGED:
1992 iStatus = iObjectStatus;
1993 break;
1994 case SA_PROPAGATE_FIXED:
1995 iStatus = ((iObjectStatus > STATUS_NORMAL) && (iObjectStatus < STATUS_UNKNOWN)) ? m_iFixedStatus : iObjectStatus;
1996 break;
1997 case SA_PROPAGATE_RELATIVE:
1998 if ((iObjectStatus > STATUS_NORMAL) && (iObjectStatus < STATUS_UNKNOWN))
1999 {
2000 iStatus = iObjectStatus + m_iStatusShift;
2001 if (iStatus < 0)
2002 iStatus = 0;
2003 if (iStatus > STATUS_CRITICAL)
2004 iStatus = STATUS_CRITICAL;
2005 }
2006 else
2007 {
2008 iStatus = iObjectStatus;
2009 }
2010 break;
2011 case SA_PROPAGATE_TRANSLATED:
2012 if ((iObjectStatus > STATUS_NORMAL) && (iObjectStatus < STATUS_UNKNOWN))
2013 {
2014 iStatus = m_iStatusTranslation[iObjectStatus - 1];
2015 }
2016 else
2017 {
2018 iStatus = iObjectStatus;
2019 }
2020 break;
2021 default:
2022 iStatus = STATUS_UNKNOWN;
2023 break;
2024 }
2025 return iStatus;
2026}
2027
69bb7f47
VK
2028/**
2029 * Get default data for status calculation
2030 */
5039dede
AK
2031int GetDefaultStatusCalculation(int *pnSingleThreshold, int **ppnThresholds)
2032{
2033 *pnSingleThreshold = m_iStatusSingleThreshold;
2034 *ppnThresholds = m_iStatusThresholds;
2035 return m_iStatusCalcAlg;
2036}
1f385e47 2037
69bb7f47
VK
2038/**
2039 * Check if given object is an agent policy object
2040 */
1f385e47
VK
2041bool IsAgentPolicyObject(NetObj *object)
2042{
c42b4551 2043 return (object->getObjectClass() == OBJECT_AGENTPOLICY) || (object->getObjectClass() == OBJECT_AGENTPOLICY_CONFIG);
1f385e47 2044}
fc381a38
VK
2045
2046/**
2047 * Returns true if object of given class can be event source
2048 */
2049bool IsEventSource(int objectClass)
2050{
2051 return (objectClass == OBJECT_NODE) ||
2052 (objectClass == OBJECT_CONTAINER) ||
2053 (objectClass == OBJECT_CLUSTER) ||
2054 (objectClass == OBJECT_MOBILEDEVICE);
2055}