implemented issue 484 (event on peer change); DB access optimized
authorVictor Kirhenshtein <victor@netxms.org>
Wed, 12 Feb 2014 18:06:42 +0000 (20:06 +0200)
committerVictor Kirhenshtein <victor@netxms.org>
Wed, 12 Feb 2014 18:06:42 +0000 (20:06 +0200)
12 files changed:
ChangeLog
include/netxmsdb.h
include/nxevent.h
sql/events.in
src/server/core/dcitem.cpp
src/server/core/dctable.cpp
src/server/core/events.cpp
src/server/core/interface.cpp
src/server/core/node.cpp
src/server/core/session.cpp
src/server/include/nms_objects.h
src/server/tools/nxdbmgr/upgrade.cpp

index 211a04b..d45a4dc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,6 +8,7 @@
 - DCI access functions in NXSL works correctly with table DCIs
 - Fixed bugs with instance discovery DCIs created from templates
 - New property "runtimeFlags" in NXSL class "Node"
+- New event SYS_IF_PEER_CHANGED (sent when peer change detected in interface)
 - Management console:
    - Fixed bug with red zone display in "last value" dashboard element
    - Edit and delete for alarm comments are working now
@@ -21,7 +22,7 @@
        - Fix bug in resetting switch preference (settings) 
        - Implemented "Entire network" root (feature #482)
        - Manage last alarm from status bar: acknowledge, resolve, terminate (only for Android >= 4.1)
-- Fixed issues: #79, #88, #393, #481, #482, #483, #486, #487, #490
+- Fixed issues: #79, #88, #393, #481, #482, #483, #484, #486, #487, #490
 
 
 *
index 92fc85a..5be72f1 100644 (file)
@@ -23,6 +23,6 @@
 #ifndef _netxmsdb_h
 #define _netxmsdb_h
 
-#define DB_FORMAT_VERSION   304
+#define DB_FORMAT_VERSION   305
 
 #endif
index 8a40ce7..2ee47f2 100644 (file)
 #define EVENT_NODE_UNREACHABLE            68
 #define EVENT_TABLE_THRESHOLD_ACTIVATED   69
 #define EVENT_TABLE_THRESHOLD_DEACTIVATED 70
+#define EVENT_IF_PEER_CHANGED             71
 
 #define EVENT_SNMP_UNMATCHED_TRAP         500
 #define EVENT_SNMP_COLD_START             501
index 0c72dc0..cb25f5c 100644 (file)
@@ -800,6 +800,26 @@ INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description)
                '   4) Table row' CONCAT CRLF CONCAT
                '   5) Instance'
        );
+INSERT INTO event_cfg (event_code,event_name,severity,flags,message,description) VALUES
+       (
+               EVENT_IF_PEER_CHANGED, 'SYS_IF_PEER_CHANGED',
+               EVENT_SEVERITY_NORMAL, 1,
+               'New peer for interface %3 is %7 interface %10 (%12)',
+               'Generated when peer information for interface changes.' CONCAT CRLF CONCAT
+               'Parameters:' CONCAT CRLF CONCAT
+               '    1) Local interface object ID' CONCAT CRLF CONCAT
+               '    2) Local interface index' CONCAT CRLF CONCAT
+               '    3) Local interface name' CONCAT CRLF CONCAT
+               '    4) Local interface IP address' CONCAT CRLF CONCAT
+               '    5) Local interface MAC address' CONCAT CRLF CONCAT
+               '    6) Peer node object ID' CONCAT CRLF CONCAT
+               '    7) Peer node name' CONCAT CRLF CONCAT
+               '    8) Peer interface object ID' CONCAT CRLF CONCAT
+               '    9) Peer interface index' CONCAT CRLF CONCAT
+               '   10) Peer interface name' CONCAT CRLF CONCAT
+               '   11) Peer interface IP address' CONCAT CRLF CONCAT
+               '   12) Peer interface MAC address'
+       );
 
 /*
 ** SNMP traps
index bb6c3d3..b213048 100644 (file)
@@ -1251,8 +1251,10 @@ bool DCItem::deleteAllData()
        bool success;
 
    lock();
+   DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
    _sntprintf(szQuery, 256, _T("DELETE FROM idata_%d WHERE item_id=%d"), m_pNode->Id(), m_dwId);
-       success = DBQuery(g_hCoreDB, szQuery) ? true : false;
+       success = DBQuery(hdb, szQuery) ? true : false;
+   DBConnectionPoolReleaseConnection(hdb);
        clearCache();
        updateCacheSize();
    unlock();
index edd6645..5abad06 100644 (file)
@@ -286,8 +286,10 @@ bool DCTable::deleteAllData()
        bool success;
 
    lock();
+   DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
    _sntprintf(szQuery, 256, _T("DELETE FROM tdata_%d WHERE item_id=%d"), m_pNode->Id(), (int)m_dwId);
-       success = DBQuery(g_hCoreDB, szQuery) ? true : false;
+       success = DBQuery(hdb, szQuery) ? true : false;
+   DBConnectionPoolReleaseConnection(hdb);
    unlock();
        return success;
 }
index d33aa9c..b189c84 100644 (file)
@@ -123,6 +123,11 @@ Event::Event(EVENT_TEMPLATE *pTemplate, UINT32 dwSourceId, const TCHAR *pszUserT
                IpToStr(va_arg(args, UINT32), buffer);
                                        m_parameters.add(buffer);
                break;
+            case 'h':
+               buffer = (TCHAR *)malloc(32 * sizeof(TCHAR));
+               MACToStr(va_arg(args, BYTE *), buffer);
+                                       m_parameters.add(buffer);
+               break;
             default:
                buffer = (TCHAR *)malloc(64 * sizeof(TCHAR));
                _sntprintf(buffer, 64, _T("BAD FORMAT \"%c\" [value = 0x%08X]"), szFormat[i], va_arg(args, UINT32));
@@ -534,22 +539,18 @@ TCHAR *Event::expandText(Event *event, UINT32 sourceObject, const TCHAR *pszTemp
    return pText;
 }
 
-
-//
-// Add new parameter to event
-//
-
+/**
+ * Add new parameter to event
+ */
 void Event::addParameter(const TCHAR *name, const TCHAR *value)
 {
        m_parameters.add(_tcsdup(value));
        m_parameterNames.add(name);
 }
 
-
-//
-// Set value of named parameter
-//
-
+/**
+ * Set value of named parameter
+ */
 void Event::setNamedParameter(const TCHAR *name, const TCHAR *value)
 {
        int index = m_parameterNames.getIndexIgnoreCase(name);
@@ -565,11 +566,9 @@ void Event::setNamedParameter(const TCHAR *name, const TCHAR *value)
        }
 }
 
-
-//
-// Fill message with event data
-//
-
+/**
+ * Fill message with event data
+ */
 void Event::prepareMessage(CSCPMessage *pMsg)
 {
        UINT32 dwId = VID_EVENTLOG_MSG_BASE;
@@ -588,18 +587,17 @@ void Event::prepareMessage(CSCPMessage *pMsg)
                pMsg->SetVariable(dwId++, (TCHAR *)m_parameters.get(i));
 }
 
-
-//
-// Load event configuration from database
-//
-
+/**
+ * Load event configuration from database
+ */
 static BOOL LoadEvents()
 {
    DB_RESULT hResult;
    UINT32 i;
    BOOL bSuccess = FALSE;
 
-   hResult = DBSelect(g_hCoreDB, _T("SELECT event_code,severity,flags,message,description,event_name FROM event_cfg ORDER BY event_code"));
+   DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
+   hResult = DBSelect(hdb, _T("SELECT event_code,severity,flags,message,description,event_name FROM event_cfg ORDER BY event_code"));
    if (hResult != NULL)
    {
       m_dwNumTemplates = DBGetNumRows(hResult);
@@ -622,6 +620,7 @@ static BOOL LoadEvents()
       nxlog_write(MSG_EVENT_LOAD_ERROR, EVENTLOG_ERROR_TYPE, NULL);
    }
 
+   DBConnectionPoolReleaseConnection(hdb);
    return bSuccess;
 }
 
@@ -680,11 +679,9 @@ void ShutdownEventSubsystem()
    RWLockDestroy(m_rwlockTemplateAccess);
 }
 
-
-//
-// Reload event templates from database
-//
-
+/**
+ * Reload event templates from database
+ */
 void ReloadEvents()
 {
    UINT32 i;
@@ -705,11 +702,9 @@ void ReloadEvents()
    RWLockUnlock(m_rwlockTemplateAccess);
 }
 
-
-//
-// Delete event template from list
-//
-
+/**
+ * Delete event template from list
+ */
 void DeleteEventTemplateFromList(UINT32 dwEventCode)
 {
    UINT32 i;
@@ -769,10 +764,13 @@ static EVENT_TEMPLATE *FindEventTemplate(UINT32 dwCode)
  * szFormat    - Parameter format string, each parameter represented by one character.
  *    The following format characters can be used:
  *        s - String
+ *        m - Multibyte string
+ *        u - UNICODE string
  *        d - Decimal integer
  *        D - 64-bit decimal integer
  *        x - Hex integer
  *        a - IP address
+ *        h - MAC (hardware) address
  *        i - Object ID
  * names - names for parameters
  * PostEventEx will put events to specified queue, and PostEvent to system
index 432b136..4139d28 100644 (file)
@@ -40,6 +40,7 @@ Interface::Interface() : NetObj()
        m_peerInterfaceId = 0;
        m_dot1xPaeAuthState = PAE_STATE_UNKNOWN;
        m_dot1xBackendAuthState = BACKEND_STATE_UNKNOWN;
+   memset(m_bMacAddr, 0, MAC_ADDR_LENGTH);
    m_lastDownEventId = 0;
        m_pendingStatus = -1;
        m_pollCount = 0;
@@ -746,11 +747,9 @@ UINT32 Interface::wakeUp()
    return dwResult;
 }
 
-
-//
-// Get interface's parent node
-//
-
+/**
+ * Get interface's parent node
+ */
 Node *Interface::getParentNode()
 {
    UINT32 i;
@@ -767,11 +766,18 @@ Node *Interface::getParentNode()
    return pNode;
 }
 
+/**
+ * Get ID of parent node object
+ */
+UINT32 Interface::getParentNodeId()
+{
+   Node *node = getParentNode();
+   return (node != NULL) ? node->Id() : 0;
+}
 
-//
-// Change interface's IP address
-//
-
+/**
+ * Change interface's IP address
+ */
 void Interface::setIpAddr(UINT32 dwNewAddr) 
 {
    UpdateInterfaceIndex(m_dwIpAddr, dwNewAddr, this);
@@ -781,11 +787,9 @@ void Interface::setIpAddr(UINT32 dwNewAddr)
    UnlockData();
 }
 
-
-//
-// Change interface's IP subnet mask
-//
-
+/**
+ * Change interface's IP subnet mask
+ */
 void Interface::setIpNetMask(UINT32 dwNetMask) 
 {
    LockData();
@@ -794,7 +798,6 @@ void Interface::setIpNetMask(UINT32 dwNetMask)
    UnlockData();
 }
 
-
 /**
  * Update zone ID. New zone ID taken from parent node.
  */
@@ -835,3 +838,23 @@ void Interface::onObjectDelete(UINT32 dwObjectId)
        }
        NetObj::onObjectDelete(dwObjectId);
 }
+
+/**
+ * Set peer information
+ */
+void Interface::setPeer(Node *node, Interface *iface)
+{
+   if ((m_peerNodeId == node->Id()) && (m_peerInterfaceId == iface->Id()))
+      return;
+
+   m_peerNodeId = node->Id();
+   m_peerInterfaceId = iface->Id();
+   Modify();
+
+   static const TCHAR *names[] = { _T("localIfId"), _T("localIfIndex"), _T("localIfName"), 
+      _T("localIfIP"), _T("localIfMAC"), _T("remoteNodeId"), _T("remoteNodeName"),
+      _T("remoteIfId"), _T("remoteIfIndex"), _T("remoteIfName"), _T("remoteIfIP"), _T("remoteIfMAC") };
+   PostEventWithNames(EVENT_IF_PEER_CHANGED, getParentNodeId(), "ddsahdsddsah", names,
+      m_dwId, m_dwIfIndex, m_szName, m_dwIpAddr, m_bMacAddr, node->Id(), node->Name(),
+      iface->Id(), iface->getIfIndex(), iface->Name(), iface->IpAddr(), iface->getMacAddr());
+}
index 349727c..834cf0a 100644 (file)
@@ -4978,7 +4978,7 @@ void Node::topologyPoll(ClientSession *pSession, UINT32 dwRqId, int nPoller)
                                                Interface *ifOldPeer = (Interface *)FindObjectById(ifRemote->getPeerInterfaceId(), OBJECT_INTERFACE);
                                                if (ifOldPeer != NULL)
                                                {
-                                                       ifOldPeer->setPeer(0, 0);
+                                                       ifOldPeer->clearPeer();
                                                }
                                        }
                                        if ((ifLocal->getPeerInterfaceId() != 0) && (ifLocal->getPeerInterfaceId() != ifRemote->Id()))
@@ -4986,12 +4986,12 @@ void Node::topologyPoll(ClientSession *pSession, UINT32 dwRqId, int nPoller)
                                                Interface *ifOldPeer = (Interface *)FindObjectById(ifLocal->getPeerInterfaceId(), OBJECT_INTERFACE);
                                                if (ifOldPeer != NULL)
                                                {
-                                                       ifOldPeer->setPeer(0, 0);
+                                                       ifOldPeer->clearPeer();
                                                }
                                        }
 
-                                       ifLocal->setPeer(ni->objectId, ifRemote->Id());
-                                       ifRemote->setPeer(m_dwId, ifLocal->Id());
+                                       ifLocal->setPeer((Node *)object, ifRemote);
+                                       ifRemote->setPeer(this, ifLocal);
                                        sendPollerMsg(dwRqId, _T("   Local interface %s linked to remote interface %s:%s\r\n"),
                                                      ifLocal->Name(), object->Name(), ifRemote->Name());
                                        DbgPrintf(5, _T("Local interface %s:%s linked to remote interface %s:%s"),
@@ -5010,7 +5010,7 @@ void Node::topologyPoll(ClientSession *pSession, UINT32 dwRqId, int nPoller)
          Interface *iface = (Interface *)m_pChildList[i];
          if ((iface->getPeerNodeId() == m_dwId) && (iface->getPeerInterfaceId() == iface->Id()))
          {
-            iface->setPeer(0, 0);
+            iface->clearPeer();
             DbgPrintf(6, _T("Node::topologyPoll(%s [%d]): Self-linked interface %s [%d] fixed"), m_szName, m_dwId, iface->Name(), iface->Id());
          }
       }
index 95658d0..32acc66 100644 (file)
@@ -1827,7 +1827,8 @@ void ClientSession::sendEventDB(UINT32 dwRqId)
          msg.SetCode(CMD_EVENT_DB_RECORD);
          msg.SetId(dwRqId);
 
-         hResult = DBAsyncSelect(g_hCoreDB, _T("SELECT event_code,event_name,severity,flags,message,description FROM event_cfg"));
+         DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
+         hResult = DBAsyncSelect(hdb, _T("SELECT event_code,event_name,severity,flags,message,description FROM event_cfg"));
          if (hResult != NULL)
          {
             while(DBFetch(hResult))
@@ -1848,6 +1849,7 @@ void ClientSession::sendEventDB(UINT32 dwRqId)
             }
             DBFreeAsyncResult(hResult);
          }
+         DBConnectionPoolReleaseConnection(hdb);
 
          // End-of-list indicator
          msg.SetVariable(VID_EVENT_CODE, (UINT32)0);
@@ -1893,9 +1895,11 @@ void ClientSession::modifyEventTemplate(CSCPMessage *pRequest)
    {
       TCHAR szQuery[8192], szName[MAX_EVENT_NAME];
 
+      DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
+
       // Check if event with specific code exists
       UINT32 dwEventCode = pRequest->GetVariableLong(VID_EVENT_CODE);
-               bool bEventExist = IsDatabaseRecordExist(g_hCoreDB, _T("event_cfg"), _T("event_code"), dwEventCode);
+               bool bEventExist = IsDatabaseRecordExist(hdb, _T("event_cfg"), _T("event_code"), dwEventCode);
 
       // Check that we are not trying to create event below 100000
       if (bEventExist || (dwEventCode >= FIRST_USER_EVENT_ID))
@@ -1927,7 +1931,7 @@ void ClientSession::modifyEventTemplate(CSCPMessage *pRequest)
 
             safe_free(pszDescription);
 
-            if (DBQuery(g_hCoreDB, szQuery))
+            if (DBQuery(hdb, szQuery))
             {
                msg.SetVariable(VID_RCC, RCC_SUCCESS);
                ReloadEvents();
@@ -1952,6 +1956,7 @@ void ClientSession::modifyEventTemplate(CSCPMessage *pRequest)
       {
          msg.SetVariable(VID_RCC, RCC_INVALID_EVENT_CODE);
       }
+      DBConnectionPoolReleaseConnection(hdb);
    }
    else
    {
@@ -2184,6 +2189,7 @@ void ClientSession::sendEventLog(CSCPMessage *pRequest)
    msg.SetId(dwRqId);
 
    MutexLock(m_mutexSendEvents);
+   DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
 
    // Retrieve events from database
    switch(g_nDBSyntax)
@@ -2192,7 +2198,7 @@ void ClientSession::sendEventLog(CSCPMessage *pRequest)
       case DB_SYNTAX_PGSQL:
       case DB_SYNTAX_SQLITE:
          dwNumRows = 0;
-         hTempResult = DBSelect(g_hCoreDB, _T("SELECT count(*) FROM event_log"));
+         hTempResult = DBSelect(hdb, _T("SELECT count(*) FROM event_log"));
          if (hTempResult != NULL)
          {
             if (DBGetNumRows(hTempResult) > 0)
@@ -2229,7 +2235,7 @@ void ClientSession::sendEventLog(CSCPMessage *pRequest)
          szQuery[0] = 0;
          break;
    }
-   hResult = DBAsyncSelect(g_hCoreDB, szQuery);
+   hResult = DBAsyncSelect(hdb, szQuery);
    if (hResult != NULL)
    {
       msg.SetVariable(VID_RCC, RCC_SUCCESS);
@@ -2273,6 +2279,7 @@ void ClientSession::sendEventLog(CSCPMessage *pRequest)
        sendMessage(&msg);
        }
 
+   DBConnectionPoolReleaseConnection(hdb);
    MutexUnlock(m_mutexSendEvents);
 }
 
@@ -5802,11 +5809,9 @@ void ClientSession::LockPackageDB(UINT32 dwRqId, BOOL bLock)
    sendMessage(&msg);
 }
 
-
-//
-// Send list of all installed packages to client
-//
-
+/**
+ * Send list of all installed packages to client
+ */
 void ClientSession::SendAllPackages(UINT32 dwRqId)
 {
    CSCPMessage msg;
@@ -5822,7 +5827,8 @@ void ClientSession::SendAllPackages(UINT32 dwRqId)
    {
       if (m_dwFlags & CSF_PACKAGE_DB_LOCKED)
       {
-         hResult = DBAsyncSelect(g_hCoreDB, _T("SELECT pkg_id,version,platform,pkg_file,pkg_name,description FROM agent_pkg"));
+         DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
+         hResult = DBAsyncSelect(hdb, _T("SELECT pkg_id,version,platform,pkg_file,pkg_name,description FROM agent_pkg"));
          if (hResult != NULL)
          {
             msg.SetVariable(VID_RCC, RCC_SUCCESS);
@@ -5855,6 +5861,7 @@ void ClientSession::SendAllPackages(UINT32 dwRqId)
          {
             msg.SetVariable(VID_RCC, RCC_DB_FAILURE);
          }
+         DBConnectionPoolReleaseConnection(hdb);
       }
       else
       {
@@ -5872,11 +5879,9 @@ void ClientSession::SendAllPackages(UINT32 dwRqId)
       sendMessage(&msg);
 }
 
-
-//
-// Install package to server
-//
-
+/**
+ * Install package to server
+ */
 void ClientSession::InstallPackage(CSCPMessage *pRequest)
 {
    CSCPMessage msg;
@@ -6922,7 +6927,8 @@ void ClientSession::sendObjectTools(UINT32 dwRqId)
    msg.SetCode(CMD_REQUEST_COMPLETED);
    msg.SetId(dwRqId);
 
-   hResult = DBSelect(g_hCoreDB, _T("SELECT tool_id,user_id FROM object_tools_acl"));
+   DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
+   hResult = DBSelect(hdb, _T("SELECT tool_id,user_id FROM object_tools_acl"));
    if (hResult != NULL)
    {
       dwAclSize = DBGetNumRows(hResult);
@@ -6934,7 +6940,7 @@ void ClientSession::sendObjectTools(UINT32 dwRqId)
       }
       DBFreeResult(hResult);
 
-      hResult = DBSelect(g_hCoreDB, _T("SELECT tool_id,tool_name,tool_type,tool_data,flags,description,matching_oid,confirmation_text FROM object_tools"));
+      hResult = DBSelect(hdb, _T("SELECT tool_id,tool_name,tool_type,tool_data,flags,description,matching_oid,confirmation_text FROM object_tools"));
       if (hResult != NULL)
       {
          dwNumTools = DBGetNumRows(hResult);
@@ -7007,6 +7013,7 @@ void ClientSession::sendObjectTools(UINT32 dwRqId)
    {
       msg.SetVariable(VID_RCC, RCC_DB_FAILURE);
    }
+   DBConnectionPoolReleaseConnection(hdb);
 
    // Send response
    sendMessage(&msg);
@@ -7029,9 +7036,11 @@ void ClientSession::sendObjectToolDetails(CSCPMessage *pRequest)
 
    if (m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_TOOLS)
    {
+      DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
+
       dwToolId = pRequest->GetVariableLong(VID_TOOL_ID);
       _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("SELECT tool_name,tool_type,tool_data,description,flags,matching_oid,confirmation_text FROM object_tools WHERE tool_id=%d"), dwToolId);
-      hResult = DBSelect(g_hCoreDB, szQuery);
+      hResult = DBSelect(hdb, szQuery);
       if (hResult != NULL)
       {
          if (DBGetNumRows(hResult) > 0)
@@ -7063,7 +7072,7 @@ void ClientSession::sendObjectToolDetails(CSCPMessage *pRequest)
 
             // Access list
             _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("SELECT user_id FROM object_tools_acl WHERE tool_id=%d"), dwToolId);
-            hResult = DBSelect(g_hCoreDB, szQuery);
+            hResult = DBSelect(hdb, szQuery);
             if (hResult != NULL)
             {
                iNumRows = DBGetNumRows(hResult);
@@ -7084,7 +7093,7 @@ void ClientSession::sendObjectToolDetails(CSCPMessage *pRequest)
                   _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("SELECT col_name,col_oid,col_format,col_substr ")
                                      _T("FROM object_tools_table_columns WHERE tool_id=%d ")
                                      _T("ORDER BY col_number"), dwToolId);
-                  hResult = DBSelect(g_hCoreDB, szQuery);
+                  hResult = DBSelect(hdb, szQuery);
                   if (hResult != NULL)
                   {
                      iNumRows = DBGetNumRows(hResult);
@@ -7123,6 +7132,7 @@ void ClientSession::sendObjectToolDetails(CSCPMessage *pRequest)
       {
          msg.SetVariable(VID_RCC, RCC_DB_FAILURE);
       }
+      DBConnectionPoolReleaseConnection(hdb);
    }
    else
    {
@@ -7383,11 +7393,9 @@ void ClientSession::sendServerStats(UINT32 dwRqId)
    sendMessage(&msg);
 }
 
-
-//
-// Send script list
-//
-
+/**
+ * Send script list
+ */
 void ClientSession::sendScriptList(UINT32 dwRqId)
 {
    CSCPMessage msg;
@@ -7424,11 +7432,9 @@ void ClientSession::sendScriptList(UINT32 dwRqId)
    sendMessage(&msg);
 }
 
-
-//
-// Send script
-//
-
+/**
+ * Send script
+ */
 void ClientSession::sendScript(CSCPMessage *pRequest)
 {
    CSCPMessage msg;
@@ -9349,7 +9355,8 @@ void ClientSession::saveGraph(CSCPMessage *pRequest)
        {
                debugPrintf(5, _T("%s graph %d"), bNew ? _T("Creating") : _T("Updating"), graphId);
                bSuccess = FALSE;
-               if (DBBegin(g_hCoreDB))
+      DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
+               if (DBBegin(hdb))
                {
                        pRequest->GetVariableStr(VID_NAME, szQuery, 256);
                        pszEscName = EncodeSQLString(szQuery);
@@ -9372,7 +9379,7 @@ void ClientSession::saveGraph(CSCPMessage *pRequest)
                        free(pszEscName);
                        free(pszEscData);
 
-                       if (DBQuery(g_hCoreDB, szQuery))
+                       if (DBQuery(hdb, szQuery))
                        {
                                // Insert new ACL
                                nACLSize = (int)pRequest->GetVariableLong(VID_ACL_SIZE);
@@ -9382,7 +9389,7 @@ void ClientSession::saveGraph(CSCPMessage *pRequest)
                                        graphAccess = pRequest->GetVariableLong(id++);
                                        _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("INSERT INTO graph_acl (graph_id,user_id,user_rights) VALUES (%d,%d,%d)"),
                                                  graphId, graphUserId, graphAccess);
-                                       if (!DBQuery(g_hCoreDB, szQuery))
+                                       if (!DBQuery(hdb, szQuery))
                                        {
                                                bSuccess = FALSE;
                                                msg.SetVariable(VID_RCC, RCC_DB_FAILURE);
@@ -9397,20 +9404,21 @@ void ClientSession::saveGraph(CSCPMessage *pRequest)
 
                        if (bSuccess)
                        {
-                               DBCommit(g_hCoreDB);
+                               DBCommit(hdb);
                                msg.SetVariable(VID_RCC, RCC_SUCCESS);
                                msg.SetVariable(VID_GRAPH_ID, graphId);
                                notify(NX_NOTIFY_GRAPHS_CHANGED);
                        }
                        else
                        {
-                               DBRollback(g_hCoreDB);
+                               DBRollback(hdb);
                        }
                }
                else
                {
                        msg.SetVariable(VID_RCC, RCC_DB_FAILURE);
                }
+      DBConnectionPoolReleaseConnection(hdb);
        }
 
    sendMessage(&msg);
index bc63f08..e18a4cc 100644 (file)
@@ -628,6 +628,7 @@ public:
    virtual BOOL CreateFromDB(UINT32 dwId);
 
    Node *getParentNode();
+   UINT32 getParentNodeId();
 
    UINT32 getZoneId() { return m_zoneId; }
    UINT32 getIpNetMask() { return m_dwIpNetMask; }
@@ -666,7 +667,8 @@ public:
    void setPortNumber(UINT32 port) { m_portNumber = port; Modify(); }
        void setPhysicalPortFlag(bool isPhysical) { if (isPhysical) m_flags |= IF_PHYSICAL_PORT; else m_flags &= ~IF_PHYSICAL_PORT; Modify(); }
        void setManualCreationFlag(bool isManual) { if (isManual) m_flags |= IF_CREATED_MANUALLY; else m_flags &= ~IF_CREATED_MANUALLY; Modify(); }
-       void setPeer(UINT32 nodeId, UINT32 ifId) { m_peerNodeId = nodeId; m_peerInterfaceId = ifId; Modify(); }
+       void setPeer(Node *node, Interface *iface);
+   void clearPeer() { m_peerNodeId = 0; m_peerInterfaceId = 0; Modify(); }
    void setDescription(const TCHAR *descr) { nx_strncpy(m_description, descr, MAX_DB_STRING); Modify(); }
 
        void updateZoneId();
index c528c3c..2364ff6 100644 (file)
@@ -1,6 +1,6 @@
 /*
 ** nxdbmgr - NetXMS database manager
-** Copyright (C) 2004-2013 Victor Kirhenshtein
+** Copyright (C) 2004-2014 Victor Kirhenshtein
 **
 ** This program is free software; you can redistribute it and/or modify
 ** it under the terms of the GNU General Public License as published by
@@ -361,6 +361,31 @@ static BOOL RecreateTData(const TCHAR *className, bool multipleTables)
 }
 
 /**
+ * Upgrade from V304 to V305
+ */
+static BOOL H_UpgradeFromV304(int currVersion, int newVersion)
+{
+   CHK_EXEC(CreateEventTemplate(EVENT_IF_PEER_CHANGED, _T("SYS_IF_PEER_CHANGED"), SEVERITY_NORMAL, EF_LOG, 
+      _T("New peer for interface %3 is %7 interface %10 (%12)"),
+               _T("Generated when peer information for interface changes.\r\n")
+               _T("Parameters:\r\n")
+               _T("    1) Local interface object ID\r\n")
+               _T("    2) Local interface index\r\n")
+               _T("    3) Local interface name\r\n")
+               _T("    4) Local interface IP address\r\n")
+               _T("    5) Local interface MAC address\r\n")
+               _T("    6) Peer node object ID\r\n")
+               _T("    7) Peer node name\r\n")
+               _T("    8) Peer interface object ID\r\n")
+               _T("    9) Peer interface index\r\n")
+               _T("   10) Peer interface name\r\n")
+               _T("   11) Peer interface IP address\r\n")
+               _T("   12) Peer interface MAC address")));
+   CHK_EXEC(SQLQuery(_T("UPDATE metadata SET var_value='305' WHERE var_name='SchemaVersion'")));
+   return TRUE;
+}
+
+/**
  * Upgrade from V303 to V304
  */
 static BOOL H_UpgradeFromV303(int currVersion, int newVersion)
@@ -7380,6 +7405,7 @@ static struct
    { 301, 302, H_UpgradeFromV301 },
    { 302, 303, H_UpgradeFromV302 },
    { 303, 304, H_UpgradeFromV303 },
+   { 304, 305, H_UpgradeFromV304 },
    { 0, 0, NULL }
 };