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