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