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