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