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