Adapt TransportPCE code to Sulfur
[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.portmapping.rev220316.mapping.Mapping;
24 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220316.network.Nodes;
25 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
26 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.types.rev191129.XpdrNodeTypes;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev201211.xpdr.odu.switching.pools.OduSwitchingPools;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev201211.xpdr.odu.switching.pools.OduSwitchingPoolsBuilder;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev201211.xpdr.odu.switching.pools.OduSwitchingPoolsKey;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev201211.xpdr.odu.switching.pools.odu.switching.pools.NonBlockingList;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev201211.xpdr.odu.switching.pools.odu.switching.pools.NonBlockingListBuilder;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev201211.xpdr.odu.switching.pools.odu.switching.pools.NonBlockingListKey;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.OpenroadmLinkType;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.OpenroadmNodeType;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.OpenroadmTpType;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.xpdr.tp.supported.interfaces.SupportedInterfaceCapability;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.xpdr.tp.supported.interfaces.SupportedInterfaceCapabilityBuilder;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.xpdr.tp.supported.interfaces.SupportedInterfaceCapabilityKey;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev210924.ODTU4TsAllocated;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev210924.ODTUCnTs;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev210924.ODU0;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev210924.ODU2;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev210924.ODU2e;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev210924.ODU4;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev210924.OdtuTypeIdentity;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev210924.OduRateIdentity;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev211210.Link1;
49 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev211210.Link1Builder;
50 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev211210.Node1Builder;
51 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev211210.TerminationPoint1;
52 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev211210.TerminationPoint1Builder;
53 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev211210.networks.network.node.SwitchingPoolsBuilder;
54 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev211210.networks.network.node.TpBandwidthSharingBuilder;
55 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev211210.networks.network.node.XpdrAttributesBuilder;
56 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev211210.networks.network.node.termination.point.TpSupportedInterfacesBuilder;
57 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev211210.networks.network.node.termination.point.XpdrTpPortConnectionAttributesBuilder;
58 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev201211.SupportedIfCapability;
59 import org.opendaylight.yang.gen.v1.http.org.openroadm.switching.pool.types.rev191129.SwitchingPoolTypes;
60 import org.opendaylight.yang.gen.v1.http.org.openroadm.xponder.rev211210.xpdr.otn.tp.attributes.OdtuTpnPool;
61 import org.opendaylight.yang.gen.v1.http.org.openroadm.xponder.rev211210.xpdr.otn.tp.attributes.OdtuTpnPoolBuilder;
62 import org.opendaylight.yang.gen.v1.http.transportpce.topology.rev220123.OtnLinkType;
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, Class<? extends OduRateIdentity>> RATE_MAP = Map.of(
96         "If100GEODU4", ODU4.class,
97         "IfOCHOTU4ODU4", ODU4.class,
98         "If1GEODU0", ODU0.class,
99         "If10GEODU2", ODU2.class,
100         "If10GEODU2e", ODU2e.class);
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, Class<? extends OdtuTypeIdentity>> SERVICERATE_ODTUTYPECLASS_MAP = Map.of(
114         Uint32.valueOf(1), ODTU4TsAllocated.class,
115         Uint32.valueOf(10), ODTU4TsAllocated.class,
116         Uint32.valueOf(100), ODTUCnTs.class);
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.transportpce.topology.rev220123.Link1.class) == null) {
302                 LOG.error(OTN_PARAMS_ERROR, link.getLinkId().getValue());
303                 return new TopologyShard(null, null, null);
304             }
305             OtnLinkType otnLinkType = link.augmentation(
306                     org.opendaylight.yang.gen.v1.http.transportpce.topology.rev220123.Link1.class).getOtnLinkType();
307             if (!OTNLINKTYPE_OTU_BW_MAP.containsKey(otnLinkType)) {
308             //TODO shouldn't other link type listed in OTNLINKTYPE_BW_MAP be handled too ?
309                 LOG.warn("Unexpected otn-link-type {} for link {}", otnLinkType, link.getLinkId());
310                 continue;
311             }
312             links.add(updateOtnLinkBwParameters(link, OTNLINKTYPE_OTU_BW_MAP.get(otnLinkType) , 0L));
313         }
314         List<TerminationPoint> tps = new ArrayList<>();
315         for (TerminationPoint tp : oldTps) {
316             tps.add(updateTp(tp, false, linkType));
317         }
318         return
319             links.isEmpty() || tps.isEmpty()
320                 ? new TopologyShard(null, null, null)
321                 : new TopologyShard(null, links, tps);
322     }
323
324     private static List<Link> initialiseOtnLinks(String nodeA, String tpA, String nodeZ, String tpZ,
325             OtnLinkType linkType) {
326
327         List<Link> links = new ArrayList<>();
328         String nodeATopo = formatNodeName(nodeA, tpA);
329         String nodeZTopo = formatNodeName(nodeZ, tpZ);
330         org.opendaylight.yang.gen.v1.http.transportpce.topology.rev220123.Link1 tpceLink1
331             = new org.opendaylight.yang.gen.v1.http.transportpce.topology.rev220123.Link1Builder()
332                 .setOtnLinkType(linkType).build();
333         Link1Builder otnLink1Bldr = new Link1Builder()
334             .setUsedBandwidth(Uint32.valueOf(0));
335         if (OTNLINKTYPE_OTU_BW_MAP.containsKey(linkType)) {
336             otnLink1Bldr.setAvailableBandwidth(Uint32.valueOf(OTNLINKTYPE_OTU_BW_MAP.get(linkType)));
337         } else if (OTNLINKTYPE_BW_MAP.containsKey(linkType)) {
338             otnLink1Bldr.setAvailableBandwidth(Uint32.valueOf(OTNLINKTYPE_BW_MAP.get(linkType)));
339         } else {
340             LOG.error("unable to set available bandwidth to unknown link type");
341         }
342         // create link A-Z
343         LinkBuilder ietfLinkAZBldr = TopologyUtils.createLink(nodeATopo, nodeZTopo, tpA, tpZ, linkType.getName());
344         links.add(ietfLinkAZBldr
345             .addAugmentation(tpceLink1)
346             .addAugmentation(otnLink1Bldr.build())
347             .addAugmentation(
348                 new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Link1Builder(
349                         ietfLinkAZBldr.augmentation(
350                             org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Link1.class))
351                     .setLinkType(OpenroadmLinkType.OTNLINK)
352                     .setOperationalState(State.InService)
353                     .setAdministrativeState(AdminStates.InService)
354                     .build())
355             .build());
356         // create link Z-A
357         LinkBuilder ietfLinkZABldr = TopologyUtils.createLink(nodeZTopo, nodeATopo, tpZ, tpA, linkType.getName());
358         links.add(ietfLinkZABldr
359             .addAugmentation(tpceLink1)
360             .addAugmentation(otnLink1Bldr.build())
361             .addAugmentation(
362                 new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Link1Builder(
363                         ietfLinkZABldr.augmentation(
364                             org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Link1.class))
365                     .setLinkType(OpenroadmLinkType.OTNLINK)
366                     .setOperationalState(State.InService)
367                     .setAdministrativeState(AdminStates.InService)
368                     .build())
369             .build());
370         return links;
371     }
372
373     private static Link updateOtnLinkBwParameters(Link link, Long availBw, Long usedBw) {
374
375         LOG.debug("in updateOtnLinkBwParameters with availBw = {}, usedBw = {}", availBw, usedBw);
376         return new LinkBuilder(link)
377             .addAugmentation(
378                 new Link1Builder(link.augmentation(Link1.class))
379                     .setAvailableBandwidth(Uint32.valueOf(availBw))
380                     .setUsedBandwidth(Uint32.valueOf(usedBw))
381                     .build())
382             .build();
383     }
384
385     private static List<Link> updateOtnLinkBwParameters(List<Link> supportedLinks, OtnLinkType linkType) {
386
387         LOG.debug("in updateOtnLinkBwParameters with supportedLinks = {}, linkType = {}", supportedLinks, linkType);
388         List<Link> updatedlinks = new ArrayList<>();
389         for (Link link : supportedLinks) {
390             updatedlinks.add(
391                 new LinkBuilder(link)
392                     .addAugmentation(new Link1Builder(link.augmentation(Link1.class))
393                         .setAvailableBandwidth(Uint32.valueOf(0))
394                         .setUsedBandwidth(
395                             OTNLINKTYPE_BW_MAP.containsKey(linkType)
396                                 ? Uint32.valueOf(OTNLINKTYPE_BW_MAP.get(linkType))
397                                 : Uint32.valueOf(0))
398                         .build())
399                     .build());
400         }
401         return updatedlinks;
402     }
403
404     private static TerminationPoint updateTp(TerminationPoint originalTp, boolean addingTsTpnPoolTermination,
405             OtnLinkType linkType) {
406
407         LOG.debug("in updateTp");
408         TerminationPointBuilder tpBldr = new TerminationPointBuilder(originalTp);
409         TerminationPoint1Builder otnTp1Bldr =
410             new TerminationPoint1Builder(tpBldr.augmentation(TerminationPoint1.class));
411         XpdrTpPortConnectionAttributesBuilder xtpcaBldr =
412             new XpdrTpPortConnectionAttributesBuilder(otnTp1Bldr.getXpdrTpPortConnectionAttributes());
413         if (addingTsTpnPoolTermination) {
414             Set<Uint16> tsPool = new HashSet<>();
415             for (int i = 1; i <= NB_TRIB_SLOTS; i++) {
416                 tsPool.add(Uint16.valueOf(i));
417             }
418             xtpcaBldr.setTsPool(tsPool);
419             Set<Uint16> tpnPool = new HashSet<>();
420             int nbTribPort = NB_TRIB_PORTS;
421             if (OtnLinkType.ODUC4.equals(linkType)) {
422                 nbTribPort = 4;
423             }
424             for (int i = 1; i <= nbTribPort; i++) {
425                 tpnPool.add(Uint16.valueOf(i));
426             }
427             OdtuTpnPool oduTpnPool = new OdtuTpnPoolBuilder()
428                 .setOdtuType(ODTU4TsAllocated.class)
429                 .setTpnPool(tpnPool)
430                 .build();
431             xtpcaBldr.setOdtuTpnPool(ImmutableMap.of(oduTpnPool.key(),oduTpnPool));
432         } else {
433             xtpcaBldr.setTsPool(null);
434             xtpcaBldr.setOdtuTpnPool(ImmutableMap.of());
435         }
436         return tpBldr.addAugmentation(otnTp1Bldr.setXpdrTpPortConnectionAttributes(xtpcaBldr.build()).build()).build();
437     }
438
439     private static TerminationPoint updateNodeTpTsPool(TerminationPoint tp, Uint32 serviceRate, Short tribPortNb,
440             Short minTribSlotNb, Short maxTribSlotNb, boolean isDeletion) {
441
442         LOG.debug("in updateNodeTpTsPool");
443         TerminationPointBuilder tpBldr = new TerminationPointBuilder(tp);
444         @Nullable
445         XpdrTpPortConnectionAttributesBuilder xtpcaBldr =
446             new XpdrTpPortConnectionAttributesBuilder(
447                 tpBldr.augmentation(TerminationPoint1.class).getXpdrTpPortConnectionAttributes());
448         Set<Uint16> tsPool = new HashSet<>(xtpcaBldr.getTsPool());
449         if (isDeletion) {
450             for (int i = minTribSlotNb; i <= maxTribSlotNb; i++) {
451                 tsPool.add(Uint16.valueOf(i));
452             }
453         } else {
454             for (int i = minTribSlotNb; i <= maxTribSlotNb; i++) {
455                 tsPool.remove(Uint16.valueOf(i));
456             }
457         }
458         xtpcaBldr.setTsPool(tsPool);
459         Set<Uint16> tpnPool;
460         List<OdtuTpnPool> odtuTpnPoolValues = new ArrayList<>(xtpcaBldr.getOdtuTpnPool().values());
461         if (odtuTpnPoolValues.get(0).getTpnPool() == null) {
462             tpnPool = new HashSet<>();
463         } else {
464             tpnPool = new HashSet<>(odtuTpnPoolValues.get(0).getTpnPool());
465             if (isDeletion) {
466                 tpnPool.add(Uint16.valueOf(tribPortNb));
467             } else {
468                 tpnPool.remove(Uint16.valueOf(tribPortNb));
469             }
470         }
471         Class<? extends OdtuTypeIdentity> odtuType;
472         if (SERVICERATE_ODTUTYPECLASS_MAP.containsKey(serviceRate)) {
473             odtuType = SERVICERATE_ODTUTYPECLASS_MAP.get(serviceRate);
474         } else {
475             odtuType = null;
476             LOG.warn("Unable to set the odtu-type");
477         }
478         OdtuTpnPool odtuTpnPool = new OdtuTpnPoolBuilder()
479             .setOdtuType(odtuType)
480             .setTpnPool(tpnPool)
481             .build();
482         return tpBldr
483             .addAugmentation(
484                 new TerminationPoint1Builder(tp.augmentation(TerminationPoint1.class))
485                     .setXpdrTpPortConnectionAttributes(
486                         xtpcaBldr
487                             .setOdtuTpnPool(ImmutableMap.of(odtuTpnPool.key(),odtuTpnPool))
488                             .build())
489                     .build())
490             .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         Map<TerminationPointKey,TerminationPoint> tpMap = new HashMap<>();
544         createTP(tpMap, node, OpenroadmTpType.XPONDERCLIENT, false);
545         createTP(tpMap, node, OpenroadmTpType.XPONDERNETWORK, true);
546         // return ietfNode
547         return new NodeBuilder()
548             .setNodeId(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb()))
549             .withKey(new NodeKey(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb())))
550             .setSupportingNode(createSupportingNodes(node))
551             .addAugmentation(
552                 new Node1Builder()
553                     .setXpdrAttributes(
554                         new XpdrAttributesBuilder()
555                             .setXpdrNumber(Uint16.valueOf(node.getXpdrNb()))
556                             .build())
557                     .build())
558             .addAugmentation(
559                 new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Node1Builder()
560                     .setNodeType(OpenroadmNodeType.TPDR)
561                     .setOperationalState(State.InService)
562                     .setAdministrativeState(AdminStates.InService)
563                     .build())
564             .addAugmentation(
565                 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
566                     .Node1Builder()
567                         .setTerminationPoint(tpMap)
568                         .build())
569             .build();
570     }
571
572     private static Node createMuxpdr(OtnTopoNode node) {
573
574         // prepare otn-topology node augmentation
575         // TODO: will need to be completed
576         Map<NonBlockingListKey, NonBlockingList> nbMap = new HashMap<>();
577         for (int i = 1; i <= node.getNbTpClient(); i++) {
578             Set<TpId> tpList = new HashSet<>();
579             tpList.add(new TpId("XPDR" + node.getXpdrNb() + CLIENT + i));
580             tpList.add(new TpId("XPDR" + node.getXpdrNb() + "-NETWORK1"));
581             NonBlockingList nbl = new NonBlockingListBuilder()
582                 .setNblNumber(Uint16.valueOf(i))
583                 .setTpList(tpList)
584                 .setAvailableInterconnectBandwidth(Uint32.valueOf(node.getNbTpNetwork() * 10L))
585                 .setInterconnectBandwidthUnit(Uint32.valueOf(1000000000))
586                 .build();
587             nbMap.put(nbl.key(),nbl);
588         }
589         OduSwitchingPools oduSwitchPool = new OduSwitchingPoolsBuilder()
590             .setSwitchingPoolNumber(Uint16.valueOf(1))
591             .setSwitchingPoolType(SwitchingPoolTypes.NonBlocking)
592             .setNonBlockingList(nbMap)
593             .build();
594         Map<TerminationPointKey, TerminationPoint> tpMap = new HashMap<>();
595         createTP(tpMap, node, OpenroadmTpType.XPONDERCLIENT, true);
596         createTP(tpMap, node, OpenroadmTpType.XPONDERNETWORK, true);
597         // return ietfNode
598         return new NodeBuilder()
599             .setNodeId(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb()))
600             .withKey(new NodeKey(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb())))
601             .setSupportingNode(createSupportingNodes(node))
602             .addAugmentation(
603                 new Node1Builder()
604                     .setTpBandwidthSharing(new TpBandwidthSharingBuilder().build())
605                     .setXpdrAttributes(
606                         new XpdrAttributesBuilder()
607                             .setXpdrNumber(Uint16.valueOf(node.getXpdrNb()))
608                             .build())
609                     .setSwitchingPools(
610                         new SwitchingPoolsBuilder()
611                             .setOduSwitchingPools(Map.of(oduSwitchPool.key(),oduSwitchPool))
612                             .build())
613                     .build())
614             .addAugmentation(
615                 new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Node1Builder()
616                     .setNodeType(OpenroadmNodeType.MUXPDR)
617                     .setAdministrativeState(AdminStates.InService)
618                     .setOperationalState(State.InService)
619                     .build())
620             .addAugmentation(
621                 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
622                     .Node1Builder()
623                         .setTerminationPoint(tpMap)
624                         .build())
625             .build();
626     }
627
628     private static Node createSwitch(OtnTopoNode node) {
629
630         Set<TpId> tpl = new HashSet<>();
631         for (int i = 1; i <= node.getNbTpClient(); i++) {
632             tpl.add(new TpId("XPDR" + node.getXpdrNb() + CLIENT + i));
633         }
634         for (int i = 1; i <= node.getNbTpNetwork(); i++) {
635             tpl.add(new TpId("XPDR" + node.getXpdrNb() + NETWORK + i));
636         }
637         Map<NonBlockingListKey, NonBlockingList> nbMap = new HashMap<>();
638         NonBlockingList nbl = new NonBlockingListBuilder()
639             .setNblNumber(Uint16.valueOf(1))
640             .setTpList(tpl)
641             .build();
642         nbMap.put(nbl.key(),nbl);
643         OduSwitchingPools oduSwitchPool = new OduSwitchingPoolsBuilder()
644             .setSwitchingPoolNumber(Uint16.valueOf(1))
645             .setSwitchingPoolType(SwitchingPoolTypes.NonBlocking)
646             .setNonBlockingList(nbMap)
647             .build();
648         Map<OduSwitchingPoolsKey, OduSwitchingPools> oduSwitchPoolList = new HashMap<>();
649         oduSwitchPoolList.put(oduSwitchPool.key(),oduSwitchPool);
650         Map<TerminationPointKey, TerminationPoint> tpMap = new HashMap<>();
651         createTP(tpMap, node, OpenroadmTpType.XPONDERCLIENT, true);
652         createTP(tpMap, node, OpenroadmTpType.XPONDERNETWORK, true);
653         // return ietfNode
654         return new NodeBuilder()
655             .setNodeId(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb()))
656             .withKey(new NodeKey(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb())))
657             .setSupportingNode(createSupportingNodes(node))
658             .addAugmentation(
659                 new Node1Builder()
660                     .setTpBandwidthSharing(new TpBandwidthSharingBuilder().build())
661                     .setXpdrAttributes(
662                         new XpdrAttributesBuilder()
663                             .setXpdrNumber(Uint16.valueOf(node.getXpdrNb()))
664                             .build())
665                     .setSwitchingPools(
666                         new SwitchingPoolsBuilder()
667                             .setOduSwitchingPools(oduSwitchPoolList)
668                             .build())
669                     .build())
670             .addAugmentation(
671                 new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Node1Builder()
672                     .setNodeType(OpenroadmNodeType.SWITCH)
673                     .setOperationalState(State.InService)
674                     .setAdministrativeState(AdminStates.InService)
675                     .build())
676             .addAugmentation(
677                 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
678                     .Node1Builder()
679                         .setTerminationPoint(tpMap)
680                         .build())
681             .build();
682     }
683
684     private static void createTP(Map<TerminationPointKey, TerminationPoint> tpMap,
685             OtnTopoNode node, OpenroadmTpType tpType, boolean withRate) {
686
687         List<Mapping> mappings = null;
688         switch (tpType) {
689             case XPONDERNETWORK:
690                 mappings = node.getXpdrNetMappings();
691                 break;
692             case XPONDERCLIENT:
693                 mappings = node.getXpdrClMappings();
694                 break;
695             default:
696                 LOG.error("Error with Termination Point type {}", tpType);
697                 return;
698         }
699         fillTpMap(tpMap, node, tpType, withRate, mappings);
700     }
701
702     private static void fillTpMap(Map<TerminationPointKey, TerminationPoint> tpMap, OtnTopoNode node,
703             OpenroadmTpType tpType, boolean withRate, List<Mapping> mappings) {
704
705         for (Mapping mapping : mappings) {
706             // openroadm-otn-topoology augmentation
707             Map<SupportedInterfaceCapabilityKey, SupportedInterfaceCapability> supIfMap = new HashMap<>();
708             TerminationPoint1Builder otnTp1Bldr = new TerminationPoint1Builder();
709             if (mapping.getSupportedInterfaceCapability() == null) {
710                 LOG.warn("mapping {} of node {} has no if-cap-type",
711                     mapping.getLogicalConnectionPoint(), node.getNodeId());
712             } else {
713                 XpdrTpPortConnectionAttributesBuilder xtpcaBldr = new XpdrTpPortConnectionAttributesBuilder();
714                 for (Class<? extends SupportedIfCapability> supInterCapa : mapping.getSupportedInterfaceCapability()) {
715                     SupportedInterfaceCapability supIfCapa = new SupportedInterfaceCapabilityBuilder()
716                         .withKey(new SupportedInterfaceCapabilityKey(supInterCapa))
717                         .setIfCapType(supInterCapa)
718                         .build();
719                     supIfMap.put(supIfCapa.key(), supIfCapa);
720                 }
721                 otnTp1Bldr.setTpSupportedInterfaces(
722                     new TpSupportedInterfacesBuilder()
723                         .setSupportedInterfaceCapability(supIfMap)
724                         .build()
725                 );
726                 //TODO: It is not logical to assign a priori one of the possible rate to the TP.
727                 //Would be worth assigning per default "unallocated" at the tp creation step,
728                 //and updating it with correct rate when it supports a specific service.
729                 if (withRate) {
730                     otnTp1Bldr.setXpdrTpPortConnectionAttributes(
731                         xtpcaBldr.setRate(fixRate(mapping.getSupportedInterfaceCapability())).build());
732                 }
733             }
734             setclientNwTpAttr(
735                 tpMap,
736                 node,
737                 new TpId(mapping.getLogicalConnectionPoint()),
738                 tpType,
739                 otnTp1Bldr.build(),
740                 new org.opendaylight.yang.gen.v1.http.transportpce.topology.rev220123.TerminationPoint1Builder(),
741                 mapping);
742         }
743     }
744
745     private static void setclientNwTpAttr(Map<TerminationPointKey, TerminationPoint> tpMap, OtnTopoNode node, TpId tpId,
746             OpenroadmTpType tpType, TerminationPoint1 otnTp1,
747             org.opendaylight.yang.gen.v1.http.transportpce.topology.rev220123.TerminationPoint1Builder tpceTp1Bldr,
748             Mapping mapping) {
749
750         switch (tpType) {
751             case XPONDERNETWORK:
752                 if (node.getXpdrNetConnectionMap().get(tpId.getValue()) != null) {
753                     tpceTp1Bldr.setAssociatedConnectionMapPort(node.getXpdrNetConnectionMap().get(tpId.getValue()));
754                 }
755                 SupportingTerminationPoint stp = new SupportingTerminationPointBuilder()
756                     .setNetworkRef(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID))
757                     .setNodeRef(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb()))
758                     .setTpRef(tpId)
759                     .build();
760                 TerminationPoint ietfTpNw =
761                     buildIetfTp(tpceTp1Bldr, otnTp1, tpType, tpId, Map.of(stp.key(), stp), mapping);
762                 tpMap.put(ietfTpNw.key(),ietfTpNw);
763                 break;
764             case XPONDERCLIENT:
765                 if (node.getXpdrCliConnectionMap().get(tpId.getValue()) != null) {
766                     tpceTp1Bldr.setAssociatedConnectionMapPort(node.getXpdrCliConnectionMap().get(tpId.getValue()));
767                 }
768                 TerminationPoint ietfTpCl = buildIetfTp(tpceTp1Bldr, otnTp1, tpType, tpId, null, mapping);
769                 tpMap.put(ietfTpCl.key(),ietfTpCl);
770                 break;
771             default:
772                 LOG.error("Undefined tpType for Termination point {} of {}", tpId.getValue(), node.getNodeId());
773                 break;
774         }
775     }
776
777     private static Class<? extends OduRateIdentity> fixRate(Set<Class<? extends SupportedIfCapability>> list) {
778
779         for (Class<? extends  SupportedIfCapability> class1 : list) {
780             if (RATE_MAP.containsKey(class1.getSimpleName())) {
781                 return RATE_MAP.get(class1.getSimpleName());
782             }
783         }
784         return null;
785     }
786
787     private static Map<SupportingNodeKey,SupportingNode> createSupportingNodes(OtnTopoNode node) {
788
789         SupportingNode suppNode1 = new SupportingNodeBuilder()
790             .setNetworkRef(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID))
791             .setNodeRef(new NodeId(node.getNodeId()))
792             .withKey(
793                 new SupportingNodeKey(
794                     new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID),
795                     new NodeId(node.getNodeId())))
796             .build();
797         SupportingNode suppNode2 = new SupportingNodeBuilder()
798             .setNetworkRef(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID))
799             .setNodeRef(new NodeId(node.getNodeId() + XPDR + node.getXpdrNb()))
800             .withKey(
801                 new SupportingNodeKey(
802                     new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID),
803                     new NodeId(node.getNodeId() + XPDR + node.getXpdrNb())))
804             .build();
805         SupportingNode suppNode3 = new SupportingNodeBuilder()
806             .setNetworkRef(new NetworkId(NetworkUtils.CLLI_NETWORK_ID))
807             .setNodeRef(new NodeId(node.getClli()))
808             .withKey(
809                 new SupportingNodeKey(
810                     new NetworkId(NetworkUtils.CLLI_NETWORK_ID),
811                     new NodeId(node.getClli())))
812             .build();
813         Map<SupportingNodeKey,SupportingNode> suppNodeMap = new HashMap<>();
814         suppNodeMap.put(suppNode1.key(),suppNode1);
815         suppNodeMap.put(suppNode2.key(),suppNode2);
816         suppNodeMap.put(suppNode3.key(),suppNode3);
817         return suppNodeMap;
818     }
819
820     private static TerminationPoint buildIetfTp(
821             org.opendaylight.yang.gen.v1.http.transportpce.topology.rev220123.TerminationPoint1Builder tpceTp1Bldr,
822             TerminationPoint1 otnTp1, OpenroadmTpType tpType, TpId tpId,
823             Map<SupportingTerminationPointKey, SupportingTerminationPoint> supportTpMap, Mapping mapping) {
824
825         TerminationPointBuilder ietfTpBldr = new TerminationPointBuilder();
826         if (tpceTp1Bldr.getAssociatedConnectionMapPort() != null) {
827             ietfTpBldr.addAugmentation(tpceTp1Bldr.build());
828         }
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(
837                 new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.TerminationPoint1Builder()
838                     .setTpType(tpType)
839                     .setAdministrativeState(TopologyUtils.setNetworkAdminState(mapping.getPortAdminState()))
840                     .setOperationalState(TopologyUtils.setNetworkOperState(mapping.getPortOperState()))
841                     .build())
842             .build();
843     }
844
845     private static String formatNodeName(String nodeName, String tpName) {
846
847         return nodeName.contains(XPDR)
848                 ? nodeName
849                 : new StringBuilder(nodeName).append("-").append(tpName.split("-")[0]).toString();
850     }
851 }