Freeze upstream versions
[genius.git] / itm / itm-impl / src / main / java / org / opendaylight / genius / itm / listeners / OvsdbNodeListener.java
1 /*
2  * Copyright (c) 2016, 2017 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.itm.listeners;
10
11 import java.time.Duration;
12 import java.util.List;
13 import java.util.Map;
14 import javax.inject.Inject;
15 import javax.inject.Singleton;
16 import org.eclipse.jdt.annotation.NonNull;
17 import org.eclipse.jdt.annotation.Nullable;
18 import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
19 import org.opendaylight.genius.itm.commons.OvsdbTepInfo;
20 import org.opendaylight.genius.itm.confighelpers.OvsdbTepAddWorker;
21 import org.opendaylight.genius.itm.confighelpers.OvsdbTepRemoveWorker;
22 import org.opendaylight.genius.itm.globals.ITMConstants;
23 import org.opendaylight.genius.itm.impl.ItmUtils;
24 import org.opendaylight.genius.mdsalutil.MDSALUtil;
25 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
26 import org.opendaylight.mdsal.binding.api.DataBroker;
27 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
28 import org.opendaylight.serviceutils.tools.listener.AbstractSyncDataTreeChangeListener;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembership;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchExternalIds;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchExternalIdsKey;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigsKey;
46 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
47 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
48 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
49 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
50 import org.opendaylight.yangtools.yang.common.Uint64;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54 /**
55  * This class listens for OvsdbNode creation/removal/update in Network Topology Operational DS.
56  * This is used to handle add/update/remove of TEPs of switches into/from ITM.
57  */
58 @Singleton
59 public class OvsdbNodeListener extends AbstractSyncDataTreeChangeListener<Node> {
60
61     private static final Logger LOG = LoggerFactory.getLogger(OvsdbNodeListener.class);
62
63     private final DataBroker dataBroker;
64     private final JobCoordinator jobCoordinator;
65     private final ItmConfig itmConfig;
66     private final DataTreeEventCallbackRegistrar eventCallbacks;
67
68     @Inject
69     public OvsdbNodeListener(DataBroker dataBroker, ItmConfig itmConfig, JobCoordinator jobCoordinator,
70                              DataTreeEventCallbackRegistrar eventCallbacks,
71                              final IdManagerService idManagerService) {
72         super(dataBroker, LogicalDatastoreType.OPERATIONAL,
73               InstanceIdentifier.create(NetworkTopology.class).child(Topology.class).child(Node.class));
74         this.dataBroker = dataBroker;
75         this.jobCoordinator = jobCoordinator;
76         this.itmConfig = itmConfig;
77         this.eventCallbacks = eventCallbacks;
78     }
79
80     @Override
81     public void add(@NonNull InstanceIdentifier<Node> instanceIdentifier, @NonNull Node ovsdbNodeNew) {
82         String bridgeName = null;
83         String strDpnId = "";
84         OvsdbNodeAugmentation ovsdbNewNodeAugmentation = null;
85
86         LOG.trace("OvsdbNodeListener called for Ovsdb Node ({}) Add.", ovsdbNodeNew.getNodeId().getValue());
87
88         // check for OVS bridge node
89         OvsdbBridgeAugmentation ovsdbNewBridgeAugmentation = ovsdbNodeNew
90                 .augmentation(OvsdbBridgeAugmentation.class);
91
92         if (ovsdbNewBridgeAugmentation != null) {
93             processBridgeUpdate(ovsdbNewBridgeAugmentation, true);
94         }
95     }
96
97     @Override
98     public void remove(@NonNull InstanceIdentifier<Node> instanceIdentifier, @NonNull Node removedDataObject) {
99         LOG.trace("OvsdbNodeListener called for Ovsdb Node {} Remove.", removedDataObject);
100         processBridgeUpdate(removedDataObject, false);
101     }
102
103     @Override
104     public void update(@NonNull InstanceIdentifier<Node> instanceIdentifier, @NonNull Node originalOvsdbNode,
105                        @NonNull Node updatedOvsdbNode) {
106         String newLocalIp = null;
107         String oldLocalIp = null;
108         String tzName = null;
109         String oldTzName = null;
110         String oldDpnBridgeName = null;
111         String newDpnBridgeName = null;
112         boolean newOfTunnel = false;
113         boolean isTepInfoUpdated = false;
114         boolean isTepInfoDeleted = false;
115         boolean isLocalIpAdded = false;
116         boolean isLocalIpRemoved = false;
117         boolean isLocalIpUpdated = false;
118         boolean isTzChanged = false;
119         boolean isDpnBrChanged = false;
120
121         LOG.trace("OvsdbNodeListener called for Ovsdb Node ({}) Update.", originalOvsdbNode.getNodeId().getValue());
122
123         // If this is a bridge update, see if dpid was added. If so, need to
124         // addTep, as TEP would not be added in node add case above
125         if (isBridgeDpIdAdded(originalOvsdbNode, updatedOvsdbNode)) {
126             processBridgeUpdate(updatedOvsdbNode, true);
127             return;
128         }
129
130         // get OVSDB TEP info from old ovsdb node
131         OvsdbTepInfo newTepInfoObj = getOvsdbTepInfo(
132                 updatedOvsdbNode.augmentation(OvsdbNodeAugmentation.class));
133
134         // get OVSDB TEP info from new ovsdb node
135         OvsdbTepInfo oldTepInfoObj = getOvsdbTepInfo(
136                 originalOvsdbNode.augmentation(OvsdbNodeAugmentation.class));
137
138         if (oldTepInfoObj == null && newTepInfoObj == null) {
139             LOG.trace("Tep Info is not received in old and new Ovsdb Nodes.");
140             return;
141         }
142
143         if (oldTepInfoObj != null && newTepInfoObj == null) {
144             isTepInfoDeleted = true;
145             LOG.trace("Tep Info is deleted from Ovsdb node: {}", originalOvsdbNode.getNodeId().getValue());
146         }
147
148         // store TEP info required parameters
149         if (newTepInfoObj != null) {
150             tzName = newTepInfoObj.getTzName();
151             newLocalIp = newTepInfoObj.getLocalIp();
152             newDpnBridgeName = newTepInfoObj.getBrName();
153             newOfTunnel = newTepInfoObj.getOfTunnel();
154         }
155
156         if (oldTepInfoObj != null) {
157             oldLocalIp = oldTepInfoObj.getLocalIp();
158             oldDpnBridgeName = oldTepInfoObj.getBrName();
159             oldTzName = oldTepInfoObj.getTzName();
160         }
161
162         // handle case when TEP parameters are not configured from switch side
163         if (newLocalIp == null && oldLocalIp == null) {
164             LOG.trace("TEP info Local IP parameters are not specified in old and new Ovsdb Nodes.");
165             return;
166         }
167
168         if (!isTepInfoDeleted) {
169             isLocalIpRemoved = isLocalIpRemoved(oldLocalIp, newLocalIp);
170             isLocalIpAdded = isLocalIpAdded(oldLocalIp, newLocalIp);
171             isLocalIpUpdated = isLocalIpUpdated(oldLocalIp, newLocalIp);
172
173             if (isLocalIpAdded || isLocalIpRemoved || isLocalIpUpdated) {
174                 isTepInfoUpdated = true;
175             }
176             if (isTzUpdated(oldTzName, tzName)) {
177                 isTepInfoUpdated = true;
178                 if (oldLocalIp != null && newLocalIp != null) {
179                     isTzChanged = true;
180                     LOG.trace("tzname is changed from {} to {} for Local IP: {}", oldTzName, tzName, newLocalIp);
181                 }
182             }
183             if (isDpnUpdated(oldDpnBridgeName, newDpnBridgeName)) {
184                 isTepInfoUpdated = true;
185                 if (oldLocalIp != null && newLocalIp != null) {
186                     isDpnBrChanged = true;
187                     LOG.trace("dpn-br-name is changed from {} to {} for Local IP: {}", oldDpnBridgeName,
188                             newDpnBridgeName, newLocalIp);
189                 }
190             }
191
192             if (!isTepInfoUpdated) {
193                 LOG.trace("Old TEP (local-ip: {}, tz-name: {}) and New TEP (local-ip: {}, tz-name: {}). "
194                         + "No updates in the TEP Info parameters. Nothing to do.", oldLocalIp, oldTzName,
195                         newLocalIp, tzName);
196                 return;
197             }
198         }
199
200         LOG.trace("TepInfo state change flags (isTepInfoUpdated: {}, isTepInfoDeleted: {}, isLocalIpRemoved: {},"
201                 + "isLocalIpAdded: {}, isLocalIpUpdated: {}, isTzChanged:{}, isDpnBrChanged: {})",
202                 isTepInfoUpdated, isTepInfoDeleted, isLocalIpRemoved, isLocalIpAdded, isLocalIpUpdated,
203                 isTzChanged, isDpnBrChanged);
204
205         String jobKey = oldLocalIp;
206         // handle TEP-remove in remove case, tep-ip update case, TZ change case, Bridge change case
207         if (isTepInfoDeleted || isLocalIpRemoved || isTzChanged || isDpnBrChanged || isLocalIpUpdated) {
208             // TBD: Move this time taking operations into DataStoreJobCoordinator
209             String strOldDpnId = ItmUtils.getBridgeDpid(originalOvsdbNode, oldDpnBridgeName, dataBroker);
210             if (strOldDpnId == null || strOldDpnId.isEmpty()) {
211                 LOG.error("TEP {} cannot be deleted. DPID for bridge {} is NULL.", oldLocalIp, oldDpnBridgeName);
212                 return;
213             }
214             addOrRemoveTep(oldTzName, strOldDpnId, jobKey, oldLocalIp, oldDpnBridgeName, false, false);
215         }
216         // handle TEP-add in add case, tep-ip update case, TZ change case, Bridge change case
217         if (isLocalIpAdded || isTzChanged || isDpnBrChanged || isLocalIpUpdated) {
218             // TBD: Move this time taking operations into DataStoreJobCoordinator
219             String strNewDpnId = ItmUtils.getBridgeDpid(updatedOvsdbNode, newDpnBridgeName, dataBroker);
220             if (strNewDpnId == null || strNewDpnId.isEmpty()) {
221                 LOG.error("TEP {} cannot be added. DPID for bridge {} is NULL.", newLocalIp, newDpnBridgeName);
222                 return;
223             }
224             /*
225              * Special handling for TEP movement from one TZ to another TZ
226              * Register for DpnTepsInfo remove event to make sure TEP remove is happened through ITM internal logic,
227              * then after perform TEP addition into updated TZ
228              */
229             if (isTzChanged) {
230                 IpAddress tepIpAddress = IpAddressBuilder.getDefaultInstance(newLocalIp);
231                 Uint64 dpnId = MDSALUtil.getDpnId(strNewDpnId);
232                 String tos = itmConfig.getDefaultTunnelTos();
233                 Class<? extends TunnelTypeBase> tunnelType  = TunnelTypeVxlan.class;
234                 List<TzMembership> zones = ItmUtils.createTransportZoneMembership(oldTzName);
235
236                 String portName = itmConfig.getPortname() == null ? ITMConstants.DUMMY_PORT : itmConfig.getPortname();
237                 int vlanId = itmConfig.getVlanId() != null ? itmConfig.getVlanId().toJava()
238                                                              : ITMConstants.DUMMY_VLANID;
239
240                 TunnelEndPoints tunnelEndPoints = ItmUtils.createDummyTunnelEndPoints(dpnId, tepIpAddress, newOfTunnel,
241                         tos, zones, tunnelType, portName, vlanId);
242                 String finalTzName = tzName;
243                 String finalJobKey = jobKey;
244                 String finalLocalIp = newLocalIp;
245                 String finalDpnBridgeName = newDpnBridgeName;
246                 boolean finalOfTunnel = newOfTunnel;
247
248                 InstanceIdentifier<TunnelEndPoints> tunnelEndPointsIdentifier =
249                         InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class,
250                                 new DPNTEPsInfoKey(dpnId)).child(TunnelEndPoints.class, tunnelEndPoints.key()).build();
251                 eventCallbacks.onRemove(LogicalDatastoreType.CONFIGURATION, tunnelEndPointsIdentifier, (unused) -> {
252                     LOG.info("TZ movement case: callback event for a deletion of {} from DpnTepsInfo.", dpnId);
253                     addOrRemoveTep(finalTzName, strNewDpnId, finalJobKey, finalLocalIp,
254                                     finalDpnBridgeName, finalOfTunnel, true);
255                     return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
256                 }, Duration.ofMillis(5000), (id) -> {
257                         LOG.info("TZ movement case: callback event timed-out for a deletion of {} from DpnTepsInfo.",
258                                 dpnId);
259                         addOrRemoveTep(finalTzName, strNewDpnId, finalJobKey, finalLocalIp,
260                             finalDpnBridgeName, finalOfTunnel, true);
261                     });
262             } else {
263                 jobKey = isLocalIpUpdated ? oldLocalIp : newLocalIp;
264                 addOrRemoveTep(tzName, strNewDpnId, jobKey, newLocalIp, newDpnBridgeName,  newOfTunnel, true);
265             }
266         }
267     }
268
269     private void addOrRemoveTep(String tzName, String strDpnId, String jobKey, String localIp, String  bridgeName,
270                                 boolean newOfTunnel, boolean isTepAdd) {
271         // check if defTzEnabled flag is false in config file,
272         // if flag is OFF, then no need to add TEP into ITM config DS.
273         if (tzName == null || tzName.equals(ITMConstants.DEFAULT_TRANSPORT_ZONE)) {
274             boolean defTzEnabled = itmConfig.isDefTzEnabled();
275             if (!defTzEnabled) {
276                 if (isTepAdd) {
277                     LOG.info("TEP ({}) cannot be added into {} when def-tz-enabled flag is false.", localIp,
278                             ITMConstants.DEFAULT_TRANSPORT_ZONE);
279                 } else {
280                     LOG.info("TEP ({}) cannot be removed from {} when def-tz-enabled flag is false.", localIp,
281                             ITMConstants.DEFAULT_TRANSPORT_ZONE);
282                 }
283                 return;
284             }
285             tzName = ITMConstants.DEFAULT_TRANSPORT_ZONE;
286         }
287
288         if (isTepAdd) {
289             // add TEP
290             LOG.trace("Update case: Adding TEP-IP: {}, TZ name: {}, Bridge Name: {}, Bridge DPID: {}, of-tunnel: {}",
291                     localIp, tzName, bridgeName, strDpnId, newOfTunnel);
292
293             // Enqueue 'add TEP into new TZ' operation into DataStoreJobCoordinator
294             jobCoordinator.enqueueJob(jobKey,
295                     new OvsdbTepAddWorker(localIp, strDpnId, tzName, newOfTunnel, dataBroker));
296         } else {
297             // remove TEP
298             LOG.trace("Update case: Removing TEP-IP: {}, TZ name: {}, Bridge Name: {}, Bridge DPID: {}", localIp,
299                     tzName, bridgeName, strDpnId);
300
301             // Enqueue 'remove TEP from TZ' operation into DataStoreJobCoordinator
302             jobCoordinator.enqueueJob(jobKey, new OvsdbTepRemoveWorker(localIp, strDpnId, tzName, dataBroker));
303         }
304     }
305
306     private boolean isLocalIpRemoved(String oldTepIp, String newTepIp) {
307         return oldTepIp != null && newTepIp == null;
308     }
309
310     private boolean isLocalIpAdded(String oldTepIp, String newTepIp) {
311         return oldTepIp == null && newTepIp != null;
312     }
313
314     private boolean isLocalIpUpdated(String oldTepIp, String newTepIp) {
315         return oldTepIp != null && newTepIp != null && !oldTepIp.equals(newTepIp);
316     }
317
318     private boolean isTzUpdated(String oldTzName, String tzName) {
319         return oldTzName == null && tzName != null || oldTzName != null && tzName == null
320                 || oldTzName != null && !oldTzName.equals(tzName);
321     }
322
323     private boolean isDpnUpdated(String oldDpnBridgeName, String dpnBridgeName) {
324         return oldDpnBridgeName == null && dpnBridgeName != null || oldDpnBridgeName != null && dpnBridgeName == null
325                 || oldDpnBridgeName != null && !oldDpnBridgeName.equals(dpnBridgeName);
326     }
327
328     private boolean isBridgeDpIdAdded(Node ovsdbNodeOld, Node ovsdbNodeNew) {
329         String oldBridgeName = null;
330         String oldDpId = null;
331         String newDpId = null;
332
333         OvsdbBridgeAugmentation ovsdbNewBridgeAugmentation =
334                 ovsdbNodeNew.augmentation(OvsdbBridgeAugmentation.class);
335         if (ovsdbNewBridgeAugmentation != null) {
336             // Read DPID from OVSDBBridgeAugmentation
337             newDpId = ItmUtils.getStrDatapathId(ovsdbNewBridgeAugmentation);
338         }
339
340         OvsdbBridgeAugmentation ovsdbOldBridgeAugmentation =
341                 ovsdbNodeOld.augmentation(OvsdbBridgeAugmentation.class);
342         if (ovsdbOldBridgeAugmentation != null) {
343             oldBridgeName = ovsdbNewBridgeAugmentation.getBridgeName().getValue();
344             // Read DPID from OVSDBBridgeAugmentation
345             oldDpId = ItmUtils.getStrDatapathId(ovsdbOldBridgeAugmentation);
346         }
347         if (oldDpId == null && newDpId != null) {
348             LOG.trace("DpId changed to {} for bridge {}", newDpId, oldBridgeName);
349             return true;
350         }
351         return false;
352     }
353
354     private OvsdbTepInfo getOvsdbTepInfo(OvsdbNodeAugmentation ovsdbNodeAugmentation) {
355         if (ovsdbNodeAugmentation == null) {
356             return null;
357         }
358
359         @Nullable Map<OpenvswitchOtherConfigsKey, OpenvswitchOtherConfigs> ovsdbNodeOtherConfigsList =
360                 ovsdbNodeAugmentation.getOpenvswitchOtherConfigs();
361         if (ovsdbNodeOtherConfigsList == null) {
362             //Local IP is not configured
363             LOG.debug("OtherConfigs list does not exist in the OVSDB Node Augmentation.");
364             return null;
365         }
366
367         OvsdbTepInfo ovsdbTepInfoObj = new OvsdbTepInfo();
368
369         for (OpenvswitchOtherConfigs otherConfigs : ovsdbNodeOtherConfigsList.values()) {
370             if (ITMConstants.OTH_CFG_TEP_PARAM_KEY_LOCAL_IP.equals(otherConfigs.getOtherConfigKey())) {
371                 String tepIp = otherConfigs.getOtherConfigValue();
372                 ovsdbTepInfoObj.setLocalIp(tepIp);
373             }
374         }
375
376         @Nullable Map<OpenvswitchExternalIdsKey, OpenvswitchExternalIds> ovsdbNodeExternalIdsList =
377                 ovsdbNodeAugmentation.getOpenvswitchExternalIds();
378         if (ovsdbNodeExternalIdsList == null) {
379             LOG.debug("ExternalIds list does not exist in the OVSDB Node Augmentation.");
380         } else {
381             for (OpenvswitchExternalIds externalId : ovsdbNodeExternalIdsList.values()) {
382                 switch (externalId.getExternalIdKey()) {
383                     case ITMConstants.EXT_ID_TEP_PARAM_KEY_TZNAME:
384                         ovsdbTepInfoObj.setTzName(externalId.getExternalIdValue());
385                         break;
386                     case ITMConstants.EXT_ID_TEP_PARAM_KEY_BR_NAME:
387                         ovsdbTepInfoObj.setBrName(externalId.getExternalIdValue());
388                         break;
389                     case ITMConstants.EXT_ID_TEP_PARAM_KEY_OF_TUNNEL:
390                         ovsdbTepInfoObj.setOfTunnel(Boolean.parseBoolean(externalId.getExternalIdValue()));
391                         break;
392                     default:
393                         break;
394                 }
395             }
396         }
397         return ovsdbTepInfoObj;
398     }
399
400     private void processBridgeUpdate(Node ovsdbNodeNew, boolean isBridgeAdd) {
401         OvsdbBridgeAugmentation ovsdbNewBridgeAugmentation =
402                 ovsdbNodeNew.augmentation(OvsdbBridgeAugmentation.class);
403         if (ovsdbNewBridgeAugmentation != null) {
404             processBridgeUpdate(ovsdbNewBridgeAugmentation, isBridgeAdd);
405         }
406     }
407
408     private void processBridgeUpdate(OvsdbBridgeAugmentation ovsdbNewBridgeAugmentation, boolean isBridgeAdd) {
409         String bridgeName = null;
410         String strDpnId = null;
411         OvsdbNodeAugmentation ovsdbNewNodeAugmentation = null;
412
413         if (ovsdbNewBridgeAugmentation != null) {
414             bridgeName = ovsdbNewBridgeAugmentation.getBridgeName().getValue();
415
416             // Read DPID from OVSDBBridgeAugmentation
417             strDpnId = ItmUtils.getStrDatapathId(ovsdbNewBridgeAugmentation);
418             if (strDpnId == null || strDpnId.isEmpty()) {
419                 LOG.trace("OvsdbBridgeAugmentation processBridgeUpdate: DPID for bridge {} is NULL.", bridgeName);
420                 return;
421             }
422
423             // TBD: Move this time taking operations into DataStoreJobCoordinator
424             Node ovsdbNodeFromBridge = ItmUtils.getOvsdbNode(ovsdbNewBridgeAugmentation, dataBroker);
425             // check for OVSDB node. NOTE: it can be null during bridge removal notification
426             // when switch is disconnected
427             if (ovsdbNodeFromBridge != null) {
428                 ovsdbNewNodeAugmentation = ovsdbNodeFromBridge.augmentation(OvsdbNodeAugmentation.class);
429             } else {
430                 LOG.warn("processBridgeUpdate: bridge {} removal case when Switch is disconnected."
431                          + "Hence, Ovsdb Node could not be fetched from Oper DS.", bridgeName);
432                 return;
433             }
434         }
435
436         if (ovsdbNewNodeAugmentation != null) {
437             OvsdbTepInfo ovsdbTepInfo = getOvsdbTepInfo(ovsdbNewNodeAugmentation);
438
439             if (ovsdbTepInfo == null) {
440                 LOG.trace("processBridgeUpdate: No Tep Info");
441                 return;
442             }
443             // store TEP info required parameters
444             String newLocalIp = ovsdbTepInfo.getLocalIp();
445             String tzName = ovsdbTepInfo.getTzName();
446             String newBridgeName = ovsdbTepInfo.getBrName();
447             boolean ofTunnel = ovsdbTepInfo.getOfTunnel();
448
449             // check if Local IP is configured or not
450             if (newLocalIp != null && !newLocalIp.isEmpty()) {
451                 // if bridge received is the one configured for TEPs from OVS side or
452                 // if it is br-int, then add TEP into Config DS
453                 if (newBridgeName.equals(bridgeName)) {
454                     LOG.trace("processBridgeUpdate for bridge {} that is configured with Local IP.", bridgeName);
455                     String jobKey = newLocalIp;
456                     // add or remove tep based on bridge (br-int) is added or removed
457                     addOrRemoveTep(tzName, strDpnId, jobKey, newLocalIp, newBridgeName,  ofTunnel, isBridgeAdd);
458                 } else {
459                     LOG.trace("processBridgeUpdate invoked for bridge {}, nothing to do.", bridgeName);
460                 }
461             } else {
462                 LOG.trace("processBridgeUpdate for bridge {} without Local IP set for ovs node. Nothing to do.",
463                           bridgeName);
464             }
465         }
466     }
467 }