20cab60baf23b6dc1b7f3d1de8b8708a464c26a8
[genius.git] / itm / itm-impl / src / main / java / org / opendaylight / genius / itm / listeners / TransportZoneListener.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 package org.opendaylight.genius.itm.listeners;
9
10 import com.google.common.util.concurrent.FluentFuture;
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.Map.Entry;
17 import java.util.Objects;
18 import java.util.Optional;
19 import java.util.concurrent.ConcurrentHashMap;
20 import javax.inject.Inject;
21 import javax.inject.Singleton;
22 import org.eclipse.jdt.annotation.NonNull;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.opendaylight.genius.cloudscaler.api.TombstonedNodeManager;
25 import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
26 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
27 import org.opendaylight.genius.itm.cache.DPNTEPsInfoCache;
28 import org.opendaylight.genius.itm.cache.DpnTepStateCache;
29 import org.opendaylight.genius.itm.cache.OfEndPointCache;
30 import org.opendaylight.genius.itm.cache.OvsBridgeEntryCache;
31 import org.opendaylight.genius.itm.cache.OvsBridgeRefEntryCache;
32 import org.opendaylight.genius.itm.cache.TunnelStateCache;
33 import org.opendaylight.genius.itm.confighelpers.HwVtep;
34 import org.opendaylight.genius.itm.confighelpers.ItmExternalTunnelAddWorker;
35 import org.opendaylight.genius.itm.confighelpers.ItmInternalTunnelAddWorker;
36 import org.opendaylight.genius.itm.confighelpers.ItmInternalTunnelDeleteWorker;
37 import org.opendaylight.genius.itm.confighelpers.ItmTepAddWorker;
38 import org.opendaylight.genius.itm.confighelpers.ItmTepRemoveWorker;
39 import org.opendaylight.genius.itm.confighelpers.ItmTepsNotHostedAddWorker;
40 import org.opendaylight.genius.itm.confighelpers.ItmTepsNotHostedMoveWorker;
41 import org.opendaylight.genius.itm.confighelpers.ItmTepsNotHostedRemoveWorker;
42 import org.opendaylight.genius.itm.globals.ITMConstants;
43 import org.opendaylight.genius.itm.impl.ItmUtils;
44 import org.opendaylight.genius.itm.impl.TunnelMonitoringConfig;
45 import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
46 import org.opendaylight.genius.itm.recovery.impl.ItmServiceRecoveryHandler;
47 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
48 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
49 import org.opendaylight.mdsal.binding.api.DataBroker;
50 import org.opendaylight.mdsal.binding.util.Datastore;
51 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
52 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl;
53 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
54 import org.opendaylight.serviceutils.srm.RecoverableListener;
55 import org.opendaylight.serviceutils.srm.ServiceRecoveryRegistry;
56 import org.opendaylight.serviceutils.tools.listener.AbstractSyncDataTreeChangeListener;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembership;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.NotHostedTransportZones;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZonesBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.not.hosted.transport.zones.TepsInNotHostedTransportZone;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.not.hosted.transport.zones.TepsInNotHostedTransportZoneKey;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.not.hosted.transport.zones.tepsinnothostedtransportzone.UnknownVteps;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.not.hosted.transport.zones.tepsinnothostedtransportzone.UnknownVtepsBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.not.hosted.transport.zones.tepsinnothostedtransportzone.UnknownVtepsKey;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.DeviceVteps;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.DeviceVtepsKey;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Vteps;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.VtepsBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.VtepsKey;
77 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
78 import org.opendaylight.yangtools.yang.common.Uint64;
79 import org.slf4j.Logger;
80 import org.slf4j.LoggerFactory;
81
82 /**
83  * This class listens for interface creation/removal/update in Configuration DS.
84  * This is used to handle interfaces for base of-ports.
85  */
86 @Singleton
87 public class TransportZoneListener extends AbstractSyncDataTreeChangeListener<TransportZone>
88         implements RecoverableListener {
89
90     private static final Logger LOG = LoggerFactory.getLogger(TransportZoneListener.class);
91     private static final Logger EVENT_LOGGER = LoggerFactory.getLogger("GeniusEventLogger");
92
93     private final DataBroker dataBroker;
94     private final JobCoordinator jobCoordinator;
95     private final IMdsalApiManager mdsalManager;
96     private final ItmConfig itmConfig;
97     private final ItmInternalTunnelDeleteWorker itmInternalTunnelDeleteWorker;
98     private final ItmInternalTunnelAddWorker itmInternalTunnelAddWorker;
99     private final ItmExternalTunnelAddWorker externalTunnelAddWorker;
100     private final DPNTEPsInfoCache dpnTEPsInfoCache;
101     private final ManagedNewTransactionRunner txRunner;
102     private final DataTreeEventCallbackRegistrar eventCallbacks;
103     private final TombstonedNodeManager tombstonedNodeManager;
104
105     @Inject
106     public TransportZoneListener(final DataBroker dataBroker,
107                                  final IMdsalApiManager mdsalManager,
108                                  final ItmConfig itmConfig, final JobCoordinator jobCoordinator,
109                                  final TunnelMonitoringConfig tunnelMonitoringConfig,
110                                  final DPNTEPsInfoCache dpnTEPsInfoCache,
111                                  final TunnelStateCache tunnelStateCache,
112                                  final DirectTunnelUtils directTunnelUtils,
113                                  final DpnTepStateCache dpnTepStateCache, final OvsBridgeEntryCache ovsBridgeEntryCache,
114                                  final OvsBridgeRefEntryCache ovsBridgeRefEntryCache,
115                                  final IInterfaceManager interfaceManager,
116                                  final OfEndPointCache ofEndPointCache,
117                                  final ServiceRecoveryRegistry serviceRecoveryRegistry,
118                                  final DataTreeEventCallbackRegistrar eventCallbacks,
119                                  final TombstonedNodeManager tombstonedNodeManager) {
120         super(dataBroker, LogicalDatastoreType.CONFIGURATION,
121                 InstanceIdentifier.create(TransportZones.class).child(TransportZone.class));
122         this.dataBroker = dataBroker;
123         this.jobCoordinator = jobCoordinator;
124         this.mdsalManager = mdsalManager;
125         this.itmConfig = itmConfig;
126         this.dpnTEPsInfoCache = dpnTEPsInfoCache;
127         this.tombstonedNodeManager = tombstonedNodeManager;
128         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
129         this.eventCallbacks = eventCallbacks;
130         initializeTZNode();
131         this.itmInternalTunnelDeleteWorker = new ItmInternalTunnelDeleteWorker(dataBroker, jobCoordinator,
132                 tunnelMonitoringConfig, interfaceManager, dpnTepStateCache, ovsBridgeEntryCache,
133                 ovsBridgeRefEntryCache, tunnelStateCache, directTunnelUtils, ofEndPointCache, itmConfig,
134                 tombstonedNodeManager);
135         this.itmInternalTunnelAddWorker = new ItmInternalTunnelAddWorker(dataBroker, jobCoordinator,
136                 tunnelMonitoringConfig, itmConfig, directTunnelUtils, interfaceManager,
137                 ovsBridgeRefEntryCache, ofEndPointCache, eventCallbacks);
138         this.externalTunnelAddWorker = new ItmExternalTunnelAddWorker(itmConfig, dpnTEPsInfoCache);
139         serviceRecoveryRegistry.addRecoverableListener(ItmServiceRecoveryHandler.getServiceRegistryKey(),
140                 this);
141     }
142
143     @Override
144     public void registerListener() {
145         register();
146     }
147
148     @Override
149     public void deregisterListener() {
150         close();
151     }
152
153     @SuppressWarnings("checkstyle:IllegalCatch")
154     private void initializeTZNode() {
155         InstanceIdentifier<TransportZones> path = InstanceIdentifier.create(TransportZones.class);
156         txRunner.callWithNewReadWriteTransactionAndSubmit(Datastore.CONFIGURATION, tx -> {
157             FluentFuture<Boolean> tzones = tx.exists(path);
158             if (!tzones.get()) {
159                 TransportZonesBuilder tzb = new TransportZonesBuilder();
160                 tx.put(path, tzb.build());
161             }
162         }).isDone();
163     }
164
165     @Override
166     public void remove(@NonNull InstanceIdentifier<TransportZone> instanceIdentifier,
167                        @NonNull TransportZone transportZone) {
168         LOG.debug("Received Transport Zone Remove Event: {}", transportZone);
169         boolean allowTunnelDeletion;
170
171         // check if TZ received for removal is default-transport-zone,
172         // if yes, then check if it is received from northbound, then
173         // do not entertain request and skip tunnels remove operation
174         // if def-tz removal request is due to def-tz-enabled flag is disabled or
175         // due to change in def-tz-tunnel-type, then allow def-tz tunnels deletion
176         if (ITMConstants.DEFAULT_TRANSPORT_ZONE.equalsIgnoreCase(transportZone.getZoneName())) {
177             // Get TunnelTypeBase object for tunnel-type configured in config file
178             Class<? extends TunnelTypeBase> tunType = ItmUtils.getTunnelType(itmConfig.getDefTzTunnelType());
179
180             if (!itmConfig.isDefTzEnabled() || !Objects.equals(transportZone.getTunnelType(), tunType)) {
181                 allowTunnelDeletion = true;
182             } else {
183                 // this is case when def-tz removal request is from Northbound.
184                 allowTunnelDeletion = false;
185                 LOG.error("Deletion of {} is an incorrect usage",ITMConstants.DEFAULT_TRANSPORT_ZONE);
186             }
187         } else {
188             allowTunnelDeletion = true;
189         }
190
191         if (allowTunnelDeletion) {
192             //TODO : DPList code can be refactor with new specific class
193             // which implement TransportZoneValidator
194             EVENT_LOGGER.debug("ITM-Transportzone,TunnelDeletion {}", transportZone.getZoneName());
195             List<DPNTEPsInfo> opDpnList = createDPNTepInfo(transportZone);
196             List<HwVtep> hwVtepList = createhWVteps(transportZone);
197             LOG.trace("Delete: Invoking deleteTunnels in ItmManager with DpnList {}", opDpnList);
198             if (!opDpnList.isEmpty() || !hwVtepList.isEmpty()) {
199                 LOG.trace("Delete: Invoking ItmManager with hwVtep List {} ", hwVtepList);
200                 jobCoordinator.enqueueJob(transportZone.getZoneName(),
201                         new ItmTepRemoveWorker(opDpnList, hwVtepList, transportZone, mdsalManager,
202                                 itmInternalTunnelDeleteWorker, dpnTEPsInfoCache, txRunner, itmConfig));
203
204                 if (transportZone.getVteps() != null && !transportZone.getVteps().isEmpty()) {
205                     Map<UnknownVtepsKey, UnknownVteps> unknownVteps =
206                             convertVtepListToUnknownVtepList(transportZone.getVteps());
207                     LOG.trace("Moving Transport Zone {} to tepsInNotHostedTransportZone Oper Ds.",
208                             transportZone.getZoneName());
209                     jobCoordinator.enqueueJob(transportZone.getZoneName(),
210                             new ItmTepsNotHostedAddWorker(unknownVteps, transportZone.getZoneName(),
211                                     dataBroker, txRunner));
212                 }
213             }
214         }
215     }
216
217     @Override
218     public void update(@NonNull InstanceIdentifier<TransportZone> instanceIdentifier,
219                        @NonNull TransportZone originalTransportZone, @NonNull TransportZone updatedTransportZone) {
220         LOG.debug("Received Transport Zone Update Event: Old - {}, Updated - {}", originalTransportZone,
221                 updatedTransportZone);
222         EVENT_LOGGER.debug("ITM-Transportzone,UPDATE {}", updatedTransportZone.getZoneName());
223         List<DPNTEPsInfo> oldDpnTepsList = createDPNTepInfo(originalTransportZone);
224         List<DPNTEPsInfo> newDpnTepsList = createDPNTepInfo(updatedTransportZone);
225         List<DPNTEPsInfo> oldDpnTepsListcopy = new ArrayList<>();
226         oldDpnTepsListcopy.addAll(oldDpnTepsList);
227         LOG.trace("oldcopy0 {}", oldDpnTepsListcopy);
228         List<DPNTEPsInfo> newDpnTepsListcopy = new ArrayList<>();
229         newDpnTepsListcopy.addAll(newDpnTepsList);
230         LOG.trace("newcopy0 {}", newDpnTepsListcopy);
231
232         oldDpnTepsList.removeAll(newDpnTepsListcopy);
233         newDpnTepsList.removeAll(oldDpnTepsListcopy);
234
235         LOG.trace("oldDpnTepsList {}", oldDpnTepsList);
236         LOG.trace("newDpnTepsList {}", newDpnTepsList);
237         LOG.trace("oldcopy {}", oldDpnTepsListcopy);
238         LOG.trace("newcopy {}", newDpnTepsListcopy);
239         LOG.trace("oldcopy Size {}", oldDpnTepsList.size());
240         LOG.trace("newcopy Size {}", newDpnTepsList.size());
241
242         boolean equalLists = newDpnTepsList.size() == oldDpnTepsList.size()
243                 && newDpnTepsList.containsAll(oldDpnTepsList);
244         LOG.trace("Is List Duplicate {} ", equalLists);
245         if (!newDpnTepsList.isEmpty() && !equalLists) {
246             LOG.trace("Adding TEPs ");
247             jobCoordinator.enqueueJob(updatedTransportZone.getZoneName(),
248                     new ItmTepAddWorker(newDpnTepsList, Collections.emptyList(), dataBroker, mdsalManager,
249                             itmInternalTunnelAddWorker, externalTunnelAddWorker));
250         }
251         if (!oldDpnTepsList.isEmpty() && !equalLists) {
252             LOG.trace("Removing TEPs ");
253             jobCoordinator.enqueueJob(updatedTransportZone.getZoneName(),
254                     new ItmTepRemoveWorker(oldDpnTepsList, Collections.emptyList(), originalTransportZone, mdsalManager,
255                             itmInternalTunnelDeleteWorker, dpnTEPsInfoCache, txRunner, itmConfig));
256         }
257         List<HwVtep> oldHwList = createhWVteps(originalTransportZone);
258         List<HwVtep> newHwList = createhWVteps(updatedTransportZone);
259         List<HwVtep> oldHwListcopy = new ArrayList<>();
260         oldHwListcopy.addAll(oldHwList);
261         LOG.trace("oldHwListcopy0 {}", oldHwListcopy);
262         List<HwVtep> newHwListcopy = new ArrayList<>();
263         newHwListcopy.addAll(newHwList);
264         LOG.trace("newHwListcopy0 {}", newHwListcopy);
265
266         oldHwList.removeAll(newHwListcopy);
267         newHwList.removeAll(oldHwListcopy);
268         LOG.trace("oldHwList {}", oldHwList);
269         LOG.trace("newHwList {}", newHwList);
270         LOG.trace("oldHwListcopy {}", oldHwListcopy);
271         LOG.trace("newHwListcopy {}", newHwListcopy);
272         if (!newHwList.isEmpty()) {
273             LOG.trace("Adding HW TEPs ");
274             jobCoordinator.enqueueJob(updatedTransportZone.getZoneName(), new ItmTepAddWorker(Collections.emptyList(),
275                     newHwList, dataBroker, mdsalManager, itmInternalTunnelAddWorker, externalTunnelAddWorker));
276         }
277         if (!oldHwList.isEmpty()) {
278             LOG.trace("Removing HW TEPs ");
279             jobCoordinator.enqueueJob(updatedTransportZone.getZoneName(),
280                     new ItmTepRemoveWorker(Collections.emptyList(), oldHwList, originalTransportZone, mdsalManager,
281                             itmInternalTunnelDeleteWorker, dpnTEPsInfoCache, txRunner, itmConfig));
282         }
283     }
284
285     @Override
286     public void add(@NonNull TransportZone transportZone) {
287         LOG.debug("Received Transport Zone Add Event: {}", transportZone);
288         EVENT_LOGGER.debug("ITM-Transportzone,ADD {}", transportZone.getZoneName());
289         List<DPNTEPsInfo> opDpnList = createDPNTepInfo(transportZone);
290         //avoiding adding duplicates from nothosted to new dpnlist.
291         List<DPNTEPsInfo> duplicateFound = new ArrayList<>();
292         List<DPNTEPsInfo> notHostedDpnList = getDPNTepInfoFromNotHosted(transportZone, opDpnList);
293         for (DPNTEPsInfo notHostedDPN:notHostedDpnList) {
294             for (DPNTEPsInfo newlyAddedDPN:opDpnList) {
295                 if (newlyAddedDPN.getDPNID().compareTo(notHostedDPN.getDPNID()) == 0
296                         || newlyAddedDPN.getTunnelEndPoints().get(0).getIpAddress()
297                         .equals(notHostedDPN.getTunnelEndPoints().get(0).getIpAddress())) {
298                     duplicateFound.add(notHostedDPN);
299                 }
300             }
301         }
302         notHostedDpnList.removeAll(duplicateFound);
303         opDpnList.addAll(notHostedDpnList);
304
305         List<HwVtep> hwVtepList = createhWVteps(transportZone);
306         LOG.trace("Add: Operational dpnTepInfo - Before invoking ItmManager {}", opDpnList);
307         if (!opDpnList.isEmpty() || !hwVtepList.isEmpty()) {
308             LOG.trace("Add: Invoking ItmManager with DPN List {} ", opDpnList);
309             LOG.trace("Add: Invoking ItmManager with hwVtep List {} ", hwVtepList);
310             jobCoordinator.enqueueJob(transportZone.getZoneName(),
311                     new ItmTepAddWorker(opDpnList, hwVtepList, dataBroker, mdsalManager, itmInternalTunnelAddWorker,
312                             externalTunnelAddWorker));
313         }
314     }
315
316     private List<DPNTEPsInfo> getDPNTepInfoFromNotHosted(TransportZone tzNew, List<DPNTEPsInfo> opDpnList) {
317         List<DPNTEPsInfo> notHostedOpDpnList = new ArrayList<>();
318         if (isNewTZExistInNotHostedTZ(tzNew)) {
319             notHostedOpDpnList = createDPNTepInfoFromNotHosted(tzNew, opDpnList);
320         }
321         return notHostedOpDpnList;
322     }
323
324     private List<DPNTEPsInfo> createDPNTepInfoFromNotHosted(TransportZone tzNew, List<DPNTEPsInfo> opDpnList) {
325         Map<Uint64, List<TunnelEndPoints>> mapNotHostedDPNToTunnelEndpt = new ConcurrentHashMap<>();
326         List<DPNTEPsInfo> notHostedDpnTepInfo = new ArrayList<>();
327         String newZoneName = tzNew.getZoneName();
328         List<TzMembership> zones = ItmUtils.createTransportZoneMembership(newZoneName);
329         Class<? extends TunnelTypeBase> tunnelType  = tzNew.getTunnelType();
330
331         TepsInNotHostedTransportZone tepsInNotHostedTransportZone = getNotHostedTransportZone(newZoneName).get();
332         if (tepsInNotHostedTransportZone == null) {
333             return notHostedDpnTepInfo;
334         }
335         @Nullable Map<UnknownVtepsKey, UnknownVteps> unVtepsLst = tepsInNotHostedTransportZone.getUnknownVteps();
336         List<Vteps> vtepsList = new ArrayList<>();
337         if (unVtepsLst != null && !unVtepsLst.isEmpty()) {
338             for (UnknownVteps vteps : unVtepsLst.values()) {
339                 Uint64 dpnID = vteps.getDpnId();
340                 IpAddress ipAddress = vteps.getIpAddress();
341                 String portName = itmConfig.getPortname() == null ? ITMConstants.DUMMY_PORT : itmConfig.getPortname();
342                 int vlanId = itmConfig.getVlanId() != null ? itmConfig.getVlanId().toJava()
343                                                              : ITMConstants.DUMMY_VLANID;
344                 boolean useOfTunnel = ItmUtils.falseIfNull(vteps.isOfTunnel());
345                 String tos = vteps.getOptionTunnelTos();
346                 if (tos == null) {
347                     tos = itmConfig.getDefaultTunnelTos();
348                 }
349                 TunnelEndPoints tunnelEndPoints =
350                         ItmUtils.createTunnelEndPoints(dpnID, ipAddress, portName, useOfTunnel, vlanId, zones,
351                                 tunnelType, tos);
352                 List<TunnelEndPoints> tunnelEndPointsList = mapNotHostedDPNToTunnelEndpt.get(dpnID);
353                 if (tunnelEndPointsList != null) {
354                     tunnelEndPointsList.add(tunnelEndPoints);
355                 } else {
356                     tunnelEndPointsList = new ArrayList<>();
357                     tunnelEndPointsList.add(tunnelEndPoints);
358                     mapNotHostedDPNToTunnelEndpt.put(dpnID, tunnelEndPointsList);
359                 }
360                 Vteps newVtep = createVtepFromUnKnownVteps(dpnID,ipAddress);
361                 vtepsList.add(newVtep);
362
363                 // Enqueue 'remove TEP from TepsNotHosted list' operation
364                 // into DataStoreJobCoordinator
365                 jobCoordinator.enqueueJob(newZoneName,
366                         new ItmTepsNotHostedRemoveWorker(newZoneName, ipAddress, dpnID, dataBroker, txRunner));
367             }
368         }
369         //avoiding duplicate vteps which are already present in dpn list pushed from NBI
370         List<Vteps> foundDuplicatevtepsList = new ArrayList<>();
371         for (Vteps notHostedVteps:vtepsList) {
372             for (DPNTEPsInfo newlyAddedDPN:opDpnList) {
373                 if (notHostedVteps.getDpnId().compareTo(newlyAddedDPN.getDPNID()) == 0
374                         || newlyAddedDPN.getTunnelEndPoints().get(0).getIpAddress()
375                         .equals(notHostedVteps.getIpAddress())) {
376                     foundDuplicatevtepsList.add(notHostedVteps);
377                 }
378             }
379         }
380         vtepsList.removeAll(foundDuplicatevtepsList);
381
382         // Enqueue 'add TEP received from southbound OVSDB into ITM config DS' operation
383         // into DataStoreJobCoordinator
384         jobCoordinator.enqueueJob(newZoneName, new ItmTepsNotHostedMoveWorker(vtepsList, newZoneName, txRunner));
385
386         if (mapNotHostedDPNToTunnelEndpt.size() > 0) {
387             for (Entry<Uint64, List<TunnelEndPoints>> entry: mapNotHostedDPNToTunnelEndpt.entrySet()) {
388                 DPNTEPsInfo newDpnTepsInfo = ItmUtils.createDPNTepInfo(entry.getKey(), entry.getValue());
389                 notHostedDpnTepInfo.add(newDpnTepsInfo);
390             }
391         }
392         return notHostedDpnTepInfo;
393
394     }
395
396     private Vteps createVtepFromUnKnownVteps(Uint64 dpnID, IpAddress ipAddress) {
397         VtepsKey vtepkey = new VtepsKey(dpnID);
398         Vteps vtepObj = new VtepsBuilder().setDpnId(dpnID).setIpAddress(ipAddress).withKey(vtepkey)
399                 .build();
400         return vtepObj;
401     }
402
403     private  Map<UnknownVtepsKey, UnknownVteps> convertVtepListToUnknownVtepList(Map<VtepsKey, Vteps> vteps) {
404         Map<UnknownVtepsKey, UnknownVteps> unknownVtepsList = new HashMap<>();
405         for (Vteps vtep : vteps.values()) {
406             UnknownVtepsKey vtepkey = new UnknownVtepsKey(vtep.getDpnId());
407             UnknownVteps vtepObj =
408                     new UnknownVtepsBuilder().setDpnId(vtep.getDpnId()).setIpAddress(vtep.getIpAddress())
409                             .withKey(vtepkey).setOfTunnel(vtep.isOptionOfTunnel()).build();
410             //unknownVtepsList.values().add(vtepObj);
411             unknownVtepsList.put(vtepObj.key(),vtepObj);
412         }
413         return unknownVtepsList;
414     }
415
416     private boolean isNewTZExistInNotHostedTZ(TransportZone tzNew) {
417         boolean isPresent = false;
418         if (getNotHostedTransportZone(tzNew.getZoneName()).isPresent()) {
419             isPresent = true;
420         }
421         return isPresent;
422     }
423
424     public  Optional<TepsInNotHostedTransportZone> getNotHostedTransportZone(String transportZoneName) {
425         InstanceIdentifier<TepsInNotHostedTransportZone> notHostedTzPath = InstanceIdentifier
426                 .builder(NotHostedTransportZones.class).child(TepsInNotHostedTransportZone.class,
427                         new TepsInNotHostedTransportZoneKey(transportZoneName)).build();
428         Optional<TepsInNotHostedTransportZone> tepsInNotHostedTransportZoneOptional =
429                 ItmUtils.read(LogicalDatastoreType.OPERATIONAL, notHostedTzPath, dataBroker);
430         return tepsInNotHostedTransportZoneOptional;
431     }
432
433     private List<DPNTEPsInfo> createDPNTepInfo(TransportZone transportZone) {
434
435         Map<Uint64, List<TunnelEndPoints>> mapDPNToTunnelEndpt = new ConcurrentHashMap<>();
436         List<DPNTEPsInfo> dpnTepInfo = new ArrayList<>();
437         List<TzMembership> zones = ItmUtils.createTransportZoneMembership(transportZone.getZoneName());
438         Class<? extends TunnelTypeBase> tunnelType = transportZone.getTunnelType();
439         LOG.trace("Transport Zone_name: {}", transportZone.getZoneName());
440         @Nullable Map<VtepsKey, Vteps> vtepsList = transportZone.getVteps();
441
442         String portName = itmConfig.getPortname() == null ? ITMConstants.DUMMY_PORT : itmConfig.getPortname();
443         int vlanId = itmConfig.getVlanId() != null ? itmConfig.getVlanId().toJava() : ITMConstants.DUMMY_VLANID;
444
445         if (vtepsList != null && !vtepsList.isEmpty()) {
446             for (Vteps vteps : vtepsList.values()) {
447                 Uint64 dpnID = vteps.getDpnId();
448                 IpAddress ipAddress = vteps.getIpAddress();
449                 boolean useOfTunnel = itmConfig.isUseOfTunnels();
450                 String tos = vteps.getOptionTunnelTos();
451                 if (tos == null) {
452                     tos = itmConfig.getDefaultTunnelTos();
453                 }
454                 LOG.trace("DpnID: {}, ipAddress: {}", dpnID, ipAddress);
455                 TunnelEndPoints tunnelEndPoints = ItmUtils.createTunnelEndPoints(dpnID, ipAddress, portName,
456                         useOfTunnel, vlanId, zones, tunnelType, tos);
457                 EVENT_LOGGER.debug("ITM-createDPNTepInfo for {} {}", dpnID, ipAddress);
458                 List<TunnelEndPoints> tunnelEndPointsList = mapDPNToTunnelEndpt.get(dpnID);
459                 if (tunnelEndPointsList != null) {
460                     LOG.trace("Existing DPN info list in the Map: {} ", dpnID);
461                     tunnelEndPointsList.add(tunnelEndPoints);
462                 } else {
463                     LOG.trace("Adding new DPN info list to the Map: {} ", dpnID);
464                     tunnelEndPointsList = new ArrayList<>();
465                     tunnelEndPointsList.add(tunnelEndPoints);
466                     mapDPNToTunnelEndpt.put(dpnID, tunnelEndPointsList);
467
468                 }
469             }
470         }
471
472         if (!mapDPNToTunnelEndpt.isEmpty()) {
473             LOG.trace("List of dpns in the Map: {} ", mapDPNToTunnelEndpt.keySet());
474             for (Entry<Uint64, List<TunnelEndPoints>> entry : mapDPNToTunnelEndpt.entrySet()) {
475                 DPNTEPsInfo newDpnTepsInfo = ItmUtils.createDPNTepInfo(entry.getKey(), entry.getValue());
476                 dpnTepInfo.add(newDpnTepsInfo);
477             }
478         }
479         return dpnTepInfo;
480     }
481
482     private List<HwVtep> createhWVteps(TransportZone transportZone) {
483         List<HwVtep> hwVtepsList = new ArrayList<>();
484
485         String zoneName = transportZone.getZoneName();
486         Class<? extends TunnelTypeBase> tunnelType = transportZone.getTunnelType();
487         LOG.trace("Transport Zone_name: {}", zoneName);
488         @Nullable Map<DeviceVtepsKey, DeviceVteps> deviceVtepsList = transportZone.getDeviceVteps();
489         if (deviceVtepsList != null) {
490             for (DeviceVteps vteps : deviceVtepsList.values()) {
491                 String topologyId = vteps.getTopologyId();
492                 String nodeId = vteps.getNodeId();
493                 IpAddress ipAddress = vteps.getIpAddress();
494                 LOG.trace("topo-id: {}, node-id: {}, ipAddress: {}", topologyId, nodeId, ipAddress);
495                 HwVtep hwVtep = ItmUtils.createHwVtepObject(topologyId, nodeId, ipAddress,
496                         tunnelType, transportZone);
497
498                 LOG.trace("Adding new HwVtep {} info ", hwVtep.getHwIp());
499                 hwVtepsList.add(hwVtep);
500             }
501         }
502         LOG.trace("returning hwvteplist {}", hwVtepsList);
503         return hwVtepsList;
504     }
505 }