Refactor SupportedIfCapability usage
[transportpce.git] / networkmodel / src / main / java / org / opendaylight / transportpce / networkmodel / service / NetworkModelServiceImpl.java
1 /*
2  * Copyright © 2016 AT&T and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.transportpce.networkmodel.service;
9
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;
15 import java.util.Map;
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.rev220316.OpenroadmNodeVersion;
42 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220316.mapping.Mapping;
43 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220316.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.rev211210.Link1;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev211210.TerminationPoint1;
47 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev210930.link.tp.LinkTp;
48 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev210930.link.tp.LinkTpBuilder;
49 import org.opendaylight.yang.gen.v1.http.transportpce.topology.rev220123.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;
71
72 public class NetworkModelServiceImpl implements NetworkModelService {
73
74     private static final Logger LOG = LoggerFactory.getLogger(NetworkModelServiceImpl.class);
75
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;
85
86     public NetworkModelServiceImpl(final NetworkTransactionService networkTransactionService,
87             final R2RLinkDiscovery linkDiscovery, PortMapping portMapping,
88             final NotificationPublishService notificationPublishService) {
89
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>();
97     }
98
99     public void init() {
100         LOG.info("init ...");
101     }
102
103     public void close() {
104     }
105
106     @Override
107     public void createOpenRoadmNode(String nodeId, String openRoadmVersion) {
108         try {
109             LOG.info("createOpenROADMNode: {} ", nodeId);
110
111             boolean firstMount;
112             if (portMapping.getNode(nodeId) == null) {
113                 firstMount = true;
114             } else {
115                 LOG.info("{} already exists in portmapping but was reconnected", nodeId);
116                 firstMount = false;
117             }
118
119             if (!portMapping.createMappingData(nodeId, openRoadmVersion)) {
120                 LOG.warn("Could not generate port mapping for {} skipping network model creation", nodeId);
121                 return;
122             }
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())
129                 .build();
130             LOG.info("creating node in {}", NetworkUtils.CLLI_NETWORK_ID);
131             networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiClliNode, clliNode);
132
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())
138                 .build();
139             LOG.info("creating node in {}", NetworkUtils.UNDERLAY_NETWORK_ID);
140             networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiopenroadmNetworkNode,
141                 openroadmNetworkNode);
142
143             // nodes/links creation in openroadm-topology
144             TopologyShard topologyShard = OpenRoadmTopology.createTopologyShard(portMapping.getNode(nodeId),
145                                                                                 firstMount);
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())
154                         .build();
155                     networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyNode,
156                         openRoadmTopologyNode);
157                 }
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())
165                         .build();
166                     networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyLink,
167                         openRoadmTopologyLink);
168                 }
169             } else {
170                 LOG.error("Unable to create openroadm-topology shard for node {}!", nodeId);
171             }
172             // nodes/links creation in otn-topology
173             if (nodeInfo.getNodeType().getIntValue() == 2 && (nodeInfo.getOpenroadmVersion().getIntValue() != 1)) {
174                 createOpenRoadmOtnNode(nodeId);
175             }
176             networkTransactionService.commit().get();
177             // neighbour links through LLDP
178             if (nodeInfo.getNodeType().getIntValue() == 1) {
179                 this.linkDiscovery.readLLDP(new NodeId(nodeId), openRoadmVersion);
180             }
181             LOG.info("all nodes and links created");
182         } catch (InterruptedException | ExecutionException e) {
183             LOG.error("ERROR: ", e);
184         }
185     }
186
187     @Override
188     public void setOpenRoadmNodeStatus(String nodeId, NetconfNodeConnectionStatus.ConnectionStatus connectionStatus) {
189         LOG.info("setOpenROADMNodeStatus: {} {}", nodeId, connectionStatus.name());
190         /*
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
195          */
196     }
197
198     /*
199      @see org.opendaylight.transportpce.networkmodel.service.NetworkModelService# deleteOpenROADMnode(java.lang.String)
200      */
201
202     @Override
203     public boolean deleteOpenRoadmnode(String nodeId) {
204         try {
205             if (!this.portMapping.isNodeExist(nodeId)) {
206                 return false;
207             }
208             NodeKey nodeIdKey = new NodeKey(new NodeId(nodeId));
209
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)
214                 .build();
215             this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiopenroadmNetworkNode);
216
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())
225                         .build();
226                     this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyNode);
227                 }
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())
235                         .build();
236                     this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyLink);
237                 }
238             } else {
239                 LOG.warn("TopologyShard for node '{}' is not present", nodeId);
240             }
241             @Nullable
242             OpenroadmNodeVersion deviceVersion = this.portMapping.getNode(nodeId).getNodeInfo().getOpenroadmVersion();
243             @Nullable
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())
255                             .build();
256                         this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiotnTopologyNode);
257                     }
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())
265                             .build();
266                         this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiotnTopologyLink);
267                     }
268                 }
269             }
270
271             LOG.info("deleteOpenROADMnode: {} version {}", nodeId, deviceVersion.getName());
272             this.portMapping.deletePortMappingNode(nodeId);
273
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);
278             return false;
279         }
280         return true;
281     }
282
283     @Override
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;
291         try {
292             openroadmTopology = this.networkTransactionService
293                 .read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifiers.OVERLAY_NETWORK_II)
294                 .get().get();
295             if (openroadmTopology.augmentation(Network1.class) != null) {
296                 openroadmTopologyLinks = openroadmTopology.augmentation(Network1.class).getLink();
297             }
298             otnTopology = this.networkTransactionService
299                 .read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifiers.OTN_NETWORK_II)
300                 .get().get();
301             if (otnTopology.augmentation(Network1.class) != null) {
302                 otnTopologyLinks = otnTopology.augmentation(Network1.class).getLink();
303             }
304         } catch (InterruptedException | ExecutionException e) {
305             LOG.error("Error when trying to update node : {}", nodeId, e);
306         }
307         if (openroadmTopology == null || otnTopology == null) {
308             LOG.warn("Error getting topologies from datastore");
309             return;
310         }
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())
324                         .build();
325                     networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyLink, link);
326                 }
327             }
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()))
336                         .build();
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())
345                         .build();
346                     if (!this.topologyChanges.containsKey(tc.key())) {
347                         this.topologyChanges.put(tc.key(), tc);
348                     }
349                 }
350             }
351         }
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())
365                         .build();
366                     networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyLink, link);
367                 }
368             }
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()))
377                         .build();
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())
386                         .build();
387                     if (!this.topologyChanges.containsKey(tc.key())) {
388                         this.topologyChanges.put(tc.key(), tc);
389                     }
390                 }
391             }
392         }
393         // commit datastore updates
394         try {
395             networkTransactionService.commit().get();
396             sendNotification();
397         } catch (InterruptedException | ExecutionException e) {
398             LOG.error("Error updating openroadm-topology", e);
399         }
400     }
401
402     @Override
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) {
406
407         TopologyShard otnTopologyShard;
408         switch (linkType) {
409             case OTU4:
410             case OTUC2:
411             case OTUC3:
412             case OTUC4:
413                 otnTopologyShard = OpenRoadmOtnTopology.createOtnLinks(notifLink, null, null, linkType);
414                 break;
415             case ODTU4:
416             case ODUC2:
417             case ODUC3:
418             case ODUC4:
419                 List<LinkId> linkIdList = new ArrayList<>();
420                 if (suppLinks != null) {
421                     suppLinks.forEach(lk -> linkIdList.add(new LinkId(lk)));
422                 }
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);
431                 break;
432             default:
433                 LOG.error("unknown otn link type {}", linkType);
434                 otnTopologyShard = new TopologyShard(null, null);
435         }
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())
444                     .build();
445                 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
446             }
447         }
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()))
458                     .build();
459                 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
460             }
461         }
462         try {
463             networkTransactionService.commit().get();
464         } catch (InterruptedException | ExecutionException e) {
465             LOG.error("Error adding OTN links in otn-topology", e);
466         }
467         LOG.info("OTN links created");
468     }
469
470     @Override
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) {
474
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();
482         List<Link> otuLinks;
483         List<LinkId> linkIdList = new ArrayList<>();
484         switch (linkType) {
485             case OTU4:
486             case OTUC2:
487             case OTUC3:
488             case OTUC4:
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);
494                 } else {
495                     LOG.error("Error deleting OTU4 links");
496                 }
497                 otnTopologyShard = new TopologyShard(null, null);
498                 break;
499             case ODTU4:
500             case ODUC2:
501             case ODUC3:
502             case ODUC4:
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);
509                     linkIdList.clear();
510                     if (suppLinks != null) {
511                         suppLinks.forEach(lk -> linkIdList.add(new LinkId(lk)));
512                     }
513                     otuLinks = getOtnLinks(linkIdList);
514
515                     otnTopologyShard = OpenRoadmOtnTopology.deleteOtnLinks(otuLinks, tps, linkType);
516                 } else {
517                     LOG.error("Error deleting ODU4 links");
518                     otnTopologyShard = new TopologyShard(null, null);
519                 }
520                 break;
521             default:
522                 LOG.error("unknown otn link type {}", linkType);
523                 otnTopologyShard = new TopologyShard(null, null);
524         }
525
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())
534                     .build();
535                 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
536             }
537         }
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()))
548                     .build();
549                 networkTransactionService.put(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
550             }
551         }
552         try {
553             networkTransactionService.commit().get();
554         } catch (InterruptedException | ExecutionException e) {
555             LOG.error("Error deleting OTN links in otn-topology", e);
556         }
557         LOG.info("OTN links deletion terminated");
558     }
559
560     @Override
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) {
565
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())
573                     .build());
574             linkTerminations.add(new LinkTpBuilder()
575                     .setNodeId(notifLink.getZTermination().getNodeId())
576                     .setTpId(notifLink.getZTermination().getTpId())
577                     .build());
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)));
585             }
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())
592                     .build();
593                 linkTerminations.add(atermination);
594             }
595         } else {
596             LOG.error("Impossible to update OTN links and their associated termination points in otn-topology");
597             return;
598         }
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())))
611                     .build();
612                 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
613             }
614         }
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()
625                         .getValue())))
626                     .build();
627                 if (isDeletion) {
628                     networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
629                 } else {
630                     networkTransactionService.put(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
631                 }
632             }
633         }
634         try {
635             networkTransactionService.commit().get();
636         } catch (InterruptedException | ExecutionException e) {
637             LOG.error("Error updating OTN links in otn-topology", e);
638         }
639     }
640
641     @Override
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)));
646         }
647         List<Link> supportedOtu4links = getOtnLinks(linkIdList);
648
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())
658                     .build();
659                 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
660             }
661         }
662         try {
663             networkTransactionService.commit().get();
664         } catch (InterruptedException | ExecutionException e) {
665             LOG.error("Error adding OTN links in otn-topology", e);
666         }
667         LOG.info("OTN links updated");
668     }
669
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))
677                 .build();
678             ListenableFuture<Optional<Link>> linkOptLf = networkTransactionService
679                 .read(LogicalDatastoreType.CONFIGURATION, iiLink);
680             if (linkOptLf.isDone()) {
681                 try {
682                     if (linkOptLf.get().isPresent()) {
683                         links.add(linkOptLf.get().get());
684                     }
685                 } catch (InterruptedException | ExecutionException e) {
686                     LOG.error("Error retreiving OTN links from otn-topology", e);
687                 }
688             } else {
689                 LOG.error("Error retreiving link {} from otn-topology", linkId.getValue());
690             }
691         }
692         return links;
693     }
694
695     private boolean checkLinks(List<Link> links) {
696         if (links.isEmpty()) {
697             return false;
698         }
699         for (Link link : links) {
700             if (link.augmentation(Link1.class) != null
701                     && !link.augmentation(Link1.class).getUsedBandwidth().equals(Uint32.valueOf(0))) {
702                 return false;
703             }
704         }
705         return true;
706     }
707
708     private boolean checkTerminationPoints(List<TerminationPoint> tps) {
709         if (tps.isEmpty()) {
710             return false;
711         }
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) {
716                 return false;
717             }
718         }
719         return true;
720     }
721
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)))
729             .build();
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)))
736             .build();
737         Optional<TerminationPoint> tpZOpt = Optional.empty();
738
739         if (networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpA).isDone()
740                 && networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpZ).isDone()) {
741             try {
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,
746                     tpZ, nodeTopoZ, e);
747             }
748         } else {
749             LOG.error("error getting node termination points from the datastore");
750         }
751
752         if (tpAOpt.isPresent() && tpZOpt.isPresent()) {
753             tps.add(tpAOpt.get());
754             tps.add(tpZOpt.get());
755         }
756         return tps;
757     }
758
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)))
769                 .build();
770             Optional<TerminationPoint> tpOpt;
771             if (networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTp).isDone()) {
772                 try {
773                     tpOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTp).get();
774                     if (tpOpt.isPresent()) {
775                         tps.add(tpOpt.get());
776                     }
777                 } catch (InterruptedException | ExecutionException e) {
778                     LOG.error("Error retreiving tp {} of node {} from otn-topology", tp, nodeId, e);
779                 }
780             } else {
781                 LOG.error("error getting node termination points from the datastore");
782             }
783         }
784         return tps;
785     }
786
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())
795                 .build();
796             networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink);
797         }
798         try {
799             networkTransactionService.commit().get();
800         } catch (InterruptedException | ExecutionException e) {
801             LOG.error("Error deleting OTN links from otn-topology", e);
802         }
803     }
804
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)
809             .build();
810         ListenableFuture<Optional<Network1>> netw1Fl = networkTransactionService
811             .read(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLinks);
812         Optional<Network1> netw1Opt = Optional.empty();
813         if (netw1Fl.isDone()) {
814             try {
815                 netw1Opt = netw1Fl.get();
816             } catch (InterruptedException | ExecutionException e) {
817                 LOG.error("Error retreiving list of links from otn-topology", e);
818             }
819         }
820         List<Link> odu4links = null;
821         if (netw1Opt.isPresent() && netw1Opt.get().getLink() != null) {
822             odu4links = netw1Opt
823                 .get()
824                 .nonnullLink().values()
825                 .stream().filter(lk -> lk.getLinkId().getValue()
826                     .startsWith(Uint32.valueOf(100).equals(serviceRate) ? "ODUC4" : "ODTU4"))
827                 .collect(Collectors.toList());
828         }
829         if (odu4links == null) {
830             return null;
831         }
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)) {
840                 links.add(slink);
841             }
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)) {
845                 links.add(dlink);
846             }
847         }
848         LOG.debug("odu4oduC4links = {}", links);
849         return links;
850     }
851
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())
862                     .build();
863                 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyNode, otnTopologyNode);
864             }
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())
872                     .build();
873                 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
874             }
875         } else {
876             LOG.error("Unable to create OTN topology shard for node {}!", nodeId);
877         }
878     }
879
880     private String convertNetconfNodeIdToTopoNodeId(String nodeId, String tpId) {
881         return new StringBuilder(nodeId).append("-").append(tpId.split("-")[0]).toString();
882     }
883
884     private static String formatNodeName(String nodeName, String tpName) {
885         return nodeName.contains("-XPDR")
886             ? nodeName
887             : new StringBuilder(nodeName).append("-").append(tpName.split("-")[0]).toString();
888     }
889
890     @SuppressFBWarnings(
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");
896             return;
897         }
898         this.notification = new TopologyUpdateResultBuilder()
899             .setTopologyChanges(topologyChanges)
900             .build();
901         try {
902             notificationPublishService.putNotification(this.notification);
903         } catch (InterruptedException e) {
904             LOG.error("Notification offer rejected. Error={}", e.getMessage());
905         }
906     }
907 }