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