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