Migrate networkmodel module to Aluminium
[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.rev200827.network.nodes.NodeInfo;
33 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200827.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.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.termination.point.SupportingTerminationPoint;
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
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
110             // node creation in openroadm-network
111             Node openroadmNetworkNode = OpenRoadmNetwork.createNode(nodeId, nodeInfo);
112             InstanceIdentifier<Node> iiopenroadmNetworkNode = InstanceIdentifier.builder(Networks.class)
113                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID)))
114                 .child(Node.class, openroadmNetworkNode.key())
115                 .build();
116             LOG.info("creating node in {}", NetworkUtils.UNDERLAY_NETWORK_ID);
117             networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiopenroadmNetworkNode,
118                 openroadmNetworkNode);
119
120             // nodes/links creation in openroadm-topology
121             TopologyShard topologyShard = OpenRoadmTopology.createTopologyShard(portMapping.getNode(nodeId));
122             if (topologyShard != null) {
123                 this.topologyShardMountedDevice.put(nodeId, topologyShard);
124                 for (Node openRoadmTopologyNode : topologyShard.getNodes()) {
125                     LOG.info("creating node {} in {}", openRoadmTopologyNode.getNodeId().getValue(),
126                         NetworkUtils.OVERLAY_NETWORK_ID);
127                     InstanceIdentifier<Node> iiOpenRoadmTopologyNode = InstanceIdentifier.builder(Networks.class)
128                         .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
129                         .child(Node.class, openRoadmTopologyNode.key())
130                         .build();
131                     networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyNode,
132                         openRoadmTopologyNode);
133                 }
134                 for (Link openRoadmTopologyLink : topologyShard.getLinks()) {
135                     LOG.info("creating link {} in {}", openRoadmTopologyLink.getLinkId().getValue(),
136                         NetworkUtils.OVERLAY_NETWORK_ID);
137                     InstanceIdentifier<Link> iiOpenRoadmTopologyLink = InstanceIdentifier.builder(Networks.class)
138                         .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
139                         .augmentation(Network1.class)
140                         .child(Link.class, openRoadmTopologyLink.key())
141                         .build();
142                     networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyLink,
143                         openRoadmTopologyLink);
144                 }
145             } else {
146                 LOG.error("Unable to create openroadm-topology shard for node {}!", nodeId);
147             }
148
149             // nodes/links creation in otn-topology
150             if (nodeInfo.getNodeType().getIntValue() == 2 && (nodeInfo.getOpenroadmVersion().getIntValue() != 1)) {
151                 createOpenRoadmOtnNode(nodeId);
152             }
153             networkTransactionService.commit().get();
154             LOG.info("all nodes and links created");
155         } catch (InterruptedException | ExecutionException e) {
156             LOG.error("ERROR: ", e);
157         }
158     }
159
160     @Override
161     public void setOpenRoadmNodeStatus(String nodeId, NetconfNodeConnectionStatus.ConnectionStatus connectionStatus) {
162         LOG.info("setOpenROADMNodeStatus: {} {}", nodeId, connectionStatus.name());
163         /*
164           TODO: set connection status of the device in model,
165           TODO: so we don't need to keep it in memory (Set<String> currentMountedDevice)
166           TODO: unfortunately there is no connection status OpenROADM in network models
167           TODO: waiting for new model version
168          */
169     }
170
171     /*
172      @see org.opendaylight.transportpce.networkmodel.service.NetworkModelService# deleteOpenROADMnode(java.lang.String)
173      */
174
175     @Override
176     public void deleteOpenRoadmnode(String nodeId) {
177         try {
178             NodeKey nodeIdKey = new NodeKey(new NodeId(nodeId));
179
180             LOG.info("deleting node in {}", NetworkUtils.UNDERLAY_NETWORK_ID);
181             InstanceIdentifier<Node> iiopenroadmNetworkNode = InstanceIdentifier.builder(Networks.class)
182                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID)))
183                 .child(Node.class, nodeIdKey)
184                 .build();
185             this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiopenroadmNetworkNode);
186
187             TopologyShard topologyShard = this.topologyShardMountedDevice.get(nodeId);
188             if (topologyShard != null) {
189                 for (Node openRoadmTopologyNode : topologyShard.getNodes()) {
190                     LOG.info("deleting node {} in {}", openRoadmTopologyNode.getNodeId().getValue(),
191                         NetworkUtils.OVERLAY_NETWORK_ID);
192                     InstanceIdentifier<Node> iiOpenRoadmTopologyNode = InstanceIdentifier.builder(Networks.class)
193                         .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
194                         .child(Node.class, openRoadmTopologyNode.key())
195                         .build();
196                     this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyNode);
197                 }
198                 for (Link openRoadmTopologyLink : topologyShard.getLinks()) {
199                     LOG.info("deleting link {} in {}", openRoadmTopologyLink.getLinkId().getValue(),
200                         NetworkUtils.OVERLAY_NETWORK_ID);
201                     InstanceIdentifier<Link> iiOpenRoadmTopologyLink = InstanceIdentifier.builder(Networks.class)
202                         .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
203                         .augmentation(Network1.class)
204                         .child(Link.class, openRoadmTopologyLink.key())
205                         .build();
206                     this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyLink);
207                 }
208             } else {
209                 LOG.warn("TopologyShard for node '{}' is not present", nodeId);
210             }
211             @Nullable
212             OpenroadmVersion deviceVersion = this.portMapping.getNode(nodeId).getNodeInfo().getOpenroadmVersion();
213             @Nullable
214             NodeTypes nodeType = this.portMapping.getNode(nodeId).getNodeInfo().getNodeType();
215             if (nodeType.getIntValue() == 2 && deviceVersion.getIntValue() != 1) {
216                 TopologyShard otnTopologyShard = this.otnTopologyShardMountedDevice.get(nodeId);
217                 if (otnTopologyShard != null) {
218                     LOG.info("suppression de otnTopologyShard = {}", otnTopologyShard.toString());
219                     for (Node otnTopologyNode : otnTopologyShard.getNodes()) {
220                         LOG.info("deleting node {} in {}", otnTopologyNode.getNodeId().getValue(),
221                             NetworkUtils.OTN_NETWORK_ID);
222                         InstanceIdentifier<Node> iiotnTopologyNode = InstanceIdentifier.builder(Networks.class)
223                             .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
224                             .child(Node.class, otnTopologyNode.key())
225                             .build();
226                         this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiotnTopologyNode);
227                     }
228                     for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
229                         LOG.info("deleting link {} in {}", otnTopologyLink.getLinkId().getValue(),
230                             NetworkUtils.OTN_NETWORK_ID);
231                         InstanceIdentifier<Link> iiotnTopologyLink = InstanceIdentifier.builder(Networks.class)
232                             .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
233                             .augmentation(Network1.class)
234                             .child(Link.class, otnTopologyLink.key())
235                             .build();
236                         this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiotnTopologyLink);
237                     }
238                 }
239             }
240
241             LOG.info("deleteOpenROADMnode: {} version {}", nodeId, deviceVersion.getName());
242             this.portMapping.deleteMappingData(nodeId);
243
244             this.networkTransactionService.commit().get(1, TimeUnit.SECONDS);
245             LOG.info("all nodes and links deleted ! ");
246         } catch (InterruptedException | ExecutionException | TimeoutException e) {
247             LOG.error("Error when trying to delete node : {}", nodeId, e);
248         }
249     }
250
251     @Override
252     public void createOtnLinks(String nodeA, String tpA, String nodeZ, String tpZ, OtnLinkType linkType) {
253         TopologyShard otnTopologyShard;
254         switch (linkType) {
255             case OTU4:
256                 otnTopologyShard = OpenRoadmOtnTopology.createOtnLinks(nodeA, tpA, nodeZ, tpZ, linkType);
257                 break;
258             case ODTU4:
259                 String nodeTopoA = new StringBuilder(nodeA).append("-").append(tpA.split("-")[0]).toString();
260                 String nodeTopoZ = new StringBuilder(nodeZ).append("-").append(tpZ.split("-")[0]).toString();
261                 List<LinkId> linkIdList = new ArrayList<>();
262                 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, "OTU4"));
263                 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, "OTU4"));
264                 List<Link> supportedOtu4links = getOtnLinks(linkIdList);
265                 List<TerminationPoint> tps = getOtnNodeTps(nodeTopoA, tpA, nodeTopoZ, tpZ);
266
267                 otnTopologyShard = OpenRoadmOtnTopology.createOtnLinks(supportedOtu4links, tps);
268                 break;
269             default:
270                 LOG.error("unknown otn link type {}", linkType);
271                 otnTopologyShard = new TopologyShard(null, null);
272         }
273         if (otnTopologyShard.getLinks() != null) {
274             for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
275                 LOG.info("creating and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(),
276                     NetworkUtils.OVERLAY_NETWORK_ID);
277                 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
278                     .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
279                     .augmentation(Network1.class)
280                     .child(Link.class, otnTopologyLink.key())
281                     .build();
282                 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink,
283                     otnTopologyLink);
284             }
285         }
286         if (otnTopologyShard.getTps() != null) {
287             for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) {
288                 LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue());
289                 List<SupportingTerminationPoint> supportingTerminationPoint =
290                         new ArrayList<>(otnTopologyTp.nonnullSupportingTerminationPoint().values());
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(supportingTerminationPoint.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,
358                         iiOtnTopologyLink, otnTopologyLink);
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                 List<SupportingTerminationPoint> supportingTerminationPoint =
365                         new ArrayList<>(otnTopologyTp.nonnullSupportingTerminationPoint().values());
366                 InstanceIdentifier<TerminationPoint> iiOtnTopologyTp = InstanceIdentifier.builder(Networks.class)
367                     .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
368                     .child(Node.class, new NodeKey(supportingTerminationPoint.get(0).getNodeRef()))
369                     .augmentation(Node1.class)
370                     .child(TerminationPoint.class, new TerminationPointKey(otnTopologyTp.getTpId()))
371                     .build();
372                 networkTransactionService.put(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
373             }
374         }
375         try {
376             networkTransactionService.commit().get();
377         } catch (InterruptedException | ExecutionException e) {
378             LOG.error("Error deleting OTN links in otn-topology", e);
379         }
380         LOG.info("OTN links deletion terminated");
381     }
382
383     @Override
384     public void updateOtnLinks(List<String> nodeTps, String serviceRate, Short tribPortNb, Short tribSoltNb,
385         boolean isDeletion) {
386         List<Link> supportedOdu4Links = getSupportingOdu4Links(nodeTps);
387         List<TerminationPoint> tps = getOtnNodeTps(nodeTps);
388         TopologyShard otnTopologyShard;
389         otnTopologyShard = OpenRoadmOtnTopology.updateOtnLinks(supportedOdu4Links, tps, serviceRate, tribPortNb,
390             tribSoltNb, isDeletion);
391         if (otnTopologyShard.getLinks() != null) {
392             for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
393                 LOG.info("creating and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(),
394                     NetworkUtils.OVERLAY_NETWORK_ID);
395                 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
396                     .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
397                     .augmentation(Network1.class)
398                     .child(Link.class, new LinkKey(new LinkId(otnTopologyLink.getLinkId().getValue())))
399                     .build();
400                 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink,
401                     otnTopologyLink);
402             }
403         }
404         if (otnTopologyShard.getTps() != null) {
405             for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) {
406                 LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue());
407                 List<SupportingTerminationPoint> supportingTerminationPoint =
408                         new ArrayList<>(otnTopologyTp.nonnullSupportingTerminationPoint().values());
409                 InstanceIdentifier<TerminationPoint> iiOtnTopologyTp = InstanceIdentifier.builder(Networks.class)
410                     .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
411                     .child(Node.class, new NodeKey(supportingTerminationPoint.get(0).getNodeRef()))
412                     .augmentation(Node1.class)
413                     .child(TerminationPoint.class, new TerminationPointKey(
414                         new TpId(otnTopologyTp.getTpId().getValue())))
415                     .build();
416                 if (isDeletion) {
417                     networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
418                 } else {
419                     networkTransactionService.put(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
420                 }
421             }
422         }
423         try {
424             networkTransactionService.commit().get();
425         } catch (InterruptedException | ExecutionException e) {
426             LOG.error("Error updating OTN links in otn-topology", e);
427         }
428     }
429
430     private List<Link> getOtnLinks(List<LinkId> linkIds) {
431         List<Link> links = new ArrayList<>();
432         for (LinkId linkId : linkIds) {
433             InstanceIdentifier<Link> iiLink = InstanceIdentifier.builder(Networks.class)
434                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
435                 .augmentation(Network1.class)
436                 .child(Link.class, new LinkKey(linkId))
437                 .build();
438             ListenableFuture<Optional<Link>> linkOptLf = networkTransactionService
439                 .read(LogicalDatastoreType.CONFIGURATION, iiLink);
440             if (linkOptLf.isDone()) {
441                 try {
442                     if (linkOptLf.get().isPresent()) {
443                         links.add(linkOptLf.get().get());
444                     }
445                 } catch (InterruptedException | ExecutionException e) {
446                     LOG.error("Error retreiving OTN links from otn-topology", e);
447                 }
448             } else {
449                 LOG.error("Error retreiving link {} from otn-topology", linkId.getValue());
450             }
451         }
452         return links;
453     }
454
455     private boolean checkLinks(List<Link> links) {
456         boolean canBeDeleted = true;
457         if (links.isEmpty()) {
458             return false;
459         } else {
460             for (Link link : links) {
461                 if (link.augmentation(Link1.class) != null
462                     && !link.augmentation(Link1.class).getUsedBandwidth().equals(Uint32.valueOf(0))) {
463                     canBeDeleted = false;
464                 }
465             }
466         }
467         return canBeDeleted;
468     }
469
470     private boolean checkTerminationPoints(List<TerminationPoint> tps) {
471         boolean canBeDeleted = true;
472         if (tps.isEmpty()) {
473             return false;
474         } else {
475             for (TerminationPoint tp : tps) {
476                 if (tp.augmentation(TerminationPoint1.class) != null
477                     && tp.augmentation(TerminationPoint1.class).getXpdrTpPortConnectionAttributes().getTsPool() != null
478                     && tp.augmentation(TerminationPoint1.class).getXpdrTpPortConnectionAttributes().getTsPool()
479                     .size() != 80) {
480                     canBeDeleted = false;
481                 }
482             }
483         }
484         return canBeDeleted;
485     }
486
487     private List<TerminationPoint> getOtnNodeTps(String nodeTopoA, String tpA, String nodeTopoZ, String tpZ) {
488         List<TerminationPoint> tps = new ArrayList<>();
489         InstanceIdentifier<TerminationPoint> iiTpA = InstanceIdentifier.builder(Networks.class)
490             .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
491             .child(Node.class, new NodeKey(new NodeId(nodeTopoA)))
492             .augmentation(Node1.class)
493             .child(TerminationPoint.class, new TerminationPointKey(new TpId(tpA)))
494             .build();
495         Optional<TerminationPoint> tpAOpt = Optional.empty();
496         InstanceIdentifier<TerminationPoint> iiTpZ = InstanceIdentifier.builder(Networks.class)
497             .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
498             .child(Node.class, new NodeKey(new NodeId(nodeTopoZ)))
499             .augmentation(Node1.class)
500             .child(TerminationPoint.class, new TerminationPointKey(new TpId(tpZ)))
501             .build();
502         Optional<TerminationPoint> tpZOpt = Optional.empty();
503
504         if (networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpA).isDone()
505             && networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpZ).isDone()) {
506             try {
507                 tpAOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpA).get();
508                 tpZOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpZ).get();
509             } catch (InterruptedException | ExecutionException e) {
510                 LOG.error("Error retreiving tp {} of node {} or tp {} from node {} from otn-topology", tpA, nodeTopoA,
511                     tpZ, nodeTopoZ, e);
512             }
513         } else {
514             LOG.error("error getting node termination points from the datastore");
515         }
516
517         if (tpAOpt.isPresent() && tpZOpt.isPresent()) {
518             tps.add(tpAOpt.get());
519             tps.add(tpZOpt.get());
520         }
521         return tps;
522     }
523
524     private List<TerminationPoint> getOtnNodeTps(List<String> nodeTopoTps) {
525         List<TerminationPoint> tps = new ArrayList<>();
526         for (String str : nodeTopoTps) {
527             String nodeId = str.split("--")[0];
528             String tp = str.split("--")[1];
529             InstanceIdentifier<TerminationPoint> iiTp = InstanceIdentifier.builder(Networks.class)
530                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
531                 .child(Node.class, new NodeKey(new NodeId(nodeId)))
532                 .augmentation(Node1.class)
533                 .child(TerminationPoint.class, new TerminationPointKey(new TpId(tp)))
534                 .build();
535             Optional<TerminationPoint> tpOpt;
536             if (networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTp).isDone()) {
537                 try {
538                     tpOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTp).get();
539                     if (tpOpt.isPresent()) {
540                         tps.add(tpOpt.get());
541                     }
542                 } catch (InterruptedException | ExecutionException e) {
543                     LOG.error("Error retreiving tp {} of node {} from otn-topology", tp, nodeId, e);
544                 }
545             } else {
546                 LOG.error("error getting node termination points from the datastore");
547             }
548         }
549         if (tps.isEmpty()) {
550             LOG.warn("returning null");
551             return null;
552         } else {
553             LOG.info("returning tps = {}", tps.toString());
554             return tps;
555         }
556     }
557
558     private void deleteLinks(List<Link> links) {
559         for (Link otnTopologyLink : links) {
560             LOG.info("deleting link {} from {}", otnTopologyLink.getLinkId().getValue(),
561                 NetworkUtils.OVERLAY_NETWORK_ID);
562             InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
563                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
564                 .augmentation(Network1.class)
565                 .child(Link.class, otnTopologyLink.key())
566                 .build();
567             networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink);
568         }
569         try {
570             networkTransactionService.commit().get();
571         } catch (InterruptedException | ExecutionException e) {
572             LOG.error("Error deleting OTN links from otn-topology", e);
573         }
574     }
575
576     private List<Link> getSupportingOdu4Links(List<String> nodesTopoTps) {
577         InstanceIdentifier<Network1> iiOtnTopologyLinks = InstanceIdentifier.builder(Networks.class)
578             .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
579             .augmentation(Network1.class)
580             .build();
581         ListenableFuture<Optional<Network1>> netw1Fl = networkTransactionService
582             .read(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLinks);
583         Optional<Network1> netw1Opt = Optional.empty();
584         if (netw1Fl.isDone()) {
585             try {
586                 netw1Opt = netw1Fl.get();
587             } catch (InterruptedException | ExecutionException e) {
588                 LOG.error("Error retreiving list of links from otn-topology", e);
589             }
590         }
591         List<Link> odu4links = null;
592         if (netw1Opt.isPresent() && netw1Opt.get().getLink() != null) {
593             odu4links = netw1Opt
594                     .get()
595                     .nonnullLink().values()
596                     .stream().filter(lk -> lk.getLinkId().getValue().startsWith("ODU4"))
597                 .collect(Collectors.toList());
598         }
599         List<Link> links = new ArrayList<>();
600         if (odu4links != null) {
601             for (String str : nodesTopoTps) {
602                 String[] nodeAndTp = str.split("--");
603                 if (nodeAndTp.length >= 2) {
604                     String nodeId = nodeAndTp[0];
605                     String tp = nodeAndTp[1];
606                     Link slink = odu4links.stream().filter(lk -> lk.getSource().getSourceNode().getValue()
607                         .equals(nodeId) && lk.getSource().getSourceTp().toString().equals(tp))
608                         .findFirst().get();
609                     if (!links.contains(slink)) {
610                         links.add(slink);
611                     }
612                     Link dlink = odu4links.stream().filter(lk -> lk.getDestination().getDestNode().getValue()
613                         .equals(nodeId) && lk.getDestination().getDestTp().toString().equals(tp))
614                         .findFirst().get();
615                     if (!links.contains(dlink)) {
616                         links.add(dlink);
617                     }
618                 }
619             }
620             LOG.debug("odu4links = {}", links.toString());
621             return links;
622         } else {
623             return null;
624         }
625     }
626
627     private void createOpenRoadmOtnNode(String nodeId) {
628         TopologyShard otnTopologyShard = OpenRoadmOtnTopology.createTopologyShard(portMapping.getNode(nodeId));
629         if (otnTopologyShard != null) {
630             this.otnTopologyShardMountedDevice.put(nodeId, otnTopologyShard);
631             for (Node otnTopologyNode : otnTopologyShard.getNodes()) {
632                 LOG.info("creating otn node {} in {}", otnTopologyNode.getNodeId().getValue(),
633                     NetworkUtils.OTN_NETWORK_ID);
634                 InstanceIdentifier<Node> iiOtnTopologyNode = InstanceIdentifier.builder(Networks.class)
635                     .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
636                     .child(Node.class, otnTopologyNode.key())
637                     .build();
638                 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyNode,
639                     otnTopologyNode);
640             }
641             for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
642                 LOG.info("creating otn link {} in {}", otnTopologyLink.getLinkId().getValue(),
643                     NetworkUtils.OVERLAY_NETWORK_ID);
644                 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
645                     .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
646                     .augmentation(Network1.class)
647                     .child(Link.class, otnTopologyLink.key())
648                     .build();
649                 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink,
650                     otnTopologyLink);
651             }
652         } else {
653             LOG.error("Unable to create OTN topology shard for node {}!", nodeId);
654         }
655
656     }
657 }