To move Tep's from not hosted transport zone to transport zone.
[genius.git] / itm / itm-impl / src / main / java / org / opendaylight / genius / itm / listeners / TransportZoneListener.java
1 /*
2  * Copyright (c) 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.base.Optional;
12 import com.google.common.util.concurrent.CheckedFuture;
13 import java.math.BigInteger;
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Set;
19 import java.util.concurrent.ConcurrentHashMap;
20 import javax.annotation.PostConstruct;
21 import javax.annotation.PreDestroy;
22 import javax.inject.Inject;
23 import javax.inject.Singleton;
24 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
25 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
26 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
27 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
28 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
29 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
30 import org.opendaylight.genius.itm.confighelpers.HwVtep;
31 import org.opendaylight.genius.itm.confighelpers.ItmTepAddWorker;
32 import org.opendaylight.genius.itm.confighelpers.ItmTepRemoveWorker;
33 import org.opendaylight.genius.itm.confighelpers.ItmTepsNotHostedMoveWorker;
34 import org.opendaylight.genius.itm.confighelpers.ItmTepsNotHostedRemoveWorker;
35 import org.opendaylight.genius.itm.globals.ITMConstants;
36 import org.opendaylight.genius.itm.impl.ITMManager;
37 import org.opendaylight.genius.itm.impl.ItmUtils;
38 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembership;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZonesBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.tepsnothostedintransportzone.UnknownVteps;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TepsNotHostedInTransportZone;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TepsNotHostedInTransportZoneKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Subnets;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.SubnetsBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.SubnetsKey;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.DeviceVteps;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.Vteps;
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.rev160406.transport.zones.transport.zone.subnets.VtepsBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.VtepsKey;
63 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
66
67 /**
68  * This class listens for interface creation/removal/update in Configuration DS.
69  * This is used to handle interfaces for base of-ports.
70  */
71 @Singleton
72 public class TransportZoneListener extends AsyncDataTreeChangeListenerBase<TransportZone, TransportZoneListener>
73         implements AutoCloseable {
74     private static final Logger LOG = LoggerFactory.getLogger(TransportZoneListener.class);
75     private final DataBroker dataBroker;
76     private final IdManagerService idManagerService;
77     private final IMdsalApiManager mdsalManager;
78     private final ITMManager itmManager;
79     private final ItmConfig itmConfig;
80
81     @Inject
82     public TransportZoneListener(final DataBroker dataBroker, final IdManagerService idManagerService,
83                                  final IMdsalApiManager iMdsalApiManager,final ITMManager itmManager,
84                                  final ItmConfig itmConfig) {
85         super(TransportZone.class, TransportZoneListener.class);
86         this.dataBroker = dataBroker;
87         this.idManagerService = idManagerService;
88         initializeTZNode(dataBroker);
89         this.itmManager = itmManager;
90         this.mdsalManager = iMdsalApiManager;
91         this.itmConfig = itmConfig;
92     }
93
94     @PostConstruct
95     public void start() {
96         registerListener(LogicalDatastoreType.CONFIGURATION, this.dataBroker);
97         LOG.info("tzChangeListener Started");
98     }
99
100     @Override
101     @PreDestroy
102     public void close() {
103         LOG.info("tzChangeListener Closed");
104     }
105
106     private void initializeTZNode(DataBroker db) {
107         ReadWriteTransaction transaction = db.newReadWriteTransaction();
108         InstanceIdentifier<TransportZones> path = InstanceIdentifier.create(TransportZones.class);
109         CheckedFuture<Optional<TransportZones>, ReadFailedException> tzones = transaction
110                 .read(LogicalDatastoreType.CONFIGURATION, path);
111         try {
112             if (!tzones.get().isPresent()) {
113                 TransportZonesBuilder tzb = new TransportZonesBuilder();
114                 transaction.put(LogicalDatastoreType.CONFIGURATION, path, tzb.build());
115                 transaction.submit();
116             } else {
117                 transaction.cancel();
118             }
119         } catch (Exception e) {
120             LOG.error("Error initializing TransportZones {}", e);
121         }
122     }
123
124     @Override
125     protected InstanceIdentifier<TransportZone> getWildCardPath() {
126         return InstanceIdentifier.create(TransportZones.class).child(TransportZone.class);
127     }
128
129     @Override
130     protected TransportZoneListener getDataTreeChangeListener() {
131         return TransportZoneListener.this;
132     }
133
134     @Override
135     protected void remove(InstanceIdentifier<TransportZone> key, TransportZone tzOld) {
136         LOG.debug("Received Transport Zone Remove Event: {}, {}", key, tzOld);
137
138         boolean allowTunnelDeletion = false;
139
140         // check if TZ received for removal is default-transport-zone,
141         // if yes, then check if it is received from northbound, then
142         // do not entertain request and skip tunnels remove operation
143         // if def-tz removal request is due to def-tz-enabled flag is disabled or
144         // due to change in def-tz-tunnel-type, then allow def-tz tunnels deletion
145         if (tzOld.getZoneName().equalsIgnoreCase(ITMConstants.DEFAULT_TRANSPORT_ZONE)) {
146             // Get TunnelTypeBase object for tunnel-type configured in config file
147             Class<? extends TunnelTypeBase> tunType = ItmUtils.getTunnelType(itmConfig.getDefTzTunnelType());
148
149             if ((!itmConfig.isDefTzEnabled()) || (!tzOld.getTunnelType().equals(tunType))) {
150                 allowTunnelDeletion = true;
151             } else {
152                 // this is case when def-tz removal request is from Northbound.
153                 allowTunnelDeletion = false;
154                 LOG.error("Deletion of {} is an incorrect usage",ITMConstants.DEFAULT_TRANSPORT_ZONE);
155             }
156         } else {
157             allowTunnelDeletion = true;
158         }
159
160         if (allowTunnelDeletion) {
161             //TODO : DPList code can be refactor with new specific class
162             // which implement TransportZoneValidator
163             List<DPNTEPsInfo> opDpnList = createDPNTepInfo(tzOld);
164             List<HwVtep> hwVtepList = createhWVteps(tzOld);
165             LOG.trace("Delete: Invoking deleteTunnels in ItmManager with DpnList {}", opDpnList);
166             if(!opDpnList.isEmpty() || !hwVtepList.isEmpty()) {
167                 LOG.trace("Delete: Invoking ItmManager with hwVtep List {} " , hwVtepList);
168                 DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
169                 ItmTepRemoveWorker removeWorker =
170                         new ItmTepRemoveWorker(opDpnList, hwVtepList, tzOld, dataBroker, idManagerService, mdsalManager);
171                 coordinator.enqueueJob(tzOld.getZoneName(), removeWorker);
172             }
173         }
174     }
175
176     @Override
177     protected void update(InstanceIdentifier<TransportZone> key, TransportZone tzOld, TransportZone tzNew) {
178         LOG.debug("Received Transport Zone Update Event: Key - {}, Old - {}, Updated - {}", key, tzOld, tzNew);
179         List<DPNTEPsInfo> oldDpnTepsList = createDPNTepInfo(tzOld);
180         List<DPNTEPsInfo> newDpnTepsList = createDPNTepInfo(tzNew);
181         List<DPNTEPsInfo> oldDpnTepsListcopy = new ArrayList<>();
182         oldDpnTepsListcopy.addAll(oldDpnTepsList);
183         LOG.trace("oldcopy0" + oldDpnTepsListcopy);
184         List<DPNTEPsInfo> newDpnTepsListcopy = new ArrayList<>();
185         newDpnTepsListcopy.addAll(newDpnTepsList);
186         LOG.trace("newcopy0" + newDpnTepsListcopy);
187         DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
188
189         oldDpnTepsList.removeAll(newDpnTepsListcopy);
190         newDpnTepsList.removeAll(oldDpnTepsListcopy);
191
192         LOG.trace("oldDpnTepsList" + oldDpnTepsList);
193         LOG.trace("newDpnTepsList" + newDpnTepsList);
194         LOG.trace("oldcopy" + oldDpnTepsListcopy);
195         LOG.trace("newcopy" + newDpnTepsListcopy);
196         LOG.trace("oldcopy Size " + oldDpnTepsList.size());
197         LOG.trace("newcopy Size " + newDpnTepsList.size());
198         if (!newDpnTepsList.isEmpty()) {
199             LOG.trace("Adding TEPs ");
200             ItmTepAddWorker addWorker = new ItmTepAddWorker(newDpnTepsList, Collections.emptyList(), dataBroker,
201                     idManagerService, mdsalManager);
202             coordinator.enqueueJob(tzNew.getZoneName(), addWorker);
203         }
204         if (!oldDpnTepsList.isEmpty()) {
205             LOG.trace("Removing TEPs ");
206             ItmTepRemoveWorker removeWorker = new ItmTepRemoveWorker(oldDpnTepsList, Collections.emptyList(),
207                     tzOld, dataBroker, idManagerService, mdsalManager);
208             coordinator.enqueueJob(tzNew.getZoneName(), removeWorker);
209         }
210         List<HwVtep> oldHwList = createhWVteps(tzOld);
211         List<HwVtep> newHwList = createhWVteps(tzNew);
212         List<HwVtep> oldHwListcopy = new ArrayList<>();
213         oldHwListcopy.addAll(oldHwList);
214         LOG.trace("oldHwListcopy0" + oldHwListcopy);
215         List<HwVtep> newHwListcopy = new ArrayList<>();
216         newHwListcopy.addAll(newHwList);
217         LOG.trace("newHwListcopy0" + newHwListcopy);
218
219         oldHwList.removeAll(newHwListcopy);
220         newHwList.removeAll(oldHwListcopy);
221         LOG.trace("oldHwList" + oldHwList);
222         LOG.trace("newHwList" + newHwList);
223         LOG.trace("oldHwListcopy" + oldHwListcopy);
224         LOG.trace("newHwListcopy" + newHwListcopy);
225         if (!newHwList.isEmpty()) {
226             LOG.trace("Adding HW TEPs ");
227             ItmTepAddWorker addWorker = new ItmTepAddWorker(Collections.emptyList(), newHwList, dataBroker,
228                     idManagerService, mdsalManager);
229             coordinator.enqueueJob(tzNew.getZoneName(), addWorker);
230         }
231         if (!oldHwList.isEmpty()) {
232             LOG.trace("Removing HW TEPs ");
233             ItmTepRemoveWorker removeWorker = new ItmTepRemoveWorker(Collections.emptyList(), oldHwList,
234                     tzOld, dataBroker, idManagerService, mdsalManager);
235             coordinator.enqueueJob(tzNew.getZoneName(), removeWorker);
236         }
237     }
238
239     @Override
240     protected void add(InstanceIdentifier<TransportZone> key, TransportZone tzNew) {
241         LOG.debug("Received Transport Zone Add Event: {}, {}", key, tzNew);
242         List<DPNTEPsInfo> opDpnList = createDPNTepInfo(tzNew);
243         List<HwVtep> hwVtepList = createhWVteps(tzNew);
244         opDpnList.addAll(getDPNTepInfoFromNotHosted(tzNew));
245         LOG.trace("Add: Operational dpnTepInfo - Before invoking ItmManager {}", opDpnList);
246         if (!opDpnList.isEmpty() || !hwVtepList.isEmpty()) {
247             LOG.trace("Add: Invoking ItmManager with DPN List {} ", opDpnList);
248             LOG.trace("Add: Invoking ItmManager with hwVtep List {} ", hwVtepList);
249             DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
250             ItmTepAddWorker addWorker = new ItmTepAddWorker(opDpnList, hwVtepList, dataBroker, idManagerService,
251                     mdsalManager);
252             coordinator.enqueueJob(tzNew.getZoneName(), addWorker);
253         }
254     }
255
256     private List<DPNTEPsInfo> getDPNTepInfoFromNotHosted(TransportZone tzNew) {
257         List<DPNTEPsInfo> notHostedOpDpnList=new ArrayList<>();
258         if(isNewTZExistInNotHostedTZ(tzNew)){
259             notHostedOpDpnList = createDPNTepInfoFromNotHosted(tzNew);
260         }
261         return notHostedOpDpnList;
262     }
263
264     private List<DPNTEPsInfo> createDPNTepInfoFromNotHosted(TransportZone tzNew) {
265         Map<BigInteger, List<TunnelEndPoints>> mapNotHostedDPNToTunnelEndpt = new ConcurrentHashMap<>();
266         List<DPNTEPsInfo> notHostedDpnTepInfo = new ArrayList<>();
267         String newZoneName=tzNew.getZoneName();
268         List<TzMembership> zones = ItmUtils.createTransportZoneMembership(newZoneName);
269         Class<? extends TunnelTypeBase> tunnelType=tzNew.getTunnelType();
270         DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
271
272         TepsNotHostedInTransportZone tepNotHostedTransportZone=getNotHostedTransportZone(newZoneName).get();
273         if (tepNotHostedTransportZone == null) {
274             return notHostedDpnTepInfo;
275         }
276         List<UnknownVteps> unVtepsLst=tepNotHostedTransportZone.getUnknownVteps();
277         List<Vteps> vtepsList=new ArrayList<Vteps>();
278         if(unVtepsLst!=null && !unVtepsLst.isEmpty()) {
279             for (UnknownVteps vteps : unVtepsLst) {
280                 BigInteger dpnID = vteps.getDpnId();
281                 String port = ITMConstants.DUMMY_PORT;
282                 int vlanID= ITMConstants.DUMMY_VLANID;
283                 IpPrefix ipPrefix = new IpPrefix(ITMConstants.DUMMY_PREFIX.toCharArray());
284                 IpAddress gatewayIP = new IpAddress(ITMConstants.DUMMY_GATEWAY_IP.toCharArray());
285                 IpAddress ipAddress = vteps.getIpAddress();
286                 boolean useOfTunnel = ItmUtils.falseIfNull(vteps.isOfTunnel());
287                 TunnelEndPoints tunnelEndPoints =
288                         ItmUtils.createTunnelEndPoints(dpnID, ipAddress, port, useOfTunnel,vlanID, ipPrefix,
289                                 gatewayIP, zones, tunnelType);
290                 List<TunnelEndPoints> tunnelEndPointsList = mapNotHostedDPNToTunnelEndpt.get(dpnID);
291                 if (tunnelEndPointsList != null) {
292                     tunnelEndPointsList.add(tunnelEndPoints);
293                 } else {
294                     tunnelEndPointsList = new ArrayList<>();
295                     tunnelEndPointsList.add(tunnelEndPoints);
296                     mapNotHostedDPNToTunnelEndpt.put(dpnID, tunnelEndPointsList);
297                 }
298                 Vteps newVtep=createVtepFromUnKnownVteps(dpnID,ipAddress,ITMConstants.DUMMY_PORT);
299                 vtepsList.add(newVtep);
300
301                 // Enqueue 'remove TEP from TepsNotHosted list' operation
302                 // into DataStoreJobCoordinator
303                 ItmTepsNotHostedRemoveWorker
304                     removeWorker = new ItmTepsNotHostedRemoveWorker(newZoneName, ipAddress, dpnID, dataBroker);
305                 coordinator.enqueueJob(newZoneName, removeWorker);
306             }
307         }
308
309         // Enqueue 'add TEP received from southbound OVSDB into ITM config DS' operation
310         // into DataStoreJobCoordinator
311         ItmTepsNotHostedMoveWorker
312             moveWorker = new ItmTepsNotHostedMoveWorker(vtepsList, newZoneName, dataBroker);
313         coordinator.enqueueJob(newZoneName, moveWorker);
314
315         if(mapNotHostedDPNToTunnelEndpt.size() > 0){
316             Set<BigInteger> keys = mapNotHostedDPNToTunnelEndpt.keySet();
317             for(BigInteger key: keys){
318                 DPNTEPsInfo newDpnTepsInfo = ItmUtils.createDPNTepInfo(key, mapNotHostedDPNToTunnelEndpt.get(key));
319                 notHostedDpnTepInfo.add(newDpnTepsInfo);
320             }
321         }
322         return notHostedDpnTepInfo;
323
324     }
325
326     private Vteps createVtepFromUnKnownVteps(BigInteger dpnID, IpAddress ipAddress, String port) {
327         VtepsKey vtepkey = new VtepsKey(dpnID, port);
328         Vteps vtepObj = new VtepsBuilder().setDpnId(dpnID).setIpAddress(ipAddress).setKey(vtepkey)
329                 .setPortname(port).build();
330         return vtepObj;
331     }
332
333     private boolean isNewTZExistInNotHostedTZ(TransportZone tzNew){
334         boolean isPresent=false;
335         if (getNotHostedTransportZone(tzNew.getZoneName()).isPresent()) {
336             isPresent=true;
337         }
338         return isPresent;
339     }
340
341     public  Optional<TepsNotHostedInTransportZone> getNotHostedTransportZone(String transportZoneName) {
342         InstanceIdentifier<TepsNotHostedInTransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class)
343                 .child(TepsNotHostedInTransportZone.class, new TepsNotHostedInTransportZoneKey(transportZoneName)).build();
344         Optional<TepsNotHostedInTransportZone> tZoneNotHostedOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath,
345                 dataBroker);
346         return tZoneNotHostedOptional;
347     }
348
349     private List<DPNTEPsInfo> createDPNTepInfo(TransportZone transportZone){
350
351         Map<BigInteger, List<TunnelEndPoints>> mapDPNToTunnelEndpt = new ConcurrentHashMap<>();
352         List<DPNTEPsInfo> dpnTepInfo = new ArrayList<>();
353         List<TzMembership> zones = ItmUtils.createTransportZoneMembership(transportZone.getZoneName());
354         Class<? extends TunnelTypeBase> tunnelType = transportZone.getTunnelType();
355         LOG.trace("Transport Zone_name: {}", transportZone.getZoneName());
356         List<Subnets> subnetsList = transportZone.getSubnets();
357         if (subnetsList != null) {
358             for (Subnets subnet : subnetsList) {
359                 IpPrefix ipPrefix = subnet.getPrefix();
360                 IpAddress gatewayIP = subnet.getGatewayIp();
361                 int vlanID = subnet.getVlanId();
362                 LOG.trace("IpPrefix: {}, gatewayIP: {}, vlanID: {} ", ipPrefix, gatewayIP, vlanID);
363                 List<Vteps> vtepsList = subnet.getVteps();
364                 if (vtepsList != null && !vtepsList.isEmpty()) {
365                     for (Vteps vteps : vtepsList) {
366                         BigInteger dpnID = vteps.getDpnId();
367                         String port = vteps.getPortname();
368                         IpAddress ipAddress = vteps.getIpAddress();
369                         boolean useOfTunnel = ItmUtils.falseIfNull(vteps.isOptionOfTunnel());
370                         LOG.trace("DpnID: {}, port: {}, ipAddress: {}", dpnID, port, ipAddress);
371                         TunnelEndPoints tunnelEndPoints = ItmUtils.createTunnelEndPoints(dpnID, ipAddress, port,
372                             useOfTunnel, vlanID,  ipPrefix, gatewayIP, zones, tunnelType);
373                         List<TunnelEndPoints> tunnelEndPointsList = mapDPNToTunnelEndpt.get(dpnID);
374                         if (tunnelEndPointsList != null) {
375                             LOG.trace("Existing DPN info list in the Map: {} ", dpnID);
376                             tunnelEndPointsList.add(tunnelEndPoints);
377                         } else {
378                             LOG.trace("Adding new DPN info list to the Map: {} ", dpnID);
379                             tunnelEndPointsList = new ArrayList<>();
380                             tunnelEndPointsList.add(tunnelEndPoints);
381                             mapDPNToTunnelEndpt.put(dpnID, tunnelEndPointsList);
382                         }
383                     }
384                 }
385             }
386         }
387
388         if (!mapDPNToTunnelEndpt.isEmpty()) {
389             Set<BigInteger> keys = mapDPNToTunnelEndpt.keySet();
390             LOG.trace("List of dpns in the Map: {} ", keys);
391             for (BigInteger key : keys) {
392                 DPNTEPsInfo newDpnTepsInfo = ItmUtils.createDPNTepInfo(key, mapDPNToTunnelEndpt.get(key));
393                 dpnTepInfo.add(newDpnTepsInfo);
394             }
395         }
396         return dpnTepInfo;
397     }
398
399     private List<HwVtep> createhWVteps(TransportZone transportZone) {
400         List<HwVtep> hwVtepsList = new ArrayList<>();
401
402         String zoneName = transportZone.getZoneName();
403         Class<? extends TunnelTypeBase> tunnelType = transportZone.getTunnelType();
404         LOG.trace("Transport Zone_name: {}", zoneName);
405         List<Subnets> subnetsList = transportZone.getSubnets();
406         if (subnetsList != null) {
407             for (Subnets subnet : subnetsList) {
408                 IpPrefix ipPrefix = subnet.getPrefix();
409                 IpAddress gatewayIP = subnet.getGatewayIp();
410                 int vlanID = subnet.getVlanId();
411                 LOG.trace("IpPrefix: {}, gatewayIP: {}, vlanID: {} ", ipPrefix, gatewayIP, vlanID);
412                 List<DeviceVteps> deviceVtepsList = subnet.getDeviceVteps();
413                 if (deviceVtepsList != null) {
414                     for (DeviceVteps vteps : deviceVtepsList) {
415                         String topologyId = vteps.getTopologyId();
416                         String nodeId = vteps.getNodeId();
417                         IpAddress ipAddress = vteps.getIpAddress();
418                         LOG.trace("topo-id: {}, node-id: {}, ipAddress: {}", topologyId, nodeId, ipAddress);
419                         HwVtep hwVtep = ItmUtils.createHwVtepObject(topologyId, nodeId, ipAddress, ipPrefix, gatewayIP,
420                                 vlanID, tunnelType, transportZone);
421
422                         if (hwVtepsList != null) {
423                             LOG.trace("Existing hwVteps");
424                             hwVtepsList.add(hwVtep);
425                         } else {
426                             LOG.trace("Adding new HwVtep {} info ", hwVtep.getHwIp());
427                             hwVtepsList.add(hwVtep);
428                         }
429                     }
430                 }
431             }
432         }
433         LOG.trace("returning hwvteplist {}", hwVtepsList);
434         return hwVtepsList;
435     }
436 }