8eebe23e393356b216ca9965017276b1f0725013
[transportpce.git] / networkmodel / src / main / java / org / opendaylight / transportpce / networkmodel / util / OpenRoadmOtnTopology.java
1 /*
2  * Copyright © 2020 Orange. 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
9 package org.opendaylight.transportpce.networkmodel.util;
10
11 import com.google.common.collect.ImmutableMap;
12 import java.util.ArrayList;
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.stream.Collectors;
17 import org.eclipse.jdt.annotation.Nullable;
18 import org.opendaylight.transportpce.common.NetworkUtils;
19 import org.opendaylight.transportpce.networkmodel.dto.OtnTopoNode;
20 import org.opendaylight.transportpce.networkmodel.dto.TopologyShard;
21 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220114.mapping.Mapping;
22 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220114.network.Nodes;
23 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
24 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.types.rev191129.XpdrNodeTypes;
25 import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates;
26 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev200327.xpdr.odu.switching.pools.OduSwitchingPools;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev200327.xpdr.odu.switching.pools.OduSwitchingPoolsBuilder;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev200327.xpdr.odu.switching.pools.OduSwitchingPoolsKey;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev200327.xpdr.odu.switching.pools.odu.switching.pools.NonBlockingList;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev200327.xpdr.odu.switching.pools.odu.switching.pools.NonBlockingListBuilder;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev200327.xpdr.odu.switching.pools.odu.switching.pools.NonBlockingListKey;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.OpenroadmLinkType;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.OpenroadmNodeType;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.OpenroadmTpType;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.xpdr.tp.supported.interfaces.SupportedInterfaceCapability;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.xpdr.tp.supported.interfaces.SupportedInterfaceCapabilityBuilder;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.xpdr.tp.supported.interfaces.SupportedInterfaceCapabilityKey;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev200327.ODTU4TsAllocated;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev200327.ODTUCnTs;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev200327.ODU0;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev200327.ODU2;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev200327.ODU2e;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev200327.ODU4;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev200327.OdtuTypeIdentity;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev200327.OduRateIdentity;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev200529.Link1;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev200529.Link1Builder;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev200529.Node1Builder;
49 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev200529.TerminationPoint1;
50 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev200529.TerminationPoint1Builder;
51 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev200529.networks.network.node.SwitchingPoolsBuilder;
52 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev200529.networks.network.node.TpBandwidthSharingBuilder;
53 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev200529.networks.network.node.XpdrAttributesBuilder;
54 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev200529.networks.network.node.termination.point.TpSupportedInterfacesBuilder;
55 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev200529.networks.network.node.termination.point.XpdrTpPortConnectionAttributesBuilder;
56 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327.SupportedIfCapability;
57 import org.opendaylight.yang.gen.v1.http.org.openroadm.switching.pool.types.rev191129.SwitchingPoolTypes;
58 import org.opendaylight.yang.gen.v1.http.org.openroadm.xponder.rev200529.xpdr.otn.tp.attributes.OdtuTpnPool;
59 import org.opendaylight.yang.gen.v1.http.org.openroadm.xponder.rev200529.xpdr.otn.tp.attributes.OdtuTpnPoolBuilder;
60 import org.opendaylight.yang.gen.v1.http.transportpce.topology.rev220123.OtnLinkType;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NetworkId;
62 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
63 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node;
64 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.NodeBuilder;
65 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.NodeKey;
66 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.node.SupportingNode;
67 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.node.SupportingNodeBuilder;
68 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.node.SupportingNodeKey;
69 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.TpId;
70 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link;
71 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.LinkBuilder;
72 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPoint;
73 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointBuilder;
74 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointKey;
75 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.termination.point.SupportingTerminationPoint;
76 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.termination.point.SupportingTerminationPointBuilder;
77 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.termination.point.SupportingTerminationPointKey;
78 import org.opendaylight.yangtools.yang.common.Uint16;
79 import org.opendaylight.yangtools.yang.common.Uint32;
80 import org.slf4j.Logger;
81 import org.slf4j.LoggerFactory;
82
83 public final class OpenRoadmOtnTopology {
84
85     private static final Logger LOG = LoggerFactory.getLogger(OpenRoadmOtnTopology.class);
86     private static final String CLIENT = "-CLIENT";
87     private static final String NETWORK = "-NETWORK";
88     private static final String XPDR = "-XPDR";
89     private static final String OTN_PARAMS_ERROR = "Error with otn parameters of supported link {}";
90     private static final int NB_TRIB_PORTS = 80;
91     private static final int NB_TRIB_SLOTS = 80;
92
93     private static Map<String, Class<? extends OduRateIdentity>> rateMap = Map.of(
94         "If100GEODU4", ODU4.class,
95         "IfOCHOTU4ODU4", ODU4.class,
96         "If1GEODU0", ODU0.class,
97         "If10GEODU2", ODU2.class,
98         "If10GEODU2e", ODU2e.class);
99     private static Map<OtnLinkType, Long> otnLinkTypeBwMap = Map.of(
100         OtnLinkType.ODTU4, 100000L,
101         OtnLinkType.ODUC4, 400000L,
102         OtnLinkType.ODUC3, 300000L,
103         OtnLinkType.ODUC2, 200000L);
104     private static Map<OtnLinkType, Long> otnOtuLinkTypeBwMap = Map.of(
105         OtnLinkType.OTU4, 100000L,
106         OtnLinkType.OTUC4, 400000L);
107     private static Map<Uint32, Long> serviceRateBwIncrMap = Map.of(
108         Uint32.valueOf(1), 1000L,
109         Uint32.valueOf(10), 10000L,
110         Uint32.valueOf(100), 100000L);
111
112     private OpenRoadmOtnTopology() {
113     }
114
115     public static TopologyShard createTopologyShard(Nodes mappingNode) {
116         List<Node> nodes = new ArrayList<>();
117         List<Link> links = new ArrayList<>();
118         Map<Integer, OtnTopoNode> xpdrMap = convertPortMappingToOtnNodeList(mappingNode);
119         for (OtnTopoNode node : xpdrMap.values()) {
120             switch (node.getNodeType()) {
121                 case Tpdr:
122                     nodes.add(createTpdr(node));
123                     break;
124                 case Mpdr:
125                     nodes.add(createMuxpdr(node));
126                     break;
127                 case Switch:
128                     nodes.add(createSwitch(node));
129                     break;
130                 default:
131                     LOG.error("unknown otn node type {}", node.getNodeType().getName());
132                     return null;
133             }
134         }
135         return new TopologyShard(nodes, links);
136     }
137
138     public static TopologyShard createOtnLinks(String nodeA, String tpA, String nodeZ, String tpZ,
139             OtnLinkType linkType) {
140
141         return new TopologyShard(
142             null,
143             otnOtuLinkTypeBwMap.containsKey(linkType)
144                 ? initialiseOtnLinks(nodeA, tpA, nodeZ, tpZ, linkType)
145                 : null);
146     }
147
148     public static TopologyShard createOtnLinks(
149             org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.renderer.rpc.result.sp
150                 .Link notifLink,
151             OtnLinkType linkType) {
152
153         return new TopologyShard(
154             null,
155             initialiseOtnLinks(notifLink.getATermination().getNodeId(),
156             notifLink.getATermination().getTpId(),
157             notifLink.getZTermination().getNodeId(),
158             notifLink.getZTermination().getTpId(),
159             linkType));
160     }
161
162     public static TopologyShard createOtnLinks(
163             org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.renderer.rpc.result.sp
164                 .Link notifLink,
165             List<Link> supportedOtu4links, List<TerminationPoint> supportedTPs, OtnLinkType linkType) {
166
167         if (otnOtuLinkTypeBwMap.containsKey(linkType)) {
168             return new TopologyShard(
169                 null,
170                 initialiseOtnLinks(
171                     notifLink.getATermination().getNodeId(), notifLink.getATermination().getTpId(),
172                     notifLink.getZTermination().getNodeId(), notifLink.getZTermination().getTpId(), linkType));
173         } else if (otnLinkTypeBwMap.containsKey(linkType)) {
174             List<Link> links = initialiseOtnLinks(
175                 notifLink.getATermination().getNodeId(), notifLink.getATermination().getTpId(),
176                 notifLink.getZTermination().getNodeId(), notifLink.getZTermination().getTpId(), linkType);
177             links.addAll(updateOtnLinkBwParameters(supportedOtu4links, linkType));
178             List<TerminationPoint> updatedTPs = new ArrayList<>();
179             for (TerminationPoint tp : supportedTPs) {
180                 updatedTPs.add(updateTp(tp, true, linkType));
181             }
182             return new TopologyShard(null, links, updatedTPs);
183         } else {
184             return null;
185         }
186     }
187
188     public static TopologyShard createOtnLinks(List<Link> suppOtuLinks, List<TerminationPoint> oldTps,
189             OtnLinkType linkType) {
190
191         List<Link> links = new ArrayList<>();
192         for (Link link : suppOtuLinks) {
193             if (link.augmentation(Link1.class) == null) {
194                 LOG.error("Error with OTN parameters of supported link {}", link.getLinkId().getValue());
195                 continue;
196             }
197             if (!otnLinkTypeBwMap.containsKey(linkType)) {
198                 LOG.error("Error with link {} : unsupported OTN link type", link.getLinkId().getValue());
199                 continue;
200             }
201             if (!link.augmentation(Link1.class).getAvailableBandwidth()
202                     .equals(Uint32.valueOf(otnLinkTypeBwMap.get(linkType)))) {
203                     //TODO shouldn't it be < rather than !equals() here ?
204                 LOG.error("Error with link {} : unsufficient available bandwith", link.getLinkId().getValue());
205                 continue;
206             }
207             links.add(updateOtnLinkBwParameters(link, 0L, otnLinkTypeBwMap.get(linkType)));
208         }
209         if (links.size() == 2) {
210             links.addAll(initialiseOtnLinks(suppOtuLinks.get(0).getSource().getSourceNode().getValue(),
211                 suppOtuLinks.get(0).getSource().getSourceTp().getValue(),
212                 suppOtuLinks.get(0).getDestination().getDestNode().getValue(),
213                 suppOtuLinks.get(0).getDestination().getDestTp().getValue(),
214                 linkType));
215         }
216         List<TerminationPoint> tps = new ArrayList<>();
217         for (TerminationPoint tp : oldTps) {
218             tps.add(updateTp(tp, true, linkType));
219         }
220         return links.size() == 4 && tps.size() == 2
221             ?  new TopologyShard(null, links, tps)
222             :  new TopologyShard(null, null, null);
223     }
224
225     public static TopologyShard updateOtnLinks(List<Link> suppOduLinks, List<TerminationPoint> oldTps,
226             Uint32 serviceRate, Short tribPortNb, Short minTribSlotNb, Short maxTribSlotNb, boolean isDeletion) {
227
228         List<Link> links = new ArrayList<>();
229         if (!serviceRateBwIncrMap.containsKey(serviceRate)) {
230             LOG.warn("Error with not managed service rate {}", serviceRate.toString());
231             return new TopologyShard(null, null, null);
232         }
233         Long bwIncr = serviceRateBwIncrMap.get(serviceRate);
234         for (Link link : suppOduLinks) {
235             if (link.augmentation(Link1.class) == null
236                     || link.augmentation(Link1.class).getAvailableBandwidth() == null
237                     || link.augmentation(Link1.class).getUsedBandwidth() == null) {
238                 LOG.error(OTN_PARAMS_ERROR, link.getLinkId().getValue());
239             } else {
240                 Uint32 avlBw = link.augmentation(Link1.class).getAvailableBandwidth();
241                 Uint32 usedBw = link.augmentation(Link1.class).getUsedBandwidth();
242                 if (avlBw.toJava() < bwIncr) {
243                     bwIncr = 0L;
244                 }
245                 links.add(
246                     isDeletion
247                         ? updateOtnLinkBwParameters(link, avlBw.toJava() + bwIncr, usedBw.toJava() - bwIncr)
248                         : updateOtnLinkBwParameters(link, avlBw.toJava() - bwIncr, usedBw.toJava() + bwIncr)
249                 );
250             }
251         }
252         List<TerminationPoint> tps = new ArrayList<>();
253         for (TerminationPoint tp : oldTps) {
254             if (bwIncr != 0) {
255             //TODO shouldn't it be 0L rather?
256                 tps.add(updateNodeTpTsPool(tp, serviceRate, tribPortNb, minTribSlotNb, maxTribSlotNb, isDeletion));
257             }
258         }
259         if (links.isEmpty() || tps.isEmpty()) {
260             LOG.error("unable to update otn links");
261             return new TopologyShard(null, null, null);
262         } else {
263             return new TopologyShard(null, links, tps);
264         }
265     }
266
267     public static TopologyShard updateOtnLinks(List<Link> suppOtuLinks, boolean isDeletion) {
268
269         List<Link> links = new ArrayList<>();
270         for (Link link : suppOtuLinks) {
271             if (link.augmentation(Link1.class) == null
272                 || link.augmentation(Link1.class).getAvailableBandwidth() == null
273                 || link.augmentation(Link1.class).getUsedBandwidth() == null) {
274                 LOG.error(OTN_PARAMS_ERROR, link.getLinkId().getValue());
275             } else {
276                 links.add(
277                     isDeletion
278                         ? updateOtnLinkBwParameters(link, Long.valueOf(100000), Long.valueOf(0))
279                         : updateOtnLinkBwParameters(link, Long.valueOf(0), Long.valueOf(100000))
280                 );
281             }
282         }
283         if (links.isEmpty()) {
284             LOG.error("unable to update otn links");
285             return new TopologyShard(null, null, null);
286         } else {
287             return new TopologyShard(null, links, null);
288         }
289     }
290
291     public static TopologyShard deleteOtnLinks(List<Link> suppOtuLinks, List<TerminationPoint> oldTps,
292             OtnLinkType linkType) {
293
294         List<Link> links = new ArrayList<>();
295         for (Link link : suppOtuLinks) {
296             if (link.augmentation(Link1.class) == null
297                     || link.augmentation(
298                         org.opendaylight.yang.gen.v1.http.transportpce.topology.rev220123.Link1.class) == null) {
299                 LOG.error(OTN_PARAMS_ERROR, link.getLinkId().getValue());
300                 return new TopologyShard(null, null, null);
301             }
302             OtnLinkType otnLinkType = link.augmentation(
303                     org.opendaylight.yang.gen.v1.http.transportpce.topology.rev220123.Link1.class).getOtnLinkType();
304             if (!otnOtuLinkTypeBwMap.containsKey(otnLinkType)) {
305             //TODO shouldn't other link type listed in otnLinkTypeBwMap be handled too ?
306                 LOG.warn("Unexpected otn-link-type {} for link {}", otnLinkType, link.getLinkId());
307                 continue;
308             }
309             links.add(updateOtnLinkBwParameters(link, otnOtuLinkTypeBwMap.get(otnLinkType) , 0L));
310         }
311         List<TerminationPoint> tps = new ArrayList<>();
312         for (TerminationPoint tp : oldTps) {
313             tps.add(updateTp(tp, false, linkType));
314         }
315         return
316             links.isEmpty() || tps.isEmpty()
317                 ? new TopologyShard(null, null, null)
318                 : new TopologyShard(null, links, tps);
319     }
320
321     private static List<Link> initialiseOtnLinks(String nodeA, String tpA, String nodeZ, String tpZ,
322             OtnLinkType linkType) {
323
324         List<Link> links = new ArrayList<>();
325         String nodeATopo = formatNodeName(nodeA, tpA);
326         String nodeZTopo = formatNodeName(nodeZ, tpZ);
327         org.opendaylight.yang.gen.v1.http.transportpce.topology.rev220123.Link1 tpceLink1
328             = new org.opendaylight.yang.gen.v1.http.transportpce.topology.rev220123.Link1Builder()
329                 .setOtnLinkType(linkType).build();
330         Link1Builder otnLink1Bldr = new Link1Builder()
331             .setUsedBandwidth(Uint32.valueOf(0));
332         if (otnOtuLinkTypeBwMap.containsKey(linkType)) {
333             otnLink1Bldr.setAvailableBandwidth(Uint32.valueOf(otnOtuLinkTypeBwMap.get(linkType)));
334         } else if (otnLinkTypeBwMap.containsKey(linkType)) {
335             otnLink1Bldr.setAvailableBandwidth(Uint32.valueOf(otnLinkTypeBwMap.get(linkType)));
336         } else {
337             LOG.error("unable to set available bandwidth to unknown link type");
338         }
339         // create link A-Z
340         LinkBuilder ietfLinkAZBldr = TopologyUtils.createLink(nodeATopo, nodeZTopo, tpA, tpZ, linkType.getName());
341         ietfLinkAZBldr
342             .addAugmentation(tpceLink1)
343             .addAugmentation(otnLink1Bldr.build())
344             .addAugmentation(
345                 new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1Builder(
346                         ietfLinkAZBldr.augmentation(
347                             org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class))
348                     .setLinkType(OpenroadmLinkType.OTNLINK)
349                     .setOperationalState(State.InService)
350                     .setAdministrativeState(AdminStates.InService)
351                     .build());
352         links.add(ietfLinkAZBldr.build());
353         // create link Z-A
354         LinkBuilder ietfLinkZABldr = TopologyUtils.createLink(nodeZTopo, nodeATopo, tpZ, tpA, linkType.getName());
355         ietfLinkZABldr
356             .addAugmentation(tpceLink1)
357             .addAugmentation(otnLink1Bldr.build())
358             .addAugmentation(
359                 new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1Builder(
360                         ietfLinkZABldr.augmentation(
361                             org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class))
362                     .setLinkType(OpenroadmLinkType.OTNLINK)
363                     .setOperationalState(State.InService)
364                     .setAdministrativeState(AdminStates.InService)
365                     .build());
366         links.add(ietfLinkZABldr.build());
367         return links;
368     }
369
370     private static Link updateOtnLinkBwParameters(Link link, Long availBw, Long usedBw) {
371
372         LOG.debug("in updateOtnLinkBwParameters with availBw = {}, usedBw = {}", availBw, usedBw);
373         return new LinkBuilder(link)
374             .addAugmentation(
375                 new Link1Builder(link.augmentation(Link1.class))
376                     .setAvailableBandwidth(Uint32.valueOf(availBw))
377                     .setUsedBandwidth(Uint32.valueOf(usedBw))
378                     .build())
379             .build();
380     }
381
382     private static List<Link> updateOtnLinkBwParameters(List<Link> supportedLinks, OtnLinkType linkType) {
383
384         LOG.debug("in updateOtnLinkBwParameters with supportedLinks = {}, linkType = {}", supportedLinks, linkType);
385         List<Link> updatedlinks = new ArrayList<>();
386         for (Link link : supportedLinks) {
387             LinkBuilder updatedLinkBldr = new LinkBuilder(link);
388             updatedLinkBldr.addAugmentation(new Link1Builder(link.augmentation(Link1.class))
389                 .setAvailableBandwidth(Uint32.valueOf(0))
390                 .setUsedBandwidth(
391                     otnLinkTypeBwMap.containsKey(linkType)
392                         ? Uint32.valueOf(otnLinkTypeBwMap.get(linkType))
393                         : Uint32.valueOf(0))
394                 .build());
395             updatedlinks.add(updatedLinkBldr.build());
396         }
397         return updatedlinks;
398     }
399
400     private static TerminationPoint updateTp(TerminationPoint originalTp, boolean addingTsTpnPoolTermination,
401             OtnLinkType linkType) {
402
403         LOG.debug("in updateTp");
404         TerminationPointBuilder tpBldr = new TerminationPointBuilder(originalTp);
405         TerminationPoint1Builder otnTp1Bldr =
406             new TerminationPoint1Builder(tpBldr.augmentation(TerminationPoint1.class));
407         XpdrTpPortConnectionAttributesBuilder xtpcaBldr =
408             new XpdrTpPortConnectionAttributesBuilder(otnTp1Bldr.getXpdrTpPortConnectionAttributes());
409         if (addingTsTpnPoolTermination) {
410             List<Uint16> tsPool = new ArrayList<>();
411             for (int i = 1; i <= NB_TRIB_SLOTS; i++) {
412                 tsPool.add(Uint16.valueOf(i));
413             }
414             xtpcaBldr.setTsPool(tsPool);
415             List<Uint16> tpnPool = new ArrayList<>();
416             int nbTribPort = NB_TRIB_PORTS;
417             if (OtnLinkType.ODUC4.equals(linkType)) {
418                 nbTribPort = 4;
419             }
420             for (int i = 1; i <= nbTribPort; i++) {
421                 tpnPool.add(Uint16.valueOf(i));
422             }
423             OdtuTpnPool oduTpnPool = new OdtuTpnPoolBuilder()
424                 .setOdtuType(ODTU4TsAllocated.class)
425                 .setTpnPool(tpnPool)
426                 .build();
427             xtpcaBldr.setOdtuTpnPool(ImmutableMap.of(oduTpnPool.key(),oduTpnPool));
428         } else {
429             xtpcaBldr.setTsPool(null);
430             xtpcaBldr.setOdtuTpnPool(ImmutableMap.of());
431         }
432         return tpBldr.addAugmentation(otnTp1Bldr.setXpdrTpPortConnectionAttributes(xtpcaBldr.build()).build()).build();
433     }
434
435     private static TerminationPoint updateNodeTpTsPool(TerminationPoint tp, Uint32 serviceRate, Short tribPortNb,
436             Short minTribSlotNb, Short maxTribSlotNb, boolean isDeletion) {
437
438         LOG.debug("in updateNodeTpTsPool");
439         TerminationPointBuilder tpBldr = new TerminationPointBuilder(tp);
440         @Nullable
441         XpdrTpPortConnectionAttributesBuilder xtpcaBldr =
442             new XpdrTpPortConnectionAttributesBuilder(
443                 tpBldr.augmentation(TerminationPoint1.class).getXpdrTpPortConnectionAttributes());
444         List<Uint16> tsPool = new ArrayList<>(xtpcaBldr.getTsPool());
445         if (isDeletion) {
446             for (int i = minTribSlotNb; i <= maxTribSlotNb; i++) {
447                 tsPool.add(Uint16.valueOf(i));
448             }
449         } else {
450             for (int i = minTribSlotNb; i <= maxTribSlotNb; i++) {
451                 tsPool.remove(Uint16.valueOf(i));
452             }
453         }
454         xtpcaBldr.setTsPool(tsPool);
455         List<Uint16> tpnPool;
456         List<OdtuTpnPool> odtuTpnPoolValues = new ArrayList<>(xtpcaBldr.getOdtuTpnPool().values());
457         if (odtuTpnPoolValues.get(0).getTpnPool() == null) {
458             tpnPool = new ArrayList<>();
459         } else {
460             tpnPool = new ArrayList<>(odtuTpnPoolValues.get(0).getTpnPool());
461             if (isDeletion) {
462                 tpnPool.add(Uint16.valueOf(tribPortNb));
463             } else {
464                 tpnPool.remove(Uint16.valueOf(tribPortNb));
465             }
466         }
467         Class<? extends OdtuTypeIdentity> odtuType = null;
468         switch (serviceRate.intValue()) {
469             case 1:
470             case 10:
471                 odtuType = ODTU4TsAllocated.class;
472                 break;
473             case 100:
474                 odtuType = ODTUCnTs.class;
475                 break;
476             default:
477                 LOG.warn("Unable to set the odtu-type");
478                 break;
479         }
480         OdtuTpnPool odtuTpnPool = new OdtuTpnPoolBuilder()
481             .setOdtuType(odtuType)
482             .setTpnPool(tpnPool)
483             .build();
484         xtpcaBldr.setOdtuTpnPool(ImmutableMap.of(odtuTpnPool.key(),odtuTpnPool));
485         tpBldr.addAugmentation(
486             new TerminationPoint1Builder(
487                 tp.augmentation(TerminationPoint1.class))
488                     .setXpdrTpPortConnectionAttributes(xtpcaBldr.build())
489                     .build());
490         return tpBldr.build();
491     }
492
493     private static Map<Integer, OtnTopoNode> convertPortMappingToOtnNodeList(Nodes mappingNode) {
494
495         List<Mapping> networkMappings =
496             mappingNode.nonnullMapping().values().stream()
497                 .filter(k -> k.getLogicalConnectionPoint().contains("NETWORK"))
498                 .collect(Collectors.toList());
499         Map<Integer, OtnTopoNode> xpdrMap = new HashMap<>();
500         for (Mapping mapping : networkMappings) {
501             Integer xpdrNb = Integer.parseInt(mapping.getLogicalConnectionPoint().split("XPDR")[1].split("-")[0]);
502             if (!xpdrMap.containsKey(xpdrNb)) {
503                 List<Mapping> xpdrNetMaps =
504                     mappingNode.nonnullMapping().values().stream()
505                         .filter(k -> k.getLogicalConnectionPoint().contains("XPDR" + xpdrNb + NETWORK))
506                         .collect(Collectors.toList());
507                 List<Mapping> xpdrClMaps =
508                     mappingNode.nonnullMapping().values().stream()
509                         .filter(k -> k.getLogicalConnectionPoint().contains("XPDR" + xpdrNb + CLIENT))
510                         .collect(Collectors.toList());
511                 xpdrMap.put(
512                     xpdrNb,
513                     new OtnTopoNode(
514                         mappingNode.getNodeId(),
515                         mappingNode.getNodeInfo().getNodeClli(),
516                         xpdrNb,
517                         mapping.getXponderType() == null
518                             ? XpdrNodeTypes.Tpdr
519                             : mapping.getXponderType(),
520                         fillConnectionMapLcp(xpdrNetMaps),
521                         fillConnectionMapLcp(xpdrClMaps),
522                         xpdrNetMaps,
523                         xpdrClMaps
524                     ));
525             }
526         }
527         LOG.debug("there are {} xpdr to build", xpdrMap.size());
528         xpdrMap.forEach((k, v) -> LOG.debug("xpdr {} = {} - {} - {} - {}",
529             k, v.getNodeId(), v.getNodeType(), v.getNbTpClient(), v.getNbTpNetwork()));
530         return xpdrMap;
531     }
532
533     private static Map<String, String> fillConnectionMapLcp(List<Mapping> mappingList) {
534
535         Map<String, String> xpdrConnectionMap = new HashMap<>();
536         for (Mapping map : mappingList) {
537             xpdrConnectionMap.put(map.getLogicalConnectionPoint(), map.getConnectionMapLcp());
538         }
539         return xpdrConnectionMap;
540     }
541
542     private static Node createTpdr(OtnTopoNode node) {
543
544         // prepare ietf node augmentation to add TP list
545         Map<TerminationPointKey,TerminationPoint> tpMap = new HashMap<>();
546         createTP(tpMap, node, OpenroadmTpType.XPONDERCLIENT, false);
547         createTP(tpMap, node, OpenroadmTpType.XPONDERNETWORK, true);
548         // return ietfNode
549         return new NodeBuilder()
550             .setNodeId(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb()))
551             .withKey(new NodeKey(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb())))
552             .setSupportingNode(createSupportingNodes(node))
553             .addAugmentation(
554                 new Node1Builder()
555                     .setXpdrAttributes(
556                         new XpdrAttributesBuilder()
557                             .setXpdrNumber(Uint16.valueOf(node.getXpdrNb()))
558                             .build())
559                     .build())
560             .addAugmentation(
561                 new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Node1Builder()
562                     .setNodeType(OpenroadmNodeType.TPDR)
563                     .setOperationalState(State.InService)
564                     .setAdministrativeState(AdminStates.InService)
565                     .build())
566             .addAugmentation(
567                 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
568                     .Node1Builder()
569                         .setTerminationPoint(tpMap)
570                         .build())
571             .build();
572     }
573
574     private static Node createMuxpdr(OtnTopoNode node) {
575
576         // prepare otn-topology node augmentation
577         // TODO: will need to be completed
578         Map<NonBlockingListKey, NonBlockingList> nbMap = new HashMap<>();
579         for (int i = 1; i <= node.getNbTpClient(); i++) {
580             List<TpId> tpList = new ArrayList<>();
581             tpList.add(new TpId("XPDR" + node.getXpdrNb() + CLIENT + i));
582             tpList.add(new TpId("XPDR" + node.getXpdrNb() + "-NETWORK1"));
583             NonBlockingList nbl = new NonBlockingListBuilder()
584                 .setNblNumber(Uint16.valueOf(i))
585                 .setTpList(tpList)
586                 .setAvailableInterconnectBandwidth(Uint32.valueOf(node.getNbTpNetwork() * 10L))
587                 .setInterconnectBandwidthUnit(Uint32.valueOf(1000000000))
588                 .build();
589             nbMap.put(nbl.key(),nbl);
590         }
591         OduSwitchingPools oduSwitchPool = new OduSwitchingPoolsBuilder()
592             .setSwitchingPoolNumber(Uint16.valueOf(1))
593             .setSwitchingPoolType(SwitchingPoolTypes.NonBlocking)
594             .setNonBlockingList(nbMap)
595             .build();
596         // prepare ietf node augmentation to add TP list
597         Map<TerminationPointKey, TerminationPoint> tpMap = new HashMap<>();
598         createTP(tpMap, node, OpenroadmTpType.XPONDERCLIENT, true);
599         createTP(tpMap, node, OpenroadmTpType.XPONDERNETWORK, true);
600         // return ietfNode
601         return new NodeBuilder()
602             .setNodeId(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb()))
603             .withKey(new NodeKey(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb())))
604             .setSupportingNode(createSupportingNodes(node))
605             .addAugmentation(
606                 new Node1Builder()
607                     .setTpBandwidthSharing(new TpBandwidthSharingBuilder().build())
608                     .setXpdrAttributes(
609                         new XpdrAttributesBuilder()
610                             .setXpdrNumber(Uint16.valueOf(node.getXpdrNb()))
611                             .build())
612                     .setSwitchingPools(
613                         new SwitchingPoolsBuilder()
614                             .setOduSwitchingPools(Map.of(oduSwitchPool.key(),oduSwitchPool))
615                             .build())
616                     .build())
617             .addAugmentation(
618                 new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Node1Builder()
619                     .setNodeType(OpenroadmNodeType.MUXPDR)
620                     .setAdministrativeState(AdminStates.InService)
621                     .setOperationalState(State.InService)
622                     .build())
623             .addAugmentation(
624                 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
625                     .Node1Builder()
626                         .setTerminationPoint(tpMap)
627                         .build())
628             .build();
629     }
630
631     private static Node createSwitch(OtnTopoNode node) {
632
633         List<TpId> tpl = new ArrayList<>();
634         for (int i = 1; i <= node.getNbTpClient(); i++) {
635             tpl.add(new TpId("XPDR" + node.getXpdrNb() + CLIENT + i));
636         }
637         for (int i = 1; i <= node.getNbTpNetwork(); i++) {
638             tpl.add(new TpId("XPDR" + node.getXpdrNb() + NETWORK + i));
639         }
640         Map<NonBlockingListKey, NonBlockingList> nbMap = new HashMap<>();
641         NonBlockingList nbl = new NonBlockingListBuilder()
642             .setNblNumber(Uint16.valueOf(1))
643             .setTpList(tpl)
644             .build();
645         nbMap.put(nbl.key(),nbl);
646         OduSwitchingPools oduSwitchPool = new OduSwitchingPoolsBuilder()
647             .setSwitchingPoolNumber(Uint16.valueOf(1))
648             .setSwitchingPoolType(SwitchingPoolTypes.NonBlocking)
649             .setNonBlockingList(nbMap)
650             .build();
651         Map<OduSwitchingPoolsKey, OduSwitchingPools> oduSwitchPoolList = new HashMap<>();
652         oduSwitchPoolList.put(oduSwitchPool.key(),oduSwitchPool);
653         // prepare ietf node augmentation to add TP list
654         Map<TerminationPointKey, TerminationPoint> tpMap = new HashMap<>();
655         createTP(tpMap, node, OpenroadmTpType.XPONDERCLIENT, true);
656         createTP(tpMap, node, OpenroadmTpType.XPONDERNETWORK, true);
657         // return ietfNode
658         return new NodeBuilder()
659             .setNodeId(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb()))
660             .withKey(new NodeKey(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb())))
661             .setSupportingNode(createSupportingNodes(node))
662             .addAugmentation(
663                 new Node1Builder()
664                     .setTpBandwidthSharing(new TpBandwidthSharingBuilder().build())
665                     .setXpdrAttributes(
666                         new XpdrAttributesBuilder()
667                             .setXpdrNumber(Uint16.valueOf(node.getXpdrNb()))
668                             .build())
669                     .setSwitchingPools(
670                         new SwitchingPoolsBuilder()
671                             .setOduSwitchingPools(oduSwitchPoolList)
672                             .build())
673                     .build())
674             .addAugmentation(
675                 new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Node1Builder()
676                     .setNodeType(OpenroadmNodeType.SWITCH)
677                     .setOperationalState(State.InService)
678                     .setAdministrativeState(AdminStates.InService)
679                     .build())
680             .addAugmentation(
681                 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
682                     .Node1Builder()
683                         .setTerminationPoint(tpMap)
684                         .build())
685             .build();
686     }
687
688     private static void createTP(Map<TerminationPointKey, TerminationPoint> tpMap,
689             OtnTopoNode node, OpenroadmTpType tpType, boolean withRate) {
690
691         List<Mapping> mappings = null;
692         switch (tpType) {
693             case XPONDERNETWORK:
694                 mappings = node.getXpdrNetMappings();
695                 break;
696             case XPONDERCLIENT:
697                 mappings = node.getXpdrClMappings();
698                 break;
699             default:
700                 LOG.error("Error with Termination Point type {}", tpType);
701                 return;
702         }
703         fillTpMap(tpMap, node, tpType, withRate, mappings);
704     }
705
706     private static void fillTpMap(Map<TerminationPointKey, TerminationPoint> tpMap, OtnTopoNode node,
707             OpenroadmTpType tpType, boolean withRate, List<Mapping> mappings) {
708
709         for (Mapping mapping : mappings) {
710             // openroadm-otn-topoology augmentation
711             Map<SupportedInterfaceCapabilityKey, SupportedInterfaceCapability> supIfMap = new HashMap<>();
712             TerminationPoint1Builder otnTp1Bldr = new TerminationPoint1Builder();
713             if (mapping.getSupportedInterfaceCapability() == null) {
714                 LOG.warn("mapping {} of node {} has no if-cap-type",
715                     mapping.getLogicalConnectionPoint(), node.getNodeId());
716             } else {
717                 XpdrTpPortConnectionAttributesBuilder xtpcaBldr = new XpdrTpPortConnectionAttributesBuilder();
718                 for (Class<? extends SupportedIfCapability> supInterCapa : mapping.getSupportedInterfaceCapability()) {
719                     SupportedInterfaceCapability supIfCapa = new SupportedInterfaceCapabilityBuilder()
720                         .withKey(new SupportedInterfaceCapabilityKey(supInterCapa))
721                         .setIfCapType(supInterCapa)
722                         .build();
723                     supIfMap.put(supIfCapa.key(), supIfCapa);
724                 }
725                 otnTp1Bldr.setTpSupportedInterfaces(
726                     new TpSupportedInterfacesBuilder()
727                         .setSupportedInterfaceCapability(supIfMap)
728                         .build()
729                 );
730                 //TODO: It is not logical to assign a priori one of the possible rate to the TP.
731                 //Would be worth assigning per default "unallocated" at the tp creation step,
732                 //and updating it with correct rate when it supports a specific service.
733                 if (withRate) {
734                     otnTp1Bldr.setXpdrTpPortConnectionAttributes(
735                         xtpcaBldr.setRate(fixRate(mapping.getSupportedInterfaceCapability())).build());
736                 }
737             }
738             setclientNwTpAttr(
739                 tpMap,
740                 node,
741                 new TpId(mapping.getLogicalConnectionPoint()),
742                 tpType,
743                 otnTp1Bldr.build(),
744                 new org.opendaylight.yang.gen.v1.http.transportpce.topology.rev220123.TerminationPoint1Builder(),
745                 mapping);
746         }
747     }
748
749     private static void setclientNwTpAttr(Map<TerminationPointKey, TerminationPoint> tpMap, OtnTopoNode node, TpId tpId,
750             OpenroadmTpType tpType, TerminationPoint1 otnTp1,
751             org.opendaylight.yang.gen.v1.http.transportpce.topology.rev220123.TerminationPoint1Builder tpceTp1Bldr,
752             Mapping mapping) {
753
754         switch (tpType) {
755             case XPONDERNETWORK:
756                 if (node.getXpdrNetConnectionMap().get(tpId.getValue()) != null) {
757                     tpceTp1Bldr.setAssociatedConnectionMapPort(node.getXpdrNetConnectionMap().get(tpId.getValue()));
758                 }
759                 SupportingTerminationPoint stp = new SupportingTerminationPointBuilder()
760                     .setNetworkRef(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID))
761                     .setNodeRef(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb()))
762                     .setTpRef(tpId)
763                     .build();
764                 TerminationPoint ietfTpNw =
765                     buildIetfTp(tpceTp1Bldr, otnTp1, tpType, tpId, Map.of(stp.key(), stp), mapping);
766                 tpMap.put(ietfTpNw.key(),ietfTpNw);
767                 break;
768             case XPONDERCLIENT:
769                 if (node.getXpdrCliConnectionMap().get(tpId.getValue()) != null) {
770                     tpceTp1Bldr.setAssociatedConnectionMapPort(node.getXpdrCliConnectionMap().get(tpId.getValue()));
771                 }
772                 TerminationPoint ietfTpCl = buildIetfTp(tpceTp1Bldr, otnTp1, tpType, tpId, null, mapping);
773                 tpMap.put(ietfTpCl.key(),ietfTpCl);
774                 break;
775             default:
776                 LOG.error("Undefined tpType for Termination point {} of {}", tpId.getValue(), node.getNodeId());
777                 break;
778         }
779     }
780
781     private static Class<? extends OduRateIdentity> fixRate(List<Class<? extends SupportedIfCapability>> list) {
782
783         for (Class<? extends SupportedIfCapability> class1 : list) {
784             if (rateMap.containsKey(class1.getSimpleName())) {
785                 return rateMap.get(class1.getSimpleName());
786             }
787         }
788         return null;
789     }
790
791     private static Map<SupportingNodeKey,SupportingNode> createSupportingNodes(OtnTopoNode node) {
792
793         SupportingNode suppNode1 = new SupportingNodeBuilder()
794             .setNetworkRef(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID))
795             .setNodeRef(new NodeId(node.getNodeId()))
796             .withKey(
797                 new SupportingNodeKey(
798                     new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID),
799                     new NodeId(node.getNodeId())))
800             .build();
801         SupportingNode suppNode2 = new SupportingNodeBuilder()
802             .setNetworkRef(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID))
803             .setNodeRef(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb()))
804             .withKey(
805                 new SupportingNodeKey(
806                     new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID),
807                     new NodeId(node.getNodeId() + XPDR + node.getXpdrNb())))
808             .build();
809         SupportingNode suppNode3 = new SupportingNodeBuilder()
810             .setNetworkRef(new NetworkId(NetworkUtils.CLLI_NETWORK_ID))
811             .setNodeRef(new NodeId(node.getClli()))
812             .withKey(
813                 new SupportingNodeKey(
814                     new NetworkId(NetworkUtils.CLLI_NETWORK_ID),
815                     new NodeId(node.getClli())))
816             .build();
817         Map<SupportingNodeKey,SupportingNode> suppNodeMap = new HashMap<>();
818         suppNodeMap.put(suppNode1.key(),suppNode1);
819         suppNodeMap.put(suppNode2.key(),suppNode2);
820         suppNodeMap.put(suppNode3.key(),suppNode3);
821         return suppNodeMap;
822     }
823
824     private static TerminationPoint buildIetfTp(
825             org.opendaylight.yang.gen.v1.http.transportpce.topology.rev220123.TerminationPoint1Builder tpceTp1Bldr,
826             TerminationPoint1 otnTp1, OpenroadmTpType tpType, TpId tpId,
827             Map<SupportingTerminationPointKey, SupportingTerminationPoint> supportTpMap, Mapping mapping) {
828
829         TerminationPointBuilder ietfTpBldr = new TerminationPointBuilder();
830         if (tpceTp1Bldr.getAssociatedConnectionMapPort() != null) {
831             ietfTpBldr.addAugmentation(tpceTp1Bldr.build());
832         }
833         if (supportTpMap != null) {
834             ietfTpBldr.setSupportingTerminationPoint(supportTpMap);
835         }
836         return ietfTpBldr
837             .setTpId(tpId)
838             .withKey(new TerminationPointKey(tpId))
839             .addAugmentation(otnTp1)
840             .addAugmentation(
841                 new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.TerminationPoint1Builder()
842                     .setTpType(tpType)
843                     .setAdministrativeState(TopologyUtils.setNetworkAdminState(mapping.getPortAdminState()))
844                     .setOperationalState(TopologyUtils.setNetworkOperState(mapping.getPortOperState()))
845                     .build())
846             .build();
847     }
848
849     private static String formatNodeName(String nodeName, String tpName) {
850
851         return nodeName.contains(XPDR)
852                 ? nodeName
853                 : new StringBuilder(nodeName).append("-").append(tpName.split("-")[0]).toString();
854     }
855 }