From 6c92e0a3ac4966ee7639118462e5769f9f6a59b6 Mon Sep 17 00:00:00 2001 From: Gilles Thouenon Date: Thu, 2 Apr 2020 09:53:30 +0200 Subject: [PATCH] Update otn-topology with otn-links Adds and implements new methods in NetworkModelService and OpenRoadmOtnTopology to create, update and delete otn links. These methods are intended to be used by renderer module after otn interfaces and odu connections have been correctly configured in otn devices. JIRA: TRNSPRTPCE-199 Signed-off-by: Gilles Thouenon Change-Id: Ieba5a6491b4fe0c8617e63a816254c26b051640f --- .../transportpce/networkmodel/OrdLink.java | 2 +- .../networkmodel/Rdm2XpdrLink.java | 2 +- .../networkmodel/dto/TopologyShard.java | 13 + .../service/NetworkModelService.java | 59 ++- .../service/NetworkModelServiceImpl.java | 476 ++++++++++++++++-- .../networkmodel/util/LinkIdUtil.java | 16 + .../util/OpenRoadmOtnTopology.java | 279 +++++++++- .../networkmodel/util/TopologyUtils.java | 25 +- 8 files changed, 793 insertions(+), 79 deletions(-) diff --git a/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/OrdLink.java b/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/OrdLink.java index 779699124..5a6eb2c3c 100644 --- a/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/OrdLink.java +++ b/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/OrdLink.java @@ -58,7 +58,7 @@ final class OrdLink { String destTp = input.getTerminationPointZ(); //IETF link builder - LinkBuilder linkBuilder = TopologyUtils.createLink(srcNode, destNode, srcTp, destTp); + LinkBuilder linkBuilder = TopologyUtils.createLink(srcNode, destNode, srcTp, destTp, null); linkBuilder.addAugmentation(Link1.class,link1Builder.build()); linkBuilder.addAugmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130 diff --git a/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/Rdm2XpdrLink.java b/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/Rdm2XpdrLink.java index d3a26f50f..3b8811cb8 100644 --- a/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/Rdm2XpdrLink.java +++ b/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/Rdm2XpdrLink.java @@ -145,7 +145,7 @@ final class Rdm2XpdrLink { = new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Link1Builder() .setLinkType(isXponderInput ? OpenroadmLinkType.XPONDERINPUT : OpenroadmLinkType.XPONDEROUTPUT) .setOppositeLink(LinkIdUtil.getOppositeLinkId(srcNode, srcTp, destNode, destTp)); - LinkBuilder linkBuilder = TopologyUtils.createLink(srcNode, destNode, srcTp, destTp) + LinkBuilder linkBuilder = TopologyUtils.createLink(srcNode, destNode, srcTp, destTp, null) .addAugmentation(Link1.class, lnk1bldr.build()) .addAugmentation( org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Link1.class, diff --git a/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/dto/TopologyShard.java b/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/dto/TopologyShard.java index b31c7a55f..5a75412c5 100644 --- a/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/dto/TopologyShard.java +++ b/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/dto/TopologyShard.java @@ -11,6 +11,7 @@ import java.util.List; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPoint; /** * Data holder for topology fragment. @@ -19,10 +20,18 @@ public class TopologyShard { private final List nodes; private final List links; + private final List tps; public TopologyShard(List nodes, List links) { this.nodes = nodes; this.links = links; + this.tps = null; + } + + public TopologyShard(List nodes, List links, List tps) { + this.nodes = nodes; + this.links = links; + this.tps = tps; } public List getNodes() { @@ -33,4 +42,8 @@ public class TopologyShard { return links; } + public List getTps() { + return tps; + } + } diff --git a/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/service/NetworkModelService.java b/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/service/NetworkModelService.java index a0b10c68f..3a02d7b71 100644 --- a/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/service/NetworkModelService.java +++ b/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/service/NetworkModelService.java @@ -7,6 +7,8 @@ */ package org.opendaylight.transportpce.networkmodel.service; +import java.util.List; +import org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.OtnLinkType; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus; /** @@ -14,9 +16,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev15 */ public interface NetworkModelService { - /** - * Create new OpenROADM node in all OpenROADM topologies. + * Create new OpenROADM node in all OpenROADM topologies. + * * @param nodeId * unique node ID of new OpenROADM node * @param nodeVersion @@ -27,7 +29,8 @@ public interface NetworkModelService { /** * Delete OpenROADM node mapping and topologies. * - * @param nodeId unique node ID of OpenROADM node. + * @param nodeId + * unique node ID of OpenROADM node. * */ void deleteOpenRoadmnode(String nodeId); @@ -42,4 +45,54 @@ public interface NetworkModelService { */ void setOpenRoadmNodeStatus(String nodeId, NetconfNodeConnectionStatus.ConnectionStatus connectionStatus); + /** + * create new otn link in otn-topology. + * + * @param nodeA + * OpenROADM node ID for link termination point A + * @param tpA + * OpenROADM tp id on nodeA for link termination point A + * @param nodeZ + * OpenROADM node ID for link termination point Z + * @param tpZ + * OpenROADM tp id on nodeZ for link termination point Z + * @param linkType + * OtnLinkType, as OTU4, ODTU, etc + */ + void createOtnLinks(String nodeA, String tpA, String nodeZ, String tpZ, OtnLinkType linkType); + + /** + * delete otn links from otn-topology. + * + * @param nodeA + * OpenROADM node ID for link termination point A + * @param tpA + * OpenROADM tp id on nodeA for link termination point A + * @param nodeZ + * OpenROADM node ID for link termination point Z + * @param tpZ + * OpenROADM tp id on nodeZ for link termination point Z + * @param linkType + * OtnLinkType, as OTU4, ODTU, etc + */ + void deleteOtnLinks(String nodeA, String tpA, String nodeZ, String tpZ, OtnLinkType linkType); + + /** + * update otn links from otn-topology. + * + * @param nodeTps + * List containing a string composed of the netconf nodeId , and the + * termination point supporting the service + * @param serviceRate + * Service rate may be 1G, 10G or 100G + * @param tribPortNb + * Trib port number allocated by the service + * @param tribSoltNb + * First trib slot number allocated by the service + * @param isDeletion + * True indicates if the low-order otn service must be deleted + */ + void updateOtnLinks(List nodeTps, String serviceRate, Short tribPortNb, Short tribSoltNb, + boolean isDeletion); + } 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 ebbd7e30d..cc9aaf72c 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 @@ -7,11 +7,17 @@ */ package org.opendaylight.transportpce.networkmodel.service; +import com.google.common.util.concurrent.ListenableFuture; + +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.concurrent.ExecutionException; 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.common.api.LogicalDatastoreType; import org.opendaylight.transportpce.common.NetworkUtils; @@ -20,12 +26,16 @@ import org.opendaylight.transportpce.common.network.NetworkTransactionService; import org.opendaylight.transportpce.networkmodel.R2RLinkDiscovery; import org.opendaylight.transportpce.networkmodel.dto.TopologyShard; import org.opendaylight.transportpce.networkmodel.util.ClliNetwork; +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.rev200128.network.nodes.NodeInfo; import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200128.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.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; @@ -33,13 +43,21 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.NetworkKey; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.NodeKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.LinkId; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Network1; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.TpId; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link; +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.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.Uint32; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + public class NetworkModelServiceImpl implements NetworkModelService { private static final Logger LOG = LoggerFactory.getLogger(NetworkModelServiceImpl.class); @@ -48,8 +66,8 @@ public class NetworkModelServiceImpl implements NetworkModelService { private NetworkTransactionService networkTransactionService; private final R2RLinkDiscovery linkDiscovery; private final PortMapping portMapping; - private HashMap topologyShardMountedDevice; - private HashMap otnTopologyShardMountedDevice; + private Map topologyShardMountedDevice; + private Map otnTopologyShardMountedDevice; public NetworkModelServiceImpl(final NetworkTransactionService networkTransactionService, final R2RLinkDiscovery linkDiscovery, PortMapping portMapping) { @@ -57,8 +75,8 @@ public class NetworkModelServiceImpl implements NetworkModelService { this.networkTransactionService = networkTransactionService; this.linkDiscovery = linkDiscovery; this.portMapping = portMapping; - this.topologyShardMountedDevice = new HashMap(); - this.otnTopologyShardMountedDevice = new HashMap(); + this.topologyShardMountedDevice = new HashMap(); + this.otnTopologyShardMountedDevice = new HashMap(); } public void init() { @@ -105,9 +123,9 @@ public class NetworkModelServiceImpl implements NetworkModelService { TopologyShard topologyShard = OpenRoadmTopology.createTopologyShard(portMapping.getNode(nodeId)); if (topologyShard != null) { this.topologyShardMountedDevice.put(nodeId, topologyShard); - for (Node openRoadmTopologyNode: topologyShard.getNodes()) { + for (Node openRoadmTopologyNode : topologyShard.getNodes()) { LOG.info("creating node {} in {}", openRoadmTopologyNode.getNodeId().getValue(), - NetworkUtils.OVERLAY_NETWORK_ID); + NetworkUtils.OVERLAY_NETWORK_ID); InstanceIdentifier iiOpenRoadmTopologyNode = InstanceIdentifier.builder(Networks.class) .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID))) .child(Node.class, openRoadmTopologyNode.key()) @@ -115,9 +133,9 @@ public class NetworkModelServiceImpl implements NetworkModelService { networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyNode, openRoadmTopologyNode, CREATE_MISSING_PARENTS); } - for (Link openRoadmTopologyLink: topologyShard.getLinks()) { + for (Link openRoadmTopologyLink : topologyShard.getLinks()) { LOG.info("creating link {} in {}", openRoadmTopologyLink.getLinkId().getValue(), - NetworkUtils.OVERLAY_NETWORK_ID); + NetworkUtils.OVERLAY_NETWORK_ID); InstanceIdentifier iiOpenRoadmTopologyLink = InstanceIdentifier.builder(Networks.class) .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID))) .augmentation(Network1.class) @@ -132,33 +150,7 @@ public class NetworkModelServiceImpl implements NetworkModelService { // nodes/links creation in otn-topology if (nodeInfo.getNodeType().getIntValue() == 2 && (nodeInfo.getOpenroadmVersion().getIntValue() != 1)) { - TopologyShard otnTopologyShard = OpenRoadmOtnTopology.createTopologyShard(portMapping.getNode(nodeId)); - if (otnTopologyShard != null) { - this.otnTopologyShardMountedDevice.put(nodeId, otnTopologyShard); - for (Node otnTopologyNode: otnTopologyShard.getNodes()) { - LOG.info("creating otn node {} in {}", otnTopologyNode.getNodeId().getValue(), - NetworkUtils.OTN_NETWORK_ID); - InstanceIdentifier iiOtnTopologyNode = InstanceIdentifier.builder(Networks.class) - .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID))) - .child(Node.class, otnTopologyNode.key()) - .build(); - networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyNode, - otnTopologyNode); - } - for (Link otnTopologyLink: otnTopologyShard.getLinks()) { - LOG.info("creating otn link {} 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, CREATE_MISSING_PARENTS); - } - } else { - LOG.error("Unable to create OTN topology shard for node {}!", nodeId); - } + createOpenRoadmOtnNode(nodeId); } networkTransactionService.commit().get(); LOG.info("all nodes and links created"); @@ -178,12 +170,10 @@ public class NetworkModelServiceImpl implements NetworkModelService { */ } - /* (non-Javadoc) - * @see org.opendaylight.transportpce.networkmodel.service.NetworkModelService#deleteOpenROADMnode(java.lang.String) + /* + @see org.opendaylight.transportpce.networkmodel.service.NetworkModelService# deleteOpenROADMnode(java.lang.String) */ - - @Override public void deleteOpenRoadmnode(String nodeId) { try { @@ -198,7 +188,7 @@ public class NetworkModelServiceImpl implements NetworkModelService { TopologyShard topologyShard = this.topologyShardMountedDevice.get(nodeId); if (topologyShard != null) { - for (Node openRoadmTopologyNode: topologyShard .getNodes()) { + for (Node openRoadmTopologyNode : topologyShard.getNodes()) { LOG.info("deleting node {} in {}", openRoadmTopologyNode.getNodeId().getValue(), NetworkUtils.OVERLAY_NETWORK_ID); InstanceIdentifier iiOpenRoadmTopologyNode = InstanceIdentifier.builder(Networks.class) @@ -207,7 +197,7 @@ public class NetworkModelServiceImpl implements NetworkModelService { .build(); this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyNode); } - for (Link openRoadmTopologyLink: topologyShard.getLinks()) { + for (Link openRoadmTopologyLink : topologyShard.getLinks()) { LOG.info("deleting link {} in {}", openRoadmTopologyLink.getLinkId().getValue(), NetworkUtils.OVERLAY_NETWORK_ID); InstanceIdentifier iiOpenRoadmTopologyLink = InstanceIdentifier.builder(Networks.class) @@ -228,7 +218,7 @@ public class NetworkModelServiceImpl implements NetworkModelService { TopologyShard otnTopologyShard = this.otnTopologyShardMountedDevice.get(nodeId); LOG.info("suppression de otnTopologyShard = {}", otnTopologyShard.toString()); if (otnTopologyShard != null) { - for (Node otnTopologyNode: otnTopologyShard .getNodes()) { + for (Node otnTopologyNode : otnTopologyShard.getNodes()) { LOG.info("deleting node {} in {}", otnTopologyNode.getNodeId().getValue(), NetworkUtils.OTN_NETWORK_ID); InstanceIdentifier iiotnTopologyNode = InstanceIdentifier.builder(Networks.class) @@ -237,7 +227,7 @@ public class NetworkModelServiceImpl implements NetworkModelService { .build(); this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiotnTopologyNode); } - for (Link otnTopologyLink: otnTopologyShard.getLinks()) { + for (Link otnTopologyLink : otnTopologyShard.getLinks()) { LOG.info("deleting link {} in {}", otnTopologyLink.getLinkId().getValue(), NetworkUtils.OTN_NETWORK_ID); InstanceIdentifier iiotnTopologyLink = InstanceIdentifier.builder(Networks.class) @@ -259,4 +249,402 @@ public class NetworkModelServiceImpl implements NetworkModelService { LOG.error("Error when trying to delete node : {}", nodeId, e); } } + + @Override + public void createOtnLinks(String nodeA, String tpA, String nodeZ, String tpZ, OtnLinkType linkType) { + TopologyShard otnTopologyShard; + switch (linkType) { + case OTU4: + otnTopologyShard = OpenRoadmOtnTopology.createOtnLinks(nodeA, tpA, nodeZ, tpZ, 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(); + List linkIdList = new ArrayList<>(); + linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, "OTU4")); + linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, "OTU4")); + List supportedOtu4links = getOtnLinks(linkIdList); + List tps = getOtnNodeTps(nodeTopoA, tpA, nodeTopoZ, tpZ); + + otnTopologyShard = OpenRoadmOtnTopology.createOtnLinks(supportedOtu4links, tps); + break; + default: + LOG.error("unknown otn link type {}", linkType); + otnTopologyShard = new TopologyShard(null, null); + } + 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, CREATE_MISSING_PARENTS); + } + } + if (otnTopologyShard.getTps() != null) { + for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) { + LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue()); + 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())) + .augmentation(Node1.class) + .child(TerminationPoint.class, new TerminationPointKey(otnTopologyTp.getTpId())) + .build(); + networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp); + } + } + try { + networkTransactionService.commit().get(); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Error adding OTN links in otn-topology", e); + } + LOG.info("OTN links created"); + } + + @Override + public void deleteOtnLinks(String nodeA, String tpA, String nodeZ, String tpZ, 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; + 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); + } 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); + List tps = getOtnNodeTps(nodeTopoA, tpA, nodeTopoZ, tpZ); + if (checkLinks(odu4Links) && checkTerminationPoints(tps)) { + deleteLinks(odu4Links); + 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); + } else { + LOG.error("Error deleting ODU4 links"); + otnTopologyShard = new TopologyShard(null, null); + } + break; + default: + 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(), + 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, + CREATE_MISSING_PARENTS); + } + } + if (otnTopologyShard.getTps() != null) { + for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) { + LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue()); + 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())) + .augmentation(Node1.class) + .child(TerminationPoint.class, new TerminationPointKey(otnTopologyTp.getTpId())) + .build(); + networkTransactionService.put(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp); + } + } + try { + networkTransactionService.commit().get(); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Error deleting OTN links in otn-topology", e); + } + LOG.info("OTN links deletion terminated"); + } + + @Override + public void updateOtnLinks(List nodeTps, String serviceRate, Short tribPortNb, Short tribSoltNb, + boolean isDeletion) { + List supportedOdu4Links = getSupportingOdu4Links(nodeTps); + List tps = getOtnNodeTps(nodeTps); + TopologyShard otnTopologyShard; + otnTopologyShard = OpenRoadmOtnTopology.updateOtnLinks(supportedOdu4Links, tps, serviceRate, tribPortNb, + tribSoltNb, 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, new LinkKey(new LinkId(otnTopologyLink.getLinkId().getValue()))) + .build(); + networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, + otnTopologyLink, CREATE_MISSING_PARENTS); + } + } + if (otnTopologyShard.getTps() != null) { + for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) { + LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue()); + 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())) + .augmentation(Node1.class) + .child(TerminationPoint.class, new TerminationPointKey( + new TpId(otnTopologyTp.getTpId().getValue()))) + .build(); + if (isDeletion) { + networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp); + } else { + networkTransactionService.put(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp); + } + } + } + try { + networkTransactionService.commit().get(); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Error updating OTN links in otn-topology", e); + } + } + + private List getOtnLinks(List linkIds) { + List links = new ArrayList<>(); + for (LinkId linkId : linkIds) { + InstanceIdentifier iiLink = InstanceIdentifier.builder(Networks.class) + .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID))) + .augmentation(Network1.class) + .child(Link.class, new LinkKey(linkId)) + .build(); + ListenableFuture> linkOptLf = networkTransactionService + .read(LogicalDatastoreType.CONFIGURATION, iiLink); + if (linkOptLf.isDone()) { + try { + if (linkOptLf.get().isPresent()) { + links.add(linkOptLf.get().get()); + } + } catch (InterruptedException | ExecutionException e) { + LOG.error("Error retreiving OTN links from otn-topology", e); + } + } else { + LOG.error("Error retreiving link {} from otn-topology", linkId.getValue()); + } + } + return links; + } + + private boolean checkLinks(List links) { + boolean canBeDeleted = true; + if (links.isEmpty()) { + return false; + } else { + for (Link link : links) { + if (link.augmentation(Link1.class) != null + && !link.augmentation(Link1.class).getUsedBandwidth().equals(Uint32.valueOf(0))) { + canBeDeleted = false; + } + } + } + return canBeDeleted; + } + + 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; + } + } + } + return canBeDeleted; + } + + private List getOtnNodeTps(String nodeTopoA, String tpA, String nodeTopoZ, String tpZ) { + List tps = new ArrayList<>(); + InstanceIdentifier iiTpA = InstanceIdentifier.builder(Networks.class) + .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID))) + .child(Node.class, new NodeKey(new NodeId(nodeTopoA))) + .augmentation(Node1.class) + .child(TerminationPoint.class, new TerminationPointKey(new TpId(tpA))) + .build(); + Optional tpAOpt = Optional.empty(); + InstanceIdentifier iiTpZ = InstanceIdentifier.builder(Networks.class) + .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID))) + .child(Node.class, new NodeKey(new NodeId(nodeTopoZ))) + .augmentation(Node1.class) + .child(TerminationPoint.class, new TerminationPointKey(new TpId(tpZ))) + .build(); + Optional tpZOpt = Optional.empty(); + + if (networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpA).isDone() + && networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpZ).isDone()) { + try { + tpAOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpA).get(); + tpZOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpZ).get(); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Error retreiving tp {} of node {} or tp {} from node {} from otn-topology", tpA, nodeTopoA, + tpZ, nodeTopoZ, e); + } + } else { + LOG.error("error getting node termination points from the datastore"); + } + + if (tpAOpt.isPresent() && tpZOpt.isPresent()) { + tps.add(tpAOpt.get()); + tps.add(tpZOpt.get()); + } + return tps; + } + + private List getOtnNodeTps(List nodeTopoTps) { + List tps = new ArrayList<>(); + for (String str : nodeTopoTps) { + String nodeId = str.split("--")[0]; + String tp = str.split("--")[1]; + 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))) + .augmentation(Node1.class) + .child(TerminationPoint.class, new TerminationPointKey(new TpId(tp))) + .build(); + Optional tpOpt; + if (networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTp).isDone()) { + try { + tpOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTp).get(); + if (tpOpt.isPresent()) { + tps.add(tpOpt.get()); + } + } catch (InterruptedException | ExecutionException e) { + LOG.error("Error retreiving tp {} of node {} from otn-topology", tp, nodeId, e); + } + } else { + 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; + } + } + + private void deleteLinks(List links) { + for (Link otnTopologyLink : links) { + LOG.info("deleting link {} from {}", 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.delete(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink); + } + try { + networkTransactionService.commit().get(); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Error deleting OTN links from otn-topology", e); + } + } + + private List getSupportingOdu4Links(List nodesTopoTps) { + InstanceIdentifier iiOtnTopologyLinks = InstanceIdentifier.builder(Networks.class) + .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID))) + .augmentation(Network1.class) + .build(); + ListenableFuture> netw1Fl = networkTransactionService + .read(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLinks); + Optional netw1Opt = Optional.empty(); + if (netw1Fl.isDone()) { + try { + netw1Opt = netw1Fl.get(); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Error retreiving list of links from otn-topology", e); + } + } + List odu4links = null; + if (netw1Opt.isPresent() && netw1Opt.get().getLink() != null) { + odu4links = netw1Opt.get().getLink().stream().filter(lk -> lk.getLinkId().getValue().startsWith("ODU4")) + .collect(Collectors.toList()); + } + 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); + } + } + } + LOG.debug("odu4links = {}", links.toString()); + return links; + } else { + return null; + } + } + + private void createOpenRoadmOtnNode(String nodeId) { + TopologyShard otnTopologyShard = OpenRoadmOtnTopology.createTopologyShard(portMapping.getNode(nodeId)); + if (otnTopologyShard != null) { + this.otnTopologyShardMountedDevice.put(nodeId, otnTopologyShard); + for (Node otnTopologyNode : otnTopologyShard.getNodes()) { + LOG.info("creating otn node {} in {}", otnTopologyNode.getNodeId().getValue(), + NetworkUtils.OTN_NETWORK_ID); + InstanceIdentifier iiOtnTopologyNode = InstanceIdentifier.builder(Networks.class) + .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID))) + .child(Node.class, otnTopologyNode.key()) + .build(); + networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyNode, + otnTopologyNode); + } + for (Link otnTopologyLink : otnTopologyShard.getLinks()) { + LOG.info("creating otn link {} 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, CREATE_MISSING_PARENTS); + } + } else { + LOG.error("Unable to create OTN topology shard for node {}!", nodeId); + } + + } } diff --git a/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/util/LinkIdUtil.java b/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/util/LinkIdUtil.java index e5184af13..22742cfe4 100644 --- a/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/util/LinkIdUtil.java +++ b/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/util/LinkIdUtil.java @@ -19,6 +19,7 @@ public final class LinkIdUtil { private static final String RECEIVE = "-RX"; private static final String BIDIRECTIONAL = "-TXRX"; private static final String LINK_ID_FORMAT = "%1$s-%2$sto%3$s-%4$s"; + private static final String OTN_LINK_ID_FORMAT = "%5$s-%1$s-%2$sto%3$s-%4$s"; private LinkIdUtil() { // utility class @@ -37,6 +38,21 @@ public final class LinkIdUtil { return new LinkId(String.format(LINK_ID_FORMAT, srcNode, srcTp, destNode, destTp)); } + /** + * Builds the OTN Link id in format {@link LinkIdUtil#OTN_LINK_ID_FORMAT}. + * + * @param srcNode source node id string + * @param srcTp source termination point + * @param destNode destination node id + * @param destTp destination termination point + * @param otnPrefix otn link type prefix + * @return {@link LinkId} + */ + public static LinkId buildOtnLinkId(String srcNode, String srcTp, String destNode, String destTp, + String otnPrefix) { + return new LinkId(String.format(OTN_LINK_ID_FORMAT, srcNode, srcTp, destNode, destTp, otnPrefix)); + } + /** * Builds the opposite {@link LinkId} from the {@link InitRoadmNodesInput}. * diff --git a/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/util/OpenRoadmOtnTopology.java b/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/util/OpenRoadmOtnTopology.java index 47b8f2c00..f3a9f37c5 100644 --- a/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/util/OpenRoadmOtnTopology.java +++ b/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/util/OpenRoadmOtnTopology.java @@ -8,12 +8,15 @@ package org.opendaylight.transportpce.networkmodel.util; +import com.google.common.collect.ImmutableList; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.transportpce.common.NetworkUtils; import org.opendaylight.transportpce.networkmodel.dto.OtnTopoNode; import org.opendaylight.transportpce.networkmodel.dto.TopologyShard; @@ -24,14 +27,18 @@ import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.re import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev181130.xpdr.odu.switching.pools.OduSwitchingPoolsBuilder; import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev181130.xpdr.odu.switching.pools.odu.switching.pools.NonBlockingList; import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev181130.xpdr.odu.switching.pools.odu.switching.pools.NonBlockingListBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmLinkType; import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmNodeType; import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmTpType; import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.xpdr.tp.supported.interfaces.SupportedInterfaceCapability; import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.xpdr.tp.supported.interfaces.SupportedInterfaceCapabilityBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev181130.ODTU4TsAllocated; import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev181130.ODU0; import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev181130.ODU2e; import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev181130.ODU4; import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev181130.OduRateIdentity; +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.Link1Builder; import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.Node1; import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.Node1Builder; import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.TerminationPoint1; @@ -51,6 +58,8 @@ import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181130.If10 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181130.IfOCHOTU4ODU4; import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev181130.SupportedIfCapability; import org.opendaylight.yang.gen.v1.http.org.openroadm.switching.pool.types.rev181130.SwitchingPoolTypes; +import org.opendaylight.yang.gen.v1.http.org.openroadm.xponder.rev181130.xpdr.otn.tp.attributes.OdtuTpnPoolBuilder; +import org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.OtnLinkType; 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.NodeId; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node; @@ -61,6 +70,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.node.SupportingNodeKey; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.TpId; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.LinkBuilder; 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.TerminationPointBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointKey; @@ -77,6 +87,9 @@ public final class OpenRoadmOtnTopology { private static final String CLIENT = "-CLIENT"; private static final String NETWORK = "-NETWORK"; private static final String XPDR = "-XPDR"; + private static final int NB_TRIB_PORTS = 80; + private static final int NB_TRIB_SLOTS = 80; + private static final int NB_TRIB_SLOT_PER_10GE = 8; private OpenRoadmOtnTopology() { } @@ -104,6 +117,222 @@ public final class OpenRoadmOtnTopology { return new TopologyShard(nodes, links); } + public static TopologyShard createOtnLinks(String nodeA, String tpA, String nodeZ, String tpZ, + OtnLinkType linkType) { + List links = null; + if (OtnLinkType.OTU4.equals(linkType)) { + links = initialiseOtnLinks(nodeA, tpA, nodeZ, tpZ, linkType, "OTU4"); + } + return new TopologyShard(null, links); + } + + public static TopologyShard createOtnLinks(List suppOtu4Links, List oldTps) { + List links = new ArrayList<>(); + for (Link link : suppOtu4Links) { + if (link.augmentation(Link1.class) != null + && link.augmentation(Link1.class).getAvailableBandwidth().equals(Uint32.valueOf(100000))) { + links.add(updateOtnLinkBwParameters(link, 0L, 100000L)); + } else { + LOG.error("Error with otn parameters of supported link {}", link.getLinkId().getValue()); + } + } + if (links.size() == 2) { + links.addAll(initialiseOtnLinks(suppOtu4Links.get(0).getSource().getSourceNode().getValue(), + suppOtu4Links.get(0).getSource().getSourceTp().toString(), + suppOtu4Links.get(0).getDestination().getDestNode().getValue(), + suppOtu4Links.get(0).getDestination().getDestTp().toString(), + OtnLinkType.ODTU4, "ODU4")); + } + List tps = new ArrayList<>(); + for (TerminationPoint tp : oldTps) { + tps.add(updateTp(tp, true)); + } + if (links.size() == 4 && tps.size() == 2) { + return new TopologyShard(null, links, tps); + } else { + return new TopologyShard(null, null, null); + } + } + + public static TopologyShard updateOtnLinks(List suppOdu4Links, List oldTps, + String serviceRate, Short tribPortNb, Short tribSoltNb, boolean isDeletion) { + List links = new ArrayList<>(); + for (Link link : suppOdu4Links) { + if (link.augmentation(Link1.class) != null && link.augmentation(Link1.class).getAvailableBandwidth() != null + && link.augmentation(Link1.class).getUsedBandwidth() != null) { + Long avlBwIncr = 10000L; + Long usedBwIncr = 10000L; + if ("1G".equals(serviceRate)) { + avlBwIncr = 1000L; + usedBwIncr = 1000L; + } + Uint32 avlBw = link.augmentation(Link1.class).getAvailableBandwidth(); + Uint32 usedBw = link.augmentation(Link1.class).getUsedBandwidth(); + if (isDeletion) { + links.add(updateOtnLinkBwParameters(link, avlBw.toJava() + avlBwIncr, + usedBw.toJava() - usedBwIncr)); + } else { + links.add(updateOtnLinkBwParameters(link, avlBw.toJava() - avlBwIncr, + usedBw.toJava() + usedBwIncr)); + } + } else { + LOG.error("Error with otn parameters of supported link {}", link.getLinkId().getValue()); + } + } + List tps = new ArrayList<>(); + for (TerminationPoint tp : oldTps) { + tps.add(updateNodeTpTsPool(tp, serviceRate, tribPortNb, tribSoltNb, isDeletion)); + } + if (!links.isEmpty() && !tps.isEmpty()) { + return new TopologyShard(null, links, tps); + } else { + return new TopologyShard(null, null, null); + } + } + + public static TopologyShard deleteOtnLinks(List suppOtu4Links, List oldTps) { + List links = new ArrayList<>(); + for (Link link : suppOtu4Links) { + if (link.augmentation(Link1.class) != null) { + links.add(updateOtnLinkBwParameters(link, 100000L, 0L)); + } else { + LOG.error("Error with otn parameters of supported link {}", link.getLinkId().getValue()); + } + } + List tps = new ArrayList<>(); + for (TerminationPoint tp : oldTps) { + tps.add(updateTp(tp, false)); + } + if (links.size() == 2 && tps.size() == 2) { + return new TopologyShard(null, links, tps); + } else { + return new TopologyShard(null, null, null); + } + } + + private static List initialiseOtnLinks(String nodeA, String tpA, String nodeZ, String tpZ, + OtnLinkType linkType, String linkIdPrefix) { + List links = new ArrayList<>(); + org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.Link1 tpceLink1 + = new org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.Link1Builder() + .setOtnLinkType(linkType).build(); + Link1 otnLink1 = new Link1Builder() + .setLinkType(OpenroadmLinkType.OTNLINK) + .setAvailableBandwidth(Uint32.valueOf(100000)) + .setUsedBandwidth(Uint32.valueOf(0)) + .build(); + // create link A-Z + String nodeATopo; + String nodeZTopo; + if (nodeA.contains(XPDR) && nodeZ.contains(XPDR)) { + nodeATopo = nodeA; + nodeZTopo = nodeZ; + } else { + nodeATopo = nodeA + "-" + tpA.split("-")[0]; + nodeZTopo = nodeZ + "-" + tpZ.split("-")[0]; + } + LinkBuilder ietfLinkAZBldr = TopologyUtils.createLink(nodeATopo, nodeZTopo, tpA, tpZ, linkIdPrefix); + ietfLinkAZBldr.addAugmentation(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.Link1.class, + tpceLink1) + .addAugmentation(Link1.class, otnLink1); + links.add(ietfLinkAZBldr.build()); + // create link Z-A + LinkBuilder ietfLinkZABldr = TopologyUtils.createLink(nodeZTopo, nodeATopo, tpZ, tpA, linkIdPrefix); + ietfLinkZABldr.addAugmentation(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.Link1.class, + tpceLink1) + .addAugmentation(Link1.class, otnLink1); + links.add(ietfLinkZABldr.build()); + return links; + } + + private static Link updateOtnLinkBwParameters(Link link, Long availBw, Long usedBw) { + LOG.debug("in updateOtnLinkBwParameters with availBw = {}, usedBw = {}", availBw, usedBw); + LinkBuilder updatedLinkBldr = new LinkBuilder(link); + Link1Builder updatedLink1Bldr = new Link1Builder(link.augmentation(Link1.class)) + .setAvailableBandwidth(Uint32.valueOf(availBw)) + .setUsedBandwidth(Uint32.valueOf(usedBw)); + updatedLinkBldr.addAugmentation(Link1.class, updatedLink1Bldr.build()); + return updatedLinkBldr.build(); + } + + private static TerminationPoint updateTp(TerminationPoint originalTp, boolean addingTsTpnPoolTermination) { + LOG.debug("in updateTp"); + TerminationPointBuilder tpBldr = new TerminationPointBuilder(originalTp); + TerminationPoint1Builder otnTp1Bldr = new TerminationPoint1Builder( + tpBldr.augmentation(TerminationPoint1.class)); + XpdrTpPortConnectionAttributesBuilder xtpcaBldr = new XpdrTpPortConnectionAttributesBuilder(otnTp1Bldr + .getXpdrTpPortConnectionAttributes()); + if (addingTsTpnPoolTermination) { + List tsPool = new ArrayList<>(); + for (int i = 0; i < NB_TRIB_SLOTS; i++) { + tsPool.add(Uint16.valueOf(i + 1)); + } + xtpcaBldr.setTsPool(tsPool); + List tpnPool = new ArrayList<>(); + for (int i = 1; i <= NB_TRIB_PORTS; i++) { + tpnPool.add(Uint16.valueOf(i)); + } + xtpcaBldr.setOdtuTpnPool(ImmutableList.of(new OdtuTpnPoolBuilder().setOdtuType(ODTU4TsAllocated.class) + .setTpnPool(tpnPool).build())); + } else { + xtpcaBldr.setTsPool(null); + xtpcaBldr.setOdtuTpnPool(null); + } + return tpBldr.addAugmentation(TerminationPoint1.class, + otnTp1Bldr.setXpdrTpPortConnectionAttributes(xtpcaBldr.build()).build()).build(); + } + + private static TerminationPoint updateNodeTpTsPool(TerminationPoint tp, String serviceRate, Short tribPortNb, + Short tribSlotNb, boolean isDeletion) { + LOG.debug("in updateNodeTpTsPool"); + TerminationPointBuilder tpBldr = new TerminationPointBuilder(tp); + @Nullable + XpdrTpPortConnectionAttributesBuilder xtpcaBldr = new XpdrTpPortConnectionAttributesBuilder( + tpBldr.augmentation(TerminationPoint1.class).getXpdrTpPortConnectionAttributes()); + List tsPool = new ArrayList<>(xtpcaBldr.getTsPool()); + switch (serviceRate) { + case "1G": + if (isDeletion) { + tsPool.add(Uint16.valueOf(tribSlotNb)); + } else { + tsPool.remove(Uint16.valueOf(tribSlotNb)); + } + break; + case "10G": + if (isDeletion) { + for (int i = 0; i < NB_TRIB_SLOT_PER_10GE; i++) { + tsPool.add(Uint16.valueOf(tribSlotNb + i)); + } + } else { + for (int i = 0; i < NB_TRIB_SLOT_PER_10GE; i++) { + tsPool.remove(Uint16.valueOf(tribSlotNb + i)); + } + } + break; + default: + LOG.error("error updating tpn and ts pool for tp {}", tp.getTpId().getValue()); + break; + } + xtpcaBldr.setTsPool(tsPool); + List tpnPool; + if (xtpcaBldr.getOdtuTpnPool().get(0).getTpnPool() != null) { + tpnPool = new ArrayList<>(xtpcaBldr.getOdtuTpnPool().get(0).getTpnPool()); + if (isDeletion) { + tpnPool.add(Uint16.valueOf(tribPortNb)); + } else { + tpnPool.remove(Uint16.valueOf(tribPortNb)); + } + } else { + tpnPool = new ArrayList<>(); + } + xtpcaBldr.setOdtuTpnPool(ImmutableList.of(new OdtuTpnPoolBuilder().setOdtuType(ODTU4TsAllocated.class) + .setTpnPool(tpnPool).build())); + + tpBldr.addAugmentation(TerminationPoint1.class, + new TerminationPoint1Builder().setXpdrTpPortConnectionAttributes(xtpcaBldr.build()).build()); + return tpBldr.build(); + } + private static Map convertPortMappingToOtnNodeList(Nodes mappingNode) { List networkMappings = mappingNode.getMapping().stream().filter(k -> k.getLogicalConnectionPoint() .contains("NETWORK")).collect(Collectors.toList()); @@ -145,7 +374,7 @@ public final class OpenRoadmOtnTopology { } private static Node createTpdr(OtnTopoNode node) { - //create otn-topology node augmentation + // create otn-topology node augmentation XpdrAttributes xpdrAttr = new XpdrAttributesBuilder() .setXpdrNumber(Uint16.valueOf(node.getXpdrNb())) .build(); @@ -155,7 +384,7 @@ public final class OpenRoadmOtnTopology { org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Node1 ocnNodeAug = new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Node1Builder() .setNodeType(OpenroadmNodeType.TPDR).build(); - //create ietf node augmentation to add TP list + // create ietf node augmentation to add TP list List tpList = new ArrayList<>(); // creation of tps createTP(tpList, node, OpenroadmTpType.XPONDERCLIENT, If100GE.class, false); @@ -166,7 +395,7 @@ public final class OpenRoadmOtnTopology { .setTerminationPoint(tpList) .build(); - //return ietfNode + // return ietfNode return new NodeBuilder() .setNodeId(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb())) .withKey(new NodeKey(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb()))) @@ -174,8 +403,9 @@ public final class OpenRoadmOtnTopology { .addAugmentation(Node1.class, otnNodeAug) .addAugmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Node1.class, ocnNodeAug) - .addAugmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226 - .Node1.class, ietfNodeAug) + .addAugmentation( + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1.class, + ietfNodeAug) .build(); } @@ -221,7 +451,7 @@ public final class OpenRoadmOtnTopology { new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Node1Builder() .setNodeType(OpenroadmNodeType.MUXPDR).build(); - //create ietf node augmentation to add TP list + // create ietf node augmentation to add TP list List tpList = new ArrayList<>(); // creation of tps createTP(tpList, node, OpenroadmTpType.XPONDERCLIENT, If10GEODU2e.class, true); @@ -232,7 +462,7 @@ public final class OpenRoadmOtnTopology { .setTerminationPoint(tpList) .build(); - //return ietfNode + // return ietfNode return new NodeBuilder() .setNodeId(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb())) .withKey(new NodeKey(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb()))) @@ -240,8 +470,9 @@ public final class OpenRoadmOtnTopology { .addAugmentation(Node1.class, otnNodeAug) .addAugmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Node1.class, ocnNodeAug) - .addAugmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226 - .Node1.class, ietfNodeAug) + .addAugmentation( + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1.class, + ietfNodeAug) .build(); } @@ -290,7 +521,7 @@ public final class OpenRoadmOtnTopology { new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Node1Builder() .setNodeType(OpenroadmNodeType.SWITCH).build(); - //create ietf node augmentation to add TP list + // create ietf node augmentation to add TP list List tpList = new ArrayList<>(); // creation of tps createTP(tpList, node, OpenroadmTpType.XPONDERCLIENT, If100GEODU4.class, true); @@ -300,7 +531,7 @@ public final class OpenRoadmOtnTopology { .setTerminationPoint(tpList) .build(); - //return ietfNode + // return ietfNode return new NodeBuilder() .setNodeId(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb())) .withKey(new NodeKey(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb()))) @@ -308,8 +539,9 @@ public final class OpenRoadmOtnTopology { .addAugmentation(Node1.class, otnNodeAug) .addAugmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Node1.class, ocnNodeAug) - .addAugmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226 - .Node1.class, ietfNodeAug) + .addAugmentation( + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1.class, + ietfNodeAug) .build(); } @@ -325,7 +557,7 @@ public final class OpenRoadmOtnTopology { } for (int i = 1; i <= nbTps; i++) { - //openroadm-otn-topoology augmentation + // openroadm-otn-topoology augmentation SupportedInterfaceCapability supIfCapa = new SupportedInterfaceCapabilityBuilder() .setIfCapType(ifCapType) .build(); @@ -408,27 +640,30 @@ public final class OpenRoadmOtnTopology { return suppNodeList; } - private static TerminationPoint buildIetfTp(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129 - .TerminationPoint1Builder tpceTp1Bldr, TerminationPoint1 otnTp1, OpenroadmTpType tpType, TpId tpId, + private static TerminationPoint buildIetfTp( + org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.TerminationPoint1Builder tpceTp1Bldr, + TerminationPoint1 otnTp1, OpenroadmTpType tpType, TpId tpId, List supportTpList) { TerminationPointBuilder ietfTpBldr = new TerminationPointBuilder(); if (tpceTp1Bldr.getAssociatedConnectionMapPort() != null) { - ietfTpBldr.addAugmentation(org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129 - .TerminationPoint1.class, tpceTp1Bldr.build()); + ietfTpBldr.addAugmentation( + org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.TerminationPoint1.class, + tpceTp1Bldr.build()); } if (supportTpList != null) { ietfTpBldr.setSupportingTerminationPoint(supportTpList); } org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.TerminationPoint1 ocnTp = - new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130 - .TerminationPoint1Builder().setTpType(tpType).build(); + new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.TerminationPoint1Builder() + .setTpType(tpType).build(); ietfTpBldr.setTpId(tpId) .withKey(new TerminationPointKey(tpId)) .addAugmentation(TerminationPoint1.class, otnTp1) - .addAugmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130 - .TerminationPoint1.class, ocnTp); + .addAugmentation( + org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.TerminationPoint1.class, + ocnTp); return ietfTpBldr.build(); } } diff --git a/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/util/TopologyUtils.java b/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/util/TopologyUtils.java index 249873f41..824d3348b 100644 --- a/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/util/TopologyUtils.java +++ b/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/util/TopologyUtils.java @@ -40,7 +40,8 @@ public final class TopologyUtils { } // This method returns the linkBuilder object for given source and destination - public static LinkBuilder createLink(String srcNode, String dstNode, String srcTp, String destTp) { + public static LinkBuilder createLink(String srcNode, String dstNode, String srcTp, String destTp, + String otnPrefix) { // Create Destination for link DestinationBuilder dstNodeBldr = new DestinationBuilder() @@ -52,17 +53,25 @@ public final class TopologyUtils { .setSourceNode(new NodeId(srcNode)) .setSourceTp(srcTp); + LinkId linkId; + LinkId oppositeLinkId; + if (otnPrefix == null) { + linkId = LinkIdUtil.buildLinkId(srcNode, srcTp, dstNode, destTp); + oppositeLinkId = LinkIdUtil.buildLinkId(dstNode, destTp, srcNode, srcTp); + } else { + linkId = LinkIdUtil.buildOtnLinkId(srcNode, srcTp, dstNode, destTp, otnPrefix); + oppositeLinkId = LinkIdUtil.buildOtnLinkId(dstNode, destTp, srcNode, srcTp, otnPrefix); + } + //set opposite link + Link1 lnk1 = new Link1Builder().setOppositeLink(oppositeLinkId).build(); + // set link builder attribute LinkBuilder lnkBldr = new LinkBuilder() .setDestination(dstNodeBldr.build()) .setSource(srcNodeBldr.build()) - .setLinkId(LinkIdUtil.buildLinkId(srcNode, srcTp, dstNode, destTp)); - lnkBldr.withKey(new LinkKey(lnkBldr.getLinkId())); - - //set opposite link - LinkId oppositeLinkId = LinkIdUtil.getOppositeLinkId(srcNode, srcTp, dstNode, destTp); - Link1 lnk1 = new Link1Builder().setOppositeLink(oppositeLinkId).build(); - lnkBldr.addAugmentation(Link1.class,lnk1); + .setLinkId(linkId) + .withKey(new LinkKey(linkId)) + .addAugmentation(Link1.class,lnk1); return lnkBldr; } -- 2.36.6