module-specific data can be transmitted in object update messages
authorVictor Kirhenshtein <victor@netxms.org>
Sun, 25 May 2014 19:24:56 +0000 (22:24 +0300)
committerVictor Kirhenshtein <victor@netxms.org>
Sun, 25 May 2014 19:24:56 +0000 (22:24 +0300)
12 files changed:
.gitignore
doc/internal/event_code_ranges.txt
include/nms_cscp.h
include/nms_util.h
src/java/netxms-base/src/main/java/org/netxms/base/NXCPCodes.java
src/java/netxms-client-api/src/main/java/org/netxms/api/client/services/ServiceHandler.java [new file with mode: 0644]
src/java/netxms-client-api/src/main/java/org/netxms/api/client/services/ServiceManager.java [new file with mode: 0644]
src/java/netxms-client/src/main/java/org/netxms/client/ModuleDataProvider.java [new file with mode: 0644]
src/java/netxms-client/src/main/java/org/netxms/client/objects/AbstractObject.java
src/server/core/modules.cpp
src/server/core/netobj.cpp
src/server/include/nxmodule.h

index 0100912..270daa1 100644 (file)
@@ -41,6 +41,8 @@ target
 .deps
 .idea
 
+/runtime-nxmc.*
+
 /aclocal.m4
 /android/src/agent/bin
 /android/src/agent/gen
index f99ad96..d4c9963 100644 (file)
@@ -1,10 +1,10 @@
 0 - 499                System events
 500 - 510      Well-known SNMP traps
 4000 - 4999    Predefined threshold violation events
-5000 - 5999     ATM monitoring
+5000 - 5999     ATM monitoring (generic events)
+5500 - 5999     XFS subagent
 80000 - 80999   VEDAS
 88000 - 88999   FIS/IST
-89000 - 89899   XFS subagent
 89900 - 89999   AVS (ATM Video Surveillance) subsystem
 90000 - 90999  Agilis monitoring subagent
 91000 - 91099   Cortex monitoring subagent
index f8f07fa..bf24ef4 100644 (file)
@@ -977,6 +977,7 @@ typedef struct
 #define VID_VIEW_REFRESH_INTERVAL   ((UINT32)473)
 #define VID_COMMAND_NAME            ((UINT32)474)
 #define VID_COMMAND_SHORT_NAME      ((UINT32)475)
+#define VID_MODULE_DATA_COUNT       ((UINT32)476)
 
 // Base variabe for single threshold in message
 #define VID_THRESHOLD_BASE          ((UINT32)0x00800000)
@@ -1024,8 +1025,9 @@ typedef struct
 #define VID_CHILD_ID_BASE           ((UINT32)0x80000000)
 #define VID_CHILD_ID_LAST           ((UINT32)0xFFFFFFFE)
 
-// Base value for custom attributes
+// Base value for custom attributes and module data
 #define VID_CUSTOM_ATTRIBUTES_BASE  ((UINT32)0x70000000)
+#define VID_MODULE_DATA_BASE        ((UINT32)0x71000000)
 
 // Base value for cluster resource list
 #define VID_RESOURCE_LIST_BASE      ((UINT32)0x20000000)
index c7da72e..32c7a92 100644 (file)
@@ -913,32 +913,37 @@ typedef struct _dir_struc_w
 #endif
 
 #ifdef __cplusplus
-   inline TCHAR *nx_strncpy(TCHAR *pszDest, const TCHAR *pszSrc, size_t nLen)
-   {
+inline TCHAR *nx_strncpy(TCHAR *pszDest, const TCHAR *pszSrc, size_t nLen)
+{
 #if defined(_WIN32) && (_MSC_VER >= 1400)
-               _tcsncpy_s(pszDest, nLen, pszSrc, _TRUNCATE);
+       _tcsncpy_s(pszDest, nLen, pszSrc, _TRUNCATE);
 #else
-      _tcsncpy(pszDest, pszSrc, nLen - 1);
-      pszDest[nLen - 1] = 0;
+   _tcsncpy(pszDest, pszSrc, nLen - 1);
+   pszDest[nLen - 1] = 0;
 #endif
-      return pszDest;
-   }
+   return pszDest;
+}
 
 #ifdef UNICODE
-   inline char *nx_strncpy_mb(char *pszDest, const char *pszSrc, size_t nLen)
-   {
+inline char *nx_strncpy_mb(char *pszDest, const char *pszSrc, size_t nLen)
+{
 #if defined(_WIN32) && (_MSC_VER >= 1400)
-               strncpy_s(pszDest, nLen, pszSrc, _TRUNCATE);
+       strncpy_s(pszDest, nLen, pszSrc, _TRUNCATE);
 #else
-      strncpy(pszDest, pszSrc, nLen - 1);
-      pszDest[nLen - 1] = 0;
+   strncpy(pszDest, pszSrc, nLen - 1);
+   pszDest[nLen - 1] = 0;
 #endif
-      return pszDest;
-   }
+   return pszDest;
+}
 #else
 #define nx_strncpy_mb nx_strncpy
 #endif
 
+inline TCHAR *_tcsdup_ex(const TCHAR *s)
+{
+   return (s != NULL) ? _tcsdup(s) : NULL;
+}
+
 int LIBNETXMS_EXPORTABLE ConnectEx(SOCKET s, struct sockaddr *addr, int len, UINT32 timeout);
 int LIBNETXMS_EXPORTABLE SendEx(SOCKET hSocket, const void *data, size_t len, int flags, MUTEX mutex);
 int LIBNETXMS_EXPORTABLE RecvEx(SOCKET hSocket, void *data, size_t len, int flags, UINT32 timeout);
index b5c6c14..7349d57 100644 (file)
@@ -803,6 +803,7 @@ public class NXCPCodes
    public static final long VID_VIEW_REFRESH_INTERVAL = 473;
    public static final long VID_COMMAND_NAME = 474;
    public static final long VID_COMMAND_SHORT_NAME = 475;
+   public static final long VID_MODULE_DATA_COUNT = 476;
 
        public static final long VID_ACL_USER_BASE = 0x00001000L;
        public static final long VID_ACL_USER_LAST = 0x00001FFFL;
@@ -829,6 +830,7 @@ public class NXCPCodes
        public static final long VID_CHILD_ID_BASE = 0x80000000L;
        public static final long VID_CHILD_ID_LAST = 0xFFFFFFFEL;
        public static final long VID_CUSTOM_ATTRIBUTES_BASE = 0x70000000L;
+   public static final long VID_MODULE_DATA_BASE = 0x71000000L;
        public static final long VID_RESOURCE_LIST_BASE = 0x20000000L;
        public static final long VID_ENUM_VALUE_BASE = 0x10000000L;
        public static final long VID_ACTION_ARG_BASE = 0x10000000L;
diff --git a/src/java/netxms-client-api/src/main/java/org/netxms/api/client/services/ServiceHandler.java b/src/java/netxms-client-api/src/main/java/org/netxms/api/client/services/ServiceHandler.java
new file mode 100644 (file)
index 0000000..b55e1ee
--- /dev/null
@@ -0,0 +1,32 @@
+/**
+ * NetXMS - open source network management system
+ * Copyright (C) 2003-2014 Victor Kirhenshtein
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * 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.
+ */
+package org.netxms.api.client.services;
+
+/**
+ * Service handler interface
+ */
+public interface ServiceHandler
+{
+   /**
+    * Get service name
+    * 
+    * @return
+    */
+   public String getServiceName();
+}
diff --git a/src/java/netxms-client-api/src/main/java/org/netxms/api/client/services/ServiceManager.java b/src/java/netxms-client-api/src/main/java/org/netxms/api/client/services/ServiceManager.java
new file mode 100644 (file)
index 0000000..3f7d3ec
--- /dev/null
@@ -0,0 +1,97 @@
+/**
+ * NetXMS - open source network management system
+ * Copyright (C) 2003-2014 Victor Kirhenshtein
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * 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.
+ */
+package org.netxms.api.client.services;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Manager for client services
+ */
+public final class ServiceManager
+{
+   private static Map<String, ServiceHandler> servicesByName = new HashMap<String, ServiceHandler>();
+   private static Map<Class<? extends ServiceHandler>, ServiceHandler> servicesByClass = new HashMap<Class<? extends ServiceHandler>, ServiceHandler>();
+   
+   /**
+    * Register service
+    * 
+    * @param name
+    * @param handler
+    * @return
+    */
+   public static synchronized boolean registerService(ServiceHandler handler)
+   {
+      if (servicesByName.containsKey(handler.getServiceName()) || servicesByClass.containsKey(handler.getClass()))
+         return false;
+      servicesByName.put(handler.getServiceName(), handler);
+      servicesByClass.put(handler.getClass(), handler);
+      return true;
+   }
+   
+   /**
+    * Unregister service
+    * 
+    * @param name
+    */
+   public static synchronized void unregisterService(String name)
+   {
+      ServiceHandler h = servicesByName.get(name);
+      if (h != null)
+      {
+         servicesByName.remove(name);
+         servicesByClass.remove(h.getClass());
+      }
+   }
+
+   /**
+    * Get service handler by name and check if handler class is correct.
+    * 
+    * @param name
+    * @param serviceClass
+    * @return
+    */
+   public static synchronized ServiceHandler getServiceHandler(String name, Class<? extends ServiceHandler> serviceClass)
+   {
+      ServiceHandler h = servicesByName.get(name);
+      return serviceClass.isInstance(h) ? h : null;
+   }
+   
+   /**
+    * Get service handler by name
+    * 
+    * @param name
+    * @return
+    */
+   public static synchronized ServiceHandler getServiceHandler(String name)
+   {
+      return servicesByName.get(name);
+   }
+   
+   /**
+    * Get service handler by class
+    * 
+    * @param serviceClass
+    * @return
+    */
+   public static synchronized ServiceHandler getServiceHandler(Class<? extends ServiceHandler> serviceClass)
+   {
+      return servicesByClass.get(serviceClass);
+   }
+}
diff --git a/src/java/netxms-client/src/main/java/org/netxms/client/ModuleDataProvider.java b/src/java/netxms-client/src/main/java/org/netxms/client/ModuleDataProvider.java
new file mode 100644 (file)
index 0000000..8c9adc6
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * 
+ */
+package org.netxms.client;
+
+import org.netxms.api.client.services.ServiceHandler;
+import org.netxms.base.NXCPMessage;
+
+/**
+ * Module data provider
+ */
+public interface ModuleDataProvider extends ServiceHandler
+{
+   /**
+    * Create module data from NXCP message
+    * 
+    * @param msg
+    * @param baseId
+    * @return
+    */
+   public Object createModuleData(NXCPMessage msg, long baseId);
+}
index 19418ec..786520d 100644 (file)
@@ -27,11 +27,13 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+import org.netxms.api.client.services.ServiceManager;
 import org.netxms.base.GeoLocation;
 import org.netxms.base.NXCPCodes;
 import org.netxms.base.NXCPMessage;
 import org.netxms.base.NXCommon;
 import org.netxms.client.AccessListElement;
+import org.netxms.client.ModuleDataProvider;
 import org.netxms.client.NXCSession;
 import org.netxms.client.constants.Severity;
 
@@ -131,6 +133,7 @@ public abstract class AbstractObject
        protected HashSet<Long> parents = new HashSet<Long>(0);
        protected HashSet<Long> children = new HashSet<Long>(0);
        protected Map<String, String> customAttributes = new HashMap<String, String>(0);
+       protected Map<String, Object> moduleData = null;
        
        private int effectiveRights = 0;
        private boolean effectiveRightsCached = false;
@@ -230,7 +233,7 @@ public abstract class AbstractObject
                        parents.add(msg.getVariableAsInt64(id));
                }
 
-               // Childs
+               // Children
                count = msg.getVariableAsInteger(NXCPCodes.VID_CHILD_CNT);
                for(i = 0, id = NXCPCodes.VID_CHILD_ID_BASE; i < count; i++, id++)
                {
@@ -263,6 +266,22 @@ public abstract class AbstractObject
                {
                        accessList.add(new AccessListElement(msg.getVariableAsInt64(id), msg.getVariableAsInteger(id2)));
                }
+               
+               // Module-specific data
+               count = msg.getVariableAsInteger(NXCPCodes.VID_MODULE_DATA_COUNT);
+               if (count > 0)
+               {
+                  moduleData = new HashMap<String, Object>(count);
+                  for(i = 0, id = NXCPCodes.VID_MODULE_DATA_BASE; i < count; i++, id += 0x100000)
+                  {
+                     String module = msg.getVariableAsString(id);
+                     ModuleDataProvider p = (ModuleDataProvider)ServiceManager.getServiceHandler(module, ModuleDataProvider.class);
+                     if (p != null)
+                     {
+                        moduleData.put(module, p.createModuleData(msg, id + 1));
+                     }
+                  }
+               }
        }
 
        /**
@@ -793,4 +812,15 @@ public abstract class AbstractObject
       }
       return effectiveRights;
    }
+   
+   /**
+    * Get module-specific data
+    * 
+    * @param module
+    * @return
+    */
+   public Object getModuleData(String module)
+   {
+      return (moduleData != null) ? moduleData.get(module) : null;
+   }
 }
index 3361a71..2d73048 100644 (file)
@@ -170,3 +170,10 @@ ModuleData::ModuleData()
 ModuleData::~ModuleData()
 {
 }
+
+/**
+ * Fill NXCP message with module data
+ */
+void ModuleData::fillMessage(CSCPMessage *msg, UINT32 baseId)
+{
+}
index b00806a..fb8b2a3 100644 (file)
@@ -880,6 +880,14 @@ void NetObj::CreateMessage(CSCPMessage *pMsg)
 
    m_pAccessList->fillMessage(pMsg);
        m_geoLocation.fillMessage(*pMsg);
+
+   pMsg->SetVariable(VID_MODULE_DATA_COUNT, (UINT16)m_moduleData->getSize());
+   for(i = 0, dwId = VID_MODULE_DATA_BASE; i < m_moduleData->getSize(); i++, dwId += 0x100000)
+   {
+      pMsg->SetVariable(dwId, m_moduleData->getKeyByIndex(i));
+      ModuleData *d = m_moduleData->getValueByIndex(i);
+      d->fillMessage(pMsg, dwId + 1);
+   }
 }
 
 /**
index f922816..bcc84f3 100644 (file)
@@ -48,6 +48,8 @@ class NXCORE_EXPORTABLE ModuleData
 public:
    ModuleData();
    virtual ~ModuleData();
+
+   virtual void fillMessage(CSCPMessage *msg, UINT32 baseId);
 };
 
 /**