Service status polling implemented
authorVictor Kirhenshtein <victor@netxms.org>
Sun, 30 Jan 2005 22:55:08 +0000 (22:55 +0000)
committerVictor Kirhenshtein <victor@netxms.org>
Sun, 30 Jan 2005 22:55:08 +0000 (22:55 +0000)
src/console/win32/NodePropsPolling.cpp
src/console/win32/NodePropsPolling.h
src/console/win32/nxcon.clw
src/server/core/netsrv.cpp
src/server/core/node.cpp
src/server/include/nms_objects.h

index 4be0881..5a45695 100644 (file)
@@ -116,3 +116,15 @@ void CNodePropsPolling::OnSelectPoller()
       SetModified();
    }
 }
+
+
+//
+// Handler for "OK" button
+//
+
+void CNodePropsPolling::OnOK() 
+{
+       CPropertyPage::OnOK();
+
+   m_pUpdate->dwPollerNode = m_dwPollerNode;
+}
index 441a3e4..68a0db2 100644 (file)
@@ -32,6 +32,8 @@ public:
 // Overrides
        // ClassWizard generate virtual function overrides
        //{{AFX_VIRTUAL(CNodePropsPolling)
+       public:
+       virtual void OnOK();
        protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
        //}}AFX_VIRTUAL
index e330e86..0aae555 100644 (file)
@@ -16,9 +16,9 @@ Class7=CEventBrowser
 Class9=CMapView
 
 ResourceCount=113
-Resource1=IDD_NEW_ACTION (English (U.S.))
+Resource1=IDD_SET_PASSWORD (English (U.S.))
 Resource2=IDD_OBJECT_NODE_GENERAL
-Resource3=IDA_EPP (English (U.S.))
+Resource3=IDD_DATA_QUERY (English (U.S.))
 Resource4=IDD_SELECT_OBJECT
 Resource5=IDD_SELECT_ACTION
 Class2=CChildView
@@ -32,9 +32,9 @@ Resource7=IDD_NEW_USER
 Class12=CObjectBrowser
 Resource8=IDD_CREATE_CONTAINER
 Class13=CObjectPropDlg
-Resource9=IDD_DATA_QUERY (English (U.S.))
-Resource10=IDA_ACTION_EDITOR (English (U.S.))
-Resource11=IDD_NEW_USER (English (U.S.))
+Resource9=IDD_OBJECT_PRESENTATION (English (U.S.))
+Resource10=IDD_SELECT_INTERNAL_ITEM (English (U.S.))
+Resource11=IDA_TRAP_EDITOR (English (U.S.))
 Resource12=IDR_CTRLPANEL (English (U.S.))
 Resource13=IDR_EVENTS (English (U.S.))
 Resource14=IDR_MAPFRAME (English (U.S.))
@@ -42,33 +42,33 @@ Resource15=IDR_OBJECTS (English (U.S.))
 Resource16=IDD_DUMMY (English (U.S.))
 Class14=CEventEditor
 Class15=CEditEventDlg
-Resource17=IDD_MIB_BROWSER (English (U.S.))
+Resource17=IDD_OBJECT_CAPS (English (U.S.))
 Class16=CDebugFrame
-Resource18=IDD_REQUEST_PROCESSING (English (U.S.))
+Resource18=IDA_ALARM_BROWSER (English (U.S.))
 Resource19=IDD_OBJECT_PROPERTIES (English (U.S.))
 Resource20=IDD_SELECT_EVENT
 Class17=CObjectPreview
-Resource21=IDD_CREATE_NETSRV (English (U.S.))
+Resource21=IDD_CREATE_CONTAINER (English (U.S.))
 Class18=CToolBox
 Class19=CObjectInfoBox
 Class20=CObjectSearchBox
-Resource22=IDD_DCI_TRANSFORM (English (U.S.))
+Resource22=IDD_SELECT_OBJECT (English (U.S.))
 Class21=CEditBox
 Class22=COPGeneral
 Class23=CNodePropsGeneral
-Resource23=IDD_OBJECT_SECURITY (English (U.S.))
+Resource23=IDA_EVENT_EDITOR (English (U.S.))
 Class24=CObjectPropCaps
 Class25=CObjectPropSheet
 Resource24=IDA_MDI_DEFAULT
 Class26=CRequestProcessingDlg
-Resource25=IDD_SELECT_USER (English (U.S.))
+Resource25=IDA_ACTION_EDITOR (English (U.S.))
 Resource26=IDD_PROGRESS (English (U.S.))
 Resource27=IDD_EDIT_RULE_ALARM
-Resource28=IDD_OBJECT_NODE_GENERAL (English (U.S.))
+Resource28=IDA_OBJECT_BROWSER (English (U.S.))
 Class27=CObjectPropsGeneral
-Resource29=IDA_GRAPH (English (U.S.))
+Resource29=IDD_INPUT_BOX (English (U.S.))
 Class28=CObjectPropsSecurity
-Resource30=IDD_SELECT_AGENT_PARAM (English (U.S.))
+Resource30=IDD_ACTION_PROPERTIES (English (U.S.))
 Resource31=IDD_SELECT_USER
 Resource32=IDD_OBJECT_SECURITY
 Class29=CUserSelectDlg
@@ -79,36 +79,36 @@ Class31=CNewUserDlg
 Resource35=IDD_THRESHOLD
 Resource36=IDA_EPP
 Class32=CUserPropDlg
-Resource37=IDA_ALARM_BROWSER (English (U.S.))
+Resource37=IDD_EDIT_TRAP (English (U.S.))
 Resource38=IDD_ABOUTBOX
 Class33=CGroupPropDlg
 Resource39=IDD_CP_GENERAL
 Resource40=IDA_TRAP_EDITOR
 Resource41=IDM_VIEW_SPECIFIC
-Resource42=IDD_SELECT_OBJECT (English (U.S.))
+Resource42=IDD_REQUEST_PROCESSING (English (U.S.))
 Class34=CPasswordChangeDlg
 Class35=CNodeSummary
 Class36=CNetSummaryFrame
 Class37=CDataCollectionEditor
-Resource43=IDD_GRAPH_PROPERTIES (English (U.S.))
+Resource43=IDD_CP_GENERAL (English (U.S.))
 Class38=CDCIPropPage
-Resource44=IDD_THRESHOLD (English (U.S.))
+Resource44=IDD_OBJECT_NODE_GENERAL (English (U.S.))
 Class39=CDCIDataView
-Resource45=IDA_MDI_DEFAULT (English (U.S.))
+Resource45=IDD_CREATE_TG (English (U.S.))
 Class40=CGraph
 Class41=CGraphFrame
 Class42=CDCIThresholdsPage
-Resource46=IDD_EDIT_TRAP (English (U.S.))
-Resource47=IDD_SET_PASSWORD (English (U.S.))
+Resource46=IDD_EDIT_RULE_SEVERITY (English (U.S.))
+Resource47=IDD_ABOUTBOX (English (U.S.))
 Resource48=IDM_CONTEXT
 Class43=CThresholdDlg
-Resource49=IDD_EDIT_RULE_COMMENT (English (U.S.))
+Resource49=IDD_OBJECT_GENERAL (English (U.S.))
 Resource50=IDD_EDIT_TRAP_ARG
 Class44=CMIBBrowserDlg
 Class45=CEventPolicyEditor
 Class46=CRuleList
 Class47=CRuleHeader
-Resource51=IDA_NETMAP (English (U.S.))
+Resource51=IDD_EDIT_TRAP_ARG (English (U.S.))
 Resource52=IDD_CREATE_NODE
 Class48=CObjectSelDlg
 Resource53=IDD_OBJECT_CAPS
@@ -117,22 +117,22 @@ Class49=CRuleCommentDlg
 Resource55=IDD_DCI_COLLECTION
 Class50=CEventSelDlg
 Resource56=IDD_DATA_QUERY
-Resource57=IDD_DCI_COLLECTION (English (U.S.))
+Resource57=IDD_LOGIN (English (U.S.))
 Resource58=IDD_CREATE_TG
-Resource59=IDD_SELECT_EVENT (English (U.S.))
-Resource60=IDD_SELECT_ACTION (English (U.S.))
+Resource59=IDD_OBJECT_SECURITY (English (U.S.))
+Resource60=IDD_DCI_THRESHOLDS (English (U.S.))
 Class51=CObjectPropsPresentation
-Resource61=IDD_CREATE_NODE (English (U.S.))
+Resource61=IDD_MIB_BROWSER (English (U.S.))
 Resource62=IDD_EDIT_RULE_COMMENT
 Class52=CRuleSeverityDlg
 Resource63=IDD_ACTION_PROPERTIES
 Class53=CRuleAlarmDlg
 Class54=CAlarmBrowser
-Resource64=IDD_OBJECT_CAPS (English (U.S.))
+Resource64=IDA_EPP (English (U.S.))
 Resource65=IDD_DCI_TRANSFORM
-Resource66=IDA_EVENT_EDITOR (English (U.S.))
-Resource67=IDD_ACTION_PROPERTIES (English (U.S.))
-Resource68=IDD_EDIT_RULE_SEVERITY (English (U.S.))
+Resource66=IDD_GRAPH_PROPERTIES (English (U.S.))
+Resource67=IDD_DCI_COLLECTION (English (U.S.))
+Resource68=IDD_NEW_USER (English (U.S.))
 Class55=CConsolePropsGeneral
 Class56=CActionEditor
 Resource69=IDA_ACTION_EDITOR
@@ -143,18 +143,18 @@ Class58=CEditActionDlg
 Resource72=IDA_NETMAP
 Class59=CActionSelDlg
 Resource73=IDD_MIB_BROWSER
-Resource74=IDD_EDIT_RULE_ALARM (English (U.S.))
-Resource75=IDD_CREATE_TEMPLATE (English (U.S.))
+Resource74=IDD_USER_PROPERTIES (English (U.S.))
+Resource75=IDD_SELECT_EVENT (English (U.S.))
 Resource76=IDD_USER_PROPERTIES
 Class60=CCreateObjectDlg
 Class61=CCreateContainerDlg
 Resource77=IDR_MAINFRAME
 Class62=CCreateNodeDlg
-Resource78=IDA_TRAP_EDITOR (English (U.S.))
-Resource79=IDD_SELECT_INTERNAL_ITEM (English (U.S.))
-Resource80=IDD_DCI_THRESHOLDS (English (U.S.))
+Resource78=IDD_SELECT_AGENT_PARAM (English (U.S.))
+Resource79=IDD_NEW_ACTION (English (U.S.))
+Resource80=IDD_EDIT_EVENT (English (U.S.))
 Class63=CDCITransformPage
-Resource81=IDD_EDIT_TRAP_ARG (English (U.S.))
+Resource81=IDD_EDIT_RULE_ALARM (English (U.S.))
 Class64=CPollNodeDlg
 Resource82=IDD_POLL_NODE (English (U.S.))
 Class65=CNodePoller
@@ -180,28 +180,28 @@ Class73=CColorSelector
 Class74=CPackageMgr
 Resource94=IDD_GROUP_PROPERTIES
 Resource95=IDD_GRAPH_PROPERTIES
-Resource96=IDA_PACKAGE_MGR (English (U.S.))
-Resource97=IDD_ABOUTBOX (English (U.S.))
-Resource98=IDD_LOGIN (English (U.S.))
-Resource99=IDD_EDIT_EVENT (English (U.S.))
-Resource100=IDD_OBJECT_PRESENTATION (English (U.S.))
-Resource101=IDD_CP_GENERAL (English (U.S.))
-Resource102=IDD_OBJECT_NETSRV_GENERAL (English (U.S.))
-Resource103=IDR_MAINFRAME (English (U.S.))
-Resource104=IDA_OBJECT_BROWSER (English (U.S.))
+Resource96=IDD_CREATE_NETSRV (English (U.S.))
+Resource97=IDD_OBJECT_NETSRV_GENERAL (English (U.S.))
+Resource98=IDR_MAINFRAME (English (U.S.))
+Resource99=IDA_MDI_DEFAULT (English (U.S.))
+Resource100=IDD_SELECT_USER (English (U.S.))
+Resource101=IDD_GROUP_PROPERTIES (English (U.S.))
+Resource102=IDD_CREATE_NODE (English (U.S.))
+Resource103=IDD_DCI_TRANSFORM (English (U.S.))
+Resource104=IDD_CREATE_TEMPLATE (English (U.S.))
 Resource105=IDM_CONTEXT (English (U.S.))
 Resource106=IDM_VIEW_SPECIFIC (English (U.S.))
-Resource107=IDD_GROUP_PROPERTIES (English (U.S.))
+Resource107=IDA_PACKAGE_MGR (English (U.S.))
 Class75=CInternalItemSelDlg
-Resource108=IDD_CREATE_CONTAINER (English (U.S.))
+Resource108=IDD_THRESHOLD (English (U.S.))
 Class76=CAgentParamSelDlg
-Resource109=IDD_USER_PROPERTIES (English (U.S.))
+Resource109=IDA_GRAPH (English (U.S.))
 Class77=CInputBox
-Resource110=IDD_INPUT_BOX (English (U.S.))
+Resource110=IDD_SELECT_ACTION (English (U.S.))
 Class78=CCreateNetSrvDlg
-Resource111=IDD_OBJECT_GENERAL (English (U.S.))
+Resource111=IDA_NETMAP (English (U.S.))
 Class79=CNetSrvPropsGeneral
-Resource112=IDD_CREATE_TG (English (U.S.))
+Resource112=IDD_EDIT_RULE_COMMENT (English (U.S.))
 Class80=CNodePropsPolling
 Resource113=IDD_OBJECT_NODE_POLL (English (U.S.))
 
index 48063ef..e40215e 100644 (file)
@@ -32,7 +32,7 @@ NetworkService::NetworkService()
 {
    m_iServiceType = NETSRV_HTTP;
    m_pHostNode = NULL;
-   m_pPollNode = NULL;
+   m_dwPollerNode = 0;
    m_wProto = IPPROTO_TCP;
    m_wPort = 80;
    m_pszRequest = NULL;
@@ -48,11 +48,11 @@ NetworkService::NetworkService()
 
 NetworkService::NetworkService(int iServiceType, WORD wProto, WORD wPort,
                                TCHAR *pszRequest, TCHAR *pszResponce,
-                               Node *pHostNode, Node *pPollNode)
+                               Node *pHostNode, DWORD dwPollerNode)
 {
    m_iServiceType = iServiceType;
    m_pHostNode = pHostNode;
-   m_pPollNode = pPollNode;
+   m_dwPollerNode = dwPollerNode;
    m_wProto = wProto;
    m_wPort = wPort;
    m_pszRequest = pszRequest;
@@ -99,19 +99,19 @@ BOOL NetworkService::SaveToDB(void)
    if (bNewObject)
       _sntprintf(szQuery, 16384, _T("INSERT INTO network_services (id,name,status,is_deleted,"
                                     "node_id,service_type,ip_bind_addr,ip_proto,ip_port,"
-                                    "check_request,check_responce,poll_node_id,image_id) VALUES "
+                                    "check_request,check_responce,poller_node_id,image_id) VALUES "
                                     "(%ld,'%s',%d,%d,%ld,%d,'%s',%d,%d,'%s','%s',%ld,%ld)"),
                  m_dwId, m_szName, m_iStatus, m_bIsDeleted, m_pHostNode->Id(), m_iServiceType,
                  IpToStr(m_dwIpAddr, szIpAddr), m_wProto, m_wPort, pszEscRequest,
-                 pszEscResponce, (m_pPollNode == NULL) ? 0 : m_pPollNode->Id(), m_dwImageId);
+                 pszEscResponce, m_dwPollerNode, m_dwImageId);
    else
       _sntprintf(szQuery, 16384, _T("UPDATE network_services SET name='%s',status=%d,"
                                     "is_deleted=%d,node_id=%ld,service_type=%d,ip_bind_addr='%s',"
                                     "ip_proto=%d,ip_port=%d,check_request='%s',"
-                                    "check_responce='%s',poll_node_id=%ld,image_id=%ld WHERE id=%ld"),
+                                    "check_responce='%s',poller_node_id=%ld,image_id=%ld WHERE id=%ld"),
                  m_szName, m_iStatus, m_bIsDeleted, m_pHostNode->Id(), m_iServiceType,
                  IpToStr(m_dwIpAddr, szIpAddr), m_wProto, m_wPort, pszEscRequest,
-                 pszEscResponce, (m_pPollNode == NULL) ? 0 : m_pPollNode->Id(), m_dwImageId, m_dwId);
+                 pszEscResponce, m_dwPollerNode, m_dwImageId, m_dwId);
    free(pszEscRequest);
    free(pszEscResponce);
    DBQuery(g_hCoreDB, szQuery);
@@ -134,7 +134,7 @@ BOOL NetworkService::CreateFromDB(DWORD dwId)
 {
    TCHAR szQuery[256];
    DB_RESULT hResult;
-   DWORD dwHostNodeId, dwPollNodeId;
+   DWORD dwHostNodeId;
    NetObj *pObject;
    BOOL bResult = FALSE;
 
@@ -142,7 +142,7 @@ BOOL NetworkService::CreateFromDB(DWORD dwId)
 
    _sntprintf(szQuery, 256, _T("SELECT name,status,is_deleted,node_id,service_type,"
                                "ip_bind_addr,ip_proto,ip_port,check_request,check_responce,"
-                               "poll_node_id,image_id FROM network_services WHERE id=%ld"), dwId);
+                               "poller_node_id,image_id FROM network_services WHERE id=%ld"), dwId);
    hResult = DBSelect(g_hCoreDB, szQuery);
    if (hResult == NULL)
       return FALSE;     // Query failed
@@ -159,7 +159,7 @@ BOOL NetworkService::CreateFromDB(DWORD dwId)
       m_wPort = (WORD)DBGetFieldULong(hResult, 0, 7);
       m_pszRequest = _tcsdup(CHECK_NULL_EX(DBGetField(hResult, 0, 8)));
       m_pszResponce = _tcsdup(CHECK_NULL_EX(DBGetField(hResult, 0, 9)));
-      dwPollNodeId = DBGetFieldULong(hResult, 0, 10);
+      m_dwPollerNode = DBGetFieldULong(hResult, 0, 10);
       m_dwImageId = DBGetFieldULong(hResult, 0, 11);
 
       // Link service to node
@@ -183,24 +183,20 @@ BOOL NetworkService::CreateFromDB(DWORD dwId)
             bResult = TRUE;
          }
 
-         // Find polling node
-         if ((dwPollNodeId != 0) && bResult)
+         // Check that polling node ID is valid
+         if ((m_dwPollerNode != 0) && bResult)
          {
-            pObject = FindObjectById(dwPollNodeId);
+            pObject = FindObjectById(m_dwPollerNode);
             if (pObject == NULL)
             {
-               WriteLog(MSG_INVALID_NODE_ID, EVENTLOG_ERROR_TYPE, "dd", dwId, dwPollNodeId);
+               WriteLog(MSG_INVALID_NODE_ID, EVENTLOG_ERROR_TYPE, "dd", dwId, m_dwPollerNode);
                bResult = FALSE;
             }
             else if (pObject->Type() != OBJECT_NODE)
             {
-               WriteLog(MSG_NODE_NOT_NODE, EVENTLOG_ERROR_TYPE, "dd", dwId, dwPollNodeId);
+               WriteLog(MSG_NODE_NOT_NODE, EVENTLOG_ERROR_TYPE, "dd", dwId, m_dwPollerNode);
                bResult = FALSE;
             }
-            else
-            {
-               m_pPollNode = (Node *)pObject;
-            }
          }
       }
       else
@@ -247,7 +243,7 @@ void NetworkService::CreateMessage(CSCPMessage *pMsg)
    pMsg->SetVariable(VID_SERVICE_TYPE, (WORD)m_iServiceType);
    pMsg->SetVariable(VID_IP_PROTO, m_wProto);
    pMsg->SetVariable(VID_IP_PORT, m_wPort);
-   pMsg->SetVariable(VID_POLLER_NODE_ID, (m_pPollNode == NULL) ? 0 : m_pPollNode->Id());
+   pMsg->SetVariable(VID_POLLER_NODE_ID, m_dwPollerNode);
    pMsg->SetVariable(VID_SERVICE_REQUEST, CHECK_NULL_EX(m_pszRequest));
    pMsg->SetVariable(VID_SERVICE_RESPONCE, CHECK_NULL_EX(m_pszResponce));
 }
@@ -270,7 +266,7 @@ DWORD NetworkService::ModifyFromMessage(CSCPMessage *pRequest, BOOL bAlreadyLock
       dwNodeId = pRequest->GetVariableLong(VID_POLLER_NODE_ID);
       if (dwNodeId == 0)
       {
-         m_pPollNode = NULL;
+         m_dwPollerNode = 0;
       }
       else
       {
@@ -281,7 +277,7 @@ DWORD NetworkService::ModifyFromMessage(CSCPMessage *pRequest, BOOL bAlreadyLock
          {
             if (pObject->Type() == OBJECT_NODE)
             {
-               m_pPollNode = (Node *)pObject;
+               m_dwPollerNode = dwNodeId;
             }
             else
             {
@@ -338,6 +334,7 @@ DWORD NetworkService::ModifyFromMessage(CSCPMessage *pRequest, BOOL bAlreadyLock
 void NetworkService::StatusPoll(ClientSession *pSession, DWORD dwRqId, Node *pPollerNode)
 {
    int iOldStatus = m_iStatus;
+   Node *pNode;
 
    m_pPollRequestor = pSession;
    if (m_pHostNode == NULL)
@@ -350,6 +347,46 @@ void NetworkService::StatusPoll(ClientSession *pSession, DWORD dwRqId, Node *pPo
                          "      Current status is %s\r\n",
                  m_szName, g_pszStatusName[m_iStatus]);
 
+   if (m_dwPollerNode != 0)
+   {
+      pNode = (Node *)FindObjectById(m_dwPollerNode);
+      if (pNode != NULL)
+         pNode->IncRefCount();
+      else
+         pNode = pPollerNode;
+   }
+   else
+   {
+      pNode = pPollerNode;
+   }
+
+   if (pNode != NULL)
+   {
+      TCHAR szBuffer[16];
+      DWORD dwStatus;
+
+      SendPollerMsg(dwRqId, "      Polling service from node %s [%s]\r\n",
+                    pNode->Name(), IpToStr(pNode->IpAddr(), szBuffer));
+      if (pNode->CheckNetworkService(&dwStatus, 
+                                     (m_dwIpAddr == 0) ? m_pHostNode->IpAddr() : m_dwIpAddr,
+                                     m_iServiceType, m_wPort, m_wProto, 
+                                     m_pszRequest, m_pszResponce) == ERR_SUCCESS)
+      {
+         m_iStatus = (dwStatus == 0) ? STATUS_NORMAL : STATUS_CRITICAL;
+         SendPollerMsg(dwRqId, "      Agent reports service status [%d]\r\n", dwStatus);
+      }
+      else
+      {
+         SendPollerMsg(dwRqId, "      Unable to check service status due to agent or communication error\r\n");
+         m_iStatus = STATUS_UNKNOWN;
+      }
+   }
+   else
+   {
+      SendPollerMsg(dwRqId, "      Unable to find node object for poll\r\n");
+      m_iStatus = STATUS_UNKNOWN;
+   }
+
    if (m_iStatus != iOldStatus)
    {
       SendPollerMsg(dwRqId, "      Service status changed to %s\r\n", g_pszStatusName[m_iStatus]);
index 966c60c..2d95a10 100644 (file)
@@ -53,6 +53,7 @@ Node::Node()
    m_szPlatformName[0] = 0;
    m_dwNumParams = 0;
    m_pParamList = NULL;
+   m_dwPollerNode = 0;
 }
 
 
@@ -88,6 +89,7 @@ Node::Node(DWORD dwAddr, DWORD dwFlags, DWORD dwDiscoveryFlags)
    m_szPlatformName[0] = 0;
    m_dwNumParams = 0;
    m_pParamList = NULL;
+   m_dwPollerNode = 0;
 }
 
 
@@ -122,7 +124,7 @@ BOOL Node::CreateFromDB(DWORD dwId)
                             "is_router,snmp_version,discovery_flags,auth_method,secret,"
                             "agent_port,status_poll_type,community,snmp_oid,is_local_mgmt,"
                             "image_id,is_deleted,description,node_type,agent_version,"
-                            "platform_name FROM nodes WHERE id=%d", dwId);
+                            "platform_name,poller_node_id FROM nodes WHERE id=%d", dwId);
    hResult = DBSelect(g_hCoreDB, szQuery);
    if (hResult == 0)
       return FALSE;     // Query failed
@@ -167,6 +169,7 @@ BOOL Node::CreateFromDB(DWORD dwId)
    DecodeSQLString(m_szAgentVersion);
    _tcsncpy(m_szPlatformName, CHECK_NULL_EX(DBGetField(hResult, 0, 22)), MAX_PLATFORM_NAME_LEN);
    DecodeSQLString(m_szPlatformName);
+   m_dwPollerNode = DBGetFieldULong(hResult, 0, 23);
 
    DBFreeResult(hResult);
 
@@ -260,9 +263,9 @@ BOOL Node::SaveToDB(void)
                "is_snmp,is_agent,is_bridge,is_router,snmp_version,community,"
                "discovery_flags,status_poll_type,agent_port,auth_method,secret,"
                "snmp_oid,is_local_mgmt,image_id,description,node_type,"
-               "agent_version,platform_name)"
+               "agent_version,platform_name,poller_node_id)"
                " VALUES (%d,'%s',%d,%d,'%s',%d,%d,%d,%d,%d,'%s',%d,%d,%d,%d,"
-               "'%s','%s',%d,%ld,'%s',%ld,'%s','%s')",
+               "'%s','%s',%d,%ld,'%s',%ld,'%s','%s',%ld)",
                m_dwId, m_szName, m_iStatus, m_bIsDeleted, 
                IpToStr(m_dwIpAddr, szIpAddr),
                m_dwFlags & NF_IS_SNMP ? 1 : 0,
@@ -272,7 +275,7 @@ BOOL Node::SaveToDB(void)
                m_iSNMPVersion, m_szCommunityString, m_dwDiscoveryFlags, m_iStatusPollType,
                m_wAgentPort,m_wAuthMethod,m_szSharedSecret, m_szObjectId,
                m_dwFlags & NF_IS_LOCAL_MGMT ? 1 : 0, m_dwImageId,
-               pszEscDescr, m_dwNodeType, pszEscVersion, pszEscPlatform);
+               pszEscDescr, m_dwNodeType, pszEscVersion, pszEscPlatform, m_dwPollerNode);
    else
       snprintf(szQuery, 4096,
                "UPDATE nodes SET name='%s',status=%d,is_deleted=%d,primary_ip='%s',"
@@ -280,7 +283,7 @@ BOOL Node::SaveToDB(void)
                "community='%s',discovery_flags=%d,status_poll_type=%d,agent_port=%d,"
                "auth_method=%d,secret='%s',snmp_oid='%s',is_local_mgmt=%d,"
                "image_id=%ld,description='%s',node_type=%ld,agent_version='%s',"
-               "platform_name='%s' WHERE id=%ld",
+               "platform_name='%s',poller_node_id=%ld WHERE id=%ld",
                m_szName, m_iStatus, m_bIsDeleted, 
                IpToStr(m_dwIpAddr, szIpAddr), 
                m_dwFlags & NF_IS_SNMP ? 1 : 0,
@@ -290,7 +293,8 @@ BOOL Node::SaveToDB(void)
                m_iSNMPVersion, m_szCommunityString, m_dwDiscoveryFlags, 
                m_iStatusPollType, m_wAgentPort, m_wAuthMethod, m_szSharedSecret, 
                m_szObjectId, m_dwFlags & NF_IS_LOCAL_MGMT ? 1 : 0, m_dwImageId, 
-               pszEscDescr, m_dwNodeType, pszEscVersion, pszEscPlatform, m_dwId);
+               pszEscDescr, m_dwNodeType, pszEscVersion, pszEscPlatform,
+               m_dwPollerNode, m_dwId);
    bResult = DBQuery(g_hCoreDB, szQuery);
    free(pszEscDescr);
    free(pszEscVersion);
@@ -667,11 +671,36 @@ void Node::CalculateCompoundStatus(void)
 void Node::StatusPoll(ClientSession *pSession, DWORD dwRqId)
 {
    DWORD i;
+   NetObj *pPollerNode = NULL;
 
    PollerLock();
    m_pPollRequestor = pSession;
    SendPollerMsg(dwRqId, _T("Starting status poll for node %s\r\n"), m_szName);
    Lock();
+
+   // Find service poller node object
+   if (m_dwPollerNode != 0)
+   {
+      pPollerNode = FindObjectById(m_dwPollerNode);
+      if (pPollerNode != NULL)
+      {
+         if (pPollerNode->Type() != OBJECT_NODE)
+            pPollerNode = NULL;
+      }
+   }
+
+   // If nothing found, use management server
+   if (pPollerNode == NULL)
+   {
+      pPollerNode = FindObjectById(g_dwMgmtNode);
+      if (pPollerNode != NULL)
+         pPollerNode->IncRefCount();
+   }
+   else
+   {
+      pPollerNode->IncRefCount();
+   }
+
    for(i = 0; i < m_dwChildCount; i++)
       if (m_pChildList[i]->Status() != STATUS_UNMANAGED)
       {
@@ -681,13 +710,17 @@ void Node::StatusPoll(ClientSession *pSession, DWORD dwRqId)
                ((Interface *)m_pChildList[i])->StatusPoll(pSession, dwRqId);
                break;
             case OBJECT_NETWORKSERVICE:
-               ((NetworkService *)m_pChildList[i])->StatusPoll(pSession, dwRqId, m_pPollerNode);
+               ((NetworkService *)m_pChildList[i])->StatusPoll(pSession, dwRqId, (Node *)pPollerNode);
                break;
             default:
                break;
          }
       }
+   
+   if (pPollerNode != NULL)
+      pPollerNode->DecRefCount();
    Unlock();
+
    CalculateCompoundStatus();
    m_tLastStatusPoll = time(NULL);
    SendPollerMsg(dwRqId, "Finished status poll for node %s\r\n"
@@ -1102,6 +1135,7 @@ void Node::CreateMessage(CSCPMessage *pMsg)
    pMsg->SetVariable(VID_SNMP_VERSION, (WORD)m_iSNMPVersion);
    pMsg->SetVariable(VID_AGENT_VERSION, m_szAgentVersion);
    pMsg->SetVariable(VID_PLATFORM_NAME, m_szPlatformName);
+   pMsg->SetVariable(VID_POLLER_NODE_ID, m_dwPollerNode);
 }
 
 
@@ -1135,6 +1169,30 @@ DWORD Node::ModifyFromMessage(CSCPMessage *pRequest, BOOL bAlreadyLocked)
       m_dwIpAddr = dwIpAddr;
    }
 
+   // Poller node ID
+   if (pRequest->IsVariableExist(VID_POLLER_NODE_ID))
+   {
+      DWORD dwNodeId;
+      NetObj *pObject;
+      
+      dwNodeId = pRequest->GetVariableLong(VID_POLLER_NODE_ID);
+      pObject = FindObjectById(dwNodeId);
+
+      // Check if received id is a valid node id
+      if (pObject == NULL)
+      {
+         Unlock();
+         return RCC_INVALID_OBJECT_ID;
+      }
+      if (pObject->Type() != OBJECT_NODE)
+      {
+         Unlock();
+         return RCC_INVALID_OBJECT_ID;
+      }
+
+      m_dwPollerNode = dwNodeId;
+   }
+
    // Change listen port of native agent
    if (pRequest->IsVariableExist(VID_AGENT_PORT))
       m_wAgentPort = pRequest->GetVariableShort(VID_AGENT_PORT);
@@ -1267,3 +1325,47 @@ void Node::WriteParamListToMessage(CSCPMessage *pMsg)
    }
    Unlock();
 }
+
+
+//
+// Check status of network service
+//
+
+DWORD Node::CheckNetworkService(DWORD *pdwStatus, DWORD dwIpAddr, int iServiceType,
+                                WORD wPort, WORD wProto, TCHAR *pszRequest,
+                                TCHAR *pszResponce)
+{
+   DWORD dwError;
+   DWORD dwTries = 3;
+
+   AgentLock();
+
+   // Establish connection if needed
+   if (m_pAgentConnection == NULL)
+      if (!ConnectToAgent())
+      {
+         AgentUnlock();
+         return ERR_NOT_CONNECTED;
+      }
+
+   // Try to check service via agent
+   while(dwTries-- > 0)
+   {
+      dwError = m_pAgentConnection->CheckNetworkService(pdwStatus, dwIpAddr, iServiceType,
+                           wPort, wProto, pszRequest, pszResponce);
+      if ((dwError == ERR_NOT_CONNECTED) ||
+          (dwError == ERR_CONNECTION_BROKEN))
+      {
+         if (!ConnectToAgent())
+            break;
+      }
+      else
+      {
+         if (dwError != ERR_REQUEST_TIMEOUT)
+            break;
+      }
+   }
+
+   AgentUnlock();
+   return dwError;
+}
index 558ed3a..4997e13 100644 (file)
@@ -271,8 +271,8 @@ class NetworkService : public NetObj
 protected:
    int m_iServiceType;   // SSH, POP3, etc.
    Node *m_pHostNode;    // Pointer to node object which hosts this service
-   Node *m_pPollNode;    // Pointer to node object which is used for polling
-                         // If NULL, m_pHostNode->m_pPollNode will be used
+   DWORD m_dwPollerNode; // ID of node object which is used for polling
+                         // If 0, m_pHostNode->m_dwPollerNode will be used
    WORD m_wProto;        // Protocol (TCP, UDP, etc.)
    WORD m_wPort;         // TCP or UDP port number
    TCHAR *m_pszRequest;  // Service-specific request
@@ -282,7 +282,7 @@ public:
    NetworkService();
    NetworkService(int iServiceType, WORD wProto, WORD wPort,
                   TCHAR *pszRequest, TCHAR *pszResponce,
-                  Node *pHostNode = NULL, Node *pPollNode = NULL);
+                  Node *pHostNode = NULL, DWORD dwPollerNode = 0);
    virtual ~NetworkService();
 
    virtual int Type(void) { return OBJECT_NETWORKSERVICE; }
@@ -328,7 +328,7 @@ protected:
    MUTEX m_hPollerMutex;
    MUTEX m_hAgentAccessMutex;
    AgentConnection *m_pAgentConnection;
-   Node *m_pPollerNode;      // Node used for network service polling
+   DWORD m_dwPollerNode;      // Node used for network service polling
 
    void PollerLock(void) { MutexLock(m_hPollerMutex, INFINITE); }
    void PollerUnlock(void) { MutexUnlock(m_hPollerMutex); }
@@ -397,7 +397,8 @@ public:
    DWORD WakeUp(void);
 
    void AddService(NetworkService *pNetSrv) { AddChild(pNetSrv); pNetSrv->AddParent(this); }
-   Node *GetPollerNode(void) { return m_pPollerNode; }
+   DWORD CheckNetworkService(DWORD *pdwStatus, DWORD dwIpAddr, int iServiceType, WORD wPort = 0,
+                             WORD wProto = 0, TCHAR *pszRequest = NULL, TCHAR *pszResponce = NULL);
 };