Merge "ITM new style component test (empty)"
[genius.git] / itm / itm-impl / src / main / java / org / opendaylight / genius / itm / cli / TepCommandHelper.java
1 /*
2  * Copyright (c) 2016 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 com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
12 import java.math.BigInteger;
13 import java.util.ArrayList;
14 import java.util.HashMap;
15 import java.util.List;
16 import java.util.Map;
17 import javax.annotation.PostConstruct;
18 import javax.annotation.PreDestroy;
19 import javax.inject.Inject;
20 import javax.inject.Singleton;
21 import org.apache.commons.net.util.SubnetUtils;
22 import org.apache.felix.service.command.CommandSession;
23 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
24 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
25 import org.opendaylight.genius.itm.globals.ITMConstants;
26 import org.opendaylight.genius.itm.impl.ItmUtils;
27 import org.opendaylight.genius.mdsalutil.MDSALDataStoreUtils;
28 import org.opendaylight.genius.utils.cache.DataStoreCache;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBase;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBfd;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeLldp;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorInterval;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorIntervalBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorParams;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorParamsBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeInternal;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZonesBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Subnets;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.SubnetsBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.SubnetsKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.Vteps;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.VtepsBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.VtepsKey;
56 import org.opendaylight.yangtools.yang.binding.DataObject;
57 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60
61 @Singleton
62 public class TepCommandHelper {
63
64     private static final Logger LOG = LoggerFactory.getLogger(TepCommandHelper.class);
65     private final DataBroker dataBroker;
66     static int check = 0;
67     static short flag = 0;
68     /*
69      * boolean flag add_or_delete --- can be set to true if the last called tep
70      * command is Tep-add else set to false when Tep-delete is called
71      * tepCommandHelper object is created only once in session initiated
72      */
73     final Map<String, Map<SubnetObject, List<Vteps>>> tZones = new HashMap<>();
74     private List<Subnets> subnetList = new ArrayList<>();
75     private List<TransportZone> tZoneList = new ArrayList<>();
76     private List<Vteps> vtepDelCommitList = new ArrayList<>();
77
78     // private List<InstanceIdentifier<? extends DataObject>> vtepPaths = new
79     // ArrayList<>();
80
81     @Inject
82     public TepCommandHelper(final DataBroker dataBroker) {
83         this.dataBroker = dataBroker;
84     }
85
86     @PostConstruct
87     public void start() throws Exception {
88         configureTunnelType(ITMConstants.DEFAULT_TRANSPORT_ZONE,ITMConstants.TUNNEL_TYPE_VXLAN);
89         LOG.info("TepCommandHelper Started");
90     }
91
92     @PreDestroy
93     public void close() throws Exception {
94         LOG.info("TepCommandHelper Closed");
95     }
96
97     public void createLocalCache(BigInteger dpnId, String portName, Integer vlanId, String ipAddress,
98                                  String subnetMask, String gatewayIp, String transportZone, CommandSession session) throws TepException{
99
100         check++;
101         IpAddress ipAddressObj = null;
102         IpAddress gatewayIpObj = null;
103         IpPrefix subnetMaskObj = null;
104         VtepsKey vtepkey = new VtepsKey(dpnId, portName);
105         try {
106             ipAddressObj = new IpAddress(ipAddress.toCharArray());
107             gatewayIpObj = new IpAddress("0.0.0.0".toCharArray());
108             if (gatewayIp != null) {
109                 gatewayIpObj = new IpAddress(gatewayIp.toCharArray());
110             } else {
111                 LOG.debug("gateway is null");
112             }
113         } catch (Exception e) {
114             handleError("Invalid IpAddress. Expected: 1.0.0.0 to 254.255.255.255", session);
115             return;
116         }
117         try {
118             subnetMaskObj = new IpPrefix(subnetMask.toCharArray());
119         } catch (Exception e) {
120             handleError("Invalid Subnet Mask. Expected: 0.0.0.0/0 to 255.255.255.255/32", session);
121             return;
122         }
123
124         if (!validateIPs(ipAddress, subnetMask, gatewayIp)) {
125             handleError("IpAddress and gateWayIp should belong to the subnet provided", session);
126             return;
127         }
128
129         if (checkTepPerTzPerDpn(transportZone, dpnId)) {
130             if(session  != null) {
131                 session.getConsole().println("Only one end point per transport Zone per Dpn is allowed");
132             }
133             return;
134         }
135         Vteps vtepCli = new VtepsBuilder().setDpnId(dpnId).setIpAddress(ipAddressObj).setKey(vtepkey)
136                 .setPortname(portName).build();
137         validateForDuplicates(vtepCli, transportZone);
138
139         SubnetsKey subnetsKey = new SubnetsKey(subnetMaskObj);
140         SubnetObject subObCli = new SubnetObject(gatewayIpObj, subnetsKey, subnetMaskObj, vlanId);
141         if (tZones.containsKey(transportZone)) {
142             Map<SubnetObject, List<Vteps>> subVtepMapTemp = tZones.get(transportZone);
143             if (subVtepMapTemp.containsKey(subObCli)) { // if Subnet exists
144                 List<Vteps> vtepListTemp = subVtepMapTemp.get(subObCli);
145                 if (vtepListTemp.contains(vtepCli)) {
146                     // do nothing
147                 } else {
148                     vtepListTemp.add(vtepCli);
149                 }
150             } else { // subnet doesnt exist
151                 if (checkExistingSubnet(subVtepMapTemp, subObCli)) {
152                     if(session != null) {
153                         session.getConsole().println("subnet with subnet mask " + subObCli.get_key() + "already exists");
154                     }
155                     return;
156                 }
157                 List<Vteps> vtepListTemp = new ArrayList<>();
158                 vtepListTemp.add(vtepCli);
159                 subVtepMapTemp.put(subObCli, vtepListTemp);
160             }
161         } else {
162             List<Vteps> vtepListTemp = new ArrayList<>();
163             vtepListTemp.add(vtepCli);
164             Map<SubnetObject, List<Vteps>> subVtepMapTemp = new HashMap<>();
165             subVtepMapTemp.put(subObCli, vtepListTemp);
166             tZones.put(transportZone, subVtepMapTemp);
167         }
168     }
169
170     private boolean validateIPs(String ipAddress, String subnetMask, String gatewayIp) {
171         SubnetUtils utils = new SubnetUtils(subnetMask);
172         if ((utils.getInfo().isInRange(ipAddress)) && ((gatewayIp == null) || (utils.getInfo().isInRange(gatewayIp)))) {
173             return true;
174         } else {
175             LOG.trace("InValid IP");
176             return false;
177         }
178     }
179
180     /**
181      * Validate for duplicates.
182      *
183      * @param inputVtep
184      *            the input vtep
185      * @param transportZone
186      *            the transport zone
187      */
188     public void validateForDuplicates(Vteps inputVtep, String transportZone) {
189         Map<String, TransportZone> tZoneMap = getAllTransportZonesAsMap();
190
191         boolean isConfiguredTepGreType = isGreTunnelType(transportZone, tZoneMap);
192         // Checking for duplicates in local cache
193         for (String tZ : tZones.keySet()) {
194             boolean isGreType = isGreTunnelType(tZ, tZoneMap);
195             Map<SubnetObject, List<Vteps>> subVtepMapTemp = tZones.get(tZ);
196             for (SubnetObject subOb : subVtepMapTemp.keySet()) {
197                 List<Vteps> vtepList = subVtepMapTemp.get(subOb);
198                 validateForDuplicateAndSingleGreTep(inputVtep, isConfiguredTepGreType, isGreType, vtepList);
199             }
200         }
201         // Checking for duplicates in config DS
202         for (TransportZone tZ : tZoneMap.values()) {
203             boolean isGreType = false;
204             if (tZ.getTunnelType().equals(TunnelTypeGre.class)) {
205                 isGreType = true;
206             }
207             for (Subnets sub : ItmUtils.emptyIfNull(tZ.getSubnets())) {
208                 List<Vteps> vtepList = sub.getVteps();
209                 validateForDuplicateAndSingleGreTep(inputVtep, isConfiguredTepGreType, isGreType, vtepList);
210             }
211         }
212     }
213
214     private void validateForDuplicateAndSingleGreTep(Vteps inputVtep, boolean isConfiguredTepGreType, boolean isGreType,
215                                                      List<Vteps> vtepList) {
216         if (ItmUtils.isEmpty(vtepList)) {
217             return;
218         }
219         if (vtepList.contains(inputVtep)) {
220             Preconditions.checkArgument(false, "VTEP already exists");
221         }
222         BigInteger dpnId = inputVtep.getDpnId();
223         if (isConfiguredTepGreType && isGreType) {
224             for (Vteps vtep : vtepList) {
225                 if (vtep.getDpnId().equals(dpnId)) {
226                     String errMsg = "DPN [" + dpnId +
227                             "] already configured with GRE TEP. Mutiple GRE TEP's on a single DPN are not allowed.";
228                     Preconditions.checkArgument(false, errMsg);
229                 }
230             }
231         }
232     }
233
234     /**
235      * Gets all transport zones as map.
236      *
237      * @return all transport zones as map
238      */
239     private Map<String, TransportZone> getAllTransportZonesAsMap() {
240         TransportZones tZones = getAllTransportZones();
241         Map<String, TransportZone> tZoneMap = new HashMap<>();
242         if( null != tZones) {
243             for (TransportZone tzone : ItmUtils.emptyIfNull(tZones.getTransportZone())) {
244                 tZoneMap.put(tzone.getZoneName(), tzone);
245             }
246         }
247         return tZoneMap;
248     }
249
250     /**
251      * Checks if is gre tunnel type.
252      *
253      * @param tZoneName
254      *            the zone name
255      * @param tZoneMap
256      *            the zone map
257      * @return true, if is gre tunnel type
258      */
259     private boolean isGreTunnelType(String tZoneName, Map<String, TransportZone> tZoneMap) {
260         TransportZone tzone = tZoneMap.get(tZoneName);
261         /*
262         if (tzone != null && StringUtils.equalsIgnoreCase(ITMConstants.TUNNEL_TYPE_GRE, tzone.getTunnelType())) {
263             return true;
264         }
265         */
266         return (tzone != null) && (tzone.getTunnelType()).equals(TunnelTypeGre.class);
267     }
268
269     /**
270      * Gets the transport zone.
271      *
272      * @param tzone
273      *            the tzone
274      * @return the transport zone
275      */
276     public TransportZone getTransportZone(String tzone) {
277         InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class)
278                 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
279         return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath, dataBroker).orNull();
280     }
281
282     /**
283      * Gets the transport zone from config ds.
284      *
285      * @param tzone
286      *            the tzone
287      * @return the transport zone
288      */
289     public TransportZone getTransportZoneFromConfigDS(String tzone) {
290         InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class)
291                 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
292         return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath, dataBroker).orNull();
293     }
294
295     /**
296      * Gets all transport zones.
297      *
298      * @return all transport zones
299      */
300     public TransportZones getAllTransportZones() {
301         InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
302         return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker).orNull();
303     }
304
305     public boolean checkExistingSubnet(Map<SubnetObject, List<Vteps>> subVtepMapTemp, SubnetObject subObCli) {
306         for (SubnetObject subOb : subVtepMapTemp.keySet()) {
307             if (subOb.get_key().equals(subObCli.get_key())) {
308                 if (!(subOb.get_vlanId().equals(subObCli.get_vlanId())))
309                     return true;
310                 if (!(subOb.get_gatewayIp().equals(subObCli.get_gatewayIp())))
311                     return true;
312             }
313         }
314         return false;
315     }
316
317     public boolean checkTepPerTzPerDpn(String tzone, BigInteger dpnId) {
318         // check in local cache
319         if (tZones.containsKey(tzone)) {
320             Map<SubnetObject, List<Vteps>> subVtepMapTemp = tZones.get(tzone);
321             for (SubnetObject subOb : subVtepMapTemp.keySet()) {
322                 List<Vteps> vtepList = subVtepMapTemp.get(subOb);
323                 for (Vteps vtep : vtepList)
324                     if (vtep.getDpnId().equals(dpnId))
325                         return true;
326             }
327         }
328
329         // check in DS
330         InstanceIdentifier<TransportZone> tzonePath =
331                 InstanceIdentifier.builder(TransportZones.class)
332                         .child(TransportZone.class, new TransportZoneKey(tzone)).build();
333         Optional<TransportZone> tZoneOptional =
334                 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath, dataBroker);
335         if (tZoneOptional.isPresent()) {
336             TransportZone tz = tZoneOptional.get();
337             if (tz.getSubnets() == null || tz.getSubnets().isEmpty())
338                 return false;
339             for (Subnets sub : tz.getSubnets()) {
340                 if (sub.getVteps() == null || sub.getVteps().isEmpty())
341                     continue;
342                 for (Vteps vtep : sub.getVteps()) {
343                     if (vtep.getDpnId().equals(dpnId)) {
344                         return true;
345                     }
346                 }
347             }
348         }
349         return false;
350     }
351
352     public void buildTeps() {
353         TransportZones tZonesBuilt = null;
354         TransportZone tZone = null;
355         try {
356             LOG.debug("no of teps added" + check);
357             if (tZones != null || !tZones.isEmpty()) {
358                 tZoneList = new ArrayList<>();
359                 for (String tZ : tZones.keySet()) {
360                     LOG.debug("tZones" + tZ);
361                     subnetList = new ArrayList<>();
362                     Map<SubnetObject, List<Vteps>> subVtepMapTemp = tZones.get(tZ);
363                     for (SubnetObject subOb : subVtepMapTemp.keySet()) {
364                         LOG.debug("subnets" + subOb.get_prefix());
365                         List<Vteps> vtepList = subVtepMapTemp.get(subOb);
366                         Subnets subnet =
367                                 new SubnetsBuilder().setGatewayIp(subOb.get_gatewayIp())
368                                         .setKey(subOb.get_key()).setPrefix(subOb.get_prefix())
369                                         .setVlanId(subOb.get_vlanId()).setVteps(vtepList).build();
370                         subnetList.add(subnet);
371                         LOG.debug("vteps" + vtepList);
372                     }
373                     InstanceIdentifier<TransportZone> tZonepath =
374                             InstanceIdentifier.builder(TransportZones.class)
375                                     .child(TransportZone.class, new TransportZoneKey(tZ)).build();
376                     Optional<TransportZone> tZoneOptional =
377                             ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tZonepath, dataBroker);
378                     LOG.debug("read container from DS");
379                     if (tZoneOptional.isPresent()) {
380                         TransportZone tzoneFromDs = tZoneOptional.get();
381                         LOG.debug("read tzone container" + tzoneFromDs.toString());
382                         if (tzoneFromDs.getTunnelType() == null
383                                 || (tzoneFromDs.getTunnelType()).equals(TunnelTypeVxlan.class)) {
384                             tZone =
385                                     new TransportZoneBuilder().setKey(new TransportZoneKey(tZ))
386                                             .setTunnelType(TunnelTypeVxlan.class).setSubnets(subnetList)
387                                             .setZoneName(tZ).build();
388                         } else if ((tzoneFromDs.getTunnelType()).equals(TunnelTypeGre.class)) {
389                             tZone =
390                                     new TransportZoneBuilder().setKey(new TransportZoneKey(tZ))
391                                             .setTunnelType(TunnelTypeGre.class).setSubnets(subnetList)
392                                             .setZoneName(tZ).build();
393                         }
394                     } else {
395                         tZone =
396                                 new TransportZoneBuilder().setKey(new TransportZoneKey(tZ))
397                                         .setTunnelType(TunnelTypeVxlan.class).setSubnets(subnetList).setZoneName(tZ)
398                                         .build();
399                     }
400                     LOG.debug("tzone object" + tZone);
401                     tZoneList.add(tZone);
402                 }
403                 tZonesBuilt = new TransportZonesBuilder().setTransportZone(tZoneList).build();
404                 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
405                 LOG.debug("InstanceIdentifier" + path);
406                 ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, path, tZonesBuilt, dataBroker,
407                         ItmUtils.DEFAULT_CALLBACK);
408                 LOG.debug("wrote to Config DS" + tZonesBuilt);
409                 tZones.clear();
410                 tZoneList.clear();
411                 subnetList.clear();
412                 LOG.debug("Everything cleared");
413             } else {
414                 LOG.debug("NO vteps were configured");
415             }
416         } catch (Exception e) {
417             LOG.error(e.getMessage());
418         }
419     }
420
421     public void showTeps(boolean monitorEnabled, int monitorInterval, CommandSession session) throws TepException {
422         boolean flag = false;
423         InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
424         Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
425         if (tZonesOptional.isPresent()) {
426             TransportZones tZones = tZonesOptional.get();
427             if(tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty())
428             {
429                 handleError("No teps configured", session);
430                 return;
431             }
432             List<String> result = new ArrayList<>();
433             result.add(String.format("Tunnel Monitoring (for VXLAN tunnels): %s", (monitorEnabled ? "On" : "Off")));
434             result.add(String.format("Tunnel Monitoring Interval (for VXLAN tunnels): %d", monitorInterval));
435             result.add(System.lineSeparator());
436             result.add(String.format("%-16s  %-16s  %-16s  %-12s  %-12s %-12s %-16s %-12s", "TransportZone", "TunnelType", "SubnetMask",
437                     "GatewayIP", "VlanID", "DpnID", "IPAddress", "PortName"));
438             result.add("------------------------------------------------------------------------------------------------------------------------------");
439             for (TransportZone tZ : tZones.getTransportZone()) {
440                 if (tZ.getSubnets() == null || tZ.getSubnets().isEmpty()) {
441                     LOG.error("Transport Zone " + tZ.getZoneName() + "has no subnets");
442                     continue;
443                 }
444                 for (Subnets sub : tZ.getSubnets()) {
445                     if (sub.getVteps() == null || sub.getVteps().isEmpty()) {
446                         LOG.error("Transport Zone " + tZ.getZoneName() + "subnet " + sub.getPrefix() + "has no vteps");
447                         continue;
448                     }
449                     for (Vteps vtep : sub.getVteps()) {
450                         flag = true;
451                         String strTunnelType ;
452                         if( (tZ.getTunnelType()).equals(TunnelTypeGre.class) )
453                             strTunnelType = ITMConstants.TUNNEL_TYPE_GRE ;
454                         else
455                             strTunnelType = ITMConstants.TUNNEL_TYPE_VXLAN ;
456                         result.add(String.format("%-16s  %-16s  %-16s  %-12s  %-12s %-12s %-16s %-12s", tZ.getZoneName(), strTunnelType, sub
457                                 .getPrefix().getIpv4Prefix().getValue(), sub.getGatewayIp().getIpv4Address()
458                                 .getValue(), sub.getVlanId().toString(), vtep.getDpnId().toString(), vtep
459                                 .getIpAddress().getIpv4Address().getValue(), vtep.getPortname()));
460                     }
461                 }
462             }
463             if (session != null) {
464                 if (flag) {
465                     for (String p : result) {
466                         session.getConsole().println(p);
467                     }
468                 } else {
469                     session.getConsole().println("No teps to display");
470                 }
471             }
472         } else if(session != null){
473             session.getConsole().println("No teps configured");
474         }
475     }
476
477 public void showCache(String cacheName) {
478
479         if( !DataStoreCache.isCacheValid(cacheName)) {
480             System.out.println( " " + cacheName + " is not a valid Cache Name ") ;
481             return ;
482         }
483         List<Object> keys = null ;
484         keys = DataStoreCache.getKeys(cacheName);
485         if( keys != null && !keys.isEmpty()) {
486             System.out.println( "Dumping the data in cache for " + cacheName ) ;
487             for( Object key : keys ) {
488                 System.out.println( " KEY:  " + key + " Value: " + DataStoreCache.get(cacheName, key) ) ;
489                 System.out.println() ;
490             }
491
492         }else
493             System.out.println( "No data in cache for " + cacheName ) ;
494         }
495
496     public void deleteVtep(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask,
497                            String gatewayIp, String transportZone,CommandSession session) throws TepException {
498
499         IpAddress ipAddressObj = null;
500         IpAddress gatewayIpObj = null;
501         IpPrefix subnetMaskObj = null;
502         VtepsKey vtepkey = new VtepsKey(dpnId, portName);
503         try {
504             ipAddressObj = new IpAddress(ipAddress.toCharArray());
505             gatewayIpObj = new IpAddress("0.0.0.0".toCharArray());
506             if (gatewayIp != null) {
507                 gatewayIpObj = new IpAddress(gatewayIp.toCharArray());
508             } else {
509                 LOG.debug("gateway is null");
510             }
511         } catch (Exception e) {
512             handleError("Invalid IpAddress. Expected: 1.0.0.0 to 254.255.255.255", session);
513             return;
514         }
515         try {
516             subnetMaskObj = new IpPrefix(subnetMask.toCharArray());
517         } catch (Exception e) {
518             handleError("Invalid Subnet Mask. Expected: 0.0.0.0/0 to 255.255.255.255/32", session);
519             return;
520         }
521
522         if (!validateIPs(ipAddress, subnetMask, gatewayIp)) {
523             handleError("IpAddress and gateWayIp should belong to the subnet provided", session);
524             return;
525         }
526         SubnetsKey subnetsKey = new SubnetsKey(subnetMaskObj);
527         Vteps vtepCli = null;
528         Subnets subCli = null;
529
530         InstanceIdentifier<Vteps> vpath =
531                 InstanceIdentifier.builder(TransportZones.class)
532                         .child(TransportZone.class, new TransportZoneKey(transportZone))
533                         .child(Subnets.class, subnetsKey).child(Vteps.class, vtepkey).build();
534
535         // check if present in tzones and delete from cache
536         boolean existsInCache = isInCache(dpnId, portName, vlanId, ipAddress, subnetMask, gatewayIp, transportZone, session);
537         if (!existsInCache) {
538             Optional<Vteps> vtepOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, vpath, dataBroker);
539             if (vtepOptional.isPresent()) {
540                 vtepCli = vtepOptional.get();
541                 if(vtepCli.getIpAddress().equals(ipAddressObj)){
542                     InstanceIdentifier<Subnets> spath =
543                             InstanceIdentifier
544                                     .builder(TransportZones.class)
545                                     .child(TransportZone.class, new TransportZoneKey(transportZone))
546                                     .child(Subnets.class, subnetsKey).build();
547                     Optional<Subnets> subOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, spath, dataBroker);
548                     if (subOptional.isPresent()) {
549                         subCli = subOptional.get();
550                         if(subCli.getGatewayIp().equals(gatewayIpObj) && subCli.getVlanId().equals(vlanId)){
551                             vtepDelCommitList.add(vtepCli);
552                         }
553                         else if(session != null) {
554                                 session.getConsole().println("vtep with this vlan or gateway doesnt exist");
555                         }
556                     }
557                 }
558                 else if(session != null) {
559                         session.getConsole().println("Vtep with this ipaddress doesnt exist");
560                 }
561             } else if(session != null) {
562                     session.getConsole().println("Vtep Doesnt exist");
563             }
564         }
565     }
566
567     public <T extends DataObject> void deleteOnCommit() {
568         List<InstanceIdentifier<T>> vtepPaths = new ArrayList<>();
569         List<InstanceIdentifier<T>> subnetPaths = new ArrayList<>();
570         List<InstanceIdentifier<T>> tzPaths = new ArrayList<>();
571         List<Subnets> subDelList = new ArrayList<>();
572         List<TransportZone> tzDelList = new ArrayList<>();
573         List<Vteps> vtepDelList = new ArrayList<>();
574         List<InstanceIdentifier<T>> allPaths = new ArrayList<>();
575         try {
576             if (vtepDelCommitList != null && !vtepDelCommitList.isEmpty()) {
577                 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
578                 Optional<TransportZones> tZonesOptional =
579                         ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
580                 if (tZonesOptional.isPresent()) {
581                     TransportZones tZones = tZonesOptional.get();
582                     for (TransportZone tZ : tZones.getTransportZone()) {
583                         if (tZ.getSubnets() == null || tZ.getSubnets().isEmpty())
584                             continue;
585                         for (Subnets sub : tZ.getSubnets()) {
586                             vtepDelList.addAll(vtepDelCommitList);
587                             for (Vteps vtep : vtepDelList) {
588                                 InstanceIdentifier<T> vpath =
589                                         (InstanceIdentifier<T>) InstanceIdentifier
590                                                 .builder(TransportZones.class)
591                                                 .child(TransportZone.class, tZ.getKey())
592                                                 .child(Subnets.class, sub.getKey())
593                                                 .child(Vteps.class, vtep.getKey()).build();
594                                 if (sub.getVteps().remove(vtep)) {
595                                     vtepPaths.add(vpath);
596                                     if (sub.getVteps().size() == 0 || sub.getVteps() == null) {
597                                         subDelList.add(sub);
598                                     }
599
600                                 }
601                             }
602                         }
603                     }
604
605                     for (TransportZone tZ : tZones.getTransportZone()) {
606                         if (tZ.getSubnets() == null || tZ.getSubnets().isEmpty())
607                             continue;
608                         for (Subnets sub : subDelList) {
609                             if (tZ.getSubnets().remove(sub)) {
610                                 InstanceIdentifier<T> spath =
611                                         (InstanceIdentifier<T>) InstanceIdentifier
612                                                 .builder(TransportZones.class)
613                                                 .child(TransportZone.class, tZ.getKey())
614                                                 .child(Subnets.class, sub.getKey()).build();
615                                 subnetPaths.add(spath);
616                                 if (tZ.getSubnets() == null || tZ.getSubnets().size() == 0) {
617                                     tzDelList.add(tZ);
618                                 }
619                             }
620                         }
621                     }
622
623                     for (TransportZone tZ : tzDelList) {
624                         if (tZones.getTransportZone().remove(tZ)) {
625                             InstanceIdentifier<T> tpath =
626                                     (InstanceIdentifier<T>) InstanceIdentifier.builder(TransportZones.class)
627                                             .child(TransportZone.class, tZ.getKey()).build();
628                             tzPaths.add(tpath);
629                             if (tZones.getTransportZone() == null || tZones.getTransportZone().size() == 0) {
630                                 MDSALDataStoreUtils.asyncRemove(dataBroker, LogicalDatastoreType.CONFIGURATION, path,
631                                         ItmUtils.DEFAULT_CALLBACK);
632                                 return;
633                             }
634                         }
635                     }
636                     allPaths.addAll(vtepPaths);
637                     allPaths.addAll(subnetPaths);
638                     allPaths.addAll(tzPaths);
639                     ItmUtils.asyncBulkRemove(dataBroker, LogicalDatastoreType.CONFIGURATION, allPaths,
640                             ItmUtils.DEFAULT_CALLBACK);
641                 }
642                 vtepPaths.clear();
643                 subnetPaths.clear();
644                 tzPaths.clear();
645                 allPaths.clear();
646                 vtepDelCommitList.clear();
647             }
648         } catch (Exception e) {
649             LOG.error(e.getMessage());
650         }
651     }
652
653     public void showState(List<StateTunnelList> tunnelLists, boolean tunnelMonitorEnabled,CommandSession session) throws TepException{
654         if (tunnelLists == null || tunnelLists.isEmpty()) {
655             handleError("No Internal Tunnels Exist", session);
656             return;
657         }
658         if (!tunnelMonitorEnabled) {
659             if(session != null) {
660                 session.getConsole().println("Tunnel Monitoring is Off");
661             }
662         }
663         String displayFormat = "%-16s  %-16s  %-16s  %-16s  %-16s  %-10s  %-10s";
664         session.getConsole().println(String.format(displayFormat, "Tunnel Name", "Source-DPN",
665                         "Destination-DPN", "Source-IP", "Destination-IP", "Trunk-State", "Transport Type"));
666         session.getConsole().println("-------------------------------------------------------------------------------------------------------------------------------------");
667
668         for (StateTunnelList tunnelInst : tunnelLists) {
669            // Display only the internal tunnels
670             if(  tunnelInst.getDstInfo().getTepDeviceType().equals(TepTypeInternal.class)) {
671                 String tunnelInterfaceName = tunnelInst.getTunnelInterfaceName();
672                 LOG.trace("tunnelInterfaceName::: {}", tunnelInterfaceName);
673                 String tunnelState = ITMConstants.TUNNEL_STATE_UNKNOWN;
674                 if (tunnelInst.getOperState() == TunnelOperStatus.Up)
675                     tunnelState = ITMConstants.TUNNEL_STATE_UP;
676                 else if (tunnelInst.getOperState() == TunnelOperStatus.Down )
677                     tunnelState = ITMConstants.TUNNEL_STATE_DOWN;
678                 Class<? extends TunnelTypeBase> tunType = tunnelInst.getTransportType();
679                 String tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
680                 if( tunType.equals(TunnelTypeVxlan.class))
681                    tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN ;
682                 else if( tunType.equals(TunnelTypeGre.class) )
683                    tunnelType = ITMConstants.TUNNEL_TYPE_GRE ;
684                 else if (tunType.equals(TunnelTypeMplsOverGre.class))
685                     tunnelType = ITMConstants.TUNNEL_TYPE_MPLSoGRE;
686                 session.getConsole().println(String.format(displayFormat, tunnelInst.getTunnelInterfaceName(), tunnelInst.getSrcInfo().getTepDeviceId(),
687                         tunnelInst.getDstInfo().getTepDeviceId(), tunnelInst.getSrcInfo().getTepIp().getIpv4Address().getValue(), tunnelInst.getDstInfo().getTepIp().getIpv4Address().getValue(), tunnelState,
688                         tunnelType));
689                 
690             }
691         }
692     }
693
694     // deletes from ADD-cache if it exists.
695     public boolean isInCache(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask,
696                              String gatewayIp, String transportZone, CommandSession session) {
697         boolean exists = false;
698         VtepsKey vtepkey = new VtepsKey(dpnId, portName);
699         IpAddress ipAddressObj = new IpAddress(ipAddress.toCharArray());
700         IpPrefix subnetMaskObj = new IpPrefix(subnetMask.toCharArray());
701         IpAddress gatewayIpObj = new IpAddress("0.0.0.0".toCharArray());
702         if (gatewayIp != null) {
703             gatewayIpObj = new IpAddress(gatewayIp.toCharArray());
704         } else {
705             LOG.debug("gateway is null");
706         }
707         SubnetsKey subnetsKey = new SubnetsKey(subnetMaskObj);
708         Vteps vtepCli =
709                 new VtepsBuilder().setDpnId(dpnId).setIpAddress(ipAddressObj).setKey(vtepkey)
710                         .setPortname(portName).build();
711         SubnetObject subObCli = new SubnetObject(gatewayIpObj, subnetsKey, subnetMaskObj, vlanId);
712
713         if (tZones.containsKey(transportZone)) {
714             Map<SubnetObject, List<Vteps>> subVtepMapTemp = tZones.get(transportZone);
715             if (subVtepMapTemp.containsKey(subObCli)) { // if Subnet exists
716                 List<Vteps> vtepListTemp = subVtepMapTemp.get(subObCli);
717                 if (vtepListTemp.contains(vtepCli)) {
718                     exists = true; // return true if tzones has vtep
719                     vtepListTemp.remove(vtepCli);
720                     if (vtepListTemp.size() == 0) {
721                         subVtepMapTemp.remove(subObCli);
722                         if (subVtepMapTemp.size() == 0) {
723                             tZones.remove(transportZone);
724                         }
725                     }
726                 } else if(session != null) {
727                         session.getConsole().println("Vtep " + "has not been configured");
728                 }
729             }
730         }
731         return exists;
732     }
733
734     public void configureTunnelType(String tZoneName, String tunnelType) {
735         LOG.debug("configureTunnelType {} for transportZone {}", tunnelType, tZoneName);
736
737         TransportZone tZoneFromConfigDS = getTransportZoneFromConfigDS(tZoneName);
738         validateTunnelType(tZoneName, tunnelType,tZoneFromConfigDS);
739
740         if (tZoneFromConfigDS != null) {
741             LOG.debug("Transport zone {} with tunnel type {} already exists. No action required.", tZoneName,
742                     tunnelType);
743             return;
744         }
745         TransportZones transportZones = null;
746         List<TransportZone> tZoneList = null;
747         InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
748         Optional<TransportZones> tZones = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
749         Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
750         if( tunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN))
751             tunType = TunnelTypeVxlan.class ;
752         else if( tunnelType.equals(ITMConstants.TUNNEL_TYPE_GRE) )
753             tunType = TunnelTypeGre.class ;
754
755         TransportZone tZone = new TransportZoneBuilder().setKey(new TransportZoneKey(tZoneName))
756                 .setTunnelType(tunType).build();
757         if (tZones.isPresent()) {
758             tZoneList = tZones.get().getTransportZone();
759             if(tZoneList == null || tZoneList.isEmpty()) {
760                 tZoneList = new ArrayList<>();
761             }
762         } else {
763             tZoneList = new ArrayList<>();
764         }
765         tZoneList.add(tZone);
766         transportZones = new TransportZonesBuilder().setTransportZone(tZoneList).build();
767         ItmUtils.syncWrite(LogicalDatastoreType.CONFIGURATION, path, transportZones, dataBroker);
768
769     }
770
771     /**
772      * Validate tunnel type.
773      *
774      * @param tZoneName
775      *            the t zone name
776      * @param tunnelType
777      *            the tunnel type
778      */
779     private void validateTunnelType(String tZoneName, String tunnelType,TransportZone tZoneFromConfigDS) {
780         /*
781         String strTunnelType = ItmUtils.validateTunnelType(tunnelType);
782
783         TransportZone tZone = getTransportZone(tZoneName);
784         if (tZone != null) {
785             if (!StringUtils.equalsIgnoreCase(strTunnelType, tZone.getTunnelType())
786                     && ItmUtils.isNotEmpty(tZone.getSubnets())) {
787                 String errorMsg = new StringBuilder("Changing the tunnel type from ").append(tZone.getTunnelType())
788                         .append(" to ").append(strTunnelType)
789                         .append(" is not allowed for already configured transport zone [").append(tZoneName)
790                         .append("].").toString();
791                 Preconditions.checkArgument(false, errorMsg);
792             }
793         }
794         */
795         String strTunnelType = ItmUtils.validateTunnelType(tunnelType);
796         Class<? extends TunnelTypeBase> tunType ;
797         if( strTunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN))
798             tunType = TunnelTypeVxlan.class ;
799         else
800             tunType = TunnelTypeGre.class ;
801         //TransportZone tZone = getTransportZone(tZoneName);
802         // if (tZone != null) {
803         if (tZoneFromConfigDS != null) {
804             if( (!tZoneFromConfigDS.getTunnelType().equals(tunType))  && ItmUtils.isNotEmpty(tZoneFromConfigDS.getSubnets())) {
805                 String errorMsg = "Changing the tunnel type from " + tZoneFromConfigDS.getTunnelType() +
806                         " to " + strTunnelType +
807                         " is not allowed for already configured transport zone [" + tZoneName +
808                         "].";
809                 Preconditions.checkArgument(false, errorMsg);
810             }
811         }
812     }
813
814     public void configureTunnelMonitorParams(boolean monitorEnabled, String monitorProtocol) {
815         InstanceIdentifier<TunnelMonitorParams> path = InstanceIdentifier.builder(TunnelMonitorParams.class).build();
816         Optional<TunnelMonitorParams> storedTunnelMonitor = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
817         Class<? extends TunnelMonitoringTypeBase> monitorType ;
818         if(storedTunnelMonitor.isPresent() && storedTunnelMonitor.get().getMonitorProtocol()!=null )
819             monitorType = storedTunnelMonitor.get().getMonitorProtocol();
820         else
821         {
822             if(monitorProtocol!=null && monitorProtocol.equalsIgnoreCase(ITMConstants.MONITOR_TYPE_LLDP))
823                 monitorType = TunnelMonitoringTypeLldp.class ;
824             else
825                 monitorType = TunnelMonitoringTypeBfd.class ;
826         }
827         if (!storedTunnelMonitor.isPresent()|| storedTunnelMonitor.get().isEnabled() != monitorEnabled)  {
828             TunnelMonitorParams tunnelMonitor = new TunnelMonitorParamsBuilder().setEnabled(monitorEnabled).setMonitorProtocol(monitorType).build();
829             ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, path, tunnelMonitor, dataBroker,
830                     ItmUtils.DEFAULT_CALLBACK);
831
832         }
833     }
834
835     public void configureTunnelMonitorInterval(int interval) {
836         InstanceIdentifier<TunnelMonitorInterval> path = InstanceIdentifier.builder(TunnelMonitorInterval.class).build();
837         Optional<TunnelMonitorInterval> storedTunnelMonitor = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
838         if (!storedTunnelMonitor.isPresent() || storedTunnelMonitor.get().getInterval() != interval) {
839             TunnelMonitorInterval tunnelMonitor = new TunnelMonitorIntervalBuilder().setInterval(interval).build();
840             ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, path, tunnelMonitor, dataBroker,
841                     ItmUtils.DEFAULT_CALLBACK);
842         }
843     }
844
845     public void handleError(String errorMessage, CommandSession session) throws TepException {
846         if(session != null) {
847             session.getConsole().println(errorMessage);
848         } else {
849             throw new TepException(errorMessage);
850         }
851
852     }
853 }