Update otn-topology with otn-links
[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
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.common.api.LogicalDatastoreType;
23 import org.opendaylight.transportpce.common.NetworkUtils;
24 import org.opendaylight.transportpce.common.mapping.PortMapping;
25 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
26 import org.opendaylight.transportpce.networkmodel.R2RLinkDiscovery;
27 import org.opendaylight.transportpce.networkmodel.dto.TopologyShard;
28 import org.opendaylight.transportpce.networkmodel.util.ClliNetwork;
29 import org.opendaylight.transportpce.networkmodel.util.LinkIdUtil;
30 import org.opendaylight.transportpce.networkmodel.util.OpenRoadmNetwork;
31 import org.opendaylight.transportpce.networkmodel.util.OpenRoadmOtnTopology;
32 import org.opendaylight.transportpce.networkmodel.util.OpenRoadmTopology;
33 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200128.network.nodes.NodeInfo;
34 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200128.network.nodes.NodeInfo.OpenroadmVersion;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev181019.NodeTypes;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.Link1;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev181130.TerminationPoint1;
38 import org.opendaylight.yang.gen.v1.http.transportpce.topology.rev200129.OtnLinkType;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NetworkId;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.Networks;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.NetworkKey;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.NodeKey;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.LinkId;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Network1;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.TpId;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.LinkKey;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPoint;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus;
55 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
56 import org.opendaylight.yangtools.yang.common.Uint32;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59
60
61 public class NetworkModelServiceImpl implements NetworkModelService {
62
63     private static final Logger LOG = LoggerFactory.getLogger(NetworkModelServiceImpl.class);
64     private static final boolean CREATE_MISSING_PARENTS = true;
65
66     private NetworkTransactionService networkTransactionService;
67     private final R2RLinkDiscovery linkDiscovery;
68     private final PortMapping portMapping;
69     private Map<String, TopologyShard> topologyShardMountedDevice;
70     private Map<String, TopologyShard> otnTopologyShardMountedDevice;
71
72     public NetworkModelServiceImpl(final NetworkTransactionService networkTransactionService,
73         final R2RLinkDiscovery linkDiscovery, PortMapping portMapping) {
74
75         this.networkTransactionService = networkTransactionService;
76         this.linkDiscovery = linkDiscovery;
77         this.portMapping = portMapping;
78         this.topologyShardMountedDevice = new HashMap<String, TopologyShard>();
79         this.otnTopologyShardMountedDevice = new HashMap<String, TopologyShard>();
80     }
81
82     public void init() {
83         LOG.info("init ...");
84     }
85
86     public void close() {
87     }
88
89     @Override
90     public void createOpenRoadmNode(String nodeId, String openRoadmVersion) {
91         try {
92             LOG.info("createOpenROADMNode: {} ", nodeId);
93
94             if (!portMapping.createMappingData(nodeId, openRoadmVersion)) {
95                 LOG.warn("Could not generate port mapping for {} skipping network model creation", nodeId);
96                 return;
97             }
98             NodeInfo nodeInfo = portMapping.getNode(nodeId).getNodeInfo();
99             if (nodeInfo.getNodeType().getIntValue() == 1) {
100                 this.linkDiscovery.readLLDP(new NodeId(nodeId), openRoadmVersion);
101             }
102             // node creation in clli-network
103             Node clliNode = ClliNetwork.createNode(nodeId, nodeInfo);
104             InstanceIdentifier<Node> iiClliNode = InstanceIdentifier.builder(Networks.class)
105                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.CLLI_NETWORK_ID)))
106                 .child(Node.class, clliNode.key())
107                 .build();
108             LOG.info("creating node in {}", NetworkUtils.CLLI_NETWORK_ID);
109             networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiClliNode, clliNode,
110                 CREATE_MISSING_PARENTS);
111
112             // node creation in openroadm-network
113             Node openroadmNetworkNode = OpenRoadmNetwork.createNode(nodeId, nodeInfo);
114             InstanceIdentifier<Node> iiopenroadmNetworkNode = InstanceIdentifier.builder(Networks.class)
115                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID)))
116                 .child(Node.class, openroadmNetworkNode.key())
117                 .build();
118             LOG.info("creating node in {}", NetworkUtils.UNDERLAY_NETWORK_ID);
119             networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiopenroadmNetworkNode,
120                 openroadmNetworkNode, CREATE_MISSING_PARENTS);
121
122             // nodes/links creation in openroadm-topology
123             TopologyShard topologyShard = OpenRoadmTopology.createTopologyShard(portMapping.getNode(nodeId));
124             if (topologyShard != null) {
125                 this.topologyShardMountedDevice.put(nodeId, topologyShard);
126                 for (Node openRoadmTopologyNode : topologyShard.getNodes()) {
127                     LOG.info("creating node {} in {}", openRoadmTopologyNode.getNodeId().getValue(),
128                         NetworkUtils.OVERLAY_NETWORK_ID);
129                     InstanceIdentifier<Node> iiOpenRoadmTopologyNode = InstanceIdentifier.builder(Networks.class)
130                         .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
131                         .child(Node.class, openRoadmTopologyNode.key())
132                         .build();
133                     networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyNode,
134                         openRoadmTopologyNode, CREATE_MISSING_PARENTS);
135                 }
136                 for (Link openRoadmTopologyLink : topologyShard.getLinks()) {
137                     LOG.info("creating link {} in {}", openRoadmTopologyLink.getLinkId().getValue(),
138                         NetworkUtils.OVERLAY_NETWORK_ID);
139                     InstanceIdentifier<Link> iiOpenRoadmTopologyLink = InstanceIdentifier.builder(Networks.class)
140                         .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
141                         .augmentation(Network1.class)
142                         .child(Link.class, openRoadmTopologyLink.key())
143                         .build();
144                     networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyLink,
145                         openRoadmTopologyLink, CREATE_MISSING_PARENTS);
146                 }
147             } else {
148                 LOG.error("Unable to create openroadm-topology shard for node {}!", nodeId);
149             }
150
151             // nodes/links creation in otn-topology
152             if (nodeInfo.getNodeType().getIntValue() == 2 && (nodeInfo.getOpenroadmVersion().getIntValue() != 1)) {
153                 createOpenRoadmOtnNode(nodeId);
154             }
155             networkTransactionService.commit().get();
156             LOG.info("all nodes and links created");
157         } catch (InterruptedException | ExecutionException e) {
158             LOG.error("ERROR: ", e);
159         }
160     }
161
162     @Override
163     public void setOpenRoadmNodeStatus(String nodeId, NetconfNodeConnectionStatus.ConnectionStatus connectionStatus) {
164         LOG.info("setOpenROADMNodeStatus: {} {}", nodeId, connectionStatus.name());
165         /*
166           TODO: set connection status of the device in model,
167           TODO: so we don't need to keep it in memory (Set<String> currentMountedDevice)
168           TODO: unfortunately there is no connection status OpenROADM in network models
169           TODO: waiting for new model version
170          */
171     }
172
173     /*
174      @see org.opendaylight.transportpce.networkmodel.service.NetworkModelService# deleteOpenROADMnode(java.lang.String)
175      */
176
177     @Override
178     public void deleteOpenRoadmnode(String nodeId) {
179         try {
180             NodeKey nodeIdKey = new NodeKey(new NodeId(nodeId));
181
182             LOG.info("deleting node in {}", NetworkUtils.UNDERLAY_NETWORK_ID);
183             InstanceIdentifier<Node> iiopenroadmNetworkNode = InstanceIdentifier.builder(Networks.class)
184                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID)))
185                 .child(Node.class, nodeIdKey)
186                 .build();
187             this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiopenroadmNetworkNode);
188
189             TopologyShard topologyShard = this.topologyShardMountedDevice.get(nodeId);
190             if (topologyShard != null) {
191                 for (Node openRoadmTopologyNode : topologyShard.getNodes()) {
192                     LOG.info("deleting node {} in {}", openRoadmTopologyNode.getNodeId().getValue(),
193                         NetworkUtils.OVERLAY_NETWORK_ID);
194                     InstanceIdentifier<Node> iiOpenRoadmTopologyNode = InstanceIdentifier.builder(Networks.class)
195                         .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
196                         .child(Node.class, openRoadmTopologyNode.key())
197                         .build();
198                     this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyNode);
199                 }
200                 for (Link openRoadmTopologyLink : topologyShard.getLinks()) {
201                     LOG.info("deleting link {} in {}", openRoadmTopologyLink.getLinkId().getValue(),
202                         NetworkUtils.OVERLAY_NETWORK_ID);
203                     InstanceIdentifier<Link> iiOpenRoadmTopologyLink = InstanceIdentifier.builder(Networks.class)
204                         .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
205                         .augmentation(Network1.class)
206                         .child(Link.class, openRoadmTopologyLink.key())
207                         .build();
208                     this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyLink);
209                 }
210             } else {
211                 LOG.warn("TopologyShard for node '{}' is not present", nodeId);
212             }
213             @Nullable
214             OpenroadmVersion deviceVersion = this.portMapping.getNode(nodeId).getNodeInfo().getOpenroadmVersion();
215             @Nullable
216             NodeTypes nodeType = this.portMapping.getNode(nodeId).getNodeInfo().getNodeType();
217             if (nodeType.getIntValue() == 2 && deviceVersion.getIntValue() != 1) {
218                 TopologyShard otnTopologyShard = this.otnTopologyShardMountedDevice.get(nodeId);
219                 LOG.info("suppression de otnTopologyShard = {}", otnTopologyShard.toString());
220                 if (otnTopologyShard != null) {
221                     for (Node otnTopologyNode : otnTopologyShard.getNodes()) {
222                         LOG.info("deleting node {} in {}", otnTopologyNode.getNodeId().getValue(),
223                             NetworkUtils.OTN_NETWORK_ID);
224                         InstanceIdentifier<Node> iiotnTopologyNode = InstanceIdentifier.builder(Networks.class)
225                             .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
226                             .child(Node.class, otnTopologyNode.key())
227                             .build();
228                         this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiotnTopologyNode);
229                     }
230                     for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
231                         LOG.info("deleting link {} in {}", otnTopologyLink.getLinkId().getValue(),
232                             NetworkUtils.OTN_NETWORK_ID);
233                         InstanceIdentifier<Link> iiotnTopologyLink = InstanceIdentifier.builder(Networks.class)
234                             .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
235                             .augmentation(Network1.class)
236                             .child(Link.class, otnTopologyLink.key())
237                             .build();
238                         this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiotnTopologyLink);
239                     }
240                 }
241             }
242
243             LOG.info("deleteOpenROADMnode: {} version {}", nodeId, deviceVersion.getName());
244             this.portMapping.deleteMappingData(nodeId);
245
246             this.networkTransactionService.commit().get(1, TimeUnit.SECONDS);
247             LOG.info("all nodes and links deleted ! ");
248         } catch (InterruptedException | ExecutionException | TimeoutException e) {
249             LOG.error("Error when trying to delete node : {}", nodeId, e);
250         }
251     }
252
253     @Override
254     public void createOtnLinks(String nodeA, String tpA, String nodeZ, String tpZ, OtnLinkType linkType) {
255         TopologyShard otnTopologyShard;
256         switch (linkType) {
257             case OTU4:
258                 otnTopologyShard = OpenRoadmOtnTopology.createOtnLinks(nodeA, tpA, nodeZ, tpZ, linkType);
259                 break;
260             case ODTU4:
261                 String nodeTopoA = new StringBuilder(nodeA).append("-").append(tpA.split("-")[0]).toString();
262                 String nodeTopoZ = new StringBuilder(nodeZ).append("-").append(tpZ.split("-")[0]).toString();
263                 List<LinkId> linkIdList = new ArrayList<>();
264                 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, "OTU4"));
265                 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, "OTU4"));
266                 List<Link> supportedOtu4links = getOtnLinks(linkIdList);
267                 List<TerminationPoint> tps = getOtnNodeTps(nodeTopoA, tpA, nodeTopoZ, tpZ);
268
269                 otnTopologyShard = OpenRoadmOtnTopology.createOtnLinks(supportedOtu4links, tps);
270                 break;
271             default:
272                 LOG.error("unknown otn link type {}", linkType);
273                 otnTopologyShard = new TopologyShard(null, null);
274         }
275         if (otnTopologyShard.getLinks() != null) {
276             for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
277                 LOG.info("creating and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(),
278                     NetworkUtils.OVERLAY_NETWORK_ID);
279                 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
280                     .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
281                     .augmentation(Network1.class)
282                     .child(Link.class, otnTopologyLink.key())
283                     .build();
284                 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink,
285                     otnTopologyLink, CREATE_MISSING_PARENTS);
286             }
287         }
288         if (otnTopologyShard.getTps() != null) {
289             for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) {
290                 LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue());
291                 InstanceIdentifier<TerminationPoint> iiOtnTopologyTp = InstanceIdentifier.builder(Networks.class)
292                     .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
293                     .child(Node.class, new NodeKey(otnTopologyTp.getSupportingTerminationPoint().get(0).getNodeRef()))
294                     .augmentation(Node1.class)
295                     .child(TerminationPoint.class, new TerminationPointKey(otnTopologyTp.getTpId()))
296                     .build();
297                 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
298             }
299         }
300         try {
301             networkTransactionService.commit().get();
302         } catch (InterruptedException | ExecutionException e) {
303             LOG.error("Error adding OTN links in otn-topology", e);
304         }
305         LOG.info("OTN links created");
306     }
307
308     @Override
309     public void deleteOtnLinks(String nodeA, String tpA, String nodeZ, String tpZ, OtnLinkType linkType) {
310         TopologyShard otnTopologyShard;
311         String nodeTopoA = new StringBuilder(nodeA).append("-").append(tpA.split("-")[0]).toString();
312         String nodeTopoZ = new StringBuilder(nodeZ).append("-").append(tpZ.split("-")[0]).toString();
313         List<Link> otu4Links;
314         List<LinkId> linkIdList = new ArrayList<>();
315         switch (linkType) {
316             case OTU4:
317                 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, "OTU4"));
318                 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, "OTU4"));
319                 otu4Links = getOtnLinks(linkIdList);
320                 if (checkLinks(otu4Links)) {
321                     deleteLinks(otu4Links);
322                 } else {
323                     LOG.error("Error deleting OTU4 links");
324                 }
325                 otnTopologyShard = new TopologyShard(null, null);
326                 break;
327             case ODTU4:
328                 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, "ODU4"));
329                 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, "ODU4"));
330                 List<Link> odu4Links = getOtnLinks(linkIdList);
331                 List<TerminationPoint> tps = getOtnNodeTps(nodeTopoA, tpA, nodeTopoZ, tpZ);
332                 if (checkLinks(odu4Links) && checkTerminationPoints(tps)) {
333                     deleteLinks(odu4Links);
334                     linkIdList.clear();
335                     linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, "OTU4"));
336                     linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, "OTU4"));
337                     otu4Links = getOtnLinks(linkIdList);
338                     otnTopologyShard = OpenRoadmOtnTopology.deleteOtnLinks(otu4Links, tps);
339                 } else {
340                     LOG.error("Error deleting ODU4 links");
341                     otnTopologyShard = new TopologyShard(null, null);
342                 }
343                 break;
344             default:
345                 LOG.error("unknown otn link type {}", linkType);
346                 otnTopologyShard = new TopologyShard(null, null);
347         }
348         if (otnTopologyShard.getLinks() != null) {
349             for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
350                 LOG.info("deleting and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(),
351                     NetworkUtils.OVERLAY_NETWORK_ID);
352                 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
353                     .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
354                     .augmentation(Network1.class)
355                     .child(Link.class, otnTopologyLink.key())
356                     .build();
357                 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink,
358                     CREATE_MISSING_PARENTS);
359             }
360         }
361         if (otnTopologyShard.getTps() != null) {
362             for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) {
363                 LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue());
364                 InstanceIdentifier<TerminationPoint> iiOtnTopologyTp = InstanceIdentifier.builder(Networks.class)
365                     .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
366                     .child(Node.class, new NodeKey(otnTopologyTp.getSupportingTerminationPoint().get(0).getNodeRef()))
367                     .augmentation(Node1.class)
368                     .child(TerminationPoint.class, new TerminationPointKey(otnTopologyTp.getTpId()))
369                     .build();
370                 networkTransactionService.put(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
371             }
372         }
373         try {
374             networkTransactionService.commit().get();
375         } catch (InterruptedException | ExecutionException e) {
376             LOG.error("Error deleting OTN links in otn-topology", e);
377         }
378         LOG.info("OTN links deletion terminated");
379     }
380
381     @Override
382     public void updateOtnLinks(List<String> nodeTps, String serviceRate, Short tribPortNb, Short tribSoltNb,
383         boolean isDeletion) {
384         List<Link> supportedOdu4Links = getSupportingOdu4Links(nodeTps);
385         List<TerminationPoint> tps = getOtnNodeTps(nodeTps);
386         TopologyShard otnTopologyShard;
387         otnTopologyShard = OpenRoadmOtnTopology.updateOtnLinks(supportedOdu4Links, tps, serviceRate, tribPortNb,
388             tribSoltNb, isDeletion);
389         if (otnTopologyShard.getLinks() != null) {
390             for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
391                 LOG.info("creating and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(),
392                     NetworkUtils.OVERLAY_NETWORK_ID);
393                 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
394                     .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
395                     .augmentation(Network1.class)
396                     .child(Link.class, new LinkKey(new LinkId(otnTopologyLink.getLinkId().getValue())))
397                     .build();
398                 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink,
399                     otnTopologyLink, CREATE_MISSING_PARENTS);
400             }
401         }
402         if (otnTopologyShard.getTps() != null) {
403             for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) {
404                 LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue());
405                 InstanceIdentifier<TerminationPoint> iiOtnTopologyTp = InstanceIdentifier.builder(Networks.class)
406                     .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
407                     .child(Node.class, new NodeKey(otnTopologyTp.getSupportingTerminationPoint().get(0).getNodeRef()))
408                     .augmentation(Node1.class)
409                     .child(TerminationPoint.class, new TerminationPointKey(
410                         new TpId(otnTopologyTp.getTpId().getValue())))
411                     .build();
412                 if (isDeletion) {
413                     networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
414                 } else {
415                     networkTransactionService.put(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
416                 }
417             }
418         }
419         try {
420             networkTransactionService.commit().get();
421         } catch (InterruptedException | ExecutionException e) {
422             LOG.error("Error updating OTN links in otn-topology", e);
423         }
424     }
425
426     private List<Link> getOtnLinks(List<LinkId> linkIds) {
427         List<Link> links = new ArrayList<>();
428         for (LinkId linkId : linkIds) {
429             InstanceIdentifier<Link> iiLink = InstanceIdentifier.builder(Networks.class)
430                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
431                 .augmentation(Network1.class)
432                 .child(Link.class, new LinkKey(linkId))
433                 .build();
434             ListenableFuture<Optional<Link>> linkOptLf = networkTransactionService
435                 .read(LogicalDatastoreType.CONFIGURATION, iiLink);
436             if (linkOptLf.isDone()) {
437                 try {
438                     if (linkOptLf.get().isPresent()) {
439                         links.add(linkOptLf.get().get());
440                     }
441                 } catch (InterruptedException | ExecutionException e) {
442                     LOG.error("Error retreiving OTN links from otn-topology", e);
443                 }
444             } else {
445                 LOG.error("Error retreiving link {} from otn-topology", linkId.getValue());
446             }
447         }
448         return links;
449     }
450
451     private boolean checkLinks(List<Link> links) {
452         boolean canBeDeleted = true;
453         if (links.isEmpty()) {
454             return false;
455         } else {
456             for (Link link : links) {
457                 if (link.augmentation(Link1.class) != null
458                     && !link.augmentation(Link1.class).getUsedBandwidth().equals(Uint32.valueOf(0))) {
459                     canBeDeleted = false;
460                 }
461             }
462         }
463         return canBeDeleted;
464     }
465
466     private boolean checkTerminationPoints(List<TerminationPoint> tps) {
467         boolean canBeDeleted = true;
468         if (tps.isEmpty()) {
469             return false;
470         } else {
471             for (TerminationPoint tp : tps) {
472                 if (tp.augmentation(TerminationPoint1.class) != null
473                     && tp.augmentation(TerminationPoint1.class).getXpdrTpPortConnectionAttributes().getTsPool() != null
474                     && tp.augmentation(TerminationPoint1.class).getXpdrTpPortConnectionAttributes().getTsPool()
475                     .size() != 80) {
476                     canBeDeleted = false;
477                 }
478             }
479         }
480         return canBeDeleted;
481     }
482
483     private List<TerminationPoint> getOtnNodeTps(String nodeTopoA, String tpA, String nodeTopoZ, String tpZ) {
484         List<TerminationPoint> tps = new ArrayList<>();
485         InstanceIdentifier<TerminationPoint> iiTpA = InstanceIdentifier.builder(Networks.class)
486             .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
487             .child(Node.class, new NodeKey(new NodeId(nodeTopoA)))
488             .augmentation(Node1.class)
489             .child(TerminationPoint.class, new TerminationPointKey(new TpId(tpA)))
490             .build();
491         Optional<TerminationPoint> tpAOpt = Optional.empty();
492         InstanceIdentifier<TerminationPoint> iiTpZ = InstanceIdentifier.builder(Networks.class)
493             .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
494             .child(Node.class, new NodeKey(new NodeId(nodeTopoZ)))
495             .augmentation(Node1.class)
496             .child(TerminationPoint.class, new TerminationPointKey(new TpId(tpZ)))
497             .build();
498         Optional<TerminationPoint> tpZOpt = Optional.empty();
499
500         if (networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpA).isDone()
501             && networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpZ).isDone()) {
502             try {
503                 tpAOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpA).get();
504                 tpZOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpZ).get();
505             } catch (InterruptedException | ExecutionException e) {
506                 LOG.error("Error retreiving tp {} of node {} or tp {} from node {} from otn-topology", tpA, nodeTopoA,
507                     tpZ, nodeTopoZ, e);
508             }
509         } else {
510             LOG.error("error getting node termination points from the datastore");
511         }
512
513         if (tpAOpt.isPresent() && tpZOpt.isPresent()) {
514             tps.add(tpAOpt.get());
515             tps.add(tpZOpt.get());
516         }
517         return tps;
518     }
519
520     private List<TerminationPoint> getOtnNodeTps(List<String> nodeTopoTps) {
521         List<TerminationPoint> tps = new ArrayList<>();
522         for (String str : nodeTopoTps) {
523             String nodeId = str.split("--")[0];
524             String tp = str.split("--")[1];
525             InstanceIdentifier<TerminationPoint> iiTp = InstanceIdentifier.builder(Networks.class)
526                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
527                 .child(Node.class, new NodeKey(new NodeId(nodeId)))
528                 .augmentation(Node1.class)
529                 .child(TerminationPoint.class, new TerminationPointKey(new TpId(tp)))
530                 .build();
531             Optional<TerminationPoint> tpOpt;
532             if (networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTp).isDone()) {
533                 try {
534                     tpOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTp).get();
535                     if (tpOpt.isPresent()) {
536                         tps.add(tpOpt.get());
537                     }
538                 } catch (InterruptedException | ExecutionException e) {
539                     LOG.error("Error retreiving tp {} of node {} from otn-topology", tp, nodeId, e);
540                 }
541             } else {
542                 LOG.error("error getting node termination points from the datastore");
543             }
544         }
545         if (tps.isEmpty()) {
546             LOG.warn("returning null");
547             return null;
548         } else {
549             LOG.info("returning tps = {}", tps.toString());
550             return tps;
551         }
552     }
553
554     private void deleteLinks(List<Link> links) {
555         for (Link otnTopologyLink : links) {
556             LOG.info("deleting link {} from {}", otnTopologyLink.getLinkId().getValue(),
557                 NetworkUtils.OVERLAY_NETWORK_ID);
558             InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
559                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
560                 .augmentation(Network1.class)
561                 .child(Link.class, otnTopologyLink.key())
562                 .build();
563             networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink);
564         }
565         try {
566             networkTransactionService.commit().get();
567         } catch (InterruptedException | ExecutionException e) {
568             LOG.error("Error deleting OTN links from otn-topology", e);
569         }
570     }
571
572     private List<Link> getSupportingOdu4Links(List<String> nodesTopoTps) {
573         InstanceIdentifier<Network1> iiOtnTopologyLinks = InstanceIdentifier.builder(Networks.class)
574             .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
575             .augmentation(Network1.class)
576             .build();
577         ListenableFuture<Optional<Network1>> netw1Fl = networkTransactionService
578             .read(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLinks);
579         Optional<Network1> netw1Opt = Optional.empty();
580         if (netw1Fl.isDone()) {
581             try {
582                 netw1Opt = netw1Fl.get();
583             } catch (InterruptedException | ExecutionException e) {
584                 LOG.error("Error retreiving list of links from otn-topology", e);
585             }
586         }
587         List<Link> odu4links = null;
588         if (netw1Opt.isPresent() && netw1Opt.get().getLink() != null) {
589             odu4links = netw1Opt.get().getLink().stream().filter(lk -> lk.getLinkId().getValue().startsWith("ODU4"))
590                 .collect(Collectors.toList());
591         }
592         List<Link> links = new ArrayList<>();
593         if (odu4links != null) {
594             for (String str : nodesTopoTps) {
595                 String[] nodeAndTp = str.split("--");
596                 if (nodeAndTp.length >= 2) {
597                     String nodeId = nodeAndTp[0];
598                     String tp = nodeAndTp[1];
599                     Link slink = odu4links.stream().filter(lk -> lk.getSource().getSourceNode().getValue()
600                         .equals(nodeId) && lk.getSource().getSourceTp().toString().equals(tp))
601                         .findFirst().get();
602                     if (!links.contains(slink)) {
603                         links.add(slink);
604                     }
605                     Link dlink = odu4links.stream().filter(lk -> lk.getDestination().getDestNode().getValue()
606                         .equals(nodeId) && lk.getDestination().getDestTp().toString().equals(tp))
607                         .findFirst().get();
608                     if (!links.contains(dlink)) {
609                         links.add(dlink);
610                     }
611                 }
612             }
613             LOG.debug("odu4links = {}", links.toString());
614             return links;
615         } else {
616             return null;
617         }
618     }
619
620     private void createOpenRoadmOtnNode(String nodeId) {
621         TopologyShard otnTopologyShard = OpenRoadmOtnTopology.createTopologyShard(portMapping.getNode(nodeId));
622         if (otnTopologyShard != null) {
623             this.otnTopologyShardMountedDevice.put(nodeId, otnTopologyShard);
624             for (Node otnTopologyNode : otnTopologyShard.getNodes()) {
625                 LOG.info("creating otn node {} in {}", otnTopologyNode.getNodeId().getValue(),
626                     NetworkUtils.OTN_NETWORK_ID);
627                 InstanceIdentifier<Node> iiOtnTopologyNode = InstanceIdentifier.builder(Networks.class)
628                     .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
629                     .child(Node.class, otnTopologyNode.key())
630                     .build();
631                 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyNode,
632                     otnTopologyNode);
633             }
634             for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
635                 LOG.info("creating otn link {} in {}", otnTopologyLink.getLinkId().getValue(),
636                     NetworkUtils.OVERLAY_NETWORK_ID);
637                 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
638                     .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
639                     .augmentation(Network1.class)
640                     .child(Link.class, otnTopologyLink.key())
641                     .build();
642                 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink,
643                     otnTopologyLink, CREATE_MISSING_PARENTS);
644             }
645         } else {
646             LOG.error("Unable to create OTN topology shard for node {}!", nodeId);
647         }
648
649     }
650 }