Skip to content

Commit

Permalink
Merge pull request #2390 from OpenNMS/HZN-1475-rebase
Browse files Browse the repository at this point in the history
HZN-1475: Extend topology generator and test suite to support bridge topology - release 4.0.0
  • Loading branch information
Jesse White committed Mar 12, 2019
2 parents c6c3334 + d16500f commit 849b280
Show file tree
Hide file tree
Showing 15 changed files with 819 additions and 28 deletions.
Expand Up @@ -772,6 +772,9 @@ public void reloadConfig() {
@Override
public void reloadTopology() {
LOG.info("reloadTopology: reload enlinkd topology updaters");
LOG.debug("reloadTopology: Loading Bridge Topology.....");
m_bridgeTopologyService.load();
LOG.debug("reloadTopology: Bridge Topology Loaded");
for (ProtocolSupported protocol :ProtocolSupported.values()) {
forceTopologyUpdaterRun(protocol);
runTopologyUpdater(protocol);
Expand Down
Expand Up @@ -30,6 +30,7 @@

import java.util.function.Consumer;

import org.opennms.enlinkd.generator.protocol.BridgeProtocol;
import org.opennms.enlinkd.generator.protocol.CdpProtocol;
import org.opennms.enlinkd.generator.protocol.IsIsProtocol;
import org.opennms.enlinkd.generator.protocol.LldpProtocol;
Expand Down Expand Up @@ -65,7 +66,7 @@ public enum Topology {
}

public enum Protocol {
cdp, isis, lldp, ospf
cdp, isis, lldp, ospf, bridge
}

private TopologyContext topologyContext;
Expand All @@ -78,9 +79,9 @@ private TopologyGenerator(


public void generateTopology(TopologySettings topologySettings) {
topologySettings.verify();
org.opennms.enlinkd.generator.protocol.Protocol protocol = getProtocol(topologySettings);
deleteTopology(); // Let's first get rid of old generated topologies
getProtocol(topologySettings).createAndPersistNetwork();
protocol.createAndPersistNetwork();
}

public void deleteTopology() {
Expand All @@ -97,6 +98,8 @@ private org.opennms.enlinkd.generator.protocol.Protocol getProtocol(TopologySett
return new LldpProtocol(topologySettings, topologyContext);
} else if (Protocol.ospf == protocol) {
return new OspfProtocol(topologySettings, topologyContext);
} else if (Protocol.bridge == protocol) {
return new BridgeProtocol(topologySettings, topologyContext);
} else {
throw new IllegalArgumentException("Don't know this protocol: " + topologySettings.getProtocol());
}
Expand Down
Expand Up @@ -32,8 +32,12 @@
import java.util.List;

import org.opennms.netmgt.dao.api.GenericPersistenceAccessor;
import org.opennms.netmgt.enlinkd.model.BridgeBridgeLink;
import org.opennms.netmgt.enlinkd.model.BridgeElement;
import org.opennms.netmgt.enlinkd.model.BridgeMacLink;
import org.opennms.netmgt.enlinkd.model.CdpElement;
import org.opennms.netmgt.enlinkd.model.CdpLink;
import org.opennms.netmgt.enlinkd.model.IpNetToMedia;
import org.opennms.netmgt.enlinkd.model.IsIsElement;
import org.opennms.netmgt.enlinkd.model.IsIsLink;
import org.opennms.netmgt.enlinkd.model.LldpElement;
Expand Down Expand Up @@ -63,6 +67,10 @@ public <E> void persist(E entity) {
progressCallback.currentProgress(" Inserting of %s done.", entity.getClass().getSimpleName());
}

public <E> void persist(E ... elements) {
persist(Arrays.asList(elements));
}

public <E> void persist(List<E> elements) {
if (elements.size() < 1) {
return; // nothing do do
Expand All @@ -88,8 +96,12 @@ public void deleteTopology() {
IsIsElement.class,
LldpElement.class,
OspfLink.class,
BridgeBridgeLink.class,
BridgeMacLink.class,
BridgeElement.class,
OnmsIpInterface.class,
OnmsSnmpInterface.class);
OnmsSnmpInterface.class,
IpNetToMedia.class);

for (Class<?> clazz : deleteOperations) {
deleteEntities(clazz);
Expand Down
@@ -0,0 +1,179 @@
/*******************************************************************************
* This file is part of OpenNMS(R).
*
* Copyright (C) 2019 The OpenNMS Group, Inc.
* OpenNMS(R) is Copyright (C) 1999-2019 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.enlinkd.generator.protocol;

import java.util.List;

import org.opennms.enlinkd.generator.TopologyContext;
import org.opennms.enlinkd.generator.TopologyGenerator;
import org.opennms.enlinkd.generator.TopologySettings;
import org.opennms.enlinkd.generator.protocol.bridge.BridgeBuilder;
import org.opennms.enlinkd.generator.protocol.bridge.BridgeBuilderContext;
import org.opennms.enlinkd.generator.util.InetAddressGenerator;
import org.opennms.enlinkd.generator.util.MacAddressGenerator;
import org.opennms.netmgt.enlinkd.model.BridgeBridgeLink;
import org.opennms.netmgt.model.OnmsNode;

/**
* Creates a topology with Bridges and Segments.
* Call with: enlinkd:generate-topology --protocol bridge --nodes 10
* will result in:
*
* bridge0
* ------------------------------------
* | | | | |
* bridge1 bridge3 bridge4 bridge5 Macs/Ip
* | | | no node
* ------- -------- ...subtree...
* | | |
* Segment host8 host9
* -----------
* | |
* Macs/Ip bridge2
* no node |
* Segment
*
* If more than 10 nodes are requested then the tree repeats itself with bridge5 as the root node of the new subtree.
*/
public class BridgeProtocol extends Protocol<BridgeBridgeLink> {

/* this is the vlan id for all the bridgebridgelinks and bridgemaclinks */
private final static int VLAN_ID = 1;

private final MacAddressGenerator macGenerator = new MacAddressGenerator();
private final InetAddressGenerator inetGenerator = new InetAddressGenerator();

public BridgeProtocol(TopologySettings topologySettings, TopologyContext context) {
super(topologySettings, context);
}

@Override
protected void printProtocolSpecificMessage() {
// the bridge topology is different as the other topologies since it consists of different node types -> we need
// a different implementation of this method
this.context.currentProgress("%nCreating %s topology with %s Nodes. Other settings are ignored since they not relevant for this topology",
this.getProtocol(),
topologySettings.getAmountNodes());
}

@Override
protected TopologySettings adoptAndVerifySettings(TopologySettings topologySettings) {
// make amount of nodes multiple of 10+1 since each (sub)tree needs 10 nodes:
int amountNodes;
if (topologySettings.getAmountNodes() < 11) {
amountNodes = 11;
} else {
amountNodes = topologySettings.getAmountNodes();
int modulo = (amountNodes -1) % 10;
if(modulo != 0) {
amountNodes += (10-modulo);
}
}

return TopologySettings.builder()
.amountNodes(amountNodes)
.amountSnmpInterfaces(0)
.amountIpInterfaces(0)
.amountLinks(0)
.amountElements(0)
.build();
}

@Override
protected TopologyGenerator.Protocol getProtocol() {
return TopologyGenerator.Protocol.bridge;
}

@Override
protected void createAndPersistProtocolSpecificEntities(List<OnmsNode> nodes) {
OnmsNode bridge0 = nodes.get(0);
BridgeBuilderContext context = new BridgeBuilderContext(this.context.getTopologyPersister(), this.macGenerator, this.inetGenerator);
BridgeBuilder bridge0B = new BridgeBuilder(bridge0, 0, context);
createAndPersistProtocolSpecificEntities(nodes, bridge0B, bridge0, 0);

}

private void createAndPersistProtocolSpecificEntities(List<OnmsNode> nodes, BridgeBuilder root, OnmsNode gateway, int iteration) {

int offset = iteration * 10;
OnmsNode bridge1 = nodes.get(1 + offset);
OnmsNode bridge2 = nodes.get(2 + offset);
OnmsNode bridge3 = nodes.get(3 + offset);
OnmsNode host4 = nodes.get(4 + offset);
OnmsNode bridge5 = nodes.get(5 + offset);
OnmsNode host6 = nodes.get(6 + offset);
OnmsNode host7 = nodes.get(7 + offset);
OnmsNode host8 = nodes.get(8 + offset);
OnmsNode host9 = nodes.get(9 + offset);
OnmsNode bridge10 = nodes.get(10 + offset);
//bridge0
//bridge0:port1 connected to up bridge1:port11
BridgeBuilder bridge1B = root.connectToNewBridge(bridge1, 11);

//bridge3:port31 connected to up bridge0:port2
BridgeBuilder bridge3B = root.connectToNewBridge(bridge3, 31);

//bridge0:port3 connected to cloud
root.increasePortCounter();
root.createAndPersistCloud(2, 2);

// bridge0:port4 connected to host4:port41
root.increasePortCounter();
root.createAndPersistBridgeMacLink(host4, 41, gateway);

// bridge5 will be the new root bridge for the next interation
BridgeBuilder bridge5B = root.connectToNewBridge(bridge5, 51);

//bridge1
//bridge2:port21 connected to bridge1:port12 with clouds
BridgeBuilder bridge2B = bridge1B.connectToNewBridge(bridge2, 21);
bridge1B.createAndPersistCloud(2, 2);

//bridge2
// host6 and host 7 connected to port 22 : "cloud" symbol
bridge2B.increasePortCounter();
bridge2B.createAndPersistBridgeMacLink(true, host6, 61, gateway);
bridge2B.createAndPersistBridgeMacLink(false, host7, 71, gateway);

// bridge3
// host8:with-no-snmp connected bridge3:port32
bridge3B.increasePortCounter();
bridge3B.createAndPersistBridgeMacLink(host8, null, gateway);
bridge3B.increasePortCounter();
bridge3B.createAndPersistBridgeMacLink(host9, null, gateway);

//bridge3:port31 connected to up bridge0:port2
root.connectToNewBridge(bridge10, 10);

// create sub tree on bridge5:
if (nodes.size() >= offset + 20) {
createAndPersistProtocolSpecificEntities(nodes, bridge5B, gateway, iteration + 1);
}
}
}
Expand Up @@ -34,6 +34,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.opennms.enlinkd.generator.TopologyContext;
import org.opennms.enlinkd.generator.TopologyGenerator;
Expand All @@ -59,19 +60,12 @@ public abstract class Protocol<Element> {
final Map<Integer, Integer> nodeIfIndexes = new HashMap<>();

public Protocol(TopologySettings topologySettings, TopologyContext context) {
this.topologySettings = topologySettings;
this.topologySettings = adoptAndVerifySettings(topologySettings);
this.context = context;
}

public void createAndPersistNetwork() {
this.context.currentProgress("%nCreating %s %s topology with %s Nodes, %s Elements, %s Links, %s SnmpInterfaces, %s IpInterfaces:",
topologySettings.getTopology(),
this.getProtocol(),
topologySettings.getAmountNodes(),
topologySettings.getAmountElements(),
topologySettings.getAmountElements(),
topologySettings.getAmountSnmpInterfaces(),
topologySettings.getAmountIpInterfaces());
printProtocolSpecificMessage();
OnmsCategory category = createCategory();
context.getTopologyPersister().persist(category);
List<OnmsNode> nodes = createNodes(topologySettings.getAmountNodes(), category);
Expand All @@ -84,11 +78,27 @@ public void createAndPersistNetwork() {
createAndPersistProtocolSpecificEntities(nodes);
}

protected void printProtocolSpecificMessage() {
this.context.currentProgress("%nCreating %s %s topology with %s Nodes, %s Elements, %s Links, %s SnmpInterfaces, %s IpInterfaces:",
topologySettings.getTopology(),
this.getProtocol(),
topologySettings.getAmountNodes(),
topologySettings.getAmountElements(),
topologySettings.getAmountElements(),
topologySettings.getAmountSnmpInterfaces(),
topologySettings.getAmountIpInterfaces());
}

protected abstract void createAndPersistProtocolSpecificEntities(List<OnmsNode> nodes);

protected abstract TopologyGenerator.Protocol getProtocol();

private OnmsCategory createCategory() {
protected TopologySettings adoptAndVerifySettings(TopologySettings topologySettings) {
topologySettings.verify();
return topologySettings;
}

protected OnmsCategory createCategory() {
OnmsCategory category = new OnmsCategory();
category.setName(TopologyGenerator.CATEGORY_NAME);
return category;
Expand Down Expand Up @@ -130,7 +140,7 @@ protected List<OnmsSnmpInterface> createSnmpInterfaces(List<OnmsNode> nodes) {
return interfaces;
}

private OnmsSnmpInterface createSnmpInterface(int ifIndex, OnmsNode node) {
protected OnmsSnmpInterface createSnmpInterface(int ifIndex, OnmsNode node) {
OnmsSnmpInterface onmsSnmpInterface = new OnmsSnmpInterface();
onmsSnmpInterface.setId((node.getId() * topologySettings.getAmountSnmpInterfaces()) + ifIndex);
onmsSnmpInterface.setNode(node);
Expand All @@ -155,12 +165,12 @@ protected List<OnmsIpInterface> createIpInterfaces(List<OnmsSnmpInterface> snmps
return interfaces;
}

private OnmsIpInterface createIpInterface(OnmsSnmpInterface snmp, InetAddress inetAddress) {
protected OnmsIpInterface createIpInterface(OnmsSnmpInterface snmp, InetAddress inetAddress) {
OnmsIpInterface ip = new OnmsIpInterface();
ip.setId(snmp.getId());
ip.setSnmpInterface(snmp);
ip.setIpLastCapsdPoll(new Date());
ip.setNode(snmp.getNode());
ip.setNode(Optional.ofNullable(snmp).map(OnmsSnmpInterface::getNode).orElse(null));
ip.setIpAddress(inetAddress);
return ip;
}
Expand Down

0 comments on commit 849b280

Please sign in to comment.