Add 'last communication with agent' timestamp to Overview tab. Fixes #847
authorzev <zev@radensolutions.com>
Wed, 4 Nov 2015 15:01:40 +0000 (17:01 +0200)
committerzev <zev@radensolutions.com>
Wed, 4 Nov 2015 15:01:40 +0000 (17:01 +0200)
ChangeLog
include/netxmsdb.h
include/nms_cscp.h
sql/schema.in
src/java/client/netxms-base/src/main/java/org/netxms/base/NXCPCodes.java
src/java/client/netxms-client/src/main/java/org/netxms/client/objects/AbstractNode.java
src/java/netxms-eclipse/ObjectView/src/org/netxms/ui/eclipse/objectview/objecttabs/elements/GeneralInfo.java
src/server/core/node.cpp
src/server/include/nms_objects.h
src/server/tools/nxdbmgr/upgrade.cpp
webui/webapp/ObjectView/src/org/netxms/ui/eclipse/objectview/objecttabs/elements/GeneralInfo.java

index e6da8e6..421c399 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,7 +6,7 @@
 - NXSL node object attribute snmpSysDescription renamed back to sysDescription
 - Management console:
        - Object tool input fields can be rearranged
-- Fixed issues: #948, #967
+- Fixed issues: #847, #948, #967
 
 
 *
index 65b87ff..eee3f43 100644 (file)
@@ -23,6 +23,6 @@
 #ifndef _netxmsdb_h
 #define _netxmsdb_h
 
-#define DB_FORMAT_VERSION   375
+#define DB_FORMAT_VERSION   376
 
 #endif
index 62a681d..5501cf9 100644 (file)
@@ -1105,6 +1105,7 @@ typedef struct
 #define VID_OWNER                   ((UINT32)529)
 #define VID_MAINTENANCE_MODE        ((UINT32)530)
 #define VID_IS_MASTER               ((UINT32)531)
+#define VID_AGENT_COMM_TIME         ((UINT32)532)
 
 // Base variabe for single threshold in message
 #define VID_THRESHOLD_BASE          ((UINT32)0x00800000)
index 1fe1957..e375ef3 100644 (file)
@@ -294,6 +294,7 @@ CREATE TABLE nodes
    rack_height integer not null,
        rack_id integer not null,
    agent_cache_mode char(1) not null,
+   last_agent_comm_time integer not null,
        PRIMARY KEY(id)
 ) TABLE_TYPE;
 
index 3fbce84..80ec6bd 100644 (file)
@@ -890,6 +890,8 @@ public class NXCPCodes
    public static final long VID_DASHBOARDS = 528;
    public static final long VID_OWNER = 529;
    public static final long VID_MAINTENANCE_MODE = 530;
+   public static final long VID_IS_MASTER = 531;
+   public static final long VID_AGENT_COMM_TIME = 532;
 
        public static final long VID_ACL_USER_BASE = 0x00001000L;
        public static final long VID_ACL_USER_LAST = 0x00001FFFL;
index 8107bb8..0bec3f0 100644 (file)
@@ -124,6 +124,7 @@ public abstract class AbstractNode extends DataCollectionTarget
        protected MacAddress bridgeBaseAddress;
        protected int ifXTablePolicy;
        protected Date bootTime;
+       protected Date lastAgentCommTime;
        protected long rackId;
        protected UUID rackImage;
        protected short rackPosition;
@@ -193,6 +194,10 @@ public abstract class AbstractNode extends DataCollectionTarget
                
                long bootTimeSeconds = msg.getFieldAsInt64(NXCPCodes.VID_BOOT_TIME);
                bootTime = (bootTimeSeconds > 0) ? new Date(bootTimeSeconds * 1000) : null;
+               
+
+      long commTimeSeconds = msg.getFieldAsInt64(NXCPCodes.VID_AGENT_COMM_TIME);
+      lastAgentCommTime = (commTimeSeconds > 0) ? new Date(commTimeSeconds * 1000) : null;
        }
 
        /**
@@ -643,4 +648,9 @@ public abstract class AbstractNode extends DataCollectionTarget
    {
       return rackHeight;
    }
+
+   public Date getLastAgentCommTime()
+   {
+      return lastAgentCommTime;
+   }
 }
index d51320c..aa2bd11 100644 (file)
@@ -126,6 +126,8 @@ public class GeneralInfo extends TableElement
                                addPair(Messages.get().GeneralInfo_Driver, node.getDriverName(), false);
             if (node.getBootTime() != null)
                addPair(Messages.get().GeneralInfo_BootTime, RegionalSettings.getDateTimeFormat().format(node.getBootTime()), false);
+            if (node.getLastAgentCommTime() != null)
+               addPair("Agent Last Communication Time", RegionalSettings.getDateTimeFormat().format(node.getLastAgentCommTime()), false);
             if (node.getRackId() != 0)
             {
                Rack rack = session.findObjectById(node.getRackId(), Rack.class);
index 665886f..2d91a07 100644 (file)
@@ -78,6 +78,7 @@ Node::Node() : DataCollectionTarget()
    m_pRoutingTable = NULL;
    m_failTimeSNMP = 0;
    m_failTimeAgent = 0;
+   m_lastAgentCommTime = 0;
        m_linkLayerNeighbors = NULL;
        m_vrrpInfo = NULL;
        m_pTopology = NULL;
@@ -163,6 +164,7 @@ Node::Node(const InetAddress& addr, UINT32 dwFlags, UINT32 agentProxy, UINT32 sn
    m_pRoutingTable = NULL;
    m_failTimeSNMP = 0;
    m_failTimeAgent = 0;
+   m_lastAgentCommTime = 0;
        m_linkLayerNeighbors = NULL;
        m_vrrpInfo = NULL;
        m_pTopology = NULL;
@@ -255,7 +257,8 @@ BOOL Node::loadFromDatabase(UINT32 dwId)
                _T("usm_priv_password,usm_methods,snmp_sys_name,bridge_base_addr,")
       _T("runtime_flags,down_since,boot_time,driver_name,icmp_proxy,")
       _T("agent_cache_mode,snmp_sys_contact,snmp_sys_location,")
-      _T("rack_id,rack_image,rack_position,rack_height FROM nodes WHERE id=?"));
+      _T("rack_id,rack_image,rack_position,rack_height,")
+      _T("last_agent_comm_time FROM nodes WHERE id=?"));
        if (hStmt == NULL)
                return FALSE;
 
@@ -337,6 +340,7 @@ BOOL Node::loadFromDatabase(UINT32 dwId)
    m_rackImage = DBGetFieldGUID(hResult, 0, 34);
    m_rackPosition = (INT16)DBGetFieldLong(hResult, 0, 35);
    m_rackHeight = (INT16)DBGetFieldLong(hResult, 0, 36);
+   m_lastAgentCommTime = DBGetFieldLong(hResult, 0, 37);
 
    DBFreeResult(hResult);
        DBFreeStatement(hStmt);
@@ -431,7 +435,7 @@ BOOL Node::saveToDatabase(DB_HANDLE hdb)
                        _T("platform_name=?,poller_node_id=?,zone_guid=?,proxy_node=?,snmp_proxy=?,icmp_proxy=?,required_polls=?,")
                        _T("use_ifxtable=?,usm_auth_password=?,usm_priv_password=?,usm_methods=?,snmp_sys_name=?,bridge_base_addr=?,")
                        _T("runtime_flags=?,down_since=?,driver_name=?,rack_image=?,rack_position=?,rack_height=?,rack_id=?,boot_time=?,")
-         _T("agent_cache_mode=?,snmp_sys_contact=?,snmp_sys_location=? WHERE id=?"));
+         _T("agent_cache_mode=?,snmp_sys_contact=?,snmp_sys_location=?,last_agent_comm_time=? WHERE id=?"));
        }
    else
        {
@@ -440,8 +444,8 @@ BOOL Node::saveToDatabase(DB_HANDLE hdb)
                  _T("agent_port,auth_method,secret,snmp_oid,uname,agent_version,platform_name,poller_node_id,zone_guid,")
                  _T("proxy_node,snmp_proxy,icmp_proxy,required_polls,use_ifxtable,usm_auth_password,usm_priv_password,usm_methods,")
                  _T("snmp_sys_name,bridge_base_addr,runtime_flags,down_since,driver_name,rack_image,rack_position,rack_height,rack_id,boot_time,")
-        _T("agent_cache_mode,snmp_sys_contact,snmp_sys_location,id) ")
-                 _T("VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"));
+        _T("agent_cache_mode,snmp_sys_contact,snmp_sys_location,last_agent_comm_time,id) ")
+                 _T("VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"));
        }
        if (hStmt == NULL)
        {
@@ -497,7 +501,8 @@ BOOL Node::saveToDatabase(DB_HANDLE hdb)
    DBBind(hStmt, 35, DB_SQLTYPE_VARCHAR, _itot(m_agentCacheMode, cacheMode, 10), DB_BIND_STATIC);
    DBBind(hStmt, 36, DB_SQLTYPE_VARCHAR, m_sysContact, DB_BIND_STATIC);
    DBBind(hStmt, 37, DB_SQLTYPE_VARCHAR, m_sysLocation, DB_BIND_STATIC);
-       DBBind(hStmt, 38, DB_SQLTYPE_INTEGER, m_id);
+       DBBind(hStmt, 38, DB_SQLTYPE_INTEGER, (LONG)m_lastAgentCommTime);       // rack ID
+       DBBind(hStmt, 39, DB_SQLTYPE_INTEGER, m_id);
 
        BOOL bResult = DBExecute(hStmt);
        DBFreeStatement(hStmt);
@@ -3409,6 +3414,7 @@ bool Node::connectToAgent(UINT32 *error, UINT32 *socketError, bool *newConnectio
                        DbgPrintf(7, _T("Node::connectToAgent(%s [%d]): already connected"), m_name, m_id);
          if (newConnection != NULL)
             *newConnection = false;
+         setLastAgentCommTime();
                        return TRUE;
                }
 
@@ -3441,6 +3447,7 @@ bool Node::connectToAgent(UINT32 *error, UINT32 *socketError, bool *newConnectio
       }
       m_pAgentConnection->enableTraps();
       setFileUpdateConn(NULL);
+      setLastAgentCommTime();
       CALL_ALL_MODULES(pfOnConnectToAgent, (this, m_pAgentConnection));
        }
    return success;
@@ -3765,9 +3772,11 @@ UINT32 Node::getItemFromAgent(const TCHAR *szParam, UINT32 dwBufSize, TCHAR *szB
       {
          case ERR_SUCCESS:
             dwResult = DCE_SUCCESS;
+            setLastAgentCommTime();
             goto end_loop;
          case ERR_UNKNOWN_PARAMETER:
             dwResult = DCE_NOT_SUPPORTED;
+            setLastAgentCommTime();
             goto end_loop;
          case ERR_NOT_CONNECTED:
          case ERR_CONNECTION_BROKEN:
@@ -3822,9 +3831,11 @@ UINT32 Node::getTableFromAgent(const TCHAR *name, Table **table)
       {
          case ERR_SUCCESS:
             dwResult = DCE_SUCCESS;
+            setLastAgentCommTime();
             goto end_loop;
          case ERR_UNKNOWN_PARAMETER:
             dwResult = DCE_NOT_SUPPORTED;
+            setLastAgentCommTime();
             goto end_loop;
          case ERR_NOT_CONNECTED:
          case ERR_CONNECTION_BROKEN:
@@ -3882,9 +3893,11 @@ UINT32 Node::getListFromAgent(const TCHAR *name, StringList **list)
                                *list = new StringList;
                                for(i = 0; i < m_pAgentConnection->getNumDataLines(); i++)
                                        (*list)->add(m_pAgentConnection->getDataLine(i));
+            setLastAgentCommTime();
             goto end_loop;
          case ERR_UNKNOWN_PARAMETER:
             dwResult = DCE_NOT_SUPPORTED;
+            setLastAgentCommTime();
             goto end_loop;
          case ERR_NOT_CONNECTED:
          case ERR_CONNECTION_BROKEN:
@@ -4294,6 +4307,7 @@ void Node::fillMessageInternal(NXCPMessage *pMsg)
    pMsg->setField(VID_SYS_CONTACT, CHECK_NULL_EX(m_sysContact));
    pMsg->setField(VID_SYS_LOCATION, CHECK_NULL_EX(m_sysLocation));
    pMsg->setField(VID_BOOT_TIME, (UINT32)m_bootTime);
+   pMsg->setField(VID_AGENT_COMM_TIME, (UINT32)m_lastAgentCommTime);
        pMsg->setField(VID_BRIDGE_BASE_ADDRESS, m_baseBridgeAddress, 6);
        if (m_lldpNodeId != NULL)
                pMsg->setField(VID_LLDP_NODE_ID, m_lldpNodeId);
@@ -4868,6 +4882,8 @@ AgentConnectionEx *Node::createAgentConnection()
       delete conn;
       conn = NULL;
    }
+   else
+      setLastAgentCommTime();
        DbgPrintf(6, _T("Node::createAgentConnection(%s [%d]): conn=%p"), m_name, (int)m_id, conn);
    return conn;
 }
index 6a57162..43c969c 100644 (file)
@@ -1183,6 +1183,7 @@ protected:
        time_t m_downSince;
    time_t m_bootTime;
    time_t m_agentUpTime;
+   time_t m_lastAgentCommTime;
    MUTEX m_hPollerMutex;
    MUTEX m_hAgentAccessMutex;
    MUTEX m_hSmclpAccessMutex;
@@ -1266,6 +1267,7 @@ protected:
        bool updateInterfaceConfiguration(UINT32 rqid, int maskBits);
    bool deleteDuplicateInterfaces(UINT32 rqid);
    void updateRackBinding();
+   void setLastAgentCommTime() {m_lastAgentCommTime = time(NULL); setModified();}
 
        void buildIPTopologyInternal(nxmap_ObjList &topology, int nDepth, UINT32 seedObject, bool vpnLink, bool includeEndNodes);
 
index 9890d90..2ebcb83 100644 (file)
@@ -573,6 +573,20 @@ static bool ConvertObjectToolMacros(UINT32 id, const TCHAR *text, const TCHAR *c
    return SQLQuery(query);
 }
 
+/**
+ * Upgrade from V375 to V376
+ */
+static BOOL H_UpgradeFromV375(int currVersion, int newVersion)
+{
+   static TCHAR batch[] =
+      _T("ALTER TABLE nodes ADD last_agent_comm_time integer\n")
+      _T("<END>");
+   CHK_EXEC(SQLBatch(batch));
+
+   CHK_EXEC(SQLQuery(_T("UPDATE metadata SET var_value='376' WHERE var_name='SchemaVersion'")));
+   return TRUE;
+}
+
 /**
  * Upgrade from V374 to V375
  */
@@ -9015,6 +9029,7 @@ static struct
    { 372, 373, H_UpgradeFromV372 },
    { 373, 374, H_UpgradeFromV373 },
    { 374, 375, H_UpgradeFromV374 },
+   { 375, 376, H_UpgradeFromV375 },
    { 0, 0, NULL }
 };
 
index d51320c..aa2bd11 100644 (file)
@@ -126,6 +126,8 @@ public class GeneralInfo extends TableElement
                                addPair(Messages.get().GeneralInfo_Driver, node.getDriverName(), false);
             if (node.getBootTime() != null)
                addPair(Messages.get().GeneralInfo_BootTime, RegionalSettings.getDateTimeFormat().format(node.getBootTime()), false);
+            if (node.getLastAgentCommTime() != null)
+               addPair("Agent Last Communication Time", RegionalSettings.getDateTimeFormat().format(node.getLastAgentCommTime()), false);
             if (node.getRackId() != 0)
             {
                Rack rack = session.findObjectById(node.getRackId(), Rack.class);