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