Refactor Renderer OpenRoadmInterfaces step 2
[transportpce.git] / renderer / src / main / java / org / opendaylight / transportpce / renderer / openroadminterface / OpenRoadmInterface710.java
1 /*
2  * Copyright © 2021 AT&T and others.  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.renderer.openroadminterface;
10
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.HashSet;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.Set;
17 import java.util.stream.IntStream;
18 import org.opendaylight.transportpce.common.StringConstants;
19 import org.opendaylight.transportpce.common.fixedflex.GridConstant;
20 import org.opendaylight.transportpce.common.fixedflex.SpectrumInformation;
21 import org.opendaylight.transportpce.common.mapping.PortMapping;
22 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaceException;
23 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaces;
24 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.device.renderer.rev211004.az.api.info.AEndApiInfo;
25 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.device.renderer.rev211004.az.api.info.ZEndApiInfo;
26 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220316.mapping.Mapping;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.attributes.rev200327.TrailTraceOther.TimDetectMode;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.attributes.rev200327.parent.odu.allocation.ParentOduAllocationBuilder;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.attributes.rev200327.parent.odu.allocation.parent.odu.allocation.trib.slots.choice.OpucnBuilder;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.link.types.rev191129.PowerDBm;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.Foic14;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.Foic24;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.Foic28;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.Foic36;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.Foic48;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.FrequencyTHz;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.ModulationFormat;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.ProvisionModeType;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.R100G;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.R100GOtsi;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.R200GOtsi;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.R300GOtsi;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.R400GOtsi;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev200529.Ofec;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev200529.Off;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev200529.Rsfec;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev200529.Scfec;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.interfaces.grp.InterfaceBuilder;
49 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.interfaces.grp.InterfaceKey;
50 import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates;
51 import org.opendaylight.yang.gen.v1.http.org.openroadm.ethernet.interfaces.rev200529.Interface1Builder;
52 import org.opendaylight.yang.gen.v1.http.org.openroadm.ethernet.interfaces.rev200529.ethernet.container.EthernetBuilder;
53 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev191129.EthernetCsmacd;
54 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev191129.InterfaceType;
55 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev191129.OpticalChannel;
56 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev191129.OtnOdu;
57 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev191129.OtnOtu;
58 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev191129.Otsi;
59 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev191129.OtsiGroup;
60 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev200529.och.container.OchBuilder;
61 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.tributary.signal.interfaces.rev200529.otsi.attributes.FlexoBuilder;
62 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.tributary.signal.interfaces.rev200529.otsi.container.OtsiBuilder;
63 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev200327.ODU4;
64 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev200327.ODUCn;
65 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev200327.ODUTTP;
66 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev200327.ODUTTPCTP;
67 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev200327.ODUflexCbr;
68 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev200327.ODUflexCbr400G;
69 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev200327.OTU4;
70 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev200327.OTUCn;
71 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev200327.OpucnTribSlotDef;
72 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev200327.PayloadTypeDef;
73 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev200529.OduAttributes.MonitoringMode;
74 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev200529.odu.container.OduBuilder;
75 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev200529.opu.OpuBuilder;
76 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.otu.interfaces.rev200529.otu.container.OtuBuilder;
77 import org.opendaylight.yang.gen.v1.http.org.openroadm.otsi.group.interfaces.rev200529.otsi.group.container.OtsiGroupBuilder;
78 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev201211.If100GE;
79 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev201211.IfOCHOTU4ODU4;
80 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev201211.IfOtsiOtsigroup;
81 import org.opendaylight.yangtools.yang.common.Decimal64;
82 import org.opendaylight.yangtools.yang.common.Uint16;
83 import org.opendaylight.yangtools.yang.common.Uint32;
84 import org.opendaylight.yangtools.yang.common.Uint8;
85 import org.slf4j.Logger;
86 import org.slf4j.LoggerFactory;
87
88 public class OpenRoadmInterface710 {
89     private static final String MODULATION_FMT_EXCEPTION_MESSAGE =
90         "Unable to get the modulation format";
91     private static final String RATE_EXCEPTION_MESSAGE =
92         "Unable to get the rate";
93     private static final String ODUC = "-ODUC";
94     private static final List<String> SUPPORTED_ODUCN_RATES = List.of("1", "2", "3", "4");
95     private final PortMapping portMapping;
96     private final OpenRoadmInterfaces openRoadmInterfaces;
97     private static final Logger LOG = LoggerFactory.getLogger(OpenRoadmInterface710.class);
98
99     public OpenRoadmInterface710(PortMapping portMapping, OpenRoadmInterfaces openRoadmInterfaces) {
100         this.portMapping = portMapping;
101         this.openRoadmInterfaces = openRoadmInterfaces;
102     }
103
104     public String createOpenRoadmEthInterface(String nodeId, String logicalConnPoint)
105             throws OpenRoadmInterfaceException {
106         Mapping portMap = portMapping.getMapping(nodeId, logicalConnPoint);
107         if (portMap == null) {
108             throw new OpenRoadmInterfaceException(
109                 OpenRoadmInterfaceException.mapping_msg_err(nodeId, logicalConnPoint));
110         }
111         InterfaceBuilder ethInterfaceBldr =
112             createGenericInterfaceBuilder(portMap, EthernetCsmacd.VALUE, logicalConnPoint + "-ETHERNET")
113                 .addAugmentation(
114                     // Create Interface1 type object required for adding as augmentation
115                     new Interface1Builder()
116                         .setEthernet(
117                             // Ethernet interface specific data
118                             // We have to differentiate if-100GE vs if-400GE
119                             // Default set to 400G
120                             portMap.getSupportedInterfaceCapability().contains(If100GE.VALUE)
121                                 // There could be different client pluggables on either side QSFP28-LR4 or QSFP28-FR4
122                                 // LR4-requires FEC to off, while FR4 can accept even when FEC is off
123                                 ? new EthernetBuilder().setFec(Off.VALUE).setSpeed(Uint32.valueOf(100000)).build()
124                                 : new EthernetBuilder().setFec(Rsfec.VALUE).setSpeed(Uint32.valueOf(400000)).build())
125                         .build());
126         // Post interface on the device
127         openRoadmInterfaces.postInterface(nodeId, ethInterfaceBldr);
128         // Post the equipment-state change on the device circuit-pack
129         openRoadmInterfaces.postEquipmentState(nodeId, portMap.getSupportingCircuitPackName(), true);
130         return ethInterfaceBldr.getName();
131     }
132
133     public String createOpenRoadmOchInterface(String nodeId, String logicalConnPoint,
134             SpectrumInformation spectrumInformation)
135             throws OpenRoadmInterfaceException {
136         ModulationFormat modulationFormat = ModulationFormat.forName(spectrumInformation.getModulationFormat());
137         if (modulationFormat == null) {
138             modulationFormat =  ModulationFormat.DpQpsk;
139         }
140         Mapping portMap = portMapping.getMapping(nodeId, logicalConnPoint);
141         if (portMap == null) {
142             throw new OpenRoadmInterfaceException(
143                 OpenRoadmInterfaceException.mapping_msg_err(nodeId, logicalConnPoint));
144         }
145         // Create generic interface
146         InterfaceBuilder ochInterfaceBldr =
147             createGenericInterfaceBuilder(
148                     portMap, OpticalChannel.VALUE,
149                     spectrumInformation.getIdentifierFromParams(logicalConnPoint))
150                 .addAugmentation(
151                 // Create Interface1 type object required for adding as augmentation
152                     new org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev200529
153                             .Interface1Builder()
154                         .setOch(
155                             // OCH interface specific data
156                             new OchBuilder()
157                                 .setFrequency(
158                                     new FrequencyTHz(Decimal64.valueOf(spectrumInformation.getCenterFrequency())))
159                                 .setRate(R100G.VALUE)
160                                 .setTransmitPower(new PowerDBm(Decimal64.valueOf("-5")))
161                                 .setModulationFormat(modulationFormat)
162                                 .build())
163                         .build());
164         // Post interface on the device
165         openRoadmInterfaces.postInterface(nodeId, ochInterfaceBldr);
166         // Post the equipment-state change on the device circuit-pack if xpdr node
167         if (portMap.getLogicalConnectionPoint().contains(StringConstants.NETWORK_TOKEN)) {
168             this.openRoadmInterfaces.postEquipmentState(nodeId, portMap.getSupportingCircuitPackName(), true);
169         }
170         return ochInterfaceBldr.getName();
171     }
172
173     public String createOpenRoadmOtsiInterface(String nodeId, String logicalConnPoint,
174             SpectrumInformation spectrumInformation)
175             throws OpenRoadmInterfaceException {
176         ModulationFormat modulationFormat = ModulationFormat.forName(spectrumInformation.getModulationFormat());
177         if (modulationFormat == null) {
178             throw new OpenRoadmInterfaceException(MODULATION_FMT_EXCEPTION_MESSAGE);
179         }
180         // OTSI interface specific data
181         OtsiBuilder otsiBuilder = new OtsiBuilder()
182             .setFrequency(new FrequencyTHz(Decimal64.valueOf(spectrumInformation.getCenterFrequency())))
183             .setTransmitPower(new PowerDBm(Decimal64.valueOf("-5")))
184             .setProvisionMode(ProvisionModeType.Explicit)
185             .setFec(Ofec.VALUE)
186             .setModulationFormat(modulationFormat);
187         // Use the rate to switch rather than modulation format
188         int serviceRate = getServiceRate(modulationFormat, spectrumInformation);
189         switch (serviceRate) {
190             case 100:
191                 LOG.info("Given modulation format and spectral width 50GHz {} and thus rate is 100G",
192                     modulationFormat);
193                 // TODO check if FOIC and Gbaud logs could not be rationalized
194                 LOG.info("FOIC is 1.4 for 31.6 Gbaud and rate is 100");
195                 otsiBuilder
196                     .setOtsiRate(R100GOtsi.VALUE)
197                     .setFlexo(new FlexoBuilder()
198                         .setFoicType(Foic14.VALUE)
199                         .setIid(new ArrayList<>(Arrays.asList(Uint8.valueOf(1))))
200                         .build());
201                 break;
202             case 200:
203                 LOG.info("Given modulation format is {} and thus rate is 200G", modulationFormat);
204                 FlexoBuilder flexoBuilder = new FlexoBuilder()
205                     .setIid(new ArrayList<>(List.of(Uint8.valueOf(1), Uint8.valueOf(2))));
206                 if (modulationFormat == ModulationFormat.DpQam16) {
207                     LOG.info("FOIC is 2.8 for 31.6 Gbaud and rate is 200");
208                     // FOIC rate is different
209                     flexoBuilder.setFoicType(Foic28.VALUE);
210                 } else {
211                     // default is dp-qpsk for 200G under 63.1 GBaud
212                     flexoBuilder.setFoicType(Foic24.VALUE);
213                 }
214                 otsiBuilder
215                     .setOtsiRate(R200GOtsi.VALUE)
216                     .setFlexo(flexoBuilder.build());
217                 break;
218             case 300:
219                 LOG.info("Given modulation format is {} and thus rate is 300G", modulationFormat);
220                 otsiBuilder.setOtsiRate(R300GOtsi.VALUE)
221                     .setFlexo(new FlexoBuilder()
222                         .setFoicType(Foic36.VALUE)
223                         .setIid(new ArrayList<>(List.of(Uint8.valueOf(1), Uint8.valueOf(2), Uint8.valueOf(3))))
224                         .build());
225                 break;
226             case 400:
227                 // Default baud-rate is 63.1 Gbaud
228                 LOG.info("Given modulation format is {} and thus rate is 400G", modulationFormat);
229                 otsiBuilder
230                     .setModulationFormat(modulationFormat)
231                     .setOtsiRate(R400GOtsi.VALUE)
232                     .setFlexo(new FlexoBuilder()
233                         .setFoicType(Foic48.VALUE)
234                         .setIid(new ArrayList<>(
235                             List.of(Uint8.valueOf(1), Uint8.valueOf(2), Uint8.valueOf(3), Uint8.valueOf(4))))
236                         .build());
237                 break;
238             default:
239                 LOG.error("Rate {} is unsupported", serviceRate);
240                 throw new OpenRoadmInterfaceException(RATE_EXCEPTION_MESSAGE);
241         }
242         Mapping portMap = portMapping.getMapping(nodeId, logicalConnPoint);
243         if (portMap == null) {
244             throw new OpenRoadmInterfaceException(
245                 OpenRoadmInterfaceException.mapping_msg_err(nodeId, logicalConnPoint));
246         }
247         // Create generic interface
248         InterfaceBuilder otsiInterfaceBldr =
249             createGenericInterfaceBuilder(
250                     portMap, Otsi.VALUE,
251                     spectrumInformation.getIdentifierFromParams(logicalConnPoint))
252                 .addAugmentation(
253                     // Create Interface1 type object required for adding as augmentation
254                     new org.opendaylight.yang.gen.v1.http
255                             .org.openroadm.optical.channel.tributary.signal.interfaces.rev200529.Interface1Builder()
256                         .setOtsi(otsiBuilder.build())
257                         .build());
258         // Post interface on the device
259         openRoadmInterfaces.postInterface(nodeId, otsiInterfaceBldr);
260         // Post the equipment-state change on the device circuit-pack if xpdr node
261         if (portMap.getLogicalConnectionPoint().contains(StringConstants.NETWORK_TOKEN)) {
262             this.openRoadmInterfaces.postEquipmentState(nodeId, portMap.getSupportingCircuitPackName(), true);
263         }
264         return otsiInterfaceBldr.getName();
265     }
266
267     // This is a transponder use-case where the supporting port is just one, but YANG model
268     // requires supporting port to be list
269     public String createOpenRoadmOtsiGroupInterface(String nodeId, String logicalConnPoint,
270             String supportingOtsiInterface, SpectrumInformation spectrumInformation)
271             throws OpenRoadmInterfaceException {
272         Mapping portMap = portMapping.getMapping(nodeId, logicalConnPoint);
273         if (portMap == null) {
274             throw new OpenRoadmInterfaceException(
275                 OpenRoadmInterfaceException.mapping_msg_err(nodeId, logicalConnPoint));
276         }
277         // Check the modulation format
278         ModulationFormat modulationFormat = ModulationFormat.forName(spectrumInformation.getModulationFormat());
279         if (modulationFormat == null) {
280             throw new OpenRoadmInterfaceException(MODULATION_FMT_EXCEPTION_MESSAGE);
281         }
282         int serviceRate = getServiceRate(modulationFormat, spectrumInformation);
283         // Create an OTSI group object
284         OtsiGroupBuilder otsiGroupBuilder = new OtsiGroupBuilder().setGroupId(Uint32.valueOf(1));
285         switch (serviceRate) {
286             case 100:
287                 otsiGroupBuilder.setGroupRate(R100GOtsi.VALUE);
288                 break;
289             case 200:
290                 otsiGroupBuilder.setGroupRate(R200GOtsi.VALUE);
291                 break;
292             case 300:
293                 otsiGroupBuilder.setGroupRate(R300GOtsi.VALUE);
294                 break;
295             case 400:
296                 otsiGroupBuilder.setGroupRate(R400GOtsi.VALUE);
297                 break;
298             default:
299                 LOG.error("Rate {} is not supported", serviceRate);
300                 throw new OpenRoadmInterfaceException(RATE_EXCEPTION_MESSAGE);
301         }
302         // Create generic interface
303         InterfaceBuilder otsiGroupInterfaceBldr =
304             createGenericInterfaceBuilder(
305                     portMap, OtsiGroup.VALUE,
306                     logicalConnPoint + String.join("-", "", "OTSIGROUP", serviceRate + "G"))
307                 .setSupportingInterfaceList(new HashSet<>(Set.of(supportingOtsiInterface)))
308                 .addAugmentation(
309                     new org.opendaylight.yang.gen.v1.http.org.openroadm.otsi.group.interfaces.rev200529
310                             .Interface1Builder()
311                         .setOtsiGroup(otsiGroupBuilder.build())
312                         .build());
313         // Post interface on the device
314         openRoadmInterfaces.postInterface(nodeId, otsiGroupInterfaceBldr);
315         // Post the equipment-state change on the device circuit-pack if xpdr node
316         if (portMap.getLogicalConnectionPoint().contains(StringConstants.NETWORK_TOKEN)) {
317             this.openRoadmInterfaces.postEquipmentState(nodeId, portMap.getSupportingCircuitPackName(), true);
318         }
319         return otsiGroupInterfaceBldr.getName();
320     }
321
322     public String createOpenRoadmOchOtsiOtsigroupInterface(String nodeId, String logicalConnPoint,
323             SpectrumInformation spectrumInformation)
324             throws OpenRoadmInterfaceException {
325         Mapping portMap = portMapping.getMapping(nodeId, logicalConnPoint);
326         if (portMap == null) {
327             throw new OpenRoadmInterfaceException(
328                 OpenRoadmInterfaceException.mapping_msg_err(nodeId, logicalConnPoint));
329         }
330         if (portMap.getSupportedInterfaceCapability().contains(IfOCHOTU4ODU4.VALUE)) {
331             // create OCH interface
332             return createOpenRoadmOchInterface(nodeId, logicalConnPoint, spectrumInformation);
333         }
334         if (portMap.getSupportedInterfaceCapability().contains(IfOtsiOtsigroup.VALUE)) {
335             // Create OTSi and OTSi-group and concat the names of the interface
336             String interfaceOtsiName = createOpenRoadmOtsiInterface(nodeId, logicalConnPoint, spectrumInformation);
337             // And Concat the two names for this interface
338             return interfaceOtsiName + "#"
339                 + createOpenRoadmOtsiGroupInterface(nodeId, logicalConnPoint, interfaceOtsiName, spectrumInformation);
340         }
341         return null;
342     }
343
344     public String createOpenRoadmOtu4Interface(String nodeId, String logicalConnPoint, String supportOchInterface,
345             AEndApiInfo apiInfoA, ZEndApiInfo apiInfoZ) throws OpenRoadmInterfaceException {
346         Mapping mapping = this.portMapping.getMapping(nodeId, logicalConnPoint);
347         if (mapping == null) {
348             throw new OpenRoadmInterfaceException(
349                 OpenRoadmInterfaceException.mapping_msg_err(nodeId, logicalConnPoint));
350         }
351         // OTU interface specific data
352         org.opendaylight.yang.gen.v1.http.org.openroadm.otn.otu.interfaces.rev200529.otu.container.OtuBuilder
353                 otuIfBuilder =
354             new org.opendaylight.yang.gen.v1.http.org.openroadm.otn.otu.interfaces.rev200529.otu.container.OtuBuilder()
355                 .setFec(Scfec.VALUE)
356                 .setRate(OTU4.VALUE);
357         if (apiInfoA != null) {
358             otuIfBuilder.setTxSapi(apiInfoA.getSapi())
359                 .setTxDapi(apiInfoA.getDapi())
360                 .setExpectedSapi(apiInfoA.getExpectedSapi())
361                 .setExpectedDapi(apiInfoA.getExpectedDapi());
362         }
363         if (apiInfoZ != null) {
364             otuIfBuilder.setTxSapi(apiInfoZ.getSapi())
365                 .setTxDapi(apiInfoZ.getDapi())
366                 .setExpectedSapi(apiInfoZ.getExpectedSapi())
367                 .setExpectedDapi(apiInfoZ.getExpectedDapi());
368         }
369         InterfaceBuilder otuInterfaceBldr =
370             createGenericInterfaceBuilder(mapping, OtnOtu.VALUE, logicalConnPoint + "-OTU4")
371                 .setSupportingInterfaceList(new HashSet<>(Set.of(supportOchInterface)))
372                 .addAugmentation(
373                     // Create Interface1 type object required for adding as augmentation
374                     new org.opendaylight.yang.gen.v1.http.org.openroadm.otn.otu.interfaces.rev200529.Interface1Builder()
375                         .setOtu(otuIfBuilder.build())
376                         .build());
377         // Post interface on the device
378         openRoadmInterfaces.postInterface(nodeId, otuInterfaceBldr);
379         this.portMapping.updateMapping(nodeId, mapping);
380         return otuInterfaceBldr.getName();
381     }
382
383
384     public String createOpenRoadmOtucnInterface(String nodeId, String logicalConnPoint,
385             String supportingOtsiGroupInterface, AEndApiInfo apiInfoA, ZEndApiInfo apiInfoZ)
386             throws OpenRoadmInterfaceException {
387         Mapping mapping = portMapping.getMapping(nodeId, logicalConnPoint);
388         if (mapping == null) {
389             throw new OpenRoadmInterfaceException(
390                 OpenRoadmInterfaceException.mapping_msg_err(nodeId, logicalConnPoint));
391         }
392         // Create an OTUCn object
393         OtuBuilder otuBuilder = new OtuBuilder()
394             .setRate(OTUCn.VALUE)
395             .setTimActEnabled(false)
396             .setTimDetectMode(TimDetectMode.Disabled)
397             .setDegmIntervals(Uint8.valueOf(2))
398             .setDegthrPercentage(Uint16.valueOf(100));
399         if (apiInfoA != null) {
400             otuBuilder.setTxSapi(apiInfoA.getSapi())
401                 .setTxDapi(apiInfoA.getDapi())
402                 .setExpectedSapi(apiInfoA.getExpectedSapi())
403                 .setExpectedDapi(apiInfoA.getExpectedDapi());
404         }
405         if (apiInfoZ != null) {
406             otuBuilder.setTxSapi(apiInfoZ.getSapi())
407                 .setTxDapi(apiInfoZ.getDapi())
408                 .setExpectedSapi(apiInfoZ.getExpectedSapi())
409                 .setExpectedDapi(apiInfoZ.getExpectedDapi());
410         }
411         // Set the OTUCn rate for various rates
412         String rate = supportingOtsiGroupInterface.substring(supportingOtsiGroupInterface.lastIndexOf('-') + 1);
413         String otucnrate = null;
414         switch (rate) {
415             case "100G":
416                 otuBuilder.setOtucnNRate(Uint16.valueOf(1));
417                 otucnrate = "1";
418                 break;
419             case "200G":
420                 otuBuilder.setOtucnNRate(Uint16.valueOf(2));
421                 otucnrate = "2";
422                 break;
423             case "300G":
424                 otuBuilder.setOtucnNRate(Uint16.valueOf(3));
425                 otucnrate = "3";
426                 break;
427             case "400G":
428                 otuBuilder.setOtucnNRate(Uint16.valueOf(4));
429                 otucnrate = "4";
430                 break;
431             default:
432                 LOG.error("Rate {} is not supported", rate);
433                 throw new OpenRoadmInterfaceException(RATE_EXCEPTION_MESSAGE);
434         }
435         InterfaceBuilder otuInterfaceBuilder =
436             createGenericInterfaceBuilder(mapping, OtnOtu.VALUE, logicalConnPoint + "-OTUC" + otucnrate)
437                 .setSupportingInterfaceList(new HashSet<>(Set.of(supportingOtsiGroupInterface)))
438                 .addAugmentation(
439                     new org.opendaylight.yang.gen.v1.http.org.openroadm.otn.otu.interfaces.rev200529.Interface1Builder()
440                         .setOtu(otuBuilder.build())
441                         .build());
442         // Post interface on the device
443         openRoadmInterfaces.postInterface(nodeId, otuInterfaceBuilder);
444         // Post the equipment-state change on the device circuit-pack if xpdr node
445         if (mapping.getLogicalConnectionPoint().contains(StringConstants.NETWORK_TOKEN)) {
446             this.openRoadmInterfaces.postEquipmentState(nodeId, mapping.getSupportingCircuitPackName(), true);
447         }
448         this.portMapping.updateMapping(nodeId, mapping);
449         return otuInterfaceBuilder.getName();
450     }
451
452     public String createOpenRoadmOtu4OtucnInterface(String nodeId, String logicalConnPoint,
453             String supportingInterface, AEndApiInfo apiInfoA, ZEndApiInfo apiInfoZ)
454             throws OpenRoadmInterfaceException {
455         Mapping portMap = portMapping.getMapping(nodeId, logicalConnPoint);
456         if (portMap == null) {
457             throw new OpenRoadmInterfaceException(
458                 OpenRoadmInterfaceException.mapping_msg_err(nodeId, logicalConnPoint));
459         }
460         // Depending on OCH-OTU4-ODU4 interface or OTSi-OTSi-group, supporting interface should
461         // reflect that
462         if (portMap.getSupportedInterfaceCapability().contains(IfOCHOTU4ODU4.VALUE)) {
463             // create OTU4 interface
464             return createOpenRoadmOtu4Interface(nodeId, logicalConnPoint, supportingInterface, apiInfoA, apiInfoZ);
465         }
466         if (portMap.getSupportedInterfaceCapability().contains(IfOtsiOtsigroup.VALUE)) {
467             // Create OTUCn
468             return createOpenRoadmOtucnInterface(nodeId, logicalConnPoint, supportingInterface, apiInfoA, apiInfoZ);
469         }
470         return null;
471     }
472
473     public String createOpenRoadmOdu4Interface(String nodeId, String logicalConnPoint,
474             AEndApiInfo apiInfoA, ZEndApiInfo apiInfoZ) throws OpenRoadmInterfaceException {
475         Mapping mapping = portMapping.getMapping(nodeId, logicalConnPoint);
476         if (mapping == null) {
477             throw new OpenRoadmInterfaceException(
478                 OpenRoadmInterfaceException.mapping_msg_err(nodeId, logicalConnPoint));
479         }
480         InterfaceBuilder oduInterfaceBldr =
481             createGenericInterfaceBuilder(mapping, OtnOdu.VALUE, logicalConnPoint + "-ODU4");
482         if (mapping.getSupportingOtu4() != null) {
483             oduInterfaceBldr.setSupportingInterfaceList(new HashSet<>(Set.of(mapping.getSupportingOtu4())));
484         }
485         // Create an ODU4 object
486         OduBuilder oduBuilder = new OduBuilder()
487             .setRate(ODU4.VALUE)
488             .setOduFunction(ODUTTP.VALUE)
489             .setMonitoringMode(MonitoringMode.Terminated)
490             .setOpu(
491                 // OPU payload
492                 new OpuBuilder()
493                     .setExpPayloadType(PayloadTypeDef.getDefaultInstance("07"))
494                     .setPayloadType(PayloadTypeDef.getDefaultInstance("07"))
495                     .build());
496         if (apiInfoA != null) {
497             oduBuilder.setTxSapi(apiInfoA.getSapi())
498                 .setTxDapi(apiInfoA.getDapi())
499                 .setExpectedSapi(apiInfoA.getExpectedSapi())
500                 .setExpectedDapi(apiInfoA.getExpectedDapi());
501         }
502         if (apiInfoZ != null) {
503             oduBuilder.setTxSapi(apiInfoZ.getSapi())
504                 .setTxDapi(apiInfoZ.getDapi())
505                 .setExpectedSapi(apiInfoZ.getExpectedSapi())
506                 .setExpectedDapi(apiInfoZ.getExpectedDapi());
507         }
508         oduInterfaceBldr
509             .addAugmentation(
510                 new org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev200529.Interface1Builder()
511                     .setOdu(oduBuilder.build())
512                 .build());
513         // Post interface on the device
514         openRoadmInterfaces.postInterface(nodeId, oduInterfaceBldr);
515         // Since this is not a CTP, we can update the port-mapping
516         LOG.info("{}-{} updating mapping with interface {}", nodeId, logicalConnPoint, oduInterfaceBldr.getName());
517         this.portMapping.updateMapping(nodeId, mapping);
518         return oduInterfaceBldr.getName();
519     }
520
521
522     public String createOpenRoadmOducnInterface(String nodeId, String logicalConnPoint)
523             throws OpenRoadmInterfaceException {
524         Mapping mapping = portMapping.getMapping(nodeId, logicalConnPoint);
525         if (mapping == null) {
526             throw new OpenRoadmInterfaceException(
527                 OpenRoadmInterfaceException.mapping_msg_err(nodeId, logicalConnPoint));
528         }
529         if (mapping.getSupportingOtucn() == null) {
530             throw new OpenRoadmInterfaceException("Missing supporting OTUCn interface on port-mapping");
531         }
532         String supportingOtucn = mapping.getSupportingOtucn();
533         // Set the ODUCn rate from OTUCn interface naming convention
534         String oducnrate = supportingOtucn.substring(supportingOtucn.length() - 1);
535         // check if the oducnrate is a valid value and if it is invalid, then throw error
536         if (!SUPPORTED_ODUCN_RATES.contains(oducnrate)) {
537             throw new OpenRoadmInterfaceException(RATE_EXCEPTION_MESSAGE);
538         }
539         InterfaceBuilder oduInterfaceBuilder =
540             createGenericInterfaceBuilder(mapping, OtnOdu.VALUE, logicalConnPoint + "-ODUC" + oducnrate)
541                 .setSupportingInterfaceList(new HashSet<>(Set.of(supportingOtucn)))
542                 .addAugmentation(
543                     new org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev200529.Interface1Builder()
544                         .setOdu(
545                             // Create an ODUCn object
546                             new OduBuilder()
547                                 .setRate(ODUCn.VALUE)
548                                 .setOduFunction(ODUTTP.VALUE)
549                                 .setMonitoringMode(MonitoringMode.Terminated)
550                                 .setTimActEnabled(false)
551                                 .setTimDetectMode(TimDetectMode.Disabled)
552                                 .setDegmIntervals(Uint8.valueOf(2))
553                                 .setDegthrPercentage(Uint16.valueOf(100))
554                                 .setOducnNRate(Uint16.valueOf(oducnrate))
555                                 .setOpu(
556                                     // OPU payload
557                                     new OpuBuilder()
558                                         .setExpPayloadType(PayloadTypeDef.getDefaultInstance("22"))
559                                         .setPayloadType(PayloadTypeDef.getDefaultInstance("22"))
560                                         .build())
561                                 .build())
562                         .build());
563         // Post interface on the device
564         openRoadmInterfaces.postInterface(nodeId, oduInterfaceBuilder);
565         // Post the equipment-state change on the device circuit-pack if xpdr node
566         if (mapping.getLogicalConnectionPoint().contains(StringConstants.NETWORK_TOKEN)) {
567             this.openRoadmInterfaces.postEquipmentState(nodeId, mapping.getSupportingCircuitPackName(), true);
568         }
569         return oduInterfaceBuilder.getName();
570     }
571
572     // Overloaded methods should be together
573     // With SAPI and DAPI information
574     public String createOpenRoadmOducnInterface(String anodeId, String alogicalConnPoint,
575             String supportingOtucn, String znodeId, String zlogicalConnPoint)
576             throws OpenRoadmInterfaceException {
577         // Set the ODUCn rate from OTUCn interface naming convention
578         String oducnrate = supportingOtucn.substring(supportingOtucn.length() - 1);
579         // check if the oducnrate is a valid value and if it is invalid, then throw error
580         if (!SUPPORTED_ODUCN_RATES.contains(oducnrate)) {
581             throw new OpenRoadmInterfaceException(RATE_EXCEPTION_MESSAGE);
582         }
583         Mapping portMapA = portMapping.getMapping(anodeId, alogicalConnPoint);
584         if (portMapA == null) {
585             throw new OpenRoadmInterfaceException(
586                 OpenRoadmInterfaceException.mapping_msg_err(anodeId, alogicalConnPoint));
587         }
588         // On the Zside
589         Mapping portMapZ = portMapping.getMapping(znodeId, zlogicalConnPoint);
590         if (portMapZ == null) {
591             throw new OpenRoadmInterfaceException(
592                 OpenRoadmInterfaceException.mapping_msg_err(znodeId, zlogicalConnPoint));
593         }
594         InterfaceBuilder oduInterfaceBuilder =
595             createGenericInterfaceBuilder(portMapA, OtnOdu.VALUE, alogicalConnPoint + ODUC + oducnrate)
596                 .setSupportingInterfaceList(new HashSet<>(Set.of(supportingOtucn)))
597                 .addAugmentation(
598                     new org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev200529.Interface1Builder()
599                         .setOdu(
600                             new OduBuilder()
601                                 .setRate(ODUCn.VALUE)
602                                 .setOducnNRate(Uint16.valueOf(oducnrate))
603                                 .setOduFunction(ODUTTP.VALUE)
604                                 .setMonitoringMode(MonitoringMode.Terminated)
605                                 .setTimActEnabled(false)
606                                 .setTimDetectMode(TimDetectMode.Disabled)
607                                 .setDegmIntervals(Uint8.valueOf(2))
608                                 .setDegthrPercentage(Uint16.valueOf(100))
609                                 .setOpu(
610                                     // OPU payload
611                                     new OpuBuilder()
612                                         .setExpPayloadType(PayloadTypeDef.getDefaultInstance("22"))
613                                         .setPayloadType(PayloadTypeDef.getDefaultInstance("22"))
614                                         .build())
615                                 .setTxSapi(portMapA.getLcpHashVal())
616                                 .setTxDapi(portMapZ.getLcpHashVal())
617                                 .setExpectedSapi(portMapZ.getLcpHashVal())
618                                 .setExpectedDapi(portMapZ.getLcpHashVal())
619                                 .build())
620                         .build());
621         // Post interface on the device
622         openRoadmInterfaces.postInterface(anodeId, oduInterfaceBuilder);
623         // Post the equipment-state change on the device circuit-pack if xpdr node
624         if (portMapA.getLogicalConnectionPoint().contains(StringConstants.NETWORK_TOKEN)) {
625             this.openRoadmInterfaces.postEquipmentState(anodeId, portMapA.getSupportingCircuitPackName(), true);
626         }
627         return oduInterfaceBuilder.getName();
628     }
629
630
631     // This is only for transponder
632     public String createOpenRoadmOduflexInterface(String nodeId, String logicalConnPoint,
633             String supportingOducn)
634             throws OpenRoadmInterfaceException {
635         Mapping portMap = portMapping.getMapping(nodeId, logicalConnPoint);
636         if (portMap == null) {
637             throw new OpenRoadmInterfaceException(
638                 OpenRoadmInterfaceException.mapping_msg_err(nodeId, logicalConnPoint));
639         }
640         // Parent Odu-allocation
641         // Set the trib-slot array
642         Set<OpucnTribSlotDef> tribslots = new HashSet<>();
643         // Here the int stream is based on rate
644         // Get the rate, which can be 1, 2, 3 or 4 4=400G, 1=100G
645         String rate = supportingOducn.substring(supportingOducn.length() - 1);
646         IntStream.range(1, Integer.parseInt(rate) + 1)
647             .forEach(a -> IntStream.range(1, 21)
648                 .forEach(b -> tribslots.add(OpucnTribSlotDef.getDefaultInstance(a + "." + b))));
649         // Create an ODUFlex object
650         OduBuilder oduBuilder = new OduBuilder()
651             .setOduFunction(ODUTTPCTP.VALUE)
652             .setMonitoringMode(MonitoringMode.Terminated)
653             .setTimActEnabled(false)
654             .setTimDetectMode(TimDetectMode.Disabled)
655             .setDegmIntervals(Uint8.valueOf(2))
656             .setDegthrPercentage(Uint16.valueOf(100))
657             .setParentOduAllocation(
658                 new ParentOduAllocationBuilder()
659                     .setTribPortNumber(Uint16.valueOf(1))
660                     .setTribSlotsChoice(new OpucnBuilder().setOpucnTribSlots(tribslots).build())
661                     .build());
662         // Build the OPU container to the ODU builder
663         switch (rate) {
664             case "1":
665                 oduBuilder
666                     .setRate(ODU4.VALUE)
667                     .setOpu(
668                         new OpuBuilder()
669                             .setExpPayloadType(PayloadTypeDef.getDefaultInstance("07"))
670                             .setPayloadType(PayloadTypeDef.getDefaultInstance("07"))
671                             .build());
672                 logicalConnPoint += "-ODU4";
673                 break;
674             case "4":
675                 oduBuilder
676                     .setRate(ODUflexCbr.VALUE)
677                     .setOduflexCbrService(ODUflexCbr400G.VALUE)
678                     .setOpu(
679                         new OpuBuilder()
680                             .setExpPayloadType(PayloadTypeDef.getDefaultInstance("32"))
681                             .setPayloadType(PayloadTypeDef.getDefaultInstance("32"))
682                             .build());
683                 logicalConnPoint += "-ODUFLEX";
684                 break;
685             default:
686                 oduBuilder.setOpu(new OpuBuilder().build());
687                 break;
688         }
689         InterfaceBuilder oduflexInterfaceBuilder =
690             createGenericInterfaceBuilder(portMap, OtnOdu.VALUE, logicalConnPoint)
691                 .setSupportingInterfaceList(new HashSet<>(Set.of(supportingOducn)))
692                 .addAugmentation(
693                     new org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev200529.Interface1Builder()
694                         .setOdu(oduBuilder.build())
695                         .build());
696         // Post interface on the device
697         openRoadmInterfaces.postInterface(nodeId, oduflexInterfaceBuilder);
698         // Post the equipment-state change on the device circuit-pack if xpdr node
699         if (portMap.getLogicalConnectionPoint().contains(StringConstants.NETWORK_TOKEN)) {
700             this.openRoadmInterfaces.postEquipmentState(nodeId, portMap.getSupportingCircuitPackName(), true);
701         }
702         return oduflexInterfaceBuilder.getName();
703     }
704
705     // Overloaded methods should be together
706     // This is only for transponder; with SAPI/DAPI information
707     public String createOpenRoadmOduflexInterface(String anodeId, String alogicalConnPoint,
708             String supportingOducn, String znodeId, String zlogicalConnPoint)
709             throws OpenRoadmInterfaceException {
710         Mapping portMapA = portMapping.getMapping(anodeId, alogicalConnPoint);
711         if (portMapA == null) {
712             throw new OpenRoadmInterfaceException(
713                 OpenRoadmInterfaceException.mapping_msg_err(anodeId, alogicalConnPoint));
714         }
715         // On the Zside
716         Mapping portMapZ = portMapping.getMapping(znodeId, zlogicalConnPoint);
717         if (portMapZ == null) {
718             throw new OpenRoadmInterfaceException(
719                 OpenRoadmInterfaceException.mapping_msg_err(znodeId, zlogicalConnPoint));
720         }
721         // Parent Odu-allocation
722         // Set the trib-slot array
723         Set<OpucnTribSlotDef> tribslots = new HashSet<>();
724         // Here the int stream is based on rate
725         // Get the rate, which can be 1, 2, 3 or 4 4=400G, 1=100G
726         String rate = supportingOducn.substring(supportingOducn.lastIndexOf('-') + 1);
727         IntStream.range(1, Integer.parseInt(rate) + 1)
728             .forEach(a -> IntStream.range(1, 21)
729                 .forEach(b -> tribslots.add(OpucnTribSlotDef.getDefaultInstance(a + "." + b))));
730         // Create an ODUFlex object
731         OduBuilder oduBuilder = new OduBuilder()
732             .setOduFunction(ODUTTPCTP.VALUE)
733             .setMonitoringMode(MonitoringMode.Terminated)
734             .setTimActEnabled(false)
735             .setTimDetectMode(TimDetectMode.Disabled)
736             .setDegmIntervals(Uint8.valueOf(2))
737             .setDegthrPercentage(Uint16.valueOf(100))
738             // TODO the following line seemed to come a bit early
739             // so it is now commented out and the code was aligned with previous method
740             //.setOpu(opuBuilder.build())
741             .setParentOduAllocation(
742                 new ParentOduAllocationBuilder()
743                     .setTribPortNumber(Uint16.valueOf(1))
744                     .setTribSlotsChoice(new OpucnBuilder().setOpucnTribSlots(tribslots).build())
745                     .build());
746         switch (rate) {
747             case "1":
748                 oduBuilder
749                     .setRate(ODU4.VALUE)
750                     .setOpu(
751                         new OpuBuilder()
752                             .setExpPayloadType(PayloadTypeDef.getDefaultInstance("07"))
753                             .setPayloadType(PayloadTypeDef.getDefaultInstance("07"))
754                             .build());
755                 alogicalConnPoint += "-ODU4";
756                 break;
757             case "4":
758                 oduBuilder
759                     .setRate(ODUflexCbr.VALUE)
760                     .setOduflexCbrService(ODUflexCbr400G.VALUE)
761                     .setOpu(
762                         new OpuBuilder()
763                             .setExpPayloadType(PayloadTypeDef.getDefaultInstance("32"))
764                             .setPayloadType(PayloadTypeDef.getDefaultInstance("32"))
765                             .build());
766                 alogicalConnPoint += "-ODUFLEX";
767                 break;
768             default:
769                 oduBuilder.setOpu(new OpuBuilder().build());
770                 break;
771         }
772         InterfaceBuilder oduflexInterfaceBuilder =
773             createGenericInterfaceBuilder(portMapA, OtnOdu.VALUE, alogicalConnPoint)
774                 .setSupportingInterfaceList(new HashSet<>(Set.of(supportingOducn)))
775                 .addAugmentation(
776                     new org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev200529.Interface1Builder()
777                         .setOdu(oduBuilder.build())
778                         .build());
779         // Post the equipment-state change on the device circuit-pack if xpdr node
780         if (portMapA.getLogicalConnectionPoint().contains(StringConstants.NETWORK_TOKEN)) {
781             this.openRoadmInterfaces.postEquipmentState(anodeId, portMapA.getSupportingCircuitPackName(), true);
782         }
783         return oduflexInterfaceBuilder.getName();
784     }
785
786     public String createOpenRoadmOdu4OducnOduflex(String nodeId, String logicalConnPoint,
787             AEndApiInfo apiInfoA, ZEndApiInfo apiInfoZ) throws OpenRoadmInterfaceException {
788         Mapping portMap = portMapping.getMapping(nodeId, logicalConnPoint);
789         if (portMap == null) {
790             throw new OpenRoadmInterfaceException(
791                 OpenRoadmInterfaceException.mapping_msg_err(nodeId, logicalConnPoint));
792         }
793         // Depending on OTU4 or OTUCn, supporting interface should
794         // reflect that
795         String interfaceOdu4OducnOduflex = null;
796         // Depending on OTU4 or OTUCn, supporting interface should reflect that
797         if (portMap.getSupportedInterfaceCapability().contains(IfOCHOTU4ODU4.VALUE)) {
798             // create OTU4 interface
799             return createOpenRoadmOdu4Interface(nodeId, logicalConnPoint, apiInfoA, apiInfoZ);
800         }
801         if (portMap.getSupportedInterfaceCapability().contains(IfOtsiOtsigroup.VALUE)) {
802             // Create ODUCn and ODUFlex interface.
803             String interfaceOducn = createOpenRoadmOducnInterface(nodeId, logicalConnPoint);
804             return interfaceOducn + "#"
805                 + createOpenRoadmOduflexInterface(nodeId, logicalConnPoint, interfaceOducn);
806         }
807         return null;
808     }
809
810     public String createOpenRoadmOtnOducnInterface(String nodeId, String logicalConnPoint,
811             String supportingOtucn)
812             throws OpenRoadmInterfaceException {
813         Mapping portMap = portMapping.getMapping(nodeId, logicalConnPoint);
814         if (portMap == null) {
815             throw new OpenRoadmInterfaceException(
816                 OpenRoadmInterfaceException.mapping_msg_err(nodeId, logicalConnPoint));
817         }
818         // Set the ODUCn rate from OTUCn interface naming convention
819         String oducnrate = supportingOtucn.substring(supportingOtucn.length() - 1);
820         // check if the oducnrate is a valid value and if it is invalid, then throw error
821         if (!SUPPORTED_ODUCN_RATES.contains(oducnrate)) {
822             throw new OpenRoadmInterfaceException(RATE_EXCEPTION_MESSAGE);
823         }
824         InterfaceBuilder oduInterfaceBuilder =
825             createGenericInterfaceBuilder(portMap, OtnOdu.VALUE, logicalConnPoint + ODUC + oducnrate)
826                 .setSupportingInterfaceList(new HashSet<>(Set.of(supportingOtucn)))
827                 .addAugmentation(
828                     new org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev200529.Interface1Builder()
829                         .setOdu(
830                             // Create an ODUC4 object
831                             new OduBuilder()
832                                 .setRate(ODUCn.VALUE)
833                                 .setOducnNRate(Uint16.valueOf(oducnrate))
834                                 .setOduFunction(ODUTTP.VALUE)
835                                 .setMonitoringMode(MonitoringMode.Terminated)
836                                 .setTimActEnabled(false)
837                                 .setTimDetectMode(TimDetectMode.Disabled)
838                                 .setDegmIntervals(Uint8.valueOf(2))
839                                 .setDegthrPercentage(Uint16.valueOf(100))
840                                 .setOpu(
841                                     // OPU payload
842                                     new OpuBuilder()
843                                         .setExpPayloadType(PayloadTypeDef.getDefaultInstance("22"))
844                                         .setPayloadType(PayloadTypeDef.getDefaultInstance("22"))
845                                     .build())
846                                 .build())
847                         .build());
848         // Post interface on the device
849         openRoadmInterfaces.postInterface(nodeId, oduInterfaceBuilder);
850         // Post the equipment-state change on the device circuit-pack if xpdr node
851         if (portMap.getLogicalConnectionPoint().contains(StringConstants.NETWORK_TOKEN)) {
852             this.openRoadmInterfaces.postEquipmentState(nodeId, portMap.getSupportingCircuitPackName(), true);
853         }
854         // Update the port-mapping with the interface information
855         this.portMapping.updateMapping(nodeId, portMap);
856         return oduInterfaceBuilder.getName();
857     }
858
859
860     // With SAPI and DAPI information
861     public String createOpenRoadmOtnOducnInterface(String anodeId, String alogicalConnPoint,
862             String supportingOtucn, String znodeId, String zlogicalConnPoint)
863             throws OpenRoadmInterfaceException {
864         Mapping portMapA = portMapping.getMapping(anodeId, alogicalConnPoint);
865         if (portMapA == null) {
866             throw new OpenRoadmInterfaceException(
867                 OpenRoadmInterfaceException.mapping_msg_err(anodeId, alogicalConnPoint));
868         }
869         // On the Zside
870         Mapping portMapZ = portMapping.getMapping(znodeId, zlogicalConnPoint);
871         if (portMapZ == null) {
872             throw new OpenRoadmInterfaceException(
873                 OpenRoadmInterfaceException.mapping_msg_err(znodeId, zlogicalConnPoint));
874         }
875         // Set the ODUCn rate from OTUCn interface naming convention
876         String oducnrate = supportingOtucn.substring(supportingOtucn.length() - 1);
877         // check if the oducnrate is a valid value and if it is invalid, then throw error
878         if (!SUPPORTED_ODUCN_RATES.contains(oducnrate)) {
879             throw new OpenRoadmInterfaceException(RATE_EXCEPTION_MESSAGE);
880         }
881
882         InterfaceBuilder oduInterfaceBuilder =
883             createGenericInterfaceBuilder(portMapA, OtnOdu.VALUE, alogicalConnPoint + ODUC + oducnrate)
884                 .setSupportingInterfaceList(new HashSet<>(Set.of(supportingOtucn)))
885                 .addAugmentation(
886                     new org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev200529.Interface1Builder()
887                         .setOdu(
888                             // Create an ODUCn object
889                             new OduBuilder()
890                                 .setRate(ODUCn.VALUE)
891                                 .setOducnNRate(Uint16.valueOf(oducnrate))
892                                 .setOduFunction(ODUTTP.VALUE)
893                                 .setMonitoringMode(MonitoringMode.Terminated)
894                                 .setTimActEnabled(false)
895                                 .setTimDetectMode(TimDetectMode.Disabled)
896                                 .setDegmIntervals(Uint8.valueOf(2))
897                                 .setDegthrPercentage(Uint16.valueOf(100))
898                                 .setOpu(
899                                     // OPU payload
900                                     new OpuBuilder()
901                                         .setExpPayloadType(PayloadTypeDef.getDefaultInstance("22"))
902                                         .setPayloadType(PayloadTypeDef.getDefaultInstance("22"))
903                                         .build())
904                                 .setTxSapi(portMapA.getLcpHashVal())
905                                 .setTxDapi(portMapZ.getLcpHashVal())
906                                 .setExpectedSapi(portMapZ.getLcpHashVal())
907                                 .setExpectedDapi(portMapZ.getLcpHashVal())
908                                 .build())
909                         .build());
910         // Post interface on the device
911         openRoadmInterfaces.postInterface(anodeId, oduInterfaceBuilder);
912         // Post the equipment-state change on the device circuit-pack if xpdr node
913         if (portMapA.getLogicalConnectionPoint().contains(StringConstants.NETWORK_TOKEN)) {
914             this.openRoadmInterfaces.postEquipmentState(anodeId, portMapA.getSupportingCircuitPackName(), true);
915         }
916         // Update the port-mapping with the interface information
917         this.portMapping.updateMapping(anodeId, portMapA);
918         return oduInterfaceBuilder.getName();
919     }
920
921     // This creates the name of the interface with slot numbers at the end
922     public String createOpenRoadmOtsiInterfaceName(String logicalConnectionPoint, String spectralSlotName) {
923         return String.join(GridConstant.NAME_PARAMETERS_SEPARATOR, logicalConnectionPoint, spectralSlotName);
924     }
925
926     private InterfaceBuilder createGenericInterfaceBuilder(Mapping portMap, InterfaceType type, String key) {
927         return new org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.interfaces.grp.InterfaceBuilder()
928             .setDescription("  TBD   ")
929             .setCircuitId("   TBD    ")
930             .setSupportingCircuitPackName(portMap.getSupportingCircuitPackName())
931             .setSupportingPort(portMap.getSupportingPort())
932             .setAdministrativeState(AdminStates.InService)
933             .setType(type)
934             .setName(key)
935             .withKey(new InterfaceKey(key));
936     }
937
938     private int getServiceRate(ModulationFormat modulationFormat, SpectrumInformation spectrumInformation) {
939         switch (modulationFormat) {
940             case DpQpsk:
941             case DpQam16:
942                 // DpQpsk and DpQam16 are possible for both 31.6 or 63.1 GBaud, for which spectral width is different
943                 // Here take the difference of highest and lowest spectral numbers and determine the width
944                 double spectralWidth = (spectrumInformation.getHigherSpectralSlotNumber()
945                     - spectrumInformation.getLowerSpectralSlotNumber() + 1) * GridConstant.GRANULARITY;
946                 LOG.info("The width with guard band {}", spectralWidth);
947                 if (spectralWidth == 50.0) {
948                     LOG.info("The baud-rate is 31.6 GBaud");
949                     return Map.of(
950                             ModulationFormat.DpQpsk , 100,
951                             ModulationFormat.DpQam16 , 200)
952                         .get(modulationFormat);
953                     // Based on roll-of-factor of 0.2, 50 - 12.5 = 37.5GHz translates to 31.6 GBaud
954                 }
955                 LOG.info("The baud-rate is 63.1 GBaud");
956                 Map<ModulationFormat, Integer> rateMap = Map.of(
957                         ModulationFormat.DpQpsk , 200,
958                         ModulationFormat.DpQam16 , 400);
959                 // Based on roll-of-factor of 0.2, 87.5 - 12.5 = 75GHz translates to 63.1 GBaud
960                 int rate = rateMap.get(modulationFormat);
961                 LOG.info("Given modulation format {} rate is {}", modulationFormat, rate);
962                 return rate;
963             case DpQam8:
964                 LOG.info("Given modulation format DpQam8 rate is 300");
965                 return 300;
966             default:
967                 LOG.error(RATE_EXCEPTION_MESSAGE + " for modulation format {}", modulationFormat);
968                 return 0;
969         }
970     }
971 }