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