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