Refactor common CatalogUtils step 1
[transportpce.git] / common / src / main / java / org / opendaylight / transportpce / common / catalog / CatalogUtils.java
index 0fab6def1715489f97279530ca061cfb1560f279..3fb21cf3a2742fdbf60781a22ea4db85d6bcf6a9 100644 (file)
@@ -14,6 +14,7 @@ import java.util.concurrent.ExecutionException;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.transportpce.common.StringConstants;
 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.link.types.rev191129.RatioDB;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.operational.mode.catalog.rev211210.ImpairmentType;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.operational.mode.catalog.rev211210.operational.mode.amplifier.parameters.Amplifier;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.operational.mode.catalog.rev211210.operational.mode.catalog.OpenroadmOperationalModes;
@@ -51,6 +52,23 @@ import org.slf4j.LoggerFactory;
 public class CatalogUtils {
 
     private static final Logger LOG = LoggerFactory.getLogger(CatalogUtils.class);
+
+    private static final String OPMODE_MISMATCH_MSG =
+        "Operational Mode {} passed to getPceRoadmAmpParameters does not correspond to an OpenROADM mode"
+        + "Parameters for amplifier and/or ROADMs can not be derived from specific-operational-modes.";
+    private static final Map<CatalogConstant.CatalogNodeType, String> CATALOGNODETYPE_OPERATIONMODEID_MAP = Map.of(
+        CatalogConstant.CatalogNodeType.ADD, CatalogConstant.MWWRCORE,
+        CatalogConstant.CatalogNodeType.DROP, CatalogConstant.MWWRCORE,
+        CatalogConstant.CatalogNodeType.EXPRESS, CatalogConstant.MWMWCORE,
+        CatalogConstant.CatalogNodeType.AMP, CatalogConstant.MWISTANDARD);
+    private static final Map<String, String> TSP_DEFAULT_OM_MAP = Map.of(
+        StringConstants.SERVICE_TYPE_100GE_T, CatalogConstant.ORW100GSC,
+        StringConstants.SERVICE_TYPE_OTU4, CatalogConstant.ORW100GSC,
+        StringConstants.SERVICE_TYPE_OTUC2,  CatalogConstant.ORW200GOFEC316GBD,
+        StringConstants.SERVICE_TYPE_OTUC3, CatalogConstant.ORW300GOFEC631GBD,
+        StringConstants.SERVICE_TYPE_OTUC4, CatalogConstant.ORW400GOFEC631GBD,
+        StringConstants.SERVICE_TYPE_400GE, CatalogConstant.ORW400GOFEC631GBD);
+
     private final PenaltiesComparator penaltiesComparator = new PenaltiesComparator();
     private NetworkTransactionService networkTransactionService;
 
@@ -71,40 +89,18 @@ public class CatalogUtils {
      */
     public String getPceTxTspOperationalModeFromServiceType(CatalogConstant.CatalogNodeType catalogNodeType,
             String serviceType) {
-        String operationalModeId = "";
-
-        switch (catalogNodeType) {
-            case ADD:
-            case DROP:
-                operationalModeId = CatalogConstant.MWWRCORE;
-                break;
-            case EXPRESS:
-                operationalModeId = CatalogConstant.MWMWCORE;
-                break;
-            case AMP:
-                operationalModeId = CatalogConstant.MWISTANDARD;
-                break;
-            case TSP:
-                if (StringConstants.SERVICE_TYPE_100GE_T.contentEquals(serviceType)
-                        || StringConstants.SERVICE_TYPE_OTU4.contentEquals(serviceType)) {
-                    operationalModeId = CatalogConstant.ORW100GSC;
-                }
-                if (StringConstants.SERVICE_TYPE_OTUC2.contentEquals(serviceType)) {
-                    operationalModeId = CatalogConstant.ORW200GOFEC316GBD;
-                }
-                if (StringConstants.SERVICE_TYPE_OTUC3.contentEquals(serviceType)) {
-                    operationalModeId = CatalogConstant.ORW300GOFEC631GBD;
-                }
-                if ((StringConstants.SERVICE_TYPE_OTUC4.contentEquals(serviceType))
-                        || (StringConstants.SERVICE_TYPE_400GE.contentEquals(serviceType))) {
-                    operationalModeId = CatalogConstant.ORW400GOFEC631GBD;
-                }
-                break;
-            default:
-                LOG.warn("Unsupported catalogNodeType {}", catalogNodeType);
-                break;
+        if (CATALOGNODETYPE_OPERATIONMODEID_MAP.containsKey(catalogNodeType)) {
+            return CATALOGNODETYPE_OPERATIONMODEID_MAP.get(catalogNodeType);
         }
-        return operationalModeId;
+        if (!catalogNodeType.equals(CatalogConstant.CatalogNodeType.TSP)) {
+            LOG.warn("Unsupported catalogNodeType {}", catalogNodeType);
+            return "";
+        }
+        if (!TSP_DEFAULT_OM_MAP.containsKey(serviceType)) {
+            LOG.warn("Unsupported serviceType {} for TSP catalogNodeType", serviceType);
+            return "";
+        }
+        return TSP_DEFAULT_OM_MAP.get(serviceType);
     }
 
     /**
@@ -120,11 +116,8 @@ public class CatalogUtils {
      */
 
     public double getPceTxTspChannelSpacing(String operationalModeId) {
-        double spacing = 0.0;
-        double rolloff = 0.2;
-        XponderPluggableOpenroadmOperationalMode orTspOM = null;
-        SpecificOperationalMode speTspOM = null;
-
+        double baudRate;
+        double maxRollOff;
         if (operationalModeId.startsWith("OR")) {
             InstanceIdentifier<XponderPluggableOpenroadmOperationalMode> omCatalogIid = InstanceIdentifier
                 .builder(OperationalModeCatalog.class)
@@ -134,40 +127,21 @@ public class CatalogUtils {
                     new XponderPluggableOpenroadmOperationalModeKey(operationalModeId))
                 .build();
             try {
-                Optional<XponderPluggableOpenroadmOperationalMode> omOptional = networkTransactionService
-                    .read(LogicalDatastoreType.CONFIGURATION, omCatalogIid).get();
-                if (omOptional.isPresent()) {
-                    orTspOM = omOptional.get();
-                    if ((orTspOM.getMaxRollOff() == null) || (orTspOM.getMaxRollOff().doubleValue() == 0)) {
-                        if (CatalogConstant.ORW100GSC.contentEquals(operationalModeId)) {
-                            spacing = 50.0;
-                            LOG.info("Operational Mode {} associated channel spacing is {}",
-                                operationalModeId, spacing);
-
-                        } else {
-                            spacing = (Math.ceil(
-                                orTspOM.getBaudRate().doubleValue() * (1 + 0.2) / 12.5)) * 12.5;
-                            LOG.warn("Did not succeed in retrieving rolloff factor from Operational Mode {},"
-                                + " used default value of 0.2  --> Please check operational mode catalog,"
-                                + " Rolloff factor is a mandatory parameter", operationalModeId);
-                        }
-                    } else {
-                        spacing = (Math.ceil(
-                            orTspOM.getBaudRate().doubleValue() * (1 + orTspOM.getMaxRollOff().doubleValue()) / 12.5))
-                            * 12.5;
-                    }
-                    LOG.info("Operational Mode {} associated channel spacing is {}",
-                        operationalModeId, spacing);
+                Optional<XponderPluggableOpenroadmOperationalMode> omOptional =
+                    networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, omCatalogIid).get();
+                if (omOptional.isEmpty()) {
+                    LOG.error("readMdSal: Error reading Operational Mode Catalog {} , empty list", omCatalogIid);
+                    return 0.0;
                 }
+                XponderPluggableOpenroadmOperationalMode orTspOM = omOptional.get();
+                maxRollOff = orTspOM.getMaxRollOff() == null ? 0 : orTspOM.getMaxRollOff().doubleValue();
+                baudRate = orTspOM.getBaudRate().doubleValue();
             } catch (InterruptedException | ExecutionException e) {
                 LOG.error("readMdSal: Error reading Operational Mode Catalog {} , Mode does not exist", omCatalogIid);
-                throw new RuntimeException(
-                    "Operational mode not populated in Catalog : "
-                        + omCatalogIid + " :" + e);
+                throw new RuntimeException("Operational mode not populated in Catalog : " + omCatalogIid + " :" + e);
             } finally {
                 networkTransactionService.close();
             }
-
         } else {
             // In other cases, means the mode is a non OpenROADM specific Operational Mode
             InstanceIdentifier<SpecificOperationalMode> omCatalogIid = InstanceIdentifier
@@ -176,32 +150,34 @@ public class CatalogUtils {
                 .child(SpecificOperationalMode.class, new SpecificOperationalModeKey(operationalModeId))
                 .build();
             try {
-                var somOptional = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, omCatalogIid)
-                    .get();
-                if (somOptional.isPresent()) {
-                    speTspOM = somOptional.get();
-                    if ((speTspOM.getMaxRollOff() == null) || (speTspOM.getMaxRollOff().doubleValue() == 0)) {
-                        spacing = (Math.ceil(speTspOM.getBaudRate().doubleValue() * (1 + 0.2) / 12.5)) * 12.5;
-                        LOG.warn("Did not succeed in retrieving rolloff factor from Operational Mode {},"
-                            + " used default value of 0.2  --> Please check operational mode catalog,"
-                            + " Rolloff factor is a mandatory parameter", operationalModeId);
-                    } else {
-                        spacing = (Math.ceil(
-                            speTspOM.getBaudRate().doubleValue() * (1 + speTspOM.getMaxRollOff().doubleValue()) / 12.5))
-                            * 12.5;
-                    }
-                    LOG.info("Operational Mode {} associated channel spacing is {}",
-                        operationalModeId, spacing);
+                var somOptional =
+                    networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, omCatalogIid).get();
+                if (somOptional.isEmpty()) {
+                    LOG.error("readMdSal: Error reading Operational Mode Catalog {} , empty list", omCatalogIid);
+                    return 0.0;
                 }
+                SpecificOperationalMode speTspOM = somOptional.get();
+                maxRollOff = speTspOM.getMaxRollOff() == null ? 0 : speTspOM.getMaxRollOff().doubleValue();
+                baudRate = speTspOM.getBaudRate().doubleValue();
             } catch (InterruptedException | ExecutionException e) {
                 LOG.error("readMdSal: Error reading Operational Mode Catalog {} , Mode does not exist", omCatalogIid);
-                throw new RuntimeException(
-                    "Operational mode not populated in Catalog : "
-                        + omCatalogIid + " :" + e);
+                throw new RuntimeException("Operational mode not populated in Catalog : " + omCatalogIid + " :" + e);
             } finally {
                 networkTransactionService.close();
             }
         }
+        if (maxRollOff == 0) {
+            if (CatalogConstant.ORW100GSC.contentEquals(operationalModeId)) {
+            // OR 100G SCFEC is the only case where rolloff factor is not mandatory in the catalog
+                LOG.info("Operational Mode {} associated channel spacing is 50.0", operationalModeId);
+                return 50.0;
+            }
+            LOG.warn("Missing rolloff factor (mandatory in Catalog) from Operational Mode {}: use default=0.2",
+                operationalModeId);
+            maxRollOff = 0.2;
+        }
+        double spacing = 12.5 * Math.ceil(baudRate * (1 + maxRollOff) / 12.5);
+        LOG.info("Operational Mode {} associated channel spacing is {}", operationalModeId, spacing);
         return spacing;
     }
 
@@ -222,7 +198,8 @@ public class CatalogUtils {
         double txOnsrLin = 0.0;
         XponderPluggableOpenroadmOperationalMode orTspOM = null;
         SpecificOperationalMode speTspOM = null;
-
+        RatioDB minOOBOsnrSingleChannelValue;
+        RatioDB minOOBOsnrMultiChannelValue;
         if (operationalModeId.startsWith("OR")) {
             InstanceIdentifier<XponderPluggableOpenroadmOperationalMode> omCatalogIid = InstanceIdentifier
                 .builder(OperationalModeCatalog.class)
@@ -232,38 +209,31 @@ public class CatalogUtils {
                     new XponderPluggableOpenroadmOperationalModeKey(operationalModeId))
                 .build();
             try {
-                Optional<XponderPluggableOpenroadmOperationalMode> omOptional = networkTransactionService
-                    .read(LogicalDatastoreType.CONFIGURATION, omCatalogIid).get();
-                if (omOptional.isPresent()) {
-                    orTspOM = omOptional.get();
-                    LOG.debug("readMdSal: Operational Mode Catalog: omOptional.isPresent = true {}", orTspOM);
-                    TXOOBOsnrKey key = new TXOOBOsnrKey(addDropMuxOperationalModeId);
-                    if (orTspOM.getMinTXOsnr() != null) {
-                        txOnsrLin = 1.0 / (Math.pow(10.0, (orTspOM.getMinTXOsnr().getValue().doubleValue() / 10.0)));
-                    }
-                    if (orTspOM.nonnullTXOOBOsnr().get(key) != null
-                            && orTspOM.nonnullTXOOBOsnr().get(key).getMinOOBOsnrSingleChannelValue() != null) {
-                        // To 1/(Xponder Min TX OSNR lin) Add 1/(Xponder TX OOB OSNR Single channel lin)
-                        txOnsrLin = txOnsrLin + 1.0 / (Math.pow(10.0, (orTspOM.nonnullTXOOBOsnr().get(key)
-                            .getMinOOBOsnrSingleChannelValue().getValue().doubleValue() / 10.0)));
-                    }
-                    if (orTspOM.getTXOOBOsnr() != null && orTspOM.nonnullTXOOBOsnr().get(key)
-                            .getMinOOBOsnrMultiChannelValue() != null) {
-                        // To resulting 1/(OSNR lin) Add 1/(Xponder TX OOB OSNR Multi channel lin)
-                        // contribution
-                        txOnsrLin = txOnsrLin + 1.0 / (Math.pow(10.0, (orTspOM.nonnullTXOOBOsnr().get(key)
-                            .getMinOOBOsnrMultiChannelValue().getValue().doubleValue() / 10.0)));
-                    }
+                Optional<XponderPluggableOpenroadmOperationalMode> omOptional =
+                    networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, omCatalogIid).get();
+                if (omOptional.isEmpty()) {
+                    LOG.error("readMdSal: Error reading Operational Mode Catalog {} , empty list", omCatalogIid);
+                    return 0.0;
                 }
+                orTspOM = omOptional.get();
+                LOG.debug("readMdSal: Operational Mode Catalog: omOptional.isPresent = true {}", orTspOM);
+                TXOOBOsnrKey key = new TXOOBOsnrKey(addDropMuxOperationalModeId);
+                if (orTspOM.getMinTXOsnr() != null) {
+                    txOnsrLin = 1.0 / Math.pow(10.0, orTspOM.getMinTXOsnr().getValue().doubleValue() / 10.0);
+                }
+                if (orTspOM.nonnullTXOOBOsnr().get(key) == null) {
+                    return txOnsrLin;
+                }
+                minOOBOsnrSingleChannelValue = orTspOM.nonnullTXOOBOsnr().get(key).getMinOOBOsnrSingleChannelValue();
+                minOOBOsnrMultiChannelValue =  orTspOM.nonnullTXOOBOsnr().get(key).getMinOOBOsnrMultiChannelValue();
             } catch (InterruptedException | ExecutionException e) {
                 LOG.error("readMdSal: Error reading Operational Mode Catalog {} , Mode does not exist", omCatalogIid);
                 throw new RuntimeException(
-                    "readMdSal: Error reading from operational store, Operational Mode Catalog : " + omCatalogIid + " :"
-                        + e);
+                    "readMdSal: Error reading from operational store, Operational Mode Catalog : "
+                        + omCatalogIid + " :" + e);
             } finally {
                 networkTransactionService.close();
             }
-
         } else {
             // In other cases, means the mode is a non OpenROADM specific Operational Mode
             InstanceIdentifier<SpecificOperationalMode> omCatalogIid = InstanceIdentifier
@@ -272,30 +242,23 @@ public class CatalogUtils {
                 .child(SpecificOperationalMode.class, new SpecificOperationalModeKey(operationalModeId))
                 .build();
             try {
-                var somOptional = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, omCatalogIid)
-                    .get();
-                if (somOptional.isPresent()) {
-                    speTspOM = somOptional.get();
-                    LOG.debug("readMdSal: Operational Mode Catalog: omOptional.isPresent = true {}", speTspOM);
-                    TXOOBOsnrKey key = new TXOOBOsnrKey(addDropMuxOperationalModeId);
-                    if (speTspOM.getMinTXOsnr() != null) {
-                        txOnsrLin = 1.0 / (Math.pow(10.0, (speTspOM.getMinTXOsnr().getValue().doubleValue() / 10.0)));
-                    }
-                    if (speTspOM.nonnullTXOOBOsnr().get(key) != null
-                            && speTspOM.nonnullTXOOBOsnr().get(key).getMinOOBOsnrSingleChannelValue() != null) {
-                        // Add to 1/(Transponder Min TX OSNR lin) 1/(Transponder TX OOB OSNR Single
-                        // channel lin)
-                        txOnsrLin = txOnsrLin + 1.0 / (Math.pow(10.0, (speTspOM.nonnullTXOOBOsnr().get(key)
-                            .getMinOOBOsnrSingleChannelValue().getValue().doubleValue() / 10.0)));
-                    }
-                    if (speTspOM.nonnullTXOOBOsnr().get(key) != null
-                            && speTspOM.nonnullTXOOBOsnr().get(key).getMinOOBOsnrMultiChannelValue() != null) {
-                        // Add to resulting 1/(OSNR lin) 1/(Transponder TX OOB OSNR Multi channel lin)
-                        // contribution
-                        txOnsrLin = txOnsrLin + 1.0 / (Math.pow(10.0, (speTspOM.nonnullTXOOBOsnr().get(key)
-                            .getMinOOBOsnrMultiChannelValue().getValue().doubleValue() / 10.0)));
-                    }
+                var somOptional =
+                    networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, omCatalogIid).get();
+                if (somOptional.isEmpty()) {
+                    LOG.error("readMdSal: Error reading Operational Mode Catalog {} , empty list", omCatalogIid);
+                    return 0.0;
+                }
+                speTspOM = somOptional.get();
+                LOG.debug("readMdSal: Operational Mode Catalog: omOptional.isPresent = true {}", speTspOM);
+                TXOOBOsnrKey key = new TXOOBOsnrKey(addDropMuxOperationalModeId);
+                if (speTspOM.getMinTXOsnr() != null) {
+                    txOnsrLin = 1.0 / Math.pow(10.0, speTspOM.getMinTXOsnr().getValue().doubleValue() / 10.0);
                 }
+                if (speTspOM.nonnullTXOOBOsnr().get(key) == null) {
+                    return txOnsrLin;
+                }
+                minOOBOsnrSingleChannelValue = speTspOM.nonnullTXOOBOsnr().get(key).getMinOOBOsnrSingleChannelValue();
+                minOOBOsnrMultiChannelValue = speTspOM.nonnullTXOOBOsnr().get(key).getMinOOBOsnrMultiChannelValue();
             } catch (InterruptedException | ExecutionException e) {
                 LOG.error("readMdSal: Error reading Operational Mode Catalog {} , Mode does not exist", omCatalogIid);
                 throw new RuntimeException(
@@ -305,6 +268,12 @@ public class CatalogUtils {
                 networkTransactionService.close();
             }
         }
+        if (minOOBOsnrSingleChannelValue != null) {
+            txOnsrLin += 1.0 / Math.pow(10.0, minOOBOsnrSingleChannelValue.getValue().doubleValue() / 10.0);
+        }
+        if (minOOBOsnrMultiChannelValue != null) {
+            txOnsrLin += 1.0 / Math.pow(10.0, minOOBOsnrMultiChannelValue.getValue().doubleValue() / 10.0);
+        }
         return txOnsrLin;
     }
 
@@ -332,11 +301,7 @@ public class CatalogUtils {
      */
     public double getPceRxTspParameters(String operationalModeId, double calcCd, double calcPmd,
             double calcPdl, double calcOsnrdB) {
-        HashMap<String, Double> impairments = new HashMap<>();
-        double totalPenalty = 0.0;
-        double penalty ;
         double rxOsnrdB = 0.0;
-        double margin = -9999.9;
         XponderPluggableOpenroadmOperationalMode orTspOM = null;
         SpecificOperationalMode speTspOM = null;
         Map<PenaltiesKey, Penalties> penaltiesMap = null;
@@ -395,34 +360,35 @@ public class CatalogUtils {
                 networkTransactionService.close();
             }
         }
-        if (penaltiesMap != null) {
-            penalty = getRxTspPenalty(calcCd, ImpairmentType.CDPsNm, penaltiesMap);
-            impairments.put("CDpenalty", penalty);
-            totalPenalty = totalPenalty + penalty;
-            penalty = getRxTspPenalty(calcPmd, ImpairmentType.PMDPs, penaltiesMap);
-            impairments.put("PMD Penalty", penalty);
-            totalPenalty = totalPenalty + penalty;
-            penalty = getRxTspPenalty(calcPdl, ImpairmentType.PDLDB, penaltiesMap);
-            impairments.put("PDL penalty", penalty);
-            totalPenalty = totalPenalty + penalty;
-            // For Future work since at that time we have no way to calculate the following
-            // parameters,even if penalties are defined in the OpenROADM specifications
-            //
-            // impairments.put("Colorless Drop Adjacent Xtalk Penalty", getRxTspPenalty(TBD,
-            // ImpairmentType.ColorlessDropAdjacentChannelCrosstalkGHz, penalitiesMap));
-            // impairments.put("XTalk total Power Penalty", getRxTspPenalty(TBD,
-            // ImpairmentType.CrossTalkTotalPowerDB, penalitiesMap));
-            // impairments.put("Power penalty", getRxTspPenalty(TBD,
-            // ImpairmentType.PowerDBm, penalitiesMap));
-            LOG.info("Penalty resulting from CD, PMD and PDL is {} dB with following contributions {}",
-                totalPenalty, impairments);
-            margin = calcOsnrdB - totalPenalty - rxOsnrdB;
-            LOG.info("According to RX TSP Specification and calculated impairments Margin is {} dB ", margin);
-            if (margin < 0) {
-                LOG.info("Negative margin shall result in PCE rejecting the analyzed path");
-            }
-        } else {
-            LOG.info("Unable to calculate margin as penaltyMap can not be retrieved : Operational mode not populated");
+        if (penaltiesMap == null) {
+            LOG.error("Unable to calculate margin as penaltyMap can not be retrieved : Operational mode not populated");
+            return -9999.9;
+        }
+        HashMap<String, Double> impairments = new HashMap<>();
+        double penalty = getRxTspPenalty(calcCd, ImpairmentType.CDPsNm, penaltiesMap);
+        impairments.put("CDpenalty", penalty);
+        double totalPenalty = penalty;
+        penalty = getRxTspPenalty(calcPmd, ImpairmentType.PMDPs, penaltiesMap);
+        impairments.put("PMD Penalty", penalty);
+        totalPenalty += penalty;
+        penalty = getRxTspPenalty(calcPdl, ImpairmentType.PDLDB, penaltiesMap);
+        impairments.put("PDL penalty", penalty);
+        totalPenalty += penalty;
+        // TODO for Future work since at that time we have no way to calculate the following
+        // parameters,even if penalties are defined in the OpenROADM specifications
+        //
+        // impairments.put("Colorless Drop Adjacent Xtalk Penalty", getRxTspPenalty(TBD,
+        // ImpairmentType.ColorlessDropAdjacentChannelCrosstalkGHz, penalitiesMap));
+        // impairments.put("XTalk total Power Penalty", getRxTspPenalty(TBD,
+        // ImpairmentType.CrossTalkTotalPowerDB, penalitiesMap));
+        // impairments.put("Power penalty", getRxTspPenalty(TBD,
+        // ImpairmentType.PowerDBm, penalitiesMap));
+        LOG.info("Penalty resulting from CD, PMD and PDL is {} dB with following contributions {}",
+            totalPenalty, impairments);
+        double margin = calcOsnrdB - totalPenalty - rxOsnrdB;
+        LOG.info("According to RX TSP Specification and calculated impairments Margin is {} dB ", margin);
+        if (margin < 0) {
+            LOG.warn("Negative margin shall result in PCE rejecting the analyzed path");
         }
         return margin;
     }
@@ -447,7 +413,7 @@ public class CatalogUtils {
      */
 
     private double getRxTspPenalty(double calculatedParameter, ImpairmentType impairmentType,
-        Map<PenaltiesKey, Penalties> penalitiesMap) {
+            Map<PenaltiesKey, Penalties> penalitiesMap) {
         Penalties penalty = penalitiesMap.values().stream()
             // We only keep penalties corresponding to the calculated Parameter
             .filter(val -> val.getParameterAndUnit().getName().equals(impairmentType.getName()))
@@ -457,14 +423,12 @@ public class CatalogUtils {
             .filter(val -> val.getUpToBoundary().doubleValue() >= calculatedParameter)
             // takes the immediate greater or equal value
             .findFirst().orElse(null);
-
-        if (penalty == null) {
+        return penalty == null
             //means a boundary that is greater than calculatedParameter couldn't be found
             // Out of specification!
-            return 9999.9;
-        }
-        // In spec, return penalty associated with calculatedParameter
-        return penalty.getPenaltyValue().getValue().doubleValue();
+                ? 9999.9
+            // In spec, return penalty associated with calculatedParameter
+                : penalty.getPenaltyValue().getValue().doubleValue();
     }
 
     /**
@@ -504,16 +468,13 @@ public class CatalogUtils {
      */
 
     public Map<String, Double> getPceRoadmAmpParameters(CatalogConstant.CatalogNodeType catalogNodeType,
-        String operationalModeId, double pwrIn, double calcCd, double calcDgd2, double calcPdl2,
-        double calcOnsrLin, double spacing) {
-
-        Map<String, Double> impairments = new HashMap<>();
+            String operationalModeId, double pwrIn, double calcCd, double calcDgd2, double calcPdl2,
+            double calcOnsrLin, double spacing) {
+        //TODO more refactoring need here
         double pdl2 = calcPdl2;
         double dgd2 = calcDgd2;
         double cd = calcCd;
         double onsrLin = calcOnsrLin;
-        boolean supportedMode = true;
-
         switch (catalogNodeType) {
             case ADD:
                 var omCatalogIid = InstanceIdentifier
@@ -524,21 +485,21 @@ public class CatalogUtils {
                     .child(AddOpenroadmOperationalMode.class, new AddOpenroadmOperationalModeKey(operationalModeId))
                     .build();
                 try {
-                    var omOptional = networkTransactionService.read(LogicalDatastoreType.CONFIGURATION,
-                        omCatalogIid).get();
-                    if (omOptional.isPresent()) {
-                        var orAddOM = omOptional.get();
-                        LOG.debug("readMdSal: Operational Mode Catalog: omOptional.isPresent = true {}", orAddOM);
-                        networkTransactionService.close();
-                        onsrLin = onsrLin
-                            + Math.pow(10, (-orAddOM.getIncrementalOsnr().getValue().doubleValue()
-                            - Math.log10(spacing / 50.0)) / 10.0);
-                        cd = cd + orAddOM.getMaxIntroducedCd().doubleValue();
-                        pdl2 = pdl2 + Math.pow(orAddOM.getMaxIntroducedPdl().getValue().doubleValue(), 2.0);
-                        dgd2 = dgd2 + Math.pow(orAddOM.getMaxIntroducedDgd().doubleValue(), 2.0);
-                    } else {
-                        supportedMode = false;
+                    var omOptional =
+                        networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, omCatalogIid).get();
+                    if (omOptional.isEmpty()) {
+                        LOG.error(OPMODE_MISMATCH_MSG, operationalModeId);
+                        return new HashMap<>();
                     }
+                    var orAddOM = omOptional.get();
+                    LOG.debug("readMdSal: Operational Mode Catalog: omOptional.isPresent = true {}", orAddOM);
+                    networkTransactionService.close();
+                    onsrLin +=
+                        + Math.pow(10, (-orAddOM.getIncrementalOsnr().getValue().doubleValue()
+                        - Math.log10(spacing / 50.0)) / 10.0);
+                    cd += orAddOM.getMaxIntroducedCd().doubleValue();
+                    pdl2 += Math.pow(orAddOM.getMaxIntroducedPdl().getValue().doubleValue(), 2.0);
+                    dgd2 += Math.pow(orAddOM.getMaxIntroducedDgd().doubleValue(), 2.0);
                 } catch (InterruptedException | ExecutionException e) {
                     onsrLin = 1;
                     LOG.error("readMdSal: Error reading Operational Mode Catalog {} , Mode does not exist",
@@ -560,28 +521,25 @@ public class CatalogUtils {
                     .child(OpenroadmOperationalMode.class, new OpenroadmOperationalModeKey(operationalModeId))
                     .build();
                 try {
-                    var omOptional = networkTransactionService
-                        .read(LogicalDatastoreType.CONFIGURATION, omCatalogIid1)
-                        .get();
-                    if (omOptional.isPresent()) {
-                        var orDropOM = omOptional.get();
-                        LOG.debug("readMdSal: Operational Mode Catalog: omOptional.isPresent = true {}", orDropOM);
-                        networkTransactionService.close();
-                        cd = cd + orDropOM.getMaxIntroducedCd().doubleValue();
-                        pdl2 = pdl2 + Math.pow(orDropOM.getMaxIntroducedPdl().getValue().doubleValue(), 2.0);
-                        dgd2 = dgd2 + Math.pow(orDropOM.getMaxIntroducedDgd().doubleValue(), 2);
-                        onsrLin = onsrLin + Math.pow(10,
-                            -(orDropOM.getOsnrPolynomialFit().getA().doubleValue() * Math.pow(pwrIn, 3)
-                                + orDropOM.getOsnrPolynomialFit().getB().doubleValue() * Math.pow(pwrIn, 2)
-                                + orDropOM.getOsnrPolynomialFit().getC().doubleValue() * pwrIn
-                                + orDropOM.getOsnrPolynomialFit().getD().doubleValue()
-                                + 10 * Math.log10(spacing / 50.0)) / 10);
-                    } else {
-                        supportedMode = false;
+                    var omOptional =
+                        networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, omCatalogIid1).get();
+                    if (omOptional.isEmpty()) {
+                        LOG.error(OPMODE_MISMATCH_MSG, operationalModeId);
+                        return new HashMap<>();
                     }
+                    var orDropOM = omOptional.get();
+                    LOG.debug("readMdSal: Operational Mode Catalog: omOptional.isPresent = true {}", orDropOM);
+                    networkTransactionService.close();
+                    cd += orDropOM.getMaxIntroducedCd().doubleValue();
+                    pdl2 += Math.pow(orDropOM.getMaxIntroducedPdl().getValue().doubleValue(), 2.0);
+                    dgd2 += Math.pow(orDropOM.getMaxIntroducedDgd().doubleValue(), 2);
+                    onsrLin += Math.pow(10,
+                        -(orDropOM.getOsnrPolynomialFit().getA().doubleValue() * Math.pow(pwrIn, 3)
+                            + orDropOM.getOsnrPolynomialFit().getB().doubleValue() * Math.pow(pwrIn, 2)
+                            + orDropOM.getOsnrPolynomialFit().getC().doubleValue() * pwrIn
+                            + orDropOM.getOsnrPolynomialFit().getD().doubleValue()
+                            + 10 * Math.log10(spacing / 50.0)) / 10);
                 } catch (InterruptedException | ExecutionException e) {
-                    onsrLin = 1;
-                    supportedMode = false;
                     LOG.error("readMdSal: Error reading Operational Mode Catalog {} , Mode does not exist",
                         omCatalogIid1);
                     throw new RuntimeException(
@@ -600,36 +558,33 @@ public class CatalogUtils {
                     .child(Express.class)
                     .child(
                         org.opendaylight.yang.gen.v1.http
-                        .org.openroadm.operational.mode.catalog.rev211210
-                        .operational.mode.roadm.express.parameters.express.OpenroadmOperationalMode.class,
+                            .org.openroadm.operational.mode.catalog.rev211210
+                            .operational.mode.roadm.express.parameters.express.OpenroadmOperationalMode.class,
                         new org.opendaylight.yang.gen.v1.http
-                        .org.openroadm.operational.mode.catalog.rev211210
-                        .operational.mode.roadm.express.parameters.express.OpenroadmOperationalModeKey(
-                            operationalModeId))
+                            .org.openroadm.operational.mode.catalog.rev211210
+                            .operational.mode.roadm.express.parameters.express.OpenroadmOperationalModeKey(
+                                operationalModeId))
                     .build();
                 try {
                     var omOptional = networkTransactionService
                         .read(LogicalDatastoreType.CONFIGURATION, omCatalogIid2)
                         .get();
-                    if (omOptional.isPresent()) {
-                        var orExpressOM = omOptional.get();
-                        LOG.debug("readMdSal: Operational Mode Catalog: omOptional.isPresent = true {}",
-                            orExpressOM);
-                        cd = cd + orExpressOM.getMaxIntroducedCd().doubleValue();
-                        pdl2 = pdl2 + Math.pow(orExpressOM.getMaxIntroducedPdl().getValue().doubleValue(), 2.0);
-                        dgd2 = dgd2 + Math.pow(orExpressOM.getMaxIntroducedDgd().doubleValue(), 2.0);
-                        onsrLin = onsrLin + Math.pow(10,
-                            -(orExpressOM.getOsnrPolynomialFit().getA().doubleValue() * Math.pow(pwrIn, 3)
-                                + orExpressOM.getOsnrPolynomialFit().getB().doubleValue() * Math.pow(pwrIn, 2)
-                                + orExpressOM.getOsnrPolynomialFit().getC().doubleValue() * pwrIn
-                                + orExpressOM.getOsnrPolynomialFit().getD().doubleValue()
-                                + 10 * Math.log10(spacing / 50.0)) / 10);
-                    } else {
-                        supportedMode = false;
+                    if (omOptional.isEmpty()) {
+                        LOG.error(OPMODE_MISMATCH_MSG, operationalModeId);
+                        return new HashMap<>();
                     }
+                    var orExpressOM = omOptional.get();
+                    LOG.debug("readMdSal: Operational Mode Catalog: omOptional.isPresent = true {}", orExpressOM);
+                    cd += orExpressOM.getMaxIntroducedCd().doubleValue();
+                    pdl2 += Math.pow(orExpressOM.getMaxIntroducedPdl().getValue().doubleValue(), 2.0);
+                    dgd2 += Math.pow(orExpressOM.getMaxIntroducedDgd().doubleValue(), 2.0);
+                    onsrLin += Math.pow(10,
+                        -(orExpressOM.getOsnrPolynomialFit().getA().doubleValue() * Math.pow(pwrIn, 3)
+                            + orExpressOM.getOsnrPolynomialFit().getB().doubleValue() * Math.pow(pwrIn, 2)
+                            + orExpressOM.getOsnrPolynomialFit().getC().doubleValue() * pwrIn
+                            + orExpressOM.getOsnrPolynomialFit().getD().doubleValue()
+                            + 10 * Math.log10(spacing / 50.0)) / 10);
                 } catch (InterruptedException | ExecutionException e) {
-                    onsrLin = 1;
-                    supportedMode = false;
                     LOG.error("readMdSal: Error reading Operational Mode Catalog {} , Mode does not exist",
                         omCatalogIid2);
                     throw new RuntimeException(
@@ -652,26 +607,23 @@ public class CatalogUtils {
                     var omOptional = networkTransactionService
                         .read(LogicalDatastoreType.CONFIGURATION, omCatalogIid3)
                         .get();
-                    if (omOptional.isPresent()) {
-                        var orAmpOM = omOptional.get();
-                        LOG.debug("readMdSal: Operational Mode Catalog: omOptional.isPresent = true {}", orAmpOM);
-                        networkTransactionService.close();
-                        cd = cd + orAmpOM.getMaxIntroducedCd().doubleValue();
-                        pdl2 = pdl2 + Math.pow(orAmpOM.getMaxIntroducedPdl().getValue().doubleValue(), 2.0);
-                        dgd2 = dgd2 + Math.pow(orAmpOM.getMaxIntroducedDgd().doubleValue(), 2.0);
-                        onsrLin = onsrLin + Math.pow(10,
-                            -(orAmpOM.getOsnrPolynomialFit().getA().doubleValue() * Math.pow(pwrIn, 3)
-                                + orAmpOM.getOsnrPolynomialFit().getB().doubleValue() * Math.pow(pwrIn, 2)
-                                + orAmpOM.getOsnrPolynomialFit().getC().doubleValue() * pwrIn
-                                + orAmpOM.getOsnrPolynomialFit().getD().doubleValue()
-                                + 10 * Math.log10(spacing / 50.0)) / 10);
-
-                    } else {
-                        supportedMode = false;
+                    if (omOptional.isEmpty()) {
+                        LOG.error(OPMODE_MISMATCH_MSG, operationalModeId);
+                        return new HashMap<>();
                     }
+                    var orAmpOM = omOptional.get();
+                    LOG.debug("readMdSal: Operational Mode Catalog: omOptional.isPresent = true {}", orAmpOM);
+                    networkTransactionService.close();
+                    cd += orAmpOM.getMaxIntroducedCd().doubleValue();
+                    pdl2 += Math.pow(orAmpOM.getMaxIntroducedPdl().getValue().doubleValue(), 2.0);
+                    dgd2 += Math.pow(orAmpOM.getMaxIntroducedDgd().doubleValue(), 2.0);
+                    onsrLin += Math.pow(10,
+                        -(orAmpOM.getOsnrPolynomialFit().getA().doubleValue() * Math.pow(pwrIn, 3)
+                            + orAmpOM.getOsnrPolynomialFit().getB().doubleValue() * Math.pow(pwrIn, 2)
+                            + orAmpOM.getOsnrPolynomialFit().getC().doubleValue() * pwrIn
+                            + orAmpOM.getOsnrPolynomialFit().getD().doubleValue()
+                            + 10 * Math.log10(spacing / 50.0)) / 10);
                 } catch (InterruptedException | ExecutionException e) {
-                    onsrLin = 1;
-                    supportedMode = false;
                     LOG.error("readMdSal: Error reading Operational Mode Catalog {} , Mode does not exist",
                         omCatalogIid3);
                     throw new RuntimeException(
@@ -685,22 +637,13 @@ public class CatalogUtils {
                 LOG.warn("Unsupported catalogNodeType {}", catalogNodeType);
                 break;
         }
-
-        if (supportedMode) {
-            impairments.put("CD", cd);
-            impairments.put("DGD2", dgd2);
-            impairments.put("PDL2", pdl2);
-            impairments.put("ONSRLIN", onsrLin);
-
-            LOG.info("Accumulated CD is {} ps, DGD2 is {} ps and PDL2 is {} dB", cd, Math.sqrt(dgd2), Math.sqrt(pdl2));
-            LOG.info("Resulting OSNR is {} dB", 10 * Math.log10(1 / onsrLin));
-
-        } else {
-            LOG.error("Operational Mode {} passed to getPceRoadmAmpParameters does not correspond to an OpenROADM mode"
-                + "Parameters for amplifier and/or ROADMs can not be derived from specific-operational-modes.",
-                operationalModeId);
-        }
-
+        Map<String, Double> impairments = new HashMap<>();
+        impairments.put("CD", cd);
+        impairments.put("DGD2", dgd2);
+        impairments.put("PDL2", pdl2);
+        impairments.put("ONSRLIN", onsrLin);
+        LOG.info("Accumulated CD is {} ps, DGD2 is {} ps and PDL2 is {} dB", cd, Math.sqrt(dgd2), Math.sqrt(pdl2));
+        LOG.info("Resulting OSNR is {} dB", 10 * Math.log10(1 / onsrLin));
         return impairments;
     }
 
@@ -726,27 +669,19 @@ public class CatalogUtils {
         double constanteC0 = 0 ;
         if (spacing > 162.5) {
             constanteC0 = CatalogConstant.NLCONSTANTC0GT1625;
-        }
-        else if (spacing > 112.5) {
+        } else if (spacing > 112.5) {
             constanteC0 = CatalogConstant.NLCONSTANTC0UPTO1625;
-        }
-        else if (spacing > 100.0) {
+        } else if (spacing > 100.0) {
             constanteC0 = CatalogConstant.NLCONSTANTC0UPTO1125;
-        }
-        else if (spacing > 87.5) {
+        } else if (spacing > 87.5) {
             constanteC0 = CatalogConstant.NLCONSTANTC0UPTO1000;
-        }
-        else {
+        } else {
             constanteC0 = CatalogConstant.NLCONSTANTC0UPTO875;
         }
-
-        double nonLinearOnsrContributionLin = Math.pow(10.0, -(launchedPowerdB * CatalogConstant.NLCONSTANTC1
-            + constanteC0
-            + CatalogConstant.NLCONSTANTCE * Math.exp(CatalogConstant.NLCONSTANTEX * spanLength)) / 10);
-        LOG.info(" OSNR Non Linear contribution is {} dB", launchedPowerdB * CatalogConstant.NLCONSTANTC1
-            + constanteC0
-            + CatalogConstant.NLCONSTANTCE * Math.exp(CatalogConstant.NLCONSTANTEX * spanLength));
-        return nonLinearOnsrContributionLin;
+        double nonLinearOnsrContributionLinDb = launchedPowerdB * CatalogConstant.NLCONSTANTC1
+            + constanteC0 + CatalogConstant.NLCONSTANTCE * Math.exp(CatalogConstant.NLCONSTANTEX * spanLength);
+        LOG.info(" OSNR Non Linear contribution is {} dB", nonLinearOnsrContributionLinDb);
+        return Math.pow(10.0, -nonLinearOnsrContributionLinDb / 10);
     }
 
 }