From OpenNMS
Contents |
Problematics
OpenNMS SNMP grapher/collector is based on assumption, that counters and descriptions of particular probe should contains in the same indexes.
Let's take a look at the Cisco jitter probes:
.1.3.6.1.4.1.9.9.42.1.2.1.1.3.<index> - has describe the probe, while .1.3.6.1.4.1.9.9.42.1.5.2.1.<counter_id>.<index> - contain counters.
In the Cisco class based QoS things are much more complex. It has different groups of counters in one oid, and describe each group in different oid, using different indexes. Also it has reference to parent interface ids, deep down in that structures.
In fact, there is no way to configure OpenNMS to handle that structure and show you something, that make a sense. You still can collect that counters, but you never knows what it meant to be.
Solution
Even where OpenNMS can't do something, and does have not respective API, we can still extend the coding by ourselves :)
The way is:
- to configure what we can (SNMP data collection and prefabricated graphs)
- to add lacking functionality (as included JSP)
- to create an interface where we need new functionality
Configuration
datacollection-config.xml
Include code that configures / extends the respective parts of your datacollection-config.xml
<resourceType name="cbQoSPolicyDescr" label="cbQoS Policy Config Description"
resourceLabel="${index}">
<persistenceSelectorStrategy class="org.opennms.netmgt.collectd.PersistAllSelectorStrategy"/>
<storageStrategy class="org.opennms.netmgt.dao.support.IndexStorageStrategy"/>
</resourceType>
<resourceType name="cbQoSMonPolicy" label="cbQoS Policy Config"
resourceLabel="${index}">
<persistenceSelectorStrategy class="org.opennms.netmgt.collectd.PersistAllSelectorStrategy"/>
<storageStrategy class="org.opennms.netmgt.dao.support.IndexStorageStrategy"/>
</resourceType>
<resourceType name="cbQoSCfgCM" label="cbQoS Classmaps Config"
resourceLabel="${index}">
<persistenceSelectorStrategy class="org.opennms.netmgt.collectd.PersistAllSelectorStrategy"/>
<storageStrategy class="org.opennms.netmgt.dao.support.IndexStorageStrategy"/>
</resourceType>
<resourceType name="cbQoS" label="cbQoS Statistics"
resourceLabel="${index}">
<persistenceSelectorStrategy class="org.opennms.netmgt.collectd.PersistAllSelectorStrategy"/>
<storageStrategy class="org.opennms.netmgt.dao.support.IndexStorageStrategy"/>
</resourceType>
<group name="cisco-cbqos-config-policy-descr" ifType="all"> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.6.1.1.1" instance="cbQoSPolicyDescr" alias="cbqosPolicyName" type="string" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.6.1.1.2" instance="cbQoSPolicyDescr" alias="cbqosPolicyDescr" type="string" /> </group> <group name="cisco-cbqos-config-policy" ifType="all"> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.1.1.1.2" instance="cbQoSMonPolicy" alias="cbqosIfType" type="string" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.1.1.1.3" instance="cbQoSMonPolicy" alias="cbqosPolicyDirection" type="string" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.1.1.1.4" instance="cbQoSMonPolicy" alias="cbqosIfId" type="string" /> </group> <group name="cisco-cbqos-config-classmap" ifType="all"> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.7.1.1.1" instance="cbQoSCfgCM" alias="cbqosCMName" type="string" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.7.1.1.2" instance="cbQoSCfgCM" alias="cbqosCMDesc" type="string" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.7.1.1.3" instance="cbQoSCfgCM" alias="cbqosCMInfo" type="string" /> </group> <group name="cisco-cbqos-stats" ifType="all"> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.5.1.1.2" instance="cbQoS" alias="cbqosConfId" type="string" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.5.1.1.3" instance="cbQoS" alias="cbqosObjectType" type="string" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.5.1.1.4" instance="cbQoS" alias="cbqosParentId" type="string" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.15.1.1.1" instance="cbQoS" alias="cbqosCMPrePPktOf" type="counter" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.15.1.1.3" instance="cbQoS" alias="cbqosCMPrePPkt" type="counter" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.15.1.1.4" instance="cbQoS" alias="cbqosCMPrePByteOf" type="counter" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.15.1.1.6" instance="cbQoS" alias="cbqosCMPrePByte" type="counter" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.15.1.1.7" instance="cbQoS" alias="cbqosCMPrePBitR" type="gauge" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.15.1.1.8" instance="cbQoS" alias="cbqosCMPostPByteOf" type="counter" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.15.1.1.10" instance="cbQoS" alias="cbqosCMPostPByte" type="counter" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.15.1.1.11" instance="cbQoS" alias="cbqosCMPostPBitR" type="gauge" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.15.1.1.12" instance="cbQoS" alias="cbqosCMDropPktOf" type="counter" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.15.1.1.14" instance="cbQoS" alias="cbqosCMDropPkt" type="counter" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.15.1.1.15" instance="cbQoS" alias="cbqosCMDropByteOf" type="counter" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.15.1.1.17" instance="cbQoS" alias="cbqosCMDropByte" type="counter" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.15.1.1.18" instance="cbQoS" alias="cbqosCMDropBitR" type="gauge" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.15.1.1.19" instance="cbQoS" alias="cbqosCMNBufDrPktOf" type="counter" /> <mibObj oid=".1.3.6.1.4.1.9.9.166.1.15.1.1.21" instance="cbQoS" alias="cbqosCMNBufDrPkt" type="counter" /> </group>
<includeGroup>cisco-cbqos-config-policy</includeGroup> <includeGroup>cisco-cbqos-config-classmap</includeGroup> <includeGroup>cisco-cbqos-stats</includeGroup>
snmp-graph.properties
Include code that configures / extends the respective parts of your snmp-graph.properties
cisco.cbQoS.class.pkt, cisco.cbQoS.class.pktof, cisco.cbQoS.class.byte, cisco.cbQoS.class.byteof, cisco.cbQoS.class.bit, \
report.cisco.cbQoS.class.pkt.name=cbQoS Packets
report.cisco.cbQoS.class.pkt.columns=cbqosCMPrePPkt,cbqosCMDropPkt,cbqosCMNBufDrPkt
report.cisco.cbQoS.class.pkt.type=cbQoS
report.cisco.cbQoS.class.pkt.command=--title="cbQoS Packets" \
--vertical-label packets/sec \
DEF:pre={rrd1}:cbqosCMPrePPkt:AVERAGE \
DEF:drop={rrd2}:cbqosCMDropPkt:AVERAGE \
DEF:nobuf={rrd3}:cbqosCMNBufDrPkt:AVERAGE \
AREA:pre#00dd00:"PrePolicy " \
GPRINT:pre:AVERAGE:"Avg \\: %8.2lf %s" \
GPRINT:pre:MIN:"Min \\: %8.2lf %s" \
GPRINT:pre:MAX:"Max \\: %8.2lf %s\\n" \
LINE2:drop#ff0000:"Dropped " \
GPRINT:drop:AVERAGE:"Avg \\: %8.2lf %s" \
GPRINT:drop:MIN:"Min \\: %8.2lf %s" \
GPRINT:drop:MAX:"Max \\: %8.2lf %s\\n" \
LINE1:nobuf#440000:"NoBuff " \
GPRINT:nobuf:AVERAGE:"Avg \\: %8.2lf %s" \
GPRINT:nobuf:MIN:"Min \\: %8.2lf %s" \
GPRINT:nobuf:MAX:"Max \\: %8.2lf %s\\n"
report.cisco.cbQoS.class.pktof.name=cbQoS Packets Overflow
report.cisco.cbQoS.class.pktof.columns=cbqosCMPrePPktOf,cbqosCMDropPktOf,cbqosCMNBufDrPktOf
report.cisco.cbQoS.class.pktof.type=cbQoS
report.cisco.cbQoS.class.pktof.command=--title="cbQoS Packets Overflow" \
--vertical-label packets/sec \
DEF:pre={rrd1}:cbqosCMPrePPktOf:AVERAGE \
DEF:drop={rrd2}:cbqosCMDropPktOf:AVERAGE \
DEF:nobuf={rrd3}:cbqosCMNBufDrPktOf:AVERAGE \
AREA:pre#00dd00:"PrePolicy " \
GPRINT:pre:AVERAGE:"Avg \\: %8.2lf %s" \
GPRINT:pre:MIN:"Min \\: %8.2lf %s" \
GPRINT:pre:MAX:"Max \\: %8.2lf %s\\n" \
LINE2:drop#ff0000:"Dropped " \
GPRINT:drop:AVERAGE:"Avg \\: %8.2lf %s" \
GPRINT:drop:MIN:"Min \\: %8.2lf %s" \
GPRINT:drop:MAX:"Max \\: %8.2lf %s\\n" \
LINE1:nobuf#440000:"NoBuff " \
GPRINT:nobuf:AVERAGE:"Avg \\: %8.2lf %s" \
GPRINT:nobuf:MIN:"Min \\: %8.2lf %s" \
GPRINT:nobuf:MAX:"Max \\: %8.2lf %s\\n"
report.cisco.cbQoS.class.byte.name=cbQoS Bytes
report.cisco.cbQoS.class.byte.columns=cbqosCMPrePByte,cbqosCMPostPByte,cbqosCMDropByte
report.cisco.cbQoS.class.byte.type=cbQoS
report.cisco.cbQoS.class.byte.command=--title="cbQoS Bytes" \
--vertical-label bytes/sec \
DEF:pre={rrd1}:cbqosCMPrePByte:AVERAGE \
DEF:post={rrd2}:cbqosCMPostPByte:AVERAGE \
DEF:drop={rrd3}:cbqosCMDropByte:AVERAGE \
AREA:pre#00dd00:"PrePolicy " \
GPRINT:pre:AVERAGE:"Avg \\: %8.2lf %s" \
GPRINT:pre:MIN:"Min \\: %8.2lf %s" \
GPRINT:pre:MAX:"Max \\: %8.2lf %s\\n" \
LINE1:post#0000ff:"PostPolicy " \
GPRINT:post:AVERAGE:"Avg \\: %8.2lf %s" \
GPRINT:post:MIN:"Min \\: %8.2lf %s" \
GPRINT:post:MAX:"Max \\: %8.2lf %s\\n" \
LINE2:drop#ff0000:"Dropped " \
GPRINT:drop:AVERAGE:"Avg \\: %8.2lf %s" \
GPRINT:drop:MIN:"Min \\: %8.2lf %s" \
GPRINT:drop:MAX:"Max \\: %8.2lf %s\\n"
report.cisco.cbQoS.class.byteof.name=cbQoS Bytes Overflow
report.cisco.cbQoS.class.byteof.columns=cbqosCMPrePByteOf,cbqosCMPostPByteOf,cbqosCMDropByteOf
report.cisco.cbQoS.class.byteof.type=cbQoS
report.cisco.cbQoS.class.byteof.command=--title="cbQoS Bytes Overflow" \
--vertical-label bytes/sec \
DEF:pre={rrd1}:cbqosCMPrePByteOf:AVERAGE \
DEF:post={rrd2}:cbqosCMPostPByteOf:AVERAGE \
DEF:drop={rrd3}:cbqosCMDropByteOf:AVERAGE \
AREA:pre#00dd00:"PrePolicy " \
GPRINT:pre:AVERAGE:"Avg \\: %8.2lf %s" \
GPRINT:pre:MIN:"Min \\: %8.2lf %s" \
GPRINT:pre:MAX:"Max \\: %8.2lf %s\\n" \
LINE1:post#0000ff:"PostPolicy " \
GPRINT:post:AVERAGE:"Avg \\: %8.2lf %s" \
GPRINT:post:MIN:"Min \\: %8.2lf %s" \
GPRINT:post:MAX:"Max \\: %8.2lf %s\\n" \
LINE2:drop#ff0000:"Dropped " \
GPRINT:drop:AVERAGE:"Avg \\: %8.2lf %s" \
GPRINT:drop:MIN:"Min \\: %8.2lf %s" \
GPRINT:drop:MAX:"Max \\: %8.2lf %s\\n"
report.cisco.cbQoS.class.bit.name=cbQoS BitRates
report.cisco.cbQoS.class.bit.columns=cbqosCMPrePBitR,cbqosCMPostPBitR,cbqosCMDropBitR
report.cisco.cbQoS.class.bit.type=cbQoS
report.cisco.cbQoS.class.bit.command=--title="cbQoS BitRates" \
--vertical-label="bitrate" \
DEF:pre={rrd1}:cbqosCMPrePBitR:AVERAGE \
DEF:post={rrd2}:cbqosCMPostPBitR:AVERAGE \
DEF:drop={rrd3}:cbqosCMDropBitR:AVERAGE \
AREA:pre#00dd00:"PrePolicy " \
GPRINT:pre:AVERAGE:"Avg \\: %8.2lf %s" \
GPRINT:pre:MIN:"Min \\: %8.2lf %s" \
GPRINT:pre:MAX:"Max \\: %8.2lf %s\\n" \
LINE1:post#0000ff:"PostPolicy " \
GPRINT:post:AVERAGE:"Avg \\: %8.2lf %s" \
GPRINT:post:MIN:"Min \\: %8.2lf %s" \
GPRINT:post:MAX:"Max \\: %8.2lf %s\\n" \
LINE2:drop#ff0000:"Dropped " \
GPRINT:drop:AVERAGE:"Avg \\: %8.2lf %s" \
GPRINT:drop:MIN:"Min \\: %8.2lf %s" \
GPRINT:drop:MAX:"Max \\: %8.2lf %s\\n"
Installation
Create the file <opennms>/[jetty-]webapps/opennms/includes/cbqos.jsp and fill it with the following code:
<%
String nodeid = request.getParameter("node");
String resourceLabel = request.getParameter("resource");
if( nodeid == null ) {
throw new MissingParameterException("node");
}
String selectlist = "";
WebApplicationContext webAppContext = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
ResourceService resourceService = (ResourceService)webAppContext.getBean("resourceService", ResourceService.class);
RrdDao rrdDao = (RrdDao)webAppContext.getBean("rrdDao", RrdDao.class);
File rrdDir = new File(resourceService.getRrdDirectory(), "snmp");
PropertiesCache s_cache = new PropertiesCache();
Map<String, String> resourceLables = new HashMap<String, String>();
Map<Integer, Interface> ifaces = new HashMap<Integer, Interface>();
Map<String, Map> cbqos_policy = new HashMap<String, Map>();
Map<String, Map> cbqos_class = new HashMap<String, Map>();
Map<String, Map> policy_props = new HashMap<String, Map>();
Map<String, Map> class_props = new HashMap<String, Map>();
Set<String> usable_ifaces = new HashSet<String>();
OnmsResource node = resourceService.getResourceById(nodeid);
String node_name = node.toString();
Matcher mnode = Pattern.compile("node\\[(\\d+)\\]").matcher(node_name);
boolean node_status = mnode.matches();
String node_index = mnode.group(1);
selectlist += "<h3>cbQoS Statistics</h3>";
for (Interface iface : NetworkElementFactory.getActiveInterfacesOnNode(Integer.parseInt(node_index))) {
ifaces.put(iface.getIfIndex(), iface);
}
List<OnmsResource> resourcesx = resourceService.findChildResources(node, "cbQoS");
// Set [class_id = Set [class_resource_id, class_name, child_policy_id]]
Map <String, Set <String[]>> classes = new HashMap<String, Set<String[]>>();
// Set [policy_id = Set [class_id, object_type (1 == policy), policy_name ]]
Map <String, Set <String[]>> policies = new HashMap<String, Set<String[]>>();
// Set [interface_name = Set [policy_id, policy_direction, ]]
Map <String, Set <String[]>> cbqos_ifaces = new HashMap<String, Set<String[]>>();
for (OnmsResource resource : resourcesx) {
Map <String, String> _attributes = resource.getStringPropertyAttributes();
if (_attributes.get("cbqosObjectType").equals("2")) {
Matcher _ids = Pattern.compile("node\\[\\d+\\]\\.cbQoS\\[(\\d+)\\.(\\d+)\\]").matcher(resource.toString());
boolean _matches = _ids.matches();
String _bush_id = _ids.group(1);
String _id = _bush_id + "." + _ids.group(2);
String _conf = _attributes.get("cbqosConfId");
String _parent = _bush_id + "." + _attributes.get("cbqosParentId");
File _CfgCM_file = new File(rrdDir, node_index +"/cbQoSCfgCM/" + _conf + "/strings.properties");
String cbqos_classname = s_cache.getProperty(_CfgCM_file, "cbqosCMName");
_CfgCM_file = null;
Set <String[]> _res = new HashSet<String[]>();
if (classes.containsKey(_parent)) {
_res = classes.remove(_parent);
}
String[] _props = {resource.toString(), cbqos_classname, _id};
_res.add(_props);
classes.put(_parent, _res);
}
}
for (String pid : classes.keySet()) {
File _policy_file = new File(rrdDir, node_index +"/cbQoS/" + pid + "/strings.properties");
Map _policy_props = s_cache.getProperties(_policy_file);
String _parent_suf = s_cache.getProperty(_policy_file, "cbqosParentId");
String _parent_pref = pid.split("\\.")[0];
String _parent = _parent_pref + "." + _parent_suf;
String _policy_conf = s_cache.getProperty(_policy_file, "cbqosConfId");
String _policy_type = s_cache.getProperty(_policy_file, "cbqosObjectType");
if (_parent_suf.equals("0")) {
File _policy_cfg_file = new File(rrdDir, node_index +"/cbQoSMonPolicy/" + _parent_pref + "/strings.properties");
Map _policy_cfg_props = s_cache.getProperties(_policy_cfg_file);
String _policy_cfg_iface = s_cache.getProperty(_policy_cfg_file, "cbqosIfId");
String _policy_cfg_direction = s_cache.getProperty(_policy_cfg_file, "cbqosPolicyDirection");
if (_policy_cfg_direction.equals("1")) {
_policy_cfg_direction = "[in]";
} else if (_policy_cfg_direction.equals("2")) {
_policy_cfg_direction = "[out]";
} else {
_policy_cfg_direction = "[]";
}
String _iface_fullname = "";
if (ifaces.containsKey(Integer.parseInt(_policy_cfg_iface))) {
Interface _iface = ifaces.get(Integer.parseInt(_policy_cfg_iface));
String _iface_name = _iface.getSnmpIfName();
String _iface_addr = _iface.getIpAddress();
if (_iface_name != null && _iface_name != "") {
_iface_fullname += _iface_name + " ";
}
if (_iface_addr != "0.0.0.0") {
_iface_fullname += "(" + _iface_addr + ")";
}
} else {
_iface_fullname = "unknown iface " + _policy_cfg_iface;
}
Set <String[]> _res = new HashSet<String[]>();
if (cbqos_ifaces.containsKey(_iface_fullname)) {
_res = cbqos_ifaces.remove(_iface_fullname);
}
String[] _props = {_parent, _policy_cfg_direction, ""};
_res.add(_props);
cbqos_ifaces.put(_iface_fullname, _res);
}
File _policy_descr_file = new File(rrdDir, node_index +"/cbQoSPolicyDescr/" + _policy_conf + "/strings.properties");
String _policy_descr_name = s_cache.getProperty(_policy_descr_file, "cbqosPolicyName");
Set <String[]> _res = new HashSet<String[]>();
if (policies.containsKey(_parent)) {
_res = policies.remove(_parent);
}
String[] _props = {pid, _policy_type, _policy_descr_name};
_res.add(_props);
policies.put(_parent, _res);
}
for (Map.Entry <String, Set <String[]>> entry : cbqos_ifaces.entrySet()) {
String iface_id = entry.getKey();
selectlist += "<div style=\"float: left; margin: 0 0 0 11px\"><div>" + iface_id + "</div>";
selectlist += "<select multiple=\"\" size=\"\" name=\"resourceId\">";
for (String[] policy_prop : entry.getValue()) {
for (String[] policy : policies.get(policy_prop[0])) {
selectlist += "<optgroup label=\"" + policy[2] + "\">";
if (classes.containsKey(policy[0])) {
for (String[] cbclass : classes.get(policy[0])) {
selectlist += "<option value=\"" + cbclass[0] + "\">" + cbclass[1] + "</option>";
resourceLables.put(cbclass[0], iface_id + ": " + policy[2] + " > " + cbclass[1]);
if (policies.containsKey(cbclass[2])) {
for (String[] subpolicy : policies.get(cbclass[2])) {
selectlist += "<optgroup label=\"[" + policy[2] + " > " + cbclass[1] +
"]: " + subpolicy[2] + " \">";
if (classes.containsKey(subpolicy[0])) {
for (String[] subcbclass : classes.get(subpolicy[0])) {
selectlist += "<option value=\"" + subcbclass[0] + "\">[" + policy[2] +
" > " + cbclass[1] + "]: " + subcbclass[1] + " </option>";
resourceLables.put(subcbclass[0], iface_id + ": [" + policy[2] +
" > " + cbclass[1] + "]: " + subpolicy[2] + " > " + subcbclass[1]);
}
}
selectlist += "</optgroup>";
}
}
}
}
selectlist += "</optgroup>";
}
}
selectlist += "</select></div>";
}
selectlist += "<div style=\"clear: left\" />";
if (resourceLabel == null ) {
out.print(selectlist);
} else {
if (!resourceLables.containsKey(resourceLabel)) {
out.print("cbQoS Statistics: unknown resource");
} else {
out.print(resourceLables.get(resourceLabel));
}
}
%>
<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<%@page import="
java.io.Reader,
java.io.File,
java.io.FileReader,
java.io.FileInputStream,
java.util.*,
java.util.regex.*,
java.net.*,
org.opennms.web.*,
org.opennms.web.element.*,
org.opennms.web.acegisecurity.Authentication.*,
org.opennms.web.svclayer.ResourceService,
org.opennms.netmgt.dao.RrdDao,
org.opennms.netmgt.dao.ResourceDao,
org.opennms.core.utils.PropertiesCache,
org.opennms.netmgt.model.OnmsNode,
org.opennms.netmgt.model.OnmsResource,
org.opennms.netmgt.model.OnmsResourceType,
org.springframework.web.context.WebApplicationContext,
org.springframework.web.context.support.WebApplicationContextUtils"%>
Patching
cd to the directory <opennms>/[jetty-]webapps/opennms/WEB-INF/jsp/graph
chooseresource.jsp
Make a patch:
--- chooseresource.orig 2010-07-07 14:40:57.000000000 -0500
+++ chooseresource.jsp 2010-07-07 14:48:38.000000000 -0500
@@ -205,40 +205,52 @@
<p>
Please choose one or more resources that you wish to query.
</p>
<form method="get" name="report" action="${model.endUrl}">
<%=Util.makeHiddenTags(request, new String[] { "parentResourceId", "parentResourceType", "parentResource", "endUrl" })%>
<c:set var="num" value="0"/>
<c:forEach var="resourceType" items="${model.resourceTypes}">
+ <c:choose>
+ <c:when test="${resourceType.key.label == \"cbQoS Statistics\"}" >
+ <jsp:include page="/includes/cbqos.jsp" flush="false" >
+ <jsp:param name="node" value="${model.resource.id}" />
+ </jsp:include>
+
+ </c:when>
+ <c:otherwise>
+
<h3 class="o-box">${resourceType.key.label}</h3>
<c:choose>
<c:when test="${fn:length(resourceType.value) < 10}">
<c:set var="selectSize" value="${resource.count}"/>
</c:when>
<c:otherwise>
<c:set var="selectSize" value="10"/>
</c:otherwise>
</c:choose>
<select name="resourceId" id="resource-select-${num}" size="${selectSize}" multiple>
<c:forEach var="resource" items="${resourceType.value}">
<option value="${resource.id}">
${resource.label}
</option>
</c:forEach>
</select>
+ </c:otherwise>
+ </c:choose>
+
<c:set var="num" value="${num + 1}"/>
</c:forEach>
<br/>
<br/>
<input type="submit" value="Submit" onclick="submitForm(document.report.resourceId, document.report, 'resource')" />
<input type="button" value="Select All" onclick="selectAll('resourceId', true)" />
<input type="button" value="Unselect All" onclick="selectAll('resourceId', false)" />
</form>
results.jsp
Make a patch:
--- results.orig 2010-07-07 14:49:16.000000000 -0500
+++ results.jsp 2010-07-07 14:51:19.000000000 -0500
@@ -176,11 +176,21 @@
<br />
${resultSet.resource.resourceType.label}:
<c:choose>
- <c:when test="${(!empty resultSet.resource.link) && loggedIn}">
- <a href="<c:url value='${resultSet.resource.link}'/>">${resultSet.resource.label}</a>
+ <c:when test="${resultSet.resource.resourceType.label == 'cbQoS Statistics'}">
+ <jsp:include page="/includes/cbqos.jsp" flush="false" >
+ <jsp:param name="node" value="${resultSet.resource.parent.id}" />
+ <jsp:param name="resource" value="${resultSet.resource.id}" />
+ </jsp:include>
</c:when>
<c:otherwise>
- ${resultSet.resource.label}
+ <c:choose>
+ <c:when test="${!empty resultSet.resource.link}">
+ <a href="<c:url value='${resultSet.resource.link}'/>">${resultSet.resource.label}</a>
+ </c:when>
+ <c:otherwise>
+ ${resultSet.resource.label}
+ </c:otherwise>
+ </c:choose>
</c:otherwise>
</c:choose>
</c:if>
Enjoy
If you do things right, and I didn't mess up :) you should see something like this:
- in graph/chooseresource.htm (Home / Reports / Resource Graphs / Results)
- in graph/results.htm (Home / Reports / Resource Graphs / Choose)
Limits and bugs
This solution is limited to:
- *nix filesystems (ready for windows, do you want to test it?)
- it graphs only two levels of cbQoS classes tree, and ignore the others
Limits can be resolved, if there is some testers to make it works in mentioned environments.
Further integration (developers notes)
If there is someone, who considered of patching that functionality in to source three, i have a statement to publicize:
There is more things, along cbQoS, who needs much more complex handling, than OpenNMS default model can acquire. It would be nice to implement some sort of plugin model, that give the ability to include homemade JSP to the problematic places of the interface, without the needs of rehacking the code. And i can give you some different ideas howto implement that model, if you interested.
Contacts
You can mail me to oziabr.gmail.com








