CLI to display Of-Port status
[genius.git] / itm / itm-impl / src / main / java / org / opendaylight / genius / itm / cli / TepCommandHelper.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.cli;
9
10 import static org.opendaylight.mdsal.binding.util.Datastore.CONFIGURATION;
11
12 import com.google.common.util.concurrent.Futures;
13 import com.google.common.util.concurrent.MoreExecutors;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.HashMap;
18 import java.util.List;
19 import java.util.Map;
20 import java.util.Map.Entry;
21 import java.util.Objects;
22 import java.util.Optional;
23 import java.util.concurrent.ExecutionException;
24 import java.util.concurrent.atomic.AtomicInteger;
25 import java.util.stream.Collectors;
26 import javax.annotation.PostConstruct;
27 import javax.annotation.PreDestroy;
28 import javax.inject.Inject;
29 import javax.inject.Singleton;
30 import org.apache.commons.lang3.StringUtils;
31 import org.opendaylight.genius.itm.cache.UnprocessedTunnelsStateCache;
32 import org.opendaylight.genius.itm.globals.ITMConstants;
33 import org.opendaylight.genius.itm.impl.ItmUtils;
34 import org.opendaylight.mdsal.binding.api.DataBroker;
35 import org.opendaylight.mdsal.binding.util.Datastore;
36 import org.opendaylight.mdsal.binding.util.RetryingManagedNewTransactionRunner;
37 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBase;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBfd;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeLldp;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeLogicalGroup;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorInterval;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorIntervalBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorParams;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorParamsBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeInternal;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTep;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZonesBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Vteps;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.VtepsBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.VtepsKey;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeRef;
66 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
67 import org.opendaylight.yangtools.yang.binding.DataObject;
68 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
69 import org.opendaylight.yangtools.yang.common.Uint64;
70 import org.slf4j.Logger;
71 import org.slf4j.LoggerFactory;
72
73 @Singleton
74 @SuppressWarnings("checkstyle:RegexpSingleLineJava")
75 public class TepCommandHelper {
76
77     private static final Logger LOG = LoggerFactory.getLogger(TepCommandHelper.class);
78
79     private static final AtomicInteger CHECK = new AtomicInteger();
80
81     private final DataBroker dataBroker;
82     private final RetryingManagedNewTransactionRunner txRunner;
83     private final ItmConfig itmConfig;
84     private final UnprocessedTunnelsStateCache unprocessedTunnelsStateCache;
85
86     /*
87      * boolean flag add_or_delete --- can be set to true if the last called tep
88      * command is Tep-add else set to false when Tep-delete is called
89      * tepCommandHelper object is created only once in session initiated
90      */
91     private final Map<String, List<Vteps>> transportZonesHashMap = new HashMap<>();
92     private List<TransportZone> transportZoneArrayList = new ArrayList<>();
93     private final List<Vteps> vtepDelCommitList = new ArrayList<>();
94
95     @Inject
96     public TepCommandHelper(final DataBroker dataBroker, final ItmConfig itmConfig,
97                             final UnprocessedTunnelsStateCache unprocessedTunnelsStateCache) {
98         this.dataBroker = dataBroker;
99         this.txRunner = new RetryingManagedNewTransactionRunner(dataBroker);
100         this.itmConfig = itmConfig;
101         this.unprocessedTunnelsStateCache = unprocessedTunnelsStateCache;
102     }
103
104     @PostConstruct
105     public void start() throws ExecutionException, InterruptedException {
106         LOG.info("TepCommandHelper Started");
107     }
108
109     @PreDestroy
110     public void close() {
111         LOG.info("TepCommandHelper Closed");
112     }
113
114     @SuppressWarnings("checkstyle:IllegalCatch")
115     public void createLocalCache(Uint64 dpnId, String ipAddress,
116                                  String transportZone) throws TepException {
117
118         CHECK.incrementAndGet();
119         IpAddress ipAddressObj;
120
121         final VtepsKey vtepkey = new VtepsKey(dpnId);
122
123         ipAddressObj = IpAddressBuilder.getDefaultInstance(ipAddress);
124
125         if (checkTepPerTzPerDpn(transportZone, dpnId)) {
126             handleError("Only one end point per transport Zone per Dpn is allowed");
127             return;
128         }
129
130         Vteps vtepCli = new VtepsBuilder().setDpnId(dpnId).setIpAddress(ipAddressObj).withKey(vtepkey)
131                 .build();
132
133         if (transportZonesHashMap.containsKey(transportZone)) {
134             List<Vteps> vtepListTemp = transportZonesHashMap.get(transportZone);
135             if (!vtepListTemp.contains(vtepCli)) {
136                 vtepListTemp.add(vtepCli);
137             }
138         } else {
139             List<Vteps> vtepListTemp = new ArrayList<>();
140             vtepListTemp.add(vtepCli);
141             transportZonesHashMap.put(transportZone, vtepListTemp);
142         }
143     }
144
145     /**
146      * Gets the transport zone.
147      *
148      * @param transportZoneName
149      *            the tzone
150      * @return the transport zone
151      */
152     public TransportZone getTransportZone(String transportZoneName) {
153         InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class)
154                 .child(TransportZone.class, new TransportZoneKey(transportZoneName)).build();
155         return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath, dataBroker).orElse(null);
156     }
157
158     /**
159      * Gets all transport zones.
160      *
161      * @return all transport zones
162      */
163     public TransportZones getAllTransportZones() {
164         InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
165         return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker).orElse(null);
166     }
167
168
169     public boolean checkTepPerTzPerDpn(String tzone, Uint64 dpnId) {
170         // check in local cache
171         if (transportZonesHashMap.containsKey(tzone)) {
172             List<Vteps> vtepList = transportZonesHashMap.get(tzone);
173             for (Vteps vtep : vtepList) {
174                 if (Objects.equals(vtep.getDpnId(), dpnId)) {
175                     return true;
176                 }
177             }
178         }
179
180         // check in DS
181         InstanceIdentifier<TransportZone> tzonePath =
182                 InstanceIdentifier.builder(TransportZones.class)
183                         .child(TransportZone.class, new TransportZoneKey(tzone)).build();
184         Optional<TransportZone> transportZoneOptional =
185                 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath, dataBroker);
186         if (transportZoneOptional.isPresent()) {
187             TransportZone tz = transportZoneOptional.get();
188             for (Vteps vtep : tz.getVteps().values()) {
189                 if (Objects.equals(vtep.getDpnId(), dpnId)) {
190                     return true;
191                 }
192             }
193         }
194         return false;
195     }
196
197     @SuppressWarnings("checkstyle:IllegalCatch")
198     public void buildTeps() {
199         TransportZone transportZone = null;
200         try {
201             LOG.debug("no of teps added {}", CHECK);
202             if (transportZonesHashMap != null && !transportZonesHashMap.isEmpty()) {
203                 transportZoneArrayList = new ArrayList<>();
204                 for (Entry<String, List<Vteps>> mapEntry : transportZonesHashMap.entrySet()) {
205                     String tz = mapEntry.getKey();
206                     LOG.debug("transportZonesHashMap {}", tz);
207                     List<Vteps> vtepListTemp = mapEntry.getValue();
208                     InstanceIdentifier<TransportZone> transportZonePath =
209                             InstanceIdentifier.builder(TransportZones.class)
210                                     .child(TransportZone.class, new TransportZoneKey(tz)).build();
211                     Optional<TransportZone> transportZoneOptional =
212                             ItmUtils.read(LogicalDatastoreType.CONFIGURATION, transportZonePath, dataBroker);
213                     LOG.debug("read container from DS");
214                     if (transportZoneOptional.isPresent()) {
215                         TransportZone tzoneFromDs = transportZoneOptional.get();
216                         LOG.debug("read tzone container {}", tzoneFromDs);
217                         if (tzoneFromDs.getTunnelType() == null
218                                 || tzoneFromDs.getTunnelType().equals(TunnelTypeVxlan.class)) {
219                             transportZone =
220                                     new TransportZoneBuilder().withKey(new TransportZoneKey(tz))
221                                             .setTunnelType(TunnelTypeVxlan.class)
222                                             .setZoneName(tz).setVteps(vtepListTemp).build();
223                         } else if (tzoneFromDs.getTunnelType().equals(TunnelTypeGre.class)) {
224                             transportZone =
225                                     new TransportZoneBuilder().withKey(new TransportZoneKey(tz))
226                                             .setTunnelType(TunnelTypeGre.class).setVteps(vtepListTemp)
227                                             .setZoneName(tz).build();
228                         }
229                     } else {
230                         transportZone =
231                                 new TransportZoneBuilder().withKey(new TransportZoneKey(tz))
232                                         .setTunnelType(TunnelTypeVxlan.class).setZoneName(tz).setVteps(vtepListTemp)
233                                         .build();
234                     }
235                     LOG.debug("tzone object {}", transportZone);
236                     transportZoneArrayList.add(transportZone);
237                 }
238                 TransportZones transportZones = new TransportZonesBuilder()
239                         .setTransportZone(transportZoneArrayList.stream().collect(Collectors.toList())).build();
240                 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
241                 LOG.debug("InstanceIdentifier {}", path);
242                 Futures.addCallback(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
243                     tx -> tx.mergeParentStructureMerge(path, transportZones)), ItmUtils.DEFAULT_WRITE_CALLBACK,
244                         MoreExecutors.directExecutor());
245                 LOG.debug("wrote to Config DS {}", transportZones);
246                 transportZonesHashMap.clear();
247                 transportZoneArrayList.clear();
248                 LOG.debug("Everything cleared");
249             } else {
250                 LOG.debug("NO vteps were configured");
251             }
252         } catch (RuntimeException e) {
253             LOG.error("Error building TEPs", e);
254         }
255     }
256
257     public List<String> showTeps(boolean monitorEnabled, int monitorInterval) throws TepException {
258         boolean flag = false;
259         InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
260         Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
261                 path, dataBroker);
262         if (transportZonesOptional.isPresent()) {
263             List<String> result = new ArrayList<>();
264             TransportZones transportZones = transportZonesOptional.get();
265             if (transportZones.getTransportZone() == null || transportZones.getTransportZone().isEmpty()) {
266                 handleError("No teps configured");
267                 return result;
268             }
269             result.add(String.format("Tunnel Monitoring (for VXLAN tunnels): %s", monitorEnabled ? "On" : "Off"));
270             result.add(String.format("Tunnel Monitoring Interval (for VXLAN tunnels): %d", monitorInterval));
271             result.add(System.lineSeparator());
272             result.add(String.format("%-16s  %-16s  %-12s %-16s", "TransportZone", "TunnelType", "DpnID", "IPAddress"));
273             result.add("---------------------------------------------------------------------------------------------"
274                     + "---------------------------------");
275             for (TransportZone tz : transportZones.getTransportZone()) {
276                 if (tz.getVteps() == null || tz.getVteps().isEmpty()) {
277                     continue;
278                 }
279                 for (Vteps vtep : tz.getVteps().values()) {
280                     flag = true;
281                     String strTunnelType ;
282                     if (TunnelTypeGre.class.equals(tz.getTunnelType())) {
283                         strTunnelType = ITMConstants.TUNNEL_TYPE_GRE;
284                     } else {
285                         strTunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
286                     }
287                     result.add(String.format("%-16s  %-16s  %-12s %-16s",
288                             tz.getZoneName(), strTunnelType,
289                             vtep.getDpnId().toString(), vtep.getIpAddress().stringValue()));
290                 }
291             }
292             if (flag) {
293                 return result;
294             } else {
295                 return Collections.singletonList("No teps to display");
296             }
297         } else {
298             return Collections.singletonList("No teps configured");
299         }
300     }
301
302     @SuppressWarnings("checkstyle:RegexpSinglelineJava")
303     public void showCache(String cacheName) {
304         final Collection<String> cacheContent;
305         switch (cacheName) {
306             case ITMConstants.INTERNAL_TUNNEL_CACHE_NAME:
307                 cacheContent = ItmUtils.ITM_CACHE.getAllInternalInterfaces();
308                 break;
309             case ITMConstants.EXTERNAL_TUNNEL_CACHE_NAME:
310                 cacheContent = ItmUtils.ITM_CACHE.getAllExternalInterfaces();
311                 break;
312             case ITMConstants.UNPROCESSED_TUNNELS_CACHE_NAME:
313                 cacheContent = unprocessedTunnelsStateCache.getAllUnprocessedTunnels();
314                 break;
315             default:
316                 System.out.println(" " + cacheName + " is not a valid Cache Name ");
317                 return;
318         }
319         System.out.println("Dumping the data in cache for " + cacheName);
320         System.out.println("Number of data in cache " + cacheContent.size());
321         if (!cacheContent.isEmpty()) {
322             for (String key : cacheContent) {
323                 System.out.println(key + " ");
324             }
325         } else {
326             System.out.println("No data in cache for " + cacheName);
327         }
328     }
329
330     @SuppressWarnings("checkstyle:IllegalCatch")
331     public void deleteVtep(Uint64 dpnId, String ipAddress,
332                            String transportZone) throws TepException {
333
334         final VtepsKey vtepkey = new VtepsKey(dpnId);
335
336         IpAddress ipAddressObj = IpAddressBuilder.getDefaultInstance(ipAddress);
337
338         Vteps vtepCli;
339
340         InstanceIdentifier<Vteps> vpath = InstanceIdentifier.builder(TransportZones.class)
341                 .child(TransportZone.class, new TransportZoneKey(transportZone))
342                 .child(Vteps.class, vtepkey).build();
343
344         // check if present in tzones and delete from cache
345         boolean existsInCache = isInCache(dpnId, ipAddress, transportZone);
346         if (!existsInCache) {
347             Optional<Vteps> vtepOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, vpath, dataBroker);
348             if (vtepOptional.isPresent()) {
349                 vtepCli = vtepOptional.get();
350                 if (Objects.equals(vtepCli.getIpAddress(), ipAddressObj)) {
351                     vtepDelCommitList.add(vtepCli);
352                 }
353             } else {
354                 handleError("Vtep Doesnt exist");
355             }
356         }
357     }
358
359     @SuppressWarnings("checkstyle:IllegalCatch")
360     public <T extends DataObject> void deleteOnCommit() {
361         List<InstanceIdentifier<T>> vtepPaths = new ArrayList<>();
362         List<InstanceIdentifier<T>> subnetPaths = new ArrayList<>();
363         List<Vteps> vtepDelList = new ArrayList<>();
364         List<InstanceIdentifier<T>> allPaths = new ArrayList<>();
365         try {
366             if (vtepDelCommitList != null && !vtepDelCommitList.isEmpty()) {
367                 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
368                 Optional<TransportZones> transportZonesOptional =
369                         ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
370                 if (transportZonesOptional.isPresent()) {
371                     List<TransportZone> transportZones = transportZonesOptional.get().nonnullTransportZone();
372                     for (TransportZone tz : transportZones) {
373                         if (tz.getVteps() == null || tz.getVteps().isEmpty()) {
374                             continue;
375                         }
376                         vtepDelList.addAll(vtepDelCommitList);
377                         for (Vteps vtep : vtepDelList) {
378                             InstanceIdentifier<T> vpath =
379                                     (InstanceIdentifier<T>) InstanceIdentifier
380                                             .builder(TransportZones.class)
381                                             .child(TransportZone.class, tz.key())
382                                             .child(Vteps.class, vtep.key()).build();
383                             vtepPaths.add(vpath);
384                         }
385                     }
386
387                     allPaths.addAll(vtepPaths);
388                     allPaths.addAll(subnetPaths);
389                     Futures.addCallback(txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.CONFIGURATION,
390                         tx -> allPaths.forEach(tx::delete)), ItmUtils.DEFAULT_WRITE_CALLBACK,
391                             MoreExecutors.directExecutor());
392                 }
393                 vtepPaths.clear();
394                 subnetPaths.clear();
395                 allPaths.clear();
396                 vtepDelCommitList.clear();
397             }
398         } catch (RuntimeException e) {
399             LOG.error("Unexpected error", e);
400         }
401     }
402
403     @SuppressWarnings("checkstyle:RegexpSinglelineJava")
404     public void showState(Collection<StateTunnelList> tunnelLists, boolean tunnelMonitorEnabled) throws TepException {
405         if (tunnelLists == null || tunnelLists.isEmpty()) {
406             handleError("No Internal Tunnels Exist");
407             return;
408         }
409         if (!tunnelMonitorEnabled) {
410             System.out.println("Tunnel Monitoring is Off");
411         }
412         String displayFormat = "%-16s  %-16s  %-16s  %-16s  %-16s  %-10s  %-10s";
413         System.out.println(String.format(displayFormat, "Tunnel Name", "Source-DPN",
414                 "Destination-DPN", "Source-IP", "Destination-IP", "Trunk-State", "Transport Type"));
415         System.out.println("-----------------------------------------------------------------------------------------"
416                 + "--------------------------------------------");
417
418         for (StateTunnelList tunnelInst : tunnelLists) {
419             // Display only the internal tunnels
420             if (TepTypeInternal.class.equals(tunnelInst.getDstInfo().getTepDeviceType())) {
421                 String tunnelInterfaceName = tunnelInst.getTunnelInterfaceName();
422                 LOG.trace("tunnelInterfaceName::: {}", tunnelInterfaceName);
423                 String tunnelState = ITMConstants.TUNNEL_STATE_UNKNOWN;
424                 if (tunnelInst.getOperState() == TunnelOperStatus.Up) {
425                     tunnelState = ITMConstants.TUNNEL_STATE_UP;
426                 } else if (tunnelInst.getOperState() == TunnelOperStatus.Down) {
427                     tunnelState = ITMConstants.TUNNEL_STATE_DOWN;
428                 }
429                 Class<? extends TunnelTypeBase> tunType = tunnelInst.getTransportType();
430                 String tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
431                 if (TunnelTypeVxlan.class.equals(tunType)) {
432                     tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
433                 } else if (tunType.equals(TunnelTypeGre.class)) {
434                     tunnelType = ITMConstants.TUNNEL_TYPE_GRE;
435                 } else if (tunType.equals(TunnelTypeMplsOverGre.class)) {
436                     tunnelType = ITMConstants.TUNNEL_TYPE_MPLSoGRE;
437                 } else if (tunType.equals(TunnelTypeLogicalGroup.class)) {
438                     tunnelType = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
439                 }
440                 System.out.println(String.format(displayFormat, tunnelInst.getTunnelInterfaceName(),
441                         tunnelInst.getSrcInfo().getTepDeviceId(), tunnelInst.getDstInfo().getTepDeviceId(),
442                         tunnelInst.getSrcInfo().getTepIp().stringValue(),
443                         tunnelInst.getDstInfo().getTepIp().stringValue(), tunnelState, tunnelType));
444             }
445         }
446     }
447
448     // Show DPN-ID and Bridge mapping
449     public void showBridges(Map<Uint64, OvsdbBridgeRef> dpnIdBridgeRefMap) {
450         System.out.println(String.format("%-16s  %-16s  %-36s%n", "DPN-ID", "Bridge-Name", "Bridge-UUID")
451                 + "------------------------------------------------------------------------");
452         dpnIdBridgeRefMap.forEach((dpnId, ovsdbBridgeRef) -> {
453             String szBridgeId = ovsdbBridgeRef.getValue().firstKeyOf(Node.class).getNodeId().getValue();
454             String bridgeUUID = szBridgeId.substring(13, 49);
455             String bridgeName = szBridgeId.substring(57);
456             System.out.println(String.format("%-16s  %-16s  %-36s", dpnId, bridgeName, bridgeUUID));
457         });
458     }
459
460     // deletes from ADD-cache if it exists.
461     public boolean isInCache(Uint64 dpnId, String ipAddress,
462                              String transportZone) throws TepException {
463         boolean exists = false;
464         final VtepsKey vtepkey = new VtepsKey(dpnId);
465         IpAddress ipAddressObj = IpAddressBuilder.getDefaultInstance(ipAddress);
466
467         Vteps vtepCli = new VtepsBuilder().setDpnId(dpnId).setIpAddress(ipAddressObj).withKey(vtepkey).build();
468
469         if (transportZonesHashMap.containsKey(transportZone)) {
470             List<Vteps> vtepListTemp = transportZonesHashMap.get(transportZone);
471             if (vtepListTemp.contains(vtepCli)) {
472                 exists = true; // return true if tzones has vtep
473                 vtepListTemp.remove(vtepCli);
474                 if (vtepListTemp.size() == 0) {
475                     transportZonesHashMap.remove(transportZone);
476                 }
477             } else {
478                 handleError("Vtep has not been configured");
479             }
480         }
481         return exists;
482     }
483
484     public void configureTunnelType(String transportZoneName, String tunnelType) throws ExecutionException,
485             InterruptedException {
486         LOG.debug("configureTunnelType {} for transportZone {}", tunnelType, transportZoneName);
487
488         TransportZone transportZoneFromConfigDS = ItmUtils.getTransportZoneFromConfigDS(transportZoneName, dataBroker);
489         Class<? extends TunnelTypeBase> tunType;
490
491         if (transportZoneFromConfigDS != null) {
492             if (!transportZoneName.equals(ITMConstants.DEFAULT_TRANSPORT_ZONE)) {
493                 LOG.debug("Transport zone {} with tunnel type {} already exists. No action required.",
494                         transportZoneName, tunnelType);
495                 return;
496             } else {
497                 tunnelType = StringUtils.upperCase(tunnelType);
498                 tunType = ItmUtils.TUNNEL_TYPE_MAP.get(tunnelType);
499                 if (Objects.equals(transportZoneFromConfigDS.getTunnelType(), tunType)) {
500                     // default-TZ already exists and tunnel-type is not changed during
501                     // controller restart, then nothing to do now. Just return.
502                     return;
503                 }
504             }
505         }
506
507         // get tunnel-type
508         tunnelType = StringUtils.upperCase(tunnelType);
509         tunType = ItmUtils.TUNNEL_TYPE_MAP.get(tunnelType);
510
511
512         InstanceIdentifier<TransportZones> path = InstanceIdentifier.create(TransportZones.class);
513
514         Optional<TransportZones> tzones = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
515
516         TransportZone tzone = new TransportZoneBuilder().withKey(new TransportZoneKey(transportZoneName))
517                 .setTunnelType(tunType).build();
518         List<TransportZone> tzList = new ArrayList<>();
519         if (tzones.isPresent()) {
520             final List<TransportZone> lst = tzones.get().getTransportZone();
521             if (lst != null) {
522                 tzList.addAll(lst);
523             }
524         }
525         tzList.add(tzone);
526         TransportZones transportZones = new TransportZonesBuilder().setTransportZone(tzList).build();
527
528         /*InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class).
529         child(TransportZone.class, new TransportZoneKey(transportZoneName)).build();
530
531         TransportZone transportZone = new TransportZoneBuilder().setZoneName(transportZoneName)
532                 .setTunnelType(tunType)
533                 .withKey(new TransportZoneKey(transportZoneName)).build();*/
534
535         txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> tx.put(path, transportZones)).get();
536
537     }
538
539     public void configureTunnelMonitorParams(boolean monitorEnabled, String monitorProtocol) {
540         InstanceIdentifier<TunnelMonitorParams> path = InstanceIdentifier.create(TunnelMonitorParams.class);
541         Optional<TunnelMonitorParams> storedTunnelMonitor = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
542                 path, dataBroker);
543         Class<? extends TunnelMonitoringTypeBase> monitorType ;
544         if (storedTunnelMonitor.isPresent() && storedTunnelMonitor.get().getMonitorProtocol() != null) {
545             monitorType = storedTunnelMonitor.get().getMonitorProtocol();
546         } else {
547             if (monitorProtocol != null && monitorProtocol.equalsIgnoreCase(ITMConstants.MONITOR_TYPE_LLDP)) {
548                 monitorType = TunnelMonitoringTypeLldp.class;
549             } else {
550                 monitorType = TunnelMonitoringTypeBfd.class;
551             }
552         }
553         if (!storedTunnelMonitor.isPresent() || storedTunnelMonitor.get().isEnabled() != monitorEnabled) {
554             TunnelMonitorParams tunnelMonitor = new TunnelMonitorParamsBuilder().setEnabled(monitorEnabled)
555                     .setMonitorProtocol(monitorType).build();
556             Futures.addCallback(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
557                 tx -> tx.merge(path, tunnelMonitor)), ItmUtils.DEFAULT_WRITE_CALLBACK,
558                     MoreExecutors.directExecutor());
559         }
560     }
561
562     public void configureTunnelMonitorInterval(int interval) {
563         InstanceIdentifier<TunnelMonitorInterval> path =
564                 InstanceIdentifier.builder(TunnelMonitorInterval.class).build();
565         Optional<TunnelMonitorInterval> storedTunnelMonitor = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path,
566                 dataBroker);
567         if (!storedTunnelMonitor.isPresent() || storedTunnelMonitor.get().getInterval().toJava() != interval) {
568             TunnelMonitorInterval tunnelMonitor = new TunnelMonitorIntervalBuilder().setInterval(interval).build();
569             Futures.addCallback(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
570                 tx -> tx.mergeParentStructureMerge(path, tunnelMonitor)), ItmUtils.DEFAULT_WRITE_CALLBACK,
571                     MoreExecutors.directExecutor());
572         }
573     }
574
575     public void handleError(String errorMessage) throws TepException {
576         throw new TepException(errorMessage);
577     }
578
579     @SuppressWarnings("checkstyle:RegexpSinglelineJava")
580     public void showOfPorts(Collection<OfTep> ofTeps) {
581         List<String> result = new ArrayList<String>();
582
583         result.add(String.format("%-16s  %-40s %-16s %-16s %-16s", "Source_DPN", "OfTep_Ip", "OfPort_Name",
584                 "OfPort_Number", "State"));
585         result.add("-------------------------------------------------------------------------------------------------");
586
587         for (OfTep ofTep : ofTeps) {
588             result.add(String.format("%-16s  %-40s %-16s %-16s %-16s", ofTep.getSourceDpnId(),
589                     ofTep.getTepIp().getIpv4Address().getValue(), ofTep.getOfPortName(),ofTep.getPortNumber(),
590                     ofTep.getOfTepState()));
591         }
592
593         for (String p : result) {
594             System.out.println(p);
595         }
596     }
597 }