implemented data collection for chassis (cached mode not working yet)
authorVictor Kirhenshtein <victor@netxms.org>
Tue, 26 Jul 2016 15:54:25 +0000 (18:54 +0300)
committerVictor Kirhenshtein <victor@netxms.org>
Tue, 26 Jul 2016 15:54:25 +0000 (18:54 +0300)
24 files changed:
src/java/netxms-eclipse/DataCollection/plugin.xml
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/actions/OpenEditor.java
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/actions/ShowLastValues.java
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/objecttabs/LastValues.java
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/views/DataCollectionEditor.java
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/views/LastValues.java
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/widgets/LastValuesWidget.java
src/server/core/agent.cpp
src/server/core/chassis.cpp
src/server/core/datacoll.cpp
src/server/core/dcitem.cpp
src/server/core/dcobject.cpp
src/server/core/dctarget.cpp
src/server/core/node.cpp
src/server/core/objects.cpp
src/server/core/session.cpp
src/server/include/nms_objects.h
webui/webapp/DataCollection/plugin.xml
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/actions/OpenEditor.java
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/actions/ShowLastValues.java
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/objecttabs/LastValues.java
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/views/DataCollectionEditor.java
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/views/LastValues.java
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/widgets/LastValuesWidget.java

index f7d32f3..e531e4f 100644 (file)
    <extension
          point="org.eclipse.ui.popupMenus">
       <objectContribution
-            id="org.netxms.ui.eclipse.datacollection.actions.popup.object.Node"
-            objectClass="org.netxms.client.objects.Node">
+            id="org.netxms.ui.eclipse.datacollection.actions.popup.object.DataCollectionTarget"
+            objectClass="org.netxms.client.objects.DataCollectionTarget">
          <action
                class="org.netxms.ui.eclipse.datacollection.actions.OpenEditor"
                enablesFor="1"
-               id="org.netxms.ui.eclipse.datacollection.popupActions.OpenEditor#Node"
+               id="org.netxms.ui.eclipse.datacollection.popupActions.OpenEditor#DataCollectionTarget"
                label="%action.label.DataCollection"
                icon="icons/dc_editor.png"
                menubarPath="datacollection">
@@ -56,7 +56,7 @@
                class="org.netxms.ui.eclipse.datacollection.actions.ShowLastValues"
                enablesFor="1"
                icon="icons/last_values.png"
-               id="org.netxms.ui.eclipse.datacollection.popupActions.ShowLastValues#Node"
+               id="org.netxms.ui.eclipse.datacollection.popupActions.ShowLastValues#DataCollectionTarget"
                label="%action.label.LastValues"
                menubarPath="datacollection">
          </action>
                menubarPath="datacollection">
          </action>
       </objectContribution>
-      <objectContribution
-            adaptable="false"
-            id="org.netxms.ui.eclipse.datacollection.actions.popup.object.Cluster"
-            objectClass="org.netxms.client.objects.Cluster">
-         <action
-               class="org.netxms.ui.eclipse.datacollection.actions.OpenEditor"
-               enablesFor="1"
-               icon="icons/dc_editor.png"
-               id="org.netxms.ui.eclipse.datacollection.popupActions.OpenEditor#Cluster"
-               label="%action.label.DataCollection"
-               menubarPath="datacollection">
-         </action>
-         <action
-               class="org.netxms.ui.eclipse.datacollection.actions.ShowLastValues"
-               enablesFor="1"
-               icon="icons/last_values.png"
-               id="org.netxms.ui.eclipse.datacollection.popupActions.ShowLastValues#Cluster"
-               label="%action.label.LastValues"
-               menubarPath="datacollection">
-         </action>
-      </objectContribution>
       <objectContribution
             adaptable="false"
             id="org.netxms.ui.eclipse.datacollection.actions.popup.object.DciValue"
                menubarPath="additions">
          </action>
       </objectContribution>
-      <objectContribution
-            id="org.netxms.ui.eclipse.datacollection.actions.popup.object.MobileDevice"
-            objectClass="org.netxms.client.objects.MobileDevice">
-         <action
-               class="org.netxms.ui.eclipse.datacollection.actions.OpenEditor"
-               enablesFor="1"
-               icon="icons/dc_editor.png"
-               id="org.netxms.ui.eclipse.datacollection.popupActions.OpenEditor#MobileDevice"
-               label="%action.label.DataCollection"
-               menubarPath="datacollection">
-         </action>
-         <action
-               class="org.netxms.ui.eclipse.datacollection.actions.ShowLastValues"
-               enablesFor="1"
-               icon="icons/last_values.png"
-               id="org.netxms.ui.eclipse.datacollection.popupActions.ShowLastValues#MobileDevice"
-               label="%action.label.LastValues"
-               menubarPath="datacollection">
-         </action>
-      </objectContribution>
    </extension>
 
   <extension
index 35def95..4a66a70 100644 (file)
@@ -26,10 +26,8 @@ import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.PartInitException;
-import org.netxms.client.objects.AbstractNode;
 import org.netxms.client.objects.AbstractObject;
-import org.netxms.client.objects.Cluster;
-import org.netxms.client.objects.MobileDevice;
+import org.netxms.client.objects.DataCollectionTarget;
 import org.netxms.client.objects.Template;
 import org.netxms.ui.eclipse.datacollection.Messages;
 import org.netxms.ui.eclipse.datacollection.views.DataCollectionEditor;
@@ -81,7 +79,7 @@ public class OpenEditor implements IObjectActionDelegate
                    (((IStructuredSelection)selection).size() == 1))
                {
                        Object element = ((IStructuredSelection)selection).getFirstElement();
-                       if ((element instanceof AbstractNode) || (element instanceof Template) || (element instanceof Cluster) || (element instanceof MobileDevice))
+                       if ((element instanceof DataCollectionTarget) || (element instanceof Template))
                        {
                                object = (AbstractObject)element;
                        }
index e7fe5d0..257d271 100644 (file)
@@ -26,10 +26,7 @@ import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.PartInitException;
-import org.netxms.client.objects.AbstractNode;
-import org.netxms.client.objects.AbstractObject;
-import org.netxms.client.objects.Cluster;
-import org.netxms.client.objects.MobileDevice;
+import org.netxms.client.objects.DataCollectionTarget;
 import org.netxms.ui.eclipse.datacollection.Messages;
 import org.netxms.ui.eclipse.datacollection.views.LastValues;
 import org.netxms.ui.eclipse.tools.MessageDialogHelper;
@@ -40,7 +37,7 @@ import org.netxms.ui.eclipse.tools.MessageDialogHelper;
 public class ShowLastValues implements IObjectActionDelegate
 {
        private IWorkbenchWindow window;
-       private AbstractObject object;
+       private DataCollectionTarget object;
 
        /* (non-Javadoc)
         * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
@@ -80,9 +77,9 @@ public class ShowLastValues implements IObjectActionDelegate
                    (((IStructuredSelection)selection).size() == 1))
                {
                        Object obj = ((IStructuredSelection)selection).getFirstElement();
-                       if ((obj instanceof AbstractNode) || (obj instanceof MobileDevice) || (obj instanceof Cluster))
+                       if (obj instanceof DataCollectionTarget)
                        {
-                               object = (AbstractObject)obj;
+                               object = (DataCollectionTarget)obj;
                        }
                        else
                        {
index 110dc1d..8153daf 100644 (file)
@@ -27,9 +27,7 @@ import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.commands.ICommandService;
 import org.eclipse.ui.contexts.IContextService;
 import org.netxms.client.objects.AbstractObject;
-import org.netxms.client.objects.Cluster;
-import org.netxms.client.objects.MobileDevice;
-import org.netxms.client.objects.Node;
+import org.netxms.client.objects.DataCollectionTarget;
 import org.netxms.ui.eclipse.datacollection.widgets.LastValuesWidget;
 import org.netxms.ui.eclipse.objectview.objecttabs.ObjectTab;
 import org.netxms.ui.eclipse.tools.VisibilityValidator;
@@ -86,7 +84,7 @@ public class LastValues extends ObjectTab
        @Override
        public boolean showForObject(AbstractObject object)
        {
-               return (object instanceof Node) || (object instanceof MobileDevice) || (object instanceof Cluster);
+               return object instanceof DataCollectionTarget;
        }
 
        /* (non-Javadoc)
index 297b585..9b8667a 100644 (file)
@@ -63,6 +63,7 @@ import org.netxms.client.datacollection.DataCollectionTable;
 import org.netxms.client.objects.AbstractNode;
 import org.netxms.client.objects.AbstractObject;
 import org.netxms.client.objects.Cluster;
+import org.netxms.client.objects.DataCollectionTarget;
 import org.netxms.client.objects.MobileDevice;
 import org.netxms.client.objects.Template;
 import org.netxms.ui.eclipse.actions.RefreshAction;
@@ -137,7 +138,7 @@ public class DataCollectionEditor extends ViewPart
                
                session = (NXCSession)ConsoleSharedData.getSession();
                AbstractObject obj = session.findObjectById(Long.parseLong(site.getSecondaryId()));
-               object = ((obj != null) && ((obj instanceof AbstractNode) || (obj instanceof Template) || (obj instanceof Cluster) || (obj instanceof MobileDevice))) ? obj : null;
+               object = ((obj != null) && ((obj instanceof DataCollectionTarget) || (obj instanceof Template))) ? obj : null;
                setPartName(Messages.get().DataCollectionEditor_PartNamePrefix + ((object != null) ? object.getObjectName() : Messages.get().DataCollectionEditor_Error));
        }
 
index ee264ae..9e01d61 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * NetXMS - open source network management system
- * Copyright (C) 2003-2015 Victor Kirhenshtein
+ * Copyright (C) 2003-2016 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
@@ -35,10 +35,8 @@ import org.eclipse.ui.contexts.IContextService;
 import org.eclipse.ui.handlers.IHandlerService;
 import org.eclipse.ui.part.ViewPart;
 import org.netxms.client.NXCSession;
-import org.netxms.client.objects.AbstractNode;
 import org.netxms.client.objects.AbstractObject;
-import org.netxms.client.objects.Cluster;
-import org.netxms.client.objects.MobileDevice;
+import org.netxms.client.objects.DataCollectionTarget;
 import org.netxms.ui.eclipse.actions.RefreshAction;
 import org.netxms.ui.eclipse.console.resources.SharedIcons;
 import org.netxms.ui.eclipse.datacollection.Messages;
@@ -54,7 +52,7 @@ public class LastValues extends ViewPart
        public static final String ID = "org.netxms.ui.eclipse.datacollection.view.last_values"; //$NON-NLS-1$
        
        private NXCSession session;
-       private AbstractObject dcTarget;
+       private DataCollectionTarget dcTarget;
        private LastValuesWidget dataView;
        private Action actionRefresh;
        private Action actionAutoUpdate;
@@ -70,7 +68,7 @@ public class LastValues extends ViewPart
                
                session = (NXCSession)ConsoleSharedData.getSession();
                AbstractObject obj = session.findObjectById(Long.parseLong(site.getSecondaryId()));
-               dcTarget = ((obj != null) && ((obj instanceof AbstractNode) || (obj instanceof MobileDevice) || (obj instanceof Cluster))) ? obj : null;
+               dcTarget = ((obj != null) && (obj instanceof DataCollectionTarget)) ? (DataCollectionTarget)obj : null;
                setPartName(Messages.get().LastValues_PartNamePrefix + ((dcTarget != null) ? dcTarget.getObjectName() : Messages.get().LastValues_Error));
        }
 
index cd9c15a..0c6b480 100644 (file)
@@ -52,10 +52,8 @@ import org.eclipse.ui.IWorkbenchActionConstants;
 import org.eclipse.ui.part.ViewPart;
 import org.netxms.client.NXCSession;
 import org.netxms.client.datacollection.DciValue;
-import org.netxms.client.objects.AbstractNode;
 import org.netxms.client.objects.AbstractObject;
-import org.netxms.client.objects.Cluster;
-import org.netxms.client.objects.MobileDevice;
+import org.netxms.client.objects.DataCollectionTarget;
 import org.netxms.ui.eclipse.actions.ExportToCsvAction;
 import org.netxms.ui.eclipse.console.resources.GroupMarkers;
 import org.netxms.ui.eclipse.console.resources.SharedIcons;
@@ -88,7 +86,7 @@ public class LastValuesWidget extends Composite
        public static final int COLUMN_THRESHOLD = 4;
        
        private final ViewPart viewPart;
-       private AbstractObject dcTarget;
+       private DataCollectionTarget dcTarget;
        private NXCSession session;
        private boolean filterEnabled = false;
        private FilterText filterText;
@@ -400,10 +398,7 @@ public class LastValuesWidget extends Composite
         */
        public void setDataCollectionTarget(AbstractObject dcTarget)
        {
-               if ((dcTarget instanceof AbstractNode) || (dcTarget instanceof MobileDevice) || (dcTarget instanceof Cluster))
-                       this.dcTarget = dcTarget;
-               else
-                       this.dcTarget = null;
+               this.dcTarget = (dcTarget instanceof DataCollectionTarget) ? (DataCollectionTarget)dcTarget : null;
        }
        
        /**
index df6548a..0b4aa3b 100644 (file)
@@ -508,31 +508,44 @@ UINT32 AgentConnectionEx::processCollectedData(NXCPMessage *msg)
       return ERR_INTERNAL_ERROR;
    }
 
-   uuid nodeId = msg->getFieldAsGUID(VID_NODE_ID);
-   if (!nodeId.isNull())
+   DataCollectionTarget *target;
+   uuid targetId = msg->getFieldAsGUID(VID_NODE_ID);
+   if (!targetId.isNull())
    {
-      Node *targetNode = (Node *)FindObjectByGUID(nodeId, OBJECT_NODE);
-      if (targetNode == NULL)
+      NetObj *object = FindObjectByGUID(targetId, -1);
+      if (object == NULL)
       {
          TCHAR buffer[64];
-         DbgPrintf(5, _T("AgentConnectionEx::processCollectedData: cannot find target node with GUID %s"), nodeId.toString(buffer));
+         nxlog_debug(5, _T("AgentConnectionEx::processCollectedData: cannot find target node with GUID %s"), targetId.toString(buffer));
          return ERR_INTERNAL_ERROR;
       }
-      node = targetNode;
+      if (!object->isDataCollectionTarget())
+      {
+         TCHAR buffer[64];
+         nxlog_debug(5, _T("AgentConnectionEx::processCollectedData: object with GUID %s is not a data collection target"), targetId.toString(buffer));
+         return ERR_INTERNAL_ERROR;
+      }
+      target = (DataCollectionTarget *)object;
+   }
+   else
+   {
+      target = node;
    }
 
    UINT32 dciId = msg->getFieldAsUInt32(VID_DCI_ID);
-   DCObject *dcObject = node->getDCObjectById(dciId);
+   DCObject *dcObject = target->getDCObjectById(dciId);
    if (dcObject == NULL)
    {
-      DbgPrintf(5, _T("AgentConnectionEx::processCollectedData: cannot find DCI with ID %d on node %s [%d]"), dciId, node->getName(), node->getId());
+      nxlog_debug(5, _T("AgentConnectionEx::processCollectedData: cannot find DCI with ID %d on object %s [%d]"),
+                  dciId, target->getName(), target->getId());
       return ERR_INTERNAL_ERROR;
    }
 
    int type = msg->getFieldAsInt16(VID_DCOBJECT_TYPE);
    if ((dcObject->getType() != type) || (dcObject->getDataSource() != origin) || (dcObject->getAgentCacheMode() != AGENT_CACHE_ON))
    {
-      DbgPrintf(5, _T("AgentConnectionEx::processCollectedData: DCI %s [%d] on node %s [%d] configuration mismatch"), dcObject->getName(), dciId, node->getName(), node->getId());
+      nxlog_debug(5, _T("AgentConnectionEx::processCollectedData: DCI %s [%d] on object %s [%d] configuration mismatch"),
+                  dcObject->getName(), dciId, target->getName(), target->getId());
       return ERR_INTERNAL_ERROR;
    }
 
@@ -553,10 +566,12 @@ UINT32 AgentConnectionEx::processCollectedData(NXCPMessage *msg)
          value = new Table(msg);
          break;
       default:
-         DbgPrintf(5, _T("AgentConnectionEx::processCollectedData: invalid type %d of DCI %s [%d] on node %s [%d]"), type, dcObject->getName(), dciId, node->getName(), node->getId());
+         nxlog_debug(5, _T("AgentConnectionEx::processCollectedData: invalid type %d of DCI %s [%d] on object %s [%d]"),
+                     type, dcObject->getName(), dciId, target->getName(), target->getId());
          return ERR_INTERNAL_ERROR;
    }
-   DbgPrintf(7, _T("AgentConnectionEx::processCollectedData: processing DCI %s [%d] (type=%d) (status=%d) on node %s [%d]"), dcObject->getName(), dciId, type, status, node->getName(), node->getId());
+   nxlog_debug(7, _T("AgentConnectionEx::processCollectedData: processing DCI %s [%d] (type=%d) (status=%d) on object %s [%d]"),
+               dcObject->getName(), dciId, type, status, target->getName(), target->getId());
 
    switch(status)
    {
@@ -564,7 +579,7 @@ UINT32 AgentConnectionEx::processCollectedData(NXCPMessage *msg)
       {
          if (dcObject->getStatus() == ITEM_STATUS_NOT_SUPPORTED)
             dcObject->setStatus(ITEM_STATUS_ACTIVE, true);
-         success = node->processNewDCValue(dcObject, t, value);
+         success = target->processNewDCValue(dcObject, t, value);
          if (t > dcObject->getLastPollTime())
             dcObject->setLastPollTime(t);
          break;
@@ -629,30 +644,45 @@ UINT32 AgentConnectionEx::processBulkCollectedData(NXCPMessage *request, NXCPMes
       int origin = request->getFieldAsInt16(fieldId + 1);
       if ((origin != DS_NATIVE_AGENT) && (origin != DS_SNMP_AGENT))
       {
-         DbgPrintf(5, _T("AgentConnectionEx::processBulkCollectedData: unsupported data source type %d (element %d)"), origin, i);
+         nxlog_debug(5, _T("AgentConnectionEx::processBulkCollectedData: unsupported data source type %d (element %d)"), origin, i);
          status[i] = BULK_DATA_REC_FAILURE;
          continue;
       }
 
-      uuid nodeId = request->getFieldAsGUID(fieldId + 3);
-      if (!nodeId.isNull())
+      DataCollectionTarget *target;
+      uuid targetId = request->getFieldAsGUID(fieldId + 3);
+      if (!targetId.isNull())
       {
-         Node *targetNode = (Node *)FindObjectByGUID(nodeId, OBJECT_NODE);
-         if (targetNode == NULL)
+         NetObj *object = FindObjectByGUID(targetId, -1);
+         if (object == NULL)
          {
             TCHAR buffer[64];
-            DbgPrintf(5, _T("AgentConnectionEx::processBulkCollectedData: cannot find target node with GUID %s (element %d)"), nodeId.toString(buffer), i);
+            nxlog_debug(5, _T("AgentConnectionEx::processBulkCollectedData: cannot find target object with GUID %s (element %d)"),
+                        targetId.toString(buffer), i);
             status[i] = BULK_DATA_REC_FAILURE;
             continue;
          }
-         node = targetNode;
+         if (!object->isDataCollectionTarget())
+         {
+            TCHAR buffer[64];
+            nxlog_debug(5, _T("AgentConnectionEx::processBulkCollectedData: object with GUID %s (element %d) is not a data collection target"),
+                        targetId.toString(buffer), i);
+            status[i] = BULK_DATA_REC_FAILURE;
+            continue;
+         }
+         target = (DataCollectionTarget *)object;
+      }
+      else
+      {
+         target = node;
       }
 
       UINT32 dciId = request->getFieldAsUInt32(fieldId);
-      DCObject *dcObject = node->getDCObjectById(dciId);
+      DCObject *dcObject = target->getDCObjectById(dciId);
       if (dcObject == NULL)
       {
-         DbgPrintf(5, _T("AgentConnectionEx::processBulkCollectedData: cannot find DCI with ID %d on node %s [%d] (element %d)"), dciId, node->getName(), node->getId(), i);
+         nxlog_debug(5, _T("AgentConnectionEx::processBulkCollectedData: cannot find DCI with ID %d on object %s [%d] (element %d)"),
+                     dciId, target->getName(), target->getId(), i);
          status[i] = BULK_DATA_REC_FAILURE;
          continue;
       }
@@ -660,14 +690,16 @@ UINT32 AgentConnectionEx::processBulkCollectedData(NXCPMessage *request, NXCPMes
       int type = request->getFieldAsInt16(fieldId + 2);
       if ((type != DCO_TYPE_ITEM) || (dcObject->getType() != type) || (dcObject->getDataSource() != origin) || (dcObject->getAgentCacheMode() != AGENT_CACHE_ON))
       {
-         DbgPrintf(5, _T("AgentConnectionEx::processBulkCollectedData: DCI %s [%d] on node %s [%d] configuration mismatch (element %d)"), dcObject->getName(), dciId, node->getName(), node->getId(), i);
+         nxlog_debug(5, _T("AgentConnectionEx::processBulkCollectedData: DCI %s [%d] on object %s [%d] configuration mismatch (element %d)"),
+                     dcObject->getName(), dciId, target->getName(), target->getId(), i);
          status[i] = BULK_DATA_REC_FAILURE;
          continue;
       }
 
       void *value = request->getFieldAsString(fieldId + 5);
       UINT32 status_code = request->getFieldAsUInt32(fieldId + 6);
-      DbgPrintf(7, _T("AgentConnectionEx::processBulkCollectedData: processing DCI %s [%d] (type=%d) (status=%d) on node %s [%d] (element %d)"), dcObject->getName(), dciId, type, status, node->getName(), node->getId(), i);
+      nxlog_debug(7, _T("AgentConnectionEx::processBulkCollectedData: processing DCI %s [%d] (type=%d) (status=%d) on object %s [%d] (element %d)"),
+                  dcObject->getName(), dciId, type, status, target->getName(), target->getId(), i);
       time_t t = request->getFieldAsTime(fieldId + 4);
       bool success = true;
 
@@ -677,7 +709,7 @@ UINT32 AgentConnectionEx::processBulkCollectedData(NXCPMessage *request, NXCPMes
          {
             if (dcObject->getStatus() == ITEM_STATUS_NOT_SUPPORTED)
                dcObject->setStatus(ITEM_STATUS_ACTIVE, true);
-            success = node->processNewDCValue(dcObject, t, value);
+            success = target->processNewDCValue(dcObject, t, value);
             if (t > dcObject->getLastPollTime())
                dcObject->setLastPollTime(t);
             break;
index bd3e5b6..3d05b2f 100644 (file)
@@ -174,6 +174,19 @@ BOOL Chassis::saveToDatabase(DB_HANDLE hdb)
       }
    }
    unlockProperties();
+
+   if (success)
+   {
+      lockDciAccess(false);
+      for(int i = 0; (i < m_dcObjects->size()) && success; i++)
+         success = m_dcObjects->get(i)->saveToDatabase(hdb);
+      unlockDciAccess();
+   }
+
+   if (success)
+   {
+      success = saveACLToDB(hdb);
+   }
    return success;
 }
 
@@ -223,25 +236,65 @@ bool Chassis::loadFromDatabase(DB_HANDLE hdb, UINT32 id)
    DBFreeResult(hResult);
    DBFreeStatement(hStmt);
 
+   loadACLFromDB(hdb);
+   loadItemsFromDB(hdb);
+   for(int i = 0; i < m_dcObjects->size(); i++)
+      if (!m_dcObjects->get(i)->loadThresholdsFromDB(hdb))
+         return false;
+
    updateRackBinding();
    return true;
 }
 
 /**
- * Unbind cluster from template
+ * Called when data collection configuration changed
  */
-void Chassis::unbindFromTemplate(UINT32 dwTemplateId, bool removeDCI)
+void Chassis::onDataCollectionChange()
 {
-   DataCollectionTarget::unbindFromTemplate(dwTemplateId, removeDCI);
-   queueUpdate();
+   Node *controller = (Node *)FindObjectById(m_controllerId, OBJECT_NODE);
+   if (controller == NULL)
+   {
+      nxlog_debug(4, _T("Chassis::onDataCollectionChange(%s [%d]): cannot find controller node object with id %d"), m_name, m_id, m_controllerId);
+      return;
+   }
+   controller->relatedNodeDataCollectionChanged();
 }
 
 /**
- * Called when data collection configuration changed
+ * Collect info for SNMP proxy and DCI source (proxy) nodes
  */
-void Chassis::onDataCollectionChange()
+void Chassis::collectProxyInfo(ProxyInfo *info)
 {
-   queueUpdate();
+   Node *controller = (Node *)FindObjectById(m_controllerId, OBJECT_NODE);
+   if (controller == NULL)
+   {
+      nxlog_debug(4, _T("Chassis::collectProxyInfo(%s [%d]): cannot find controller node object with id %d"), m_name, m_id, m_controllerId);
+      return;
+   }
+
+   bool snmpProxy = (controller->getEffectiveSnmpProxy() == info->proxyId);
+   bool isTarget = false;
+
+   lockDciAccess(false);
+   for(int i = 0; i < m_dcObjects->size(); i++)
+   {
+      DCObject *dco = m_dcObjects->get(i);
+      if (dco->getStatus() == ITEM_STATUS_DISABLED)
+         continue;
+
+      if (((snmpProxy && (dco->getDataSource() == DS_SNMP_AGENT) && (dco->getSourceNode() == 0)) ||
+           ((dco->getDataSource() == DS_NATIVE_AGENT) && (dco->getSourceNode() == info->proxyId))) &&
+          dco->hasValue() && (dco->getAgentCacheMode() == AGENT_CACHE_ON))
+      {
+         addProxyDataCollectionElement(info, dco);
+         if (dco->getDataSource() == DS_SNMP_AGENT)
+            isTarget = true;
+      }
+   }
+   unlockDciAccess();
+
+   if (isTarget)
+      addProxySnmpTarget(info, controller);
 }
 
 /**
@@ -251,3 +304,20 @@ NXSL_Value *Chassis::createNXSLObject()
 {
    return new NXSL_Value(new NXSL_Object(&g_nxslChassisClass, this));
 }
+
+/**
+ * Get effective source node for given data collection object
+ */
+UINT32 Chassis::getEffectiveSourceNode(DCObject *dco)
+{
+   if (dco->getSourceNode() != 0)
+      return dco->getSourceNode();
+   if ((dco->getDataSource() == DS_NATIVE_AGENT) ||
+       (dco->getDataSource() == DS_SMCLP) ||
+       (dco->getDataSource() == DS_SNMP_AGENT) ||
+       (dco->getDataSource() == DS_WINPERF))
+   {
+      return m_controllerId;
+   }
+   return 0;
+}
index e02e887..154f322 100644 (file)
@@ -190,44 +190,50 @@ static THREAD_RESULT THREAD_CALL DataCollector(void *pArg)
 
                if (pItem->isScheduledForDeletion())
                {
-             DbgPrintf(7, _T("DataCollector(): about to destroy DC object %d \"%s\" owner=%d"),
-                                 pItem->getId(), pItem->getName(), (target != NULL) ? (int)target->getId() : -1);
+             nxlog_debug(7, _T("DataCollector(): about to destroy DC object %d \"%s\" owner=%d"),
+                                   pItem->getId(), pItem->getName(), (target != NULL) ? (int)target->getId() : -1);
                        pItem->deleteFromDatabase();
                        delete pItem;
                        continue;
                }
 
+               if (target == NULL)
+               {
+         nxlog_debug(3, _T("DataCollector: attempt to collect information for non-existing node (DCI=%d \"%s\")"),
+                     pItem->getId(), pItem->getName());
+
+         // Update item's last poll time and clear busy flag so item can be polled again
+         pItem->setLastPollTime(time(NULL));
+         pItem->setBusyFlag(FALSE);
+                  continue;
+               }
+
       DbgPrintf(8, _T("DataCollector(): processing DC object %d \"%s\" owner=%d sourceNode=%d"),
                          pItem->getId(), pItem->getName(), (target != NULL) ? (int)target->getId() : -1, pItem->getSourceNode());
-               if (pItem->getSourceNode() != 0)
+      UINT32 sourceNodeId = target->getEffectiveSourceNode(pItem);
+               if (sourceNodeId != 0)
                {
-                       NetObj *object = FindObjectById(pItem->getSourceNode(), OBJECT_NODE);
-                       if (object != NULL)
+                       Node *sourceNode = (Node *)FindObjectById(sourceNodeId, OBJECT_NODE);
+                       if (sourceNode != NULL)
                        {
-                               if (object->isTrustedNode((target != NULL) ? target->getId() : 0))
+                               if (((target->getObjectClass() == OBJECT_CHASSIS) && (((Chassis *)target)->getControllerId() == sourceNodeId)) ||
+                                   sourceNode->isTrustedNode(target->getId()))
                                {
-                                       target = (Node *)object;
+                                       target = sourceNode;
                                        target->incRefCount();
                                }
                                else
                                {
                // Change item's status to _T("not supported")
                pItem->setStatus(ITEM_STATUS_NOT_SUPPORTED, true);
-
-                                       if (target != NULL)
-                                       {
-                                               target->decRefCount();
-                                               target = NULL;
-                                       }
+               target->decRefCount();
+               target = NULL;
                                }
                        }
                        else
                        {
-                               if (target != NULL)
-                               {
-                                       target->decRefCount();
-                                       target = NULL;
-                               }
+            target->decRefCount();
+            target = NULL;
                        }
                }
 
@@ -288,8 +294,8 @@ static THREAD_RESULT THREAD_CALL DataCollector(void *pArg)
       else     /* target == NULL */
       {
                        Template *n = pItem->getOwner();
-         DbgPrintf(3, _T("*** DataCollector: Attempt to collect information for non-existing node (DCI=%d \"%s\" target=%d sourceNode=%d)"),
-                                 pItem->getId(), pItem->getName(), (n != NULL) ? (int)n->getId() : -1, pItem->getSourceNode());
+         nxlog_debug(5, _T("DataCollector: attempt to collect information for non-existing or inaccessible node (DCI=%d \"%s\" target=%d sourceNode=%d)"),
+                                   pItem->getId(), pItem->getName(), (n != NULL) ? (int)n->getId() : -1, sourceNodeId);
       }
 
                // Update item's last poll time and clear busy flag so item can be polled again
@@ -339,6 +345,7 @@ static THREAD_RESULT THREAD_CALL ItemPoller(void *pArg)
                g_idxNodeById.forEach(QueueItems, NULL);
                g_idxClusterById.forEach(QueueItems, NULL);
                g_idxMobileDeviceById.forEach(QueueItems, NULL);
+      g_idxChassisById.forEach(QueueItems, NULL);
 
       // Save last poll time
       dwTimingHistory[currPos] = (UINT32)(GetCurrentTimeMs() - qwStart);
index 18a8cfc..52747ad 100644 (file)
@@ -1041,7 +1041,7 @@ void DCItem::updateCacheSizeInternal(UINT32 conditionId)
 
    // Minimum cache size is 1 for nodes (so GetLastValue can work)
    // and it is always 0 for templates
-   if (((m_owner->getObjectClass() == OBJECT_NODE) || (m_owner->getObjectClass() == OBJECT_MOBILEDEVICE) ||
+   if (((m_owner->isDataCollectionTarget() && (m_owner->getObjectClass() != OBJECT_CLUSTER)) ||
         ((m_owner->getObjectClass() == OBJECT_CLUSTER) && isAggregateOnCluster())) &&
        (m_instanceDiscoveryMethod == IDM_NONE))
    {
index 99eedf8..f5b4946 100644 (file)
@@ -530,12 +530,13 @@ bool DCObject::isReadyForPolling(time_t currTime)
    bool result;
 
    lock();
-   if(m_forcePoll)
+   if (m_forcePoll)
    {
       m_forcePoll = false;
       unlock();
       return true;
    }
+
    if ((m_status != ITEM_STATUS_DISABLED) && (!m_busy) &&
        isCacheLoaded() && (m_source != DS_PUSH_AGENT) &&
        matchClusterResource() && hasValue() && (getAgentCacheMode() == AGENT_CACHE_OFF))
@@ -872,19 +873,27 @@ void DCObject::setTransformationScript(const TCHAR *source)
  */
 INT16 DCObject::getAgentCacheMode()
 {
-   if ((m_owner->getObjectClass() != OBJECT_NODE) ||
-       ((m_source != DS_NATIVE_AGENT) && (m_source != DS_SNMP_AGENT)))
+   if ((m_source != DS_NATIVE_AGENT) && (m_source != DS_SNMP_AGENT))
       return AGENT_CACHE_OFF;
 
-   Node *node = (Node *)m_owner;
+   Node *node = NULL;
    if (m_sourceNode != 0)
    {
       node = (Node *)FindObjectById(m_sourceNode, OBJECT_NODE);
-      if (node == NULL)
+   }
+   else
+   {
+      if (m_owner->getObjectClass() == OBJECT_NODE)
       {
-         return AGENT_CACHE_OFF;
+         node = (Node *)m_owner;
+      }
+      else if (m_owner->getObjectClass() == OBJECT_CHASSIS)
+      {
+         node = (Node *)FindObjectById(((Chassis *)m_owner)->getControllerId(), OBJECT_NODE);
       }
    }
+   if (node == NULL)
+      return AGENT_CACHE_OFF;
 
    if ((m_source == DS_SNMP_AGENT) && (node->getEffectiveSnmpProxy() == 0))
       return AGENT_CACHE_OFF;
index adacdf3..9f62604 100644 (file)
@@ -1,6 +1,6 @@
 /*
 ** NetXMS - Network Management System
-** Copyright (C) 2003-2014 Victor Kirhenshtein
+** Copyright (C) 2003-2016 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
@@ -951,3 +951,82 @@ bool DataCollectionTarget::isDataCollectionTarget()
 {
    return true;
 }
+
+/**
+ * Add data collection element to proxy info structure
+ */
+void DataCollectionTarget::addProxyDataCollectionElement(ProxyInfo *info, const DCObject *dco)
+{
+   info->msg->setField(info->fieldId++, dco->getId());
+   info->msg->setField(info->fieldId++, (INT16)dco->getType());
+   info->msg->setField(info->fieldId++, (INT16)dco->getDataSource());
+   info->msg->setField(info->fieldId++, dco->getName());
+   info->msg->setField(info->fieldId++, (INT32)dco->getEffectivePollingInterval());
+   info->msg->setFieldFromTime(info->fieldId++, dco->getLastPollTime());
+   info->msg->setField(info->fieldId++, m_guid);
+   info->msg->setField(info->fieldId++, dco->getSnmpPort());
+   if (dco->getType() == DCO_TYPE_ITEM)
+      info->msg->setField(info->fieldId++, ((DCItem *)dco)->getSnmpRawValueType());
+   else
+      info->msg->setField(info->fieldId++, (INT16)0);
+   info->fieldId += 1;
+   info->count++;
+}
+
+/**
+ * Add SNMP target to proxy info structure
+ */
+void DataCollectionTarget::addProxySnmpTarget(ProxyInfo *info, const Node *node)
+{
+   info->msg->setField(info->nodeInfoFieldId++, m_guid);
+   info->msg->setField(info->nodeInfoFieldId++, node->getIpAddress());
+   info->msg->setField(info->nodeInfoFieldId++, node->getSNMPVersion());
+   info->msg->setField(info->nodeInfoFieldId++, node->getSNMPPort());
+   SNMP_SecurityContext *snmpSecurity = node->getSnmpSecurityContext();
+   info->msg->setField(info->nodeInfoFieldId++, (INT16)snmpSecurity->getAuthMethod());
+   info->msg->setField(info->nodeInfoFieldId++, (INT16)snmpSecurity->getPrivMethod());
+   info->msg->setFieldFromMBString(info->nodeInfoFieldId++, snmpSecurity->getUser());
+   info->msg->setFieldFromMBString(info->nodeInfoFieldId++, snmpSecurity->getAuthPassword());
+   info->msg->setFieldFromMBString(info->nodeInfoFieldId++, snmpSecurity->getPrivPassword());
+   delete snmpSecurity;
+   info->nodeInfoFieldId += 41;
+   info->nodeInfoCount++;
+}
+
+/**
+ * Collect info for SNMP proxy and DCI source (proxy) nodes
+ * Default implementation adds only agent based DCIs with source node set to requesting node
+ */
+void DataCollectionTarget::collectProxyInfo(ProxyInfo *info)
+{
+   lockDciAccess(false);
+   for(int i = 0; i < m_dcObjects->size(); i++)
+   {
+      DCObject *dco = m_dcObjects->get(i);
+      if (dco->getStatus() == ITEM_STATUS_DISABLED)
+         continue;
+
+      if ((dco->getDataSource() == DS_NATIVE_AGENT) && (dco->getSourceNode() == info->proxyId) &&
+          dco->hasValue() && (dco->getAgentCacheMode() == AGENT_CACHE_ON))
+      {
+         addProxyDataCollectionElement(info, dco);
+      }
+   }
+   unlockDciAccess();
+}
+
+/**
+ * Callback for colecting proxied SNMP DCIs
+ */
+void DataCollectionTarget::collectProxyInfoCallback(NetObj *object, void *data)
+{
+   ((DataCollectionTarget *)object)->collectProxyInfo((ProxyInfo *)data);
+}
+
+/**
+ * Get effective source node for given data collection object
+ */
+UINT32 DataCollectionTarget::getEffectiveSourceNode(DCObject *dco)
+{
+   return dco->getSourceNode();
+}
index b0c7d1c..ac82ebb 100644 (file)
@@ -5788,7 +5788,7 @@ Cluster *Node::getMyCluster()
 /**
  * Get effective SNMP proxy for this node
  */
-UINT32 Node::getEffectiveSnmpProxy()
+UINT32 Node::getEffectiveSnmpProxy() const
 {
        UINT32 snmpProxy = m_snmpProxy;
        if (IsZoningEnabled() && (snmpProxy == 0) && (m_zoneId != 0))
@@ -5872,7 +5872,7 @@ SNMP_Transport *Node::createSnmpTransport(WORD port, const TCHAR *context)
  * ATTENTION: This method returns new copy of security context
  * which must be destroyed by the caller
  */
-SNMP_SecurityContext *Node::getSnmpSecurityContext()
+SNMP_SecurityContext *Node::getSnmpSecurityContext() const
 {
        lockProperties();
        SNMP_SecurityContext *ctx = new SNMP_SecurityContext(m_snmpSecurity);
@@ -7434,82 +7434,6 @@ AccessPointState Node::getAccessPointState(AccessPoint *ap, SNMP_Transport *snmp
    return m_driver->getAccessPointState(snmpTransport, &m_customAttributes, m_driverData, ap->getIndex(), ap->getMacAddr(), ap->getIpAddress());
 }
 
-/**
- * SNMP proxy information structure
- */
-struct ProxyInfo
-{
-   UINT32 proxyId;
-   NXCPMessage *msg;
-   UINT32 fieldId;
-   UINT32 count;
-   UINT32 nodeInfoFieldId;
-   UINT32 nodeInfoCount;
-};
-
-/**
- * Collect info for SNMP proxy and DCI source (proxy) nodes
- */
-void Node::collectProxyInfo(ProxyInfo *info)
-{
-   bool snmpProxy = (getEffectiveSnmpProxy() == info->proxyId);
-   bool isTarget = false;
-
-   lockDciAccess(false);
-   for(int i = 0; i < m_dcObjects->size(); i++)
-   {
-      DCObject *dco = m_dcObjects->get(i);
-      if (dco->getStatus() == ITEM_STATUS_DISABLED)
-         continue;
-
-      if (((snmpProxy && (dco->getDataSource() == DS_SNMP_AGENT) && (dco->getSourceNode() == 0)) ||
-           ((dco->getDataSource() == DS_NATIVE_AGENT) && (dco->getSourceNode() == info->proxyId))) &&
-          dco->hasValue() && (dco->getAgentCacheMode() == AGENT_CACHE_ON))
-      {
-         info->msg->setField(info->fieldId++, dco->getId());
-         info->msg->setField(info->fieldId++, (INT16)dco->getType());
-         info->msg->setField(info->fieldId++, (INT16)dco->getDataSource());
-         info->msg->setField(info->fieldId++, dco->getName());
-         info->msg->setField(info->fieldId++, (INT32)dco->getEffectivePollingInterval());
-         info->msg->setFieldFromTime(info->fieldId++, dco->getLastPollTime());
-         info->msg->setField(info->fieldId++, m_guid);
-         info->msg->setField(info->fieldId++, dco->getSnmpPort());
-         if (dco->getType() == DCO_TYPE_ITEM)
-            info->msg->setField(info->fieldId++, ((DCItem *)dco)->getSnmpRawValueType());
-         else
-            info->msg->setField(info->fieldId++, (INT16)0);
-         info->fieldId += 1;
-         info->count++;
-         if (dco->getDataSource() == DS_SNMP_AGENT)
-            isTarget = true;
-      }
-   }
-   unlockDciAccess();
-
-   if (isTarget)
-   {
-      info->msg->setField(info->nodeInfoFieldId++, m_guid);
-      info->msg->setField(info->nodeInfoFieldId++, m_ipAddress);
-      info->msg->setField(info->nodeInfoFieldId++, m_snmpVersion);
-      info->msg->setField(info->nodeInfoFieldId++, m_snmpPort);
-      info->msg->setField(info->nodeInfoFieldId++, (INT16)m_snmpSecurity->getAuthMethod());
-      info->msg->setField(info->nodeInfoFieldId++, (INT16)m_snmpSecurity->getPrivMethod());
-      info->msg->setFieldFromMBString(info->nodeInfoFieldId++, m_snmpSecurity->getUser());
-      info->msg->setFieldFromMBString(info->nodeInfoFieldId++, m_snmpSecurity->getAuthPassword());
-      info->msg->setFieldFromMBString(info->nodeInfoFieldId++, m_snmpSecurity->getPrivPassword());
-      info->nodeInfoFieldId += 41;
-      info->nodeInfoCount++;
-   }
-}
-
-/**
- * Callback for colecting proxied SNMP DCIs
- */
-void Node::collectProxyInfoCallback(NetObj *node, void *data)
-{
-   ((Node *)node)->collectProxyInfo((ProxyInfo *)data);
-}
-
 /**
  * Synchronize data collection settings with agent
  */
@@ -7549,7 +7473,11 @@ void Node::syncDataCollectionWithAgent(AgentConnectionEx *conn)
    data.fieldId = fieldId;
    data.nodeInfoCount = 0;
    data.nodeInfoFieldId = VID_NODE_INFO_LIST_BASE;
-   g_idxNodeById.forEach(Node::collectProxyInfoCallback, &data);
+
+   g_idxAccessPointById.forEach(DataCollectionTarget::collectProxyInfoCallback, &data);
+   g_idxChassisById.forEach(DataCollectionTarget::collectProxyInfoCallback, &data);
+   g_idxNodeById.forEach(DataCollectionTarget::collectProxyInfoCallback, &data);
+
    msg.setField(VID_NUM_ELEMENTS, data.count);
    msg.setField(VID_NUM_NODES, data.nodeInfoCount);
 
@@ -7591,7 +7519,7 @@ void Node::clearDataCollectionConfigFromAgent(AgentConnectionEx *conn)
    NXCPMessage *response = conn->customRequest(&msg);
    if (response != NULL)
    {
-      DbgPrintf(4, _T("ClearDataCollectionConfigFromAgent: DCI configuration sucessfully removed from node %s [%d]"), m_name, (int)m_id);
+      DbgPrintf(4, _T("ClearDataCollectionConfigFromAgent: DCI configuration successfully removed from node %s [%d]"), m_name, (int)m_id);
       delete response;
    }
 }
@@ -7640,9 +7568,9 @@ void Node::onDataCollectionChange()
 /**
  * Force data collection configuration synchronization with agent
  */
-void Node::forceSyncDataCollectionConfig(Node *node)
+void Node::forceSyncDataCollectionConfig()
 {
-   ThreadPoolExecute(g_mainThreadPool, Node::onDataCollectionChangeAsyncCallback, node);
+   ThreadPoolExecute(g_mainThreadPool, Node::onDataCollectionChangeAsyncCallback, this);
 }
 
 /**
@@ -7724,3 +7652,33 @@ void Node::incSnmpTrapCount()
    setModified(false);
    unlockProperties();
 }
+
+/**
+ * Collect info for SNMP proxy and DCI source (proxy) nodes
+ */
+void Node::collectProxyInfo(ProxyInfo *info)
+{
+   bool snmpProxy = (getEffectiveSnmpProxy() == info->proxyId);
+   bool isTarget = false;
+
+   lockDciAccess(false);
+   for(int i = 0; i < m_dcObjects->size(); i++)
+   {
+      DCObject *dco = m_dcObjects->get(i);
+      if (dco->getStatus() == ITEM_STATUS_DISABLED)
+         continue;
+
+      if (((snmpProxy && (dco->getDataSource() == DS_SNMP_AGENT) && (dco->getSourceNode() == 0)) ||
+           ((dco->getDataSource() == DS_NATIVE_AGENT) && (dco->getSourceNode() == info->proxyId))) &&
+          dco->hasValue() && (dco->getAgentCacheMode() == AGENT_CACHE_ON))
+      {
+         addProxyDataCollectionElement(info, dco);
+         if (dco->getDataSource() == DS_SNMP_AGENT)
+            isTarget = true;
+      }
+   }
+   unlockDciAccess();
+
+   if (isTarget)
+      addProxySnmpTarget(info, this);
+}
index 6f97ff6..cb8e331 100644 (file)
@@ -51,6 +51,7 @@ ObjectIndex g_idxAccessPointById;
 ObjectIndex g_idxConditionById;
 ObjectIndex g_idxServiceCheckById;
 ObjectIndex g_idxNetMapById;
+ObjectIndex g_idxChassisById;
 
 /**
  * Static data
@@ -82,7 +83,7 @@ static THREAD_RESULT THREAD_CALL ApplyTemplateThread(void *pArg)
       NetObj *dcTarget = FindObjectById(pInfo->targetId);
       if (dcTarget != NULL)
       {
-         if ((dcTarget->getObjectClass() == OBJECT_NODE) || (dcTarget->getObjectClass() == OBJECT_CLUSTER) || (dcTarget->getObjectClass() == OBJECT_MOBILEDEVICE))
+         if (dcTarget->isDataCollectionTarget())
          {
             BOOL lock1, lock2;
 
@@ -160,6 +161,7 @@ static THREAD_RESULT THREAD_CALL CacheLoadingThread(void *pArg)
        UpdateDataCollectionCache(&g_idxClusterById);
        UpdateDataCollectionCache(&g_idxMobileDeviceById);
        UpdateDataCollectionCache(&g_idxAccessPointById);
+   UpdateDataCollectionCache(&g_idxChassisById);
 
    DbgPrintf(1, _T("Finished caching of DCI values"));
    return THREAD_OK;
@@ -255,10 +257,7 @@ void NetObjInsert(NetObj *pObject, bool newObject, bool importedObject)
          pObject->generateGuid();
 
       // Create tables for storing data collection values
-      if ((pObject->getObjectClass() == OBJECT_NODE) ||
-          (pObject->getObjectClass() == OBJECT_MOBILEDEVICE) ||
-          (pObject->getObjectClass() == OBJECT_CLUSTER) ||
-          (pObject->getObjectClass() == OBJECT_ACCESSPOINT))
+      if (pObject->isDataCollectionTarget())
       {
          TCHAR szQuery[256], szQueryTemplate[256];
          UINT32 i;
@@ -332,7 +331,6 @@ void NetObjInsert(NetObj *pObject, bool newObject, bool importedObject)
                        case OBJECT_BUSINESSSERVICE:
                        case OBJECT_NODELINK:
                        case OBJECT_RACK:
-                       case OBJECT_CHASSIS:
             break;
          case OBJECT_NODE:
                                g_idxNodeById.put(pObject->getId(), pObject);
@@ -368,6 +366,9 @@ void NetObjInsert(NetObj *pObject, bool newObject, bool importedObject)
                                g_idxAccessPointById.put(pObject->getId(), pObject);
             MacDbAddAccessPoint((AccessPoint *)pObject);
             break;
+         case OBJECT_CHASSIS:
+            g_idxChassisById.put(pObject->getId(), pObject);
+            break;
          case OBJECT_SUBNET:
             if (((Subnet *)pObject)->getIpAddress().isValidUnicast())
             {
@@ -524,6 +525,9 @@ void NetObjDeleteFromIndexes(NetObj *pObject)
                case OBJECT_ACCESSPOINT:
                        g_idxAccessPointById.remove(pObject->getId());
          MacDbRemove(((AccessPoint *)pObject)->getMacAddr());
+         break;
+               case OBJECT_CHASSIS:
+         g_idxChassisById.remove(pObject->getId());
          break;
       case OBJECT_SUBNET:
          if (((Subnet *)pObject)->getIpAddress().isValidUnicast())
index a642500..6ef1fb9 100644 (file)
@@ -601,9 +601,7 @@ void ClientSession::readThread()
    {
       object = FindObjectById(m_pOpenDCIList[i]);
       if (object != NULL)
-         if ((object->getObjectClass() == OBJECT_NODE) ||
-             (object->getObjectClass() == OBJECT_CLUSTER) ||
-             (object->getObjectClass() == OBJECT_TEMPLATE))
+         if (object->isDataCollectionTarget() || (object->getObjectClass() == OBJECT_TEMPLATE))
             ((Template *)object)->unlockDCIList(m_id);
    }
 
@@ -3254,6 +3252,7 @@ void ClientSession::enterMaintenanceMode(NXCPMessage *request)
              (object->getObjectClass() == OBJECT_NODE) ||
              (object->getObjectClass() == OBJECT_MOBILEDEVICE) ||
              (object->getObjectClass() == OBJECT_ACCESSPOINT) ||
+             (object->getObjectClass() == OBJECT_CHASSIS) ||
              (object->getObjectClass() == OBJECT_ZONE) ||
              (object->getObjectClass() == OBJECT_SUBNET) ||
              (object->getObjectClass() == OBJECT_NETWORK) ||
@@ -3304,6 +3303,7 @@ void ClientSession::leaveMaintenanceMode(NXCPMessage *request)
              (object->getObjectClass() == OBJECT_NODE) ||
              (object->getObjectClass() == OBJECT_MOBILEDEVICE) ||
              (object->getObjectClass() == OBJECT_ACCESSPOINT) ||
+             (object->getObjectClass() == OBJECT_CHASSIS) ||
              (object->getObjectClass() == OBJECT_ZONE) ||
              (object->getObjectClass() == OBJECT_SUBNET) ||
              (object->getObjectClass() == OBJECT_NETWORK) ||
@@ -3430,10 +3430,7 @@ void ClientSession::openNodeDCIList(NXCPMessage *request)
    object = FindObjectById(dwObjectId);
    if (object != NULL)
    {
-      if ((object->getObjectClass() == OBJECT_NODE) ||
-          (object->getObjectClass() == OBJECT_CLUSTER) ||
-          (object->getObjectClass() == OBJECT_MOBILEDEVICE) ||
-          (object->getObjectClass() == OBJECT_TEMPLATE))
+      if (object->isDataCollectionTarget() || (object->getObjectClass() == OBJECT_TEMPLATE))
       {
          if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
          {
@@ -3495,10 +3492,7 @@ void ClientSession::closeNodeDCIList(NXCPMessage *request)
    object = FindObjectById(dwObjectId);
    if (object != NULL)
    {
-      if ((object->getObjectClass() == OBJECT_NODE) ||
-          (object->getObjectClass() == OBJECT_CLUSTER) ||
-          (object->getObjectClass() == OBJECT_MOBILEDEVICE) ||
-          (object->getObjectClass() == OBJECT_TEMPLATE))
+      if (object->isDataCollectionTarget() || (object->getObjectClass() == OBJECT_TEMPLATE))
       {
          if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
          {
@@ -3559,10 +3553,7 @@ void ClientSession::modifyNodeDCI(NXCPMessage *request)
    object = FindObjectById(dwObjectId);
    if (object != NULL)
    {
-      if ((object->getObjectClass() == OBJECT_NODE) ||
-          (object->getObjectClass() == OBJECT_CLUSTER) ||
-          (object->getObjectClass() == OBJECT_MOBILEDEVICE) ||
-          (object->getObjectClass() == OBJECT_TEMPLATE))
+      if (object->isDataCollectionTarget() || (object->getObjectClass() == OBJECT_TEMPLATE))
       {
          if (((Template *)object)->isLockedBySession(m_id))
          {
@@ -3689,10 +3680,7 @@ void ClientSession::changeDCIStatus(NXCPMessage *request)
    object = FindObjectById(request->getFieldAsUInt32(VID_OBJECT_ID));
    if (object != NULL)
    {
-      if ((object->getObjectClass() == OBJECT_NODE) ||
-          (object->getObjectClass() == OBJECT_CLUSTER) ||
-          (object->getObjectClass() == OBJECT_MOBILEDEVICE) ||
-          (object->getObjectClass() == OBJECT_TEMPLATE))
+      if (object->isDataCollectionTarget() || (object->getObjectClass() == OBJECT_TEMPLATE))
       {
          if (((Template *)object)->isLockedBySession(m_id))
          {
@@ -3752,7 +3740,7 @@ void ClientSession::clearDCIData(NXCPMessage *request)
    object = FindObjectById(request->getFieldAsUInt32(VID_OBJECT_ID));
    if (object != NULL)
    {
-      if ((object->getObjectClass() == OBJECT_NODE) || (object->getObjectClass() == OBJECT_MOBILEDEVICE) || (object->getObjectClass() == OBJECT_CLUSTER))
+      if (object->isDataCollectionTarget())
       {
          if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_DELETE))
          {
@@ -3806,7 +3794,7 @@ void ClientSession::forceDCIPoll(NXCPMessage *request)
    object = FindObjectById(request->getFieldAsUInt32(VID_OBJECT_ID));
    if (object != NULL)
    {
-      if ((object->getObjectClass() == OBJECT_NODE) || (object->getObjectClass() == OBJECT_MOBILEDEVICE) || (object->getObjectClass() == OBJECT_CLUSTER))
+      if (object->isDataCollectionTarget())
       {
          if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
          {
@@ -3864,8 +3852,8 @@ void ClientSession::copyDCI(NXCPMessage *pRequest)
    if ((pSource != NULL) && (pDestination != NULL))
    {
       // Check object types
-      if (((pSource->getObjectClass() == OBJECT_NODE) || (pSource->getObjectClass() == OBJECT_MOBILEDEVICE) || (pSource->getObjectClass() == OBJECT_TEMPLATE) || (pSource->getObjectClass() == OBJECT_CLUSTER)) &&
-                   ((pDestination->getObjectClass() == OBJECT_NODE) || (pDestination->getObjectClass() == OBJECT_MOBILEDEVICE) || (pDestination->getObjectClass() == OBJECT_TEMPLATE) || (pDestination->getObjectClass() == OBJECT_CLUSTER)))
+      if ((pSource->isDataCollectionTarget() || (pSource->getObjectClass() == OBJECT_TEMPLATE)) &&
+                   (pDestination->isDataCollectionTarget() || (pDestination->getObjectClass() == OBJECT_TEMPLATE)))
       {
          if (((Template *)pSource)->isLockedBySession(m_id))
          {
@@ -3998,7 +3986,7 @@ void ClientSession::sendDCIThresholds(NXCPMessage *request)
    {
       if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
       {
-                       if ((object->getObjectClass() == OBJECT_NODE) || (object->getObjectClass() == OBJECT_MOBILEDEVICE) || (object->getObjectClass() == OBJECT_CLUSTER))
+                       if (object->isDataCollectionTarget())
                        {
                                DCObject *dci = ((Template *)object)->getDCObjectById(request->getFieldAsUInt32(VID_DCI_ID));
                                if ((dci != NULL) && (dci->getType() == DCO_TYPE_ITEM))
@@ -4449,7 +4437,7 @@ void ClientSession::getCollectedData(NXCPMessage *request)
    {
                if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
                {
-                       if ((object->getObjectClass() == OBJECT_NODE) || (object->getObjectClass() == OBJECT_MOBILEDEVICE) || (object->getObjectClass() == OBJECT_CLUSTER))
+                       if (object->isDataCollectionTarget())
                        {
                                if (!(g_flags & AF_DB_CONNECTION_LOST))
                                {
@@ -4497,7 +4485,7 @@ void ClientSession::getTableCollectedData(NXCPMessage *request)
    {
                if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
                {
-                       if ((object->getObjectClass() == OBJECT_NODE) || (object->getObjectClass() == OBJECT_MOBILEDEVICE) || (object->getObjectClass() == OBJECT_CLUSTER))
+                       if (object->isDataCollectionTarget())
                        {
                                if (!(g_flags & AF_DB_CONNECTION_LOST))
                                {
@@ -4545,8 +4533,8 @@ void ClientSession::getLastValues(NXCPMessage *pRequest)
    {
       if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
       {
-         if ((object->getObjectClass() == OBJECT_NODE) || (object->getObjectClass() == OBJECT_MOBILEDEVICE) ||
-             (object->getObjectClass() == OBJECT_TEMPLATE) || (object->getObjectClass() == OBJECT_CLUSTER))
+         // Templates allowed here to allow simplified creation of DCI selection dialog in management console.
+         if (object->isDataCollectionTarget() || (object->getObjectClass() == OBJECT_TEMPLATE))
          {
             msg.setField(VID_RCC,
                ((Template *)object)->getLastValues(&msg,
@@ -4601,8 +4589,7 @@ void ClientSession::getLastValuesByDciId(NXCPMessage *pRequest)
       {
          if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
          {
-            if ((object->getObjectClass() == OBJECT_NODE) || (object->getObjectClass() == OBJECT_MOBILEDEVICE) ||
-                (object->getObjectClass() == OBJECT_TEMPLATE) || (object->getObjectClass() == OBJECT_CLUSTER))
+            if (object->isDataCollectionTarget() || (object->getObjectClass() == OBJECT_TEMPLATE))
             {
                UINT32 dciID = pRequest->getFieldAsUInt32(incomingIndex+1);
                dcoObj = ((DataCollectionTarget *)object)->getDCObjectById(dciID);
@@ -4677,7 +4664,7 @@ void ClientSession::getTableLastValues(NXCPMessage *pRequest)
    {
       if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
       {
-         if ((object->getObjectClass() == OBJECT_NODE) || (object->getObjectClass() == OBJECT_MOBILEDEVICE) || (object->getObjectClass() == OBJECT_CLUSTER))
+         if (object->isDataCollectionTarget())
          {
                                msg.setField(VID_RCC, ((DataCollectionTarget *)object)->getTableLastValues(pRequest->getFieldAsUInt32(VID_DCI_ID), &msg));
          }
@@ -5384,13 +5371,11 @@ void ClientSession::changeObjectBinding(NXCPMessage *pRequest, BOOL bBind)
                pChild->deleteParent(pParent);
                ObjectTransactionEnd();
                pParent->calculateCompoundStatus();
-               if ((pParent->getObjectClass() == OBJECT_TEMPLATE) &&
-                   ((pChild->getObjectClass() == OBJECT_NODE) || (pChild->getObjectClass() == OBJECT_CLUSTER) || (pChild->getObjectClass() == OBJECT_MOBILEDEVICE)))
+               if ((pParent->getObjectClass() == OBJECT_TEMPLATE) && pChild->isDataCollectionTarget())
                {
                   ((Template *)pParent)->queueRemoveFromTarget(pChild->getId(), pRequest->getFieldAsBoolean(VID_REMOVE_DCI));
                }
-               else if ((pParent->getObjectClass() == OBJECT_CLUSTER) &&
-                        (pChild->getObjectClass() == OBJECT_NODE))
+               else if ((pParent->getObjectClass() == OBJECT_CLUSTER) && (pChild->getObjectClass() == OBJECT_NODE))
                {
                   ((Cluster *)pParent)->queueRemoveFromTarget(pChild->getId(), TRUE);
                                                ((Node *)pChild)->setRecheckCapsFlag();
@@ -6948,6 +6933,14 @@ void ClientSession::getParametersList(NXCPMessage *pRequest)
             msg.setField(VID_RCC, RCC_SUCCESS);
             WriteFullParamListToMessage(&msg, pRequest->getFieldAsUInt16(VID_FLAGS));
             break;
+         case OBJECT_CHASSIS:
+            if (((Chassis *)object)->getControllerId() != 0)
+            {
+               Node *controller = (Node *)FindObjectById(((Chassis *)object)->getControllerId(), OBJECT_NODE);
+               if (controller != NULL)
+                  controller->writeParamListToMessage(&msg, pRequest->getFieldAsUInt16(VID_FLAGS));
+            }
+            break;
          default:
             msg.setField(VID_RCC, RCC_INCOMPATIBLE_OPERATION);
             break;
@@ -7131,8 +7124,7 @@ void ClientSession::applyTemplate(NXCPMessage *pRequest)
    if ((pSource != NULL) && (pDestination != NULL))
    {
       // Check object types
-      if ((pSource->getObjectClass() == OBJECT_TEMPLATE) &&
-          ((pDestination->getObjectClass() == OBJECT_NODE) || (pDestination->getObjectClass() == OBJECT_CLUSTER) || (pDestination->getObjectClass() == OBJECT_MOBILEDEVICE)))
+      if ((pSource->getObjectClass() == OBJECT_TEMPLATE) && pDestination->isDataCollectionTarget())
       {
          TCHAR szLockInfo[MAX_SESSION_NAME];
          BOOL bLockSucceed = FALSE;
@@ -8935,10 +8927,7 @@ UINT32 ClientSession::resolveDCIName(UINT32 dwNode, UINT32 dwItem, TCHAR **ppszN
    NetObj *object = FindObjectById(dwNode);
    if (object != NULL)
    {
-               if ((object->getObjectClass() == OBJECT_NODE) ||
-                        (object->getObjectClass() == OBJECT_CLUSTER) ||
-                        (object->getObjectClass() == OBJECT_MOBILEDEVICE) ||
-                        (object->getObjectClass() == OBJECT_TEMPLATE))
+               if (object->isDataCollectionTarget() || (object->getObjectClass() == OBJECT_TEMPLATE))
                {
                        if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
                        {
@@ -9556,7 +9545,7 @@ void ClientSession::pushDCIData(NXCPMessage *pRequest)
          // Validate object
          if (object != NULL)
          {
-            if ((object->getObjectClass() == OBJECT_NODE) || (object->getObjectClass() == OBJECT_MOBILEDEVICE))
+            if (object->isDataCollectionTarget())
             {
                if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_PUSH_DATA))
                {
@@ -9770,9 +9759,7 @@ void ClientSession::getDCIEventList(NXCPMessage *request)
    {
       if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
       {
-         if ((object->getObjectClass() == OBJECT_NODE) ||
-             (object->getObjectClass() == OBJECT_CLUSTER) ||
-             (object->getObjectClass() == OBJECT_TEMPLATE))
+         if (object->isDataCollectionTarget() || (object->getObjectClass() == OBJECT_TEMPLATE))
          {
             pdwEventList = ((Template *)object)->getDCIEventsList(&count);
             if (pdwEventList != NULL)
@@ -9840,9 +9827,7 @@ void ClientSession::getDCIScriptList(NXCPMessage *request)
    {
       if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
       {
-         if ((object->getObjectClass() == OBJECT_NODE) ||
-             (object->getObjectClass() == OBJECT_CLUSTER) ||
-             (object->getObjectClass() == OBJECT_TEMPLATE))
+         if (object->isDataCollectionTarget() || (object->getObjectClass() == OBJECT_TEMPLATE))
          {
             StringSet *scripts = ((Template *)object)->getDCIScriptList();
             msg.setField(VID_NUM_SCRIPTS, (INT32)scripts->size());
@@ -10108,9 +10093,7 @@ void ClientSession::SendDCIInfo(NXCPMessage *pRequest)
    {
       if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
       {
-         if ((object->getObjectClass() == OBJECT_NODE) ||
-             (object->getObjectClass() == OBJECT_CLUSTER) ||
-             (object->getObjectClass() == OBJECT_TEMPLATE))
+         if (object->isDataCollectionTarget() || (object->getObjectClass() == OBJECT_TEMPLATE))
          {
                                DCObject *pItem = ((Template *)object)->getDCObjectById(pRequest->getFieldAsUInt32(VID_DCI_ID));
                                if ((pItem != NULL) && (pItem->getType() == DCO_TYPE_ITEM))
@@ -11079,7 +11062,7 @@ void ClientSession::testDCITransformation(NXCPMessage *pRequest)
    object = FindObjectById(pRequest->getFieldAsUInt32(VID_OBJECT_ID));
    if (object != NULL)
    {
-      if ((object->getObjectClass() == OBJECT_NODE) || (object->getObjectClass() == OBJECT_CLUSTER) || (object->getObjectClass() == OBJECT_MOBILEDEVICE))
+      if (object->isDataCollectionTarget())
       {
          if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
          {
@@ -11140,6 +11123,7 @@ void ClientSession::executeScript(NXCPMessage *request)
       if ((object->getObjectClass() == OBJECT_NODE) ||
           (object->getObjectClass() == OBJECT_CLUSTER) ||
           (object->getObjectClass() == OBJECT_MOBILEDEVICE) ||
+          (object->getObjectClass() == OBJECT_CHASSIS) ||
           (object->getObjectClass() == OBJECT_CONTAINER) ||
           (object->getObjectClass() == OBJECT_ZONE) ||
           (object->getObjectClass() == OBJECT_SUBNET))
@@ -13997,7 +13981,7 @@ void ClientSession::resyncAgentDciConfiguration(NXCPMessage *request)
                        if (object->getObjectClass() == OBJECT_NODE)
                        {
             Node *node = (Node *)object;
-            node->forceSyncDataCollectionConfig(node);
+            node->forceSyncDataCollectionConfig();
                                msg.setField(VID_RCC, RCC_SUCCESS);
                        }
                        else
index e3d7fcf..b0aee07 100644 (file)
@@ -971,6 +971,19 @@ public:
    InetAddress getPeerGatewayAddr();
 };
 
+/**
+ * Data collection proxy information structure
+ */
+struct ProxyInfo
+{
+   UINT32 proxyId;
+   NXCPMessage *msg;
+   UINT32 fieldId;
+   UINT32 count;
+   UINT32 nodeInfoFieldId;
+   UINT32 nodeInfoCount;
+};
+
 /**
  * Common base class for all objects capable of collecting data
  */
@@ -989,6 +1002,11 @@ protected:
 
    NetObj *objectFromParameter(const TCHAR *param);
 
+   void addProxyDataCollectionElement(ProxyInfo *info, const DCObject *dco);
+   void addProxySnmpTarget(ProxyInfo *info, const Node *node);
+   virtual void collectProxyInfo(ProxyInfo *info);
+   static void collectProxyInfoCallback(NetObj *object, void *data);
+
 public:
    DataCollectionTarget();
    DataCollectionTarget(const TCHAR *name);
@@ -1005,6 +1023,8 @@ public:
    virtual UINT32 getInternalItem(const TCHAR *param, size_t bufSize, TCHAR *buffer);
    virtual UINT32 getScriptItem(const TCHAR *param, size_t bufSize, TCHAR *buffer);
 
+   virtual UINT32 getEffectiveSourceNode(DCObject *dco);
+
    UINT32 getListFromScript(const TCHAR *param, StringList **list);
 
    UINT32 getTableLastValues(UINT32 dciId, NXCPMessage *msg);
@@ -1200,6 +1220,7 @@ protected:
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *request);
 
    virtual void onDataCollectionChange();
+   virtual void collectProxyInfo(ProxyInfo *info);
 
    void updateRackBinding();
 
@@ -1213,8 +1234,7 @@ public:
    virtual bool deleteFromDatabase(DB_HANDLE hdb);
    virtual bool loadFromDatabase(DB_HANDLE hdb, UINT32 id);
    virtual bool showThresholdSummary();
-
-   virtual void unbindFromTemplate(UINT32 templateId, bool removeDCI);
+   virtual UINT32 getEffectiveSourceNode(DCObject *dco);
 
    virtual NXSL_Value *createNXSLObject();
 
@@ -1377,9 +1397,6 @@ protected:
        bool updateInstances(DCItem *root, StringMap *instances, UINT32 requestId);
    void syncDataCollectionWithAgent(AgentConnectionEx *conn);
 
-   void collectProxyInfo(ProxyInfo *info);
-   static void collectProxyInfoCallback(NetObj *node, void *data);
-
        void updateContainerMembership();
        bool updateInterfaceConfiguration(UINT32 rqid, int maskBits);
    bool deleteDuplicateInterfaces(UINT32 rqid);
@@ -1391,6 +1408,7 @@ protected:
        void buildIPTopologyInternal(nxmap_ObjList &topology, int nDepth, UINT32 seedObject, bool vpnLink, bool includeEndNodes);
 
        virtual bool isDataCollectionDisabled();
+   virtual void collectProxyInfo(ProxyInfo *info);
 
    virtual void prepareForDeletion();
    virtual void onObjectDelete(UINT32 dwObjectId);
@@ -1408,7 +1426,6 @@ public:
    virtual ~Node();
 
    virtual int getObjectClass() const { return OBJECT_NODE; }
-       UINT32 getIcmpProxy() { return m_icmpProxy; }
 
    virtual BOOL saveToDatabase(DB_HANDLE hdb);
    virtual bool deleteFromDatabase(DB_HANDLE hdb);
@@ -1420,24 +1437,25 @@ public:
 
        Cluster *getMyCluster();
 
-   const InetAddress& getIpAddress() { return m_ipAddress; }
-   UINT32 getZoneId() { return m_zoneId; }
-   UINT32 getFlags() { return m_dwFlags; }
-   UINT32 getRuntimeFlags() { return m_dwDynamicFlags; }
+   const InetAddress& getIpAddress() const { return m_ipAddress; }
+   UINT32 getZoneId() const { return m_zoneId; }
+   UINT32 getFlags() const { return m_dwFlags; }
+   UINT32 getRuntimeFlags() const { return m_dwDynamicFlags; }
    void setFlag(UINT32 flag) { lockProperties(); m_dwFlags |= flag; setModified(); unlockProperties(); }
    void clearFlag(UINT32 flag) { lockProperties(); m_dwFlags &= ~flag; setModified(); unlockProperties(); }
    void setLocalMgmtFlag() { m_dwFlags |= NF_IS_LOCAL_MGMT; }
    void clearLocalMgmtFlag() { m_dwFlags &= ~NF_IS_LOCAL_MGMT; }
 
-   bool isSNMPSupported() { return m_dwFlags & NF_IS_SNMP ? true : false; }
-   bool isNativeAgent() { return m_dwFlags & NF_IS_NATIVE_AGENT ? true : false; }
-   bool isBridge() { return m_dwFlags & NF_IS_BRIDGE ? true : false; }
-   bool isRouter() { return m_dwFlags & NF_IS_ROUTER ? true : false; }
-   bool isLocalManagement() { return m_dwFlags & NF_IS_LOCAL_MGMT ? true : false; }
-       bool isPerVlanFdbSupported() { return (m_driver != NULL) ? m_driver->isPerVlanFdbSupported() : false; }
-       bool isWirelessController() { return m_dwFlags & NF_IS_WIFI_CONTROLLER ? true : false; }
+   bool isSNMPSupported() const { return m_dwFlags & NF_IS_SNMP ? true : false; }
+   bool isNativeAgent() const { return m_dwFlags & NF_IS_NATIVE_AGENT ? true : false; }
+   bool isBridge() const { return m_dwFlags & NF_IS_BRIDGE ? true : false; }
+   bool isRouter() const { return m_dwFlags & NF_IS_ROUTER ? true : false; }
+   bool isLocalManagement() const { return m_dwFlags & NF_IS_LOCAL_MGMT ? true : false; }
+       bool isPerVlanFdbSupported() const { return (m_driver != NULL) ? m_driver->isPerVlanFdbSupported() : false; }
+       bool isWirelessController() const { return m_dwFlags & NF_IS_WIFI_CONTROLLER ? true : false; }
 
        LONG getSNMPVersion() const { return m_snmpVersion; }
+       UINT16 getSNMPPort() const { return m_snmpPort; }
        const TCHAR *getSNMPObjectId() const { return m_szObjectId; }
        const TCHAR *getAgentVersion() const { return m_szAgentVersion; }
        const TCHAR *getPlatformName() const { return m_szPlatformName; }
@@ -1457,7 +1475,8 @@ public:
        UINT32 getRackId() const { return m_rackId; }
    INT16 getRackHeight() const { return m_rackHeight; }
    INT16 getRackPosition() const { return m_rackPosition; }
-       bool hasFileUpdateConnection() { lockProperties(); bool result = (m_fileUpdateConn != NULL); unlockProperties(); return result; }
+       bool hasFileUpdateConnection() const { lockProperties(); bool result = (m_fileUpdateConn != NULL); unlockProperties(); return result; }
+   UINT32 getIcmpProxy() const { return m_icmpProxy; }
 
    bool isDown() { return (m_dwDynamicFlags & NDF_UNREACHABLE) ? true : false; }
        time_t getDownTime() const { return m_downSince; }
@@ -1474,7 +1493,8 @@ public:
        void changeZone(UINT32 newZone);
        void setFileUpdateConnection(AgentConnection *conn);
    void clearDataCollectionConfigFromAgent(AgentConnectionEx *conn);
-   void forceSyncDataCollectionConfig(Node *node);
+   void forceSyncDataCollectionConfig();
+   void relatedNodeDataCollectionChanged() { onDataCollectionChange(); }
 
    ARP_CACHE *getArpCache();
    InterfaceList *getInterfaceList();
@@ -1568,8 +1588,8 @@ public:
    AgentConnectionEx *createAgentConnection(bool sendServerId = false);
    AgentConnectionEx *acquireSnmpProxyConnection();
        SNMP_Transport *createSnmpTransport(WORD port = 0, const TCHAR *context = NULL);
-       SNMP_SecurityContext *getSnmpSecurityContext();
-   UINT32 getEffectiveSnmpProxy();
+       SNMP_SecurityContext *getSnmpSecurityContext() const;
+   UINT32 getEffectiveSnmpProxy() const;
 
    void writeParamListToMessage(NXCPMessage *pMsg, WORD flags);
        void writeWinPerfObjectsToMessage(NXCPMessage *msg);
@@ -2571,11 +2591,11 @@ extern InetAddressIndex NXCORE_EXPORTABLE g_idxInterfaceByAddr;
 extern InetAddressIndex NXCORE_EXPORTABLE g_idxNodeByAddr;
 extern ObjectIndex NXCORE_EXPORTABLE g_idxZoneByGUID;
 extern ObjectIndex NXCORE_EXPORTABLE g_idxNodeById;
+extern ObjectIndex NXCORE_EXPORTABLE g_idxChassisById;
 extern ObjectIndex NXCORE_EXPORTABLE g_idxClusterById;
 extern ObjectIndex NXCORE_EXPORTABLE g_idxMobileDeviceById;
 extern ObjectIndex NXCORE_EXPORTABLE g_idxAccessPointById;
 extern ObjectIndex NXCORE_EXPORTABLE g_idxConditionById;
 extern ObjectIndex NXCORE_EXPORTABLE g_idxServiceCheckById;
 
-
 #endif   /* _nms_objects_h_ */
index f7d32f3..e531e4f 100644 (file)
    <extension
          point="org.eclipse.ui.popupMenus">
       <objectContribution
-            id="org.netxms.ui.eclipse.datacollection.actions.popup.object.Node"
-            objectClass="org.netxms.client.objects.Node">
+            id="org.netxms.ui.eclipse.datacollection.actions.popup.object.DataCollectionTarget"
+            objectClass="org.netxms.client.objects.DataCollectionTarget">
          <action
                class="org.netxms.ui.eclipse.datacollection.actions.OpenEditor"
                enablesFor="1"
-               id="org.netxms.ui.eclipse.datacollection.popupActions.OpenEditor#Node"
+               id="org.netxms.ui.eclipse.datacollection.popupActions.OpenEditor#DataCollectionTarget"
                label="%action.label.DataCollection"
                icon="icons/dc_editor.png"
                menubarPath="datacollection">
@@ -56,7 +56,7 @@
                class="org.netxms.ui.eclipse.datacollection.actions.ShowLastValues"
                enablesFor="1"
                icon="icons/last_values.png"
-               id="org.netxms.ui.eclipse.datacollection.popupActions.ShowLastValues#Node"
+               id="org.netxms.ui.eclipse.datacollection.popupActions.ShowLastValues#DataCollectionTarget"
                label="%action.label.LastValues"
                menubarPath="datacollection">
          </action>
                menubarPath="datacollection">
          </action>
       </objectContribution>
-      <objectContribution
-            adaptable="false"
-            id="org.netxms.ui.eclipse.datacollection.actions.popup.object.Cluster"
-            objectClass="org.netxms.client.objects.Cluster">
-         <action
-               class="org.netxms.ui.eclipse.datacollection.actions.OpenEditor"
-               enablesFor="1"
-               icon="icons/dc_editor.png"
-               id="org.netxms.ui.eclipse.datacollection.popupActions.OpenEditor#Cluster"
-               label="%action.label.DataCollection"
-               menubarPath="datacollection">
-         </action>
-         <action
-               class="org.netxms.ui.eclipse.datacollection.actions.ShowLastValues"
-               enablesFor="1"
-               icon="icons/last_values.png"
-               id="org.netxms.ui.eclipse.datacollection.popupActions.ShowLastValues#Cluster"
-               label="%action.label.LastValues"
-               menubarPath="datacollection">
-         </action>
-      </objectContribution>
       <objectContribution
             adaptable="false"
             id="org.netxms.ui.eclipse.datacollection.actions.popup.object.DciValue"
                menubarPath="additions">
          </action>
       </objectContribution>
-      <objectContribution
-            id="org.netxms.ui.eclipse.datacollection.actions.popup.object.MobileDevice"
-            objectClass="org.netxms.client.objects.MobileDevice">
-         <action
-               class="org.netxms.ui.eclipse.datacollection.actions.OpenEditor"
-               enablesFor="1"
-               icon="icons/dc_editor.png"
-               id="org.netxms.ui.eclipse.datacollection.popupActions.OpenEditor#MobileDevice"
-               label="%action.label.DataCollection"
-               menubarPath="datacollection">
-         </action>
-         <action
-               class="org.netxms.ui.eclipse.datacollection.actions.ShowLastValues"
-               enablesFor="1"
-               icon="icons/last_values.png"
-               id="org.netxms.ui.eclipse.datacollection.popupActions.ShowLastValues#MobileDevice"
-               label="%action.label.LastValues"
-               menubarPath="datacollection">
-         </action>
-      </objectContribution>
    </extension>
 
   <extension
index 35def95..4a66a70 100644 (file)
@@ -26,10 +26,8 @@ import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.PartInitException;
-import org.netxms.client.objects.AbstractNode;
 import org.netxms.client.objects.AbstractObject;
-import org.netxms.client.objects.Cluster;
-import org.netxms.client.objects.MobileDevice;
+import org.netxms.client.objects.DataCollectionTarget;
 import org.netxms.client.objects.Template;
 import org.netxms.ui.eclipse.datacollection.Messages;
 import org.netxms.ui.eclipse.datacollection.views.DataCollectionEditor;
@@ -81,7 +79,7 @@ public class OpenEditor implements IObjectActionDelegate
                    (((IStructuredSelection)selection).size() == 1))
                {
                        Object element = ((IStructuredSelection)selection).getFirstElement();
-                       if ((element instanceof AbstractNode) || (element instanceof Template) || (element instanceof Cluster) || (element instanceof MobileDevice))
+                       if ((element instanceof DataCollectionTarget) || (element instanceof Template))
                        {
                                object = (AbstractObject)element;
                        }
index e7fe5d0..257d271 100644 (file)
@@ -26,10 +26,7 @@ import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.PartInitException;
-import org.netxms.client.objects.AbstractNode;
-import org.netxms.client.objects.AbstractObject;
-import org.netxms.client.objects.Cluster;
-import org.netxms.client.objects.MobileDevice;
+import org.netxms.client.objects.DataCollectionTarget;
 import org.netxms.ui.eclipse.datacollection.Messages;
 import org.netxms.ui.eclipse.datacollection.views.LastValues;
 import org.netxms.ui.eclipse.tools.MessageDialogHelper;
@@ -40,7 +37,7 @@ import org.netxms.ui.eclipse.tools.MessageDialogHelper;
 public class ShowLastValues implements IObjectActionDelegate
 {
        private IWorkbenchWindow window;
-       private AbstractObject object;
+       private DataCollectionTarget object;
 
        /* (non-Javadoc)
         * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
@@ -80,9 +77,9 @@ public class ShowLastValues implements IObjectActionDelegate
                    (((IStructuredSelection)selection).size() == 1))
                {
                        Object obj = ((IStructuredSelection)selection).getFirstElement();
-                       if ((obj instanceof AbstractNode) || (obj instanceof MobileDevice) || (obj instanceof Cluster))
+                       if (obj instanceof DataCollectionTarget)
                        {
-                               object = (AbstractObject)obj;
+                               object = (DataCollectionTarget)obj;
                        }
                        else
                        {
index 110dc1d..8153daf 100644 (file)
@@ -27,9 +27,7 @@ import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.commands.ICommandService;
 import org.eclipse.ui.contexts.IContextService;
 import org.netxms.client.objects.AbstractObject;
-import org.netxms.client.objects.Cluster;
-import org.netxms.client.objects.MobileDevice;
-import org.netxms.client.objects.Node;
+import org.netxms.client.objects.DataCollectionTarget;
 import org.netxms.ui.eclipse.datacollection.widgets.LastValuesWidget;
 import org.netxms.ui.eclipse.objectview.objecttabs.ObjectTab;
 import org.netxms.ui.eclipse.tools.VisibilityValidator;
@@ -86,7 +84,7 @@ public class LastValues extends ObjectTab
        @Override
        public boolean showForObject(AbstractObject object)
        {
-               return (object instanceof Node) || (object instanceof MobileDevice) || (object instanceof Cluster);
+               return object instanceof DataCollectionTarget;
        }
 
        /* (non-Javadoc)
index 52e65a2..e9eac3b 100644 (file)
@@ -63,6 +63,7 @@ import org.netxms.client.datacollection.DataCollectionTable;
 import org.netxms.client.objects.AbstractNode;
 import org.netxms.client.objects.AbstractObject;
 import org.netxms.client.objects.Cluster;
+import org.netxms.client.objects.DataCollectionTarget;
 import org.netxms.client.objects.MobileDevice;
 import org.netxms.client.objects.Template;
 import org.netxms.ui.eclipse.actions.RefreshAction;
@@ -137,7 +138,7 @@ public class DataCollectionEditor extends ViewPart
                
                session = (NXCSession)ConsoleSharedData.getSession();
                AbstractObject obj = session.findObjectById(Long.parseLong(site.getSecondaryId()));
-               object = ((obj != null) && ((obj instanceof AbstractNode) || (obj instanceof Template) || (obj instanceof Cluster) || (obj instanceof MobileDevice))) ? obj : null;
+               object = ((obj != null) && ((obj instanceof DataCollectionTarget) || (obj instanceof Template))) ? obj : null;
                setPartName(Messages.get().DataCollectionEditor_PartNamePrefix + ((object != null) ? object.getObjectName() : Messages.get().DataCollectionEditor_Error));
        }
 
index ee264ae..9e01d61 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * NetXMS - open source network management system
- * Copyright (C) 2003-2015 Victor Kirhenshtein
+ * Copyright (C) 2003-2016 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
@@ -35,10 +35,8 @@ import org.eclipse.ui.contexts.IContextService;
 import org.eclipse.ui.handlers.IHandlerService;
 import org.eclipse.ui.part.ViewPart;
 import org.netxms.client.NXCSession;
-import org.netxms.client.objects.AbstractNode;
 import org.netxms.client.objects.AbstractObject;
-import org.netxms.client.objects.Cluster;
-import org.netxms.client.objects.MobileDevice;
+import org.netxms.client.objects.DataCollectionTarget;
 import org.netxms.ui.eclipse.actions.RefreshAction;
 import org.netxms.ui.eclipse.console.resources.SharedIcons;
 import org.netxms.ui.eclipse.datacollection.Messages;
@@ -54,7 +52,7 @@ public class LastValues extends ViewPart
        public static final String ID = "org.netxms.ui.eclipse.datacollection.view.last_values"; //$NON-NLS-1$
        
        private NXCSession session;
-       private AbstractObject dcTarget;
+       private DataCollectionTarget dcTarget;
        private LastValuesWidget dataView;
        private Action actionRefresh;
        private Action actionAutoUpdate;
@@ -70,7 +68,7 @@ public class LastValues extends ViewPart
                
                session = (NXCSession)ConsoleSharedData.getSession();
                AbstractObject obj = session.findObjectById(Long.parseLong(site.getSecondaryId()));
-               dcTarget = ((obj != null) && ((obj instanceof AbstractNode) || (obj instanceof MobileDevice) || (obj instanceof Cluster))) ? obj : null;
+               dcTarget = ((obj != null) && (obj instanceof DataCollectionTarget)) ? (DataCollectionTarget)obj : null;
                setPartName(Messages.get().LastValues_PartNamePrefix + ((dcTarget != null) ? dcTarget.getObjectName() : Messages.get().LastValues_Error));
        }
 
index d47c201..88b818d 100644 (file)
@@ -52,12 +52,11 @@ import org.eclipse.ui.IWorkbenchActionConstants;
 import org.eclipse.ui.part.ViewPart;
 import org.netxms.client.NXCSession;
 import org.netxms.client.datacollection.DciValue;
-import org.netxms.client.objects.AbstractNode;
 import org.netxms.client.objects.AbstractObject;
-import org.netxms.client.objects.Cluster;
-import org.netxms.client.objects.MobileDevice;
+import org.netxms.client.objects.DataCollectionTarget;
 import org.netxms.ui.eclipse.actions.ExportToCsvAction;
 import org.netxms.ui.eclipse.console.resources.GroupMarkers;
+
 import org.netxms.ui.eclipse.datacollection.Activator;
 import org.netxms.ui.eclipse.datacollection.Messages;
 import org.netxms.ui.eclipse.datacollection.api.DciOpenHandler;
@@ -87,7 +86,7 @@ public class LastValuesWidget extends Composite
        public static final int COLUMN_THRESHOLD = 4;
        
        private final ViewPart viewPart;
-       private AbstractObject dcTarget;
+       private DataCollectionTarget dcTarget;
        private NXCSession session;
        private boolean filterEnabled = false;
        private FilterText filterText;
@@ -389,10 +388,7 @@ public class LastValuesWidget extends Composite
         */
        public void setDataCollectionTarget(AbstractObject dcTarget)
        {
-               if ((dcTarget instanceof AbstractNode) || (dcTarget instanceof MobileDevice) || (dcTarget instanceof Cluster))
-                       this.dcTarget = dcTarget;
-               else
-                       this.dcTarget = null;
+               this.dcTarget = (dcTarget instanceof DataCollectionTarget) ? (DataCollectionTarget)dcTarget : null;
        }
        
        /**