Skip to content

Commit

Permalink
Merge pull request #1158 from OpenNMS/jira/NMS-8776
Browse files Browse the repository at this point in the history
Merging for inclusion in OpenNMS 19.
  • Loading branch information
soleger committed Nov 29, 2016
2 parents 102a5d8 + e5ccd1c commit 2703910
Show file tree
Hide file tree
Showing 12 changed files with 183 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,19 @@
public class MockMonitoredService implements MonitoredService {
private final int m_nodeId;
private String m_nodeLabel;
private final String m_nodeLocation;
private final String m_ipAddr;
private final String m_svcName;
private InetAddress m_inetAddr;

public MockMonitoredService(int nodeId, String nodeLabel, InetAddress inetAddress, String svcName) {
this(nodeId, nodeLabel, null, inetAddress, svcName);
}

public MockMonitoredService(int nodeId, String nodeLabel, String nodeLocation, InetAddress inetAddress, String svcName) {
m_nodeId = nodeId;
m_nodeLabel = nodeLabel;
m_nodeLocation = nodeLocation;
m_inetAddr = inetAddress;
m_svcName = svcName;
m_ipAddr = InetAddressUtils.str(m_inetAddr);
Expand Down Expand Up @@ -74,7 +80,7 @@ public void setNodeLabel(String nodeLabel) {

@Override
public String getNodeLocation() {
return null;
return m_nodeLocation;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

package org.opennms.netmgt.dao.api;

import org.opennms.netmgt.model.OnmsNode;
import org.opennms.netmgt.model.monitoringLocations.OnmsMonitoringLocation;

/**
Expand All @@ -41,5 +42,27 @@ public interface MonitoringLocationDao extends OnmsDao<OnmsMonitoringLocation, S

public static final String DEFAULT_MONITORING_LOCATION_ID = "Default";

/**
* Returns <b>true</b> if the given location name is <b>null</b> or the system default.
*
* @param locationName
* @return
*/
public static boolean isDefaultLocationName(String locationName) {
return locationName == null || DEFAULT_MONITORING_LOCATION_ID.equals(locationName);
}

/**
* Returns the name to which the given node is associated, or null if the if node
* is associated to either the default location, or no location.
*
* @param node
* @return
*/
public static String getLocationNameOrNullIfDefault(OnmsNode node) {
final String locationName = node.getLocation() != null ? node.getLocation().getLocationName() : null;
return isDefaultLocationName(locationName) ? null : locationName;
}

OnmsMonitoringLocation getDefaultLocation();
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.opennms.core.utils.InetAddressUtils;
import org.opennms.core.utils.LazySet;
import org.opennms.netmgt.dao.api.IpInterfaceDao;
import org.opennms.netmgt.dao.api.MonitoringLocationDao;
import org.opennms.netmgt.dao.api.ResourceStorageDao;
import org.opennms.netmgt.model.OnmsAttribute;
import org.opennms.netmgt.model.OnmsIpInterface;
Expand Down Expand Up @@ -108,6 +109,9 @@ public OnmsResource getChildByName(OnmsResource parent, String ipAddress) {
// Grab the node entity
final OnmsNode node = ResourceTypeUtils.getNodeFromResource(parent);

// Determine the location name
final String locationName = MonitoringLocationDao.getLocationNameOrNullIfDefault(node);

// Grab the interface
final OnmsIpInterface matchingIf = m_ipInterfaceDao.get(node, ipAddress);
if (matchingIf == null) {
Expand All @@ -116,13 +120,13 @@ public OnmsResource getChildByName(OnmsResource parent, String ipAddress) {
}

// Verify the path
final ResourcePath path = getInterfacePath(ipAddress);
final ResourcePath path = getInterfacePath(locationName, ipAddress);
if (!m_resourceStorageDao.exists(path, 0)) {
throw new ObjectRetrievalFailureException(OnmsResource.class, "No metrics found in parent path '" + parent.getPath() + "'");
}

// Create the resource
final OnmsResource resource = createResource(matchingIf, ipAddress, path);
final OnmsResource resource = createResource(locationName, matchingIf, ipAddress, path);
resource.setParent(parent);
return resource;
}
Expand All @@ -135,14 +139,17 @@ private List<OnmsResource> getResourcesForParent(OnmsResource parent, boolean st
// Grab the node entity
final OnmsNode node = ResourceTypeUtils.getNodeFromResource(parent);

// Determine the location name
final String locationName = MonitoringLocationDao.getLocationNameOrNullIfDefault(node);

// Verify the existence of the individual interfaces
final LinkedList<OnmsResource> resources = new LinkedList<OnmsResource>();
for (final OnmsIpInterface i : node.getIpInterfaces()) {
String ipAddr = InetAddressUtils.str(i.getIpAddress());

final ResourcePath path = getInterfacePath(ipAddr);
final ResourcePath path = getInterfacePath(locationName, ipAddr);
if (m_resourceStorageDao.exists(path, 0)) {
resources.add(createResource(i, ipAddr, path));
resources.add(createResource(locationName, i, ipAddr, path));
if (stopAfterFirst) {
break;
}
Expand All @@ -151,15 +158,21 @@ private List<OnmsResource> getResourcesForParent(OnmsResource parent, boolean st
return resources;
}

private OnmsResource createResource(final OnmsIpInterface ipInterface, final String ipAddr, final ResourcePath path) {
private OnmsResource createResource(final String location, final OnmsIpInterface ipInterface, final String ipAddr, final ResourcePath path) {
final LazyResourceAttributeLoader loader = new LazyResourceAttributeLoader(m_resourceStorageDao, path);
final Set<OnmsAttribute> set = new LazySet<OnmsAttribute>(loader);
final OnmsResource resource = new OnmsResource(ipAddr, ipAddr, this, set, path);
final OnmsResource resource = new OnmsResource(ipAddr, ipAddr, this, set, path);
resource.setEntity(ipInterface);
return resource;
}

private static ResourcePath getInterfacePath(String ipAddr) {
return new ResourcePath(ResourceTypeUtils.RESPONSE_DIRECTORY, ipAddr);
private static ResourcePath getInterfacePath(final String location, final String ipAddr) {
if (location == null) {
return new ResourcePath(ResourceTypeUtils.RESPONSE_DIRECTORY, ipAddr);
} else {
return new ResourcePath(ResourceTypeUtils.RESPONSE_DIRECTORY, ResourcePath.sanitize(location), ipAddr);
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,20 @@
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.opennms.netmgt.dao.api.IpInterfaceDao;
import org.opennms.netmgt.dao.api.MonitoringLocationDao;
import org.opennms.netmgt.dao.api.NodeDao;
import org.opennms.netmgt.dao.api.ResourceDao;
import org.opennms.netmgt.model.OnmsIpInterface;
import org.opennms.netmgt.model.OnmsNode;
import org.opennms.netmgt.model.OnmsResource;
import org.opennms.netmgt.model.ResourcePath;
import org.opennms.netmgt.model.ResourceTypeUtils;
import org.opennms.netmgt.model.monitoringLocations.OnmsMonitoringLocation;

public class ResponseTimeResourceTypeTest {

private static final String NON_DEFAULT_LOCATION_NAME = "!" + MonitoringLocationDao.DEFAULT_MONITORING_LOCATION_ID;

@Rule
public TemporaryFolder tempFolder = new TemporaryFolder();

Expand Down Expand Up @@ -85,12 +89,17 @@ public void setUp() throws IOException {
File http = new File(ifResponseFolder, "http.rrd");
http.createNewFile();

ifResponseFolder = tempFolder.newFolder(ResourceTypeUtils.RESPONSE_DIRECTORY, ResourcePath.sanitize(NON_DEFAULT_LOCATION_NAME), "127.0.0.1");
http = new File(ifResponseFolder, "http.rrd");
http.createNewFile();

ipInterfaces.add(ipInterface);
}

@Test
public void canGetResourcesForNode() throws IOException {
expect(node.getIpInterfaces()).andReturn(ipInterfaces);
expect(node.getLocation()).andReturn(null);
expect(ipInterface.getIpAddress()).andReturn(InetAddress.getByName("127.0.0.1")).atLeastOnce();

replay(node, ipInterface);
Expand All @@ -105,6 +114,27 @@ public void canGetResourcesForNode() throws IOException {
assertEquals("127.0.0.1", resources.get(0).getName());
}

@Test
public void canGetResourcesForNodeAtLocation() throws IOException {
OnmsMonitoringLocation location = new OnmsMonitoringLocation();
location.setLocationName(NON_DEFAULT_LOCATION_NAME);

expect(node.getIpInterfaces()).andReturn(ipInterfaces);
expect(node.getLocation()).andReturn(location).atLeastOnce();
expect(ipInterface.getIpAddress()).andReturn(InetAddress.getByName("127.0.0.1")).atLeastOnce();

replay(node, ipInterface);
NodeResourceType nodeResourceType = new NodeResourceType(resourceDao, nodeDao);
OnmsResource nodeResource = new OnmsResource("1", "Node", nodeResourceType, Collections.emptySet(), ResourcePath.get("foo"));
nodeResource.setEntity(node);

List<OnmsResource> resources = responseTimeResourceType.getResourcesForParent(nodeResource);
verify(node, ipInterface);

assertEquals(1, resources.size());
assertEquals("127.0.0.1", resources.get(0).getName());
}

@Test
public void canGetChildByName() throws IOException {
expect(ipInterfaceDao.get(node, "127.0.0.1")).andReturn(ipInterface);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;

/**
* An abstract path used to represent a resource or its parent.
Expand All @@ -18,6 +19,9 @@
*/
public class ResourcePath implements Iterable<String>, Comparable<ResourcePath> {

private static final Pattern SANITIZE_PATH_PATTERN = Pattern.compile("[^a-zA-Z0-9.-]");
private static final String SANITIZE_PATH_PLACEHOLDER = "_";

private final List<String> m_elements = new ArrayList<String>();

public ResourcePath(String... path) {
Expand Down Expand Up @@ -172,4 +176,10 @@ public int compareTo(ResourcePath other) {
return this.toString().compareTo(other.toString());
}

public static String sanitize(String path) {
if (path == null) {
return null;
}
return SANITIZE_PATH_PATTERN.matcher(path).replaceAll(SANITIZE_PATH_PLACEHOLDER);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*******************************************************************************
* This file is part of OpenNMS(R).
*
* Copyright (C) 2016-2016 The OpenNMS Group, Inc.
* OpenNMS(R) is Copyright (C) 1999-2016 The OpenNMS Group, Inc.
*
* OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
*
* OpenNMS(R) is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* OpenNMS(R) 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with OpenNMS(R). If not, see:
* http://www.gnu.org/licenses/
*
* For more information contact:
* OpenNMS(R) Licensing <license@opennms.org>
* http://www.opennms.org/
* http://www.opennms.com/
*******************************************************************************/

package org.opennms.netmgt.model;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

public class ResourcePathTest {

@Test
public void canSanitizePath() {
assertEquals("abc123", ResourcePath.sanitize("abc123"));
assertEquals("My_Path_", ResourcePath.sanitize("My Path!"));
assertEquals("_________", ResourcePath.sanitize(\\_(ツ)_/¯"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
import org.opennms.netmgt.collection.api.CollectionSetVisitor;
import org.opennms.netmgt.collection.api.ServiceParameters;
import org.opennms.netmgt.collection.api.TimeKeeper;
import org.opennms.netmgt.dao.api.MonitoringLocationDao;
import org.opennms.netmgt.model.ResourcePath;

import com.google.common.collect.Maps;

Expand All @@ -52,17 +54,20 @@ public class LatencyCollectionResource implements CollectionResource {

private final String m_serviceName;
private final String m_ipAddress;
private final String m_location;
private final Map<AttributeGroupType, AttributeGroup> m_attributeGroups = Maps.newLinkedHashMap();

/**
* <p>Constructor for LatencyCollectionResource.</p>
*
* @param serviceName a {@link java.lang.String} object.
* @param ipAddress a {@link java.lang.String} object.
* @param location a {@link java.lang.String} object.
*/
public LatencyCollectionResource(String serviceName, String ipAddress) {
public LatencyCollectionResource(String serviceName, String ipAddress, String location) {
m_serviceName = serviceName;
m_ipAddress = ipAddress;
m_location = location;
}

/**
Expand Down Expand Up @@ -176,13 +181,17 @@ public String getOwnerName() {

@Override
public Path getPath() {
return Paths.get(m_ipAddress);
if (MonitoringLocationDao.isDefaultLocationName(m_location)) {
return Paths.get(m_ipAddress);
} else {
return Paths.get(ResourcePath.sanitize(m_location), m_ipAddress);
}
}

/** {@inheritDoc} */
@Override
public String toString() {
return m_serviceName + "@" + m_ipAddress;
return String.format("%s on %s at %s", m_serviceName, m_ipAddress, m_location);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ private void applyThresholds(String rrdPath, MonitoredService service, String ds
if (m_thresholdingSet == null) {
RrdRepository repository = new RrdRepository();
repository.setRrdBaseDir(new File(rrdPath));
m_thresholdingSet = new LatencyThresholdingSet(service.getNodeId(), service.getIpAddr(), service.getSvcName(), repository, m_resourceStorageDao);
m_thresholdingSet = new LatencyThresholdingSet(service.getNodeId(), service.getIpAddr(), service.getSvcName(), service.getNodeLocation(), repository, m_resourceStorageDao);
}
LinkedHashMap<String, Double> attributes = new LinkedHashMap<String, Double>();
for (String ds : entries.keySet()) {
Expand Down Expand Up @@ -170,7 +170,7 @@ private void persistLatencySamples(MonitoredService service, Map<String, Number>
// 2) If multiple entries are present, the DSs are created in the same order that they
// appear in the map

LatencyCollectionResource latencyResource = new LatencyCollectionResource(service.getSvcName(), service.getIpAddr());
LatencyCollectionResource latencyResource = new LatencyCollectionResource(service.getSvcName(), service.getIpAddr(), service.getNodeLocation());
for (final Entry<String, Number> entry : entries.entrySet()) {
final String ds = entry.getKey();
final Number value = entry.getValue() != null ? entry.getValue() : Double.NaN;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
*/
public class LatencyThresholdingSet extends ThresholdingSet {

private final String m_location;

private final ResourceStorageDao m_resourceStorageDao;

/**
Expand All @@ -62,9 +64,10 @@ public class LatencyThresholdingSet extends ThresholdingSet {
* @param repository a {@link org.opennms.netmgt.rrd.RrdRepository} object.
* @param interval a long.
*/
public LatencyThresholdingSet(int nodeId, String hostAddress, String serviceName, RrdRepository repository, ResourceStorageDao resourceStorageDao) {
public LatencyThresholdingSet(int nodeId, String hostAddress, String serviceName, String location, RrdRepository repository, ResourceStorageDao resourceStorageDao) {
super(nodeId, hostAddress, serviceName, repository);
m_resourceStorageDao = resourceStorageDao;
m_location = location;
}

/*
Expand Down Expand Up @@ -92,7 +95,7 @@ public boolean hasThresholds(Map<String, Double> attributes) {
*/
/** {@inheritDoc} */
public List<Event> applyThresholds(String svcName, Map<String, Double> attributes) {
LatencyCollectionResource latencyResource = new LatencyCollectionResource(svcName, m_hostAddress);
LatencyCollectionResource latencyResource = new LatencyCollectionResource(svcName, m_hostAddress, m_location);
LatencyCollectionAttributeType latencyType = new LatencyCollectionAttributeType();
Map<String, CollectionAttribute> attributesMap = new HashMap<String, CollectionAttribute>();
for (final Entry<String, Double> entry : attributes.entrySet()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import org.opennms.netmgt.config.PollerConfig;
import org.opennms.netmgt.config.poller.Package;
import org.opennms.netmgt.config.poller.Rrd;
import org.opennms.netmgt.dao.api.MonitoringLocationDao;
import org.opennms.netmgt.dao.api.ResourceStorageDao;
import org.opennms.netmgt.dao.mock.MockEventIpcManager;
import org.opennms.netmgt.events.api.EventConstants;
Expand Down Expand Up @@ -224,6 +225,7 @@ private void executeThresholdTest(Double[] rtValues) throws Exception {
expect(svc.getNodeId()).andReturn(1);
expect(svc.getIpAddr()).andReturn("127.0.0.1").atLeastOnce();
expect(svc.getSvcName()).andReturn("ICMP").atLeastOnce();
expect(svc.getNodeLocation()).andReturn(MonitoringLocationDao.DEFAULT_MONITORING_LOCATION_ID).atLeastOnce();

ServiceMonitor service = new MockServiceMonitor(rtValues);

Expand Down
Loading

0 comments on commit 2703910

Please sign in to comment.