Cleanup Optional uses
[genius.git] / interfacemanager / interfacemanager-impl / src / main / java / org / opendaylight / genius / interfacemanager / commons / InterfaceManagerCommonUtils.java
1 /*
2  * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. 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.genius.interfacemanager.commons;
10
11 import com.google.common.base.Optional;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import java.math.BigInteger;
14 import java.util.ArrayList;
15 import java.util.List;
16 import java.util.Objects;
17 import java.util.concurrent.ConcurrentHashMap;
18 import java.util.regex.Matcher;
19 import java.util.regex.Pattern;
20
21 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
22 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.genius.interfacemanager.IfmConstants;
25 import org.opendaylight.genius.interfacemanager.IfmUtil;
26 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
27 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
28 import org.opendaylight.genius.mdsalutil.FlowEntity;
29 import org.opendaylight.genius.mdsalutil.InstructionInfo;
30 import org.opendaylight.genius.mdsalutil.InstructionType;
31 import org.opendaylight.genius.mdsalutil.MDSALUtil;
32 import org.opendaylight.genius.mdsalutil.MatchFieldType;
33 import org.opendaylight.genius.mdsalutil.MatchInfo;
34 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
35 import org.opendaylight.genius.mdsalutil.NwConstants;
36 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.DpnToInterfaceList;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntry;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntryKey;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntry;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntryBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntryKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.DpnToInterface;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.DpnToInterfaceKey;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.dpn.to._interface.InterfaceNameEntry;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.dpn.to._interface.InterfaceNameEntryBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.dpn.to._interface.InterfaceNameEntryKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
65 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
66 import org.slf4j.Logger;
67 import org.slf4j.LoggerFactory;
68
69 public class InterfaceManagerCommonUtils {
70     private static final Logger LOG = LoggerFactory.getLogger(InterfaceManagerCommonUtils.class);
71     private static ConcurrentHashMap<String, Interface> interfaceConfigMap = new ConcurrentHashMap<>();
72     private static ConcurrentHashMap<String, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> interfaceStateMap = new ConcurrentHashMap<>();
73     private static ConcurrentHashMap<String, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus> bfdStateMap =
74             new ConcurrentHashMap<>();
75
76     private static final String NOVA_OR_TUNNEL_PORT_REGEX = "(tap|vhu)[0-9a-f]{8}-[0-9a-f]{2}|tun[0-9a-f]{11}";
77     private static final Pattern pattern = Pattern.compile(NOVA_OR_TUNNEL_PORT_REGEX);
78
79     public static NodeConnector getNodeConnectorFromInventoryOperDS(NodeConnectorId nodeConnectorId,
80             DataBroker dataBroker) {
81         NodeId nodeId = IfmUtil.getNodeIdFromNodeConnectorId(nodeConnectorId);
82         InstanceIdentifier<NodeConnector> ncIdentifier = InstanceIdentifier.builder(Nodes.class)
83                 .child(Node.class, new NodeKey(nodeId))
84                 .child(NodeConnector.class, new NodeConnectorKey(nodeConnectorId)).build();
85
86         return IfmUtil.read(LogicalDatastoreType.OPERATIONAL, ncIdentifier, dataBroker).orNull();
87     }
88
89     public static boolean isNodePresent(DataBroker dataBroker, NodeConnectorId nodeConnectorId) {
90         NodeId nodeID = IfmUtil.getNodeIdFromNodeConnectorId(nodeConnectorId);
91         InstanceIdentifier<Node> nodeInstanceIdentifier = InstanceIdentifier.builder(Nodes.class)
92                 .child(Node.class, new NodeKey(nodeID)).build();
93         return IfmUtil.read(LogicalDatastoreType.OPERATIONAL, nodeInstanceIdentifier, dataBroker).isPresent();
94     }
95
96     public static InstanceIdentifier<Interface> getInterfaceIdentifier(InterfaceKey interfaceKey) {
97         InstanceIdentifier.InstanceIdentifierBuilder<Interface> interfaceInstanceIdentifierBuilder = InstanceIdentifier
98                 .builder(Interfaces.class).child(Interface.class, interfaceKey);
99         return interfaceInstanceIdentifierBuilder.build();
100     }
101
102     public static List<Interface> getAllTunnelInterfaces(DataBroker dataBroker,
103             InterfaceInfo.InterfaceType interfaceType) {
104         List<Interface> vxlanList = new ArrayList<>();
105         InstanceIdentifier<Interfaces> interfacesInstanceIdentifier = InstanceIdentifier.builder(Interfaces.class)
106                 .build();
107         Optional<Interfaces> interfacesOptional = IfmUtil.read(LogicalDatastoreType.CONFIGURATION,
108                 interfacesInstanceIdentifier, dataBroker);
109         if (!interfacesOptional.isPresent()) {
110             return vxlanList;
111         }
112         Interfaces interfaces = interfacesOptional.get();
113         List<Interface> interfacesList = interfaces.getInterface();
114         for (Interface iface : interfacesList) {
115             if (IfmUtil.getInterfaceType(iface) == InterfaceInfo.InterfaceType.VXLAN_TRUNK_INTERFACE
116                     && iface.getAugmentation(IfTunnel.class).isInternal()) {
117                 vxlanList.add(iface);
118             }
119         }
120         return vxlanList;
121     }
122
123     /**
124      * Searches for an interface by its name
125      * @param interfaceName name of the interface to search for
126      * @param dataBroker data tree store to start searching for the interface
127      * @return the Interface object
128      *
129      */
130     public static Interface getInterfaceFromConfigDS (String interfaceName, DataBroker dataBroker) {
131         Interface iface = interfaceConfigMap.get(interfaceName);
132         if (iface != null) {
133             return iface;
134         }
135         InstanceIdentifier<Interface> interfaceId = getInterfaceIdentifier(new InterfaceKey(interfaceName));
136         Optional<Interface> interfaceOptional = IfmUtil.read(LogicalDatastoreType.CONFIGURATION, interfaceId,
137                 dataBroker);
138         if (interfaceOptional.isPresent()) {
139             iface = interfaceOptional.get();
140             interfaceConfigMap.put(iface.getName(), iface);
141         }
142         return iface;
143     }
144
145     @Deprecated
146     public static Interface getInterfaceFromConfigDS (InterfaceKey interfaceKey, DataBroker dataBroker) {
147         return getInterfaceFromConfigDS(interfaceKey.getName(), dataBroker);
148     }
149
150     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface getInterfaceStateFromOperDS(
151             String interfaceName, DataBroker dataBroker) {
152         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceStateMap
153                 .get(interfaceName);
154         if (ifState != null) {
155             return ifState;
156         }
157         Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateOptional = IfmUtil
158                 .read(LogicalDatastoreType.OPERATIONAL, IfmUtil.buildStateInterfaceId(interfaceName), dataBroker);
159         if (ifStateOptional.isPresent()) {
160             ifState = ifStateOptional.get();
161             interfaceStateMap.put(ifState.getName(), ifState);
162         }
163         return ifState;
164     }
165
166     @Deprecated
167     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface getInterfaceStateFromOperDS(
168             InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId,
169             DataBroker dataBroker) {
170         return IfmUtil.read(LogicalDatastoreType.OPERATIONAL, ifStateId, dataBroker).orNull();
171     }
172
173     public static void makeTunnelIngressFlow(List<ListenableFuture<Void>> futures, IMdsalApiManager mdsalApiManager,
174             IfTunnel tunnel, BigInteger dpnId, long portNo, String interfaceName, int ifIndex, int addOrRemoveFlow) {
175         LOG.debug("make tunnel ingress flow for {}", interfaceName);
176         String flowRef = InterfaceManagerCommonUtils.getTunnelInterfaceFlowRef(dpnId,
177                 NwConstants.VLAN_INTERFACE_INGRESS_TABLE, interfaceName);
178         List<MatchInfo> matches = new ArrayList<>();
179         List<InstructionInfo> mkInstructions = new ArrayList<>();
180         if (NwConstants.ADD_FLOW == addOrRemoveFlow) {
181             matches.add(new MatchInfo(MatchFieldType.in_port, new BigInteger[] { dpnId, BigInteger.valueOf(portNo) }));
182             mkInstructions.add(new InstructionInfo(InstructionType.write_metadata,
183                     new BigInteger[] { MetaDataUtil.getLportTagMetaData(ifIndex).or(BigInteger.ONE),
184                             MetaDataUtil.METADATA_MASK_LPORT_TAG_SH_FLAG }));
185             short tableId = (tunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeMplsOverGre.class))
186                     ? NwConstants.L3_LFIB_TABLE
187                     : tunnel.isInternal() ? NwConstants.INTERNAL_TUNNEL_TABLE : NwConstants.DHCP_TABLE_EXTERNAL_TUNNEL;
188             mkInstructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { tableId }));
189         }
190
191         FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId, NwConstants.VLAN_INTERFACE_INGRESS_TABLE, flowRef,
192                 IfmConstants.DEFAULT_FLOW_PRIORITY, interfaceName, 0, 0, NwConstants.COOKIE_VM_INGRESS_TABLE, matches,
193                 mkInstructions);
194         if (NwConstants.ADD_FLOW == addOrRemoveFlow) {
195             futures.add(mdsalApiManager.installFlow(dpnId, flowEntity));
196         } else {
197             futures.add(mdsalApiManager.removeFlow(dpnId, flowEntity));
198         }
199     }
200
201     public static String getTunnelInterfaceFlowRef(BigInteger dpnId, short tableId, String ifName) {
202         return String.valueOf(dpnId) + tableId + ifName;
203     }
204
205     public static void setOpStateForInterface(DataBroker broker, String interfaceName,
206             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus opStatus) {
207         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> interfaceId = IfmUtil
208                 .buildStateInterfaceId(interfaceName);
209         InterfaceBuilder ifaceBuilder = new InterfaceBuilder()
210                 .setKey(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(
211                         interfaceName));
212         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface interfaceData = ifaceBuilder
213                 .setOperStatus(opStatus).build();
214         MDSALUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, interfaceId, interfaceData);
215     }
216
217     public static void createInterfaceChildEntry(WriteTransaction t, String parentInterface, String childInterface) {
218         InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentInterface);
219         InterfaceChildEntryKey interfaceChildEntryKey = new InterfaceChildEntryKey(childInterface);
220         InstanceIdentifier<InterfaceChildEntry> intfId = InterfaceMetaUtils
221                 .getInterfaceChildEntryIdentifier(interfaceParentEntryKey, interfaceChildEntryKey);
222         InterfaceChildEntryBuilder entryBuilder = new InterfaceChildEntryBuilder().setKey(interfaceChildEntryKey)
223                 .setChildInterface(childInterface);
224         t.put(LogicalDatastoreType.CONFIGURATION, intfId, entryBuilder.build(), true);
225     }
226
227     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus updateStateEntry(
228             Interface interfaceNew, DataBroker dataBroker, WriteTransaction transaction,
229             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
230         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus;
231         if (!interfaceNew.isEnabled()) {
232             operStatus = org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down;
233         } else {
234             String ncStr = ifState.getLowerLayerIf().get(0);
235             NodeConnectorId nodeConnectorId = new NodeConnectorId(ncStr);
236             NodeConnector nodeConnector = InterfaceManagerCommonUtils
237                     .getNodeConnectorFromInventoryOperDS(nodeConnectorId, dataBroker);
238             FlowCapableNodeConnector flowCapableNodeConnector = nodeConnector
239                     .getAugmentation(FlowCapableNodeConnector.class);
240             // State state = flowCapableNodeConnector.getState();
241             operStatus = flowCapableNodeConnector == null
242                     ? org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down
243                     : org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Up;
244         }
245
246         String ifName = interfaceNew.getName();
247         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId = IfmUtil
248                 .buildStateInterfaceId(interfaceNew.getName());
249         InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
250         ifaceBuilder.setOperStatus(operStatus);
251         ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifName));
252         transaction.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build());
253         return operStatus;
254     }
255
256     public static void updateOperStatus(String interfaceName,
257             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus,
258             WriteTransaction transaction) {
259         LOG.debug("updating operational status for interface {}", interfaceName);
260         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifChildStateId = IfmUtil
261                 .buildStateInterfaceId(interfaceName);
262         InterfaceBuilder ifaceBuilderChild = new InterfaceBuilder();
263         ifaceBuilderChild.setOperStatus(operStatus);
264         ifaceBuilderChild.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceName));
265         transaction.merge(LogicalDatastoreType.OPERATIONAL, ifChildStateId, ifaceBuilderChild.build());
266     }
267
268     public static void addStateEntry(String interfaceName, DataBroker dataBroker,
269                                      IdManagerService idManager, List<ListenableFuture<Void>> futures,
270                                      org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
271         WriteTransaction interfaceOperShardTransaction = dataBroker.newWriteOnlyTransaction();
272         addStateEntry(interfaceName, dataBroker, interfaceOperShardTransaction, idManager, futures, ifState);
273         futures.add(interfaceOperShardTransaction.submit());
274     }
275
276     public static void addStateEntry(String interfaceName, DataBroker dataBroker, WriteTransaction interfaceOperShardTransaction,
277                                      IdManagerService idManager, List<ListenableFuture<Void>> futures,
278                                      org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
279         // allocate lport tag and create interface-if-index map.
280         // This is done even if interface-state is not present, so that there is
281         // no throttling
282         // on id allocation even when multiple southbound port_up events come in
283         // one shot
284         Integer ifIndex = IfmUtil.allocateId(idManager, IfmConstants.IFM_IDPOOL_NAME, interfaceName);
285         InterfaceMetaUtils.createLportTagInterfaceMap(interfaceOperShardTransaction, interfaceName, ifIndex);
286         if (ifState == null) {
287             LOG.debug("could not retrieve interface state corresponding to {}", interfaceName);
288             return;
289         }
290         LOG.debug("adding interface state for {}", interfaceName);
291         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus = ifState
292                 .getOperStatus();
293         PhysAddress physAddress = ifState.getPhysAddress();
294         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus adminStatus = ifState
295                 .getAdminStatus();
296         NodeConnectorId nodeConnectorId = new NodeConnectorId(ifState.getLowerLayerIf().get(0));
297         InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
298         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface interfaceInfo = InterfaceManagerCommonUtils
299                 .getInterfaceFromConfigDS(interfaceKey, dataBroker);
300
301         if (interfaceInfo != null && !interfaceInfo.isEnabled()) {
302             operStatus = org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down;
303         }
304
305         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId = IfmUtil
306                 .buildStateInterfaceId(interfaceName);
307         List<String> childLowerLayerIfList = new ArrayList<>();
308         childLowerLayerIfList.add(0, nodeConnectorId.getValue());
309         InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setAdminStatus(adminStatus).setOperStatus(operStatus)
310                 .setPhysAddress(physAddress).setLowerLayerIf(childLowerLayerIfList);
311         ifaceBuilder.setIfIndex(ifIndex);
312
313         if (interfaceInfo != null) {
314             ifaceBuilder.setType(interfaceInfo.getType());
315         }
316         ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceName));
317         interfaceOperShardTransaction.put(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), true);
318
319         // install ingress flow
320         BigInteger dpId = IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId);
321         long portNo = Long.valueOf(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId));
322         if (interfaceInfo != null && interfaceInfo.isEnabled() && ifState
323                 .getOperStatus() == org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Up) {
324             FlowBasedServicesUtils.installLportIngressFlow(dpId, portNo, interfaceInfo, futures, dataBroker, ifIndex);
325             FlowBasedServicesUtils.bindDefaultEgressDispatcherService(dataBroker, futures, interfaceInfo, Long.toString(portNo), interfaceName, ifIndex);
326         }
327
328         // Update the DpnToInterfaceList OpDS
329         createOrUpdateDpnToInterface(dpId, interfaceName,interfaceOperShardTransaction);
330     }
331
332     public static boolean checkIfBfdStateIsDown(String interfaceName){
333         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus =
334                 InterfaceManagerCommonUtils.getBfdStateFromCache(interfaceName);
335         return (operStatus == org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down);
336     }
337
338     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface addStateEntry(
339             DataBroker dataBroker, Interface interfaceInfo, String interfaceName, WriteTransaction transaction, IdManagerService idManager,
340             PhysAddress physAddress,
341             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus,
342             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus adminStatus,
343             NodeConnectorId nodeConnectorId) {
344         LOG.debug("adding interface state for {}", interfaceName);
345         InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
346         Integer ifIndex = null;
347         if (interfaceInfo != null) {
348             if(!interfaceInfo.isEnabled() || (InterfaceManagerCommonUtils.isTunnelInterface(interfaceInfo) &&
349                     checkIfBfdStateIsDown(interfaceInfo.getName()))){
350                 operStatus = org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down;
351             }
352
353             ifaceBuilder.setType(interfaceInfo.getType());
354             // retrieve if-index only for northbound configured interfaces
355             ifIndex = IfmUtil.allocateId(idManager, IfmConstants.IFM_IDPOOL_NAME, interfaceName);
356             ifaceBuilder.setIfIndex(ifIndex);
357             InterfaceMetaUtils.createLportTagInterfaceMap(transaction, interfaceName, ifIndex);
358         }
359         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId = IfmUtil
360                 .buildStateInterfaceId(interfaceName);
361         List<String> childLowerLayerIfList = new ArrayList<>();
362         childLowerLayerIfList.add(0, nodeConnectorId.getValue());
363         ifaceBuilder.setAdminStatus(adminStatus).setOperStatus(operStatus).setPhysAddress(physAddress)
364                 .setLowerLayerIf(childLowerLayerIfList);
365         ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceName));
366         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = ifaceBuilder
367                 .build();
368         transaction.put(LogicalDatastoreType.OPERATIONAL, ifStateId, ifState, true);
369
370         BigInteger dpId = IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId);
371         // Update the DpnToInterfaceList OpDS
372         createOrUpdateDpnToInterface(dpId, interfaceName, transaction);
373         return ifState;
374     }
375
376     public static void deleteStateEntry(String interfaceName, WriteTransaction transaction) {
377         LOG.debug("removing interface state entry for {}", interfaceName);
378         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifChildStateId = IfmUtil
379                 .buildStateInterfaceId(interfaceName);
380         transaction.delete(LogicalDatastoreType.OPERATIONAL, ifChildStateId);
381     }
382
383     public static void deleteInterfaceStateInformation(String interfaceName, WriteTransaction transaction,
384             IdManagerService idManagerService) {
385         LOG.debug("removing interface state information for {}", interfaceName);
386         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId = IfmUtil
387                 .buildStateInterfaceId(interfaceName);
388         transaction.delete(LogicalDatastoreType.OPERATIONAL, ifStateId);
389         InterfaceMetaUtils.removeLportTagInterfaceMap(idManagerService, transaction, interfaceName);
390     }
391
392     // For trunk interfaces, binding to a parent interface which is already
393     // bound to another trunk interface should not
394     // be allowed
395     public static boolean createInterfaceChildEntryIfNotPresent(DataBroker dataBroker, WriteTransaction t,
396             String parentInterface, String childInterface) {
397         InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentInterface);
398         InstanceIdentifier<InterfaceParentEntry> interfaceParentEntryIdentifier = InterfaceMetaUtils
399                 .getInterfaceParentEntryIdentifier(interfaceParentEntryKey);
400         InterfaceParentEntry interfaceParentEntry = InterfaceMetaUtils
401                 .getInterfaceParentEntryFromConfigDS(interfaceParentEntryIdentifier, dataBroker);
402
403         if (interfaceParentEntry != null) {
404             if (!Objects.equals(parentInterface, interfaceParentEntry.getParentInterface())) {
405                 LOG.error("Trying to bind the same parent interface {} to multiple trunk interfaces. ", parentInterface);
406             } else {
407                 LOG.trace("Child entry for interface {} already exists", childInterface);
408             }
409             return false;
410         }
411
412         LOG.info("First vlan trunk {} bound on parent-interface {}", childInterface, parentInterface);
413         InterfaceChildEntryKey interfaceChildEntryKey = new InterfaceChildEntryKey(childInterface);
414         InstanceIdentifier<InterfaceChildEntry> intfId = InterfaceMetaUtils
415                 .getInterfaceChildEntryIdentifier(interfaceParentEntryKey, interfaceChildEntryKey);
416         InterfaceChildEntryBuilder entryBuilder = new InterfaceChildEntryBuilder().setKey(interfaceChildEntryKey)
417                 .setChildInterface(childInterface);
418         t.put(LogicalDatastoreType.CONFIGURATION, intfId, entryBuilder.build(), true);
419         return true;
420     }
421
422     public static boolean deleteParentInterfaceEntry(WriteTransaction t, String parentInterface) {
423         InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentInterface);
424         InstanceIdentifier<InterfaceParentEntry> interfaceParentEntryIdentifier = InterfaceMetaUtils
425                 .getInterfaceParentEntryIdentifier(interfaceParentEntryKey);
426         t.delete(LogicalDatastoreType.CONFIGURATION, interfaceParentEntryIdentifier);
427         return true;
428     }
429
430     /*
431      * update operational state of interface based on events like tunnel
432      * monitoring
433      */
434     public static void updateOpState(WriteTransaction transaction, String interfaceName,
435             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus) {
436         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId = IfmUtil
437                 .buildStateInterfaceId(interfaceName);
438         LOG.debug("updating tep interface state as {} for {}", operStatus.name(), interfaceName);
439         InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setOperStatus(operStatus);
440         ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceName));
441         transaction.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), false);
442     }
443
444     public static boolean isTunnelInterface(Interface interfaceInfo) {
445         return interfaceInfo != null && interfaceInfo.getAugmentation(IfTunnel.class) != null;
446     }
447
448     public static boolean isVlanInterface(Interface interfaceInfo) {
449         return interfaceInfo != null && interfaceInfo.getAugmentation(IfL2vlan.class) != null;
450     }
451
452     // Cache Util methods
453     public static void addInterfaceToCache(Interface iface) {
454         interfaceConfigMap.put(iface.getName(), iface);
455     }
456
457     public static void removeFromInterfaceCache(Interface iface) {
458         interfaceConfigMap.remove(iface.getName());
459     }
460
461     public static void addInterfaceStateToCache(
462             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface iface) {
463         interfaceStateMap.put(iface.getName(), iface);
464     }
465
466     public static void removeFromInterfaceStateCache(
467             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface iface) {
468         interfaceStateMap.remove(iface.getName());
469     }
470
471     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus getBfdStateFromCache(String interfaceName) {
472         return bfdStateMap.get(interfaceName);
473     }
474
475     public static void addBfdStateToCache(String interfaceName,
476                                           org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus) {
477         bfdStateMap.put(interfaceName, operStatus);
478     }
479
480     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus removeBfdStateFromCache(String interfaceName){
481         return bfdStateMap.remove(interfaceName);
482     }
483
484     public static boolean isNovaOrTunnelPort(String portName) {
485
486         Matcher matcher = pattern.matcher(portName);
487         return matcher.matches();
488     }
489
490
491     public static void createOrUpdateDpnToInterface(BigInteger dpId, String infName, WriteTransaction transaction) {
492         DpnToInterfaceKey dpnToInterfaceKey = new DpnToInterfaceKey(dpId);
493         InterfaceNameEntryKey interfaceNameEntryKey = new InterfaceNameEntryKey(infName);
494         InstanceIdentifier<InterfaceNameEntry> intfid = InstanceIdentifier.builder(DpnToInterfaceList.class)
495                                                         .child(DpnToInterface.class, dpnToInterfaceKey)
496                                                         .child(InterfaceNameEntry.class, interfaceNameEntryKey)
497                                                         .build();
498         InterfaceNameEntryBuilder entryBuilder = new InterfaceNameEntryBuilder().setKey(interfaceNameEntryKey).setInterfaceName(infName);
499         transaction.put(LogicalDatastoreType.OPERATIONAL, intfid, entryBuilder.build(), true);
500     }
501
502     public static void deleteDpnToInterface(DataBroker dataBroker, BigInteger dpId, String infName, WriteTransaction transaction) {
503         DpnToInterfaceKey dpnToInterfaceKey = new DpnToInterfaceKey(dpId);
504         InstanceIdentifier<DpnToInterface> dpnToInterfaceId = InstanceIdentifier.builder(DpnToInterfaceList.class)
505                 .child(DpnToInterface.class, dpnToInterfaceKey).build();
506         Optional<DpnToInterface> dpnToInterfaceOptional = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, dpnToInterfaceId, dataBroker);
507         if (!dpnToInterfaceOptional.isPresent()) {
508             LOG.debug("DPN {} is already removed from the Operational DS", dpId);
509             return;
510         }
511
512         List<InterfaceNameEntry> interfaceNameEntries = dpnToInterfaceOptional.get().getInterfaceNameEntry();
513         InterfaceNameEntryKey interfaceNameEntryKey = new InterfaceNameEntryKey(infName);
514         InstanceIdentifier<InterfaceNameEntry> intfid = InstanceIdentifier.builder(DpnToInterfaceList.class)
515                 .child(DpnToInterface.class, dpnToInterfaceKey)
516                 .child(InterfaceNameEntry.class, interfaceNameEntryKey)
517                 .build();
518         transaction.delete(LogicalDatastoreType.OPERATIONAL, intfid);
519
520         if (interfaceNameEntries.size() <=1) {
521             transaction.delete(LogicalDatastoreType.OPERATIONAL, dpnToInterfaceId);
522         }
523     }
524
525 }