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