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