Non-existing resources or attributes break JasperReports when using the Measurements API

Description

I have a custom jasper report template that uses the Measurements API:

<queryString language="measurement"> <![CDATA[<query-request step="300000" start="$P{startDateTime}" end="$P{endDateTime}" maxrows="5000"> <source aggregation="AVERAGE" label="ifInErrors" attribute="ifInErrors" transient="false" resourceId="$P{nodeResourceDescriptor}.interfaceSnmp[$P{interface}]"/> <source aggregation="AVERAGE" label="ifOutErrors" attribute="ifOutErrors" transient="false" resourceId="$P{nodeResourceDescriptor}.interfaceSnmp[$P{interface}]"/> <source aggregation="AVERAGE" label="ifOutDiscards" attribute="ifOutDiscards" transient="false" resourceId="$P{nodeResourceDescriptor}.interfaceSnmp[$P{interface}]"/> <source aggregation="AVERAGE" label="ifInDiscards" attribute="ifInDiscards" transient="false" resourceId="$P{nodeResourceDescriptor}.interfaceSnmp[$P{interface}]"/> <source aggregation="AVERAGE" label="InPauseFrame" attribute="dot3HCInPauseFrame" transient="false" resourceId="$P{nodeResourceDescriptor}.interfaceSnmp[$P{interface}]"/> </query-request>]]> </queryString>

For all the nodes involved, some of the interface have all the attributes, but some of them don't (specially dot3HCInPauseFrame). When they don't have the attributes, an exception is thrown and the report is generated but all the values associated with metric fields are always going to be null, even those that are supposed to have data:

2016-04-12 07:27:08,661 DEBUG [gkvi_Ifin_outErrors subreports #2] o.o.n.d.s.InterfaceSnmpResourceType: populateResourceList: adding resource toString interfaceSnmp[Gi2_0_12-503de57e070c] 2016-04-12 07:27:08,661 DEBUG [gkvi_Ifin_outErrors subreports #2] o.o.n.d.s.DefaultResourceDao: getChildResource: returning resource nodeSource[RZ-Access-Switche%3A30036a].interfaceSnmp[Gi2_0_12-503de57e070c] 2016-04-12 07:27:08,661 ERROR [gkvi_Ifin_outErrors subreports #2] o.o.n.m.i.AbstractRrdBasedFetchStrategy: No attribute with name: dot3HCInPauseFrame 2016-04-12 07:27:08,661 WARN [gkvi_Ifin_outErrors subreports #2] o.o.n.j.m.l.LocalMeasurementDataSourceWrapper: A attribute or resource was not found org.opennms.netmgt.measurements.api.exceptions.ResourceNotFoundException: Resource or attribute not found for QueryRequest{Step=300, Start=1460325600000, End=1460412000000, Max Rows=0, Interval=null, Heartbeat=null, Sources=[Source{Label=ifInErrors, Resource ID=nodeSource [RZ-Access-Switche:30036a].interfaceSnmp[Gi2_0_12-503de57e070c], Attribute=ifInErrors, Datasource=null, Transient=false}, Source{Label=ifOutErrors, Resource ID=nodeSource[RZ-Access-Switche:30036a].interfaceSnmp[Gi2_0_12-503de57e070c], Attribute=ifOutErrors, Datasource=nul l, Transient=false}, Source{Label=ifOutDiscards, Resource ID=nodeSource[RZ-Access-Switche:30036a].interfaceSnmp[Gi2_0_12-503de57e070c], Attribute=ifOutDiscards, Datasource=null, Transient=false}, Source{Label=ifInDiscards, Resource ID=nodeSource[RZ-Access-Switche:30036a]. interfaceSnmp[Gi2_0_12-503de57e070c], Attribute=ifInDiscards, Datasource=null, Transient=false}, Source{Label=InPauseFrame, Resource ID=nodeSource[RZ-Access-Switche:30036a].interfaceSnmp[Gi2_0_12-503de57e070c], Attribute=dot3HCInPauseFrame, Datasource=null, Transient=fals e}], Expressions=[], Filters=[]} at org.opennms.netmgt.measurements.api.MeasurementsService.query(MeasurementsService.java:79) ~[org.opennms.features.measurements.api-17.1.0.jar:?] at org.opennms.netmgt.jasper.measurement.local.LocalMeasurementDataSourceWrapper.createDataSource(LocalMeasurementDataSourceWrapper.java:76) [jasper-extensions-17.1.0.jar:?] at org.opennms.netmgt.jasper.measurement.MeasurementQueryExecutor.createDatasource(MeasurementQueryExecutor.java:77) [jasper-extensions-17.1.0.jar:?] at org.opennms.netmgt.jasper.measurement.MeasurementQueryExecutor.createDatasource(MeasurementQueryExecutor.java:46) [jasper-extensions-17.1.0.jar:?] at net.sf.jasperreports.engine.fill.JRFillDataset.createQueryDatasource(JRFillDataset.java:1129) [jasperreports-6.1.1.jar:6.1.1] at net.sf.jasperreports.engine.fill.JRFillDataset.initDatasource(JRFillDataset.java:696) [jasperreports-6.1.1.jar:6.1.1] at net.sf.jasperreports.engine.fill.BaseReportFiller.setParameters(BaseReportFiller.java:437) [jasperreports-6.1.1.jar:6.1.1] at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:523) [jasperreports-6.1.1.jar:6.1.1] at net.sf.jasperreports.engine.fill.JRFillSubreport.fillSubreport(JRFillSubreport.java:742) [jasperreports-6.1.1.jar:6.1.1] at net.sf.jasperreports.engine.fill.JRSubreportRunnable.run(JRSubreportRunnable.java:58) [jasperreports-6.1.1.jar:6.1.1] at net.sf.jasperreports.engine.fill.AbstractThreadSubreportRunner.run(AbstractThreadSubreportRunner.java:216) [jasperreports-6.1.1.jar:6.1.1] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_45] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_45] at java.lang.Thread.run(Thread.java:745) [?:1.8.0_45]

A missing resource or attribute should not break the filling process of a report. In fact, with the old jrobin/rrdtool query language, a missing entity is silently ignored (i.e. no data, NaN or whatever Jasper expects for "not a number"), which is the expected behavior.

Acceptance / Success Criteria

None

Attachments

1
  • 18 Apr 2016, 03:32 PM

Lucidchart Diagrams

Activity

Show:

Markus von Rüden April 19, 2016 at 1:58 PM

Good Point, I updated the patch to fill not available attributes with Double.NaN.
In addition I also updated the NewtsFetchStrategy, as it was missing in the original patch.

The PR can be found here: https://github.com/OpenNMS/opennms/pull/725

Alejandro Galue April 18, 2016 at 3:32 PM

I tried the changes made on the branch created for this issue, and the "relaxed" mode seems to work (see the attached image: sample-report.png).

As you can see on the report, it shows "null" for the non-existing metric. I modified the field on the report to be the following and it still shows null:

$V{InPauseFrame_tot}.isNaN() ? "NaN" : String.format("%.4f", $V{InPauseFrame_tot})

I also tried:

$V{InPauseFrame_tot}.isNaN() || $V{InPauseFrame_tot} == null ? "NaN" : String.format("%.4f", $V{InPauseFrame_tot})

Maybe this is not related with this problem, but I just want to be sure:
Is there a way to return Double.NaN ? I think that is more accurate.

Alejandro Galue April 14, 2016 at 11:58 AM
Edited

I verified with the same template I've been analyzing the following:

If I remove the metrics associated with the exception, the report is generated and all the fields are properly populated. But if I restore the field that I know some resources are not going to have, I can only see null for ALL the fields. I expect to see null or even better, an empty content for the field that doesn't exist, but the rest of them should be properly filled.

Fixed

Details

Assignee

Reporter

Labels

Affects versions

Priority

PagerDuty

Created April 14, 2016 at 11:02 AM
Updated April 21, 2016 at 10:54 AM
Resolved April 21, 2016 at 6:54 AM

Flag notifications