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.networkutils.rev220630.OtnLinkType;
42 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220316.OpenroadmNodeVersion;
43 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220316.mapping.Mapping;
44 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220316.network.nodes.NodeInfo;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.types.rev191129.NodeTypes;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev211210.Link1;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev211210.TerminationPoint1;
48 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev210930.link.tp.LinkTp;
49 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev210930.link.tp.LinkTpBuilder;
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);
112 if (portMapping.getNode(nodeId) == null) {
115 LOG.info("{} already exists in portmapping but was reconnected", nodeId);
119 if (!portMapping.createMappingData(nodeId, openRoadmVersion)) {
120 LOG.warn("Could not generate port mapping for {} skipping network model creation", nodeId);
123 NodeInfo nodeInfo = portMapping.getNode(nodeId).getNodeInfo();
124 // node creation in clli-network
125 Node clliNode = ClliNetwork.createNode(nodeId, nodeInfo);
126 InstanceIdentifier<Node> iiClliNode = InstanceIdentifier.builder(Networks.class)
127 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.CLLI_NETWORK_ID)))
128 .child(Node.class, clliNode.key())
130 LOG.info("creating node in {}", NetworkUtils.CLLI_NETWORK_ID);
131 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiClliNode, clliNode);
133 // node creation in openroadm-network
134 Node openroadmNetworkNode = OpenRoadmNetwork.createNode(nodeId, nodeInfo);
135 InstanceIdentifier<Node> iiopenroadmNetworkNode = InstanceIdentifier.builder(Networks.class)
136 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID)))
137 .child(Node.class, openroadmNetworkNode.key())
139 LOG.info("creating node in {}", NetworkUtils.UNDERLAY_NETWORK_ID);
140 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiopenroadmNetworkNode,
141 openroadmNetworkNode);
143 // nodes/links creation in openroadm-topology
144 TopologyShard topologyShard = OpenRoadmTopology.createTopologyShard(portMapping.getNode(nodeId),
146 if (topologyShard != null) {
147 this.topologyShardMountedDevice.put(nodeId, topologyShard);
148 for (Node openRoadmTopologyNode : topologyShard.getNodes()) {
149 LOG.info("creating node {} in {}", openRoadmTopologyNode.getNodeId().getValue(),
150 NetworkUtils.OVERLAY_NETWORK_ID);
151 InstanceIdentifier<Node> iiOpenRoadmTopologyNode = InstanceIdentifier.builder(Networks.class)
152 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
153 .child(Node.class, openRoadmTopologyNode.key())
155 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyNode,
156 openRoadmTopologyNode);
158 for (Link openRoadmTopologyLink : topologyShard.getLinks()) {
159 LOG.info("creating link {} in {}", openRoadmTopologyLink.getLinkId().getValue(),
160 NetworkUtils.OVERLAY_NETWORK_ID);
161 InstanceIdentifier<Link> iiOpenRoadmTopologyLink = InstanceIdentifier.builder(Networks.class)
162 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
163 .augmentation(Network1.class)
164 .child(Link.class, openRoadmTopologyLink.key())
166 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyLink,
167 openRoadmTopologyLink);
170 LOG.error("Unable to create openroadm-topology shard for node {}!", nodeId);
172 // nodes/links creation in otn-topology
173 if (nodeInfo.getNodeType().getIntValue() == 2 && (nodeInfo.getOpenroadmVersion().getIntValue() != 1)) {
174 createOpenRoadmOtnNode(nodeId);
176 networkTransactionService.commit().get();
177 // neighbour links through LLDP
178 if (nodeInfo.getNodeType().getIntValue() == 1) {
179 this.linkDiscovery.readLLDP(new NodeId(nodeId), openRoadmVersion);
181 LOG.info("all nodes and links created");
182 } catch (InterruptedException | ExecutionException e) {
183 LOG.error("ERROR: ", e);
188 public void setOpenRoadmNodeStatus(String nodeId, NetconfNodeConnectionStatus.ConnectionStatus connectionStatus) {
189 LOG.info("setOpenROADMNodeStatus: {} {}", nodeId, connectionStatus.name());
191 TODO: set connection status of the device in model,
192 TODO: so we don't need to keep it in memory (Set<String> currentMountedDevice)
193 TODO: unfortunately there is no connection status OpenROADM in network models
194 TODO: waiting for new model version
199 @see org.opendaylight.transportpce.networkmodel.service.NetworkModelService# deleteOpenROADMnode(java.lang.String)
203 public boolean deleteOpenRoadmnode(String nodeId) {
205 if (!this.portMapping.isNodeExist(nodeId)) {
208 NodeKey nodeIdKey = new NodeKey(new NodeId(nodeId));
210 LOG.info("deleting node in {}", NetworkUtils.UNDERLAY_NETWORK_ID);
211 InstanceIdentifier<Node> iiopenroadmNetworkNode = InstanceIdentifier.builder(Networks.class)
212 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID)))
213 .child(Node.class, nodeIdKey)
215 this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiopenroadmNetworkNode);
217 TopologyShard topologyShard = this.topologyShardMountedDevice.get(nodeId);
218 if (topologyShard != null) {
219 for (Node openRoadmTopologyNode : topologyShard.getNodes()) {
220 LOG.info("deleting node {} in {}", openRoadmTopologyNode.getNodeId().getValue(),
221 NetworkUtils.OVERLAY_NETWORK_ID);
222 InstanceIdentifier<Node> iiOpenRoadmTopologyNode = InstanceIdentifier.builder(Networks.class)
223 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
224 .child(Node.class, openRoadmTopologyNode.key())
226 this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyNode);
228 for (Link openRoadmTopologyLink : topologyShard.getLinks()) {
229 LOG.info("deleting link {} in {}", openRoadmTopologyLink.getLinkId().getValue(),
230 NetworkUtils.OVERLAY_NETWORK_ID);
231 InstanceIdentifier<Link> iiOpenRoadmTopologyLink = InstanceIdentifier.builder(Networks.class)
232 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
233 .augmentation(Network1.class)
234 .child(Link.class, openRoadmTopologyLink.key())
236 this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyLink);
239 LOG.warn("TopologyShard for node '{}' is not present", nodeId);
242 OpenroadmNodeVersion deviceVersion = this.portMapping.getNode(nodeId).getNodeInfo().getOpenroadmVersion();
244 NodeTypes nodeType = this.portMapping.getNode(nodeId).getNodeInfo().getNodeType();
245 if (nodeType.getIntValue() == 2 && deviceVersion.getIntValue() != 1) {
246 TopologyShard otnTopologyShard = this.otnTopologyShardMountedDevice.get(nodeId);
247 if (otnTopologyShard != null) {
248 LOG.info("suppression de otnTopologyShard = {}", otnTopologyShard.toString());
249 for (Node otnTopologyNode : otnTopologyShard.getNodes()) {
250 LOG.info("deleting node {} in {}", otnTopologyNode.getNodeId().getValue(),
251 NetworkUtils.OTN_NETWORK_ID);
252 InstanceIdentifier<Node> iiotnTopologyNode = InstanceIdentifier.builder(Networks.class)
253 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
254 .child(Node.class, otnTopologyNode.key())
256 this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiotnTopologyNode);
258 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
259 LOG.info("deleting link {} in {}", otnTopologyLink.getLinkId().getValue(),
260 NetworkUtils.OTN_NETWORK_ID);
261 InstanceIdentifier<Link> iiotnTopologyLink = InstanceIdentifier.builder(Networks.class)
262 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
263 .augmentation(Network1.class)
264 .child(Link.class, otnTopologyLink.key())
266 this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiotnTopologyLink);
271 LOG.info("deleteOpenROADMnode: {} version {}", nodeId, deviceVersion.getName());
272 this.portMapping.deletePortMappingNode(nodeId);
274 this.networkTransactionService.commit().get(1, TimeUnit.SECONDS);
275 LOG.info("all nodes and links deleted ! ");
276 } catch (InterruptedException | ExecutionException | TimeoutException e) {
277 LOG.error("Error when trying to delete node : {}", nodeId, e);
284 public void updateOpenRoadmTopologies(String nodeId, Mapping mapping) {
285 LOG.info("update OpenRoadm topologies after change update from: {} ", nodeId);
286 this.topologyChanges.clear();
287 Network openroadmTopology = null;
288 Network otnTopology = null;
289 Map<LinkKey, Link> openroadmTopologyLinks = null;
290 Map<LinkKey, Link> otnTopologyLinks = null;
292 openroadmTopology = this.networkTransactionService
293 .read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifiers.OVERLAY_NETWORK_II)
295 if (openroadmTopology.augmentation(Network1.class) != null) {
296 openroadmTopologyLinks = openroadmTopology.augmentation(Network1.class).getLink();
298 otnTopology = this.networkTransactionService
299 .read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifiers.OTN_NETWORK_II)
301 if (otnTopology.augmentation(Network1.class) != null) {
302 otnTopologyLinks = otnTopology.augmentation(Network1.class).getLink();
304 } catch (InterruptedException | ExecutionException e) {
305 LOG.error("Error when trying to update node : {}", nodeId, e);
307 if (openroadmTopology == null || otnTopology == null) {
308 LOG.warn("Error getting topologies from datastore");
311 String abstractNodeid = String.join("-", nodeId, mapping.getLogicalConnectionPoint().split("-")[0]);
312 // nodes/links update in openroadm-topology
313 if (openroadmTopology.getNode() != null) {
314 TopologyShard topologyShard = TopologyUtils.updateTopologyShard(abstractNodeid, mapping,
315 openroadmTopology.getNode(), openroadmTopologyLinks);
316 if (topologyShard.getLinks() != null) {
317 for (Link link : topologyShard.getLinks()) {
318 LOG.info("updating links {} in {}", link.getLinkId().getValue(),
319 NetworkUtils.OVERLAY_NETWORK_ID);
320 InstanceIdentifier<Link> iiTopologyLink = InstanceIdentifier.builder(Networks.class)
321 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
322 .augmentation(Network1.class)
323 .child(Link.class, link.key())
325 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyLink, link);
328 if (topologyShard.getTps() != null) {
329 for (TerminationPoint tp : topologyShard.getTps()) {
330 LOG.info("updating TP {} in openroadm-topology", tp.getTpId().getValue());
331 InstanceIdentifier<TerminationPoint> iiTopologyTp = InstanceIdentifier.builder(Networks.class)
332 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
333 .child(Node.class, new NodeKey(new NodeId(abstractNodeid)))
334 .augmentation(Node1.class)
335 .child(TerminationPoint.class, new TerminationPointKey(tp.getTpId()))
337 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyTp, tp);
338 TopologyChanges tc = new TopologyChangesBuilder()
339 .withKey(new TopologyChangesKey(abstractNodeid, tp.getTpId().getValue()))
340 .setNodeId(abstractNodeid)
341 .setTpId(tp.getTpId().getValue())
342 .setState(tp.augmentation(
343 org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.TerminationPoint1
344 .class).getOperationalState())
346 if (!this.topologyChanges.containsKey(tc.key())) {
347 this.topologyChanges.put(tc.key(), tc);
352 // nodes/links update in otn-topology
353 if (otnTopology.getNode() != null
354 && otnTopology.getNode().containsKey(new NodeKey(new NodeId(abstractNodeid)))) {
355 TopologyShard otnShard = TopologyUtils.updateTopologyShard(abstractNodeid, mapping,
356 otnTopology.getNode(), otnTopologyLinks);
357 if (otnShard.getLinks() != null) {
358 for (Link link : otnShard.getLinks()) {
359 LOG.info("updating links {} in {}", link.getLinkId().getValue(),
360 NetworkUtils.OVERLAY_NETWORK_ID);
361 InstanceIdentifier<Link> iiTopologyLink = InstanceIdentifier.builder(Networks.class)
362 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
363 .augmentation(Network1.class)
364 .child(Link.class, link.key())
366 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyLink, link);
369 if (otnShard.getTps() != null) {
370 for (TerminationPoint tp : otnShard.getTps()) {
371 LOG.info("updating TP {} in otn-topology", tp.getTpId().getValue());
372 InstanceIdentifier<TerminationPoint> iiTopologyTp = InstanceIdentifier.builder(Networks.class)
373 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
374 .child(Node.class, new NodeKey(new NodeId(abstractNodeid)))
375 .augmentation(Node1.class)
376 .child(TerminationPoint.class, new TerminationPointKey(tp.getTpId()))
378 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyTp, tp);
379 TopologyChanges tc = new TopologyChangesBuilder()
380 .withKey(new TopologyChangesKey(abstractNodeid, tp.getTpId().getValue()))
381 .setNodeId(abstractNodeid)
382 .setTpId(tp.getTpId().getValue())
383 .setState(tp.augmentation(
384 org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.TerminationPoint1
385 .class).getOperationalState())
387 if (!this.topologyChanges.containsKey(tc.key())) {
388 this.topologyChanges.put(tc.key(), tc);
393 // commit datastore updates
395 networkTransactionService.commit().get();
397 } catch (InterruptedException | ExecutionException e) {
398 LOG.error("Error updating openroadm-topology", e);
403 public void createOtnLinks(
404 org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.renderer.rpc.result.sp.Link
405 notifLink, List<String> suppLinks, OtnLinkType linkType) {
407 TopologyShard otnTopologyShard;
413 otnTopologyShard = OpenRoadmOtnTopology.createOtnLinks(notifLink, null, null, linkType);
419 List<LinkId> linkIdList = new ArrayList<>();
420 if (suppLinks != null) {
421 suppLinks.forEach(lk -> linkIdList.add(new LinkId(lk)));
423 List<Link> supportedOtu4links = getOtnLinks(linkIdList);
424 String nodeTopoA = convertNetconfNodeIdToTopoNodeId(notifLink.getATermination().getNodeId(),
425 notifLink.getATermination().getTpId());
426 String nodeTopoZ = convertNetconfNodeIdToTopoNodeId(notifLink.getZTermination().getNodeId(),
427 notifLink.getZTermination().getTpId());
428 List<TerminationPoint> tps = getOtnNodeTps(nodeTopoA, notifLink.getATermination().getTpId(), nodeTopoZ,
429 notifLink.getZTermination().getTpId());
430 otnTopologyShard = OpenRoadmOtnTopology.createOtnLinks(notifLink, supportedOtu4links, tps, linkType);
433 LOG.error("unknown otn link type {}", linkType);
434 otnTopologyShard = new TopologyShard(null, null);
436 if (otnTopologyShard.getLinks() != null) {
437 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
438 LOG.info("creating and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(),
439 NetworkUtils.OVERLAY_NETWORK_ID);
440 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
441 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
442 .augmentation(Network1.class)
443 .child(Link.class, otnTopologyLink.key())
445 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
448 if (otnTopologyShard.getTps() != null) {
449 for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) {
450 LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue());
451 List<SupportingTerminationPoint> supportingTerminationPoint =
452 new ArrayList<>(otnTopologyTp.nonnullSupportingTerminationPoint().values());
453 InstanceIdentifier<TerminationPoint> iiOtnTopologyTp = InstanceIdentifier.builder(Networks.class)
454 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
455 .child(Node.class, new NodeKey(supportingTerminationPoint.get(0).getNodeRef()))
456 .augmentation(Node1.class)
457 .child(TerminationPoint.class, new TerminationPointKey(otnTopologyTp.getTpId()))
459 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
463 networkTransactionService.commit().get();
464 } catch (InterruptedException | ExecutionException e) {
465 LOG.error("Error adding OTN links in otn-topology", e);
467 LOG.info("OTN links created");
471 public void deleteOtnLinks(
472 org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.renderer.rpc.result.sp.Link
473 notifLink, List<String> suppLinks, OtnLinkType linkType) {
475 TopologyShard otnTopologyShard;
476 String nodeTopoA = convertNetconfNodeIdToTopoNodeId(notifLink.getATermination().getNodeId(),
477 notifLink.getATermination().getTpId());
478 String nodeTopoZ = convertNetconfNodeIdToTopoNodeId(notifLink.getZTermination().getNodeId(),
479 notifLink.getZTermination().getTpId());
480 String tpA = notifLink.getATermination().getTpId();
481 String tpZ = notifLink.getZTermination().getTpId();
483 List<LinkId> linkIdList = new ArrayList<>();
489 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, linkType.getName()));
490 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, linkType.getName()));
491 otuLinks = getOtnLinks(linkIdList);
492 if (checkLinks(otuLinks)) {
493 deleteLinks(otuLinks);
495 LOG.error("Error deleting OTU4 links");
497 otnTopologyShard = new TopologyShard(null, null);
503 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, linkType.getName()));
504 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, linkType.getName()));
505 List<Link> oduLinks = getOtnLinks(linkIdList);
506 List<TerminationPoint> tps = getOtnNodeTps(nodeTopoA, tpA, nodeTopoZ, tpZ);
507 if (checkLinks(oduLinks) && checkTerminationPoints(tps)) {
508 deleteLinks(oduLinks);
510 if (suppLinks != null) {
511 suppLinks.forEach(lk -> linkIdList.add(new LinkId(lk)));
513 otuLinks = getOtnLinks(linkIdList);
515 otnTopologyShard = OpenRoadmOtnTopology.deleteOtnLinks(otuLinks, tps, linkType);
517 LOG.error("Error deleting ODU4 links");
518 otnTopologyShard = new TopologyShard(null, null);
522 LOG.error("unknown otn link type {}", linkType);
523 otnTopologyShard = new TopologyShard(null, null);
526 if (otnTopologyShard.getLinks() != null) {
527 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
528 LOG.info("deleting and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(),
529 NetworkUtils.OVERLAY_NETWORK_ID);
530 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
531 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
532 .augmentation(Network1.class)
533 .child(Link.class, otnTopologyLink.key())
535 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
538 if (otnTopologyShard.getTps() != null) {
539 for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) {
540 LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue());
541 List<SupportingTerminationPoint> supportingTerminationPoint =
542 new ArrayList<>(otnTopologyTp.nonnullSupportingTerminationPoint().values());
543 InstanceIdentifier<TerminationPoint> iiOtnTopologyTp = InstanceIdentifier.builder(Networks.class)
544 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
545 .child(Node.class, new NodeKey(supportingTerminationPoint.get(0).getNodeRef()))
546 .augmentation(Node1.class)
547 .child(TerminationPoint.class, new TerminationPointKey(otnTopologyTp.getTpId()))
549 networkTransactionService.put(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
553 networkTransactionService.commit().get();
554 } catch (InterruptedException | ExecutionException e) {
555 LOG.error("Error deleting OTN links in otn-topology", e);
557 LOG.info("OTN links deletion terminated");
561 public void updateOtnLinks(
562 org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.renderer.rpc.result.sp.Link
563 notifLink, List<String> suppLinks, Uint32 serviceRate, Short tribPortNb, Short minTribSoltNb,
564 Short maxTribSlotNb, boolean isDeletion) {
566 List<LinkTp> linkTerminations = new ArrayList<>();
567 List<Link> supportedOdu4Links = null;
568 if (notifLink != null) {
569 // retreive termination-points to be updated
570 linkTerminations.add(new LinkTpBuilder()
571 .setNodeId(notifLink.getATermination().getNodeId())
572 .setTpId(notifLink.getATermination().getTpId())
574 linkTerminations.add(new LinkTpBuilder()
575 .setNodeId(notifLink.getZTermination().getNodeId())
576 .setTpId(notifLink.getZTermination().getTpId())
578 // retreive supported links
579 supportedOdu4Links = getSupportingOdu4Links(linkTerminations, serviceRate);
580 } else if (suppLinks != null) {
581 // retreive supported links
582 List<LinkId> linkIdList = new ArrayList<>();
583 if (suppLinks != null) {
584 suppLinks.forEach(lk -> linkIdList.add(new LinkId(lk)));
586 supportedOdu4Links = getOtnLinks(linkIdList);
587 // retreive termination-points to be updated
588 for (Link link : supportedOdu4Links) {
589 LinkTp atermination = new LinkTpBuilder()
590 .setNodeId(link.getSource().getSourceNode().getValue())
591 .setTpId(link.getSource().getSourceTp().getValue())
593 linkTerminations.add(atermination);
596 LOG.error("Impossible to update OTN links and their associated termination points in otn-topology");
599 List<TerminationPoint> tps = getOtnNodeTps(linkTerminations);
600 TopologyShard otnTopologyShard;
601 otnTopologyShard = OpenRoadmOtnTopology.updateOtnLinks(supportedOdu4Links, tps, serviceRate, tribPortNb,
602 minTribSoltNb, maxTribSlotNb, isDeletion);
603 if (otnTopologyShard.getLinks() != null) {
604 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
605 LOG.info("creating and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(),
606 NetworkUtils.OVERLAY_NETWORK_ID);
607 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
608 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
609 .augmentation(Network1.class)
610 .child(Link.class, new LinkKey(new LinkId(otnTopologyLink.getLinkId().getValue())))
612 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
615 if (otnTopologyShard.getTps() != null) {
616 for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) {
617 LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue());
618 List<SupportingTerminationPoint> supportingTerminationPoint =
619 new ArrayList<>(otnTopologyTp.nonnullSupportingTerminationPoint().values());
620 InstanceIdentifier<TerminationPoint> iiOtnTopologyTp = InstanceIdentifier.builder(Networks.class)
621 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
622 .child(Node.class, new NodeKey(supportingTerminationPoint.get(0).getNodeRef()))
623 .augmentation(Node1.class)
624 .child(TerminationPoint.class, new TerminationPointKey(new TpId(otnTopologyTp.getTpId()
628 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
630 networkTransactionService.put(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
635 networkTransactionService.commit().get();
636 } catch (InterruptedException | ExecutionException e) {
637 LOG.error("Error updating OTN links in otn-topology", e);
642 public void updateOtnLinks(List<String> suppLinks, boolean isDeletion) {
643 List<LinkId> linkIdList = new ArrayList<>();
644 if (suppLinks != null) {
645 suppLinks.forEach(lk -> linkIdList.add(new LinkId(lk)));
647 List<Link> supportedOtu4links = getOtnLinks(linkIdList);
649 TopologyShard otnTopologyShard = OpenRoadmOtnTopology.updateOtnLinks(supportedOtu4links, isDeletion);
650 if (otnTopologyShard.getLinks() != null) {
651 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
652 LOG.info("creating and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(),
653 NetworkUtils.OVERLAY_NETWORK_ID);
654 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
655 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
656 .augmentation(Network1.class)
657 .child(Link.class, otnTopologyLink.key())
659 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
663 networkTransactionService.commit().get();
664 } catch (InterruptedException | ExecutionException e) {
665 LOG.error("Error adding OTN links in otn-topology", e);
667 LOG.info("OTN links updated");
670 private List<Link> getOtnLinks(List<LinkId> linkIds) {
671 List<Link> links = new ArrayList<>();
672 for (LinkId linkId : linkIds) {
673 InstanceIdentifier<Link> iiLink = InstanceIdentifier.builder(Networks.class)
674 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
675 .augmentation(Network1.class)
676 .child(Link.class, new LinkKey(linkId))
678 ListenableFuture<Optional<Link>> linkOptLf = networkTransactionService
679 .read(LogicalDatastoreType.CONFIGURATION, iiLink);
680 if (linkOptLf.isDone()) {
682 if (linkOptLf.get().isPresent()) {
683 links.add(linkOptLf.get().get());
685 } catch (InterruptedException | ExecutionException e) {
686 LOG.error("Error retreiving OTN links from otn-topology", e);
689 LOG.error("Error retreiving link {} from otn-topology", linkId.getValue());
695 private boolean checkLinks(List<Link> links) {
696 if (links.isEmpty()) {
699 for (Link link : links) {
700 if (link.augmentation(Link1.class) != null
701 && !link.augmentation(Link1.class).getUsedBandwidth().equals(Uint32.valueOf(0))) {
708 private boolean checkTerminationPoints(List<TerminationPoint> tps) {
712 for (TerminationPoint tp : tps) {
713 if (tp.augmentation(TerminationPoint1.class) != null && tp.augmentation(TerminationPoint1.class)
714 .getXpdrTpPortConnectionAttributes().getTsPool() != null && tp.augmentation(TerminationPoint1.class)
715 .getXpdrTpPortConnectionAttributes().getTsPool().size() != 80) {
722 private List<TerminationPoint> getOtnNodeTps(String nodeTopoA, String tpA, String nodeTopoZ, String tpZ) {
723 List<TerminationPoint> tps = new ArrayList<>();
724 InstanceIdentifier<TerminationPoint> iiTpA = InstanceIdentifier.builder(Networks.class)
725 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
726 .child(Node.class, new NodeKey(new NodeId(nodeTopoA)))
727 .augmentation(Node1.class)
728 .child(TerminationPoint.class, new TerminationPointKey(new TpId(tpA)))
730 Optional<TerminationPoint> tpAOpt = Optional.empty();
731 InstanceIdentifier<TerminationPoint> iiTpZ = InstanceIdentifier.builder(Networks.class)
732 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
733 .child(Node.class, new NodeKey(new NodeId(nodeTopoZ)))
734 .augmentation(Node1.class)
735 .child(TerminationPoint.class, new TerminationPointKey(new TpId(tpZ)))
737 Optional<TerminationPoint> tpZOpt = Optional.empty();
739 if (networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpA).isDone()
740 && networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpZ).isDone()) {
742 tpAOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpA).get();
743 tpZOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpZ).get();
744 } catch (InterruptedException | ExecutionException e) {
745 LOG.error("Error retreiving tp {} of node {} or tp {} from node {} from otn-topology", tpA, nodeTopoA,
749 LOG.error("error getting node termination points from the datastore");
752 if (tpAOpt.isPresent() && tpZOpt.isPresent()) {
753 tps.add(tpAOpt.get());
754 tps.add(tpZOpt.get());
759 private List<TerminationPoint> getOtnNodeTps(List<LinkTp> linkTerminations) {
760 List<TerminationPoint> tps = new ArrayList<>();
761 for (LinkTp linkTp : linkTerminations) {
762 String tp = linkTp.getTpId();
763 String nodeId = formatNodeName(linkTp.getNodeId(), tp);
764 InstanceIdentifier<TerminationPoint> iiTp = InstanceIdentifier.builder(Networks.class)
765 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
766 .child(Node.class, new NodeKey(new NodeId(nodeId)))
767 .augmentation(Node1.class)
768 .child(TerminationPoint.class, new TerminationPointKey(new TpId(tp)))
770 Optional<TerminationPoint> tpOpt;
771 if (networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTp).isDone()) {
773 tpOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTp).get();
774 if (tpOpt.isPresent()) {
775 tps.add(tpOpt.get());
777 } catch (InterruptedException | ExecutionException e) {
778 LOG.error("Error retreiving tp {} of node {} from otn-topology", tp, nodeId, e);
781 LOG.error("error getting node termination points from the datastore");
787 private void deleteLinks(List<Link> links) {
788 for (Link otnTopologyLink : links) {
789 LOG.info("deleting link {} from {}", otnTopologyLink.getLinkId().getValue(),
790 NetworkUtils.OVERLAY_NETWORK_ID);
791 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
792 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
793 .augmentation(Network1.class)
794 .child(Link.class, otnTopologyLink.key())
796 networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink);
799 networkTransactionService.commit().get();
800 } catch (InterruptedException | ExecutionException e) {
801 LOG.error("Error deleting OTN links from otn-topology", e);
805 private List<Link> getSupportingOdu4Links(List<LinkTp> nodesTopoTps, Uint32 serviceRate) {
806 InstanceIdentifier<Network1> iiOtnTopologyLinks = InstanceIdentifier.builder(Networks.class)
807 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
808 .augmentation(Network1.class)
810 ListenableFuture<Optional<Network1>> netw1Fl = networkTransactionService
811 .read(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLinks);
812 Optional<Network1> netw1Opt = Optional.empty();
813 if (netw1Fl.isDone()) {
815 netw1Opt = netw1Fl.get();
816 } catch (InterruptedException | ExecutionException e) {
817 LOG.error("Error retreiving list of links from otn-topology", e);
820 List<Link> odu4links = null;
821 if (netw1Opt.isPresent() && netw1Opt.get().getLink() != null) {
824 .nonnullLink().values()
825 .stream().filter(lk -> lk.getLinkId().getValue()
826 .startsWith(Uint32.valueOf(100).equals(serviceRate) ? "ODUC4" : "ODTU4"))
827 .collect(Collectors.toList());
829 if (odu4links == null) {
832 List<Link> links = new ArrayList<>();
833 for (LinkTp linkTp : nodesTopoTps) {
834 String tp = linkTp.getTpId();
835 String nodeId = new StringBuilder(linkTp.getNodeId()).append("-")
836 .append(tp.split("-")[0]).toString();
837 Link slink = odu4links.stream().filter(lk -> lk.getSource().getSourceNode().getValue()
838 .equals(nodeId) && lk.getSource().getSourceTp().getValue().equals(tp)).findFirst().get();
839 if (!links.contains(slink)) {
842 Link dlink = odu4links.stream().filter(lk -> lk.getDestination().getDestNode().getValue()
843 .equals(nodeId) && lk.getDestination().getDestTp().getValue().equals(tp)).findFirst().get();
844 if (!links.contains(dlink)) {
848 LOG.debug("odu4oduC4links = {}", links);
852 private void createOpenRoadmOtnNode(String nodeId) {
853 TopologyShard otnTopologyShard = OpenRoadmOtnTopology.createTopologyShard(portMapping.getNode(nodeId));
854 if (otnTopologyShard != null) {
855 this.otnTopologyShardMountedDevice.put(nodeId, otnTopologyShard);
856 for (Node otnTopologyNode : otnTopologyShard.getNodes()) {
857 LOG.info("creating otn node {} in {}", otnTopologyNode.getNodeId().getValue(),
858 NetworkUtils.OTN_NETWORK_ID);
859 InstanceIdentifier<Node> iiOtnTopologyNode = InstanceIdentifier.builder(Networks.class)
860 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
861 .child(Node.class, otnTopologyNode.key())
863 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyNode, otnTopologyNode);
865 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
866 LOG.info("creating otn link {} in {}", otnTopologyLink.getLinkId().getValue(),
867 NetworkUtils.OVERLAY_NETWORK_ID);
868 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
869 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
870 .augmentation(Network1.class)
871 .child(Link.class, otnTopologyLink.key())
873 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
876 LOG.error("Unable to create OTN topology shard for node {}!", nodeId);
880 private String convertNetconfNodeIdToTopoNodeId(String nodeId, String tpId) {
881 return new StringBuilder(nodeId).append("-").append(tpId.split("-")[0]).toString();
884 private static String formatNodeName(String nodeName, String tpName) {
885 return nodeName.contains("-XPDR")
887 : new StringBuilder(nodeName).append("-").append(tpName.split("-")[0]).toString();
891 value = "UPM_UNCALLED_PRIVATE_METHOD",
892 justification = "false positive, this method is used by public updateOpenRoadmNetworkTopology")
893 private void sendNotification() {
894 if (topologyChanges.isEmpty()) {
895 LOG.warn("Empty Topology Change List. No updates in topology");
898 this.notification = new TopologyUpdateResultBuilder()
899 .setTopologyChanges(topologyChanges)
902 notificationPublishService.putNotification(this.notification);
903 } catch (InterruptedException e) {
904 LOG.error("Notification offer rejected. Error={}", e.getMessage());