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.DataBroker;
23 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
24 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
25 import org.opendaylight.transportpce.common.InstanceIdentifiers;
26 import org.opendaylight.transportpce.common.NetworkUtils;
27 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
28 import org.opendaylight.transportpce.common.mapping.PortMapping;
29 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
30 import org.opendaylight.transportpce.networkmodel.R2RLinkDiscovery;
31 import org.opendaylight.transportpce.networkmodel.dto.TopologyShard;
32 import org.opendaylight.transportpce.networkmodel.util.ClliNetwork;
33 import org.opendaylight.transportpce.networkmodel.util.LinkIdUtil;
34 import org.opendaylight.transportpce.networkmodel.util.OpenRoadmNetwork;
35 import org.opendaylight.transportpce.networkmodel.util.OpenRoadmOtnTopology;
36 import org.opendaylight.transportpce.networkmodel.util.OpenRoadmTopology;
37 import org.opendaylight.transportpce.networkmodel.util.TopologyUtils;
38 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.TopologyUpdateResult;
39 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.TopologyUpdateResultBuilder;
40 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.topology.update.result.TopologyChanges;
41 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.topology.update.result.TopologyChangesBuilder;
42 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.topology.update.result.TopologyChangesKey;
43 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkutils.rev220630.OtnLinkType;
44 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220922.OpenroadmNodeVersion;
45 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220922.mapping.Mapping;
46 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220922.network.nodes.NodeInfo;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.types.rev191129.NodeTypes;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev230526.Link1;
49 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev230526.TerminationPoint1;
50 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev220926.link.tp.LinkTp;
51 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev220926.link.tp.LinkTpBuilder;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NetworkId;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.Networks;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.NetworkKey;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.NodeKey;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.LinkId;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Network1;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1;
62 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.TpId;
63 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link;
64 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.LinkKey;
65 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPoint;
66 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointKey;
67 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.termination.point.SupportingTerminationPoint;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.ConnectionOper.ConnectionStatus;
69 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
70 import org.opendaylight.yangtools.yang.common.Uint32;
71 import org.osgi.service.component.annotations.Activate;
72 import org.osgi.service.component.annotations.Component;
73 import org.osgi.service.component.annotations.Reference;
74 import org.slf4j.Logger;
75 import org.slf4j.LoggerFactory;
77 @Component(immediate = true)
78 public class NetworkModelServiceImpl implements NetworkModelService {
80 private static final Logger LOG = LoggerFactory.getLogger(NetworkModelServiceImpl.class);
82 private NetworkTransactionService networkTransactionService;
83 private final R2RLinkDiscovery linkDiscovery;
84 private final PortMapping portMapping;
85 private Map<String, TopologyShard> topologyShardMountedDevice;
86 private Map<String, TopologyShard> otnTopologyShardMountedDevice;
87 // Variables for creating and sending topology update notification
88 private final NotificationPublishService notificationPublishService;
89 private Map<TopologyChangesKey, TopologyChanges> topologyChanges;
90 private TopologyUpdateResult notification = null;
93 public NetworkModelServiceImpl(@Reference DataBroker dataBroker,
94 @Reference DeviceTransactionManager deviceTransactionManager,
95 @Reference final NetworkTransactionService networkTransactionService,
96 @Reference PortMapping portMapping,
97 @Reference final NotificationPublishService notificationPublishService) {
99 this.networkTransactionService = networkTransactionService;
100 this.linkDiscovery = new R2RLinkDiscovery(dataBroker, deviceTransactionManager, networkTransactionService);
101 this.portMapping = portMapping;
102 this.topologyShardMountedDevice = new HashMap<String, TopologyShard>();
103 this.otnTopologyShardMountedDevice = new HashMap<String, TopologyShard>();
104 this.notificationPublishService = notificationPublishService;
105 this.topologyChanges = new HashMap<TopologyChangesKey, TopologyChanges>();
106 LOG.debug("NetworkModelServiceImpl instantiated");
110 public void createOpenRoadmNode(String nodeId, String openRoadmVersion) {
112 LOG.info("createOpenROADMNode: {} ", nodeId);
115 if (portMapping.getNode(nodeId) == null) {
118 LOG.info("{} already exists in portmapping but was reconnected", nodeId);
122 if (!portMapping.createMappingData(nodeId, openRoadmVersion)) {
123 LOG.warn("Could not generate port mapping for {} skipping network model creation", nodeId);
126 NodeInfo nodeInfo = portMapping.getNode(nodeId).getNodeInfo();
127 // node creation in clli-network
128 Node clliNode = ClliNetwork.createNode(nodeId, nodeInfo);
129 InstanceIdentifier<Node> iiClliNode = InstanceIdentifier.builder(Networks.class)
130 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.CLLI_NETWORK_ID)))
131 .child(Node.class, clliNode.key())
133 LOG.info("creating node in {}", NetworkUtils.CLLI_NETWORK_ID);
134 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiClliNode, clliNode);
136 // node creation in openroadm-network
137 Node openroadmNetworkNode = OpenRoadmNetwork.createNode(nodeId, nodeInfo);
138 InstanceIdentifier<Node> iiopenroadmNetworkNode = InstanceIdentifier.builder(Networks.class)
139 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID)))
140 .child(Node.class, openroadmNetworkNode.key())
142 LOG.info("creating node in {}", NetworkUtils.UNDERLAY_NETWORK_ID);
143 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiopenroadmNetworkNode,
144 openroadmNetworkNode);
146 // nodes/links creation in openroadm-topology
147 TopologyShard topologyShard = OpenRoadmTopology.createTopologyShard(portMapping.getNode(nodeId),
149 if (topologyShard != null) {
150 this.topologyShardMountedDevice.put(nodeId, topologyShard);
151 for (Node openRoadmTopologyNode : topologyShard.getNodes()) {
152 LOG.info("creating node {} in {}", openRoadmTopologyNode.getNodeId().getValue(),
153 NetworkUtils.OVERLAY_NETWORK_ID);
154 InstanceIdentifier<Node> iiOpenRoadmTopologyNode = InstanceIdentifier.builder(Networks.class)
155 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
156 .child(Node.class, openRoadmTopologyNode.key())
158 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyNode,
159 openRoadmTopologyNode);
161 for (Link openRoadmTopologyLink : topologyShard.getLinks()) {
162 LOG.info("creating link {} in {}", openRoadmTopologyLink.getLinkId().getValue(),
163 NetworkUtils.OVERLAY_NETWORK_ID);
164 InstanceIdentifier<Link> iiOpenRoadmTopologyLink = InstanceIdentifier.builder(Networks.class)
165 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
166 .augmentation(Network1.class)
167 .child(Link.class, openRoadmTopologyLink.key())
169 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyLink,
170 openRoadmTopologyLink);
173 LOG.error("Unable to create openroadm-topology shard for node {}!", nodeId);
175 // nodes/links creation in otn-topology
176 if (nodeInfo.getNodeType().getIntValue() == 2 && (nodeInfo.getOpenroadmVersion().getIntValue() != 1)) {
177 createOpenRoadmOtnNode(nodeId);
179 networkTransactionService.commit().get();
180 // neighbour links through LLDP
181 if (nodeInfo.getNodeType().getIntValue() == 1) {
182 this.linkDiscovery.readLLDP(new NodeId(nodeId), openRoadmVersion);
184 LOG.info("all nodes and links created");
185 } catch (InterruptedException | ExecutionException e) {
186 LOG.error("ERROR: ", e);
191 public void setOpenRoadmNodeStatus(String nodeId, ConnectionStatus connectionStatus) {
192 LOG.info("setOpenROADMNodeStatus: {} {}", nodeId, connectionStatus.name());
194 TODO: set connection status of the device in model,
195 TODO: so we don't need to keep it in memory (Set<String> currentMountedDevice)
196 TODO: unfortunately there is no connection status OpenROADM in network models
197 TODO: waiting for new model version
202 @see org.opendaylight.transportpce.networkmodel.service.NetworkModelService# deleteOpenROADMnode(java.lang.String)
206 public boolean deleteOpenRoadmnode(String nodeId) {
208 if (!this.portMapping.isNodeExist(nodeId)) {
211 NodeKey nodeIdKey = new NodeKey(new NodeId(nodeId));
213 LOG.info("deleting node in {}", NetworkUtils.UNDERLAY_NETWORK_ID);
214 InstanceIdentifier<Node> iiopenroadmNetworkNode = InstanceIdentifier.builder(Networks.class)
215 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID)))
216 .child(Node.class, nodeIdKey)
218 this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiopenroadmNetworkNode);
220 TopologyShard topologyShard = this.topologyShardMountedDevice.get(nodeId);
221 if (topologyShard != null) {
222 for (Node openRoadmTopologyNode : topologyShard.getNodes()) {
223 LOG.info("deleting node {} in {}", openRoadmTopologyNode.getNodeId().getValue(),
224 NetworkUtils.OVERLAY_NETWORK_ID);
225 InstanceIdentifier<Node> iiOpenRoadmTopologyNode = InstanceIdentifier.builder(Networks.class)
226 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
227 .child(Node.class, openRoadmTopologyNode.key())
229 this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyNode);
231 for (Link openRoadmTopologyLink : topologyShard.getLinks()) {
232 LOG.info("deleting link {} in {}", openRoadmTopologyLink.getLinkId().getValue(),
233 NetworkUtils.OVERLAY_NETWORK_ID);
234 InstanceIdentifier<Link> iiOpenRoadmTopologyLink = InstanceIdentifier.builder(Networks.class)
235 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
236 .augmentation(Network1.class)
237 .child(Link.class, openRoadmTopologyLink.key())
239 this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyLink);
242 LOG.warn("TopologyShard for node '{}' is not present", nodeId);
245 OpenroadmNodeVersion deviceVersion = this.portMapping.getNode(nodeId).getNodeInfo().getOpenroadmVersion();
247 NodeTypes nodeType = this.portMapping.getNode(nodeId).getNodeInfo().getNodeType();
248 if (nodeType.getIntValue() == 2 && deviceVersion.getIntValue() != 1) {
249 TopologyShard otnTopologyShard = this.otnTopologyShardMountedDevice.get(nodeId);
250 if (otnTopologyShard != null) {
251 LOG.info("suppression de otnTopologyShard = {}", otnTopologyShard.toString());
252 for (Node otnTopologyNode : otnTopologyShard.getNodes()) {
253 LOG.info("deleting node {} in {}", otnTopologyNode.getNodeId().getValue(),
254 NetworkUtils.OTN_NETWORK_ID);
255 InstanceIdentifier<Node> iiotnTopologyNode = InstanceIdentifier.builder(Networks.class)
256 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
257 .child(Node.class, otnTopologyNode.key())
259 this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiotnTopologyNode);
261 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
262 LOG.info("deleting link {} in {}", otnTopologyLink.getLinkId().getValue(),
263 NetworkUtils.OTN_NETWORK_ID);
264 InstanceIdentifier<Link> iiotnTopologyLink = InstanceIdentifier.builder(Networks.class)
265 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
266 .augmentation(Network1.class)
267 .child(Link.class, otnTopologyLink.key())
269 this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiotnTopologyLink);
274 LOG.info("deleteOpenROADMnode: {} version {}", nodeId, deviceVersion.getName());
275 this.portMapping.deletePortMappingNode(nodeId);
277 this.networkTransactionService.commit().get(1, TimeUnit.SECONDS);
278 LOG.info("all nodes and links deleted ! ");
279 } catch (InterruptedException | ExecutionException | TimeoutException e) {
280 LOG.error("Error when trying to delete node : {}", nodeId, e);
287 public void updateOpenRoadmTopologies(String nodeId, Mapping mapping) {
288 LOG.info("update OpenRoadm topologies after change update from: {} ", nodeId);
289 this.topologyChanges.clear();
290 Network openroadmTopology = null;
291 Network otnTopology = null;
292 Map<LinkKey, Link> openroadmTopologyLinks = null;
293 Map<LinkKey, Link> otnTopologyLinks = null;
295 openroadmTopology = this.networkTransactionService
296 .read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifiers.OVERLAY_NETWORK_II)
297 .get().orElseThrow();
298 if (openroadmTopology.augmentation(Network1.class) != null) {
299 openroadmTopologyLinks = openroadmTopology.augmentation(Network1.class).getLink();
301 otnTopology = this.networkTransactionService
302 .read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifiers.OTN_NETWORK_II)
303 .get().orElseThrow();
304 if (otnTopology.augmentation(Network1.class) != null) {
305 otnTopologyLinks = otnTopology.augmentation(Network1.class).getLink();
307 } catch (InterruptedException | ExecutionException e) {
308 LOG.error("Error when trying to update node : {}", nodeId, e);
310 if (openroadmTopology == null || otnTopology == null) {
311 LOG.warn("Error getting topologies from datastore");
314 String abstractNodeid = String.join("-", nodeId, mapping.getLogicalConnectionPoint().split("-")[0]);
315 // nodes/links update in openroadm-topology
316 if (openroadmTopology.getNode() != null) {
317 TopologyShard topologyShard = TopologyUtils.updateTopologyShard(abstractNodeid, mapping,
318 openroadmTopology.getNode(), openroadmTopologyLinks);
319 if (topologyShard.getLinks() != null) {
320 for (Link link : topologyShard.getLinks()) {
321 LOG.info("updating links {} in {}", link.getLinkId().getValue(),
322 NetworkUtils.OVERLAY_NETWORK_ID);
323 InstanceIdentifier<Link> iiTopologyLink = InstanceIdentifier.builder(Networks.class)
324 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
325 .augmentation(Network1.class)
326 .child(Link.class, link.key())
328 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyLink, link);
331 if (topologyShard.getTps() != null) {
332 for (TerminationPoint tp : topologyShard.getTps()) {
333 LOG.info("updating TP {} in openroadm-topology", tp.getTpId().getValue());
334 InstanceIdentifier<TerminationPoint> iiTopologyTp = InstanceIdentifier.builder(Networks.class)
335 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
336 .child(Node.class, new NodeKey(new NodeId(abstractNodeid)))
337 .augmentation(Node1.class)
338 .child(TerminationPoint.class, new TerminationPointKey(tp.getTpId()))
340 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyTp, tp);
341 TopologyChanges tc = new TopologyChangesBuilder()
342 .withKey(new TopologyChangesKey(abstractNodeid, tp.getTpId().getValue()))
343 .setNodeId(abstractNodeid)
344 .setTpId(tp.getTpId().getValue())
345 .setState(tp.augmentation(
346 org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev230526.TerminationPoint1
347 .class).getOperationalState())
349 if (!this.topologyChanges.containsKey(tc.key())) {
350 this.topologyChanges.put(tc.key(), tc);
355 // nodes/links update in otn-topology
356 if (otnTopology.getNode() != null
357 && otnTopology.getNode().containsKey(new NodeKey(new NodeId(abstractNodeid)))) {
358 TopologyShard otnShard = TopologyUtils.updateTopologyShard(abstractNodeid, mapping,
359 otnTopology.getNode(), otnTopologyLinks);
360 if (otnShard.getLinks() != null) {
361 for (Link link : otnShard.getLinks()) {
362 LOG.info("updating links {} in {}", link.getLinkId().getValue(),
363 NetworkUtils.OVERLAY_NETWORK_ID);
364 InstanceIdentifier<Link> iiTopologyLink = InstanceIdentifier.builder(Networks.class)
365 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
366 .augmentation(Network1.class)
367 .child(Link.class, link.key())
369 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyLink, link);
372 if (otnShard.getTps() != null) {
373 for (TerminationPoint tp : otnShard.getTps()) {
374 LOG.info("updating TP {} in otn-topology", tp.getTpId().getValue());
375 InstanceIdentifier<TerminationPoint> iiTopologyTp = InstanceIdentifier.builder(Networks.class)
376 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
377 .child(Node.class, new NodeKey(new NodeId(abstractNodeid)))
378 .augmentation(Node1.class)
379 .child(TerminationPoint.class, new TerminationPointKey(tp.getTpId()))
381 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyTp, tp);
382 TopologyChanges tc = new TopologyChangesBuilder()
383 .withKey(new TopologyChangesKey(abstractNodeid, tp.getTpId().getValue()))
384 .setNodeId(abstractNodeid)
385 .setTpId(tp.getTpId().getValue())
386 .setState(tp.augmentation(
387 org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev230526.TerminationPoint1
388 .class).getOperationalState())
390 if (!this.topologyChanges.containsKey(tc.key())) {
391 this.topologyChanges.put(tc.key(), tc);
396 // commit datastore updates
398 networkTransactionService.commit().get();
400 } catch (InterruptedException | ExecutionException e) {
401 LOG.error("Error updating openroadm-topology", e);
406 public void createOtnLinks(
407 org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.renderer.rpc.result.sp.Link
408 notifLink, List<String> suppLinks, OtnLinkType linkType) {
410 TopologyShard otnTopologyShard;
416 otnTopologyShard = OpenRoadmOtnTopology.createOtnLinks(notifLink, null, null, linkType);
422 List<LinkId> linkIdList = new ArrayList<>();
423 if (suppLinks != null) {
424 suppLinks.forEach(lk -> linkIdList.add(new LinkId(lk)));
426 List<Link> supportedOtu4links = getOtnLinks(linkIdList);
427 String nodeTopoA = convertNetconfNodeIdToTopoNodeId(notifLink.getATermination().getNodeId(),
428 notifLink.getATermination().getTpId());
429 String nodeTopoZ = convertNetconfNodeIdToTopoNodeId(notifLink.getZTermination().getNodeId(),
430 notifLink.getZTermination().getTpId());
431 List<TerminationPoint> tps = getOtnNodeTps(nodeTopoA, notifLink.getATermination().getTpId(), nodeTopoZ,
432 notifLink.getZTermination().getTpId());
433 otnTopologyShard = OpenRoadmOtnTopology.createOtnLinks(notifLink, supportedOtu4links, tps, linkType);
436 LOG.error("unknown otn link type {}", linkType);
437 otnTopologyShard = new TopologyShard(null, null);
439 if (otnTopologyShard.getLinks() != null) {
440 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
441 LOG.info("creating and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(),
442 NetworkUtils.OVERLAY_NETWORK_ID);
443 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
444 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
445 .augmentation(Network1.class)
446 .child(Link.class, otnTopologyLink.key())
448 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
451 if (otnTopologyShard.getTps() != null) {
452 for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) {
453 LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue());
454 List<SupportingTerminationPoint> supportingTerminationPoint =
455 new ArrayList<>(otnTopologyTp.nonnullSupportingTerminationPoint().values());
456 InstanceIdentifier<TerminationPoint> iiOtnTopologyTp = InstanceIdentifier.builder(Networks.class)
457 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
458 .child(Node.class, new NodeKey(supportingTerminationPoint.get(0).getNodeRef()))
459 .augmentation(Node1.class)
460 .child(TerminationPoint.class, new TerminationPointKey(otnTopologyTp.getTpId()))
462 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
466 networkTransactionService.commit().get();
467 } catch (InterruptedException | ExecutionException e) {
468 LOG.error("Error adding OTN links in otn-topology", e);
470 LOG.info("OTN links created");
474 public void deleteOtnLinks(
475 org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.renderer.rpc.result.sp.Link
476 notifLink, List<String> suppLinks, OtnLinkType linkType) {
478 TopologyShard otnTopologyShard;
479 String nodeTopoA = convertNetconfNodeIdToTopoNodeId(notifLink.getATermination().getNodeId(),
480 notifLink.getATermination().getTpId());
481 String nodeTopoZ = convertNetconfNodeIdToTopoNodeId(notifLink.getZTermination().getNodeId(),
482 notifLink.getZTermination().getTpId());
483 String tpA = notifLink.getATermination().getTpId();
484 String tpZ = notifLink.getZTermination().getTpId();
486 List<LinkId> linkIdList = new ArrayList<>();
492 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, linkType.getName()));
493 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, linkType.getName()));
494 otuLinks = getOtnLinks(linkIdList);
495 if (checkLinks(otuLinks)) {
496 deleteLinks(otuLinks);
498 LOG.error("Error deleting OTU4 links");
500 otnTopologyShard = new TopologyShard(null, null);
506 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, linkType.getName()));
507 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, linkType.getName()));
508 List<Link> oduLinks = getOtnLinks(linkIdList);
509 List<TerminationPoint> tps = getOtnNodeTps(nodeTopoA, tpA, nodeTopoZ, tpZ);
510 if (checkLinks(oduLinks) && checkTerminationPoints(tps)) {
511 deleteLinks(oduLinks);
513 if (suppLinks != null) {
514 suppLinks.forEach(lk -> linkIdList.add(new LinkId(lk)));
516 otuLinks = getOtnLinks(linkIdList);
518 otnTopologyShard = OpenRoadmOtnTopology.deleteOtnLinks(otuLinks, tps, linkType);
520 LOG.error("Error deleting ODU4 links");
521 otnTopologyShard = new TopologyShard(null, null);
525 LOG.error("unknown otn link type {}", linkType);
526 otnTopologyShard = new TopologyShard(null, null);
529 if (otnTopologyShard.getLinks() != null) {
530 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
531 LOG.info("deleting and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(),
532 NetworkUtils.OVERLAY_NETWORK_ID);
533 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
534 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
535 .augmentation(Network1.class)
536 .child(Link.class, otnTopologyLink.key())
538 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
541 if (otnTopologyShard.getTps() != null) {
542 for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) {
543 LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue());
544 List<SupportingTerminationPoint> supportingTerminationPoint =
545 new ArrayList<>(otnTopologyTp.nonnullSupportingTerminationPoint().values());
546 InstanceIdentifier<TerminationPoint> iiOtnTopologyTp = InstanceIdentifier.builder(Networks.class)
547 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
548 .child(Node.class, new NodeKey(supportingTerminationPoint.get(0).getNodeRef()))
549 .augmentation(Node1.class)
550 .child(TerminationPoint.class, new TerminationPointKey(otnTopologyTp.getTpId()))
552 networkTransactionService.put(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
556 networkTransactionService.commit().get();
557 } catch (InterruptedException | ExecutionException e) {
558 LOG.error("Error deleting OTN links in otn-topology", e);
560 LOG.info("OTN links deletion terminated");
564 public void updateOtnLinks(
565 org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.renderer.rpc.result.sp.Link
566 notifLink, List<String> suppLinks, Uint32 serviceRate, Short tribPortNb, Short minTribSoltNb,
567 Short maxTribSlotNb, boolean isDeletion) {
569 List<LinkTp> linkTerminations = new ArrayList<>();
570 List<Link> supportedOdu4Links = null;
571 if (notifLink != null) {
572 // retreive termination-points to be updated
573 linkTerminations.add(new LinkTpBuilder()
574 .setNodeId(notifLink.getATermination().getNodeId())
575 .setTpId(notifLink.getATermination().getTpId())
577 linkTerminations.add(new LinkTpBuilder()
578 .setNodeId(notifLink.getZTermination().getNodeId())
579 .setTpId(notifLink.getZTermination().getTpId())
581 // retreive supported links
582 supportedOdu4Links = getSupportingOdu4Links(linkTerminations, serviceRate);
583 } else if (suppLinks != null) {
584 // retreive supported links
585 List<LinkId> linkIdList = new ArrayList<>();
586 if (suppLinks != null) {
587 suppLinks.forEach(lk -> linkIdList.add(new LinkId(lk)));
589 supportedOdu4Links = getOtnLinks(linkIdList);
590 // retreive termination-points to be updated
591 for (Link link : supportedOdu4Links) {
592 LinkTp atermination = new LinkTpBuilder()
593 .setNodeId(link.getSource().getSourceNode().getValue())
594 .setTpId(link.getSource().getSourceTp().getValue())
596 linkTerminations.add(atermination);
599 LOG.error("Impossible to update OTN links and their associated termination points in otn-topology");
602 List<TerminationPoint> tps = getOtnNodeTps(linkTerminations);
603 TopologyShard otnTopologyShard;
604 otnTopologyShard = OpenRoadmOtnTopology.updateOtnLinks(supportedOdu4Links, tps, serviceRate, tribPortNb,
605 minTribSoltNb, maxTribSlotNb, isDeletion);
606 if (otnTopologyShard.getLinks() != null) {
607 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
608 LOG.info("creating and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(),
609 NetworkUtils.OVERLAY_NETWORK_ID);
610 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
611 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
612 .augmentation(Network1.class)
613 .child(Link.class, new LinkKey(new LinkId(otnTopologyLink.getLinkId().getValue())))
615 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
618 if (otnTopologyShard.getTps() != null) {
619 for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) {
620 LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue());
621 List<SupportingTerminationPoint> supportingTerminationPoint =
622 new ArrayList<>(otnTopologyTp.nonnullSupportingTerminationPoint().values());
623 InstanceIdentifier<TerminationPoint> iiOtnTopologyTp = InstanceIdentifier.builder(Networks.class)
624 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
625 .child(Node.class, new NodeKey(supportingTerminationPoint.get(0).getNodeRef()))
626 .augmentation(Node1.class)
627 .child(TerminationPoint.class, new TerminationPointKey(new TpId(otnTopologyTp.getTpId()
631 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
633 networkTransactionService.put(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
638 networkTransactionService.commit().get();
639 } catch (InterruptedException | ExecutionException e) {
640 LOG.error("Error updating OTN links in otn-topology", e);
645 public void updateOtnLinks(List<String> suppLinks, boolean isDeletion) {
646 List<LinkId> linkIdList = new ArrayList<>();
647 if (suppLinks != null) {
648 suppLinks.forEach(lk -> linkIdList.add(new LinkId(lk)));
650 List<Link> supportedOtu4links = getOtnLinks(linkIdList);
652 TopologyShard otnTopologyShard = OpenRoadmOtnTopology.updateOtnLinks(supportedOtu4links, isDeletion);
653 if (otnTopologyShard.getLinks() != null) {
654 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
655 LOG.info("creating and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(),
656 NetworkUtils.OVERLAY_NETWORK_ID);
657 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
658 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
659 .augmentation(Network1.class)
660 .child(Link.class, otnTopologyLink.key())
662 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
666 networkTransactionService.commit().get();
667 } catch (InterruptedException | ExecutionException e) {
668 LOG.error("Error adding OTN links in otn-topology", e);
670 LOG.info("OTN links updated");
673 private List<Link> getOtnLinks(List<LinkId> linkIds) {
674 List<Link> links = new ArrayList<>();
675 for (LinkId linkId : linkIds) {
676 InstanceIdentifier<Link> iiLink = InstanceIdentifier.builder(Networks.class)
677 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
678 .augmentation(Network1.class)
679 .child(Link.class, new LinkKey(linkId))
681 ListenableFuture<Optional<Link>> linkOptLf = networkTransactionService
682 .read(LogicalDatastoreType.CONFIGURATION, iiLink);
683 if (linkOptLf.isDone()) {
685 if (linkOptLf.get().isPresent()) {
686 links.add(linkOptLf.get().orElseThrow());
688 } catch (InterruptedException | ExecutionException e) {
689 LOG.error("Error retreiving OTN links from otn-topology", e);
692 LOG.error("Error retreiving link {} from otn-topology", linkId.getValue());
698 private boolean checkLinks(List<Link> links) {
699 if (links.isEmpty()) {
702 for (Link link : links) {
703 if (link.augmentation(Link1.class) != null
704 && !link.augmentation(Link1.class).getUsedBandwidth().equals(Uint32.valueOf(0))) {
711 private boolean checkTerminationPoints(List<TerminationPoint> tps) {
715 for (TerminationPoint tp : tps) {
716 if (tp.augmentation(TerminationPoint1.class) != null && tp.augmentation(TerminationPoint1.class)
717 .getXpdrTpPortConnectionAttributes().getTsPool() != null && tp.augmentation(TerminationPoint1.class)
718 .getXpdrTpPortConnectionAttributes().getTsPool().size() != 80) {
725 private List<TerminationPoint> getOtnNodeTps(String nodeTopoA, String tpA, String nodeTopoZ, String tpZ) {
726 List<TerminationPoint> tps = new ArrayList<>();
727 InstanceIdentifier<TerminationPoint> iiTpA = InstanceIdentifier.builder(Networks.class)
728 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
729 .child(Node.class, new NodeKey(new NodeId(nodeTopoA)))
730 .augmentation(Node1.class)
731 .child(TerminationPoint.class, new TerminationPointKey(new TpId(tpA)))
733 Optional<TerminationPoint> tpAOpt = Optional.empty();
734 InstanceIdentifier<TerminationPoint> iiTpZ = InstanceIdentifier.builder(Networks.class)
735 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
736 .child(Node.class, new NodeKey(new NodeId(nodeTopoZ)))
737 .augmentation(Node1.class)
738 .child(TerminationPoint.class, new TerminationPointKey(new TpId(tpZ)))
740 Optional<TerminationPoint> tpZOpt = Optional.empty();
742 if (networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpA).isDone()
743 && networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpZ).isDone()) {
745 tpAOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpA).get();
746 tpZOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpZ).get();
747 } catch (InterruptedException | ExecutionException e) {
748 LOG.error("Error retreiving tp {} of node {} or tp {} from node {} from otn-topology", tpA, nodeTopoA,
752 LOG.error("error getting node termination points from the datastore");
755 if (tpAOpt.isPresent() && tpZOpt.isPresent()) {
756 tps.add(tpAOpt.orElseThrow());
757 tps.add(tpZOpt.orElseThrow());
762 private List<TerminationPoint> getOtnNodeTps(List<LinkTp> linkTerminations) {
763 List<TerminationPoint> tps = new ArrayList<>();
764 for (LinkTp linkTp : linkTerminations) {
765 String tp = linkTp.getTpId();
766 String nodeId = formatNodeName(linkTp.getNodeId(), tp);
767 InstanceIdentifier<TerminationPoint> iiTp = InstanceIdentifier.builder(Networks.class)
768 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
769 .child(Node.class, new NodeKey(new NodeId(nodeId)))
770 .augmentation(Node1.class)
771 .child(TerminationPoint.class, new TerminationPointKey(new TpId(tp)))
773 Optional<TerminationPoint> tpOpt;
774 if (networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTp).isDone()) {
776 tpOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTp).get();
777 if (tpOpt.isPresent()) {
778 tps.add(tpOpt.orElseThrow());
780 } catch (InterruptedException | ExecutionException e) {
781 LOG.error("Error retreiving tp {} of node {} from otn-topology", tp, nodeId, e);
784 LOG.error("error getting node termination points from the datastore");
790 private void deleteLinks(List<Link> links) {
791 for (Link otnTopologyLink : links) {
792 LOG.info("deleting link {} from {}", otnTopologyLink.getLinkId().getValue(),
793 NetworkUtils.OTN_NETWORK_ID);
794 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
795 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
796 .augmentation(Network1.class)
797 .child(Link.class, otnTopologyLink.key())
799 networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink);
802 networkTransactionService.commit().get();
803 } catch (InterruptedException | ExecutionException e) {
804 LOG.error("Error deleting OTN links from otn-topology", e);
808 private List<Link> getSupportingOdu4Links(List<LinkTp> nodesTopoTps, Uint32 serviceRate) {
809 InstanceIdentifier<Network1> iiOtnTopologyLinks = InstanceIdentifier.builder(Networks.class)
810 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
811 .augmentation(Network1.class)
813 ListenableFuture<Optional<Network1>> netw1Fl = networkTransactionService
814 .read(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLinks);
815 Optional<Network1> netw1Opt = Optional.empty();
816 if (netw1Fl.isDone()) {
818 netw1Opt = netw1Fl.get();
819 } catch (InterruptedException | ExecutionException e) {
820 LOG.error("Error retreiving list of links from otn-topology", e);
823 List<Link> odu4links = null;
824 if (netw1Opt.isPresent() && netw1Opt.orElseThrow().getLink() != null) {
827 .nonnullLink().values()
828 .stream().filter(lk -> lk.getLinkId().getValue()
829 .startsWith(Uint32.valueOf(100).equals(serviceRate) ? "ODUC4" : "ODTU4"))
830 .collect(Collectors.toList());
832 if (odu4links == null) {
835 List<Link> links = new ArrayList<>();
836 for (LinkTp linkTp : nodesTopoTps) {
837 String tp = linkTp.getTpId();
838 String nodeId = new StringBuilder(linkTp.getNodeId()).append("-")
839 .append(tp.split("-")[0]).toString();
840 Link slink = odu4links.stream().filter(lk -> lk.getSource().getSourceNode().getValue()
841 .equals(nodeId) && lk.getSource().getSourceTp().getValue().equals(tp)).findFirst().orElseThrow();
842 if (!links.contains(slink)) {
845 Link dlink = odu4links.stream().filter(lk -> lk.getDestination().getDestNode().getValue()
846 .equals(nodeId) && lk.getDestination().getDestTp().getValue().equals(tp)).findFirst().orElseThrow();
847 if (!links.contains(dlink)) {
851 LOG.debug("odu4oduC4links = {}", links);
855 private void createOpenRoadmOtnNode(String nodeId) {
856 TopologyShard otnTopologyShard = OpenRoadmOtnTopology.createTopologyShard(portMapping.getNode(nodeId));
857 if (otnTopologyShard != null) {
858 this.otnTopologyShardMountedDevice.put(nodeId, otnTopologyShard);
859 for (Node otnTopologyNode : otnTopologyShard.getNodes()) {
860 LOG.info("creating otn node {} in {}", otnTopologyNode.getNodeId().getValue(),
861 NetworkUtils.OTN_NETWORK_ID);
862 InstanceIdentifier<Node> iiOtnTopologyNode = InstanceIdentifier.builder(Networks.class)
863 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
864 .child(Node.class, otnTopologyNode.key())
866 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyNode, otnTopologyNode);
868 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
869 LOG.info("creating otn link {} in {}", otnTopologyLink.getLinkId().getValue(),
870 NetworkUtils.OVERLAY_NETWORK_ID);
871 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
872 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
873 .augmentation(Network1.class)
874 .child(Link.class, otnTopologyLink.key())
876 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
879 LOG.error("Unable to create OTN topology shard for node {}!", nodeId);
883 private String convertNetconfNodeIdToTopoNodeId(String nodeId, String tpId) {
884 return new StringBuilder(nodeId).append("-").append(tpId.split("-")[0]).toString();
887 private static String formatNodeName(String nodeName, String tpName) {
888 return nodeName.contains("-XPDR")
890 : new StringBuilder(nodeName).append("-").append(tpName.split("-")[0]).toString();
894 value = "UPM_UNCALLED_PRIVATE_METHOD",
895 justification = "false positive, this method is used by public updateOpenRoadmNetworkTopology")
896 private void sendNotification() {
897 if (topologyChanges.isEmpty()) {
898 LOG.warn("Empty Topology Change List. No updates in topology");
901 this.notification = new TopologyUpdateResultBuilder()
902 .setTopologyChanges(topologyChanges)
905 notificationPublishService.putNotification(this.notification);
906 } catch (InterruptedException e) {
907 LOG.error("Notification offer rejected. Error={}", e.getMessage());