f7741591e394297e9079a6efb3898da8f2895df4
[vpnservice.git] / itm / itm-impl / src / main / java / org / opendaylight / vpnservice / 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.vpnservice.itm.cli;
9
10 import java.math.BigInteger;
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16
17 import org.apache.commons.lang3.StringUtils;
18 import org.apache.commons.net.util.SubnetUtils;
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.vpnservice.interfacemgr.exceptions.InterfaceNotFoundException;
22 import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
23 //import org.opendaylight.vpnservice.interfacemgr.util.OperationalIfmUtil;
24 import org.opendaylight.vpnservice.itm.globals.ITMConstants;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
26 import org.opendaylight.vpnservice.itm.impl.ItmUtils;
27 import org.opendaylight.vpnservice.mdsalutil.MDSALDataStoreUtils;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.TunnelMonitorEnabled;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.TunnelMonitorEnabledBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.TunnelMonitorInterval;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.TunnelMonitorIntervalBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.TunnelList ;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.tunnel.list.InternalTunnel;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.tunnel.list.InternalTunnelKey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeGre;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeVxlan;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.TransportZones;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.TransportZonesBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.TransportZone;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.TransportZoneBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.TransportZoneKey;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.Subnets;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.SubnetsBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.SubnetsKey;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.subnets.Vteps;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.subnets.VtepsBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.subnets.VtepsKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
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 import com.google.common.base.Optional;
62 import com.google.common.base.Preconditions;
63
64
65 public class TepCommandHelper {
66
67     private static final Logger LOG = LoggerFactory.getLogger(TepCommandHelper.class);
68     private DataBroker dataBroker;
69     static int check = 0;
70     static short flag = 0;
71     /*
72      * boolean flag add_or_delete --- can be set to true if the last called tep
73      * command is Tep-add else set to false when Tep-delete is called
74      * tepCommandHelper object is created only once in session initiated
75      */
76     final Map<String, Map<SubnetObject, List<Vteps>>> tZones = new HashMap<String, Map<SubnetObject, List<Vteps>>>();
77     private List<Subnets> subnetList = new ArrayList<Subnets>();
78     private List<TransportZone> tZoneList = new ArrayList<TransportZone>();
79     private List<Vteps> vtepDelCommitList = new ArrayList<Vteps>();
80     private IInterfaceManager interfaceManager;
81
82     // private List<InstanceIdentifier<? extends DataObject>> vtepPaths = new
83     // ArrayList<>();
84
85
86     public TepCommandHelper(final DataBroker broker) {
87         this.dataBroker = broker;
88     }
89
90
91     public void setInterfaceManager(IInterfaceManager interfaceManager) {
92         this.interfaceManager = interfaceManager;
93     }
94
95     public void createLocalCache(BigInteger dpnId, String portName, Integer vlanId, String ipAddress,
96                     String subnetMask, String gatewayIp, String transportZone) {
97
98         check++;
99         IpAddress ipAddressObj = null;
100         IpAddress gatewayIpObj = null;
101         IpPrefix subnetMaskObj = null;
102         VtepsKey vtepkey = new VtepsKey(dpnId, portName);
103         try {
104             ipAddressObj = new IpAddress(ipAddress.toCharArray());
105             gatewayIpObj = new IpAddress("0.0.0.0".toCharArray());
106             if (gatewayIp != null) {
107                 gatewayIpObj = new IpAddress(gatewayIp.toCharArray());
108             } else {
109                 LOG.debug("gateway is null");
110             }
111         } catch (Exception e) {
112             System.out.println("Invalid IpAddress. Expected: 1.0.0.0 to 254.255.255.255");
113             return;
114         }
115         try {
116             subnetMaskObj = new IpPrefix(subnetMask.toCharArray());
117         } catch (Exception e) {
118             System.out.println("Invalid Subnet Mask. Expected: 0.0.0.0/0 to 255.255.255.255/32");
119             return;
120         }
121
122         if (!validateIPs(ipAddress, subnetMask, gatewayIp)) {
123             System.out.println("IpAddress and gateWayIp should belong to the subnet provided");
124             return;
125         }
126
127         if (checkTepPerTzPerDpn(transportZone, dpnId)) {
128             System.out.println("Only one end point per transport Zone per Dpn is allowed");
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                     System.out.println("subnet with subnet mask " + subObCli.get_key() + "already exists");
149                     return;
150                 }
151                 List<Vteps> vtepListTemp = new ArrayList<Vteps>();
152                 vtepListTemp.add(vtepCli);
153                 subVtepMapTemp.put(subObCli, vtepListTemp);
154             }
155         } else {
156             List<Vteps> vtepListTemp = new ArrayList<Vteps>();
157             vtepListTemp.add(vtepCli);
158             Map<SubnetObject, List<Vteps>> subVtepMapTemp = new HashMap<SubnetObject, List<Vteps>>();
159             subVtepMapTemp.put(subObCli, vtepListTemp);
160             tZones.put(transportZone, subVtepMapTemp);
161         }
162     }
163
164     private boolean validateIPs(String ipAddress, String subnetMask, String gatewayIp) {
165         SubnetUtils utils = new SubnetUtils(subnetMask);
166         if ((utils.getInfo().isInRange(ipAddress)) && ((gatewayIp == null) || (utils.getInfo().isInRange(gatewayIp)))) {
167             return true;
168         } else {
169             LOG.trace("InValid IP");
170             return false;
171         }
172     }
173
174     /**
175      * Validate for duplicates.
176      *
177      * @param inputVtep
178      *            the input vtep
179      * @param transportZone
180      *            the transport zone
181      */
182     public void validateForDuplicates(Vteps inputVtep, String transportZone) {
183         Map<String, TransportZone> tZoneMap = getAllTransportZonesAsMap();
184
185         boolean isConfiguredTepGreType = isGreTunnelType(transportZone, tZoneMap);
186         // Checking for duplicates in local cache
187         for (String tZ : tZones.keySet()) {
188             boolean isGreType = isGreTunnelType(tZ, tZoneMap);
189             Map<SubnetObject, List<Vteps>> subVtepMapTemp = (Map<SubnetObject, List<Vteps>>) tZones.get(tZ);
190             for (SubnetObject subOb : subVtepMapTemp.keySet()) {
191                 List<Vteps> vtepList = subVtepMapTemp.get(subOb);
192                 validateForDuplicateAndSingleGreTep(inputVtep, isConfiguredTepGreType, isGreType, vtepList);
193             }
194         }
195         // Checking for duplicates in config DS
196         for (TransportZone tZ : tZoneMap.values()) {
197             boolean isGreType = false;
198             if (tZ.getTunnelType().equals(TunnelTypeGre.class)) {
199                 isGreType = true;
200             }
201             for (Subnets sub : ItmUtils.emptyIfNull(tZ.getSubnets())) {
202                 List<Vteps> vtepList = sub.getVteps();
203                 validateForDuplicateAndSingleGreTep(inputVtep, isConfiguredTepGreType, isGreType, vtepList);
204             }
205         }
206     }
207
208     private void validateForDuplicateAndSingleGreTep(Vteps inputVtep, boolean isConfiguredTepGreType, boolean isGreType,
209             List<Vteps> vtepList) {
210         if (ItmUtils.isEmpty(vtepList)) {
211             return;
212         }
213         if (vtepList.contains(inputVtep)) {
214             Preconditions.checkArgument(false, "VTEP already exists");
215         }
216         BigInteger dpnId = inputVtep.getDpnId();
217         if (isConfiguredTepGreType && isGreType) {
218             for (Vteps vtep : vtepList) {
219                 if (vtep.getDpnId().equals(dpnId)) {
220                     String errMsg = new StringBuilder("DPN [").append(dpnId)
221                             .append("] already configured with GRE TEP. Mutiple GRE TEP's on a single DPN are not allowed.")
222                             .toString();
223                     Preconditions.checkArgument(false, errMsg);
224                 }
225             }
226         }
227     }
228
229     /**
230      * Gets all transport zones as map.
231      *
232      * @return all transport zones as map
233      */
234     private Map<String, TransportZone> getAllTransportZonesAsMap() {
235         TransportZones tZones = getAllTransportZones();
236         Map<String, TransportZone> tZoneMap = new HashMap<>();
237         if( null != tZones) {
238            for (TransportZone tzone : ItmUtils.emptyIfNull(tZones.getTransportZone())) {
239              tZoneMap.put(tzone.getZoneName(), tzone);
240            }
241         }
242         return tZoneMap;
243     }
244
245     /**
246      * Checks if is gre tunnel type.
247      *
248      * @param tZoneName
249      *            the zone name
250      * @param tZoneMap
251      *            the zone map
252      * @return true, if is gre tunnel type
253      */
254     private boolean isGreTunnelType(String tZoneName, Map<String, TransportZone> tZoneMap) {
255         TransportZone tzone = tZoneMap.get(tZoneName);
256         /*
257         if (tzone != null && StringUtils.equalsIgnoreCase(ITMConstants.TUNNEL_TYPE_GRE, tzone.getTunnelType())) {
258             return true;
259         }
260         */
261         if( (tzone != null) && (tzone.getTunnelType()).equals(TunnelTypeGre.class) ) {
262            return true;
263         }
264         return false;
265     }
266
267     /**
268      * Gets the transport zone.
269      *
270      * @param tzone
271      *            the tzone
272      * @return the transport zone
273      */
274     public TransportZone getTransportZone(String tzone) {
275         InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class)
276                 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
277         Optional<TransportZone> tZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath,
278                 dataBroker);
279         if (tZoneOptional.isPresent()) {
280             return tZoneOptional.get();
281         }
282         return null;
283     }
284
285     /**
286      * Gets the transport zone from config ds.
287      *
288      * @param tzone
289      *            the tzone
290      * @return the transport zone
291      */
292     public TransportZone getTransportZoneFromConfigDS(String tzone) {
293         InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class)
294                 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
295         Optional<TransportZone> tZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath,
296                 dataBroker);
297         if (tZoneOptional.isPresent()) {
298             return tZoneOptional.get();
299         }
300         return null;
301     }
302
303     /**
304      * Gets all transport zones.
305      *
306      * @return all transport zones
307      */
308     public TransportZones getAllTransportZones() {
309         InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
310         Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
311         if (tZonesOptional.isPresent()) {
312             return tZonesOptional.get();
313         }
314         return null;
315     }
316
317     public boolean checkExistingSubnet(Map<SubnetObject, List<Vteps>> subVtepMapTemp, SubnetObject subObCli) {
318         for (SubnetObject subOb : subVtepMapTemp.keySet()) {
319             if (subOb.get_key().equals(subObCli.get_key())) {
320                 if (!(subOb.get_vlanId().equals(subObCli.get_vlanId())))
321                     return true;
322                 if (!(subOb.get_gatewayIp().equals(subObCli.get_gatewayIp())))
323                     return true;
324             }
325         }
326         return false;
327     }
328
329     public boolean checkTepPerTzPerDpn(String tzone, BigInteger dpnId) {
330         // check in local cache
331         if (tZones.containsKey(tzone)) {
332             Map<SubnetObject, List<Vteps>> subVtepMapTemp = (Map<SubnetObject, List<Vteps>>) tZones.get(tzone);
333             for (SubnetObject subOb : subVtepMapTemp.keySet()) {
334                 List<Vteps> vtepList = subVtepMapTemp.get(subOb);
335                 for (Vteps vtep : vtepList)
336                     if (vtep.getDpnId().equals(dpnId))
337                         return true;
338             }
339         }
340
341         // check in DS
342         InstanceIdentifier<TransportZone> tzonePath =
343                         InstanceIdentifier.builder(TransportZones.class)
344                                         .child(TransportZone.class, new TransportZoneKey(tzone)).build();
345         Optional<TransportZone> tZoneOptional =
346                         ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath, dataBroker);
347         if (tZoneOptional.isPresent()) {
348             TransportZone tz = tZoneOptional.get();
349             if (tz.getSubnets() == null || tz.getSubnets().isEmpty())
350                 return false;
351             for (Subnets sub : tz.getSubnets()) {
352                 if (sub.getVteps() == null || sub.getVteps().isEmpty())
353                     continue;
354                 for (Vteps vtep : sub.getVteps()) {
355                     if (vtep.getDpnId().equals(dpnId)) {
356                         return true;
357                     }
358                 }
359             }
360         }
361         return false;
362     }
363
364     public void buildTeps() {
365         TransportZones tZonesBuilt = null;
366         TransportZone tZone = null;
367         try {
368             LOG.debug("no of teps added" + check);
369             if (tZones != null || !tZones.isEmpty()) {
370                 tZoneList = new ArrayList<TransportZone>();
371                 for (String tZ : tZones.keySet()) {
372                     LOG.debug("tZones" + tZ);
373                     subnetList = new ArrayList<Subnets>();
374                     Map<SubnetObject, List<Vteps>> subVtepMapTemp = (Map<SubnetObject, List<Vteps>>) tZones.get(tZ);
375                     for (SubnetObject subOb : subVtepMapTemp.keySet()) {
376                         LOG.debug("subnets" + subOb.get_prefix());
377                         List<Vteps> vtepList = subVtepMapTemp.get(subOb);
378                         Subnets subnet =
379                                         new SubnetsBuilder().setGatewayIp(subOb.get_gatewayIp())
380                                                         .setKey(subOb.get_key()).setPrefix(subOb.get_prefix())
381                                                         .setVlanId(subOb.get_vlanId()).setVteps(vtepList).build();
382                         subnetList.add(subnet);
383                         LOG.debug("vteps" + vtepList);
384                     }
385                     InstanceIdentifier<TransportZone> tZonepath =
386                                     InstanceIdentifier.builder(TransportZones.class)
387                                                     .child(TransportZone.class, new TransportZoneKey(tZ)).build();
388                     Optional<TransportZone> tZoneOptional =
389                                     ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tZonepath, dataBroker);
390                     LOG.debug("read container from DS");
391                     if (tZoneOptional.isPresent()) {
392                         TransportZone tzoneFromDs = tZoneOptional.get();
393                         LOG.debug("read tzone container" + tzoneFromDs.toString());
394                         if (tzoneFromDs.getTunnelType() == null
395                                         || (tzoneFromDs.getTunnelType()).equals(TunnelTypeVxlan.class)) {
396                             tZone =
397                                             new TransportZoneBuilder().setKey(new TransportZoneKey(tZ))
398                                                             .setTunnelType(TunnelTypeVxlan.class).setSubnets(subnetList)
399                                                             .setZoneName(tZ).build();
400                         } else if ((tzoneFromDs.getTunnelType()).equals(TunnelTypeGre.class)) {
401                             tZone =
402                                             new TransportZoneBuilder().setKey(new TransportZoneKey(tZ))
403                                                             .setTunnelType(TunnelTypeGre.class).setSubnets(subnetList)
404                                                             .setZoneName(tZ).build();
405                         }
406                     } else {
407                         tZone =
408                                         new TransportZoneBuilder().setKey(new TransportZoneKey(tZ))
409                                                         .setTunnelType(TunnelTypeVxlan.class).setSubnets(subnetList).setZoneName(tZ)
410                                                         .build();
411                     }
412                     LOG.debug("tzone object" + tZone);
413                     tZoneList.add(tZone);
414                 }
415                 tZonesBuilt = new TransportZonesBuilder().setTransportZone(tZoneList).build();
416                 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
417                 LOG.debug("InstanceIdentifier" + path);
418                 ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, path, tZonesBuilt, dataBroker,
419                                 ItmUtils.DEFAULT_CALLBACK);
420                 LOG.debug("wrote to Config DS" + tZonesBuilt);
421                 tZones.clear();
422                 tZoneList.clear();
423                 subnetList.clear();
424                 LOG.debug("Everything cleared");
425             } else {
426                 LOG.debug("NO vteps were configured");
427             }
428         } catch (Exception e) {
429             e.printStackTrace();
430         }
431     }
432
433     public void showTeps(boolean monitorEnabled, int monitorInterval) {
434         boolean flag = false;
435         InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
436         Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
437         if (tZonesOptional.isPresent()) {
438             TransportZones tZones = tZonesOptional.get();
439             if(tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty())
440             {
441                 System.out.println("No teps configured");
442                 return;
443             }
444             List<String> result = new ArrayList<String>();
445             result.add(String.format("Tunnel Monitoring (for VXLAN tunnels): %s", (monitorEnabled ? "On" : "Off")));
446             result.add(String.format("Tunnel Monitoring Interval (for VXLAN tunnels): %d", monitorInterval));
447             result.add(System.lineSeparator());
448             result.add(String.format("%-16s  %-16s  %-16s  %-12s  %-12s %-12s %-16s %-12s", "TransportZone", "TunnelType", "SubnetMask",
449                             "GatewayIP", "VlanID", "DpnID", "IPAddress", "PortName"));
450             result.add("------------------------------------------------------------------------------------------------------------------------------");
451             for (TransportZone tZ : tZones.getTransportZone()) {
452                 if (tZ.getSubnets() == null || tZ.getSubnets().isEmpty()) {
453                     LOG.error("Transport Zone " + tZ.getZoneName() + "has no subnets");
454                     continue;
455                 }
456                 for (Subnets sub : tZ.getSubnets()) {
457                     if (sub.getVteps() == null || sub.getVteps().isEmpty()) {
458                         LOG.error("Transport Zone " + tZ.getZoneName() + "subnet " + sub.getPrefix() + "has no vteps");
459                         continue;
460                     }
461                     for (Vteps vtep : sub.getVteps()) {
462                         flag = true;
463                         String strTunnelType ;
464                         if( (tZ.getTunnelType()).equals(TunnelTypeGre.class) )
465                           strTunnelType = ITMConstants.TUNNEL_TYPE_GRE ;
466                         else
467                           strTunnelType = ITMConstants.TUNNEL_TYPE_VXLAN ;
468                         result.add(String.format("%-16s  %-16s  %-16s  %-12s  %-12s %-12s %-16s %-12s", tZ.getZoneName(), strTunnelType, sub
469                                         .getPrefix().getIpv4Prefix().getValue(), sub.getGatewayIp().getIpv4Address()
470                                         .getValue(), sub.getVlanId().toString(), vtep.getDpnId().toString(), vtep
471                                         .getIpAddress().getIpv4Address().getValue(), vtep.getPortname().toString()));
472                     }
473                 }
474             }
475             if (flag == true) {
476                 for (String p : result) {
477                     System.out.println(p);
478                 }
479             } else
480                 System.out.println("No teps to display");
481         } else
482             System.out.println("No teps configured");
483     }
484
485
486     public void deleteVtep(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask,
487                     String gatewayIp, String transportZone) {
488
489         IpAddress ipAddressObj = null;
490         IpAddress gatewayIpObj = null;
491         IpPrefix subnetMaskObj = null;
492         VtepsKey vtepkey = new VtepsKey(dpnId, portName);
493         try {
494             ipAddressObj = new IpAddress(ipAddress.toCharArray());
495             gatewayIpObj = new IpAddress("0.0.0.0".toCharArray());
496             if (gatewayIp != null) {
497                 gatewayIpObj = new IpAddress(gatewayIp.toCharArray());
498             } else {
499                 LOG.debug("gateway is null");
500             }
501         } catch (Exception e) {
502             System.out.println("Invalid IpAddress. Expected: 1.0.0.0 to 254.255.255.255");
503             return;
504         }
505         try {
506             subnetMaskObj = new IpPrefix(subnetMask.toCharArray());
507         } catch (Exception e) {
508             System.out.println("Invalid Subnet Mask. Expected: 0.0.0.0/0 to 255.255.255.255/32");
509             return;
510         }
511
512         if (!validateIPs(ipAddress, subnetMask, gatewayIp)) {
513             System.out.println("IpAddress and gateWayIp should belong to the subnet provided");
514             return;
515         }
516         SubnetsKey subnetsKey = new SubnetsKey(subnetMaskObj);
517         Vteps vtepCli = null;
518         Subnets subCli = null;
519
520         InstanceIdentifier<Vteps> vpath =
521                         InstanceIdentifier.builder(TransportZones.class)
522                                         .child(TransportZone.class, new TransportZoneKey(transportZone))
523                                         .child(Subnets.class, subnetsKey).child(Vteps.class, vtepkey).build();
524  
525         // check if present in tzones and delete from cache
526         boolean existsInCache = isInCache(dpnId, portName, vlanId, ipAddress, subnetMask, gatewayIp, transportZone);
527         if (!existsInCache) {
528             Optional<Vteps> vtepOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, vpath, dataBroker);
529             if (vtepOptional.isPresent()) {
530                 vtepCli = vtepOptional.get();
531                 if(vtepCli.getIpAddress().equals(ipAddressObj)){
532                     InstanceIdentifier<Subnets> spath =
533                                     InstanceIdentifier
534                                                     .builder(TransportZones.class)
535                                                     .child(TransportZone.class, new TransportZoneKey(transportZone))
536                                                     .child(Subnets.class, subnetsKey).build();
537                     Optional<Subnets> subOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, spath, dataBroker);
538                     if (subOptional.isPresent()) {
539                         subCli = subOptional.get();
540                         if(subCli.getGatewayIp().equals(gatewayIpObj) && subCli.getVlanId().equals(vlanId)){
541                     vtepDelCommitList.add(vtepCli);
542                       }
543                         else
544                             System.out.println(String.format("vtep with this vlan or gateway doesnt exist"));
545                         }
546                 }
547                 else 
548                     System.out.println(String.format("Vtep with this ipaddress doesnt exist"));
549                 } else {
550                 System.out.println(String.format("Vtep Doesnt exist"));
551             }
552         }
553     }
554
555     public <T extends DataObject> void deleteOnCommit() {
556         List<InstanceIdentifier<T>> vtepPaths = new ArrayList<>();
557         List<InstanceIdentifier<T>> subnetPaths = new ArrayList<>();
558         List<InstanceIdentifier<T>> tzPaths = new ArrayList<>();
559         List<Subnets> subDelList = new ArrayList<Subnets>();
560         List<TransportZone> tzDelList = new ArrayList<TransportZone>();
561         List<Vteps> vtepDelList = new ArrayList<Vteps>();
562         List<InstanceIdentifier<T>> allPaths = new ArrayList<>();
563         try {
564             if (vtepDelCommitList != null && !vtepDelCommitList.isEmpty()) {
565                 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
566                 Optional<TransportZones> tZonesOptional =
567                                 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
568                 if (tZonesOptional.isPresent()) {
569                     TransportZones tZones = tZonesOptional.get();
570                     for (TransportZone tZ : tZones.getTransportZone()) {
571                         if (tZ.getSubnets() == null || tZ.getSubnets().isEmpty())
572                             continue;
573                         for (Subnets sub : tZ.getSubnets()) {
574                             vtepDelList.addAll(vtepDelCommitList);
575                             for (Vteps vtep : vtepDelList) {
576                                 InstanceIdentifier<T> vpath =
577                                                 (InstanceIdentifier<T>) InstanceIdentifier
578                                                                 .builder(TransportZones.class)
579                                                                 .child(TransportZone.class, tZ.getKey())
580                                                                 .child(Subnets.class, sub.getKey())
581                                                                 .child(Vteps.class, vtep.getKey()).build();
582                                 if (sub.getVteps().remove(vtep)) {
583                                     vtepPaths.add(vpath);
584                                     if (sub.getVteps().size() == 0 || sub.getVteps() == null) {
585                                         subDelList.add(sub);
586                                     }
587
588                                 }
589                             }
590                         }
591                     }
592
593                     for (TransportZone tZ : tZones.getTransportZone()) {
594                         if (tZ.getSubnets() == null || tZ.getSubnets().isEmpty())
595                             continue;
596                         for (Subnets sub : subDelList) {
597                             if (tZ.getSubnets().remove(sub)) {
598                                 InstanceIdentifier<T> spath =
599                                                 (InstanceIdentifier<T>) InstanceIdentifier
600                                                                 .builder(TransportZones.class)
601                                                                 .child(TransportZone.class, tZ.getKey())
602                                                                 .child(Subnets.class, sub.getKey()).build();
603                                 subnetPaths.add(spath);
604                                 if (tZ.getSubnets() == null || tZ.getSubnets().size() == 0) {
605                                     tzDelList.add(tZ);
606                                 }
607                             }
608                         }
609                     }
610
611                     for (TransportZone tZ : tzDelList) {
612                         if (tZones.getTransportZone().remove(tZ)) {
613                             InstanceIdentifier<T> tpath =
614                                             (InstanceIdentifier<T>) InstanceIdentifier.builder(TransportZones.class)
615                                                             .child(TransportZone.class, tZ.getKey()).build();
616                             tzPaths.add(tpath);
617                             if (tZones.getTransportZone() == null || tZones.getTransportZone().size() == 0) {
618                                 MDSALDataStoreUtils.asyncRemove(dataBroker, LogicalDatastoreType.CONFIGURATION, path,
619                                                 ItmUtils.DEFAULT_CALLBACK);
620                                 return;
621                             }
622                         }
623                     }
624                     allPaths.addAll(vtepPaths);
625                     allPaths.addAll(subnetPaths);
626                     allPaths.addAll(tzPaths);
627                     ItmUtils.asyncBulkRemove(dataBroker, LogicalDatastoreType.CONFIGURATION, allPaths,
628                                     ItmUtils.DEFAULT_CALLBACK);
629                 }
630                 vtepPaths.clear();
631                 subnetPaths.clear();
632                 tzPaths.clear();
633                 allPaths.clear();
634                 vtepDelCommitList.clear();
635             }
636         } catch (Exception e) {
637             e.printStackTrace();
638         }
639     }
640
641     public void showState(TunnelList tunnels, boolean tunnelMonitorEnabled) {
642         IfTunnel tunnelInterface = null;
643         IfL2vlan l2Vlan = null;
644         List<InternalTunnel> tunnelLists = tunnels.getInternalTunnel();
645         if (tunnelLists == null || tunnelLists.isEmpty()) {
646             System.out.println("No Internal Tunnels Exist");
647             return;
648         }
649         if (!tunnelMonitorEnabled) {
650             System.out.println("Tunnel Monitoring is Off");
651         }
652         String displayFormat = "%-16s  %-16s  %-16s  %-16s  %-16s  %-8s  %-10s  %-10s";
653         System.out.println(String.format(displayFormat, "Tunnel Name", "Source-DPN",
654                         "Destination-DPN", "Source-IP", "Destination-IP", "Vlan Id", "Trunk-State", "Transport Type"));
655         System.out.println("-------------------------------------------------------------------------------------------------------------------------------------");
656
657         for (InternalTunnel tunnel : tunnelLists) {
658             String tunnelInterfaceName = tunnel.getTunnelInterfaceName();
659             LOG.trace("tunnelInterfaceName::: {}", tunnelInterfaceName);
660             
661             InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
662                     ItmUtils.buildStateInterfaceId(tunnelInterfaceName);
663             Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateOptional =
664                   ItmUtils.read(LogicalDatastoreType.OPERATIONAL, ifStateId, dataBroker);
665             String tunnelState = "DOWN" ;
666             if (ifStateOptional.isPresent()) {
667                 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface iface = ifStateOptional.get() ;
668                 if(iface.getAdminStatus() == AdminStatus.Up && iface.getOperStatus() == OperStatus.Up)
669                 tunnelState = "UP" ;
670             }
671                 InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(tunnelInterfaceName);
672                 Optional<Interface> ifaceObj = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, trunkIdentifier, dataBroker) ;
673                 if (ifaceObj.isPresent()) {
674                     l2Vlan = (IfL2vlan) ifaceObj.get().getAugmentation(IfL2vlan.class);
675                     tunnelInterface = (IfTunnel) ifaceObj.get().getAugmentation(IfTunnel.class);
676                 }
677
678                 Class<? extends TunnelTypeBase> tunType = tunnelInterface.getTunnelInterfaceType();
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                 int vlanId = 0;
685                 if( l2Vlan != null ) {
686                    vlanId = l2Vlan.getVlanId().getValue() ;
687                 }
688                 System.out.println(String.format(displayFormat, tunnel.getTunnelInterfaceName(), tunnel
689                                 .getSourceDPN().toString(), tunnel.getDestinationDPN().toString(), tunnelInterface.getTunnelSource().getIpv4Address().getValue(), tunnelInterface.getTunnelDestination().getIpv4Address().getValue(),vlanId, tunnelState ,
690                                 tunnelType));
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) {
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 = (Map<SubnetObject, List<Vteps>>) tZones.get(transportZone);
715             if (subVtepMapTemp.containsKey(subObCli)) { // if Subnet exists
716                 List<Vteps> vtepListTemp = (List<Vteps>) 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 {
727                     System.out.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<TransportZone>();
761             }
762         } else {
763             tZoneList = new ArrayList<TransportZone>();
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 = new StringBuilder("Changing the tunnel type from ").append(tZoneFromConfigDS.getTunnelType())
806                        .append(" to ").append(strTunnelType)
807                        .append(" is not allowed for already configured transport zone [").append(tZoneName)
808                        .append("].").toString();
809                Preconditions.checkArgument(false, errorMsg);
810            }
811         }
812     }
813
814     public void configureTunnelMonitorEnabled(boolean monitorEnabled) {
815         InstanceIdentifier<TunnelMonitorEnabled> path = InstanceIdentifier.builder(TunnelMonitorEnabled.class).build();
816         Optional<TunnelMonitorEnabled> storedTunnelMonitor = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
817         if (!storedTunnelMonitor.isPresent() || storedTunnelMonitor.get().isEnabled() != monitorEnabled) {
818             TunnelMonitorEnabled tunnelMonitor = new TunnelMonitorEnabledBuilder().setEnabled(monitorEnabled).build();
819             ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, path, tunnelMonitor, dataBroker,
820                                             ItmUtils.DEFAULT_CALLBACK);
821         }
822     }
823
824     public void configureTunnelMonitorInterval(int interval) {
825         InstanceIdentifier<TunnelMonitorInterval> path = InstanceIdentifier.builder(TunnelMonitorInterval.class).build();
826         Optional<TunnelMonitorInterval> storedTunnelMonitor = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
827         if (!storedTunnelMonitor.isPresent() || storedTunnelMonitor.get().getInterval() != interval) {
828             TunnelMonitorInterval tunnelMonitor = new TunnelMonitorIntervalBuilder().setInterval(interval).build();
829             ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, path, tunnelMonitor, dataBroker,
830                                             ItmUtils.DEFAULT_CALLBACK);
831         }
832     }
833 }