- added ServiceContainer class, minor tweaks
authorAlex Kalimulin <alex@netxms.org>
Sun, 4 Sep 2011 21:16:25 +0000 (21:16 +0000)
committerAlex Kalimulin <alex@netxms.org>
Sun, 4 Sep 2011 21:16:25 +0000 (21:16 +0000)
src/server/core/bizservice.cpp
src/server/core/nodelink.cpp
src/server/core/nxcore.vcproj
src/server/core/svccontainer.cpp [copied from src/server/core/bizservice.cpp with 51% similarity]
src/server/include/nms_objects.h

index a51e90e..308baf6 100644 (file)
 
 #define QUERY_LENGTH           (512)
 
-LONG BusinessService::logRecordId = -1;
-
-
 //
 // Service default constructor
 //
 
-BusinessService::BusinessService() : Container()
+BusinessService::BusinessService()
 {
        m_busy = false;
        m_lastPollTime = time_t(0);
-       m_lastPollStatus = m_prevUptimeUpdateStatus = STATUS_UNKNOWN;
-       m_prevUptimeUpdateTime = time(NULL);
+       m_lastPollStatus = STATUS_UNKNOWN;
        _tcscpy(m_szName, _T("Default"));
-       m_uptimeDay = 100.0;
-       m_uptimeWeek = 100.0;
-       m_uptimeMonth = 100.0;
-       m_downtimeDay = 0;
-       m_downtimeWeek = 0;
-       m_downtimeMonth = 0;
-       m_prevDiffDay = 0;
-       m_prevDiffWeek = 0;
-       m_prevDiffMonth = 0;
 }
 
 
@@ -54,22 +41,13 @@ BusinessService::BusinessService() : Container()
 // Constructor for new service object
 //
 
-BusinessService::BusinessService(const TCHAR *name) : Container(name, 0)
+BusinessService::BusinessService(const TCHAR *name) 
+: ServiceContainer(name, 0)
 {
        m_busy = false;
        m_lastPollTime = time_t(0);
-       m_lastPollStatus = m_prevUptimeUpdateStatus = STATUS_UNKNOWN;
-       m_prevUptimeUpdateTime = time(NULL);
+       m_lastPollStatus = STATUS_UNKNOWN;
        nx_strncpy(m_szName, name, MAX_OBJECT_NAME);
-       m_uptimeDay = 100.0;
-       m_uptimeWeek = 100.0;
-       m_uptimeMonth = 100.0;
-       m_downtimeDay = 0;
-       m_downtimeWeek = 0;
-       m_downtimeMonth = 0;
-       m_prevDiffDay = 0;
-       m_prevDiffWeek = 0;
-       m_prevDiffMonth = 0;
 }
 
 
@@ -88,37 +66,7 @@ BusinessService::~BusinessService()
 
 void BusinessService::calculateCompoundStatus(BOOL bForcedRecalc)
 {
-       int i, iCount, iMostCriticalStatus;
-       int iOldStatus = m_iStatus;
-
-       // Calculate own status by selecting the most critical status of the kids
-       LockChildList(FALSE);
-       for(i = 0, iCount = 0, iMostCriticalStatus = -1; i < int(m_dwChildCount); i++)
-       {
-               int iChildStatus = m_pChildList[i]->Status();
-               if ((iChildStatus < STATUS_UNKNOWN) &&
-                       (iChildStatus > iMostCriticalStatus))
-               {
-                       iMostCriticalStatus = iChildStatus;
-                       iCount++;
-               }
-       }
-       // Set status and update uptime counters
-       setStatus((iCount > 0) ? iMostCriticalStatus : STATUS_UNKNOWN);
-       UnlockChildList();
-
-       // Cause parent object(s) to recalculate it's status
-       if ((iOldStatus != m_iStatus) || bForcedRecalc)
-       {
-               LockParentList(FALSE);
-               for(i = 0; i < int(m_dwParentCount); i++)
-                       m_pParentList[i]->calculateCompoundStatus();
-               UnlockParentList();
-               Modify();   /* LOCK? */
-       }
-
-       if (iOldStatus != STATUS_UNKNOWN && iOldStatus != m_iStatus)
-               addHistoryRecord();
+       ServiceContainer::calculateCompoundStatus(bForcedRecalc);
 }
 
 
@@ -290,7 +238,7 @@ void BusinessService::poll(ClientSession *pSession, DWORD dwRqId, int nPoller)
                if (m_pChildList[i]->Type() == OBJECT_SLMCHECK)
                        ((SlmCheck *)m_pChildList[i])->execute();
                else if (m_pChildList[i]->Type() == OBJECT_NODELINK)
-                       ((NodeLink *)m_pChildList[i])->execute();
+                       ((NodeLink*)m_pChildList[i])->execute();
        }
    UnlockChildList();
 
@@ -302,246 +250,3 @@ void BusinessService::poll(ClientSession *pSession, DWORD dwRqId, int nPoller)
        m_busy = false;
 }
 
-//
-// Set service status - use this instead of direct assignment;
-//
-
-void BusinessService::setStatus(int newStatus)
-{
-       m_iStatus = newStatus;
-       updateUptimeStats();    
-}
-
-//
-// Add a record to slm_service_history table
-//
-
-BOOL BusinessService::addHistoryRecord()
-{
-       DB_RESULT hResult;
-       DB_STATEMENT hStmt;
-
-       if (BusinessService::logRecordId < 0)
-       {
-               hResult = DBSelect(g_hCoreDB, _T("SELECT max(record_id) FROM slm_service_history"));
-               if (hResult == NULL)
-                       return FALSE;
-               BusinessService::logRecordId = DBGetNumRows(hResult) > 0 ? DBGetFieldLong(hResult, 0, 0) : 0;
-               DBFreeResult(hResult);
-       }
-
-       BusinessService::logRecordId++;
-
-       hStmt = DBPrepare(g_hCoreDB, _T("INSERT INTO slm_service_history (record_id,service_id,change_timestamp,new_status) ")
-               _T("VALUES (?,?,?,?)"));
-       if (hStmt != NULL)
-       {
-               DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, BusinessService::logRecordId);
-               DBBind(hStmt, 2, DB_SQLTYPE_INTEGER, m_dwId);
-               DBBind(hStmt, 3, DB_SQLTYPE_INTEGER, DWORD(time(NULL)));
-               DBBind(hStmt, 4, DB_SQLTYPE_INTEGER, DWORD(m_iStatus));
-               if (!DBExecute(hStmt))
-               {
-                       DBFreeStatement(hStmt);
-                       return FALSE;
-               }
-               DbgPrintf(9, _T("BusinessService::addHistoryRecord() ok with id %ld"), BusinessService::logRecordId);
-       }
-       else
-       {
-               return FALSE;
-       }
-
-       DBFreeStatement(hStmt);
-       return TRUE;
-}
-
-
-//
-// Initialize uptime statistics (daily, weekly, monthly) by examining slm_service_history
-//
-
-void BusinessService::initUptimeStats()
-{
-       m_uptimeDay = getUptimeFromDBFor(DAY, &m_downtimeDay);
-       m_uptimeWeek = getUptimeFromDBFor(WEEK, &m_downtimeWeek);
-       m_uptimeMonth = getUptimeFromDBFor(MONTH, &m_downtimeMonth);
-       DbgPrintf(7, _T("++++ BusinessService::initUptimeStats() %lf %lf %lf"), m_uptimeDay, m_uptimeWeek, m_uptimeMonth);
-}
-
-//
-// Calculate uptime for given period using data in database
-//
-
-double BusinessService::getUptimeFromDBFor(Period period, LONG *downtime)
-{
-       time_t beginTime;
-       LONG timediffTillNow    = BusinessService::getSecondsSinceBeginningOf(period, &beginTime);
-       double percentage = 0;
-
-       DB_STATEMENT hStmt = DBPrepare(g_hCoreDB, _T("SELECT change_timestamp,new_status FROM slm_service_history ")
-                                                                                         _T("WHERE service_id=? AND change_timestamp>?"));
-       if (hStmt != NULL)
-       {
-               time_t changeTimestamp, prevChangeTimestamp;
-               int newStatus;
-               DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, m_dwId);
-               DBBind(hStmt, 2, DB_SQLTYPE_INTEGER, (DWORD)beginTime);
-               DB_RESULT hResult = DBSelectPrepared(hStmt);
-               if (hResult == NULL)
-               {
-                       DBFreeStatement(hStmt);
-                       return percentage;
-               }
-
-               int numRows = DBGetNumRows(hResult);
-               *downtime = 0;
-               prevChangeTimestamp = beginTime;
-               if (numRows > 0) // if <= 0 then assume zero downtime   FIXME: it can be 100% downtime
-               {
-                       for (int i = 0; i < numRows; i++)
-                       {
-                               changeTimestamp = DBGetFieldLong(hResult, i, 0);
-                               newStatus = DBGetFieldLong(hResult, i, 1);
-                               if (newStatus == STATUS_NORMAL)
-                                       *downtime += (LONG)(changeTimestamp - prevChangeTimestamp);
-                               else 
-                                       prevChangeTimestamp = changeTimestamp;
-                       }
-                       if (newStatus == STATUS_CRITICAL) // the service is still down, add period till now
-                               *downtime += LONG(time(NULL) - prevChangeTimestamp);
-               }
-               percentage = 100.0 - (double)(*downtime * 100) / (double)getSecondsInPeriod(period);
-               DbgPrintf(7, _T("++++ BusinessService::getUptimeFromDBFor(), downtime %ld"), *downtime);
-
-               DBFreeResult(hResult);
-               DBFreeStatement(hStmt);
-       }
-       
-       return percentage;
-}
-
-
-//
-// Update uptime counters 
-//
-
-void BusinessService::updateUptimeStats()
-{
-       LONG timediffTillNow;
-       LONG downtimeBetweenPolls = 0;
-       time_t curTime = time(NULL);
-
-       LockData();
-
-       double prevUptimeDay = m_uptimeDay;
-       double prevUptimeWeek = m_uptimeWeek;
-       double prevUptimeMonth = m_uptimeMonth;
-
-       if (m_iStatus == STATUS_CRITICAL && m_prevUptimeUpdateStatus == STATUS_CRITICAL)
-       {
-               downtimeBetweenPolls = LONG(curTime - m_prevUptimeUpdateTime);          
-               DbgPrintf(7, _T("++++ BusinessService::updateUptimeStats() both statuses critical"));
-       }
-
-       timediffTillNow = BusinessService::getSecondsSinceBeginningOf(DAY, NULL);
-       m_downtimeDay += downtimeBetweenPolls;
-       if (timediffTillNow < m_prevDiffDay)
-               m_downtimeDay = 0;
-       m_uptimeDay = 100.0 - (double)(m_downtimeDay * 100) / (double)BusinessService::getSecondsInPeriod(DAY);
-       m_prevDiffDay = timediffTillNow;
-       DbgPrintf(7, _T("++++ BusinessService::updateUptimeStats() m_downtimeDay %ld, timediffTillNow %ld, downtimeBetweenPolls %ld"), 
-                               m_downtimeDay, timediffTillNow, downtimeBetweenPolls);
-
-       timediffTillNow = BusinessService::getSecondsSinceBeginningOf(WEEK, NULL);
-       m_downtimeWeek += downtimeBetweenPolls;
-       if (timediffTillNow < m_prevDiffWeek)
-               m_downtimeWeek = 0;
-       m_uptimeWeek = 100.0 - (double)(m_downtimeWeek * 100) / (double)BusinessService::getSecondsInPeriod(WEEK);
-       m_prevDiffWeek = timediffTillNow;
-
-       timediffTillNow = BusinessService::getSecondsSinceBeginningOf(MONTH, NULL);
-       m_downtimeMonth += downtimeBetweenPolls;
-       if (timediffTillNow < m_prevDiffMonth)
-               m_downtimeMonth = 0;
-       m_uptimeMonth = 100.0 - (double)(m_downtimeMonth * 100) / (double)BusinessService::getSecondsInPeriod(MONTH);
-       m_prevDiffMonth = timediffTillNow;
-
-       if ((prevUptimeDay != m_uptimeDay) || (prevUptimeWeek != m_uptimeWeek) || (prevUptimeMonth != m_uptimeMonth))
-       {
-               Modify();
-       }
-       UnlockData();
-       
-       m_prevUptimeUpdateStatus = m_iStatus;
-       m_prevUptimeUpdateTime = curTime;
-       
-       DbgPrintf(7, _T("++++ BusinessService::updateUptimeStats() %lf %lf %lf"), m_uptimeDay, m_uptimeWeek, m_uptimeMonth);
-}
-
-
-//
-// Calculate number of seconds since the beginning of given period
-//
-
-LONG BusinessService::getSecondsSinceBeginningOf(Period period, time_t *beginTime)
-{
-       time_t curTime = time(NULL);
-       struct tm *tms;
-       struct tm tmBuffer;
-
-#if HAVE_LOCALTIME_R
-       tms = localtime_r(&curTime, &tmBuffer);
-#else
-       tms = localtime(&curTime);
-       memcpy((void*)&tmBuffer, (void*)tms, sizeof(struct tm));
-#endif
-
-       tmBuffer.tm_hour = 0;
-       tmBuffer.tm_min = 0;
-       tmBuffer.tm_sec = 0;
-       if (period == MONTH)
-               tmBuffer.tm_mday = 1;
-       time_t beginTimeL = mktime(&tmBuffer);
-       if (period == WEEK)
-       {
-               if (tmBuffer.tm_wday == 0)
-                       tmBuffer.tm_wday = 7;
-               tmBuffer.tm_wday--;
-               beginTimeL -= 3600 * 24 * tmBuffer.tm_wday;
-       }
-
-       if (beginTime != NULL)
-               *beginTime = beginTimeL;
-
-       return LONG(curTime - beginTimeL);
-}
-
-
-//
-// Calculate number of seconds in the current month
-//
-
-LONG BusinessService::getSecondsInMonth()
-{
-       time_t curTime = time(NULL);
-       struct tm *tms;
-
-#if HAVE_LOCALTIME_R
-       struct tm tmBuffer;
-       tms = localtime_r(&curTime, &tmBuffer);
-#else
-       tms = localtime(&curTime);
-#endif
-
-       int& month = tms->tm_mon;
-       int year = tms->tm_year + 1900;
-       int days = 31;
-       
-       if (month == 3 || month == 5 || month == 8 || month == 10)
-               days = 30;      
-       else if (month == 1) /* February */
-               days = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) ? 29 : 28;
-               
-       return LONG(days * 24 * 3600);
-}
index f3b87df..917873d 100644 (file)
@@ -29,7 +29,7 @@
 // NodeLink default constructor
 //
 
-NodeLink::NodeLink() : Container()
+NodeLink::NodeLink()
 {
        _tcscpy(m_szName, _T("Default"));
        m_nodeId = 0;
@@ -40,7 +40,8 @@ NodeLink::NodeLink() : Container()
 // Constructor for new nodelink object
 //
 
-NodeLink::NodeLink(const TCHAR *name, DWORD nodeId) : Container(name, 0)
+NodeLink::NodeLink(const TCHAR *name, DWORD nodeId) 
+: ServiceContainer(name, 0)
 {
        nx_strncpy(m_szName, name, MAX_OBJECT_NAME);
        m_nodeId = nodeId;
@@ -63,36 +64,10 @@ NodeLink::~NodeLink()
 
 void NodeLink::calculateCompoundStatus(BOOL bForcedRecalc)
 {
-       int i, iCount, iMostCriticalStatus;
-       int iOldStatus = m_iStatus;
+       ServiceContainer::calculateCompoundStatus(bForcedRecalc);
 
-       // Calculate own status by selecting the most critical status of the kids
-       LockChildList(FALSE);
-       for(i = 0, iCount = 0, iMostCriticalStatus = -1; i < int(m_dwChildCount); i++)
-       {
-               int iChildStatus = m_pChildList[i]->Status();
-               if ((iChildStatus < STATUS_UNKNOWN) &&
-                       (iChildStatus > iMostCriticalStatus))
-               {
-                       iMostCriticalStatus = iChildStatus;
-                       iCount++;
-               }
-       }
-       m_iStatus = (iCount > 0) ? iMostCriticalStatus : STATUS_UNKNOWN;
-       UnlockChildList();
-
-       // Cause parent object(s) to recalculate it's status
-       if ((iOldStatus != m_iStatus) || bForcedRecalc)
-       {
-               LockParentList(FALSE);
-               for(i = 0; i < int(m_dwParentCount); i++)
-                       m_pParentList[i]->calculateCompoundStatus();
-               UnlockParentList();
-               Modify();   /* LOCK? */
-       }
 }
 
-
 //
 // Create object from database data
 //
index 976f9a6..6d7aefb 100644 (file)
                                RelativePath=".\subnet.cpp"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath=".\svccontainer.cpp"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath=".\syncer.cpp"\r
                                >\r
similarity index 51%
copy from src/server/core/bizservice.cpp
copy to src/server/core/svccontainer.cpp
index a51e90e..7ce217c 100644 (file)
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software
 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 **
-** File: bizservice.cpp
+** File: svccontainer.cpp
 **
 **/
 
 
 #define QUERY_LENGTH           (512)
 
-LONG BusinessService::logRecordId = -1;
-
+LONG ServiceContainer::logRecordId = -1;
 
 //
-// Service default constructor
+// Constructor for service service object
 //
 
-BusinessService::BusinessService() : Container()
+ServiceContainer::ServiceContainer()
 {
-       m_busy = false;
-       m_lastPollTime = time_t(0);
-       m_lastPollStatus = m_prevUptimeUpdateStatus = STATUS_UNKNOWN;
-       m_prevUptimeUpdateTime = time(NULL);
-       _tcscpy(m_szName, _T("Default"));
-       m_uptimeDay = 100.0;
-       m_uptimeWeek = 100.0;
-       m_uptimeMonth = 100.0;
-       m_downtimeDay = 0;
-       m_downtimeWeek = 0;
-       m_downtimeMonth = 0;
-       m_prevDiffDay = 0;
-       m_prevDiffWeek = 0;
-       m_prevDiffMonth = 0;
+       initServiceContainer();
 }
 
+ServiceContainer::ServiceContainer(const TCHAR *pszName, DWORD dwCategory)
+:Container(pszName, dwCategory)
+{
+       initServiceContainer();
+}
 
-//
-// Constructor for new service object
-//
 
-BusinessService::BusinessService(const TCHAR *name) : Container(name, 0)
+void ServiceContainer::initServiceContainer()
 {
-       m_busy = false;
-       m_lastPollTime = time_t(0);
-       m_lastPollStatus = m_prevUptimeUpdateStatus = STATUS_UNKNOWN;
+       m_prevUptimeUpdateStatus = STATUS_UNKNOWN;
        m_prevUptimeUpdateTime = time(NULL);
-       nx_strncpy(m_szName, name, MAX_OBJECT_NAME);
        m_uptimeDay = 100.0;
        m_uptimeWeek = 100.0;
        m_uptimeMonth = 100.0;
@@ -72,21 +57,11 @@ BusinessService::BusinessService(const TCHAR *name) : Container(name, 0)
        m_prevDiffMonth = 0;
 }
 
-
-//
-// Service class destructor
-//
-
-BusinessService::~BusinessService()
-{
-}
-
-
 //
 // Calculate status for compound object based on childs status
 //
 
-void BusinessService::calculateCompoundStatus(BOOL bForcedRecalc)
+void ServiceContainer::calculateCompoundStatus(BOOL bForcedRecalc)
 {
        int i, iCount, iMostCriticalStatus;
        int iOldStatus = m_iStatus;
@@ -121,192 +96,11 @@ void BusinessService::calculateCompoundStatus(BOOL bForcedRecalc)
                addHistoryRecord();
 }
 
-
-//
-// Create object from database data
-//
-
-BOOL BusinessService::CreateFromDB(DWORD id)
-{
-       if (!Container::CreateFromDB(id))
-               return FALSE;
-
-       // now it doesn't make any sense but hopefully will do in the future
-       DB_STATEMENT hStmt = DBPrepare(g_hCoreDB, _T("SELECT service_id FROM business_services WHERE service_id=?"));
-       if (hStmt == NULL)
-       {
-               DbgPrintf(4, _T("Cannot prepare select from business_services"));
-               return FALSE;
-       }
-       DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, m_dwId);
-       DB_RESULT hResult = DBSelectPrepared(hStmt);
-       if (hResult == NULL)
-       {
-               DBFreeStatement(hStmt);
-               return FALSE;
-       }
-
-       if (DBGetNumRows(hResult) == 0)
-       {
-               DBFreeResult(hResult);
-               DBFreeStatement(hStmt);
-               DbgPrintf(4, _T("Cannot load biz service object %ld - record missing"), (long)m_dwId);
-               return FALSE;
-       }
-
-       DBFreeResult(hResult);
-       DBFreeStatement(hStmt);
-
-       initUptimeStats();
-
-       return TRUE;
-}
-
-
-//
-// Save service to database
-//
-
-BOOL BusinessService::SaveToDB(DB_HANDLE hdb)
-{
-       BOOL bNewObject = TRUE;
-
-       LockData();
-
-       DB_STATEMENT hStmt = DBPrepare(hdb, _T("SELECT service_id FROM business_services WHERE service_id=?"));
-       if (hStmt == NULL)
-               return FALSE;
-       DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, m_dwId);
-       DB_RESULT hResult = DBSelectPrepared(hStmt);
-       if (hResult != NULL)
-       {
-               bNewObject = (DBGetNumRows(hResult) <= 0);
-               DBFreeResult(hResult);
-       }
-       DBFreeStatement(hStmt);
-
-       hStmt = DBPrepare(g_hCoreDB, bNewObject ? _T("INSERT INTO business_services (service_id) VALUES (?)") :
-                                                                                         _T("UPDATE business_services SET service_id=service_id WHERE service_id=?"));
-       if (hStmt == NULL)      
-               return FALSE;
-       DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, m_dwId);
-       if (!DBExecute(hStmt))
-       {
-               DBFreeStatement(hStmt);
-               return FALSE;
-       }
-
-       DBFreeStatement(hStmt);
-
-       saveACLToDB(hdb);
-
-       // Unlock object and clear modification flag
-       m_bIsModified = FALSE;
-       UnlockData();
-
-       return Container::SaveToDB(hdb);
-}
-
-
-//
-// Delete object from database
-//
-
-BOOL BusinessService::DeleteFromDB()
-{
-   TCHAR szQuery[QUERY_LENGTH];
-   BOOL bSuccess;
-
-   bSuccess = Container::DeleteFromDB();
-   if (bSuccess)
-   {
-      _sntprintf(szQuery, QUERY_LENGTH, _T("DELETE FROM business_services WHERE id=%d"), m_dwId);
-      QueueSQLRequest(szQuery);
-   }
-
-   return bSuccess;
-}
-
-
-//
-// Create CSCP message with object's data
-//
-
-void BusinessService::CreateMessage(CSCPMessage *pMsg)
-{
-   NetObj::CreateMessage(pMsg);
-   pMsg->SetVariable(VID_UPTIME_DAY, m_uptimeDay);
-   pMsg->SetVariable(VID_UPTIME_WEEK, m_uptimeWeek);
-   pMsg->SetVariable(VID_UPTIME_MONTH, m_uptimeMonth);
-}
-
-
-//
-// Modify object from message
-//
-
-DWORD BusinessService::ModifyFromMessage(CSCPMessage *pRequest, BOOL bAlreadyLocked)
-{
-   if (!bAlreadyLocked)
-      LockData();
-
-   return NetObj::ModifyFromMessage(pRequest, TRUE);
-}
-
-
-//
-// Check if service is ready for poll
-//
-
-bool BusinessService::isReadyForPolling()
-{
-       return time(NULL) - m_lastPollTime > g_dwSlmPollingInterval && !m_busy;
-}
-
-
-//
-// Lock service for polling
-//
-
-void BusinessService::lockForPolling()
-{
-       m_busy = true;
-}
-
-
-//
-// A callback for poller threads
-//
-
-void BusinessService::poll(ClientSession *pSession, DWORD dwRqId, int nPoller)
-{
-       DbgPrintf(5, _T("Started polling of business service %s [%d]"), m_szName, (int)m_dwId);
-       m_lastPollTime = time(NULL);
-
-       // Loop through the kids and execute their either scripts or thresholds
-   LockChildList(FALSE);
-       for (int i = 0; i < int(m_dwChildCount); i++)
-       {
-               if (m_pChildList[i]->Type() == OBJECT_SLMCHECK)
-                       ((SlmCheck *)m_pChildList[i])->execute();
-               else if (m_pChildList[i]->Type() == OBJECT_NODELINK)
-                       ((NodeLink *)m_pChildList[i])->execute();
-       }
-   UnlockChildList();
-
-       // Set the status based on what the kids' been up to
-       calculateCompoundStatus();
-
-       m_lastPollStatus = m_iStatus;
-       DbgPrintf(5, _T("Finished polling of business service %s [%d]"), m_szName, (int)m_dwId);
-       m_busy = false;
-}
-
 //
 // Set service status - use this instead of direct assignment;
 //
 
-void BusinessService::setStatus(int newStatus)
+void ServiceContainer::setStatus(int newStatus)
 {
        m_iStatus = newStatus;
        updateUptimeStats();    
@@ -316,27 +110,27 @@ void BusinessService::setStatus(int newStatus)
 // Add a record to slm_service_history table
 //
 
-BOOL BusinessService::addHistoryRecord()
+BOOL ServiceContainer::addHistoryRecord()
 {
        DB_RESULT hResult;
        DB_STATEMENT hStmt;
 
-       if (BusinessService::logRecordId < 0)
+       if (ServiceContainer::logRecordId < 0)
        {
                hResult = DBSelect(g_hCoreDB, _T("SELECT max(record_id) FROM slm_service_history"));
                if (hResult == NULL)
                        return FALSE;
-               BusinessService::logRecordId = DBGetNumRows(hResult) > 0 ? DBGetFieldLong(hResult, 0, 0) : 0;
+               ServiceContainer::logRecordId = DBGetNumRows(hResult) > 0 ? DBGetFieldLong(hResult, 0, 0) : 0;
                DBFreeResult(hResult);
        }
 
-       BusinessService::logRecordId++;
+       ServiceContainer::logRecordId++;
 
        hStmt = DBPrepare(g_hCoreDB, _T("INSERT INTO slm_service_history (record_id,service_id,change_timestamp,new_status) ")
                _T("VALUES (?,?,?,?)"));
        if (hStmt != NULL)
        {
-               DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, BusinessService::logRecordId);
+               DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, ServiceContainer::logRecordId);
                DBBind(hStmt, 2, DB_SQLTYPE_INTEGER, m_dwId);
                DBBind(hStmt, 3, DB_SQLTYPE_INTEGER, DWORD(time(NULL)));
                DBBind(hStmt, 4, DB_SQLTYPE_INTEGER, DWORD(m_iStatus));
@@ -345,7 +139,7 @@ BOOL BusinessService::addHistoryRecord()
                        DBFreeStatement(hStmt);
                        return FALSE;
                }
-               DbgPrintf(9, _T("BusinessService::addHistoryRecord() ok with id %ld"), BusinessService::logRecordId);
+               DbgPrintf(9, _T("ServiceContainer::addHistoryRecord() ok with id %ld"), ServiceContainer::logRecordId);
        }
        else
        {
@@ -361,26 +155,27 @@ BOOL BusinessService::addHistoryRecord()
 // Initialize uptime statistics (daily, weekly, monthly) by examining slm_service_history
 //
 
-void BusinessService::initUptimeStats()
+void ServiceContainer::initUptimeStats()
 {
+       m_prevUptimeUpdateStatus = m_iStatus;
        m_uptimeDay = getUptimeFromDBFor(DAY, &m_downtimeDay);
        m_uptimeWeek = getUptimeFromDBFor(WEEK, &m_downtimeWeek);
        m_uptimeMonth = getUptimeFromDBFor(MONTH, &m_downtimeMonth);
-       DbgPrintf(7, _T("++++ BusinessService::initUptimeStats() %lf %lf %lf"), m_uptimeDay, m_uptimeWeek, m_uptimeMonth);
+       DbgPrintf(7, _T("++++ ServiceContainer::initUptimeStats() id=%d %lf %lf %lf"), m_dwId, m_uptimeDay, m_uptimeWeek, m_uptimeMonth);
 }
 
 //
 // Calculate uptime for given period using data in database
 //
 
-double BusinessService::getUptimeFromDBFor(Period period, LONG *downtime)
+double ServiceContainer::getUptimeFromDBFor(Period period, LONG *downtime)
 {
        time_t beginTime;
-       LONG timediffTillNow    = BusinessService::getSecondsSinceBeginningOf(period, &beginTime);
+       LONG timediffTillNow    = ServiceContainer::getSecondsSinceBeginningOf(period, &beginTime);
        double percentage = 0;
 
        DB_STATEMENT hStmt = DBPrepare(g_hCoreDB, _T("SELECT change_timestamp,new_status FROM slm_service_history ")
-                                                                                         _T("WHERE service_id=? AND change_timestamp>?"));
+               _T("WHERE service_id=? AND change_timestamp>?"));
        if (hStmt != NULL)
        {
                time_t changeTimestamp, prevChangeTimestamp;
@@ -412,12 +207,12 @@ double BusinessService::getUptimeFromDBFor(Period period, LONG *downtime)
                                *downtime += LONG(time(NULL) - prevChangeTimestamp);
                }
                percentage = 100.0 - (double)(*downtime * 100) / (double)getSecondsInPeriod(period);
-               DbgPrintf(7, _T("++++ BusinessService::getUptimeFromDBFor(), downtime %ld"), *downtime);
+               DbgPrintf(7, _T("++++ ServiceContainer::getUptimeFromDBFor(), downtime %ld"), *downtime);
 
                DBFreeResult(hResult);
                DBFreeStatement(hStmt);
        }
-       
+
        return percentage;
 }
 
@@ -426,7 +221,7 @@ double BusinessService::getUptimeFromDBFor(Period period, LONG *downtime)
 // Update uptime counters 
 //
 
-void BusinessService::updateUptimeStats()
+void ServiceContainer::updateUptimeStats()
 {
        LONG timediffTillNow;
        LONG downtimeBetweenPolls = 0;
@@ -441,30 +236,30 @@ void BusinessService::updateUptimeStats()
        if (m_iStatus == STATUS_CRITICAL && m_prevUptimeUpdateStatus == STATUS_CRITICAL)
        {
                downtimeBetweenPolls = LONG(curTime - m_prevUptimeUpdateTime);          
-               DbgPrintf(7, _T("++++ BusinessService::updateUptimeStats() both statuses critical"));
+               DbgPrintf(7, _T("++++ ServiceContainer::updateUptimeStats() both statuses critical"));
        }
 
-       timediffTillNow = BusinessService::getSecondsSinceBeginningOf(DAY, NULL);
+       timediffTillNow = ServiceContainer::getSecondsSinceBeginningOf(DAY, NULL);
        m_downtimeDay += downtimeBetweenPolls;
        if (timediffTillNow < m_prevDiffDay)
                m_downtimeDay = 0;
-       m_uptimeDay = 100.0 - (double)(m_downtimeDay * 100) / (double)BusinessService::getSecondsInPeriod(DAY);
+       m_uptimeDay = 100.0 - (double)(m_downtimeDay * 100) / (double)ServiceContainer::getSecondsInPeriod(DAY);
        m_prevDiffDay = timediffTillNow;
-       DbgPrintf(7, _T("++++ BusinessService::updateUptimeStats() m_downtimeDay %ld, timediffTillNow %ld, downtimeBetweenPolls %ld"), 
-                               m_downtimeDay, timediffTillNow, downtimeBetweenPolls);
+       DbgPrintf(7, _T("++++ ServiceContainer::updateUptimeStats() m_downtimeDay %ld, timediffTillNow %ld, downtimeBetweenPolls %ld"), 
+               m_downtimeDay, timediffTillNow, downtimeBetweenPolls);
 
-       timediffTillNow = BusinessService::getSecondsSinceBeginningOf(WEEK, NULL);
+       timediffTillNow = ServiceContainer::getSecondsSinceBeginningOf(WEEK, NULL);
        m_downtimeWeek += downtimeBetweenPolls;
        if (timediffTillNow < m_prevDiffWeek)
                m_downtimeWeek = 0;
-       m_uptimeWeek = 100.0 - (double)(m_downtimeWeek * 100) / (double)BusinessService::getSecondsInPeriod(WEEK);
+       m_uptimeWeek = 100.0 - (double)(m_downtimeWeek * 100) / (double)ServiceContainer::getSecondsInPeriod(WEEK);
        m_prevDiffWeek = timediffTillNow;
 
-       timediffTillNow = BusinessService::getSecondsSinceBeginningOf(MONTH, NULL);
+       timediffTillNow = ServiceContainer::getSecondsSinceBeginningOf(MONTH, NULL);
        m_downtimeMonth += downtimeBetweenPolls;
        if (timediffTillNow < m_prevDiffMonth)
                m_downtimeMonth = 0;
-       m_uptimeMonth = 100.0 - (double)(m_downtimeMonth * 100) / (double)BusinessService::getSecondsInPeriod(MONTH);
+       m_uptimeMonth = 100.0 - (double)(m_downtimeMonth * 100) / (double)ServiceContainer::getSecondsInPeriod(MONTH);
        m_prevDiffMonth = timediffTillNow;
 
        if ((prevUptimeDay != m_uptimeDay) || (prevUptimeWeek != m_uptimeWeek) || (prevUptimeMonth != m_uptimeMonth))
@@ -472,11 +267,11 @@ void BusinessService::updateUptimeStats()
                Modify();
        }
        UnlockData();
-       
+
        m_prevUptimeUpdateStatus = m_iStatus;
        m_prevUptimeUpdateTime = curTime;
-       
-       DbgPrintf(7, _T("++++ BusinessService::updateUptimeStats() %lf %lf %lf"), m_uptimeDay, m_uptimeWeek, m_uptimeMonth);
+
+       DbgPrintf(7, _T("++++ ServiceContainer::updateUptimeStats() %lf %lf %lf"), m_uptimeDay, m_uptimeWeek, m_uptimeMonth);
 }
 
 
@@ -484,7 +279,7 @@ void BusinessService::updateUptimeStats()
 // Calculate number of seconds since the beginning of given period
 //
 
-LONG BusinessService::getSecondsSinceBeginningOf(Period period, time_t *beginTime)
+LONG ServiceContainer::getSecondsSinceBeginningOf(Period period, time_t *beginTime)
 {
        time_t curTime = time(NULL);
        struct tm *tms;
@@ -522,7 +317,7 @@ LONG BusinessService::getSecondsSinceBeginningOf(Period period, time_t *beginTim
 // Calculate number of seconds in the current month
 //
 
-LONG BusinessService::getSecondsInMonth()
+LONG ServiceContainer::getSecondsInMonth()
 {
        time_t curTime = time(NULL);
        struct tm *tms;
@@ -537,11 +332,11 @@ LONG BusinessService::getSecondsInMonth()
        int& month = tms->tm_mon;
        int year = tms->tm_year + 1900;
        int days = 31;
-       
+
        if (month == 3 || month == 5 || month == 8 || month == 10)
                days = 30;      
        else if (month == 1) /* February */
                days = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) ? 29 : 28;
-               
+
        return LONG(days * 24 * 3600);
 }
index 27cdff9..850d739 100644 (file)
@@ -1552,36 +1552,6 @@ public:
 };
 
 
-//
-// Node link object for business service
-//
-
-class NXCORE_EXPORTABLE NodeLink : public Container
-{
-protected:
-       DWORD m_nodeId;
-
-public:
-       NodeLink();
-       NodeLink(const TCHAR *name, DWORD nodeId);
-       virtual ~NodeLink();
-
-       virtual int Type() { return OBJECT_NODELINK; }
-       virtual void calculateCompoundStatus(BOOL bForcedRecalc = FALSE);
-
-       virtual BOOL SaveToDB(DB_HANDLE hdb);
-       virtual BOOL DeleteFromDB();
-       virtual BOOL CreateFromDB(DWORD dwId);
-
-       virtual void CreateMessage(CSCPMessage *pMsg);
-       virtual DWORD ModifyFromMessage(CSCPMessage *pRequest, BOOL bAlreadyLocked = FALSE);
-
-       void execute();
-       BOOL applyTemplates();
-
-       DWORD getNodeId() { return m_nodeId; }
-};
-
 
 //
 // SLM check object
@@ -1624,34 +1594,16 @@ public:
        const TCHAR *getReason() { return m_reason; }
 };
 
-
 //
-// Business service root
+// Service container - common logic for BusinessService, NodeLink and BusinessServiceRoot
 //
 
-class NXCORE_EXPORTABLE BusinessServiceRoot : public UniversalRoot
-{
-public:
-       BusinessServiceRoot();
-       virtual ~BusinessServiceRoot();
-
-       virtual int Type() { return OBJECT_BUSINESSSERVICEROOT; }
-};
-
-
-//
-// Business service object
-//
-
-class NXCORE_EXPORTABLE BusinessService : public Container
+class NXCORE_EXPORTABLE ServiceContainer: public Container 
 {
        enum Period { DAY, WEEK, MONTH };
 
 protected:
-       bool m_busy;
-       time_t m_lastPollTime;
        time_t m_prevUptimeUpdateTime;
-       int m_lastPollStatus;
        int m_prevUptimeUpdateStatus;
        double m_uptimeDay;
        double m_uptimeWeek;
@@ -1670,11 +1622,46 @@ protected:
        static LONG getSecondsInPeriod(Period period) { return period == MONTH ? getSecondsInMonth() : (period == WEEK ? secondsInWeek : secondsInDay); }
        static LONG getSecondsSinceBeginningOf(Period period, time_t *beginTime = NULL);
 
+       void initServiceContainer();
        BOOL addHistoryRecord();
        void initUptimeStats();
        void updateUptimeStats();
        double getUptimeFromDBFor(Period period, LONG *downtime);
 
+public:
+       ServiceContainer();
+       ServiceContainer(const TCHAR *pszName, DWORD dwCategory);
+       virtual void calculateCompoundStatus(BOOL bForcedRecalc = FALSE);
+       virtual void setStatus(int newStatus);
+};
+
+//
+// Business service root
+//
+
+class NXCORE_EXPORTABLE BusinessServiceRoot : public UniversalRoot
+{
+public:
+       BusinessServiceRoot();
+       virtual ~BusinessServiceRoot();
+
+       virtual void calculateCompoundStatus(BOOL bForcedRecalc = FALSE) { UniversalRoot::calculateCompoundStatus(bForcedRecalc); }
+       virtual BOOL SaveToDB(DB_HANDLE hdb) { return UniversalRoot::SaveToDB(hdb); }
+       virtual int Type() { return OBJECT_BUSINESSSERVICEROOT; }
+};
+
+
+//
+// Business service object
+//
+
+class NXCORE_EXPORTABLE BusinessService : public ServiceContainer
+{
+protected:
+       bool m_busy;
+       time_t m_lastPollTime;
+       int m_lastPollStatus;
+
 public:
        BusinessService();
        BusinessService(const TCHAR *name);
@@ -1690,12 +1677,41 @@ public:
        virtual void CreateMessage(CSCPMessage *pMsg);
        virtual DWORD ModifyFromMessage(CSCPMessage *pRequest, BOOL bAlreadyLocked = FALSE);
 
-       virtual void setStatus(int newStatus);
        bool isReadyForPolling();
        void lockForPolling();
        void poll(ClientSession *pSession, DWORD dwRqId, int nPoller);
 };
 
+//
+// Node link object for business service
+//
+
+class NXCORE_EXPORTABLE NodeLink : public ServiceContainer
+{
+protected:
+       DWORD m_nodeId;
+
+public:
+       NodeLink();
+       NodeLink(const TCHAR *name, DWORD nodeId);
+       virtual ~NodeLink();
+
+       virtual int Type() { return OBJECT_NODELINK; }
+       virtual void calculateCompoundStatus(BOOL bForcedRecalc = FALSE);
+
+       virtual BOOL SaveToDB(DB_HANDLE hdb);
+       virtual BOOL DeleteFromDB();
+       virtual BOOL CreateFromDB(DWORD dwId);
+
+       virtual void CreateMessage(CSCPMessage *pMsg);
+       virtual DWORD ModifyFromMessage(CSCPMessage *pRequest, BOOL bAlreadyLocked = FALSE);
+
+       void execute();
+       BOOL applyTemplates();
+
+       DWORD getNodeId() { return m_nodeId; }
+};
+
 
 //
 // Container category information