2 * Copyright © 2016 AT&T and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.transportpce.networkmodel.service;
10 import com.google.common.util.concurrent.ListenableFuture;
11 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
12 import java.util.ArrayList;
13 import java.util.HashMap;
14 import java.util.List;
16 import java.util.Optional;
17 import java.util.concurrent.ExecutionException;
18 import java.util.concurrent.TimeUnit;
19 import java.util.concurrent.TimeoutException;
20 import java.util.stream.Collectors;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
23 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
24 import org.opendaylight.transportpce.common.InstanceIdentifiers;
25 import org.opendaylight.transportpce.common.NetworkUtils;
26 import org.opendaylight.transportpce.common.mapping.PortMapping;
27 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
28 import org.opendaylight.transportpce.networkmodel.R2RLinkDiscovery;
29 import org.opendaylight.transportpce.networkmodel.dto.TopologyShard;
30 import org.opendaylight.transportpce.networkmodel.util.ClliNetwork;
31 import org.opendaylight.transportpce.networkmodel.util.LinkIdUtil;
32 import org.opendaylight.transportpce.networkmodel.util.OpenRoadmNetwork;
33 import org.opendaylight.transportpce.networkmodel.util.OpenRoadmOtnTopology;
34 import org.opendaylight.transportpce.networkmodel.util.OpenRoadmTopology;
35 import org.opendaylight.transportpce.networkmodel.util.TopologyUtils;
36 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.TopologyUpdateResult;
37 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.TopologyUpdateResultBuilder;
38 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.topology.update.result.TopologyChanges;
39 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.topology.update.result.TopologyChangesBuilder;
40 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.topology.update.result.TopologyChangesKey;
41 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210927.OpenroadmNodeVersion;
42 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210927.mapping.Mapping;
43 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210927.network.nodes.NodeInfo;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.types.rev191129.NodeTypes;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev200529.Link1;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev200529.TerminationPoint1;
47 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev210618.link.tp.LinkTp;
48 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev210618.link.tp.LinkTpBuilder;
49 import org.opendaylight.yang.gen.v1.http.transportpce.topology.rev210511.OtnLinkType;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NetworkId;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.Networks;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.NetworkKey;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.NodeKey;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.LinkId;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Network1;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.TpId;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link;
62 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.LinkKey;
63 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPoint;
64 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointKey;
65 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.termination.point.SupportingTerminationPoint;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus;
67 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
68 import org.opendaylight.yangtools.yang.common.Uint32;
69 import org.slf4j.Logger;
70 import org.slf4j.LoggerFactory;
72 public class NetworkModelServiceImpl implements NetworkModelService {
74 private static final Logger LOG = LoggerFactory.getLogger(NetworkModelServiceImpl.class);
76 private NetworkTransactionService networkTransactionService;
77 private final R2RLinkDiscovery linkDiscovery;
78 private final PortMapping portMapping;
79 private Map<String, TopologyShard> topologyShardMountedDevice;
80 private Map<String, TopologyShard> otnTopologyShardMountedDevice;
81 // Variables for creating and sending topology update notification
82 private final NotificationPublishService notificationPublishService;
83 private Map<TopologyChangesKey, TopologyChanges> topologyChanges;
84 private TopologyUpdateResult notification = null;
86 public NetworkModelServiceImpl(final NetworkTransactionService networkTransactionService,
87 final R2RLinkDiscovery linkDiscovery, PortMapping portMapping,
88 final NotificationPublishService notificationPublishService) {
90 this.networkTransactionService = networkTransactionService;
91 this.linkDiscovery = linkDiscovery;
92 this.portMapping = portMapping;
93 this.topologyShardMountedDevice = new HashMap<String, TopologyShard>();
94 this.otnTopologyShardMountedDevice = new HashMap<String, TopologyShard>();
95 this.notificationPublishService = notificationPublishService;
96 this.topologyChanges = new HashMap<TopologyChangesKey, TopologyChanges>();
100 LOG.info("init ...");
103 public void close() {
107 public void createOpenRoadmNode(String nodeId, String openRoadmVersion) {
109 LOG.info("createOpenROADMNode: {} ", nodeId);
111 if (!portMapping.createMappingData(nodeId, openRoadmVersion)) {
112 LOG.warn("Could not generate port mapping for {} skipping network model creation", nodeId);
115 NodeInfo nodeInfo = portMapping.getNode(nodeId).getNodeInfo();
116 // node creation in clli-network
117 Node clliNode = ClliNetwork.createNode(nodeId, nodeInfo);
118 InstanceIdentifier<Node> iiClliNode = InstanceIdentifier.builder(Networks.class)
119 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.CLLI_NETWORK_ID)))
120 .child(Node.class, clliNode.key())
122 LOG.info("creating node in {}", NetworkUtils.CLLI_NETWORK_ID);
123 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiClliNode, clliNode);
125 // node creation in openroadm-network
126 Node openroadmNetworkNode = OpenRoadmNetwork.createNode(nodeId, nodeInfo);
127 InstanceIdentifier<Node> iiopenroadmNetworkNode = InstanceIdentifier.builder(Networks.class)
128 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID)))
129 .child(Node.class, openroadmNetworkNode.key())
131 LOG.info("creating node in {}", NetworkUtils.UNDERLAY_NETWORK_ID);
132 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiopenroadmNetworkNode,
133 openroadmNetworkNode);
135 // nodes/links creation in openroadm-topology
136 TopologyShard topologyShard = OpenRoadmTopology.createTopologyShard(portMapping.getNode(nodeId));
137 if (topologyShard != null) {
138 this.topologyShardMountedDevice.put(nodeId, topologyShard);
139 for (Node openRoadmTopologyNode : topologyShard.getNodes()) {
140 LOG.info("creating node {} in {}", openRoadmTopologyNode.getNodeId().getValue(),
141 NetworkUtils.OVERLAY_NETWORK_ID);
142 InstanceIdentifier<Node> iiOpenRoadmTopologyNode = InstanceIdentifier.builder(Networks.class)
143 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
144 .child(Node.class, openRoadmTopologyNode.key())
146 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyNode,
147 openRoadmTopologyNode);
149 for (Link openRoadmTopologyLink : topologyShard.getLinks()) {
150 LOG.info("creating link {} in {}", openRoadmTopologyLink.getLinkId().getValue(),
151 NetworkUtils.OVERLAY_NETWORK_ID);
152 InstanceIdentifier<Link> iiOpenRoadmTopologyLink = InstanceIdentifier.builder(Networks.class)
153 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
154 .augmentation(Network1.class)
155 .child(Link.class, openRoadmTopologyLink.key())
157 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyLink,
158 openRoadmTopologyLink);
161 LOG.error("Unable to create openroadm-topology shard for node {}!", nodeId);
163 // nodes/links creation in otn-topology
164 if (nodeInfo.getNodeType().getIntValue() == 2 && (nodeInfo.getOpenroadmVersion().getIntValue() != 1)) {
165 createOpenRoadmOtnNode(nodeId);
167 networkTransactionService.commit().get();
168 // neighbour links through LLDP
169 if (nodeInfo.getNodeType().getIntValue() == 1) {
170 this.linkDiscovery.readLLDP(new NodeId(nodeId), openRoadmVersion);
172 LOG.info("all nodes and links created");
173 } catch (InterruptedException | ExecutionException e) {
174 LOG.error("ERROR: ", e);
179 public void setOpenRoadmNodeStatus(String nodeId, NetconfNodeConnectionStatus.ConnectionStatus connectionStatus) {
180 LOG.info("setOpenROADMNodeStatus: {} {}", nodeId, connectionStatus.name());
182 TODO: set connection status of the device in model,
183 TODO: so we don't need to keep it in memory (Set<String> currentMountedDevice)
184 TODO: unfortunately there is no connection status OpenROADM in network models
185 TODO: waiting for new model version
190 @see org.opendaylight.transportpce.networkmodel.service.NetworkModelService# deleteOpenROADMnode(java.lang.String)
194 public boolean deleteOpenRoadmnode(String nodeId) {
196 if (!this.portMapping.isNodeExist(nodeId)) {
199 NodeKey nodeIdKey = new NodeKey(new NodeId(nodeId));
201 LOG.info("deleting node in {}", NetworkUtils.UNDERLAY_NETWORK_ID);
202 InstanceIdentifier<Node> iiopenroadmNetworkNode = InstanceIdentifier.builder(Networks.class)
203 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID)))
204 .child(Node.class, nodeIdKey)
206 this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiopenroadmNetworkNode);
208 TopologyShard topologyShard = this.topologyShardMountedDevice.get(nodeId);
209 if (topologyShard != null) {
210 for (Node openRoadmTopologyNode : topologyShard.getNodes()) {
211 LOG.info("deleting node {} in {}", openRoadmTopologyNode.getNodeId().getValue(),
212 NetworkUtils.OVERLAY_NETWORK_ID);
213 InstanceIdentifier<Node> iiOpenRoadmTopologyNode = InstanceIdentifier.builder(Networks.class)
214 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
215 .child(Node.class, openRoadmTopologyNode.key())
217 this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyNode);
219 for (Link openRoadmTopologyLink : topologyShard.getLinks()) {
220 LOG.info("deleting link {} in {}", openRoadmTopologyLink.getLinkId().getValue(),
221 NetworkUtils.OVERLAY_NETWORK_ID);
222 InstanceIdentifier<Link> iiOpenRoadmTopologyLink = InstanceIdentifier.builder(Networks.class)
223 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
224 .augmentation(Network1.class)
225 .child(Link.class, openRoadmTopologyLink.key())
227 this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOpenRoadmTopologyLink);
230 LOG.warn("TopologyShard for node '{}' is not present", nodeId);
233 OpenroadmNodeVersion deviceVersion = this.portMapping.getNode(nodeId).getNodeInfo().getOpenroadmVersion();
235 NodeTypes nodeType = this.portMapping.getNode(nodeId).getNodeInfo().getNodeType();
236 if (nodeType.getIntValue() == 2 && deviceVersion.getIntValue() != 1) {
237 TopologyShard otnTopologyShard = this.otnTopologyShardMountedDevice.get(nodeId);
238 if (otnTopologyShard != null) {
239 LOG.info("suppression de otnTopologyShard = {}", otnTopologyShard.toString());
240 for (Node otnTopologyNode : otnTopologyShard.getNodes()) {
241 LOG.info("deleting node {} in {}", otnTopologyNode.getNodeId().getValue(),
242 NetworkUtils.OTN_NETWORK_ID);
243 InstanceIdentifier<Node> iiotnTopologyNode = InstanceIdentifier.builder(Networks.class)
244 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
245 .child(Node.class, otnTopologyNode.key())
247 this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiotnTopologyNode);
249 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
250 LOG.info("deleting link {} in {}", otnTopologyLink.getLinkId().getValue(),
251 NetworkUtils.OTN_NETWORK_ID);
252 InstanceIdentifier<Link> iiotnTopologyLink = InstanceIdentifier.builder(Networks.class)
253 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
254 .augmentation(Network1.class)
255 .child(Link.class, otnTopologyLink.key())
257 this.networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiotnTopologyLink);
262 LOG.info("deleteOpenROADMnode: {} version {}", nodeId, deviceVersion.getName());
263 this.portMapping.deletePortMappingNode(nodeId);
265 this.networkTransactionService.commit().get(1, TimeUnit.SECONDS);
266 LOG.info("all nodes and links deleted ! ");
267 } catch (InterruptedException | ExecutionException | TimeoutException e) {
268 LOG.error("Error when trying to delete node : {}", nodeId, e);
275 public void updateOpenRoadmTopologies(String nodeId, Mapping mapping) {
276 LOG.info("update OpenRoadm topologies after change update from: {} ", nodeId);
277 this.topologyChanges.clear();
278 Network openroadmTopology = null;
279 Network otnTopology = null;
280 Map<LinkKey, Link> openroadmTopologyLinks = null;
281 Map<LinkKey, Link> otnTopologyLinks = null;
283 openroadmTopology = this.networkTransactionService
284 .read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifiers.OVERLAY_NETWORK_II)
286 if (openroadmTopology.augmentation(Network1.class) != null) {
287 openroadmTopologyLinks = openroadmTopology.augmentation(Network1.class).getLink();
289 otnTopology = this.networkTransactionService
290 .read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifiers.OTN_NETWORK_II)
292 if (otnTopology.augmentation(Network1.class) != null) {
293 otnTopologyLinks = otnTopology.augmentation(Network1.class).getLink();
295 } catch (InterruptedException | ExecutionException e) {
296 LOG.error("Error when trying to update node : {}", nodeId, e);
298 if (openroadmTopology == null || otnTopology == null) {
299 LOG.warn("Error getting topologies from datastore");
302 String abstractNodeid = String.join("-", nodeId, mapping.getLogicalConnectionPoint().split("-")[0]);
303 // nodes/links update in openroadm-topology
304 if (openroadmTopology.getNode() != null) {
305 TopologyShard topologyShard = TopologyUtils.updateTopologyShard(abstractNodeid, mapping,
306 openroadmTopology.getNode(), openroadmTopologyLinks);
307 if (topologyShard.getLinks() != null) {
308 for (Link link : topologyShard.getLinks()) {
309 LOG.info("updating links {} in {}", link.getLinkId().getValue(),
310 NetworkUtils.OVERLAY_NETWORK_ID);
311 InstanceIdentifier<Link> iiTopologyLink = InstanceIdentifier.builder(Networks.class)
312 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
313 .augmentation(Network1.class)
314 .child(Link.class, link.key())
316 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyLink, link);
319 if (topologyShard.getTps() != null) {
320 for (TerminationPoint tp : topologyShard.getTps()) {
321 LOG.info("updating TP {} in openroadm-topology", tp.getTpId().getValue());
322 InstanceIdentifier<TerminationPoint> iiTopologyTp = InstanceIdentifier.builder(Networks.class)
323 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
324 .child(Node.class, new NodeKey(new NodeId(abstractNodeid)))
325 .augmentation(Node1.class)
326 .child(TerminationPoint.class, new TerminationPointKey(tp.getTpId()))
328 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyTp, tp);
329 TopologyChanges tc = new TopologyChangesBuilder()
330 .withKey(new TopologyChangesKey(abstractNodeid, tp.getTpId().getValue()))
331 .setNodeId(abstractNodeid)
332 .setTpId(tp.getTpId().getValue())
333 .setState(tp.augmentation(
334 org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.TerminationPoint1
335 .class).getOperationalState())
337 if (!this.topologyChanges.containsKey(tc.key())) {
338 this.topologyChanges.put(tc.key(), tc);
343 // nodes/links update in otn-topology
344 if (otnTopology.getNode() != null
345 && otnTopology.getNode().containsKey(new NodeKey(new NodeId(abstractNodeid)))) {
346 TopologyShard otnShard = TopologyUtils.updateTopologyShard(abstractNodeid, mapping,
347 otnTopology.getNode(), otnTopologyLinks);
348 if (otnShard.getLinks() != null) {
349 for (Link link : otnShard.getLinks()) {
350 LOG.info("updating links {} in {}", link.getLinkId().getValue(),
351 NetworkUtils.OVERLAY_NETWORK_ID);
352 InstanceIdentifier<Link> iiTopologyLink = InstanceIdentifier.builder(Networks.class)
353 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
354 .augmentation(Network1.class)
355 .child(Link.class, link.key())
357 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyLink, link);
360 if (otnShard.getTps() != null) {
361 for (TerminationPoint tp : otnShard.getTps()) {
362 LOG.info("updating TP {} in otn-topology", tp.getTpId().getValue());
363 InstanceIdentifier<TerminationPoint> iiTopologyTp = InstanceIdentifier.builder(Networks.class)
364 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
365 .child(Node.class, new NodeKey(new NodeId(abstractNodeid)))
366 .augmentation(Node1.class)
367 .child(TerminationPoint.class, new TerminationPointKey(tp.getTpId()))
369 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiTopologyTp, tp);
370 TopologyChanges tc = new TopologyChangesBuilder()
371 .withKey(new TopologyChangesKey(abstractNodeid, tp.getTpId().getValue()))
372 .setNodeId(abstractNodeid)
373 .setTpId(tp.getTpId().getValue())
374 .setState(tp.augmentation(
375 org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.TerminationPoint1
376 .class).getOperationalState())
378 if (!this.topologyChanges.containsKey(tc.key())) {
379 this.topologyChanges.put(tc.key(), tc);
384 // commit datastore updates
386 networkTransactionService.commit().get();
388 } catch (InterruptedException | ExecutionException e) {
389 LOG.error("Error updating openroadm-topology", e);
394 public void createOtnLinks(String nodeA, String tpA, String nodeZ, String tpZ, OtnLinkType linkType) {
395 TopologyShard otnTopologyShard;
399 otnTopologyShard = OpenRoadmOtnTopology.createOtnLinks(nodeA, tpA, nodeZ, tpZ, linkType);
403 List<LinkId> linkIdList = new ArrayList<>();
405 if (OtnLinkType.ODTU4.equals(linkType)) {
406 prefix = OtnLinkType.OTU4.getName();
408 prefix = OtnLinkType.OTUC4.getName();
410 linkIdList.add(LinkIdUtil.buildOtnLinkId(convertNetconfNodeIdToTopoNodeId(nodeA, tpA), tpA,
411 convertNetconfNodeIdToTopoNodeId(nodeZ, tpZ), tpZ, prefix));
412 linkIdList.add(LinkIdUtil.buildOtnLinkId(convertNetconfNodeIdToTopoNodeId(nodeZ, tpZ), tpZ,
413 convertNetconfNodeIdToTopoNodeId(nodeA, tpA), tpA, prefix));
414 List<Link> supportedOtu4links = getOtnLinks(linkIdList);
415 List<TerminationPoint> tps = getOtnNodeTps(convertNetconfNodeIdToTopoNodeId(nodeA, tpA), tpA,
416 convertNetconfNodeIdToTopoNodeId(nodeZ, tpZ), tpZ);
417 otnTopologyShard = OpenRoadmOtnTopology.createOtnLinks(supportedOtu4links, tps, linkType);
420 LOG.error("unknown otn link type {}", linkType);
421 otnTopologyShard = new TopologyShard(null, null);
423 if (otnTopologyShard.getLinks() != null) {
424 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
425 LOG.info("creating and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(),
426 NetworkUtils.OVERLAY_NETWORK_ID);
427 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
428 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
429 .augmentation(Network1.class)
430 .child(Link.class, otnTopologyLink.key())
432 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
435 if (otnTopologyShard.getTps() != null) {
436 for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) {
437 LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue());
438 List<SupportingTerminationPoint> supportingTerminationPoint =
439 new ArrayList<>(otnTopologyTp.nonnullSupportingTerminationPoint().values());
440 InstanceIdentifier<TerminationPoint> iiOtnTopologyTp = InstanceIdentifier.builder(Networks.class)
441 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
442 .child(Node.class, new NodeKey(supportingTerminationPoint.get(0).getNodeRef()))
443 .augmentation(Node1.class)
444 .child(TerminationPoint.class, new TerminationPointKey(otnTopologyTp.getTpId()))
446 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
450 networkTransactionService.commit().get();
451 } catch (InterruptedException | ExecutionException e) {
452 LOG.error("Error adding OTN links in otn-topology", e);
454 LOG.info("OTN links created");
458 public void deleteOtnLinks(String nodeA, String tpA, String nodeZ, String tpZ, OtnLinkType linkType) {
459 TopologyShard otnTopologyShard;
460 String nodeTopoA = new StringBuilder(nodeA).append("-").append(tpA.split("-")[0]).toString();
461 String nodeTopoZ = new StringBuilder(nodeZ).append("-").append(tpZ.split("-")[0]).toString();
463 List<LinkId> linkIdList = new ArrayList<>();
468 if (OtnLinkType.OTU4.equals(linkType)) {
469 prefix = OtnLinkType.OTU4.getName();
471 prefix = OtnLinkType.OTUC4.getName();
473 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, prefix));
474 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, prefix));
475 otuLinks = getOtnLinks(linkIdList);
476 if (checkLinks(otuLinks)) {
477 deleteLinks(otuLinks);
479 LOG.error("Error deleting OTU4 links");
481 otnTopologyShard = new TopologyShard(null, null);
486 if (OtnLinkType.ODTU4.equals(linkType)) {
487 prefix = OtnLinkType.ODTU4.getName();
488 prefix2 = OtnLinkType.OTU4.getName();
490 prefix = OtnLinkType.ODUC4.getName();
491 prefix2 = OtnLinkType.OTUC4.getName();
493 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, prefix));
494 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, prefix));
495 List<Link> oduLinks = getOtnLinks(linkIdList);
496 List<TerminationPoint> tps = getOtnNodeTps(nodeTopoA, tpA, nodeTopoZ, tpZ);
497 if (checkLinks(oduLinks) && checkTerminationPoints(tps)) {
498 deleteLinks(oduLinks);
500 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, tpA, nodeTopoZ, tpZ, prefix2));
501 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, tpZ, nodeTopoA, tpA, prefix2));
502 otuLinks = getOtnLinks(linkIdList);
503 otnTopologyShard = OpenRoadmOtnTopology.deleteOtnLinks(otuLinks, tps, linkType);
505 LOG.error("Error deleting ODU4 links");
506 otnTopologyShard = new TopologyShard(null, null);
510 LOG.error("unknown otn link type {}", linkType);
511 otnTopologyShard = new TopologyShard(null, null);
513 if (otnTopologyShard.getLinks() != null) {
514 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
515 LOG.info("deleting and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(),
516 NetworkUtils.OVERLAY_NETWORK_ID);
517 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
518 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
519 .augmentation(Network1.class)
520 .child(Link.class, otnTopologyLink.key())
522 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
525 if (otnTopologyShard.getTps() != null) {
526 for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) {
527 LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue());
528 List<SupportingTerminationPoint> supportingTerminationPoint =
529 new ArrayList<>(otnTopologyTp.nonnullSupportingTerminationPoint().values());
530 InstanceIdentifier<TerminationPoint> iiOtnTopologyTp = InstanceIdentifier.builder(Networks.class)
531 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
532 .child(Node.class, new NodeKey(supportingTerminationPoint.get(0).getNodeRef()))
533 .augmentation(Node1.class)
534 .child(TerminationPoint.class, new TerminationPointKey(otnTopologyTp.getTpId()))
536 networkTransactionService.put(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
540 networkTransactionService.commit().get();
541 } catch (InterruptedException | ExecutionException e) {
542 LOG.error("Error deleting OTN links in otn-topology", e);
544 LOG.info("OTN links deletion terminated");
548 public void updateOtnLinks(
549 org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.renderer.rpc.result.sp.Link
550 notifLink, Uint32 serviceRate, Short tribPortNb, Short minTribSoltNb, Short maxTribSlotNb,
551 boolean isDeletion) {
553 LinkTp atermination = new LinkTpBuilder()
554 .setNodeId(notifLink.getATermination().getNodeId())
555 .setTpId(notifLink.getATermination().getTpId())
557 LinkTp ztermination = new LinkTpBuilder()
558 .setNodeId(notifLink.getZTermination().getNodeId())
559 .setTpId(notifLink.getZTermination().getTpId())
561 List<LinkTp> linkTerminations = new ArrayList<>();
562 linkTerminations.add(atermination);
563 linkTerminations.add(ztermination);
565 List<Link> supportedOdu4Links = getSupportingOdu4Links(linkTerminations, serviceRate);
566 List<TerminationPoint> tps = getOtnNodeTps(linkTerminations);
567 TopologyShard otnTopologyShard;
568 otnTopologyShard = OpenRoadmOtnTopology.updateOtnLinks(supportedOdu4Links, tps, serviceRate, tribPortNb,
569 minTribSoltNb, maxTribSlotNb, isDeletion);
570 if (otnTopologyShard.getLinks() != null) {
571 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
572 LOG.info("creating and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(),
573 NetworkUtils.OVERLAY_NETWORK_ID);
574 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
575 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
576 .augmentation(Network1.class)
577 .child(Link.class, new LinkKey(new LinkId(otnTopologyLink.getLinkId().getValue())))
579 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
582 if (otnTopologyShard.getTps() != null) {
583 for (TerminationPoint otnTopologyTp : otnTopologyShard.getTps()) {
584 LOG.info("updating otn nodes TP {} in otn-topology", otnTopologyTp.getTpId().getValue());
585 List<SupportingTerminationPoint> supportingTerminationPoint =
586 new ArrayList<>(otnTopologyTp.nonnullSupportingTerminationPoint().values());
587 InstanceIdentifier<TerminationPoint> iiOtnTopologyTp = InstanceIdentifier.builder(Networks.class)
588 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
589 .child(Node.class, new NodeKey(supportingTerminationPoint.get(0).getNodeRef()))
590 .augmentation(Node1.class)
591 .child(TerminationPoint.class, new TerminationPointKey(new TpId(otnTopologyTp.getTpId()
595 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
597 networkTransactionService.put(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyTp, otnTopologyTp);
602 networkTransactionService.commit().get();
603 } catch (InterruptedException | ExecutionException e) {
604 LOG.error("Error updating OTN links in otn-topology", e);
609 public void updateOtnLinks(
610 org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.renderer.rpc.result.sp.Link
611 notifLink, List<String> suppLinks, boolean isDeletion) {
613 List<LinkId> linkIdList = new ArrayList<>();
614 if (notifLink != null) {
615 String nodeTopoA = convertNetconfNodeIdToTopoNodeId(notifLink.getATermination().getNodeId(),
616 notifLink.getATermination().getTpId());
617 String nodeTopoZ = convertNetconfNodeIdToTopoNodeId(notifLink.getZTermination().getNodeId(),
618 notifLink.getZTermination().getTpId());
619 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoA, notifLink.getATermination().getTpId(),
620 nodeTopoZ, notifLink.getZTermination().getTpId(), OtnLinkType.OTU4.getName()));
621 linkIdList.add(LinkIdUtil.buildOtnLinkId(nodeTopoZ, notifLink.getZTermination().getTpId(),
622 nodeTopoA, notifLink.getATermination().getTpId(), OtnLinkType.OTU4.getName()));
623 } else if (suppLinks != null) {
624 suppLinks.forEach(lk -> linkIdList.add(new LinkId(lk)));
626 LOG.error("Impossible to determine supported otn links without correct input data");
628 List<Link> supportedOtu4links = getOtnLinks(linkIdList);
630 TopologyShard otnTopologyShard = OpenRoadmOtnTopology.updateOtnLinks(supportedOtu4links, isDeletion);
631 if (otnTopologyShard.getLinks() != null) {
632 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
633 LOG.info("creating and updating otn links {} in {}", otnTopologyLink.getLinkId().getValue(),
634 NetworkUtils.OVERLAY_NETWORK_ID);
635 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
636 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
637 .augmentation(Network1.class)
638 .child(Link.class, otnTopologyLink.key())
640 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
644 networkTransactionService.commit().get();
645 } catch (InterruptedException | ExecutionException e) {
646 LOG.error("Error adding OTN links in otn-topology", e);
648 LOG.info("OTN links updated");
651 private List<Link> getOtnLinks(List<LinkId> linkIds) {
652 List<Link> links = new ArrayList<>();
653 for (LinkId linkId : linkIds) {
654 InstanceIdentifier<Link> iiLink = InstanceIdentifier.builder(Networks.class)
655 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
656 .augmentation(Network1.class)
657 .child(Link.class, new LinkKey(linkId))
659 ListenableFuture<Optional<Link>> linkOptLf = networkTransactionService
660 .read(LogicalDatastoreType.CONFIGURATION, iiLink);
661 if (linkOptLf.isDone()) {
663 if (linkOptLf.get().isPresent()) {
664 links.add(linkOptLf.get().get());
666 } catch (InterruptedException | ExecutionException e) {
667 LOG.error("Error retreiving OTN links from otn-topology", e);
670 LOG.error("Error retreiving link {} from otn-topology", linkId.getValue());
676 private boolean checkLinks(List<Link> links) {
677 if (links.isEmpty()) {
680 for (Link link : links) {
681 if (link.augmentation(Link1.class) != null
682 && !link.augmentation(Link1.class).getUsedBandwidth().equals(Uint32.valueOf(0))) {
689 private boolean checkTerminationPoints(List<TerminationPoint> tps) {
693 for (TerminationPoint tp : tps) {
694 if (tp.augmentation(TerminationPoint1.class) != null && tp.augmentation(TerminationPoint1.class)
695 .getXpdrTpPortConnectionAttributes().getTsPool() != null && tp.augmentation(TerminationPoint1.class)
696 .getXpdrTpPortConnectionAttributes().getTsPool().size() != 80) {
703 private List<TerminationPoint> getOtnNodeTps(String nodeTopoA, String tpA, String nodeTopoZ, String tpZ) {
704 List<TerminationPoint> tps = new ArrayList<>();
705 InstanceIdentifier<TerminationPoint> iiTpA = InstanceIdentifier.builder(Networks.class)
706 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
707 .child(Node.class, new NodeKey(new NodeId(nodeTopoA)))
708 .augmentation(Node1.class)
709 .child(TerminationPoint.class, new TerminationPointKey(new TpId(tpA)))
711 Optional<TerminationPoint> tpAOpt = Optional.empty();
712 InstanceIdentifier<TerminationPoint> iiTpZ = InstanceIdentifier.builder(Networks.class)
713 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
714 .child(Node.class, new NodeKey(new NodeId(nodeTopoZ)))
715 .augmentation(Node1.class)
716 .child(TerminationPoint.class, new TerminationPointKey(new TpId(tpZ)))
718 Optional<TerminationPoint> tpZOpt = Optional.empty();
720 if (networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpA).isDone()
721 && networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpZ).isDone()) {
723 tpAOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpA).get();
724 tpZOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTpZ).get();
725 } catch (InterruptedException | ExecutionException e) {
726 LOG.error("Error retreiving tp {} of node {} or tp {} from node {} from otn-topology", tpA, nodeTopoA,
730 LOG.error("error getting node termination points from the datastore");
733 if (tpAOpt.isPresent() && tpZOpt.isPresent()) {
734 tps.add(tpAOpt.get());
735 tps.add(tpZOpt.get());
740 private List<TerminationPoint> getOtnNodeTps(List<LinkTp> linkTerminations) {
741 List<TerminationPoint> tps = new ArrayList<>();
742 for (LinkTp linkTp : linkTerminations) {
743 String tp = linkTp.getTpId();
744 String nodeId = new StringBuilder(linkTp.getNodeId()).append("-")
745 .append(tp.split("-")[0]).toString();
746 InstanceIdentifier<TerminationPoint> iiTp = InstanceIdentifier.builder(Networks.class)
747 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
748 .child(Node.class, new NodeKey(new NodeId(nodeId)))
749 .augmentation(Node1.class)
750 .child(TerminationPoint.class, new TerminationPointKey(new TpId(tp)))
752 Optional<TerminationPoint> tpOpt;
753 if (networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTp).isDone()) {
755 tpOpt = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, iiTp).get();
756 if (tpOpt.isPresent()) {
757 tps.add(tpOpt.get());
759 } catch (InterruptedException | ExecutionException e) {
760 LOG.error("Error retreiving tp {} of node {} from otn-topology", tp, nodeId, e);
763 LOG.error("error getting node termination points from the datastore");
767 LOG.warn("returning null");
770 LOG.info("returning tps = {}", tps.toString());
775 private void deleteLinks(List<Link> links) {
776 for (Link otnTopologyLink : links) {
777 LOG.info("deleting link {} from {}", otnTopologyLink.getLinkId().getValue(),
778 NetworkUtils.OVERLAY_NETWORK_ID);
779 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
780 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
781 .augmentation(Network1.class)
782 .child(Link.class, otnTopologyLink.key())
784 networkTransactionService.delete(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink);
787 networkTransactionService.commit().get();
788 } catch (InterruptedException | ExecutionException e) {
789 LOG.error("Error deleting OTN links from otn-topology", e);
793 private List<Link> getSupportingOdu4Links(List<LinkTp> nodesTopoTps, Uint32 serviceRate) {
794 InstanceIdentifier<Network1> iiOtnTopologyLinks = InstanceIdentifier.builder(Networks.class)
795 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
796 .augmentation(Network1.class)
798 ListenableFuture<Optional<Network1>> netw1Fl = networkTransactionService
799 .read(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLinks);
800 Optional<Network1> netw1Opt = Optional.empty();
801 if (netw1Fl.isDone()) {
803 netw1Opt = netw1Fl.get();
804 } catch (InterruptedException | ExecutionException e) {
805 LOG.error("Error retreiving list of links from otn-topology", e);
808 List<Link> odu4links = null;
809 if (netw1Opt.isPresent() && netw1Opt.get().getLink() != null) {
812 .nonnullLink().values()
813 .stream().filter(lk -> lk.getLinkId().getValue()
814 .startsWith(Uint32.valueOf(100).equals(serviceRate) ? "ODUC4" : "ODTU4"))
815 .collect(Collectors.toList());
817 if (odu4links == null) {
820 List<Link> links = new ArrayList<>();
821 for (LinkTp linkTp : nodesTopoTps) {
822 String tp = linkTp.getTpId();
823 String nodeId = new StringBuilder(linkTp.getNodeId()).append("-")
824 .append(tp.split("-")[0]).toString();
825 Link slink = odu4links.stream().filter(lk -> lk.getSource().getSourceNode().getValue()
826 .equals(nodeId) && lk.getSource().getSourceTp().getValue().equals(tp)).findFirst().get();
827 if (!links.contains(slink)) {
830 Link dlink = odu4links.stream().filter(lk -> lk.getDestination().getDestNode().getValue()
831 .equals(nodeId) && lk.getDestination().getDestTp().getValue().equals(tp)).findFirst().get();
832 if (!links.contains(dlink)) {
836 LOG.debug("odu4oduC4links = {}", links);
840 private void createOpenRoadmOtnNode(String nodeId) {
841 TopologyShard otnTopologyShard = OpenRoadmOtnTopology.createTopologyShard(portMapping.getNode(nodeId));
842 if (otnTopologyShard != null) {
843 this.otnTopologyShardMountedDevice.put(nodeId, otnTopologyShard);
844 for (Node otnTopologyNode : otnTopologyShard.getNodes()) {
845 LOG.info("creating otn node {} in {}", otnTopologyNode.getNodeId().getValue(),
846 NetworkUtils.OTN_NETWORK_ID);
847 InstanceIdentifier<Node> iiOtnTopologyNode = InstanceIdentifier.builder(Networks.class)
848 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
849 .child(Node.class, otnTopologyNode.key())
851 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyNode, otnTopologyNode);
853 for (Link otnTopologyLink : otnTopologyShard.getLinks()) {
854 LOG.info("creating otn link {} in {}", otnTopologyLink.getLinkId().getValue(),
855 NetworkUtils.OVERLAY_NETWORK_ID);
856 InstanceIdentifier<Link> iiOtnTopologyLink = InstanceIdentifier.builder(Networks.class)
857 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID)))
858 .augmentation(Network1.class)
859 .child(Link.class, otnTopologyLink.key())
861 networkTransactionService.merge(LogicalDatastoreType.CONFIGURATION, iiOtnTopologyLink, otnTopologyLink);
864 LOG.error("Unable to create OTN topology shard for node {}!", nodeId);
868 private String convertNetconfNodeIdToTopoNodeId(String nodeId, String tpId) {
869 return new StringBuilder(nodeId).append("-").append(tpId.split("-")[0]).toString();
873 value = "UPM_UNCALLED_PRIVATE_METHOD",
874 justification = "false positive, this method is used by public updateOpenRoadmNetworkTopology")
875 private void sendNotification() {
876 if (topologyChanges.isEmpty()) {
877 LOG.warn("Empty Topology Change List. No updates in topology");
880 this.notification = new TopologyUpdateResultBuilder()
881 .setTopologyChanges(topologyChanges)
884 notificationPublishService.putNotification(this.notification);
885 } catch (InterruptedException e) {
886 LOG.error("Notification offer rejected. Error={}", e.getMessage());