X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=networkmodel%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Ftransportpce%2Fnetworkmodel%2Fservice%2FNetworkModelServiceImpl.java;h=ef07a03f20fb5cee999ddf9ba407cf938f8948cc;hb=b1b3bafd549bb501937cea5c976d5344608b6ed3;hp=57e398eb08d965ee0a947e07bf4a1a71847e8652;hpb=38788ce8eedd77f7b1dc089df00d9e2a9bcfc1f8;p=transportpce.git diff --git a/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/service/NetworkModelServiceImpl.java b/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/service/NetworkModelServiceImpl.java index 57e398eb0..ef07a03f2 100644 --- a/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/service/NetworkModelServiceImpl.java +++ b/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/service/NetworkModelServiceImpl.java @@ -8,6 +8,7 @@ package org.opendaylight.transportpce.networkmodel.service; import com.google.common.util.concurrent.ListenableFuture; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -18,8 +19,12 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; import org.eclipse.jdt.annotation.Nullable; +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.binding.api.NotificationPublishService; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; +import org.opendaylight.transportpce.common.InstanceIdentifiers; import org.opendaylight.transportpce.common.NetworkUtils; +import org.opendaylight.transportpce.common.device.DeviceTransactionManager; import org.opendaylight.transportpce.common.mapping.PortMapping; import org.opendaylight.transportpce.common.network.NetworkTransactionService; import org.opendaylight.transportpce.networkmodel.R2RLinkDiscovery; @@ -29,12 +34,21 @@ import org.opendaylight.transportpce.networkmodel.util.LinkIdUtil; import org.opendaylight.transportpce.networkmodel.util.OpenRoadmNetwork; import org.opendaylight.transportpce.networkmodel.util.OpenRoadmOtnTopology; import org.opendaylight.transportpce.networkmodel.util.OpenRoadmTopology; -import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200429.network.nodes.NodeInfo; -import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200429.network.nodes.NodeInfo.OpenroadmVersion; -import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev181019.NodeTypes; -import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.Link1; -import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.TerminationPoint1; -import org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.OtnLinkType; +import org.opendaylight.transportpce.networkmodel.util.TopologyUtils; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.TopologyUpdateResult; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.TopologyUpdateResultBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.topology.update.result.TopologyChanges; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.topology.update.result.TopologyChangesBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.topology.update.result.TopologyChangesKey; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkutils.rev220630.OtnLinkType; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev231221.OpenroadmNodeVersion; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev231221.mapping.Mapping; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev231221.network.nodes.NodeInfo; +import org.opendaylight.yang.gen.v1.http.org.openroadm.device.types.rev191129.NodeTypes; +import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev230526.Link1; +import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev230526.TerminationPoint1; +import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev220926.link.tp.LinkTp; +import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev220926.link.tp.LinkTpBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NetworkId; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.Networks; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId; @@ -50,39 +64,46 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.top import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.LinkKey; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPoint; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.termination.point.SupportingTerminationPoint; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev240120.ConnectionOper.ConnectionStatus; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.Uint32; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - +@Component(immediate = true) public class NetworkModelServiceImpl implements NetworkModelService { private static final Logger LOG = LoggerFactory.getLogger(NetworkModelServiceImpl.class); - private static final boolean CREATE_MISSING_PARENTS = true; private NetworkTransactionService networkTransactionService; private final R2RLinkDiscovery linkDiscovery; private final PortMapping portMapping; private Map topologyShardMountedDevice; private Map otnTopologyShardMountedDevice; - - public NetworkModelServiceImpl(final NetworkTransactionService networkTransactionService, - final R2RLinkDiscovery linkDiscovery, PortMapping portMapping) { + // Variables for creating and sending topology update notification + private final NotificationPublishService notificationPublishService; + private Map topologyChanges; + private TopologyUpdateResult notification = null; + + @Activate + public NetworkModelServiceImpl(@Reference DataBroker dataBroker, + @Reference DeviceTransactionManager deviceTransactionManager, + @Reference final NetworkTransactionService networkTransactionService, + @Reference PortMapping portMapping, + @Reference final NotificationPublishService notificationPublishService) { this.networkTransactionService = networkTransactionService; - this.linkDiscovery = linkDiscovery; + this.linkDiscovery = new R2RLinkDiscovery(dataBroker, deviceTransactionManager, networkTransactionService); this.portMapping = portMapping; this.topologyShardMountedDevice = new HashMap(); this.otnTopologyShardMountedDevice = new HashMap(); - } - - public void init() { - LOG.info("init ..."); - } - - public void close() { + this.notificationPublishService = notificationPublishService; + this.topologyChanges = new HashMap(); + LOG.debug("NetworkModelServiceImpl instantiated"); } @Override @@ -90,14 +111,19 @@ public class NetworkModelServiceImpl implements NetworkModelService { try { LOG.info("createOpenROADMNode: {} ", nodeId); + boolean firstMount; + if (portMapping.getNode(nodeId) == null) { + firstMount = true; + } else { + LOG.info("{} already exists in portmapping but was reconnected", nodeId); + firstMount = false; + } + if (!portMapping.createMappingData(nodeId, openRoadmVersion)) { LOG.warn("Could not generate port mapping for {} skipping network model creation", nodeId); return; } NodeInfo nodeInfo = portMapping.getNode(nodeId).getNodeInfo(); - if (nodeInfo.getNodeType().getIntValue() == 1) { - this.linkDiscovery.readLLDP(new NodeId(nodeId), openRoadmVersion); - } // node creation in clli-network Node clliNode = ClliNetwork.createNode(nodeId, nodeInfo); InstanceIdentifier iiClliNode = InstanceIdentifier.builder(Networks.class) @@ -105,8 +131,7 @@ public class NetworkModelServiceImpl implements NetworkModelService { .child(Node.class, clliNode.key()) .build(); LOG.info("creating node in {}", NetworkUtils.CLLI_NETWORK_ID); - networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiClliNode, clliNode, - CREATE_MISSING_PARENTS); + networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiClliNode, clliNode); // node creation in openroadm-network Node openroadmNetworkNode = OpenRoadmNetwork.createNode(nodeId, nodeInfo); @@ -116,10 +141,11 @@ public class NetworkModelServiceImpl implements NetworkModelService { .build(); LOG.info("creating node in {}", NetworkUtils.UNDERLAY_NETWORK_ID); networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiopenroadmNetworkNode, - openroadmNetworkNode, CREATE_MISSING_PARENTS); + openroadmNetworkNode); // nodes/links creation in openroadm-topology - TopologyShard topologyShard = OpenRoadmTopology.createTopologyShard(portMapping.getNode(nodeId)); + TopologyShard topologyShard = OpenRoadmTopology.createTopologyShard(portMapping.getNode(nodeId), + firstMount); if (topologyShard != null) { this.topologyShardMountedDevice.put(nodeId, topologyShard); for (Node openRoadmTopologyNode : topologyShard.getNodes()) { @@ -130,7 +156,7 @@ public class NetworkModelServiceImpl implements NetworkModelService { .child(Node.class, openRoadmTopologyNode.key()) .build(); networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyNode, - openRoadmTopologyNode, CREATE_MISSING_PARENTS); + openRoadmTopologyNode); } for (Link openRoadmTopologyLink : topologyShard.getLinks()) { LOG.info("creating link {} in {}", openRoadmTopologyLink.getLinkId().getValue(), @@ -141,17 +167,20 @@ public class NetworkModelServiceImpl implements NetworkModelService { .child(Link.class, openRoadmTopologyLink.key()) .build(); networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyLink, - openRoadmTopologyLink, CREATE_MISSING_PARENTS); + openRoadmTopologyLink); } } else { LOG.error("Unable to create openroadm-topology shard for node {}!", nodeId); } - // nodes/links creation in otn-topology if (nodeInfo.getNodeType().getIntValue() == 2 && (nodeInfo.getOpenroadmVersion().getIntValue() != 1)) { createOpenRoadmOtnNode(nodeId); } networkTransactionService.commit().get(); + // neighbour links through LLDP + if (nodeInfo.getNodeType().getIntValue() == 1) { + this.linkDiscovery.readLLDP(new NodeId(nodeId), openRoadmVersion); + } LOG.info("all nodes and links created"); } catch (InterruptedException | ExecutionException e) { LOG.error("ERROR: ", e); @@ -159,7 +188,7 @@ public class NetworkModelServiceImpl implements NetworkModelService { } @Override - public void setOpenRoadmNodeStatus(String nodeId, NetconfNodeConnectionStatus.ConnectionStatus connectionStatus) { + public void setOpenRoadmNodeStatus(String nodeId, ConnectionStatus connectionStatus) { LOG.info("setOpenROADMNodeStatus: {} {}", nodeId, connectionStatus.name()); /* TODO: set connection status of the device in model, @@ -174,8 +203,11 @@ public class NetworkModelServiceImpl implements NetworkModelService { */ @Override - public void deleteOpenRoadmnode(String nodeId) { + public boolean deleteOpenRoadmnode(String nodeId) { try { + if (!this.portMapping.isNodeExist(nodeId)) { + return false; + } NodeKey nodeIdKey = new NodeKey(new NodeId(nodeId)); LOG.info("deleting node in {}", NetworkUtils.UNDERLAY_NETWORK_ID); @@ -210,7 +242,7 @@ public class NetworkModelServiceImpl implements NetworkModelService { LOG.warn("TopologyShard for node '{}' is not present", nodeId); } @Nullable - OpenroadmVersion deviceVersion = this.portMapping.getNode(nodeId).getNodeInfo().getOpenroadmVersion(); + OpenroadmNodeVersion deviceVersion = this.portMapping.getNode(nodeId).getNodeInfo().getOpenroadmVersion(); @Nullable NodeTypes nodeType = this.portMapping.getNode(nodeId).getNodeInfo().getNodeType(); if (nodeType.getIntValue() == 2 && deviceVersion.getIntValue() != 1) { @@ -240,32 +272,165 @@ public class NetworkModelServiceImpl implements NetworkModelService { } LOG.info("deleteOpenROADMnode: {} version {}", nodeId, deviceVersion.getName()); - this.portMapping.deleteMappingData(nodeId); + this.portMapping.deletePortMappingNode(nodeId); this.networkTransactionService.commit().get(1, TimeUnit.SECONDS); LOG.info("all nodes and links deleted ! "); } catch (InterruptedException | ExecutionException | TimeoutException e) { LOG.error("Error when trying to delete node : {}", nodeId, e); + return false; + } + return true; + } + + @Override + public void updateOpenRoadmTopologies(String nodeId, Mapping mapping) { + LOG.info("update OpenRoadm topologies after change update from: {} ", nodeId); + this.topologyChanges.clear(); + Network openroadmTopology = null; + Network otnTopology = null; + Map openroadmTopologyLinks = null; + Map otnTopologyLinks = null; + try { + openroadmTopology = this.networkTransactionService + .read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifiers.OVERLAY_NETWORK_II) + .get().orElseThrow(); + if (openroadmTopology.augmentation(Network1.class) != null) { + openroadmTopologyLinks = openroadmTopology.augmentation(Network1.class).getLink(); + } + otnTopology = this.networkTransactionService + .read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifiers.OTN_NETWORK_II) + .get().orElseThrow(); + if (otnTopology.augmentation(Network1.class) != null) { + otnTopologyLinks = otnTopology.augmentation(Network1.class).getLink(); + } + } catch (InterruptedException | ExecutionException e) { + LOG.error("Error when trying to update node : {}", nodeId, e); + } + if (openroadmTopology == null || otnTopology == null) { + LOG.warn("Error getting topologies from datastore"); + return; + } + String abstractNodeid = String.join("-", nodeId, mapping.getLogicalConnectionPoint().split("-")[0]); + // nodes/links update in openroadm-topology + if (openroadmTopology.getNode() != null) { + TopologyShard topologyShard = TopologyUtils.updateTopologyShard(abstractNodeid, mapping, + openroadmTopology.getNode(), openroadmTopologyLinks); + if (topologyShard.getLinks() != null) { + for (Link link : topologyShard.getLinks()) { + LOG.info("updating links {} in {}", link.getLinkId().getValue(), + NetworkUtils.OVERLAY_NETWORK_ID); + InstanceIdentifier iiTopologyLink = InstanceIdentifier.builder(Networks.class) + .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID))) + .augmentation(Network1.class) + .child(Link.class, link.key()) + .build(); + networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyLink, link); + } + } + if (topologyShard.getTps() != null) { + for (TerminationPoint tp : topologyShard.getTps()) { + LOG.info("updating TP {} in openroadm-topology", tp.getTpId().getValue()); + InstanceIdentifier iiTopologyTp = InstanceIdentifier.builder(Networks.class) + .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID))) + .child(Node.class, new NodeKey(new NodeId(abstractNodeid))) + .augmentation(Node1.class) + .child(TerminationPoint.class, new TerminationPointKey(tp.getTpId())) + .build(); + networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyTp, tp); + TopologyChanges tc = new TopologyChangesBuilder() + .withKey(new TopologyChangesKey(abstractNodeid, tp.getTpId().getValue())) + .setNodeId(abstractNodeid) + .setTpId(tp.getTpId().getValue()) + .setState(tp.augmentation( + org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev230526.TerminationPoint1 + .class).getOperationalState()) + .build(); + if (!this.topologyChanges.containsKey(tc.key())) { + this.topologyChanges.put(tc.key(), tc); + } + } + } + } + // nodes/links update in otn-topology + if (otnTopology.getNode() != null + && otnTopology.getNode().containsKey(new NodeKey(new NodeId(abstractNodeid)))) { + TopologyShard otnShard = TopologyUtils.updateTopologyShard(abstractNodeid, mapping, + otnTopology.getNode(), otnTopologyLinks); + if (otnShard.getLinks() != null) { + for (Link link : otnShard.getLinks()) { + LOG.info("updating links {} in {}", link.getLinkId().getValue(), + NetworkUtils.OVERLAY_NETWORK_ID); + InstanceIdentifier iiTopologyLink = InstanceIdentifier.builder(Networks.class) + .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID))) + .augmentation(Network1.class) + .child(Link.class, link.key()) + .build(); + networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyLink, link); + } + } + if (otnShard.getTps() != null) { + for (TerminationPoint tp : otnShard.getTps()) { + LOG.info("updating TP {} in otn-topology", tp.getTpId().getValue()); + InstanceIdentifier iiTopologyTp = InstanceIdentifier.builder(Networks.class) + .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID))) + .child(Node.class, new NodeKey(new NodeId(abstractNodeid))) + .augmentation(Node1.class) + .child(TerminationPoint.class, new TerminationPointKey(tp.getTpId())) + .build(); + networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyTp, tp); + TopologyChanges tc = new TopologyChangesBuilder() + .withKey(new TopologyChangesKey(abstractNodeid, tp.getTpId().getValue())) + .setNodeId(abstractNodeid) + .setTpId(tp.getTpId().getValue()) + .setState(tp.augmentation( + org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev230526.TerminationPoint1 + .class).getOperationalState()) + .build(); + if (!this.topologyChanges.containsKey(tc.key())) { + this.topologyChanges.put(tc.key(), tc); + } + } + } + } + // commit datastore updates + try { + networkTransactionService.commit().get(); + sendNotification(); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Error updating openroadm-topology", e); } } @Override - public void createOtnLinks(String nodeA, String tpA, String nodeZ, String tpZ, OtnLinkType linkType) { + public void createOtnLinks( + org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.renderer.rpc.result.sp.Link + notifLink, List suppLinks, OtnLinkType linkType) { + TopologyShard otnTopologyShard; switch (linkType) { case OTU4: - otnTopologyShard = OpenRoadmOtnTopology.createOtnLinks(nodeA, tpA, nodeZ, tpZ, linkType); + case OTUC2: + case OTUC3: + case OTUC4: + otnTopologyShard = OpenRoadmOtnTopology.createOtnLinks(notifLink, null, null, linkType); break; case ODTU4: - String nodeTopoA = new StringBuilder(nodeA).append("-").append(tpA.split("-")[0]).toString(); - String nodeTopoZ = new StringBuilder(nodeZ).append("-").append(tpZ.split("-")[0]).toString(); + case ODUC2: + case ODUC3: + case ODUC4: List linkIdList = new ArrayList<>(); - linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, "OTU4")); - linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, "OTU4")); + if (suppLinks != null) { + suppLinks.forEach(lk -> linkIdList.add(new LinkId(lk))); + } List supportedOtu4links = getOtnLinks(linkIdList); - List tps = getOtnNodeTps(nodeTopoA, tpA, nodeTopoZ, tpZ); - - otnTopologyShard = OpenRoadmOtnTopology.createOtnLinks(supportedOtu4links, tps); + String nodeTopoA = convertNetconfNodeIdToTopoNodeId(notifLink.getATermination().getNodeId(), + notifLink.getATermination().getTpId()); + String nodeTopoZ = convertNetconfNodeIdToTopoNodeId(notifLink.getZTermination().getNodeId(), + notifLink.getZTermination().getTpId()); + List tps = getOtnNodeTps(nodeTopoA, notifLink.getATermination().getTpId(), nodeTopoZ, + notifLink.getZTermination().getTpId()); + otnTopologyShard = OpenRoadmOtnTopology.createOtnLinks(notifLink, supportedOtu4links, tps, linkType); break; default: LOG.error("unknown otn link type {}", linkType); @@ -280,16 +445,17 @@ public class NetworkModelServiceImpl implements NetworkModelService { .augmentation(Network1.class) .child(Link.class, otnTopologyLink.key()) .build(); - networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, - otnTopologyLink, CREATE_MISSING_PARENTS); + networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink); } } if (otnTopologyShard.getTps() != null) { for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) { LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue()); + List supportingTerminationPoint = + new ArrayList<>(otnTopologyTp.nonnullSupportingTerminationPoint().values()); InstanceIdentifier iiOtnTopologyTp = InstanceIdentifier.builder(Networks.class) .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID))) - .child(Node.class, new NodeKey(otnTopologyTp.getSupportingTerminationPoint().get(0).getNodeRef())) + .child(Node.class, new NodeKey(supportingTerminationPoint.get(0).getNodeRef())) .augmentation(Node1.class) .child(TerminationPoint.class, new TerminationPointKey(otnTopologyTp.getTpId())) .build(); @@ -305,36 +471,51 @@ public class NetworkModelServiceImpl implements NetworkModelService { } @Override - public void deleteOtnLinks(String nodeA, String tpA, String nodeZ, String tpZ, OtnLinkType linkType) { + public void deleteOtnLinks( + org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.renderer.rpc.result.sp.Link + notifLink, List suppLinks, OtnLinkType linkType) { + TopologyShard otnTopologyShard; - String nodeTopoA = new StringBuilder(nodeA).append("-").append(tpA.split("-")[0]).toString(); - String nodeTopoZ = new StringBuilder(nodeZ).append("-").append(tpZ.split("-")[0]).toString(); - List otu4Links; + String nodeTopoA = convertNetconfNodeIdToTopoNodeId(notifLink.getATermination().getNodeId(), + notifLink.getATermination().getTpId()); + String nodeTopoZ = convertNetconfNodeIdToTopoNodeId(notifLink.getZTermination().getNodeId(), + notifLink.getZTermination().getTpId()); + String tpA = notifLink.getATermination().getTpId(); + String tpZ = notifLink.getZTermination().getTpId(); + List otuLinks; List linkIdList = new ArrayList<>(); switch (linkType) { case OTU4: - linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, "OTU4")); - linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, "OTU4")); - otu4Links = getOtnLinks(linkIdList); - if (checkLinks(otu4Links)) { - deleteLinks(otu4Links); + case OTUC2: + case OTUC3: + case OTUC4: + linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, linkType.getName())); + linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, linkType.getName())); + otuLinks = getOtnLinks(linkIdList); + if (checkLinks(otuLinks)) { + deleteLinks(otuLinks); } else { LOG.error("Error deleting OTU4 links"); } otnTopologyShard = new TopologyShard(null, null); break; case ODTU4: - linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, "ODU4")); - linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, "ODU4")); - List odu4Links = getOtnLinks(linkIdList); + case ODUC2: + case ODUC3: + case ODUC4: + linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, linkType.getName())); + linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, linkType.getName())); + List oduLinks = getOtnLinks(linkIdList); List tps = getOtnNodeTps(nodeTopoA, tpA, nodeTopoZ, tpZ); - if (checkLinks(odu4Links) && checkTerminationPoints(tps)) { - deleteLinks(odu4Links); + if (checkLinks(oduLinks) && checkTerminationPoints(tps)) { + deleteLinks(oduLinks); linkIdList.clear(); - linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, "OTU4")); - linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, "OTU4")); - otu4Links = getOtnLinks(linkIdList); - otnTopologyShard = OpenRoadmOtnTopology.deleteOtnLinks(otu4Links, tps); + if (suppLinks != null) { + suppLinks.forEach(lk -> linkIdList.add(new LinkId(lk))); + } + otuLinks = getOtnLinks(linkIdList); + + otnTopologyShard = OpenRoadmOtnTopology.deleteOtnLinks(otuLinks, tps, linkType); } else { LOG.error("Error deleting ODU4 links"); otnTopologyShard = new TopologyShard(null, null); @@ -344,6 +525,7 @@ public class NetworkModelServiceImpl implements NetworkModelService { LOG.error("unknown otn link type {}", linkType); otnTopologyShard = new TopologyShard(null, null); } + if (otnTopologyShard.getLinks() != null) { for (Link otnTopologyLink : otnTopologyShard.getLinks()) { LOG.info("deleting and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(), @@ -353,16 +535,17 @@ public class NetworkModelServiceImpl implements NetworkModelService { .augmentation(Network1.class) .child(Link.class, otnTopologyLink.key()) .build(); - networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink, - CREATE_MISSING_PARENTS); + networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink); } } if (otnTopologyShard.getTps() != null) { for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) { LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue()); + List supportingTerminationPoint = + new ArrayList<>(otnTopologyTp.nonnullSupportingTerminationPoint().values()); InstanceIdentifier iiOtnTopologyTp = InstanceIdentifier.builder(Networks.class) .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID))) - .child(Node.class, new NodeKey(otnTopologyTp.getSupportingTerminationPoint().get(0).getNodeRef())) + .child(Node.class, new NodeKey(supportingTerminationPoint.get(0).getNodeRef())) .augmentation(Node1.class) .child(TerminationPoint.class, new TerminationPointKey(otnTopologyTp.getTpId())) .build(); @@ -378,13 +561,48 @@ public class NetworkModelServiceImpl implements NetworkModelService { } @Override - public void updateOtnLinks(List nodeTps, String serviceRate, Short tribPortNb, Short tribSoltNb, - boolean isDeletion) { - List supportedOdu4Links = getSupportingOdu4Links(nodeTps); - List tps = getOtnNodeTps(nodeTps); + public void updateOtnLinks( + org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.renderer.rpc.result.sp.Link + notifLink, List suppLinks, Uint32 serviceRate, Short tribPortNb, Short minTribSoltNb, + Short maxTribSlotNb, boolean isDeletion) { + + List linkTerminations = new ArrayList<>(); + List supportedOdu4Links = null; + if (notifLink != null) { + // retreive termination-points to be updated + linkTerminations.add(new LinkTpBuilder() + .setNodeId(notifLink.getATermination().getNodeId()) + .setTpId(notifLink.getATermination().getTpId()) + .build()); + linkTerminations.add(new LinkTpBuilder() + .setNodeId(notifLink.getZTermination().getNodeId()) + .setTpId(notifLink.getZTermination().getTpId()) + .build()); + // retreive supported links + supportedOdu4Links = getSupportingOdu4Links(linkTerminations, serviceRate); + } else if (suppLinks != null) { + // retreive supported links + List linkIdList = new ArrayList<>(); + if (suppLinks != null) { + suppLinks.forEach(lk -> linkIdList.add(new LinkId(lk))); + } + supportedOdu4Links = getOtnLinks(linkIdList); + // retreive termination-points to be updated + for (Link link : supportedOdu4Links) { + LinkTp atermination = new LinkTpBuilder() + .setNodeId(link.getSource().getSourceNode().getValue()) + .setTpId(link.getSource().getSourceTp().getValue()) + .build(); + linkTerminations.add(atermination); + } + } else { + LOG.error("Impossible to update OTN links and their associated termination points in otn-topology"); + return; + } + List tps = getOtnNodeTps(linkTerminations); TopologyShard otnTopologyShard; otnTopologyShard = OpenRoadmOtnTopology.updateOtnLinks(supportedOdu4Links, tps, serviceRate, tribPortNb, - tribSoltNb, isDeletion); + minTribSoltNb, maxTribSlotNb, isDeletion); if (otnTopologyShard.getLinks() != null) { for (Link otnTopologyLink : otnTopologyShard.getLinks()) { LOG.info("creating and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(), @@ -394,19 +612,20 @@ public class NetworkModelServiceImpl implements NetworkModelService { .augmentation(Network1.class) .child(Link.class, new LinkKey(new LinkId(otnTopologyLink.getLinkId().getValue()))) .build(); - networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, - otnTopologyLink, CREATE_MISSING_PARENTS); + networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink); } } if (otnTopologyShard.getTps() != null) { for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) { LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue()); + List supportingTerminationPoint = + new ArrayList<>(otnTopologyTp.nonnullSupportingTerminationPoint().values()); InstanceIdentifier iiOtnTopologyTp = InstanceIdentifier.builder(Networks.class) .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID))) - .child(Node.class, new NodeKey(otnTopologyTp.getSupportingTerminationPoint().get(0).getNodeRef())) + .child(Node.class, new NodeKey(supportingTerminationPoint.get(0).getNodeRef())) .augmentation(Node1.class) - .child(TerminationPoint.class, new TerminationPointKey( - new TpId(otnTopologyTp.getTpId().getValue()))) + .child(TerminationPoint.class, new TerminationPointKey(new TpId(otnTopologyTp.getTpId() + .getValue()))) .build(); if (isDeletion) { networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp); @@ -422,6 +641,35 @@ public class NetworkModelServiceImpl implements NetworkModelService { } } + @Override + public void updateOtnLinks(List suppLinks, boolean isDeletion) { + List linkIdList = new ArrayList<>(); + if (suppLinks != null) { + suppLinks.forEach(lk -> linkIdList.add(new LinkId(lk))); + } + List supportedOtu4links = getOtnLinks(linkIdList); + + TopologyShard otnTopologyShard = OpenRoadmOtnTopology.updateOtnLinks(supportedOtu4links, isDeletion); + if (otnTopologyShard.getLinks() != null) { + for (Link otnTopologyLink : otnTopologyShard.getLinks()) { + LOG.info("creating and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(), + NetworkUtils.OVERLAY_NETWORK_ID); + InstanceIdentifier iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class) + .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID))) + .augmentation(Network1.class) + .child(Link.class, otnTopologyLink.key()) + .build(); + networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink); + } + } + try { + networkTransactionService.commit().get(); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Error adding OTN links in otn-topology", e); + } + LOG.info("OTN links updated"); + } + private List getOtnLinks(List linkIds) { List links = new ArrayList<>(); for (LinkId linkId : linkIds) { @@ -435,7 +683,7 @@ public class NetworkModelServiceImpl implements NetworkModelService { if (linkOptLf.isDone()) { try { if (linkOptLf.get().isPresent()) { - links.add(linkOptLf.get().get()); + links.add(linkOptLf.get().orElseThrow()); } } catch (InterruptedException | ExecutionException e) { LOG.error("Error retreiving OTN links from otn-topology", e); @@ -448,35 +696,30 @@ public class NetworkModelServiceImpl implements NetworkModelService { } private boolean checkLinks(List links) { - boolean canBeDeleted = true; if (links.isEmpty()) { return false; - } else { - for (Link link : links) { - if (link.augmentation(Link1.class) != null + } + for (Link link : links) { + if (link.augmentation(Link1.class) != null && !link.augmentation(Link1.class).getUsedBandwidth().equals(Uint32.valueOf(0))) { - canBeDeleted = false; - } + return false; } } - return canBeDeleted; + return true; } private boolean checkTerminationPoints(List tps) { - boolean canBeDeleted = true; if (tps.isEmpty()) { return false; - } else { - for (TerminationPoint tp : tps) { - if (tp.augmentation(TerminationPoint1.class) != null - && tp.augmentation(TerminationPoint1.class).getXpdrTpPortConnectionAttributes().getTsPool() != null - && tp.augmentation(TerminationPoint1.class).getXpdrTpPortConnectionAttributes().getTsPool() - .size() != 80) { - canBeDeleted = false; - } + } + for (TerminationPoint tp : tps) { + if (tp.augmentation(TerminationPoint1.class) != null && tp.augmentation(TerminationPoint1.class) + .getXpdrTpPortConnectionAttributes().getTsPool() != null && tp.augmentation(TerminationPoint1.class) + .getXpdrTpPortConnectionAttributes().getTsPool().size() != 80) { + return false; } } - return canBeDeleted; + return true; } private List getOtnNodeTps(String nodeTopoA, String tpA, String nodeTopoZ, String tpZ) { @@ -497,7 +740,7 @@ public class NetworkModelServiceImpl implements NetworkModelService { Optional tpZOpt = Optional.empty(); if (networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpA).isDone() - && networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpZ).isDone()) { + && networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpZ).isDone()) { try { tpAOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpA).get(); tpZOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpZ).get(); @@ -510,17 +753,17 @@ public class NetworkModelServiceImpl implements NetworkModelService { } if (tpAOpt.isPresent() && tpZOpt.isPresent()) { - tps.add(tpAOpt.get()); - tps.add(tpZOpt.get()); + tps.add(tpAOpt.orElseThrow()); + tps.add(tpZOpt.orElseThrow()); } return tps; } - private List getOtnNodeTps(List nodeTopoTps) { + private List getOtnNodeTps(List linkTerminations) { List tps = new ArrayList<>(); - for (String str : nodeTopoTps) { - String nodeId = str.split("--")[0]; - String tp = str.split("--")[1]; + for (LinkTp linkTp : linkTerminations) { + String tp = linkTp.getTpId(); + String nodeId = formatNodeName(linkTp.getNodeId(), tp); InstanceIdentifier iiTp = InstanceIdentifier.builder(Networks.class) .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID))) .child(Node.class, new NodeKey(new NodeId(nodeId))) @@ -532,7 +775,7 @@ public class NetworkModelServiceImpl implements NetworkModelService { try { tpOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTp).get(); if (tpOpt.isPresent()) { - tps.add(tpOpt.get()); + tps.add(tpOpt.orElseThrow()); } } catch (InterruptedException | ExecutionException e) { LOG.error("Error retreiving tp {} of node {} from otn-topology", tp, nodeId, e); @@ -541,19 +784,13 @@ public class NetworkModelServiceImpl implements NetworkModelService { LOG.error("error getting node termination points from the datastore"); } } - if (tps.isEmpty()) { - LOG.warn("returning null"); - return null; - } else { - LOG.info("returning tps = {}", tps.toString()); - return tps; - } + return tps; } private void deleteLinks(List links) { for (Link otnTopologyLink : links) { LOG.info("deleting link {} from {}", otnTopologyLink.getLinkId().getValue(), - NetworkUtils.OVERLAY_NETWORK_ID); + NetworkUtils.OTN_NETWORK_ID); InstanceIdentifier iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class) .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID))) .augmentation(Network1.class) @@ -568,7 +805,7 @@ public class NetworkModelServiceImpl implements NetworkModelService { } } - private List getSupportingOdu4Links(List nodesTopoTps) { + private List getSupportingOdu4Links(List nodesTopoTps, Uint32 serviceRate) { InstanceIdentifier iiOtnTopologyLinks = InstanceIdentifier.builder(Networks.class) .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID))) .augmentation(Network1.class) @@ -584,36 +821,35 @@ public class NetworkModelServiceImpl implements NetworkModelService { } } List odu4links = null; - if (netw1Opt.isPresent() && netw1Opt.get().getLink() != null) { - odu4links = netw1Opt.get().getLink().stream().filter(lk -> lk.getLinkId().getValue().startsWith("ODU4")) + if (netw1Opt.isPresent() && netw1Opt.orElseThrow().getLink() != null) { + odu4links = netw1Opt + .orElseThrow() + .nonnullLink().values() + .stream().filter(lk -> lk.getLinkId().getValue() + .startsWith(Uint32.valueOf(100).equals(serviceRate) ? "ODUC4" : "ODTU4")) .collect(Collectors.toList()); } + if (odu4links == null) { + return null; + } List links = new ArrayList<>(); - if (odu4links != null) { - for (String str : nodesTopoTps) { - String[] nodeAndTp = str.split("--"); - if (nodeAndTp.length >= 2) { - String nodeId = nodeAndTp[0]; - String tp = nodeAndTp[1]; - Link slink = odu4links.stream().filter(lk -> lk.getSource().getSourceNode().getValue() - .equals(nodeId) && lk.getSource().getSourceTp().toString().equals(tp)) - .findFirst().get(); - if (!links.contains(slink)) { - links.add(slink); - } - Link dlink = odu4links.stream().filter(lk -> lk.getDestination().getDestNode().getValue() - .equals(nodeId) && lk.getDestination().getDestTp().toString().equals(tp)) - .findFirst().get(); - if (!links.contains(dlink)) { - links.add(dlink); - } - } + for (LinkTp linkTp : nodesTopoTps) { + String tp = linkTp.getTpId(); + String nodeId = new StringBuilder(linkTp.getNodeId()).append("-") + .append(tp.split("-")[0]).toString(); + Link slink = odu4links.stream().filter(lk -> lk.getSource().getSourceNode().getValue() + .equals(nodeId) && lk.getSource().getSourceTp().getValue().equals(tp)).findFirst().orElseThrow(); + if (!links.contains(slink)) { + links.add(slink); + } + Link dlink = odu4links.stream().filter(lk -> lk.getDestination().getDestNode().getValue() + .equals(nodeId) && lk.getDestination().getDestTp().getValue().equals(tp)).findFirst().orElseThrow(); + if (!links.contains(dlink)) { + links.add(dlink); } - LOG.debug("odu4links = {}", links.toString()); - return links; - } else { - return null; } + LOG.debug("odu4oduC4links = {}", links); + return links; } private void createOpenRoadmOtnNode(String nodeId) { @@ -627,8 +863,7 @@ public class NetworkModelServiceImpl implements NetworkModelService { .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID))) .child(Node.class, otnTopologyNode.key()) .build(); - networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyNode, - otnTopologyNode); + networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyNode, otnTopologyNode); } for (Link otnTopologyLink : otnTopologyShard.getLinks()) { LOG.info("creating otn link {} in {}", otnTopologyLink.getLinkId().getValue(), @@ -638,12 +873,38 @@ public class NetworkModelServiceImpl implements NetworkModelService { .augmentation(Network1.class) .child(Link.class, otnTopologyLink.key()) .build(); - networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, - otnTopologyLink, CREATE_MISSING_PARENTS); + networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink); } } else { LOG.error("Unable to create OTN topology shard for node {}!", nodeId); } + } + + private String convertNetconfNodeIdToTopoNodeId(String nodeId, String tpId) { + return new StringBuilder(nodeId).append("-").append(tpId.split("-")[0]).toString(); + } + + private static String formatNodeName(String nodeName, String tpName) { + return nodeName.contains("-XPDR") + ? nodeName + : new StringBuilder(nodeName).append("-").append(tpName.split("-")[0]).toString(); + } + @SuppressFBWarnings( + value = "UPM_UNCALLED_PRIVATE_METHOD", + justification = "false positive, this method is used by public updateOpenRoadmNetworkTopology") + private void sendNotification() { + if (topologyChanges.isEmpty()) { + LOG.warn("Empty Topology Change List. No updates in topology"); + return; + } + this.notification = new TopologyUpdateResultBuilder() + .setTopologyChanges(topologyChanges) + .build(); + try { + notificationPublishService.putNotification(this.notification); + } catch (InterruptedException e) { + LOG.error("Notification offer rejected. Error={}", e.getMessage()); + } } }