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