2 * Copyright © 2016 AT&T and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.transportpce.networkmodel.service;
10 import com.google.common.util.concurrent.ListenableFuture;
11 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
12 import java.util.ArrayList;
13 import java.util.HashMap;
14 import java.util.List;
16 import java.util.Optional;
17 import java.util.concurrent.ExecutionException;
18 import java.util.concurrent.TimeUnit;
19 import java.util.concurrent.TimeoutException;
20 import java.util.stream.Collectors;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
23 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
24 import org.opendaylight.transportpce.common.InstanceIdentifiers;
25 import org.opendaylight.transportpce.common.NetworkUtils;
26 import org.opendaylight.transportpce.common.mapping.PortMapping;
27 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
28 import org.opendaylight.transportpce.networkmodel.R2RLinkDiscovery;
29 import org.opendaylight.transportpce.networkmodel.dto.TopologyShard;
30 import org.opendaylight.transportpce.networkmodel.util.ClliNetwork;
31 import org.opendaylight.transportpce.networkmodel.util.LinkIdUtil;
32 import org.opendaylight.transportpce.networkmodel.util.OpenRoadmNetwork;
33 import org.opendaylight.transportpce.networkmodel.util.OpenRoadmOtnTopology;
34 import org.opendaylight.transportpce.networkmodel.util.OpenRoadmTopology;
35 import org.opendaylight.transportpce.networkmodel.util.TopologyUtils;
36 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.TopologyUpdateResult;
37 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.TopologyUpdateResultBuilder;
38 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.topology.update.result.TopologyChanges;
39 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.topology.update.result.TopologyChangesBuilder;
40 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.topology.update.result.TopologyChangesKey;
41 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.OpenroadmNodeVersion;
42 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.mapping.Mapping;
43 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.network.nodes.NodeInfo;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.types.rev191129.NodeTypes;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev200529.Link1;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev200529.TerminationPoint1;
47 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev210618.link.tp.LinkTp;
48 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev210618.link.tp.LinkTpBuilder;
49 import org.opendaylight.yang.gen.v1.http.transportpce.topology.rev210511.OtnLinkType;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NetworkId;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.Networks;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.NetworkKey;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.NodeKey;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.LinkId;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Network1;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.TpId;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link;
62 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.LinkKey;
63 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPoint;
64 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointKey;
65 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.termination.point.SupportingTerminationPoint;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus;
67 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
68 import org.opendaylight.yangtools.yang.common.Uint32;
69 import org.slf4j.Logger;
70 import org.slf4j.LoggerFactory;
72 public class NetworkModelServiceImpl implements NetworkModelService {
74 private static final Logger LOG = LoggerFactory.getLogger(NetworkModelServiceImpl.class);
76 private NetworkTransactionService networkTransactionService;
77 private final R2RLinkDiscovery linkDiscovery;
78 private final PortMapping portMapping;
79 private Map<String, TopologyShard> topologyShardMountedDevice;
80 private Map<String, TopologyShard> otnTopologyShardMountedDevice;
81 // Variables for creating and sending topology update notification
82 private final NotificationPublishService notificationPublishService;
83 private Map<TopologyChangesKey, TopologyChanges> topologyChanges;
84 private TopologyUpdateResult notification = null;
86 public NetworkModelServiceImpl(final NetworkTransactionService networkTransactionService,
87 final R2RLinkDiscovery linkDiscovery, PortMapping portMapping,
88 final NotificationPublishService notificationPublishService) {
90 this.networkTransactionService = networkTransactionService;
91 this.linkDiscovery = linkDiscovery;
92 this.portMapping = portMapping;
93 this.topologyShardMountedDevice = new HashMap<String, TopologyShard>();
94 this.otnTopologyShardMountedDevice = new HashMap<String, TopologyShard>();
95 this.notificationPublishService = notificationPublishService;
96 this.topologyChanges = new HashMap<TopologyChangesKey, TopologyChanges>();
100 LOG.info("init ...");
103 public void close() {
107 public void createOpenRoadmNode(String nodeId, String openRoadmVersion) {
109 LOG.info("createOpenROADMNode: {} ", nodeId);
111 if (!portMapping.createMappingData(nodeId, openRoadmVersion)) {
112 LOG.warn("Could not generate port mapping for {} skipping network model creation", nodeId);
115 NodeInfo nodeInfo = portMapping.getNode(nodeId).getNodeInfo();
116 // node creation in clli-network
117 Node clliNode = ClliNetwork.createNode(nodeId, nodeInfo);
118 InstanceIdentifier<Node> iiClliNode = InstanceIdentifier.builder(Networks.class)
119 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.CLLI_NETWORK_ID)))
120 .child(Node.class, clliNode.key())
122 LOG.info("creating node in {}", NetworkUtils.CLLI_NETWORK_ID);
123 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiClliNode, clliNode);
125 // node creation in openroadm-network
126 Node openroadmNetworkNode = OpenRoadmNetwork.createNode(nodeId, nodeInfo);
127 InstanceIdentifier<Node> iiopenroadmNetworkNode = InstanceIdentifier.builder(Networks.class)
128 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID)))
129 .child(Node.class, openroadmNetworkNode.key())
131 LOG.info("creating node in {}", NetworkUtils.UNDERLAY_NETWORK_ID);
132 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiopenroadmNetworkNode,
133 openroadmNetworkNode);
135 // nodes/links creation in openroadm-topology
136 TopologyShard topologyShard = OpenRoadmTopology.createTopologyShard(portMapping.getNode(nodeId));
137 if (topologyShard != null) {
138 this.topologyShardMountedDevice.put(nodeId, topologyShard);
139 for (Node openRoadmTopologyNode : topologyShard.getNodes()) {
140 LOG.info("creating node {} in {}", openRoadmTopologyNode.getNodeId().getValue(),
141 NetworkUtils.OVERLAY_NETWORK_ID);
142 InstanceIdentifier<Node> iiOpenRoadmTopologyNode = InstanceIdentifier.builder(Networks.class)
143 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
144 .child(Node.class, openRoadmTopologyNode.key())
146 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyNode,
147 openRoadmTopologyNode);
149 for (Link openRoadmTopologyLink : topologyShard.getLinks()) {
150 LOG.info("creating link {} in {}", openRoadmTopologyLink.getLinkId().getValue(),
151 NetworkUtils.OVERLAY_NETWORK_ID);
152 InstanceIdentifier<Link> iiOpenRoadmTopologyLink = InstanceIdentifier.builder(Networks.class)
153 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
154 .augmentation(Network1.class)
155 .child(Link.class, openRoadmTopologyLink.key())
157 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyLink,
158 openRoadmTopologyLink);
161 LOG.error("Unable to create openroadm-topology shard for node {}!", nodeId);
163 // nodes/links creation in otn-topology
164 if (nodeInfo.getNodeType().getIntValue() == 2 && (nodeInfo.getOpenroadmVersion().getIntValue() != 1)) {
165 createOpenRoadmOtnNode(nodeId);
167 networkTransactionService.commit().get();
168 // neighbour links through LLDP
169 if (nodeInfo.getNodeType().getIntValue() == 1) {
170 this.linkDiscovery.readLLDP(new NodeId(nodeId), openRoadmVersion);
172 LOG.info("all nodes and links created");
173 } catch (InterruptedException | ExecutionException e) {
174 LOG.error("ERROR: ", e);
179 public void setOpenRoadmNodeStatus(String nodeId, NetconfNodeConnectionStatus.ConnectionStatus connectionStatus) {
180 LOG.info("setOpenROADMNodeStatus: {} {}", nodeId, connectionStatus.name());
182 TODO: set connection status of the device in model,
183 TODO: so we don't need to keep it in memory (Set<String> currentMountedDevice)
184 TODO: unfortunately there is no connection status OpenROADM in network models
185 TODO: waiting for new model version
190 @see org.opendaylight.transportpce.networkmodel.service.NetworkModelService# deleteOpenROADMnode(java.lang.String)
194 public void deleteOpenRoadmnode(String nodeId) {
196 NodeKey nodeIdKey = new NodeKey(new NodeId(nodeId));
198 LOG.info("deleting node in {}", NetworkUtils.UNDERLAY_NETWORK_ID);
199 InstanceIdentifier<Node> iiopenroadmNetworkNode = InstanceIdentifier.builder(Networks.class)
200 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID)))
201 .child(Node.class, nodeIdKey)
203 this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiopenroadmNetworkNode);
205 TopologyShard topologyShard = this.topologyShardMountedDevice.get(nodeId);
206 if (topologyShard != null) {
207 for (Node openRoadmTopologyNode : topologyShard.getNodes()) {
208 LOG.info("deleting node {} in {}", openRoadmTopologyNode.getNodeId().getValue(),
209 NetworkUtils.OVERLAY_NETWORK_ID);
210 InstanceIdentifier<Node> iiOpenRoadmTopologyNode = InstanceIdentifier.builder(Networks.class)
211 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
212 .child(Node.class, openRoadmTopologyNode.key())
214 this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyNode);
216 for (Link openRoadmTopologyLink : topologyShard.getLinks()) {
217 LOG.info("deleting link {} in {}", openRoadmTopologyLink.getLinkId().getValue(),
218 NetworkUtils.OVERLAY_NETWORK_ID);
219 InstanceIdentifier<Link> iiOpenRoadmTopologyLink = InstanceIdentifier.builder(Networks.class)
220 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
221 .augmentation(Network1.class)
222 .child(Link.class, openRoadmTopologyLink.key())
224 this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyLink);
227 LOG.warn("TopologyShard for node '{}' is not present", nodeId);
230 OpenroadmNodeVersion deviceVersion = this.portMapping.getNode(nodeId).getNodeInfo().getOpenroadmVersion();
232 NodeTypes nodeType = this.portMapping.getNode(nodeId).getNodeInfo().getNodeType();
233 if (nodeType.getIntValue() == 2 && deviceVersion.getIntValue() != 1) {
234 TopologyShard otnTopologyShard = this.otnTopologyShardMountedDevice.get(nodeId);
235 if (otnTopologyShard != null) {
236 LOG.info("suppression de otnTopologyShard = {}", otnTopologyShard.toString());
237 for (Node otnTopologyNode : otnTopologyShard.getNodes()) {
238 LOG.info("deleting node {} in {}", otnTopologyNode.getNodeId().getValue(),
239 NetworkUtils.OTN_NETWORK_ID);
240 InstanceIdentifier<Node> iiotnTopologyNode = InstanceIdentifier.builder(Networks.class)
241 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
242 .child(Node.class, otnTopologyNode.key())
244 this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiotnTopologyNode);
246 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
247 LOG.info("deleting link {} in {}", otnTopologyLink.getLinkId().getValue(),
248 NetworkUtils.OTN_NETWORK_ID);
249 InstanceIdentifier<Link> iiotnTopologyLink = InstanceIdentifier.builder(Networks.class)
250 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
251 .augmentation(Network1.class)
252 .child(Link.class, otnTopologyLink.key())
254 this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiotnTopologyLink);
259 LOG.info("deleteOpenROADMnode: {} version {}", nodeId, deviceVersion.getName());
260 this.portMapping.deleteMappingData(nodeId);
262 this.networkTransactionService.commit().get(1, TimeUnit.SECONDS);
263 LOG.info("all nodes and links deleted ! ");
264 } catch (InterruptedException | ExecutionException | TimeoutException e) {
265 LOG.error("Error when trying to delete node : {}", nodeId, e);
270 public void updateOpenRoadmTopologies(String nodeId, Mapping mapping) {
271 LOG.info("update OpenRoadm topologies after change update from: {} ", nodeId);
272 this.topologyChanges.clear();
273 Network openroadmTopology = null;
274 Network otnTopology = null;
275 Map<LinkKey, Link> openroadmTopologyLinks = null;
276 Map<LinkKey, Link> otnTopologyLinks = null;
278 openroadmTopology = this.networkTransactionService
279 .read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifiers.OVERLAY_NETWORK_II)
281 if (openroadmTopology.augmentation(Network1.class) != null) {
282 openroadmTopologyLinks = openroadmTopology.augmentation(Network1.class).getLink();
284 otnTopology = this.networkTransactionService
285 .read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifiers.OTN_NETWORK_II)
287 if (otnTopology.augmentation(Network1.class) != null) {
288 otnTopologyLinks = otnTopology.augmentation(Network1.class).getLink();
290 } catch (InterruptedException | ExecutionException e) {
291 LOG.error("Error when trying to update node : {}", nodeId, e);
293 if (openroadmTopology == null || otnTopology == null) {
294 LOG.warn("Error getting topologies from datastore");
297 String abstractNodeid = String.join("-", nodeId, mapping.getLogicalConnectionPoint().split("-")[0]);
298 // nodes/links update in openroadm-topology
299 if (openroadmTopology.getNode() != null) {
300 TopologyShard topologyShard = TopologyUtils.updateTopologyShard(abstractNodeid, mapping,
301 openroadmTopology.getNode(), openroadmTopologyLinks);
302 if (topologyShard.getLinks() != null) {
303 for (Link link : topologyShard.getLinks()) {
304 LOG.info("updating links {} in {}", link.getLinkId().getValue(),
305 NetworkUtils.OVERLAY_NETWORK_ID);
306 InstanceIdentifier<Link> iiTopologyLink = InstanceIdentifier.builder(Networks.class)
307 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
308 .augmentation(Network1.class)
309 .child(Link.class, link.key())
311 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyLink, link);
314 if (topologyShard.getTps() != null) {
315 for (TerminationPoint tp : topologyShard.getTps()) {
316 LOG.info("updating TP {} in openroadm-topology", tp.getTpId().getValue());
317 InstanceIdentifier<TerminationPoint> iiTopologyTp = InstanceIdentifier.builder(Networks.class)
318 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
319 .child(Node.class, new NodeKey(new NodeId(abstractNodeid)))
320 .augmentation(Node1.class)
321 .child(TerminationPoint.class, new TerminationPointKey(tp.getTpId()))
323 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyTp, tp);
324 TopologyChanges tc = new TopologyChangesBuilder()
325 .withKey(new TopologyChangesKey(abstractNodeid, tp.getTpId().getValue()))
326 .setNodeId(abstractNodeid)
327 .setTpId(tp.getTpId().getValue())
328 .setState(tp.augmentation(
329 org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.TerminationPoint1
330 .class).getOperationalState())
332 if (!this.topologyChanges.containsKey(tc.key())) {
333 this.topologyChanges.put(tc.key(), tc);
338 // nodes/links update in otn-topology
339 if (otnTopology.getNode() != null
340 && otnTopology.getNode().containsKey(new NodeKey(new NodeId(abstractNodeid)))) {
341 TopologyShard otnShard = TopologyUtils.updateTopologyShard(abstractNodeid, mapping,
342 otnTopology.getNode(), otnTopologyLinks);
343 if (otnShard.getLinks() != null) {
344 for (Link link : otnShard.getLinks()) {
345 LOG.info("updating links {} in {}", link.getLinkId().getValue(),
346 NetworkUtils.OVERLAY_NETWORK_ID);
347 InstanceIdentifier<Link> iiTopologyLink = InstanceIdentifier.builder(Networks.class)
348 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
349 .augmentation(Network1.class)
350 .child(Link.class, link.key())
352 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyLink, link);
355 if (otnShard.getTps() != null) {
356 for (TerminationPoint tp : otnShard.getTps()) {
357 LOG.info("updating TP {} in otn-topology", tp.getTpId().getValue());
358 InstanceIdentifier<TerminationPoint> iiTopologyTp = InstanceIdentifier.builder(Networks.class)
359 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
360 .child(Node.class, new NodeKey(new NodeId(abstractNodeid)))
361 .augmentation(Node1.class)
362 .child(TerminationPoint.class, new TerminationPointKey(tp.getTpId()))
364 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyTp, tp);
365 TopologyChanges tc = new TopologyChangesBuilder()
366 .withKey(new TopologyChangesKey(abstractNodeid, tp.getTpId().getValue()))
367 .setNodeId(abstractNodeid)
368 .setTpId(tp.getTpId().getValue())
369 .setState(tp.augmentation(
370 org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.TerminationPoint1
371 .class).getOperationalState())
373 if (!this.topologyChanges.containsKey(tc.key())) {
374 this.topologyChanges.put(tc.key(), tc);
379 // commit datastore updates
381 networkTransactionService.commit().get();
383 } catch (InterruptedException | ExecutionException e) {
384 LOG.error("Error updating openroadm-topology", e);
389 public void createOtnLinks(String nodeA, String tpA, String nodeZ, String tpZ, OtnLinkType linkType) {
390 TopologyShard otnTopologyShard;
393 otnTopologyShard = OpenRoadmOtnTopology.createOtnLinks(nodeA, tpA, nodeZ, tpZ, linkType);
396 String nodeTopoA = new StringBuilder(nodeA).append("-").append(tpA.split("-")[0]).toString();
397 String nodeTopoZ = new StringBuilder(nodeZ).append("-").append(tpZ.split("-")[0]).toString();
398 List<LinkId> linkIdList = new ArrayList<>();
399 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, "OTU4"));
400 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, "OTU4"));
401 List<Link> supportedOtu4links = getOtnLinks(linkIdList);
402 List<TerminationPoint> tps = getOtnNodeTps(nodeTopoA, tpA, nodeTopoZ, tpZ);
404 otnTopologyShard = OpenRoadmOtnTopology.createOtnLinks(supportedOtu4links, tps);
407 LOG.error("unknown otn link type {}", linkType);
408 otnTopologyShard = new TopologyShard(null, null);
410 if (otnTopologyShard.getLinks() != null) {
411 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
412 LOG.info("creating and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(),
413 NetworkUtils.OVERLAY_NETWORK_ID);
414 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
415 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
416 .augmentation(Network1.class)
417 .child(Link.class, otnTopologyLink.key())
419 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
422 if (otnTopologyShard.getTps() != null) {
423 for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) {
424 LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue());
425 List<SupportingTerminationPoint> supportingTerminationPoint =
426 new ArrayList<>(otnTopologyTp.nonnullSupportingTerminationPoint().values());
427 InstanceIdentifier<TerminationPoint> iiOtnTopologyTp = InstanceIdentifier.builder(Networks.class)
428 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
429 .child(Node.class, new NodeKey(supportingTerminationPoint.get(0).getNodeRef()))
430 .augmentation(Node1.class)
431 .child(TerminationPoint.class, new TerminationPointKey(otnTopologyTp.getTpId()))
433 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
437 networkTransactionService.commit().get();
438 } catch (InterruptedException | ExecutionException e) {
439 LOG.error("Error adding OTN links in otn-topology", e);
441 LOG.info("OTN links created");
445 public void deleteOtnLinks(String nodeA, String tpA, String nodeZ, String tpZ, OtnLinkType linkType) {
446 TopologyShard otnTopologyShard;
447 String nodeTopoA = new StringBuilder(nodeA).append("-").append(tpA.split("-")[0]).toString();
448 String nodeTopoZ = new StringBuilder(nodeZ).append("-").append(tpZ.split("-")[0]).toString();
449 List<Link> otu4Links;
450 List<LinkId> linkIdList = new ArrayList<>();
453 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, "OTU4"));
454 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, "OTU4"));
455 otu4Links = getOtnLinks(linkIdList);
456 if (checkLinks(otu4Links)) {
457 deleteLinks(otu4Links);
459 LOG.error("Error deleting OTU4 links");
461 otnTopologyShard = new TopologyShard(null, null);
464 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, "ODU4"));
465 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, "ODU4"));
466 List<Link> odu4Links = getOtnLinks(linkIdList);
467 List<TerminationPoint> tps = getOtnNodeTps(nodeTopoA, tpA, nodeTopoZ, tpZ);
468 if (checkLinks(odu4Links) && checkTerminationPoints(tps)) {
469 deleteLinks(odu4Links);
471 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, "OTU4"));
472 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, "OTU4"));
473 otu4Links = getOtnLinks(linkIdList);
474 otnTopologyShard = OpenRoadmOtnTopology.deleteOtnLinks(otu4Links, tps);
476 LOG.error("Error deleting ODU4 links");
477 otnTopologyShard = new TopologyShard(null, null);
481 LOG.error("unknown otn link type {}", linkType);
482 otnTopologyShard = new TopologyShard(null, null);
484 if (otnTopologyShard.getLinks() != null) {
485 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
486 LOG.info("deleting and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(),
487 NetworkUtils.OVERLAY_NETWORK_ID);
488 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
489 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
490 .augmentation(Network1.class)
491 .child(Link.class, otnTopologyLink.key())
493 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
496 if (otnTopologyShard.getTps() != null) {
497 for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) {
498 LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue());
499 List<SupportingTerminationPoint> supportingTerminationPoint =
500 new ArrayList<>(otnTopologyTp.nonnullSupportingTerminationPoint().values());
501 InstanceIdentifier<TerminationPoint> iiOtnTopologyTp = InstanceIdentifier.builder(Networks.class)
502 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
503 .child(Node.class, new NodeKey(supportingTerminationPoint.get(0).getNodeRef()))
504 .augmentation(Node1.class)
505 .child(TerminationPoint.class, new TerminationPointKey(otnTopologyTp.getTpId()))
507 networkTransactionService.put(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
511 networkTransactionService.commit().get();
512 } catch (InterruptedException | ExecutionException e) {
513 LOG.error("Error deleting OTN links in otn-topology", e);
515 LOG.info("OTN links deletion terminated");
519 public void updateOtnLinks(
520 org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210618.renderer.rpc.result.sp.Link
521 notifLink, Uint32 serviceRate, Short tribPortNb, Short tribSoltNb, boolean isDeletion) {
523 LinkTp atermination = new LinkTpBuilder()
524 .setNodeId(notifLink.getATermination().getNodeId())
525 .setTpId(notifLink.getATermination().getTpId())
527 LinkTp ztermination = new LinkTpBuilder()
528 .setNodeId(notifLink.getZTermination().getNodeId())
529 .setTpId(notifLink.getZTermination().getTpId())
531 List<LinkTp> linkTerminations = new ArrayList<>();
532 linkTerminations.add(atermination);
533 linkTerminations.add(ztermination);
535 List<Link> supportedOdu4Links = getSupportingOdu4Links(linkTerminations);
536 List<TerminationPoint> tps = getOtnNodeTps(linkTerminations);
537 TopologyShard otnTopologyShard;
538 otnTopologyShard = OpenRoadmOtnTopology.updateOtnLinks(supportedOdu4Links, tps, serviceRate, tribPortNb,
539 tribSoltNb, isDeletion);
540 if (otnTopologyShard.getLinks() != null) {
541 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
542 LOG.info("creating and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(),
543 NetworkUtils.OVERLAY_NETWORK_ID);
544 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
545 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
546 .augmentation(Network1.class)
547 .child(Link.class, new LinkKey(new LinkId(otnTopologyLink.getLinkId().getValue())))
549 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
552 if (otnTopologyShard.getTps() != null) {
553 for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) {
554 LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue());
555 List<SupportingTerminationPoint> supportingTerminationPoint =
556 new ArrayList<>(otnTopologyTp.nonnullSupportingTerminationPoint().values());
557 InstanceIdentifier<TerminationPoint> iiOtnTopologyTp = InstanceIdentifier.builder(Networks.class)
558 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
559 .child(Node.class, new NodeKey(supportingTerminationPoint.get(0).getNodeRef()))
560 .augmentation(Node1.class)
561 .child(TerminationPoint.class, new TerminationPointKey(new TpId(otnTopologyTp.getTpId()
565 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
567 networkTransactionService.put(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
572 networkTransactionService.commit().get();
573 } catch (InterruptedException | ExecutionException e) {
574 LOG.error("Error updating OTN links in otn-topology", e);
578 private List<Link> getOtnLinks(List<LinkId> linkIds) {
579 List<Link> links = new ArrayList<>();
580 for (LinkId linkId : linkIds) {
581 InstanceIdentifier<Link> iiLink = InstanceIdentifier.builder(Networks.class)
582 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
583 .augmentation(Network1.class)
584 .child(Link.class, new LinkKey(linkId))
586 ListenableFuture<Optional<Link>> linkOptLf = networkTransactionService
587 .read(LogicalDatastoreType.CONFIGURATION, iiLink);
588 if (linkOptLf.isDone()) {
590 if (linkOptLf.get().isPresent()) {
591 links.add(linkOptLf.get().get());
593 } catch (InterruptedException | ExecutionException e) {
594 LOG.error("Error retreiving OTN links from otn-topology", e);
597 LOG.error("Error retreiving link {} from otn-topology", linkId.getValue());
603 private boolean checkLinks(List<Link> links) {
604 if (links.isEmpty()) {
607 for (Link link : links) {
608 if (link.augmentation(Link1.class) != null
609 && !link.augmentation(Link1.class).getUsedBandwidth().equals(Uint32.valueOf(0))) {
616 private boolean checkTerminationPoints(List<TerminationPoint> tps) {
620 for (TerminationPoint tp : tps) {
621 if (tp.augmentation(TerminationPoint1.class) != null && tp.augmentation(TerminationPoint1.class)
622 .getXpdrTpPortConnectionAttributes().getTsPool() != null && tp.augmentation(TerminationPoint1.class)
623 .getXpdrTpPortConnectionAttributes().getTsPool().size() != 80) {
630 private List<TerminationPoint> getOtnNodeTps(String nodeTopoA, String tpA, String nodeTopoZ, String tpZ) {
631 List<TerminationPoint> tps = new ArrayList<>();
632 InstanceIdentifier<TerminationPoint> iiTpA = InstanceIdentifier.builder(Networks.class)
633 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
634 .child(Node.class, new NodeKey(new NodeId(nodeTopoA)))
635 .augmentation(Node1.class)
636 .child(TerminationPoint.class, new TerminationPointKey(new TpId(tpA)))
638 Optional<TerminationPoint> tpAOpt = Optional.empty();
639 InstanceIdentifier<TerminationPoint> iiTpZ = InstanceIdentifier.builder(Networks.class)
640 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
641 .child(Node.class, new NodeKey(new NodeId(nodeTopoZ)))
642 .augmentation(Node1.class)
643 .child(TerminationPoint.class, new TerminationPointKey(new TpId(tpZ)))
645 Optional<TerminationPoint> tpZOpt = Optional.empty();
647 if (networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpA).isDone()
648 && networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpZ).isDone()) {
650 tpAOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpA).get();
651 tpZOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpZ).get();
652 } catch (InterruptedException | ExecutionException e) {
653 LOG.error("Error retreiving tp {} of node {} or tp {} from node {} from otn-topology", tpA, nodeTopoA,
657 LOG.error("error getting node termination points from the datastore");
660 if (tpAOpt.isPresent() && tpZOpt.isPresent()) {
661 tps.add(tpAOpt.get());
662 tps.add(tpZOpt.get());
667 private List<TerminationPoint> getOtnNodeTps(List<LinkTp> linkTerminations) {
668 List<TerminationPoint> tps = new ArrayList<>();
669 for (LinkTp linkTp : linkTerminations) {
670 String tp = linkTp.getTpId();
671 String nodeId = new StringBuilder(linkTp.getNodeId()).append("-")
672 .append(tp.split("-")[0]).toString();
673 InstanceIdentifier<TerminationPoint> iiTp = InstanceIdentifier.builder(Networks.class)
674 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
675 .child(Node.class, new NodeKey(new NodeId(nodeId)))
676 .augmentation(Node1.class)
677 .child(TerminationPoint.class, new TerminationPointKey(new TpId(tp)))
679 Optional<TerminationPoint> tpOpt;
680 if (networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTp).isDone()) {
682 tpOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTp).get();
683 if (tpOpt.isPresent()) {
684 tps.add(tpOpt.get());
686 } catch (InterruptedException | ExecutionException e) {
687 LOG.error("Error retreiving tp {} of node {} from otn-topology", tp, nodeId, e);
690 LOG.error("error getting node termination points from the datastore");
694 LOG.warn("returning null");
697 LOG.info("returning tps = {}", tps.toString());
702 private void deleteLinks(List<Link> links) {
703 for (Link otnTopologyLink : links) {
704 LOG.info("deleting link {} from {}", otnTopologyLink.getLinkId().getValue(),
705 NetworkUtils.OVERLAY_NETWORK_ID);
706 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
707 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
708 .augmentation(Network1.class)
709 .child(Link.class, otnTopologyLink.key())
711 networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink);
714 networkTransactionService.commit().get();
715 } catch (InterruptedException | ExecutionException e) {
716 LOG.error("Error deleting OTN links from otn-topology", e);
720 private List<Link> getSupportingOdu4Links(List<LinkTp> nodesTopoTps) {
721 InstanceIdentifier<Network1> iiOtnTopologyLinks = InstanceIdentifier.builder(Networks.class)
722 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
723 .augmentation(Network1.class)
725 ListenableFuture<Optional<Network1>> netw1Fl = networkTransactionService
726 .read(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLinks);
727 Optional<Network1> netw1Opt = Optional.empty();
728 if (netw1Fl.isDone()) {
730 netw1Opt = netw1Fl.get();
731 } catch (InterruptedException | ExecutionException e) {
732 LOG.error("Error retreiving list of links from otn-topology", e);
735 List<Link> odu4links = null;
736 if (netw1Opt.isPresent() && netw1Opt.get().getLink() != null) {
739 .nonnullLink().values()
740 .stream().filter(lk -> lk.getLinkId().getValue().startsWith("ODU4"))
741 .collect(Collectors.toList());
743 List<Link> links = new ArrayList<>();
744 if (odu4links != null) {
745 for (LinkTp linkTp : nodesTopoTps) {
746 String tp = linkTp.getTpId();
747 String nodeId = new StringBuilder(linkTp.getNodeId()).append("-")
748 .append(tp.split("-")[0]).toString();
749 Link slink = odu4links.stream().filter(lk -> lk.getSource().getSourceNode().getValue()
750 .equals(nodeId) && lk.getSource().getSourceTp().toString().equals(tp)).findFirst().get();
751 if (!links.contains(slink)) {
754 Link dlink = odu4links.stream().filter(lk -> lk.getDestination().getDestNode().getValue()
755 .equals(nodeId) && lk.getDestination().getDestTp().toString().equals(tp)).findFirst().get();
756 if (!links.contains(dlink)) {
760 LOG.debug("odu4links = {}", links.toString());
767 private void createOpenRoadmOtnNode(String nodeId) {
768 TopologyShard otnTopologyShard = OpenRoadmOtnTopology.createTopologyShard(portMapping.getNode(nodeId));
769 if (otnTopologyShard != null) {
770 this.otnTopologyShardMountedDevice.put(nodeId, otnTopologyShard);
771 for (Node otnTopologyNode : otnTopologyShard.getNodes()) {
772 LOG.info("creating otn node {} in {}", otnTopologyNode.getNodeId().getValue(),
773 NetworkUtils.OTN_NETWORK_ID);
774 InstanceIdentifier<Node> iiOtnTopologyNode = InstanceIdentifier.builder(Networks.class)
775 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
776 .child(Node.class, otnTopologyNode.key())
778 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyNode, otnTopologyNode);
780 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
781 LOG.info("creating otn link {} in {}", otnTopologyLink.getLinkId().getValue(),
782 NetworkUtils.OVERLAY_NETWORK_ID);
783 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
784 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
785 .augmentation(Network1.class)
786 .child(Link.class, otnTopologyLink.key())
788 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
791 LOG.error("Unable to create OTN topology shard for node {}!", nodeId);
796 value = "UPM_UNCALLED_PRIVATE_METHOD",
797 justification = "false positive, this method is used by public updateOpenRoadmNetworkTopology")
798 private void sendNotification() {
799 if (topologyChanges.isEmpty()) {
800 LOG.warn("Empty Topology Change List. No updates in topology");
803 this.notification = new TopologyUpdateResultBuilder()
804 .setTopologyChanges(topologyChanges)
807 notificationPublishService.putNotification(this.notification);
808 } catch (InterruptedException e) {
809 LOG.error("Notification offer rejected. Error={}", e.getMessage());