added virtual method NetObj::linkObjects for post-load object linking; added flags...
authorVictor Kirhenshtein <victor@netxms.org>
Fri, 29 Jul 2016 08:49:00 +0000 (11:49 +0300)
committerVictor Kirhenshtein <victor@netxms.org>
Fri, 29 Jul 2016 08:49:00 +0000 (11:49 +0300)
include/nxcldefs.h
sql/schema.in
src/server/core/bizsvcroot.cpp
src/server/core/chassis.cpp
src/server/core/container.cpp
src/server/core/netobj.cpp
src/server/core/objects.cpp
src/server/core/uniroot.cpp
src/server/include/nms_objects.h
src/server/tools/nxdbmgr/upgrade.cpp

index 18c5f5f..790b6ca 100644 (file)
 #define CF_AUTO_BIND             0x00000001
 #define CF_AUTO_UNBIND           0x00000002
 
+/**
+ * Chassis flags
+ */
+#define CHF_BIND_UNDER_CONTROLLER   0x00000001
+
 /**
  * Interface flags
  */
index d917b91..b3a0961 100644 (file)
@@ -377,6 +377,7 @@ CREATE TABLE chassis
 (
   id integer not null,
   controller_id integer not null,
+  flags integer not null,
   rack_id integer not null,
   rack_image varchar(36) null,
   rack_position integer not null,
@@ -387,6 +388,7 @@ CREATE TABLE chassis
 COMMENT_TABLE(chassis, 'Chassis')
 COMMENT_COLUMN(chassis.id, 'Chassis id form object_properties')
 COMMENT_COLUMN(chassis.controller_id, 'Id of node object providing management capabilities for this chassis')
+COMMENT_COLUMN(chassis.flags, 'Chassis options as bit flags')
 COMMENT_COLUMN(chassis.rack_id, 'Related rack object ID')
 COMMENT_COLUMN(chassis.rack_image, 'Image to be used in rack view')
 COMMENT_COLUMN(chassis.rack_position, 'Position in rack (in rack units)')
index 8fed8b3..d1e17bd 100644 (file)
@@ -85,8 +85,10 @@ void BusinessServiceRoot::loadFromDatabase(DB_HANDLE hdb)
  * Link child objects
  * This method is expected to be called only at startup, so we don't lock
  */
-void BusinessServiceRoot::linkChildObjects()
+void BusinessServiceRoot::linkObjects()
 {
+   ServiceContainer::linkObjects();
+
    DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
 
    TCHAR szQuery[256];
index 3d05b2f..ff9f86c 100644 (file)
@@ -108,6 +108,49 @@ void Chassis::updateRackBinding()
    }
 }
 
+/**
+ * Update controller binding
+ */
+void Chassis::updateControllerBinding()
+{
+   bool controllerFound = false;
+
+   lockParentList(true);
+   for(int i = 0; i < m_parentList->size(); i++)
+   {
+      NetObj *object = m_parentList->get(i);
+      if (object->getId() == m_controllerId)
+      {
+         controllerFound = true;
+         break;
+      }
+   }
+   unlockParentList();
+
+   if ((m_flags & CHF_BIND_UNDER_CONTROLLER) && !controllerFound)
+   {
+      NetObj *controller = FindObjectById(m_controllerId);
+      if (controller != NULL)
+      {
+         controller->addChild(this);
+         addParent(controller);
+      }
+      else
+      {
+         nxlog_debug(4, _T("Chassis::updateControllerBinding(%s [%d]): controller object with ID %d not found"), m_name, m_id, m_controllerId);
+      }
+   }
+   else if (!(m_flags & CHF_BIND_UNDER_CONTROLLER) && controllerFound)
+   {
+      NetObj *controller = FindObjectById(m_controllerId);
+      if (controller != NULL)
+      {
+         controller->deleteChild(this);
+         deleteParent(controller);
+      }
+   }
+}
+
 /**
  * Create NXCP message with object's data
  */
@@ -154,9 +197,9 @@ BOOL Chassis::saveToDatabase(DB_HANDLE hdb)
    {
       DB_STATEMENT hStmt;
       if (IsDatabaseRecordExist(hdb, _T("chassis"), _T("id"), m_id))
-         hStmt = DBPrepare(hdb, _T("UPDATE chassis SET controller_id=?,rack_id=?,rack_image=?,rack_position=?,rack_height=? WHERE id=?"));
+         hStmt = DBPrepare(hdb, _T("UPDATE chassis SET controller_id=?,rack_id=?,rack_image=?,rack_position=?,rack_height=?,flags=? WHERE id=?"));
       else
-         hStmt = DBPrepare(hdb, _T("INSERT INTO chassis (controller_id,rack_id,rack_image,rack_position,rack_height,id) VALUES (?,?,?,?,?,?)"));
+         hStmt = DBPrepare(hdb, _T("INSERT INTO chassis (controller_id,rack_id,rack_image,rack_position,rack_height,flags,id) VALUES (?,?,?,?,?,?,?)"));
       if (hStmt != NULL)
       {
          DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, m_controllerId);
@@ -164,7 +207,8 @@ BOOL Chassis::saveToDatabase(DB_HANDLE hdb)
          DBBind(hStmt, 3, DB_SQLTYPE_VARCHAR, m_rackImage);
          DBBind(hStmt, 4, DB_SQLTYPE_INTEGER, m_rackPosition);
          DBBind(hStmt, 5, DB_SQLTYPE_INTEGER, m_rackHeight);
-         DBBind(hStmt, 6, DB_SQLTYPE_INTEGER, m_id);
+         DBBind(hStmt, 6, DB_SQLTYPE_INTEGER, m_flags);
+         DBBind(hStmt, 7, DB_SQLTYPE_INTEGER, m_id);
          success = DBExecute(hStmt);
          DBFreeStatement(hStmt);
       }
@@ -215,7 +259,7 @@ bool Chassis::loadFromDatabase(DB_HANDLE hdb, UINT32 id)
       return false;
    }
 
-   DB_STATEMENT hStmt = DBPrepare(hdb, _T("SELECT controller_id,rack_id,rack_image,rack_position,rack_height FROM chassis WHERE id=?"));
+   DB_STATEMENT hStmt = DBPrepare(hdb, _T("SELECT controller_id,rack_id,rack_image,rack_position,rack_height,flags FROM chassis WHERE id=?"));
    if (hStmt == NULL)
       return false;
 
@@ -232,6 +276,7 @@ bool Chassis::loadFromDatabase(DB_HANDLE hdb, UINT32 id)
    m_rackImage = DBGetFieldGUID(hResult, 0, 2);
    m_rackPosition = DBGetFieldULong(hResult, 0, 3);
    m_rackHeight = DBGetFieldULong(hResult, 0, 4);
+   m_flags = DBGetFieldULong(hResult, 0, 5);
 
    DBFreeResult(hResult);
    DBFreeStatement(hStmt);
@@ -246,6 +291,16 @@ bool Chassis::loadFromDatabase(DB_HANDLE hdb, UINT32 id)
    return true;
 }
 
+
+/**
+ * Link related objects after loading from database
+ */
+void Chassis::linkObjects()
+{
+   DataCollectionTarget::linkObjects();
+   updateControllerBinding();
+}
+
 /**
  * Called when data collection configuration changed
  */
@@ -321,3 +376,18 @@ UINT32 Chassis::getEffectiveSourceNode(DCObject *dco)
    }
    return 0;
 }
+
+/**
+ * Update controller binding flag
+ */
+void Chassis::setBindUnderController(bool doBind)
+{
+   lockProperties();
+   if (doBind)
+      m_flags |= CHF_BIND_UNDER_CONTROLLER;
+   else
+      m_flags &= ~CHF_BIND_UNDER_CONTROLLER;
+   setModified(false);
+   unlockProperties();
+   updateControllerBinding();
+}
index b48cce3..8907679 100644 (file)
@@ -203,17 +203,15 @@ bool Container::deleteFromDatabase(DB_HANDLE hdb)
  * Link child objects after loading from database
  * This method is expected to be called only at startup, so we don't lock
  */
-void Container::linkChildObjects()
+void Container::linkObjects()
 {
-   NetObj *pObject;
-   UINT32 i;
-
+   NetObj::linkObjects();
    if (m_dwChildIdListSize > 0)
    {
       // Find and link child objects
-      for(i = 0; i < m_dwChildIdListSize; i++)
+      for(UINT32 i = 0; i < m_dwChildIdListSize; i++)
       {
-         pObject = FindObjectById(m_pdwChildIdList[i]);
+         NetObj *pObject = FindObjectById(m_pdwChildIdList[i]);
          if (pObject != NULL)
             linkObject(pObject);
          else
index cc7b9aa..3e316b5 100644 (file)
@@ -132,6 +132,13 @@ bool NetObj::loadFromDatabase(DB_HANDLE hdb, UINT32 dwId)
    return false;     // Abstract objects cannot be loaded from database
 }
 
+/**
+ * Link related objects after loading from database
+ */
+void NetObj::linkObjects()
+{
+}
+
 /**
  * Save object to database
  */
index cb8e331..88a44f5 100644 (file)
@@ -1104,21 +1104,11 @@ static void RecalcStatusCallback(NetObj *object, void *data)
 }
 
 /**
- * ObjectIndex::forEach callback which links container child objects
- */
-static void LinkChildObjectsCallback(NetObj *object, void *data)
-{
-       if ((object->getObjectClass() == OBJECT_CONTAINER) ||
-                (object->getObjectClass() == OBJECT_RACK) ||
-                (object->getObjectClass() == OBJECT_TEMPLATEGROUP) ||
-                (object->getObjectClass() == OBJECT_POLICYGROUP) ||
-                (object->getObjectClass() == OBJECT_NETWORKMAPGROUP) ||
-                (object->getObjectClass() == OBJECT_DASHBOARD) ||
-                (object->getObjectClass() == OBJECT_BUSINESSSERVICE) ||
-                (object->getObjectClass() == OBJECT_NODELINK))
-       {
-               ((Container *)object)->linkChildObjects();
-       }
+ * ObjectIndex::forEach callback which links objects after loading
+ */
+static void LinkObjects(NetObj *object, void *data)
+{
+   object->linkObjects();
 }
 
 /**
@@ -1740,15 +1730,7 @@ BOOL LoadObjects()
 
    // Link children to container and template group objects
    DbgPrintf(2, _T("Linking objects..."));
-       g_idxObjectById.forEach(LinkChildObjectsCallback, NULL);
-
-   // Link children to root objects
-   g_pServiceRoot->linkChildObjects();
-   g_pTemplateRoot->linkChildObjects();
-   g_pPolicyRoot->linkChildObjects();
-   g_pMapRoot->linkChildObjects();
-       g_pDashboardRoot->linkChildObjects();
-       g_pBusinessServiceRoot->linkChildObjects();
+       g_idxObjectById.forEach(LinkObjects, NULL);
 
        // Link custom object classes provided by modules
    CALL_ALL_MODULES(pfLinkObjects, ());
index fea1c1d..6f64d04 100644 (file)
@@ -41,8 +41,10 @@ UniversalRoot::~UniversalRoot()
  * Link child objects
  * This method is expected to be called only at startup, so we don't lock
  */
-void UniversalRoot::linkChildObjects()
+void UniversalRoot::linkObjects()
 {
+   NetObj::linkObjects();
+
    DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
 
    TCHAR szQuery[256];
index 59e816d..47653f5 100644 (file)
@@ -575,6 +575,7 @@ public:
    virtual BOOL saveToDatabase(DB_HANDLE hdb);
    virtual bool deleteFromDatabase(DB_HANDLE hdb);
    virtual bool loadFromDatabase(DB_HANDLE hdb, UINT32 id);
+   virtual void linkObjects();
 
    void setId(UINT32 dwId) { m_id = dwId; setModified(); }
    void generateGuid() { m_guid = uuid::generate(); }
@@ -1223,6 +1224,7 @@ protected:
    virtual void collectProxyInfo(ProxyInfo *info);
 
    void updateRackBinding();
+   void updateControllerBinding();
 
 public:
    Chassis();
@@ -1233,6 +1235,7 @@ public:
    virtual BOOL saveToDatabase(DB_HANDLE hdb);
    virtual bool deleteFromDatabase(DB_HANDLE hdb);
    virtual bool loadFromDatabase(DB_HANDLE hdb, UINT32 id);
+   virtual void linkObjects();
    virtual bool showThresholdSummary();
    virtual UINT32 getEffectiveSourceNode(DCObject *dco);
 
@@ -1242,6 +1245,9 @@ public:
    UINT32 getRackId() const { return m_rackId; }
    INT16 getRackHeight() const { return m_rackHeight; }
    INT16 getRackPosition() const { return m_rackPosition; }
+   bool bindUnderController() { return (m_flags & CHF_BIND_UNDER_CONTROLLER) ? true : false; }
+
+   void setBindUnderController(bool doBind);
 };
 
 class Subnet;
@@ -1838,8 +1844,7 @@ public:
 
    virtual BOOL saveToDatabase(DB_HANDLE hdb);
    void loadFromDatabase(DB_HANDLE hdb);
-
-   void linkChildObjects();
+   virtual void linkObjects();
    void linkObject(NetObj *pObject) { addChild(pObject); pObject->addParent(this); }
 };
 
@@ -1897,12 +1902,12 @@ public:
    virtual BOOL saveToDatabase(DB_HANDLE hdb);
    virtual bool deleteFromDatabase(DB_HANDLE hdb);
    virtual bool loadFromDatabase(DB_HANDLE hdb, UINT32 id);
+   virtual void linkObjects();
 
        virtual bool showThresholdSummary();
 
    virtual void calculateCompoundStatus(BOOL bForcedRecalc = FALSE);
 
-   void linkChildObjects();
    void linkObject(NetObj *pObject) { addChild(pObject); pObject->addParent(this); }
 
    AutoBindDecision isSuitableForNode(Node *node);
@@ -2448,7 +2453,8 @@ public:
        virtual BOOL saveToDatabase(DB_HANDLE hdb);
    void loadFromDatabase(DB_HANDLE hdb);
 
-   void linkChildObjects();
+   virtual void linkObjects();
+
    void linkObject(NetObj *pObject) { addChild(pObject); pObject->addParent(this); }
 };
 
index a0447a8..fd5e0d1 100644 (file)
@@ -707,6 +707,7 @@ static BOOL H_UpgradeFromV407(int currVersion, int newVersion)
    CHK_EXEC(CreateTable(
          _T("CREATE TABLE chassis (")
          _T("   id integer not null,")
+         _T("   flags integer not null,")
          _T("   controller_id integer not null,")
          _T("   rack_id integer not null,")
          _T("   rack_image varchar(36) null,")