Cleanup Optional uses
[genius.git] / interfacemanager / interfacemanager-impl / src / main / java / org / opendaylight / genius / interfacemanager / commons / InterfaceManagerCommonUtils.java
index 3aae10c2b7c97785d20ba5f58ca19250e78a6112..9c66d3c5f819d6716b1054b955aab29e8a32c542 100644 (file)
@@ -12,10 +12,12 @@ import com.google.common.base.Optional;
 import com.google.common.util.concurrent.ListenableFuture;
 import java.math.BigInteger;
 import java.util.ArrayList;
-import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 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;
@@ -39,11 +41,17 @@ 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.PhysAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.DpnToInterfaceList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntryKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntryBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.DpnToInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.DpnToInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.dpn.to._interface.InterfaceNameEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.dpn.to._interface.InterfaceNameEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.dpn.to._interface.InterfaceNameEntryKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
@@ -62,6 +70,11 @@ public class InterfaceManagerCommonUtils {
     private static final Logger LOG = LoggerFactory.getLogger(InterfaceManagerCommonUtils.class);
     private static ConcurrentHashMap<String, Interface> interfaceConfigMap = new ConcurrentHashMap<>();
     private static ConcurrentHashMap<String, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> interfaceStateMap = new ConcurrentHashMap<>();
+    private static ConcurrentHashMap<String, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus> bfdStateMap =
+            new ConcurrentHashMap<>();
+
+    private static final String NOVA_OR_TUNNEL_PORT_REGEX = "(tap|vhu)[0-9a-f]{8}-[0-9a-f]{2}|tun[0-9a-f]{11}";
+    private static final Pattern pattern = Pattern.compile(NOVA_OR_TUNNEL_PORT_REGEX);
 
     public static NodeConnector getNodeConnectorFromInventoryOperDS(NodeConnectorId nodeConnectorId,
             DataBroker dataBroker) {
@@ -70,24 +83,14 @@ public class InterfaceManagerCommonUtils {
                 .child(Node.class, new NodeKey(nodeId))
                 .child(NodeConnector.class, new NodeConnectorKey(nodeConnectorId)).build();
 
-        Optional<NodeConnector> nodeConnectorOptional = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, ncIdentifier,
-                dataBroker);
-        if (!nodeConnectorOptional.isPresent()) {
-            return null;
-        }
-        return nodeConnectorOptional.get();
+        return IfmUtil.read(LogicalDatastoreType.OPERATIONAL, ncIdentifier, dataBroker).orNull();
     }
 
     public static boolean isNodePresent(DataBroker dataBroker, NodeConnectorId nodeConnectorId) {
         NodeId nodeID = IfmUtil.getNodeIdFromNodeConnectorId(nodeConnectorId);
         InstanceIdentifier<Node> nodeInstanceIdentifier = InstanceIdentifier.builder(Nodes.class)
                 .child(Node.class, new NodeKey(nodeID)).build();
-        Optional<Node> node = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, nodeInstanceIdentifier, dataBroker);
-
-        if (node.isPresent()) {
-            return true;
-        }
-        return false;
+        return IfmUtil.read(LogicalDatastoreType.OPERATIONAL, nodeInstanceIdentifier, dataBroker).isPresent();
     }
 
     public static InstanceIdentifier<Interface> getInterfaceIdentifier(InterfaceKey interfaceKey) {
@@ -164,13 +167,7 @@ public class InterfaceManagerCommonUtils {
     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface getInterfaceStateFromOperDS(
             InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId,
             DataBroker dataBroker) {
-        Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateOptional = IfmUtil
-                .read(LogicalDatastoreType.OPERATIONAL, ifStateId, dataBroker);
-        if (!ifStateOptional.isPresent()) {
-            return null;
-        }
-
-        return ifStateOptional.get();
+        return IfmUtil.read(LogicalDatastoreType.OPERATIONAL, ifStateId, dataBroker).orNull();
     }
 
     public static void makeTunnelIngressFlow(List<ListenableFuture<Void>> futures, IMdsalApiManager mdsalApiManager,
@@ -191,9 +188,8 @@ public class InterfaceManagerCommonUtils {
             mkInstructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { tableId }));
         }
 
-        BigInteger COOKIE_VM_INGRESS_TABLE = new BigInteger("8000001", 16);
         FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId, NwConstants.VLAN_INTERFACE_INGRESS_TABLE, flowRef,
-                IfmConstants.DEFAULT_FLOW_PRIORITY, interfaceName, 0, 0, COOKIE_VM_INGRESS_TABLE, matches,
+                IfmConstants.DEFAULT_FLOW_PRIORITY, interfaceName, 0, 0, NwConstants.COOKIE_VM_INGRESS_TABLE, matches,
                 mkInstructions);
         if (NwConstants.ADD_FLOW == addOrRemoveFlow) {
             futures.add(mdsalApiManager.installFlow(dpnId, flowEntity));
@@ -203,7 +199,7 @@ public class InterfaceManagerCommonUtils {
     }
 
     public static String getTunnelInterfaceFlowRef(BigInteger dpnId, short tableId, String ifName) {
-        return new StringBuilder().append(dpnId).append(tableId).append(ifName).toString();
+        return String.valueOf(dpnId) + tableId + ifName;
     }
 
     public static void setOpStateForInterface(DataBroker broker, String interfaceName,
@@ -269,16 +265,24 @@ public class InterfaceManagerCommonUtils {
         transaction.merge(LogicalDatastoreType.OPERATIONAL, ifChildStateId, ifaceBuilderChild.build());
     }
 
-    public static void addStateEntry(String interfaceName, WriteTransaction transaction, DataBroker dataBroker,
-            IdManagerService idManager,
-            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
+    public static void addStateEntry(String interfaceName, DataBroker dataBroker,
+                                     IdManagerService idManager, List<ListenableFuture<Void>> futures,
+                                     org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
+        WriteTransaction interfaceOperShardTransaction = dataBroker.newWriteOnlyTransaction();
+        addStateEntry(interfaceName, dataBroker, interfaceOperShardTransaction, idManager, futures, ifState);
+        futures.add(interfaceOperShardTransaction.submit());
+    }
+
+    public static void addStateEntry(String interfaceName, DataBroker dataBroker, WriteTransaction interfaceOperShardTransaction,
+                                     IdManagerService idManager, List<ListenableFuture<Void>> futures,
+                                     org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
         // allocate lport tag and create interface-if-index map.
         // This is done even if interface-state is not present, so that there is
         // no throttling
         // on id allocation even when multiple southbound port_up events come in
         // one shot
         Integer ifIndex = IfmUtil.allocateId(idManager, IfmConstants.IFM_IDPOOL_NAME, interfaceName);
-        InterfaceMetaUtils.createLportTagInterfaceMap(transaction, interfaceName, ifIndex);
+        InterfaceMetaUtils.createLportTagInterfaceMap(interfaceOperShardTransaction, interfaceName, ifIndex);
         if (ifState == null) {
             LOG.debug("could not retrieve interface state corresponding to {}", interfaceName);
             return;
@@ -310,21 +314,29 @@ public class InterfaceManagerCommonUtils {
             ifaceBuilder.setType(interfaceInfo.getType());
         }
         ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceName));
-        transaction.put(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), true);
+        interfaceOperShardTransaction.put(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), true);
 
         // install ingress flow
-        BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+        BigInteger dpId = IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId);
         long portNo = Long.valueOf(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId));
         if (interfaceInfo != null && interfaceInfo.isEnabled() && ifState
                 .getOperStatus() == org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Up) {
-            List<MatchInfo> matches = FlowBasedServicesUtils.getMatchInfoForVlanPortAtIngressTable(dpId, portNo,
-                    interfaceInfo);
-            FlowBasedServicesUtils.installVlanFlow(dpId, portNo, interfaceInfo, transaction, matches, ifIndex);
+            FlowBasedServicesUtils.installLportIngressFlow(dpId, portNo, interfaceInfo, futures, dataBroker, ifIndex);
+            FlowBasedServicesUtils.bindDefaultEgressDispatcherService(dataBroker, futures, interfaceInfo, Long.toString(portNo), interfaceName, ifIndex);
         }
+
+        // Update the DpnToInterfaceList OpDS
+        createOrUpdateDpnToInterface(dpId, interfaceName,interfaceOperShardTransaction);
+    }
+
+    public static boolean checkIfBfdStateIsDown(String interfaceName){
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus =
+                InterfaceManagerCommonUtils.getBfdStateFromCache(interfaceName);
+        return (operStatus == org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down);
     }
 
     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface addStateEntry(
-            Interface interfaceInfo, String interfaceName, WriteTransaction transaction, IdManagerService idManager,
+            DataBroker dataBroker, Interface interfaceInfo, String interfaceName, WriteTransaction transaction, IdManagerService idManager,
             PhysAddress physAddress,
             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus,
             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus adminStatus,
@@ -333,7 +345,8 @@ public class InterfaceManagerCommonUtils {
         InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
         Integer ifIndex = null;
         if (interfaceInfo != null) {
-            if (!interfaceInfo.isEnabled()) {
+            if(!interfaceInfo.isEnabled() || (InterfaceManagerCommonUtils.isTunnelInterface(interfaceInfo) &&
+                    checkIfBfdStateIsDown(interfaceInfo.getName()))){
                 operStatus = org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down;
             }
 
@@ -353,6 +366,10 @@ public class InterfaceManagerCommonUtils {
         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = ifaceBuilder
                 .build();
         transaction.put(LogicalDatastoreType.OPERATIONAL, ifStateId, ifState, true);
+
+        BigInteger dpId = IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId);
+        // Update the DpnToInterfaceList OpDS
+        createOrUpdateDpnToInterface(dpId, interfaceName, transaction);
         return ifState;
     }
 
@@ -384,7 +401,11 @@ public class InterfaceManagerCommonUtils {
                 .getInterfaceParentEntryFromConfigDS(interfaceParentEntryIdentifier, dataBroker);
 
         if (interfaceParentEntry != null) {
-            LOG.error("Trying to bind the same parent interface {} to multiple trunk interfaces. ", parentInterface);
+            if (!Objects.equals(parentInterface, interfaceParentEntry.getParentInterface())) {
+                LOG.error("Trying to bind the same parent interface {} to multiple trunk interfaces. ", parentInterface);
+            } else {
+                LOG.trace("Child entry for interface {} already exists", childInterface);
+            }
             return false;
         }
 
@@ -421,17 +442,11 @@ public class InterfaceManagerCommonUtils {
     }
 
     public static boolean isTunnelInterface(Interface interfaceInfo) {
-        if (interfaceInfo != null && interfaceInfo.getAugmentation(IfTunnel.class) != null) {
-            return true;
-        }
-        return false;
+        return interfaceInfo != null && interfaceInfo.getAugmentation(IfTunnel.class) != null;
     }
 
     public static boolean isVlanInterface(Interface interfaceInfo) {
-        if (interfaceInfo != null && interfaceInfo.getAugmentation(IfL2vlan.class) != null) {
-            return true;
-        }
-        return false;
+        return interfaceInfo != null && interfaceInfo.getAugmentation(IfL2vlan.class) != null;
     }
 
     // Cache Util methods
@@ -453,52 +468,58 @@ public class InterfaceManagerCommonUtils {
         interfaceStateMap.remove(iface.getName());
     }
 
-    public static List<BigInteger> getListOfDpns(DataBroker broker) {
-        List<BigInteger> dpnsList = new LinkedList<>();
-        InstanceIdentifier<Nodes> nodesInstanceIdentifier = InstanceIdentifier.builder(Nodes.class).build();
-        Optional<Nodes> nodesOptional = MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
-                nodesInstanceIdentifier);
-        if (!nodesOptional.isPresent()) {
-            return dpnsList;
-        }
-        Nodes nodes = nodesOptional.get();
-        List<Node> nodeList = nodes.getNode();
-        for (Node node : nodeList) {
-            NodeId nodeId = node.getId();
-            if (nodeId == null) {
-                continue;
-            }
-            BigInteger dpnId = MDSALUtil.getDpnIdFromNodeName(nodeId);
-            dpnsList.add(dpnId);
-        }
-        return dpnsList;
+    public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus getBfdStateFromCache(String interfaceName) {
+        return bfdStateMap.get(interfaceName);
     }
 
-    public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface getInterfaceStateForUnknownDpn(
-            String interfaceName, DataBroker dataBroker) {
-        String parentInterface;
-        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = null;
-        List<BigInteger> listOfDpns = InterfaceManagerCommonUtils.getListOfDpns(dataBroker);
-        for (BigInteger dpnId : listOfDpns) {
-            parentInterface = new StringBuilder().append(dpnId).append(IfmConstants.OF_URI_SEPARATOR)
-                    .append(interfaceName).toString();
-            ifState = InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(parentInterface, dataBroker);
-            if (ifState != null) {
-                break;
-            }
-        }
-        return ifState;
+    public static void addBfdStateToCache(String interfaceName,
+                                          org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus) {
+        bfdStateMap.put(interfaceName, operStatus);
     }
 
-    public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface getInterfaceStateFromDS(
-            String interfaceName) {
-        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = null;
-        for (Map.Entry<String, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> entry : interfaceStateMap
-                .entrySet()) {
-            if (entry.getKey().contains(interfaceName)) {
-                ifState = entry.getValue();
-            }
+    public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus removeBfdStateFromCache(String interfaceName){
+        return bfdStateMap.remove(interfaceName);
+    }
+
+    public static boolean isNovaOrTunnelPort(String portName) {
+
+        Matcher matcher = pattern.matcher(portName);
+        return matcher.matches();
+    }
+
+
+    public static void createOrUpdateDpnToInterface(BigInteger dpId, String infName, WriteTransaction transaction) {
+        DpnToInterfaceKey dpnToInterfaceKey = new DpnToInterfaceKey(dpId);
+        InterfaceNameEntryKey interfaceNameEntryKey = new InterfaceNameEntryKey(infName);
+        InstanceIdentifier<InterfaceNameEntry> intfid = InstanceIdentifier.builder(DpnToInterfaceList.class)
+                                                        .child(DpnToInterface.class, dpnToInterfaceKey)
+                                                        .child(InterfaceNameEntry.class, interfaceNameEntryKey)
+                                                        .build();
+        InterfaceNameEntryBuilder entryBuilder = new InterfaceNameEntryBuilder().setKey(interfaceNameEntryKey).setInterfaceName(infName);
+        transaction.put(LogicalDatastoreType.OPERATIONAL, intfid, entryBuilder.build(), true);
+    }
+
+    public static void deleteDpnToInterface(DataBroker dataBroker, BigInteger dpId, String infName, WriteTransaction transaction) {
+        DpnToInterfaceKey dpnToInterfaceKey = new DpnToInterfaceKey(dpId);
+        InstanceIdentifier<DpnToInterface> dpnToInterfaceId = InstanceIdentifier.builder(DpnToInterfaceList.class)
+                .child(DpnToInterface.class, dpnToInterfaceKey).build();
+        Optional<DpnToInterface> dpnToInterfaceOptional = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, dpnToInterfaceId, dataBroker);
+        if (!dpnToInterfaceOptional.isPresent()) {
+            LOG.debug("DPN {} is already removed from the Operational DS", dpId);
+            return;
+        }
+
+        List<InterfaceNameEntry> interfaceNameEntries = dpnToInterfaceOptional.get().getInterfaceNameEntry();
+        InterfaceNameEntryKey interfaceNameEntryKey = new InterfaceNameEntryKey(infName);
+        InstanceIdentifier<InterfaceNameEntry> intfid = InstanceIdentifier.builder(DpnToInterfaceList.class)
+                .child(DpnToInterface.class, dpnToInterfaceKey)
+                .child(InterfaceNameEntry.class, interfaceNameEntryKey)
+                .build();
+        transaction.delete(LogicalDatastoreType.OPERATIONAL, intfid);
+
+        if (interfaceNameEntries.size() <=1) {
+            transaction.delete(LogicalDatastoreType.OPERATIONAL, dpnToInterfaceId);
         }
-        return ifState;
     }
+
 }