- Unfinished SLM module, 1st iteration
authorAlex Kalimulin <alex@netxms.org>
Thu, 18 Aug 2011 21:53:41 +0000 (21:53 +0000)
committerAlex Kalimulin <alex@netxms.org>
Thu, 18 Aug 2011 21:53:41 +0000 (21:53 +0000)
include/nxclapi.h
sql/schema.in
src/server/core/main.cpp
src/server/core/nxcore.vcproj
src/server/core/objects.cpp
src/server/core/rootobj.cpp
src/server/core/session.cpp
src/server/core/slm.cpp [new file with mode: 0644]
src/server/core/slm_objects.cpp [new file with mode: 0644]
src/server/include/nms_objects.h
src/server/include/nxsrvapi.h

index fad2034..09be245 100644 (file)
@@ -160,6 +160,10 @@ typedef void * NXC_SESSION;
 #define OBJECT_REPORTROOT           24
 #define OBJECT_REPORTGROUP          25
 #define OBJECT_REPORT               26
+#define OBJECT_BIZSERVICEROOT          27
+#define OBJECT_BIZSERVICE                      28
+#define OBJECT_NODELINK                                29
+#define OBJECT_SLMCHECK                                30
 
 
 //
index 17687de..8ec76cb 100644 (file)
@@ -1227,49 +1227,10 @@ CREATE TABLE dashboard_elements
 CREATE TABLE business_services
 (
      service_id integer not null,
-     name varchar(63) not null,
-     parent_id integer default 0 not null,
-     status integer default 0 not null, // 1 - up, 0 - down
      PRIMARY KEY(service_id)
 ) TABLE_TYPE;
 
 
-/*
-** SLA business service - subservices relationship
-*/
-
-CREATE TABLE business_subservices
-(
-     service_id integer not null,
-     subservice_id integer not null,
-     PRIMARY KEY(service_id,subservice_id)
-) TABLE_TYPE;
-
-
-/*
-** SLA business service - node links relationship
-*/
-
-CREATE TABLE business_service_node_links
-(
-     service_id integer not null,
-     node_link_id integer not null,
-     PRIMARY KEY(service_id,node_link_id)
-) TABLE_TYPE;
-
-
-/*
-** SLA business service - checks relationship
-*/
-
-CREATE TABLE business_service_checks
-(
-     service_id integer not null,
-     check_id integer not null,
-     PRIMARY KEY(service_id,check_id)
-) TABLE_TYPE;
-
-
 /*
 ** SLA business service - templates relationship
 */
@@ -1289,11 +1250,10 @@ CREATE TABLE business_service_templates
 CREATE TABLE slm_checks
 (
      check_id integer not null,
-     name varchar(63) not null,
      type integer default 1 not null, // 1 - threshold, 2 - script
      content SQL_TEXT, // if type == 2
      threshold_id integer default 0 not null, // if type == 1; refers to thresholds.id
-     state integer not null,
+     state integer not null,   // 1 - check ok, 0 - check failed
      reason varchar(255) not null,
      PRIMARY KEY(check_id)
 ) TABLE_TYPE;
index 92a0776..cbea338 100644 (file)
@@ -97,6 +97,7 @@ THREAD_RESULT THREAD_CALL SNMPTrapReceiver(void *pArg);
 THREAD_RESULT THREAD_CALL SyslogDaemon(void *pArg);
 THREAD_RESULT THREAD_CALL BeaconPoller(void *pArg);
 THREAD_RESULT THREAD_CALL JobManagerThread(void *arg);
+THREAD_RESULT THREAD_CALL ServiceLevelMonitoring(void *arg);
 
 
 //
@@ -120,6 +121,7 @@ DWORD g_dwTopologyPollingInterval;
 DWORD g_dwConditionPollingInterval;
 DWORD g_dwPingSize;
 DWORD g_dwAuditFlags;
+DWORD g_dwSlmFlags;
 TCHAR g_szDataDir[MAX_PATH] = _T("");
 TCHAR g_szLibDir[MAX_PATH] = DEFAULT_LIBDIR;
 int g_nDBSyntax = DB_SYNTAX_UNKNOWN;
@@ -309,6 +311,9 @@ static void LoadGlobalConfig()
                g_dwFlags |= AF_INTERNAL_CA;
        if (ConfigReadInt(_T("CheckTrustedNodes"), 1))
                g_dwFlags |= AF_CHECK_TRUSTED_NODES;
+
+       if (ConfigReadInt(_T("EnableSlm"), 1))
+               g_dwSlmFlags |= SLM_ENABLED;
        
        if (g_szDataDir[0] == 0)
        {
@@ -735,6 +740,8 @@ retry_db_lock:
        ThreadCreate(WatchdogThread, 0, NULL);
        ThreadCreate(NodePoller, 0, NULL);
        ThreadCreate(JobManagerThread, 0, NULL);
+       if (g_dwSlmFlags & SLM_ENABLED)
+               ThreadCreate(ServiceLevelMonitoring, 0, NULL);
        m_thSyncer = ThreadCreateEx(Syncer, 0, NULL);
        m_thHouseKeeper = ThreadCreateEx(HouseKeeper, 0, NULL);
        m_thPollManager = ThreadCreateEx(PollManager, 0, NULL);
index fc3a144..15e8695 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="windows-1251"?>\r
 <VisualStudioProject\r
        ProjectType="Visual C++"\r
-       Version="8.00"\r
+       Version="8,00"\r
        Name="nxcore"\r
        ProjectGUID="{3B172035-5EEC-45A3-8471-2C390B7ED683}"\r
        RootNamespace="nxcore"\r
                        />\r
                </Configuration>\r
                <Configuration\r
-                       Name="Debug|x64"\r
-                       OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
-                       IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
+                       IntermediateDirectory="$(ConfigurationName)"\r
                        ConfigurationType="2"\r
                        CharacterSet="1"\r
+                       WholeProgramOptimization="1"\r
                        >\r
                        <Tool\r
                                Name="VCPreBuildEventTool"\r
                        />\r
                        <Tool\r
                                Name="VCMIDLTool"\r
-                               TargetEnvironment="3"\r
                        />\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
-                               Optimization="0"\r
                                AdditionalIncludeDirectories="..\..\..\include;..\include"\r
-                               PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;NXCORE_EXPORTS;_CRT_SECURE_NO_DEPRECATE"\r
-                               MinimalRebuild="true"\r
-                               BasicRuntimeChecks="3"\r
-                               RuntimeLibrary="3"\r
+                               PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;NXCORE_EXPORTS;_CRT_SECURE_NO_DEPRECATE"\r
+                               RuntimeLibrary="2"\r
                                UsePrecompiledHeader="0"\r
                                WarningLevel="3"\r
                                Detect64BitPortabilityProblems="false"\r
                        <Tool\r
                                Name="VCLinkerTool"\r
                                AdditionalDependencies="ws2_32.lib libeay32.lib iphlpapi.lib psapi.lib"\r
-                               LinkIncremental="2"\r
+                               LinkIncremental="1"\r
                                GenerateDebugInformation="true"\r
                                SubSystem="2"\r
-                               TargetMachine="17"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               TargetMachine="1"\r
                        />\r
                        <Tool\r
                                Name="VCALinkTool"\r
                        />\r
                </Configuration>\r
                <Configuration\r
-                       Name="Release|Win32"\r
-                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
-                       IntermediateDirectory="$(ConfigurationName)"\r
+                       Name="Debug|x64"\r
+                       OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
+                       IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
                        ConfigurationType="2"\r
                        CharacterSet="1"\r
-                       WholeProgramOptimization="1"\r
                        >\r
                        <Tool\r
                                Name="VCPreBuildEventTool"\r
                        />\r
                        <Tool\r
                                Name="VCMIDLTool"\r
+                               TargetEnvironment="3"\r
                        />\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
                                AdditionalIncludeDirectories="..\..\..\include;..\include"\r
-                               PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;NXCORE_EXPORTS;_CRT_SECURE_NO_DEPRECATE"\r
-                               RuntimeLibrary="2"\r
+                               PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;NXCORE_EXPORTS;_CRT_SECURE_NO_DEPRECATE"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="3"\r
                                UsePrecompiledHeader="0"\r
                                WarningLevel="3"\r
                                Detect64BitPortabilityProblems="false"\r
                        <Tool\r
                                Name="VCLinkerTool"\r
                                AdditionalDependencies="ws2_32.lib libeay32.lib iphlpapi.lib psapi.lib"\r
-                               LinkIncremental="1"\r
+                               LinkIncremental="2"\r
                                GenerateDebugInformation="true"\r
                                SubSystem="2"\r
-                               OptimizeReferences="2"\r
-                               EnableCOMDATFolding="2"\r
-                               TargetMachine="1"\r
+                               TargetMachine="17"\r
                        />\r
                        <Tool\r
                                Name="VCALinkTool"\r
                                RelativePath=".\situation.cpp"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath=".\slm.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\slm_objects.cpp"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath=".\smclp.cpp"\r
                                >\r
index cc097f7..22105e9 100644 (file)
@@ -36,6 +36,7 @@ PolicyRoot NXCORE_EXPORTABLE *g_pPolicyRoot = NULL;
 NetworkMapRoot NXCORE_EXPORTABLE *g_pMapRoot = NULL;
 DashboardRoot NXCORE_EXPORTABLE *g_pDashboardRoot = NULL;
 ReportRoot NXCORE_EXPORTABLE *g_pReportRoot = NULL;
+BizServiceRoot NXCORE_EXPORTABLE *g_pBizServiceRoot = NULL;
 
 DWORD NXCORE_EXPORTABLE g_dwMgmtNode = 0;
 DWORD g_dwNumCategories = 0;
@@ -57,7 +58,9 @@ const TCHAR *g_szClassName[]={ _T("Generic"), _T("Subnet"), _T("Node"), _T("Inte
                                _T("Cluster"), _T("PolicyGroup"), _T("PolicyRoot"),
                                _T("AgentPolicy"), _T("AgentPolicyConfig"), _T("NetworkMapRoot"),
                                _T("NetworkMapGroup"), _T("NetworkMap"), _T("DashboardRoot"), 
-                               _T("Dashboard"), _T("ReportRoot"), _T("ReportGroup"), _T("Report") };
+                               _T("Dashboard"), _T("ReportRoot"), _T("ReportGroup"), _T("Report"),
+                                                          _T("BizServiceRoot"), _T("BizService"), _T("NodeLink"), _T("SlmCheck")
+};
 
 
 //
@@ -210,6 +213,10 @@ void ObjectsInit()
        // Create "Report Root" object
    g_pReportRoot = new ReportRoot;
    NetObjInsert(g_pReportRoot, FALSE);
+
+   // Create "Service Root" object
+   g_pBizServiceRoot = new BizServiceRoot;
+   NetObjInsert(g_pBizServiceRoot, FALSE);
    
        DbgPrintf(1, _T("Built-in objects created"));
 
@@ -279,6 +286,10 @@ void NetObjInsert(NetObj *pObject, BOOL bNewObject)
                        case OBJECT_REPORTROOT:
                        case OBJECT_REPORTGROUP:
                        case OBJECT_REPORT:
+                       case OBJECT_BIZSERVICEROOT:
+                       case OBJECT_BIZSERVICE:
+                       case OBJECT_SLMCHECK:
+                       case OBJECT_NODELINK:
             break;
          case OBJECT_NODE:
                                g_idxNodeById.put(pObject->Id(), pObject);
@@ -378,6 +389,10 @@ void NetObjDeleteFromIndexes(NetObj *pObject)
                case OBJECT_REPORTROOT:
                case OBJECT_REPORTGROUP:
                case OBJECT_REPORT:
+               case OBJECT_BIZSERVICEROOT:
+               case OBJECT_BIZSERVICE:
+               case OBJECT_SLMCHECK:
+               case OBJECT_NODELINK:
                        break;
       case OBJECT_NODE:
                        g_idxNodeById.remove(pObject->Id());
@@ -767,7 +782,8 @@ static void LinkChildObjectsCallback(NetObj *object, void *data)
                 (object->Type() == OBJECT_POLICYGROUP) ||
                 (object->Type() == OBJECT_NETWORKMAPGROUP) ||
                 (object->Type() == OBJECT_DASHBOARD) ||
-                (object->Type() == OBJECT_REPORTGROUP))
+                (object->Type() == OBJECT_REPORTGROUP) ||
+                (object->Type() == OBJECT_BIZSERVICE))
        {
                ((Container *)object)->linkChildObjects();
        }
@@ -816,6 +832,7 @@ BOOL LoadObjects()
        g_pMapRoot->LoadFromDB();
        g_pDashboardRoot->LoadFromDB();
        g_pReportRoot->LoadFromDB();
+       g_pBizServiceRoot->LoadFromDB();
 
    // Load zones
    if (g_dwFlags & AF_ENABLE_ZONING)
@@ -1108,7 +1125,7 @@ BOOL LoadObjects()
       DBFreeResult(hResult);
    }
 
-   // Load agent policies
+   // Load network maps
    DbgPrintf(2, _T("Loading network maps..."));
    hResult = DBSelect(g_hCoreDB, _T("SELECT id FROM network_maps"));
    if (hResult != NULL)
@@ -1307,6 +1324,31 @@ BOOL LoadObjects()
       DBFreeResult(hResult);
    }
 
+   // Loading service objects
+   DbgPrintf(2, _T("Loading business services..."));
+   _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("SELECT id FROM containers WHERE object_class=%d"), OBJECT_BIZSERVICE);
+   hResult = DBSelect(g_hCoreDB, szQuery);
+   if (hResult != 0)
+   {
+          dwNumRows = DBGetNumRows(hResult);
+          for(i = 0; i < dwNumRows; i++)
+          {
+                  dwId = DBGetFieldULong(hResult, i, 0);
+                  BizService *pGroup = new BizService;
+                  if (pGroup->CreateFromDB(dwId))
+                  {
+                          NetObjInsert(pGroup, FALSE);  // Insert into indexes
+                  }
+                  else     // Object load failed
+                  {
+                          delete pGroup;
+                          /* FIXME nxlog_write(MSG_BS_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId); */
+                          DbgPrintf(1, _T("Failed to load business services"));
+                  }
+          }
+          DBFreeResult(hResult);
+   }
+
    // Link childs to container and template group objects
    DbgPrintf(2, _T("Linking objects..."));
        g_idxObjectById.forEach(LinkChildObjectsCallback, NULL);
@@ -1318,6 +1360,7 @@ BOOL LoadObjects()
    g_pMapRoot->LinkChildObjects();
        g_pDashboardRoot->LinkChildObjects();
        g_pReportRoot->LinkChildObjects();
+       g_pBizServiceRoot->LinkChildObjects();
 
    // Allow objects to change it's modification flag
    g_bModificationsLocked = FALSE;
@@ -1328,6 +1371,7 @@ BOOL LoadObjects()
    g_pTemplateRoot->calculateCompoundStatus();
    g_pPolicyRoot->calculateCompoundStatus();
    g_pMapRoot->calculateCompoundStatus();
+   g_pBizServiceRoot->calculateCompoundStatus();
 
    // Recalculate status for zone objects
    if (g_dwFlags & AF_ENABLE_ZONING)
index c84a9b0..f08fc93 100644 (file)
@@ -196,3 +196,33 @@ void ReportRoot::calculateCompoundStatus(BOOL bForcedRecalc)
 {
    m_iStatus = STATUS_NORMAL;
 }
+
+
+//
+// Biz service tree root class default constructor
+//
+
+BizServiceRoot::BizServiceRoot() : 
+       UniversalRoot()
+{
+       m_dwId = BUILTIN_OID_BIZSERVICEROOT;
+       _tcscpy(m_szName, _T("Services"));
+       m_iStatus = STATUS_NORMAL;
+}
+
+//
+// Biz service root class destructor
+//
+
+BizServiceRoot::~BizServiceRoot()
+{
+}
+
+//
+// Redefined status calculation 
+//
+
+void BizServiceRoot::calculateCompoundStatus(BOOL bForcedRecalc)
+{
+   m_iStatus = STATUS_NORMAL;
+}
index c44c53a..91b05fc 100644 (file)
@@ -3889,6 +3889,10 @@ void ClientSession::createObject(CSCPMessage *pRequest)
                                                                pObject = new Report(szObjectName);
                                                                NetObjInsert(pObject, TRUE);
                                                                break;
+                                                       case OBJECT_BIZSERVICE:
+                                                               pObject = new BizService(szObjectName);
+                                                               NetObjInsert(pObject, TRUE);
+                                                               break;
                                                        default:
                                                                break;
                                                }
diff --git a/src/server/core/slm.cpp b/src/server/core/slm.cpp
new file mode 100644 (file)
index 0000000..751e064
--- /dev/null
@@ -0,0 +1,78 @@
+/* 
+** NetXMS - Network Management System
+** Copyright (C) 2003-2011 NetXMS Team
+**
+** 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
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+** File: slm.cpp
+**
+**/
+
+#include "nxcore.h"
+
+static bool SlmLoadChecks(void)
+{
+       DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
+
+       DBConnectionPoolReleaseConnection(hdb);
+
+       return true;
+}
+
+static bool SlmInit(void)
+{
+       // Load SLM checks
+
+       if (!SlmLoadChecks())
+       {
+               DbgPrintf(1, _T("Cannot load SLM checks"));
+       }
+
+       return true;
+}
+
+THREAD_RESULT THREAD_CALL ServiceLevelMonitoring(void *pArg)
+{
+       const DWORD dwInterval = 60;
+       time_t currTime;
+
+       DbgPrintf(1, _T("SLM thread started"));
+
+       if (!SlmInit())
+               goto finish;
+
+       while(!IsShutdownInProgress())
+       {
+               currTime = time(NULL);
+               if (SleepAndCheckForShutdown(dwInterval - (DWORD)(currTime % dwInterval)))
+                       break;      // Shutdown has arrived
+
+               DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
+
+               NetObj* curObject;
+
+               for (int i = 0; i < g_pBizServiceRoot->m_dwChildCount; i++)
+               {
+                       curObject = g_pBizServiceRoot->m_pChildList[i];
+                       curObject->calculateCompoundStatus();
+               }
+
+               DBConnectionPoolReleaseConnection(hdb);
+       }
+
+finish:
+       DbgPrintf(1, _T("SLM thread terminated"));
+       return THREAD_OK;
+}
diff --git a/src/server/core/slm_objects.cpp b/src/server/core/slm_objects.cpp
new file mode 100644 (file)
index 0000000..5e78366
--- /dev/null
@@ -0,0 +1,586 @@
+/* 
+** NetXMS - Network Management System
+** Copyright (C) 2003-2011 NetXMS Team
+**
+** 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
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+** File: slm_objects.cpp
+**
+**/
+
+#include "nxcore.h"
+#include "nms_objects.h"
+
+#define QUERY_LENGTH           (512)
+
+//
+// Service default constructor
+//
+
+BizService::BizService()
+     :Container()
+{
+       _tcscpy(m_szName, _T("Default"));
+}
+
+
+//
+// Constructor for new service object
+//
+
+BizService::BizService(const TCHAR *name)
+     :Container(name, 0)
+{
+       m_dwId = 0;
+       nx_strncpy(m_szName, name, MAX_OBJECT_NAME);
+}
+
+
+//
+// Service class destructor
+//
+
+BizService::~BizService()
+{
+}
+
+void BizService::calculateCompoundStatus(BOOL bForcedRecalc /*= FALSE*/)
+{
+       int i, iCount, iMostCriticalStatus;
+
+       LockChildList(FALSE);
+
+       for(i = 0, iCount = 0, iMostCriticalStatus = -1; i < m_dwChildCount; i++)
+       {
+               int iChildStatus = m_pChildList[i]->PropagatedStatus();
+               if ((iChildStatus < STATUS_UNKNOWN) &&
+                       (iChildStatus > iMostCriticalStatus))
+               {
+                       iMostCriticalStatus = iChildStatus;
+                       iCount++;
+               }
+       }
+       m_iStatus = (iCount > 0) ? iMostCriticalStatus : STATUS_UNKNOWN;
+
+       UnlockChildList();
+}
+
+//
+// Create object from database data
+//
+
+BOOL BizService::CreateFromDB(DWORD id)
+{
+       m_dwId = id;
+
+       if (!loadCommonProperties())
+               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;
+       }
+
+       // m_svcStatus  = DBGetFieldULong(hResult, 0, 0);
+
+       DBFreeResult(hResult);
+       DBFreeStatement(hStmt);
+
+       // Load access list
+       loadACLFromDB();
+
+       return TRUE;
+}
+
+
+//
+// Save service to database
+//
+
+BOOL BizService::SaveToDB(DB_HANDLE hdb)
+{
+       BOOL bNewObject = TRUE;
+       TCHAR szQuery[QUERY_LENGTH];
+
+       LockData();
+
+       saveCommonProperties(hdb);
+   
+       DB_STATEMENT hStmt = DBPrepare(hdb, _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, 0, DB_SQLTYPE_INTEGER, m_dwId);
+       DB_RESULT hResult = DBSelectPrepared(hStmt);
+       if (hResult != NULL)
+       {
+               bNewObject = (DBGetNumRows(hResult) <= 0);
+               DBFreeResult(hResult);
+       }
+       DBFreeStatement(hStmt);
+
+       if (bNewObject)
+               nx_strncpy(szQuery, _T("INSERT INTO business_services (service_id) VALUES (?)"), QUERY_LENGTH);
+       else
+               nx_strncpy(szQuery, _T("UPDATE business_services SET service_id=service_id WHERE service_id=?"), QUERY_LENGTH);
+       hStmt = DBPrepare(g_hCoreDB, szQuery);
+       if (hStmt == NULL)      
+       {
+               DbgPrintf(4, _T("Cannot prepare %s from business_services"), bNewObject ? _T("insert") : _T("update"));
+               return FALSE;
+       }
+       DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, m_dwId);
+       if (!DBExecute(hStmt))
+       {
+               DbgPrintf(4, _T("Cannot execute %s on business_services"), bNewObject ? _T("insert") : _T("update"));
+               DBFreeStatement(hStmt);
+               return FALSE;
+       }
+
+       DBFreeResult(hResult);
+       DBFreeStatement(hStmt);
+
+       saveACLToDB(hdb);
+
+       // Unlock object and clear modification flag
+       m_bIsModified = FALSE;
+       UnlockData();
+       return TRUE;
+}
+
+
+//
+// Delete object from database
+//
+
+BOOL BizService::DeleteFromDB()
+{
+   TCHAR szQuery[QUERY_LENGTH];
+   BOOL bSuccess;
+
+   bSuccess = NetObj::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 BizService::CreateMessage(CSCPMessage *pMsg)
+{
+   NetObj::CreateMessage(pMsg);
+   // pMsg->SetVariable(VID_ID, m_dwId);
+   // pMsg->SetVariable(VID_STATUS, m_svcStatus);
+}
+
+
+//
+// Modify object from message
+//
+
+DWORD BizService::ModifyFromMessage(CSCPMessage *pRequest, BOOL bAlreadyLocked)
+{
+   if (!bAlreadyLocked)
+      LockData();
+
+       // if (pRequest->IsVariableExist(VID_STATUS))
+       //      m_svcStatus = pRequest->GetVariableLong(VID_STATUS);
+
+   return NetObj::ModifyFromMessage(pRequest, TRUE);
+}
+
+
+
+//
+// SLMCheck default constructor
+//
+
+SlmCheck::SlmCheck()
+:NetObj()
+{
+       _tcscpy(m_szName, _T("Default"));
+       m_state = FALSE;
+       m_script = NULL;
+       m_threshold = NULL;
+       m_reason[0] = _T('\0');
+}
+
+
+//
+// Constructor for new check object
+//
+
+SlmCheck::SlmCheck(const TCHAR *name)
+:NetObj()
+{
+       nx_strncpy(m_szName, name, MAX_OBJECT_NAME);
+       m_state = FALSE;
+       m_script = NULL;
+       m_threshold = NULL;
+       m_reason[0] = _T('\0');
+}
+
+
+//
+// Service class destructor
+//
+
+SlmCheck::~SlmCheck()
+{
+       safe_delete_and_null(m_threshold);
+       safe_free_and_null(m_script);
+}
+
+void SlmCheck::calculateCompoundStatus(BOOL bForcedRecalc /*= FALSE*/)
+{
+       m_iStatus = STATUS_NORMAL;
+}
+
+//
+// Create object from database data
+//
+
+BOOL SlmCheck::CreateFromDB(DWORD id)
+{
+       const int script_length = 1024;
+       DWORD thresholdId;
+       m_dwId = id;
+
+       if (!loadCommonProperties())
+               return FALSE;
+
+       DB_STATEMENT hStmt = DBPrepare(g_hCoreDB, _T("SELECT type,content,threshold_id,state,reason FROM slm_checks WHERE check_id=?"));
+       if (hStmt == NULL)
+       {
+               DbgPrintf(4, _T("Cannot prepare select from slm_checks"));
+               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 check object %ld - record missing"), (long)m_dwId);
+               return FALSE;
+       }
+
+       m_type          = SlmCheck::CheckType(DBGetFieldLong(hResult, 0, 0));
+       DBGetField(hResult, 0, 1, m_script, script_length);
+       thresholdId = DBGetFieldLong(hResult, 0, 2);
+       m_state         = DBGetFieldLong(hResult, 0, 3);
+       DBGetField(hResult, 0, 4, m_reason, 255);
+
+       if (thresholdId > 0)
+       {
+               // FIXME: load threshold
+       }
+
+       DBFreeResult(hResult);
+       DBFreeStatement(hStmt);
+
+       // Load access list
+       loadACLFromDB();
+
+       return TRUE;
+}
+
+
+//
+// Save service to database
+//
+
+BOOL SlmCheck::SaveToDB(DB_HANDLE hdb)
+{
+       return TRUE;
+}
+
+
+//
+// Delete object from database
+//
+
+BOOL SlmCheck::DeleteFromDB()
+{
+       TCHAR szQuery[QUERY_LENGTH];
+       BOOL bSuccess;
+
+       bSuccess = NetObj::DeleteFromDB();
+       if (bSuccess)
+       {
+               _sntprintf(szQuery, QUERY_LENGTH, _T("DELETE FROM slm_checks WHERE check_id=%d"), m_dwId);
+               QueueSQLRequest(szQuery);
+       }
+
+       return bSuccess;
+}
+
+
+//
+// Create CSCP message with object's data
+//
+
+void SlmCheck::CreateMessage(CSCPMessage *pMsg)
+{
+       NetObj::CreateMessage(pMsg);
+       // pMsg->SetVariable(VID_ID, m_dwId);
+       // pMsg->SetVariable(VID_STATUS, m_svcStatus);
+}
+
+
+//
+// Modify object from message
+//
+
+DWORD SlmCheck::ModifyFromMessage(CSCPMessage *pRequest, BOOL bAlreadyLocked)
+{
+       if (!bAlreadyLocked)
+               LockData();
+
+       // if (pRequest->IsVariableExist(VID_STATUS))
+       //      m_svcStatus = pRequest->GetVariableLong(VID_STATUS);
+
+       return NetObj::ModifyFromMessage(pRequest, TRUE);
+}
+
+
+//
+// NodeLink default constructor
+//
+
+NodeLink::NodeLink()
+:NetObj()
+{
+       _tcscpy(m_szName, _T("Default"));
+}
+
+
+//
+// Constructor for new nodelink object
+//
+
+NodeLink::NodeLink(const TCHAR *name)
+:NetObj()
+{
+       nx_strncpy(m_szName, name, MAX_OBJECT_NAME);
+}
+
+
+//
+// Nodelink class destructor
+//
+
+NodeLink::~NodeLink()
+{
+       safe_delete_and_null(m_node);
+}
+
+void NodeLink::calculateCompoundStatus(BOOL bForcedRecalc /*= FALSE*/)
+{
+       m_iStatus = STATUS_NORMAL;
+}
+
+//
+// Create object from database data
+//
+
+BOOL NodeLink::CreateFromDB(DWORD id)
+{
+       const int script_length = 1024;
+       DWORD nodeId;
+       m_dwId = id;
+
+       if (!loadCommonProperties())
+               return FALSE;
+
+       DB_STATEMENT hStmt = DBPrepare(g_hCoreDB, _T("SELECT node_id FROM node_links WHERE nodelink_id=?"));
+       if (hStmt == NULL)
+       {
+               DbgPrintf(4, _T("Cannot prepare select from node_links"));
+               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 nodelink object %ld - record missing"), (long)m_dwId);
+               return FALSE;
+       }
+
+       nodeId  = DBGetFieldLong(hResult, 0, 0);
+       if (nodeId > 0)
+       {
+               m_node = new Node;
+               m_node->CreateFromDB(nodeId);
+       }
+
+       DBFreeResult(hResult);
+       DBFreeStatement(hStmt);
+
+       // Load access list
+       loadACLFromDB();
+
+       return TRUE;
+}
+
+
+//
+// Save service to database
+//
+
+BOOL NodeLink::SaveToDB(DB_HANDLE hdb)
+{
+       BOOL bNewObject = TRUE;
+       TCHAR szQuery[QUERY_LENGTH];
+
+       LockData();
+
+       saveCommonProperties(hdb);
+
+       DB_STATEMENT hStmt = DBPrepare(hdb, _T("SELECT nodelink_id FROM node_links WHERE nodelink_id=?"));
+       if (hStmt == NULL)
+       {
+               DbgPrintf(4, _T("Cannot prepare select from node_links"));
+               return FALSE;
+       }
+       DBBind(hStmt, 0, DB_SQLTYPE_INTEGER, m_dwId);
+       DB_RESULT hResult = DBSelectPrepared(hStmt);
+       if (hResult != NULL)
+       {
+               bNewObject = (DBGetNumRows(hResult) <= 0);
+               DBFreeResult(hResult);
+       }
+       DBFreeStatement(hStmt);
+
+       if (bNewObject)
+               nx_strncpy(szQuery, _T("INSERT INTO node_links (node_id, nodelink_id) VALUES (?, ?)"), QUERY_LENGTH);
+       else
+               nx_strncpy(szQuery, _T("UPDATE node_links SET node_id=? WHERE nodelink_id=?"), QUERY_LENGTH);
+       hStmt = DBPrepare(g_hCoreDB, szQuery);
+       if (hStmt == NULL)      
+       {
+               DbgPrintf(4, _T("Cannot prepare %s from node_links"), bNewObject ? _T("insert") : _T("update"));
+               return FALSE;
+       }
+       DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, m_node == NULL ? 0 : m_node->Id());
+       DBBind(hStmt, 2, DB_SQLTYPE_INTEGER, m_dwId);
+       if (!DBExecute(hStmt))
+       {
+               DbgPrintf(4, _T("Cannot execute %s on node_links"), bNewObject ? _T("insert") : _T("update"));
+               DBFreeStatement(hStmt);
+               return FALSE;
+       }
+
+       DBFreeResult(hResult);
+       DBFreeStatement(hStmt);
+
+       saveACLToDB(hdb);
+
+       // Unlock object and clear modification flag
+       m_bIsModified = FALSE;
+       UnlockData();
+       return TRUE;
+}
+
+
+//
+// Delete object from database
+//
+
+BOOL NodeLink::DeleteFromDB()
+{
+       TCHAR szQuery[QUERY_LENGTH];
+       BOOL bSuccess;
+
+       bSuccess = NetObj::DeleteFromDB();
+       if (bSuccess)
+       {
+               _sntprintf(szQuery, QUERY_LENGTH, _T("DELETE FROM node_links WHERE nodelink_id=%d"), m_dwId);
+               QueueSQLRequest(szQuery);
+       }
+
+       return bSuccess;
+}
+
+
+//
+// Create CSCP message with object's data
+//
+
+void NodeLink::CreateMessage(CSCPMessage *pMsg)
+{
+       NetObj::CreateMessage(pMsg);
+       // pMsg->SetVariable(VID_ID, m_dwId);
+       // pMsg->SetVariable(VID_STATUS, m_svcStatus);
+}
+
+
+//
+// Modify object from message
+//
+
+DWORD NodeLink::ModifyFromMessage(CSCPMessage *pRequest, BOOL bAlreadyLocked)
+{
+       if (!bAlreadyLocked)
+               LockData();
+
+       // if (pRequest->IsVariableExist(VID_STATUS))
+       //      m_svcStatus = pRequest->GetVariableLong(VID_STATUS);
+
+       return NetObj::ModifyFromMessage(pRequest, TRUE);
+}
index 21ddd8d..c8d9282 100644 (file)
@@ -83,7 +83,7 @@ extern DWORD g_dwConditionPollingInterval;
 #define BUILTIN_OID_NETWORKMAPROOT  6
 #define BUILTIN_OID_DASHBOARDROOT   7
 #define BUILTIN_OID_REPORTROOT      8
-
+#define BUILTIN_OID_BIZSERVICEROOT     9
 
 //
 // Node runtime (dynamic) flags
@@ -1551,6 +1551,104 @@ public:
        DWORD execute(StringMap *parameters, DWORD userId);
 };
 
+//
+// Node link object for biz service (actually is a node)
+//
+
+class NXCORE_EXPORTABLE NodeLink : public NetObj
+{
+protected:
+       Node* m_node;
+
+public:
+       NodeLink();
+       NodeLink(const TCHAR *name);
+       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);
+};
+
+//
+// SLM check object
+//
+
+class NXCORE_EXPORTABLE SlmCheck : public NetObj
+{
+protected:
+       Threshold* m_threshold;
+       enum CheckType { check_undefined = 0, check_script = 1, check_threshold = 2 } m_type;
+       TCHAR* m_script;
+       BOOL m_state;
+       TCHAR m_reason[256];
+
+public:
+       SlmCheck();
+       SlmCheck(const TCHAR *name);
+       virtual ~SlmCheck();
+
+       virtual int Type() { return OBJECT_SLMCHECK; }
+       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 setReason(const TCHAR* reason) { nx_strncpy(m_reason, reason, 255); }
+       const TCHAR* getReason() const { return m_reason; }
+};
+
+
+//
+// Business service root
+//
+
+class NXCORE_EXPORTABLE BizServiceRoot : public UniversalRoot
+{
+public:
+       BizServiceRoot();
+       virtual ~BizServiceRoot();
+
+       virtual int Type() { return OBJECT_BIZSERVICEROOT; }
+       virtual void calculateCompoundStatus(BOOL bForcedRecalc = FALSE);
+};
+
+
+//
+// Business service object
+//
+
+class NXCORE_EXPORTABLE BizService : public Container
+{
+protected:
+
+public:
+       BizService();
+       BizService(const TCHAR *name);
+       virtual ~BizService();
+
+       virtual int Type() { return OBJECT_BIZSERVICE; }
+       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);
+};
+
+
 
 //
 // Container category information
@@ -1617,6 +1715,7 @@ extern PolicyRoot NXCORE_EXPORTABLE *g_pPolicyRoot;
 extern NetworkMapRoot NXCORE_EXPORTABLE *g_pMapRoot;
 extern DashboardRoot NXCORE_EXPORTABLE *g_pDashboardRoot;
 extern ReportRoot NXCORE_EXPORTABLE *g_pReportRoot;
+extern BizServiceRoot NXCORE_EXPORTABLE *g_pBizServiceRoot;
 
 extern DWORD NXCORE_EXPORTABLE g_dwMgmtNode;
 extern DWORD g_dwNumCategories;
index 4820df6..14a2509 100644 (file)
 #define SG_RAW_RESULT     0x0004
 #define SG_HSTRING_RESULT 0x0008
 
+//
+// SLM flags
+//
+
+#define SLM_ENABLED                    (0x0001)
 
 //
 // Win32 service and syslog constants