From 9a69a9bb32498fa2f7d631dc179e45168af9aad1 Mon Sep 17 00:00:00 2001 From: Tatjana Dubrovica Date: Wed, 23 Apr 2025 12:33:02 +0300 Subject: [PATCH 1/2] Alarm view is not revresh while not active. Performance optimization. --- .../nxmc/modules/alarms/views/AlarmsView.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/client/nxmc/java/src/main/java/org/netxms/nxmc/modules/alarms/views/AlarmsView.java b/src/client/nxmc/java/src/main/java/org/netxms/nxmc/modules/alarms/views/AlarmsView.java index 83305dae9b..d92353720e 100644 --- a/src/client/nxmc/java/src/main/java/org/netxms/nxmc/modules/alarms/views/AlarmsView.java +++ b/src/client/nxmc/java/src/main/java/org/netxms/nxmc/modules/alarms/views/AlarmsView.java @@ -28,8 +28,10 @@ import org.netxms.nxmc.base.widgets.helpers.SearchQueryContentProposalProvider; import org.netxms.nxmc.localization.LocalizationHelper; import org.netxms.nxmc.modules.alarms.widgets.AlarmList; +import org.netxms.nxmc.modules.dashboards.propertypages.AlarmViewer; import org.netxms.nxmc.modules.objects.views.ObjectView; import org.netxms.nxmc.resources.ResourceManager; +import org.netxms.nxmc.tools.VisibilityValidator; import org.xnap.commons.i18n.I18n; /** @@ -67,7 +69,7 @@ protected AlarmsView(String name, String id) @Override protected void createContent(Composite parent) { - alarmList = new AlarmList(this, parent, SWT.NONE, "AlarmView.AlarmList", null); + alarmList = new AlarmList(this, parent, SWT.NONE, "AlarmView.AlarmList", () -> AlarmsView.this.isActive()); setFilterClient(alarmList.getViewer(), alarmList.getFilter()); enableFilterAutocomplete(new SearchQueryContentProposalProvider(alarmList.getAttributeProposals())); @@ -91,6 +93,16 @@ protected void onObjectChange(AbstractObject object) alarmList.setRootObject((object != null) ? object.getObjectId() : 0); } + /** + * @see org.netxms.nxmc.base.views.View#activate() + */ + @Override + public void activate() + { + super.activate(); + alarmList.doPendingUpdates(); + } + /** * @see org.netxms.nxmc.base.views.View#refresh() */ @@ -137,5 +149,5 @@ protected void fillLocalMenu(IMenuManager manager) manager.add(new Separator()); manager.add(actionExportToCsv); super.fillLocalMenu(manager); - } + } } From 7c55fd6ba5d9b35b5602ca6b1ecf3825701a676b Mon Sep 17 00:00:00 2001 From: Tatjana Dubrovica Date: Wed, 23 Apr 2025 12:37:18 +0300 Subject: [PATCH 2/2] Added interface traffic and utilization grapht to Interface Overview. Fixes NX-2710 --- include/nms_cscp.h | 4 + .../java/org/netxms/client/NXCSession.java | 23 ++ .../InterfacePerformanceData.java | 58 ++++ .../objects/views/ObjectOverviewView.java | 9 +- .../views/elements/OverviewPageElement.java | 11 + .../views/elements/TrafficLineChart.java | 305 ++++++++++++++++++ .../main/java/org/netxms/base/NXCPCodes.java | 4 +- src/server/core/session.cpp | 114 +++++++ src/server/include/nms_core.h | 1 + 9 files changed, 526 insertions(+), 3 deletions(-) create mode 100644 src/client/java/netxms-client/src/main/java/org/netxms/client/datacollection/InterfacePerformanceData.java create mode 100644 src/client/nxmc/java/src/main/java/org/netxms/nxmc/modules/objects/views/elements/TrafficLineChart.java diff --git a/include/nms_cscp.h b/include/nms_cscp.h index c21d9346fe..2b8aa2f19b 100644 --- a/include/nms_cscp.h +++ b/include/nms_cscp.h @@ -668,6 +668,7 @@ typedef struct #define CMD_CANCEL_PACKAGE_DEPLOYMENT_JOB 0x01D4 #define CMD_QUERY_AI_ASSISTANT 0x01D5 #define CMD_GET_SMCLP_PROPERTIES 0x01D6 +#define CMD_GET_INTERFACE_DCIS 0x01D7 #define CMD_RS_LIST_REPORTS 0x1100 #define CMD_RS_GET_REPORT_DEFINITION 0x1101 @@ -1542,6 +1543,7 @@ typedef struct #define VID_JOB_ID ((uint32_t)860) #define VID_EXPECTED_CAPABILITIES ((uint32_t)861) #define VID_AI_ASSISTANT_AVAILABLE ((uint32_t)862) +#define VID_DCI_IDS ((uint32_t)863) // Base variabe for single threshold in message #define VID_THRESHOLD_BASE ((uint32_t)0x00800000) @@ -1809,4 +1811,6 @@ typedef struct // Base field for script warnings #define VID_WARNING_LIST_BASE ((uint32_t)0x38000000) +#define VID_UNIT_NAMES_BASE ((uint32_t)0x10000000) + #endif /* _nms_cscp_h_ */ diff --git a/src/client/java/netxms-client/src/main/java/org/netxms/client/NXCSession.java b/src/client/java/netxms-client/src/main/java/org/netxms/client/NXCSession.java index af680eac98..94e0fa0585 100644 --- a/src/client/java/netxms-client/src/main/java/org/netxms/client/NXCSession.java +++ b/src/client/java/netxms-client/src/main/java/org/netxms/client/NXCSession.java @@ -104,6 +104,7 @@ import org.netxms.client.datacollection.DciValue; import org.netxms.client.datacollection.GraphDefinition; import org.netxms.client.datacollection.GraphFolder; +import org.netxms.client.datacollection.InterfacePerformanceData; import org.netxms.client.datacollection.MeasurementUnit; import org.netxms.client.datacollection.PerfTabDci; import org.netxms.client.datacollection.PredictionEngine; @@ -15055,4 +15056,26 @@ public String queryAiAssistant(String prompt) throws IOException, NXCException NXCPMessage response = waitForRCC(msg.getMessageId(), commandTimeout * 10); // LLM response can take significant amount of time return response.getFieldAsString(NXCPCodes.VID_MESSAGE); } + + /** + * Find interface traffic DCIs + * + * @param object interface object to find DCIs for + * @return DCI and it's unit: 4 DCIs - 2 pairs (first are trafic, second utilization). + * @throws IOException if socket I/O error occurs + * @throws NXCException if NetXMS server returns an error or operation was timed out + */ + public InterfacePerformanceData findTrafficInformation(AbstractObject object) throws IOException, NXCException + { + final NXCPMessage msg = newMessage(NXCPCodes.CMD_GET_INTERFACE_DCIS); + msg.setFieldUInt32(NXCPCodes.VID_INTERFACE_ID, object.getObjectId()); + sendMessage(msg); + NXCPMessage response = waitForRCC(msg.getMessageId()); + Long[] dciList = response.getFieldAsUInt32ArrayEx(NXCPCodes.VID_DCI_IDS); + String[] unitNames = new String[4]; + long base = NXCPCodes.VID_UNIT_NAMES_BASE; + for (int i = 0; i < 4; i++) + unitNames[i] = response.getFieldAsString(base++); + return new InterfacePerformanceData(dciList, unitNames); + } } diff --git a/src/client/java/netxms-client/src/main/java/org/netxms/client/datacollection/InterfacePerformanceData.java b/src/client/java/netxms-client/src/main/java/org/netxms/client/datacollection/InterfacePerformanceData.java new file mode 100644 index 0000000000..f9a8ae1c28 --- /dev/null +++ b/src/client/java/netxms-client/src/main/java/org/netxms/client/datacollection/InterfacePerformanceData.java @@ -0,0 +1,58 @@ +/** + * NetXMS - open source network management system + * Copyright (C) 2003-2025 Raden Solutions + *

+ * 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.client.datacollection; + +/** + * Interface data + */ +public class InterfacePerformanceData +{ + private Long[] dciList; + private String[] unitNames; + + /** + * Interface data constructor + */ + public InterfacePerformanceData(Long[] dciList, String[] unitNames) + { + this.dciList = dciList; + this.unitNames = unitNames; + } + + /** + * Interface id's + * + * @return + */ + public Long[] getDciList() + { + return dciList; + } + + /** + * Interface id units + * + * @return + */ + public String[] getUnitNames() + { + return unitNames; + } + +} diff --git a/src/client/nxmc/java/src/main/java/org/netxms/nxmc/modules/objects/views/ObjectOverviewView.java b/src/client/nxmc/java/src/main/java/org/netxms/nxmc/modules/objects/views/ObjectOverviewView.java index 66732be307..c785a7667e 100644 --- a/src/client/nxmc/java/src/main/java/org/netxms/nxmc/modules/objects/views/ObjectOverviewView.java +++ b/src/client/nxmc/java/src/main/java/org/netxms/nxmc/modules/objects/views/ObjectOverviewView.java @@ -55,6 +55,7 @@ import org.netxms.nxmc.modules.objects.views.elements.OverviewPageElement; import org.netxms.nxmc.modules.objects.views.elements.PollStates; import org.netxms.nxmc.modules.objects.views.elements.Topology; +import org.netxms.nxmc.modules.objects.views.elements.TrafficLineChart; import org.netxms.nxmc.resources.ResourceManager; import org.netxms.nxmc.resources.ThemeEngine; import org.netxms.nxmc.tools.WidgetHelper; @@ -141,7 +142,7 @@ public void controlResized(ControlEvent e) rightColumn.setBackground(viewArea.getBackground()); gd = new GridData(); gd.verticalAlignment = SWT.TOP; - gd.horizontalAlignment = SWT.LEFT; + gd.horizontalAlignment = SWT.FILL; gd.grabExcessHorizontalSpace = true; gd.minimumWidth = SWT.DEFAULT; rightColumn.setLayoutData(gd); @@ -160,7 +161,7 @@ public void controlResized(ControlEvent e) e = new Location(leftColumn, e, this); elements.add(e); e = new LastValues(leftColumn, e, this); - elements.add(e); + elements.add(e); e = new ExternalResources(leftColumn, e, this); elements.add(e); e = new Comments(leftColumn, e, this); @@ -177,6 +178,10 @@ public void controlResized(ControlEvent e) elements.add(e); e = new Connection(rightColumn, e, this); elements.add(e); + e = new TrafficLineChart(rightColumn, e, this, false); + elements.add(e); + e = new TrafficLineChart(rightColumn, e, this, true); + elements.add(e); } /** diff --git a/src/client/nxmc/java/src/main/java/org/netxms/nxmc/modules/objects/views/elements/OverviewPageElement.java b/src/client/nxmc/java/src/main/java/org/netxms/nxmc/modules/objects/views/elements/OverviewPageElement.java index d2ac89522f..a7afff8ef8 100644 --- a/src/client/nxmc/java/src/main/java/org/netxms/nxmc/modules/objects/views/elements/OverviewPageElement.java +++ b/src/client/nxmc/java/src/main/java/org/netxms/nxmc/modules/objects/views/elements/OverviewPageElement.java @@ -82,6 +82,7 @@ protected Control createClientArea(Composite parent) gd.horizontalSpan = horizontalSpan; gd.grabExcessHorizontalSpace = true; gd.verticalAlignment = verticalAlignment; + gd.heightHint = getHeightHint(); widget.setLayoutData(gd); } onObjectChange(); @@ -204,6 +205,16 @@ protected ObjectView getObjectView() */ protected abstract Control createClientArea(Composite parent); + /** + * Get height hint for element content. + * + * @return height hint for element content + */ + protected int getHeightHint() + { + return SWT.DEFAULT; + } + /** * Handler for object change. */ diff --git a/src/client/nxmc/java/src/main/java/org/netxms/nxmc/modules/objects/views/elements/TrafficLineChart.java b/src/client/nxmc/java/src/main/java/org/netxms/nxmc/modules/objects/views/elements/TrafficLineChart.java new file mode 100644 index 0000000000..9aaf50b521 --- /dev/null +++ b/src/client/nxmc/java/src/main/java/org/netxms/nxmc/modules/objects/views/elements/TrafficLineChart.java @@ -0,0 +1,305 @@ +/** + * NetXMS - open source network management system + * Copyright (C) 2003-2015 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.nxmc.modules.objects.views.elements; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.netxms.client.NXCSession; +import org.netxms.client.TimePeriod; +import org.netxms.client.constants.HistoricalDataType; +import org.netxms.client.datacollection.ChartConfiguration; +import org.netxms.client.datacollection.ChartDciConfig; +import org.netxms.client.datacollection.DciData; +import org.netxms.client.datacollection.InterfacePerformanceData; +import org.netxms.client.datacollection.MeasurementUnit; +import org.netxms.client.datacollection.Threshold; +import org.netxms.client.objects.AbstractObject; +import org.netxms.client.objects.Interface; +import org.netxms.nxmc.Registry; +import org.netxms.nxmc.base.jobs.Job; +import org.netxms.nxmc.localization.LocalizationHelper; +import org.netxms.nxmc.modules.charts.api.ChartType; +import org.netxms.nxmc.modules.charts.widgets.Chart; +import org.netxms.nxmc.modules.objects.views.ObjectView; +import org.netxms.nxmc.tools.ViewRefreshController; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xnap.commons.i18n.I18n; + +/** + * DCI last values + */ +public class TrafficLineChart extends OverviewPageElement +{ + private static Logger logger = LoggerFactory.getLogger(TrafficLineChart.class); + + private final I18n i18n = LocalizationHelper.getI18n(TrafficLineChart.class); + + private Chart chart; + private InterfacePerformanceData items = null; + ChartConfiguration chartConfiguration = new ChartConfiguration(); + private ViewRefreshController refreshController; + private Composite content; + private boolean utilization; + private int itemBase; + private Composite labelControl; + private Label label; + + /** + * @param parent + * @param anchor + * @param objectTab + */ + public TrafficLineChart(Composite parent, OverviewPageElement anchor, ObjectView objectView, boolean utilization) + { + super(parent, anchor, objectView); + refreshController = new ViewRefreshController(objectView, -1, () -> refresh()); + this.utilization = utilization; + itemBase = utilization ? 2 : 0; + } + + /** + * @see org.netxms.nxmc.modules.objects.views.elements.OverviewPageElement#getTitle() + */ + @Override + protected String getTitle() + { + return utilization ? i18n.tr("Utilization") : i18n.tr("Traffic"); + } + + /** + * @see org.netxms.nxmc.modules.objects.views.elements.OverviewPageElement#createClientArea(org.eclipse.swt.widgets.Composite) + */ + @Override + protected Control createClientArea(Composite parent) + { + content = new Composite(parent, SWT.NONE); + content.addControlListener(new ControlListener() { + @Override + public void controlResized(ControlEvent e) + { + chart.setSize(content.getSize()); + labelControl.setSize(content.getSize()); + } + + @Override + public void controlMoved(ControlEvent e) + { + } + }); + + final Date from = new Date(System.currentTimeMillis() - chartConfiguration.getTimeRangeMillis()); + final Date to = new Date(System.currentTimeMillis()); + + chartConfiguration.setZoomEnabled(false); + chartConfiguration.setTitleVisible(false); + chartConfiguration.setLegendVisible(true); + chartConfiguration.setExtendedLegend(true); + chartConfiguration.setUseMultipliers(true); + chartConfiguration.setAutoScale(true); + chartConfiguration.setTimePeriod(new TimePeriod()); + chart = new Chart(content, SWT.NONE, ChartType.LINE, chartConfiguration); + chart.setTimeRange(from, to); + chart.addDoubleClickListener((e) -> openHistoryGraph()); + + chart.addDisposeListener((e) -> { + if (refreshController != null) + refreshController.dispose(); + }); + + labelControl = new Composite(content, SWT.NO_BACKGROUND); + labelControl.setLayout(new GridLayout()); + label = new Label(labelControl, SWT.CENTER); + label.setText("Loading..."); + + refreshController.setInterval(30); + return content; + } + + /** + * @see org.netxms.nxmc.modules.objects.views.elements.OverviewPageElement#getHeightHint() + */ + @Override + protected int getHeightHint() + { + return 300; + } + + /** + * Open history graph of dci + */ + private void openHistoryGraph() + { + List graphItems = new ArrayList(items.getDciList().length); + for(int i = 0; i < chart.getItemCount(); i++) + graphItems.add(new ChartDciConfig(chart.getItem(i))); + + /* + AbstractObject object = (view instanceof ObjectView) ? ((ObjectView)view).getObject() : session.findObjectById(nodeId); + view.openView(new HistoricalGraphView(object, graphItems, chart.getConfiguration(), 0)); + */ + } + + /** + * @see org.netxms.nxmc.modules.objects.views.elements.OverviewPageElement#onObjectChange() + */ + @Override + protected void onObjectChange() + { + items = null; + chart.removeAllParameters(); + refresh(); + } + + /** + * Refresh element + */ + private void refresh() + { + final NXCSession session = Registry.getSession(); + final long nodeId = ((Interface)getObject()).getParentNode().getObjectId(); + Job job = new Job(i18n.tr("Read last DCI values"), getObjectView()) { + @Override + protected void run(IProgressMonitor monitor) throws Exception + { + try + { + final Date from = new Date(System.currentTimeMillis() - chartConfiguration.getTimeRangeMillis()); + final Date to = new Date(System.currentTimeMillis()); + final InterfacePerformanceData perfData = session.findTrafficInformation(getObject()); + final DciData[] data = new DciData[2]; + final Threshold[][] thresholds = new Threshold[2][]; + for(int i = 0; i < data.length; i++) + { + Long currentDci = perfData.getDciList()[itemBase + i]; + if (currentDci == 0) + { + data[i] = null; + continue; + } + data[i] = session.getCollectedData(nodeId, currentDci, from, to, 0, HistoricalDataType.PROCESSED); + thresholds[i] = session.getThresholds(nodeId, currentDci); + } + + runInUIThread(() -> { + if (!chart.isDisposed()) + { + if (items == null) + { + items = perfData; + createChart(nodeId); + } + else + { + items = perfData; + } + + chart.setTimeRange(from, to); + + if (data[0] != null) + { + chart.updateParameter(0, data[0], false); + if (data[1] != null) + chart.updateParameter(1, data[1], false); + } + else + { + if (data[1] != null) + chart.updateParameter(0, data[1], false); + } + + chart.setThresholds(thresholds); + chart.refresh(); + } + }); + } + catch(Exception e) + { + logger.error("Exception in interface trafic overview element", e); + } + } + + @Override + protected String getErrorMessage() + { + return i18n.tr("Cannot read last DCI values"); + } + }; + job.setUser(false); + job.setSystem(true); + job.start(); + } + + private void createChart(Long nodeId) + { + if (items.getDciList()[itemBase] == 0 && items.getDciList()[itemBase + 1] == 0) + { + label.setText("No data"); + labelControl.moveAbove(null); + return; + } + + chart.moveAbove(null); + + if (items.getDciList()[itemBase] != 0) + { + ChartDciConfig item = new ChartDciConfig(); + item.nodeId = nodeId; + item.dciId = items.getDciList()[itemBase]; + item.name = "RX"; + item.lineChartType = ChartDciConfig.DEFAULT; + item.invertValues = false; + item.showThresholds = true; + item.measurementUnit = new MeasurementUnit(items.getUnitNames()[itemBase]); + chart.addParameter(item); + } + + if (items.getDciList()[itemBase + 1] != 0) + { + ChartDciConfig item = new ChartDciConfig(); + item.nodeId = nodeId; + item.dciId = items.getDciList()[itemBase + 1]; + item.name = "TX"; + item.lineChartType = ChartDciConfig.DEFAULT; + item.invertValues = (items.getDciList()[itemBase + 1] != 0); + item.showThresholds = true; + item.measurementUnit = new MeasurementUnit(items.getUnitNames()[itemBase + 1]); + chart.addParameter(item); + } + chart.rebuild(); + } + + /** + * @see org.netxms.nxmc.modules.objects.views.elements.OverviewPageElement#isApplicableForObject(org.netxms.client.objects.AbstractObject) + */ + @Override + public boolean isApplicableForObject(AbstractObject object) + { + return object instanceof Interface; + } +} diff --git a/src/java-common/netxms-base/src/main/java/org/netxms/base/NXCPCodes.java b/src/java-common/netxms-base/src/main/java/org/netxms/base/NXCPCodes.java index 24def0c117..c4d72b73e9 100644 --- a/src/java-common/netxms-base/src/main/java/org/netxms/base/NXCPCodes.java +++ b/src/java-common/netxms-base/src/main/java/org/netxms/base/NXCPCodes.java @@ -489,6 +489,7 @@ public class NXCPCodes public static final int CMD_CANCEL_PACKAGE_DEPLOYMENT_JOB = 0x01D4; public static final int CMD_QUERY_AI_ASSISTANT = 0x01D5; public static final int CMD_GET_SMCLP_PROPERTIES = 0x01D6; + public static final int CMD_GET_INTERFACE_DCIS = 0x01D7; // CMD_RS_ - Reporting Server related codes public static final int CMD_RS_LIST_REPORTS = 0x1100; @@ -1359,6 +1360,7 @@ public class NXCPCodes public static final long VID_JOB_ID = 860; public static final long VID_EXPECTED_CAPABILITIES = 861; public static final long VID_AI_ASSISTANT_AVAILABLE = 862; + public static final long VID_DCI_IDS = 863; public static final long VID_ACL_USER_BASE = 0x00001000L; public static final long VID_ACL_USER_LAST = 0x00001FFFL; @@ -1455,7 +1457,6 @@ public class NXCPCodes public static final long VID_UUID_LIST_BASE = 0x10000000L; public static final long VID_RULE_LIST_BASE = 0x10000000L; public static final long VID_EXTENSION_LIST_BASE = 0x10000000L; - public static final long VID_DCI_ID_LIST_BASE = 0x10000000L; public static final long VID_LOC_LIST_BASE = 0x10000000L; public static final long VID_SCHEDULE_LIST_BASE = 0x10000000L; public static final long VID_CALLBACK_BASE = 0x10000000L; @@ -1484,4 +1485,5 @@ public class NXCPCodes public static final long VID_AM_ENUM_MAP_BASE = 0x20000000L; public static final long VID_WARNING_LIST_BASE = 0x38000000L; public static final long VID_PARTIAL_OBJECT_INFO_BASE = 0x10000000L; + public static final long VID_UNIT_NAMES_BASE = 0x10000000L; } diff --git a/src/server/core/session.cpp b/src/server/core/session.cpp index 6ce5d2a18a..b67ac4af8e 100644 --- a/src/server/core/session.cpp +++ b/src/server/core/session.cpp @@ -1999,6 +1999,9 @@ void ClientSession::processRequest(NXCPMessage *request) case CMD_GET_SMCLP_PROPERTIES: getSmclpProperties(*request); break; + case CMD_GET_INTERFACE_DCIS: + getInterfaceTrafficDcis(*request); + break; case CMD_EPP_RECORD: processEventProcessingPolicyRecord(*request); break; @@ -17947,3 +17950,114 @@ void ClientSession::getSmclpProperties(const NXCPMessage& request) sendMessage(response); } + +/** + * Set to message traffic and utilization DCIs and it's units + */ +static void CollectInterfaceTrafficDcis(shared_ptr node, uint32_t interfaceId, NXCPMessage *response) +{ + bool foundElements[6] = {false, false, false, false, false, false}; + const int IN_BITS = 0; + const int OUT_BITS = 1; + const int IN_UTIL = 2; + const int OUT_UTIL = 3; + const int IN_BYTES = 4; + const int OUT_BYTES = 5; + uint32_t dciId[4] = { 0, 0, 0, 0 }; + StringBuffer units[4]; + + node->getDCObjectByFilter([interfaceId, &foundElements, &dciId, &units] (DCObject *obj) + { + if ((obj->getType() != DCO_TYPE_ITEM) || (obj->getRelatedObject() != interfaceId)) + return false; + + String tag = obj->getSystemTag(); + if (foundElements[IN_BITS] && foundElements[OUT_BITS] && foundElements[IN_UTIL] && foundElements[OUT_UTIL]) + return true; + + if (!foundElements[IN_BITS] && tag.equals(L"iface-inbound-bits")) + { + dciId[IN_BITS] = obj->getId(); + units[IN_BITS] = static_cast(obj)->getUnitName(); + foundElements[IN_BITS] = true; + return false; + } + if ((!foundElements[IN_BITS] || !foundElements[IN_BYTES]) && tag.equals(L"iface-inbound-bytes")) + { + dciId[IN_BITS] = obj->getId(); + units[IN_BITS] = static_cast(obj)->getUnitName(); + foundElements[IN_BYTES] = true; + return false; + } + + if (!foundElements[OUT_BITS] && tag.equals(L"iface-outbound-bits")) + { + dciId[OUT_BITS] = obj->getId(); + units[OUT_BITS] = static_cast(obj)->getUnitName(); + foundElements[OUT_BITS] = true; + return false; + } + if ((!foundElements[OUT_BITS] || !foundElements[OUT_BYTES]) && tag.equals(L"iface-outbound-bytes")) + { + dciId[OUT_BITS] = obj->getId(); + units[OUT_BITS] = static_cast(obj)->getUnitName(); + foundElements[OUT_BYTES] = true; + return false; + } + + if (!foundElements[IN_UTIL] && tag.equals(L"iface-inbound-util")) + { + dciId[IN_UTIL] = obj->getId(); + units[IN_UTIL] = static_cast(obj)->getUnitName(); + foundElements[IN_UTIL] = true; + return false; + } + if (!foundElements[OUT_UTIL] && tag.equals(L"iface-outbound-util")) + { + dciId[OUT_UTIL] = obj->getId(); + units[OUT_UTIL] = static_cast(obj)->getUnitName(); + foundElements[OUT_UTIL] = true; + return false; + } + return false; + }); + + response->setFieldFromInt32Array(VID_DCI_IDS, 4, dciId); + uint32_t base = VID_UNIT_NAMES_BASE; + for (int i = 0; i < 4; i++) + { + response->setField(base++, units[i]); + } +} + +/** + * Get interface related DCI list with traffic and utilization + */ +void ClientSession::getInterfaceTrafficDcis(const NXCPMessage& request) +{ + NXCPMessage response(CMD_REQUEST_COMPLETED, request.getId()); + + uint32_t interfaceId = request.getFieldAsInt32(VID_INTERFACE_ID); + shared_ptr interface = FindObjectById(interfaceId, OBJECT_INTERFACE); + if (interface != nullptr) + { + shared_ptr node = static_cast(*interface).getParentNode(); + if (interface->checkAccessRights(m_userId, OBJECT_ACCESS_READ) && + (node->checkAccessRights(m_userId, OBJECT_ACCESS_READ) || node->checkAccessRights(m_userId, OBJECT_ACCESS_DELEGATED_READ))) + { + CollectInterfaceTrafficDcis(node, interfaceId, &response); + response.setField(VID_RCC, RCC_SUCCESS); + } + else + { + response.setField(VID_RCC, RCC_ACCESS_DENIED); + } + } + else + { + response.setField(VID_RCC, RCC_INVALID_OBJECT_ID); + } + + sendMessage(response); +} + diff --git a/src/server/include/nms_core.h b/src/server/include/nms_core.h index 7e8692b073..e8c78f62e0 100644 --- a/src/server/include/nms_core.h +++ b/src/server/include/nms_core.h @@ -965,6 +965,7 @@ class NXCORE_EXPORTABLE ClientSession : public GenericClientSession void clearPeerInterface(const NXCPMessage& request); void queryAiAssistant(const NXCPMessage& request); void getSmclpProperties(const NXCPMessage& request); + void getInterfaceTrafficDcis(const NXCPMessage& request); void alarmUpdateWorker(Alarm *alarm); void sendActionDBUpdateMessage(NXCP_MESSAGE *msg);