Allow 0 dB spanloss in power management
[transportpce.git] / olm / src / main / java / org / opendaylight / transportpce / olm / power / PowerMgmtImpl.java
index d3b16f3110fa8d4dcf71e5acb59830e7b1a90057..dda3592b2009a2f8af1404e7c4385e8dd87de256 100644 (file)
@@ -11,11 +11,12 @@ package org.opendaylight.transportpce.olm.power;
 import java.math.BigDecimal;
 import java.math.MathContext;
 import java.math.RoundingMode;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Optional;
-import org.opendaylight.mdsal.binding.api.DataBroker;
+import java.util.stream.Collectors;
 import org.opendaylight.transportpce.common.crossconnect.CrossConnect;
 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
 import org.opendaylight.transportpce.common.fixedflex.GridConstant;
@@ -24,20 +25,33 @@ import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfa
 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaces;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev210618.ServicePowerSetupInput;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev210618.ServicePowerTurndownInput;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220316.OpenroadmNodeVersion;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220316.mapping.Mapping;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220316.mapping.MappingKey;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220316.network.Nodes;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev231221.OpenroadmNodeVersion;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev231221.mapping.Mapping;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev231221.mapping.MappingKey;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev231221.network.Nodes;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.OpticalControlMode;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.Interface;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.Interface1;
 import org.opendaylight.yangtools.yang.common.Decimal64;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+@Component(configurationPid = "org.opendaylight.transportpce")
 public class PowerMgmtImpl implements PowerMgmt {
+
+    @ObjectClassDefinition
+    public @interface Configuration {
+        @AttributeDefinition
+        long timer1() default 120000;
+        @AttributeDefinition
+        long timer2() default 20000;
+    }
     private static final Logger LOG = LoggerFactory.getLogger(PowerMgmtImpl.class);
-    private final DataBroker db;
     private final OpenRoadmInterfaces openRoadmInterfaces;
     private final CrossConnect crossConnect;
     private final DeviceTransactionManager deviceTransactionManager;
@@ -47,42 +61,42 @@ public class PowerMgmtImpl implements PowerMgmt {
     private static final String INTERFACE_NOT_PRESENT = "Interface {} on node {} is not present!";
     private static final double MC_WIDTH_GRAN = 2 * GridConstant.GRANULARITY;
 
-    private long timer1 = 120000;
+    private long timer1;
     // openroadm spec value is 120000, functest value is 3000
-    private long timer2 = 20000;
+    private long timer2;
     // openroadm spec value is 20000, functest value is 2000
 
-    public PowerMgmtImpl(DataBroker db, OpenRoadmInterfaces openRoadmInterfaces, CrossConnect crossConnect,
-            DeviceTransactionManager deviceTransactionManager, PortMapping portMapping) {
-        this.db = db;
-        this.openRoadmInterfaces = openRoadmInterfaces;
-        this.crossConnect = crossConnect;
-        this.deviceTransactionManager = deviceTransactionManager;
-        this.portMapping = portMapping;
+    @Activate
+    public PowerMgmtImpl(@Reference OpenRoadmInterfaces openRoadmInterfaces,
+            @Reference CrossConnect crossConnect,
+            @Reference DeviceTransactionManager deviceTransactionManager,
+            @Reference PortMapping portMapping, final Configuration configuration) {
+        this(openRoadmInterfaces, crossConnect, deviceTransactionManager, portMapping, configuration.timer1(),
+                configuration.timer2());
     }
 
-    public PowerMgmtImpl(DataBroker db, OpenRoadmInterfaces openRoadmInterfaces,
+    public PowerMgmtImpl(OpenRoadmInterfaces openRoadmInterfaces,
                          CrossConnect crossConnect, DeviceTransactionManager deviceTransactionManager,
-            PortMapping portMapping, String timer1, String timer2) {
-        this.db = db;
+            PortMapping portMapping, long timer1, long timer2) {
         this.openRoadmInterfaces = openRoadmInterfaces;
         this.crossConnect = crossConnect;
         this.deviceTransactionManager = deviceTransactionManager;
         this.portMapping = portMapping;
         try {
-            this.timer1 = Long.parseLong(timer1);
+            this.timer1 = Long.valueOf(timer1);
         } catch (NumberFormatException e) {
             this.timer1 = 120000;
             LOG.warn("Failed to retrieve Olm timer1 value from configuration - using default value {}",
                 this.timer1, e);
         }
         try {
-            this.timer2 = Long.parseLong(timer2);
+            this.timer2 = Long.valueOf(timer2);
         } catch (NumberFormatException e) {
             this.timer2 = 20000;
             LOG.warn("Failed to retrieve Olm timer2 value from configuration - using default value {}",
                 this.timer2, e);
         }
+        LOG.debug("PowerMgmtImpl instantiated with olm timers = {} - {}", this.timer1, this.timer2);
     }
 
     /**
@@ -111,7 +125,7 @@ public class PowerMgmtImpl implements PowerMgmt {
             Nodes inputNode = this.portMapping.getNode(nodeId);
             if (inputNode == null || inputNode.getNodeInfo() == null) {
                 LOG.error("OLM-PowerMgmtImpl : Error retrieving mapping node for {}", nodeId);
-                continue;
+                return false;
             }
             OpenroadmNodeVersion openroadmVersion = inputNode.getNodeInfo().getOpenroadmVersion();
 
@@ -177,14 +191,14 @@ public class PowerMgmtImpl implements PowerMgmt {
                     }
                     // TODO can it be return false rather than continue?
                     // in that case, mappingObjectOptional could be moved inside method getSpanLossTx()
-                    LOG.info("Dest point is Degree {}", mappingObjectOptional.get());
-                    BigDecimal spanLossTx = getSpanLossTx(mappingObjectOptional.get().getSupportingOts(),
+                    LOG.info("Dest point is Degree {}", mappingObjectOptional.orElseThrow());
+                    BigDecimal spanLossTx = getSpanLossTx(mappingObjectOptional.orElseThrow().getSupportingOts(),
                         destTpId, nodeId, openroadmVersion.getIntValue());
 
                     LOG.info("Spanloss TX is {}", spanLossTx);
                     // TODO: The span-loss limits should be obtained from optical specifications
-                    if (spanLossTx == null || spanLossTx.intValue() <= 0 || spanLossTx.intValue() > 27) {
-                        LOG.error("Power Value is null: spanLossTx null or out of openROADM range ]0,27] {}",
+                    if (spanLossTx == null || spanLossTx.intValue() < 0 || spanLossTx.intValue() > 27) {
+                        LOG.error("Power Value is null: spanLossTx null or out of openROADM range [0,27] {}",
                             spanLossTx);
                         return false;
                     }
@@ -236,8 +250,8 @@ public class PowerMgmtImpl implements PowerMgmt {
             // TODO Align protections with getSRGRxPowerRangeMap
         }
 
-        String circuitPackName = mappingObject.get().getSupportingCircuitPackName();
-        String portName = mappingObject.get().getSupportingPort();
+        String circuitPackName = mappingObject.orElseThrow().getSupportingCircuitPackName();
+        String portName = mappingObject.orElseThrow().getSupportingPort();
         switch (openroadmVersion) {
             case 1:
                 return PowerMgmtVersion121.getXponderPowerRange(circuitPackName, portName,
@@ -269,8 +283,8 @@ public class PowerMgmtImpl implements PowerMgmt {
             // FIXME shouldn't it lead to a return false in setPower() ?
         }
 
-        String circuitPackName = mappingObject.get().getSupportingCircuitPackName();
-        String portName = mappingObject.get().getSupportingPort();
+        String circuitPackName = mappingObject.orElseThrow().getSupportingCircuitPackName();
+        String portName = mappingObject.orElseThrow().getSupportingPort();
         switch (rdmOpenroadmVersion) {
             case 1:
                 return PowerMgmtVersion121.getSRGRxPowerRange(nodeId, srgId,
@@ -299,12 +313,12 @@ public class PowerMgmtImpl implements PowerMgmt {
                         LOG.error(INTERFACE_NOT_PRESENT, supportingOts, nodeId);
                         return null;
                     }
-                    if (interfaceOpt.get().augmentation(Interface1.class).getOts()
+                    if (interfaceOpt.orElseThrow().augmentation(Interface1.class).getOts()
                             .getSpanLossTransmit() == null) {
-                        LOG.error("interface {} has no spanloss value", interfaceOpt.get().getName());
+                        LOG.error("interface {} has no spanloss value", interfaceOpt.orElseThrow().getName());
                         return null;
                     }
-                    return interfaceOpt.get()
+                    return interfaceOpt.orElseThrow()
                             .augmentation(Interface1.class)
                             .getOts().getSpanLossTransmit().getValue().decimalValue();
                 case 2:
@@ -315,13 +329,13 @@ public class PowerMgmtImpl implements PowerMgmt {
                         LOG.error(INTERFACE_NOT_PRESENT, supportingOts, nodeId);
                         return null;
                     }
-                    if (interfaceOpt1.get().augmentation(org.opendaylight.yang.gen.v1.http.org
+                    if (interfaceOpt1.orElseThrow().augmentation(org.opendaylight.yang.gen.v1.http.org
                             .openroadm.optical.transport.interfaces.rev181019.Interface1.class).getOts()
                                 .getSpanLossTransmit() == null) {
-                        LOG.error("interface {} has no spanloss value", interfaceOpt1.get().getName());
+                        LOG.error("interface {} has no spanloss value", interfaceOpt1.orElseThrow().getName());
                         return null;
                     }
-                    return interfaceOpt1.get()
+                    return interfaceOpt1.orElseThrow()
                             .augmentation(org.opendaylight.yang.gen.v1.http.org
                                 .openroadm.optical.transport.interfaces.rev181019.Interface1.class)
                             .getOts().getSpanLossTransmit().getValue().decimalValue();
@@ -501,7 +515,7 @@ public class PowerMgmtImpl implements PowerMgmt {
                         return false;
                     }
                     powerSetupResult = PowerMgmtVersion121.setTransponderPower(nodeId, interfaceName,
-                            txPower, deviceTransactionManager, interfaceOptional121.get());
+                            txPower, deviceTransactionManager, interfaceOptional121.orElseThrow());
                     break;
                 case 2:
                     Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.interfaces.grp
@@ -512,7 +526,7 @@ public class PowerMgmtImpl implements PowerMgmt {
                         return false;
                     }
                     powerSetupResult = PowerMgmtVersion221.setTransponderPower(nodeId, interfaceName,
-                            txPower, deviceTransactionManager, interfaceOptional221.get());
+                            txPower, deviceTransactionManager, interfaceOptional221.orElseThrow());
                     break;
                 case 3:
                     Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.interfaces.grp
@@ -522,8 +536,19 @@ public class PowerMgmtImpl implements PowerMgmt {
                         LOG.error(INTERFACE_NOT_PRESENT, interfaceName, nodeId);
                         return false;
                     }
+                    // Check the support-interface-cap type
+                    // Get the logical connection point name from the interface-name, by splitting it by "-"
+                    // and discard the last part. For instance XPDR1-NETWORK1-xxx:xxx
+                    String logicalConnectionPoint =
+                        Arrays.stream(interfaceName.split("-", 3)).limit(2).collect(Collectors.joining("-"));
+                    LOG.info("Logical connection point {} for Interface {}", logicalConnectionPoint, interfaceName);
+                    Mapping portMap = portMapping.getMapping(nodeId, logicalConnectionPoint);
+                    if (portMap == null) {
+                        throw new OpenRoadmInterfaceException(
+                                OpenRoadmInterfaceException.mapping_msg_err(nodeId, logicalConnectionPoint));
+                    }
                     powerSetupResult = PowerMgmtVersion710.setTransponderPower(nodeId, interfaceName,
-                            txPower, deviceTransactionManager, interfaceOptional710.get());
+                        txPower, deviceTransactionManager, interfaceOptional710.orElseThrow(), portMap);
                     break;
                 default:
                     LOG.error("Unrecognized OpenRoadm version");