Handle nullable lists
[genius.git] / interfacemanager / interfacemanager-impl / src / main / java / org / opendaylight / genius / interfacemanager / renderer / ovs / statehelpers / OvsInterfaceStateUpdateHelper.java
index ce2a8725ff9b7976e78c8e2f55ff5903c6843786..db91e3940a9e22b40dbaa6ed638161dbb43f0d70 100644 (file)
@@ -7,12 +7,19 @@
  */
 package org.opendaylight.genius.interfacemanager.renderer.ovs.statehelpers;
 
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
+
 import com.google.common.util.concurrent.ListenableFuture;
-import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
+import javax.inject.Inject;
+import javax.inject.Singleton;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
 import org.opendaylight.genius.interfacemanager.IfmUtil;
 import org.opendaylight.genius.interfacemanager.commons.AlivenessMonitorUtils;
 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
@@ -22,21 +29,31 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.AlivenessMonitorService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+@Singleton
 public class OvsInterfaceStateUpdateHelper {
     private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceStateUpdateHelper.class);
 
-    public static List<ListenableFuture<Void>> updateState(InstanceIdentifier<FlowCapableNodeConnector> key,
-            AlivenessMonitorService alivenessMonitorService, DataBroker dataBroker, String interfaceName,
+    private final ManagedNewTransactionRunner txRunner;
+    private final InterfaceManagerCommonUtils interfaceManagerCommonUtils;
+    private final AlivenessMonitorUtils alivenessMonitorUtils;
+
+    @Inject
+    public OvsInterfaceStateUpdateHelper(DataBroker dataBroker, AlivenessMonitorUtils alivenessMonitorUtils,
+            InterfaceManagerCommonUtils interfaceManagerCommonUtils) {
+        this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
+        this.interfaceManagerCommonUtils =  interfaceManagerCommonUtils;
+        this.alivenessMonitorUtils = alivenessMonitorUtils;
+    }
+
+    public List<ListenableFuture<Void>> updateState(String interfaceName,
             FlowCapableNodeConnector flowCapableNodeConnectorNew,
             FlowCapableNodeConnector flowCapableNodeConnectorOld) {
         LOG.debug("Updating interface state information for interface: {}", interfaceName);
-        List<ListenableFuture<Void>> futures = new ArrayList<>();
 
         Interface.OperStatus operStatusNew = InterfaceManagerCommonUtils.getOpState(flowCapableNodeConnectorNew);
         MacAddress macAddressNew = flowCapableNodeConnectorNew.getHardwareAddress();
@@ -44,23 +61,17 @@ public class OvsInterfaceStateUpdateHelper {
         Interface.OperStatus operStatusOld = InterfaceManagerCommonUtils.getOpState(flowCapableNodeConnectorOld);
         MacAddress macAddressOld = flowCapableNodeConnectorOld.getHardwareAddress();
 
-        boolean opstateModified = false;
-        boolean hardwareAddressModified = false;
-        if (!operStatusNew.equals(operStatusOld)) {
-            opstateModified = true;
-        }
-        if (!macAddressNew.equals(macAddressOld)) {
-            hardwareAddressModified = true;
-        }
+        boolean opstateModified = !operStatusNew.equals(operStatusOld);
+        boolean hardwareAddressModified = !Objects.equals(macAddressNew, macAddressOld);
 
         if (!opstateModified && !hardwareAddressModified) {
             LOG.debug("If State entry for port: {} Not Modified.", interfaceName);
-            return futures;
+            return Collections.emptyList();
         }
 
         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
-            .interfaces.rev140508.interfaces.Interface iface = InterfaceManagerCommonUtils
-                .getInterfaceFromConfigDS(interfaceName, dataBroker);
+            .interfaces.rev140508.interfaces.Interface iface = interfaceManagerCommonUtils
+                .getInterfaceFromConfigDS(interfaceName);
 
         // For monitoring enabled tunnels, skip opstate update
         if (isTunnelInterface(iface) && !modifyTunnelOpState(iface, opstateModified)) {
@@ -70,7 +81,7 @@ public class OvsInterfaceStateUpdateHelper {
 
         if (!opstateModified && !hardwareAddressModified) {
             LOG.debug("If State entry for port: {} Not Modified.", interfaceName);
-            return futures;
+            return Collections.emptyList();
         }
         InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
         if (hardwareAddressModified) {
@@ -78,42 +89,48 @@ public class OvsInterfaceStateUpdateHelper {
             PhysAddress physAddress = new PhysAddress(macAddressNew.getValue());
             ifaceBuilder.setPhysAddress(physAddress);
         }
-        // modify the attributes in interface operational DS
-        WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
-        handleInterfaceStateUpdates(iface, transaction, dataBroker, ifaceBuilder, opstateModified, interfaceName,
-                flowCapableNodeConnectorNew.getName(), operStatusNew);
-
-        // start/stop monitoring based on opState
-        if (isTunnelInterface(iface) && opstateModified) {
-            handleTunnelMonitoringUpdates(alivenessMonitorService, dataBroker, iface.getAugmentation(IfTunnel.class),
-                    iface.getName(), operStatusNew);
-        }
 
-        futures.add(transaction.submit());
-        return futures;
+        if (opstateModified) {
+            return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> {
+                // modify the attributes in interface operational DS
+                handleInterfaceStateUpdates(iface, tx, ifaceBuilder, true, interfaceName,
+                        flowCapableNodeConnectorNew.getName(), operStatusNew);
+
+                // start/stop monitoring based on opState
+                if (isTunnelInterface(iface)) {
+                    handleTunnelMonitoringUpdates(iface.augmentation(IfTunnel.class), iface.getName(),
+                            operStatusNew);
+                }
+            }));
+        } else {
+            return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> {
+                // modify the attributes in interface operational DS
+                handleInterfaceStateUpdates(iface, tx, ifaceBuilder, false, interfaceName,
+                        flowCapableNodeConnectorNew.getName(), operStatusNew);
+            }));
+        }
     }
 
-    public static void updateInterfaceStateOnNodeRemove(String interfaceName,
-            FlowCapableNodeConnector flowCapableNodeConnector, DataBroker dataBroker,
-            AlivenessMonitorService alivenessMonitorService, WriteTransaction transaction) {
+    public void updateInterfaceStateOnNodeRemove(String interfaceName,
+            FlowCapableNodeConnector flowCapableNodeConnector, TypedWriteTransaction<Operational> tx) {
         LOG.debug("Updating interface oper-status to UNKNOWN for : {}", interfaceName);
 
         InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
-            .ietf.interfaces.rev140508.interfaces.Interface iface = InterfaceManagerCommonUtils
-                .getInterfaceFromConfigDS(interfaceName, dataBroker);
-        handleInterfaceStateUpdates(iface, transaction, dataBroker, ifaceBuilder, true, interfaceName,
+            .ietf.interfaces.rev140508.interfaces.Interface iface = interfaceManagerCommonUtils
+                .getInterfaceFromConfigDS(interfaceName);
+        handleInterfaceStateUpdates(iface, tx, ifaceBuilder, true, interfaceName,
                 flowCapableNodeConnector.getName(), Interface.OperStatus.Unknown);
         if (InterfaceManagerCommonUtils.isTunnelInterface(iface)) {
-            handleTunnelMonitoringUpdates(alivenessMonitorService, dataBroker, iface.getAugmentation(IfTunnel.class),
-                    interfaceName, Interface.OperStatus.Unknown);
+            handleTunnelMonitoringUpdates(iface.augmentation(IfTunnel.class), interfaceName,
+                    Interface.OperStatus.Unknown);
         }
     }
 
-    public static void handleInterfaceStateUpdates(
+    private void handleInterfaceStateUpdates(
             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
                 .ietf.interfaces.rev140508.interfaces.Interface iface,
-            WriteTransaction transaction, DataBroker dataBroker, InterfaceBuilder ifaceBuilder, boolean opStateModified,
+            TypedWriteTransaction<Operational> tx, InterfaceBuilder ifaceBuilder, boolean opStateModified,
             String interfaceName, String portName, Interface.OperStatus opState) {
         // if interface config DS is null, do the update only for the
         // lower-layer-interfaces
@@ -121,23 +138,31 @@ public class OvsInterfaceStateUpdateHelper {
         if (iface == null && !interfaceName.equals(portName)) {
             return;
         }
+
+        final Interface interfaceState = interfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName);
+        if (interfaceState == null || (interfaceState.getOperStatus() == opState)) {
+            LOG.warn("Ignoring: updating interface state for interface {}",
+                    interfaceName);
+            return;
+        }
+
         LOG.debug("updating interface state entry for {}", interfaceName);
         InstanceIdentifier<Interface> ifStateId = IfmUtil.buildStateInterfaceId(interfaceName);
-        ifaceBuilder.setKey(new InterfaceKey(interfaceName));
+        ifaceBuilder.withKey(new InterfaceKey(interfaceName));
         if (modifyOpState(iface, opStateModified)) {
             LOG.debug("updating interface oper status as {} for {}", opState.name(), interfaceName);
             ifaceBuilder.setOperStatus(opState);
         }
-        transaction.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), false);
+        tx.merge(ifStateId, ifaceBuilder.build());
     }
 
-    public static void handleTunnelMonitoringUpdates(AlivenessMonitorService alivenessMonitorService,
-            DataBroker dataBroker, IfTunnel ifTunnel, String interfaceName, Interface.OperStatus operStatus) {
+    public void handleTunnelMonitoringUpdates(IfTunnel ifTunnel,
+            String interfaceName, Interface.OperStatus operStatus) {
         LOG.debug("handling tunnel monitoring updates for {} due to opstate modification", interfaceName);
         if (operStatus == Interface.OperStatus.Down || operStatus == Interface.OperStatus.Unknown) {
-            AlivenessMonitorUtils.stopLLDPMonitoring(alivenessMonitorService, dataBroker, ifTunnel, interfaceName);
+            alivenessMonitorUtils.stopLLDPMonitoring(ifTunnel, interfaceName);
         } else {
-            AlivenessMonitorUtils.startLLDPMonitoring(alivenessMonitorService, dataBroker, ifTunnel, interfaceName);
+            alivenessMonitorUtils.startLLDPMonitoring(ifTunnel, interfaceName);
         }
     }
 
@@ -145,20 +170,20 @@ public class OvsInterfaceStateUpdateHelper {
             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
                 .interfaces.rev140508.interfaces.Interface iface,
             boolean opStateModified) {
-        return opStateModified && (iface == null || iface != null && iface.isEnabled());
+        return opStateModified && (iface == null || iface.isEnabled());
     }
 
     public static boolean isTunnelInterface(
             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
                 .ietf.interfaces.rev140508.interfaces.Interface iface) {
-        return iface != null && iface.getAugmentation(IfTunnel.class) != null;
+        return iface != null && iface.augmentation(IfTunnel.class) != null;
     }
 
     public static boolean modifyTunnelOpState(
             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
                 .ietf.interfaces.rev140508.interfaces.Interface iface,
             boolean opStateModified) {
-        if (!iface.getAugmentation(IfTunnel.class).isMonitorEnabled()) {
+        if (!iface.augmentation(IfTunnel.class).isMonitorEnabled()) {
             return modifyOpState(iface, opStateModified);
         }
         return false;