bb40d91577ca9b49b4fbe7d7e4dc71f4af048006
[genius.git] / itm / itm-impl / src / main / java / org / opendaylight / genius / itm / impl / ItmUtils.java
1 /*
2  * Copyright © 2016, 2017 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.genius.itm.impl;
9
10 import com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
12 import com.google.common.collect.ImmutableMap;
13 import com.google.common.net.InetAddresses;
14 import com.google.common.util.concurrent.CheckedFuture;
15 import com.google.common.util.concurrent.FutureCallback;
16 import com.google.common.util.concurrent.Futures;
17 import java.math.BigInteger;
18 import java.net.InetAddress;
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.List;
23 import java.util.UUID;
24 import java.util.concurrent.ExecutionException;
25 import java.util.concurrent.Future;
26 import org.apache.commons.lang3.StringUtils;
27 import org.apache.commons.net.util.SubnetUtils;
28 import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
29 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
30 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
31 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
32 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
33 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
34 import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
35 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
36 import org.opendaylight.genius.itm.api.IITMProvider;
37 import org.opendaylight.genius.itm.confighelpers.HwVtep;
38 import org.opendaylight.genius.itm.globals.ITMConstants;
39 import org.opendaylight.genius.mdsalutil.ActionInfo;
40 import org.opendaylight.genius.mdsalutil.FlowEntity;
41 import org.opendaylight.genius.mdsalutil.InstructionInfo;
42 import org.opendaylight.genius.mdsalutil.MDSALUtil;
43 import org.opendaylight.genius.mdsalutil.MatchInfo;
44 import org.opendaylight.genius.mdsalutil.NwConstants;
45 import org.opendaylight.genius.mdsalutil.actions.ActionPuntToController;
46 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
47 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
48 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
49 import org.opendaylight.genius.utils.cache.DataStoreCache;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnelBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBase;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBfd;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifier;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifierBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifierKey;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorInterval;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorIntervalBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorParams;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorParamsBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.VtepConfigSchemas;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.VtepIpPools;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchema;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchemaBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchemaKey;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.vtep.config.schema.DpnIds;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.vtep.config.schema.DpnIdsBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.vtep.config.schema.DpnIdsKey;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.ip.pools.VtepIpPool;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.ip.pools.VtepIpPoolKey;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpointsBuilder;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.ExternalTunnelList;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeBase;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeExternal;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeHwvtep;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeInternal;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelList;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelsState;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPointsBuilder;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPointsKey;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembership;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembershipBuilder;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelBuilder;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelKey;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelBuilder;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelKey;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListBuilder;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListKey;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.state.tunnel.list.DstInfoBuilder;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.state.tunnel.list.SrcInfoBuilder;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.DcGatewayIpList;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIp;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TepsNotHostedInTransportZone;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TepsNotHostedInTransportZoneKey;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Subnets;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.Vteps;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
134 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
135 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
136 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
137 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
138 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
139 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
140 import org.opendaylight.yangtools.yang.binding.DataObject;
141 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
142 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
143 import org.opendaylight.yangtools.yang.common.RpcResult;
144 import org.slf4j.Logger;
145 import org.slf4j.LoggerFactory;
146
147 public class ItmUtils {
148
149     public static final String DUMMY_IP_ADDRESS = "0.0.0.0";
150     public static final String TUNNEL_TYPE_VXLAN = "VXLAN";
151     public static final String TUNNEL_TYPE_GRE = "GRE";
152     public static final String TUNNEL = "tun";
153     public static final IpPrefix DUMMY_IP_PREFIX = new IpPrefix(ITMConstants.DUMMY_PREFIX.toCharArray());
154     public static ItmCache itmCache = new ItmCache();
155
156     private static final Logger LOG = LoggerFactory.getLogger(ItmUtils.class);
157
158     public static final ImmutableMap<String, Class<? extends TunnelTypeBase>>
159         TUNNEL_TYPE_MAP =
160         new ImmutableMap.Builder<String, Class<? extends TunnelTypeBase>>()
161             .put(ITMConstants.TUNNEL_TYPE_GRE, TunnelTypeGre.class)
162             .put(ITMConstants.TUNNEL_TYPE_MPLSoGRE, TunnelTypeMplsOverGre.class)
163             .put(ITMConstants.TUNNEL_TYPE_VXLAN, TunnelTypeVxlan.class)
164             .build();
165
166     public static final FutureCallback<Void> DEFAULT_CALLBACK = new FutureCallback<Void>() {
167         @Override
168         public void onSuccess(Void result) {
169             LOG.debug("Success in Datastore write operation");
170         }
171
172         @Override
173         public void onFailure(Throwable error) {
174             LOG.error("Error in Datastore write operation", error);
175         }
176     };
177
178     @SuppressWarnings("checkstyle:IllegalCatch")
179     public static <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
180                                                           InstanceIdentifier<T> path, DataBroker broker) {
181         try (ReadOnlyTransaction tx = broker.newReadOnlyTransaction()) {
182             return tx.read(datastoreType, path).get();
183         } catch (Exception e) {
184             throw new RuntimeException(e);
185         }
186     }
187
188     public static <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
189                                                          InstanceIdentifier<T> path, T data, DataBroker broker,
190                                                          FutureCallback<Void> callback) {
191         WriteTransaction tx = broker.newWriteOnlyTransaction();
192         tx.put(datastoreType, path, data, true);
193         Futures.addCallback(tx.submit(), callback);
194     }
195
196     public static <T extends DataObject> void asyncUpdate(LogicalDatastoreType datastoreType,
197                                                           InstanceIdentifier<T> path, T data, DataBroker broker,
198                                                           FutureCallback<Void> callback) {
199         WriteTransaction tx = broker.newWriteOnlyTransaction();
200         tx.merge(datastoreType, path, data, true);
201         Futures.addCallback(tx.submit(), callback);
202     }
203
204     public static <T extends DataObject> void asyncDelete(LogicalDatastoreType datastoreType,
205                                                           InstanceIdentifier<T> path, DataBroker broker,
206                                                           FutureCallback<Void> callback) {
207         WriteTransaction tx = broker.newWriteOnlyTransaction();
208         tx.delete(datastoreType, path);
209         Futures.addCallback(tx.submit(), callback);
210     }
211
212     public static <T extends DataObject> void asyncBulkRemove(final DataBroker broker,
213                                                               final LogicalDatastoreType datastoreType,
214                                                               List<InstanceIdentifier<T>> pathList,
215                                                               FutureCallback<Void> callback) {
216         if (!pathList.isEmpty()) {
217             WriteTransaction tx = broker.newWriteOnlyTransaction();
218             for (InstanceIdentifier<T> path : pathList) {
219                 tx.delete(datastoreType, path);
220             }
221             Futures.addCallback(tx.submit(), callback);
222         }
223     }
224
225     public static String getInterfaceName(final BigInteger datapathid, final String portName, final Integer vlanId) {
226         return String.format("%s:%s:%s", datapathid, portName, vlanId);
227     }
228
229     public static BigInteger getDpnIdFromInterfaceName(String interfaceName) {
230         String[] dpnStr = interfaceName.split(":");
231         BigInteger dpnId = new BigInteger(dpnStr[0]);
232         return dpnId;
233     }
234
235     public static String getTrunkInterfaceName(IdManagerService idManager, String parentInterfaceName,
236                                                String localHostName, String remoteHostName, String tunnelType) {
237         String tunnelTypeStr;
238         if (tunnelType.contains("TunnelTypeGre")) {
239             tunnelTypeStr = ITMConstants.TUNNEL_TYPE_GRE;
240         } else {
241             tunnelTypeStr = ITMConstants.TUNNEL_TYPE_VXLAN;
242         }
243         String trunkInterfaceName = String.format("%s:%s:%s:%s", parentInterfaceName, localHostName,
244                 remoteHostName, tunnelTypeStr);
245         LOG.trace("trunk interface name is {}", trunkInterfaceName);
246         trunkInterfaceName = String.format("%s%s", TUNNEL, getUniqueIdString(trunkInterfaceName));
247         return trunkInterfaceName;
248     }
249
250     public static void releaseIdForTrunkInterfaceName(IdManagerService idManager, String parentInterfaceName,
251                                                       String localHostName, String remoteHostName, String tunnelType) {
252         String tunnelTypeStr;
253         if (tunnelType.contains("TunnelTypeGre")) {
254             tunnelTypeStr = ITMConstants.TUNNEL_TYPE_GRE;
255         } else {
256             tunnelTypeStr = ITMConstants.TUNNEL_TYPE_VXLAN;
257         }
258         String trunkInterfaceName = String.format("%s:%s:%s:%s", parentInterfaceName, localHostName,
259                 remoteHostName, tunnelTypeStr);
260         LOG.trace("Releasing Id for trunkInterface - {}", trunkInterfaceName);
261         //releaseId(idManager, trunkInterfaceName) ;
262     }
263
264     public static InetAddress getInetAddressFromIpAddress(IpAddress ip) {
265         return InetAddresses.forString(ip.getIpv4Address().getValue());
266     }
267
268     public static InstanceIdentifier<DPNTEPsInfo> getDpnTepInstance(BigInteger dpIdKey) {
269         InstanceIdentifier.InstanceIdentifierBuilder<DPNTEPsInfo> dpnTepInfoBuilder =
270                 InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class,
271                         new DPNTEPsInfoKey(dpIdKey));
272         InstanceIdentifier<DPNTEPsInfo> dpnInfo = dpnTepInfoBuilder.build();
273         return dpnInfo;
274     }
275
276     public static DPNTEPsInfo createDPNTepInfo(BigInteger dpId, List<TunnelEndPoints> endpoints) {
277         return new DPNTEPsInfoBuilder().setKey(new DPNTEPsInfoKey(dpId)).setTunnelEndPoints(endpoints).build();
278     }
279
280     public static TunnelEndPoints createTunnelEndPoints(BigInteger dpnId, IpAddress ipAddress, String portName,
281                                                         boolean isOfTunnel, int vlanId, IpPrefix prefix,
282                                                         IpAddress gwAddress, List<TzMembership> zones,
283                                                         Class<? extends TunnelTypeBase>  tunnelType) {
284         // when Interface Mgr provides support to take in Dpn Id
285         return new TunnelEndPointsBuilder().setKey(new TunnelEndPointsKey(ipAddress, portName,tunnelType, vlanId))
286                 .setSubnetMask(prefix).setGwIpAddress(gwAddress).setTzMembership(zones)
287                 .setOptionOfTunnel(isOfTunnel).setInterfaceName(ItmUtils.getInterfaceName(dpnId, portName, vlanId))
288                 .setTunnelType(tunnelType).build();
289     }
290
291     public static DpnEndpoints createDpnEndpoints(List<DPNTEPsInfo> dpnTepInfo) {
292         return new DpnEndpointsBuilder().setDPNTEPsInfo(dpnTepInfo).build();
293     }
294
295     public static InstanceIdentifier<Interface> buildId(String interfaceName) {
296         InstanceIdentifierBuilder<Interface> idBuilder =
297                 InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName));
298         InstanceIdentifier<Interface> id = idBuilder.build();
299         return id;
300     }
301
302     public static Interface buildTunnelInterface(BigInteger dpn, String ifName, String desc, boolean enabled,
303                                                  Class<? extends TunnelTypeBase> tunType, IpAddress localIp,
304                                                  IpAddress remoteIp, IpAddress gatewayIp, Integer vlanId,
305                                                  boolean internal, Boolean monitorEnabled,
306                                                  Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
307                                                  Integer monitorInterval, boolean useOfTunnel) {
308         InterfaceBuilder builder = new InterfaceBuilder().setKey(new InterfaceKey(ifName)).setName(ifName)
309                 .setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
310         ParentRefs parentRefs = new ParentRefsBuilder().setDatapathNodeIdentifier(dpn).build();
311         builder.addAugmentation(ParentRefs.class, parentRefs);
312         Long monitoringInterval = null;
313         if (vlanId > 0) {
314             IfL2vlan l2vlan = new IfL2vlanBuilder().setVlanId(new VlanId(vlanId)).build();
315             builder.addAugmentation(IfL2vlan.class, l2vlan);
316         }
317         LOG.debug("buildTunnelInterface: monitorProtocol = {} and monitorInterval = {}",
318                 monitorProtocol.getName(),monitorInterval);
319
320         if (monitorInterval != null) {
321             monitoringInterval = monitorInterval.longValue();
322         }
323
324         IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(remoteIp).setTunnelGateway(gatewayIp)
325                 .setTunnelSource(localIp).setTunnelInterfaceType(tunType).setInternal(internal)
326                 .setMonitorEnabled(monitorEnabled).setMonitorProtocol(monitorProtocol)
327                 .setMonitorInterval(monitoringInterval).setTunnelRemoteIpFlow(useOfTunnel)
328                 .build();
329         builder.addAugmentation(IfTunnel.class, tunnel);
330         return builder.build();
331     }
332
333     public static Interface buildHwTunnelInterface(String tunnelIfName, String desc, boolean enabled, String topoId,
334                                                    String nodeId, Class<? extends TunnelTypeBase> tunType,
335                                                    IpAddress srcIp, IpAddress destIp, IpAddress gwIp,
336                                                    Boolean monitorEnabled,
337                                                    Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
338                                                    Integer monitorInterval) {
339         InterfaceBuilder builder = new InterfaceBuilder().setKey(new InterfaceKey(tunnelIfName))
340                 .setName(tunnelIfName).setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
341         List<NodeIdentifier> nodeIds = new ArrayList<>();
342         NodeIdentifier hwNode = new NodeIdentifierBuilder().setKey(new NodeIdentifierKey(topoId))
343                 .setTopologyId(topoId).setNodeId(nodeId).build();
344         nodeIds.add(hwNode);
345         ParentRefs parent = new ParentRefsBuilder().setNodeIdentifier(nodeIds).build();
346         builder.addAugmentation(ParentRefs.class, parent);
347         Long monitoringInterval = (long) ITMConstants.DEFAULT_MONITOR_INTERVAL;
348         Boolean monitoringEnabled = true;
349         Class<? extends TunnelMonitoringTypeBase> monitoringProtocol = ITMConstants.DEFAULT_MONITOR_PROTOCOL;
350         if (monitoringInterval != null) {
351             monitoringInterval = monitorInterval.longValue();
352         }
353         if (monitorEnabled != null) {
354             monitoringEnabled = monitorEnabled;
355         }
356         if (monitorProtocol != null) {
357             monitoringProtocol = monitorProtocol;
358         }
359         IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(destIp).setTunnelGateway(gwIp)
360                 .setTunnelSource(srcIp).setMonitorEnabled(monitoringEnabled).setMonitorProtocol(monitorProtocol)
361                 .setMonitorInterval(100L).setTunnelInterfaceType(tunType).setInternal(false).build();
362         builder.addAugmentation(IfTunnel.class, tunnel);
363         LOG.trace("iftunnel {} built from hwvtep {} ", tunnel, nodeId);
364         return builder.build();
365     }
366
367
368     public static InternalTunnel buildInternalTunnel(BigInteger srcDpnId, BigInteger dstDpnId,
369                                                      Class<? extends TunnelTypeBase> tunType,
370                                                      String trunkInterfaceName) {
371         InternalTunnel tnl = new InternalTunnelBuilder().setKey(new InternalTunnelKey(dstDpnId, srcDpnId, tunType))
372                 .setDestinationDPN(dstDpnId)
373                 .setSourceDPN(srcDpnId).setTransportType(tunType)
374                 .setTunnelInterfaceNames(Collections.singletonList(trunkInterfaceName)).build();
375         return tnl ;
376     }
377
378     public static ExternalTunnel buildExternalTunnel(String srcNode, String dstNode,
379                                                      Class<? extends TunnelTypeBase> tunType,
380                                                      String trunkInterfaceName) {
381         ExternalTunnel extTnl = new ExternalTunnelBuilder().setKey(
382                 new ExternalTunnelKey(dstNode, srcNode, tunType))
383                 .setSourceDevice(srcNode).setDestinationDevice(dstNode)
384                 .setTunnelInterfaceName(trunkInterfaceName)
385                 .setTransportType(tunType).build();
386         return extTnl;
387     }
388
389     public static List<DPNTEPsInfo> getTunnelMeshInfo(DataBroker dataBroker) {
390         List<DPNTEPsInfo> dpnTEPs = null ;
391
392         // Read the Mesh Information from Cache if not read from the DS
393         dpnTEPs = getTunnelMeshInfo() ;
394         if (dpnTEPs != null) {
395             return dpnTEPs;
396         }
397
398         // Read the EndPoint Info from the operational database
399         InstanceIdentifierBuilder<DpnEndpoints> depBuilder = InstanceIdentifier.builder(DpnEndpoints.class);
400         InstanceIdentifier<DpnEndpoints> deps = depBuilder.build();
401         Optional<DpnEndpoints> dpnEps = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, deps, dataBroker);
402         if (dpnEps.isPresent()) {
403             DpnEndpoints tn = dpnEps.get();
404             dpnTEPs = tn.getDPNTEPsInfo();
405             LOG.debug("Read from CONFIGURATION datastore - No. of Dpns " , dpnTEPs.size());
406         } else {
407             LOG.debug("No Dpn information in CONFIGURATION datastore ");
408         }
409         return dpnTEPs;
410     }
411
412     // Reading the Mesh Information from Cache
413     public static List<DPNTEPsInfo> getTunnelMeshInfo() {
414         List<DPNTEPsInfo> dpnTepsInfo = null ;
415         List<Object> values = null ;
416
417         values = DataStoreCache.getValues(ITMConstants.DPN_TEPs_Info_CACHE_NAME);
418         if (values != null) {
419             dpnTepsInfo = new ArrayList<>() ;
420             for (Object value : values) {
421                 dpnTepsInfo.add((DPNTEPsInfo)value) ;
422             }
423         }
424         return dpnTepsInfo;
425     }
426
427     public static int getUniqueId(IdManagerService idManager, String idKey) {
428         AllocateIdInput getIdInput = new AllocateIdInputBuilder()
429                 .setPoolName(ITMConstants.ITM_IDPOOL_NAME)
430                 .setIdKey(idKey).build();
431
432         try {
433             Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
434             RpcResult<AllocateIdOutput> rpcResult = result.get();
435             if (rpcResult.isSuccessful()) {
436                 return rpcResult.getResult().getIdValue().intValue();
437             } else {
438                 LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
439             }
440         } catch (InterruptedException | ExecutionException e) {
441             LOG.warn("Exception when getting Unique Id",e);
442         }
443         return 0;
444     }
445
446     public static String getUniqueIdString(String idKey) {
447         return UUID.nameUUIDFromBytes(idKey.getBytes()).toString().substring(0, 12).replace("-", "");
448     }
449
450     public static void releaseId(IdManagerService idManager, String idKey) {
451         ReleaseIdInput idInput =
452                 new ReleaseIdInputBuilder().setPoolName(ITMConstants.ITM_IDPOOL_NAME).setIdKey(idKey).build();
453         try {
454             Future<RpcResult<Void>> result = idManager.releaseId(idInput);
455             RpcResult<Void> rpcResult = result.get();
456             if (!rpcResult.isSuccessful()) {
457                 LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
458             }
459         } catch (InterruptedException | ExecutionException e) {
460             LOG.warn("Exception when getting Unique Id for key {}", idKey, e);
461         }
462     }
463
464     public static List<DPNTEPsInfo> getDpnTepListFromDpnId(DataBroker dataBroker, List<BigInteger> dpnIds) {
465         List<DPNTEPsInfo> meshedDpnList = getTunnelMeshInfo(dataBroker) ;
466         List<DPNTEPsInfo> cfgDpnList = new ArrayList<>();
467         if (null != meshedDpnList) {
468             for (BigInteger dpnId : dpnIds) {
469                 for (DPNTEPsInfo teps : meshedDpnList) {
470                     if (dpnId.equals(teps.getDPNID())) {
471                         cfgDpnList.add(teps);
472                     }
473                 }
474             }
475         }
476         return cfgDpnList;
477     }
478
479     @SuppressWarnings("checkstyle:IllegalCatch")
480     public static void setUpOrRemoveTerminatingServiceTable(BigInteger dpnId, IMdsalApiManager mdsalManager,
481                                                             boolean addFlag) {
482         String logmsg = addFlag ? "Installing" : "Removing";
483         LOG.trace(logmsg + " PUNT to Controller flow in DPN {} ", dpnId);
484         List<ActionInfo> listActionInfo = new ArrayList<>();
485         listActionInfo.add(new ActionPuntToController());
486
487         try {
488             List<MatchInfo> mkMatches = new ArrayList<>();
489
490             mkMatches.add(new MatchTunnelId(BigInteger.valueOf(ITMConstants.LLDP_SERVICE_ID)));
491
492             List<InstructionInfo> mkInstructions = new ArrayList<>();
493             mkInstructions.add(new InstructionApplyActions(listActionInfo));
494
495             FlowEntity terminatingServiceTableFlowEntity = MDSALUtil
496                     .buildFlowEntity(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE,
497                             getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, ITMConstants.LLDP_SERVICE_ID),
498                             5, String.format("%s:%d","ITM Flow Entry ", ITMConstants.LLDP_SERVICE_ID), 0, 0,
499                             ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(ITMConstants.LLDP_SERVICE_ID)),
500                             mkMatches, mkInstructions);
501             if (addFlag) {
502                 mdsalManager.installFlow(terminatingServiceTableFlowEntity);
503             } else {
504                 mdsalManager.removeFlow(terminatingServiceTableFlowEntity);
505             }
506         } catch (Exception e) {
507             LOG.error("Error while setting up Table 36 for {}", dpnId, e);
508         }
509     }
510
511     private static String getFlowRef(long termSvcTable, int svcId) {
512         return String.valueOf(termSvcTable) + svcId;
513     }
514
515     public static InstanceIdentifier<VtepConfigSchema> getVtepConfigSchemaIdentifier(String schemaName) {
516         return InstanceIdentifier.builder(VtepConfigSchemas.class)
517                 .child(VtepConfigSchema.class, new VtepConfigSchemaKey(schemaName)).build();
518     }
519
520     public static InstanceIdentifier<VtepConfigSchema> getVtepConfigSchemaIdentifier() {
521         return InstanceIdentifier.builder(VtepConfigSchemas.class).child(VtepConfigSchema.class).build();
522     }
523
524     public static InstanceIdentifier<VtepConfigSchemas> getVtepConfigSchemasIdentifier() {
525         return InstanceIdentifier.builder(VtepConfigSchemas.class).build();
526     }
527
528     public static InstanceIdentifier<VtepIpPool> getVtepIpPoolIdentifier(String subnetCidr) {
529         return InstanceIdentifier.builder(VtepIpPools.class).child(VtepIpPool.class, new VtepIpPoolKey(subnetCidr))
530                 .build();
531     }
532
533     public static VtepConfigSchema validateForAddVtepConfigSchema(VtepConfigSchema schema,
534                                                                   List<VtepConfigSchema> existingSchemas) {
535         VtepConfigSchema validSchema = validateVtepConfigSchema(schema);
536         for (VtepConfigSchema existingSchema : emptyIfNull(existingSchemas)) {
537             if (!StringUtils.equalsIgnoreCase(schema.getSchemaName(), existingSchema.getSchemaName())
538                     && schema.getSubnet().equals(existingSchema.getSubnet())) {
539                 String subnetCidr = getSubnetCidrAsString(schema.getSubnet());
540                 Preconditions.checkArgument(false, "VTEP schema with subnet [" + subnetCidr
541                         + "] already exists. Multiple VTEP schemas with same subnet is not allowed.");
542             }
543         }
544         if (isNotEmpty(getDpnIdList(validSchema.getDpnIds()))) {
545             String tzone = validSchema.getTransportZoneName();
546             List<BigInteger> lstDpns = getConflictingDpnsAlreadyConfiguredWithTz(validSchema.getSchemaName(), tzone,
547                     getDpnIdList(validSchema.getDpnIds()), existingSchemas);
548             if (!lstDpns.isEmpty()) {
549                 Preconditions.checkArgument(false, "DPN's " + lstDpns + " already configured for transport zone "
550                                 + tzone + ". Only one end point per transport Zone per Dpn is allowed.");
551             }
552             if (schema.getTunnelType().equals(TunnelTypeGre.class)) {
553                 validateForSingleGreTep(validSchema.getSchemaName(), getDpnIdList(validSchema.getDpnIds()),
554                         existingSchemas);
555             }
556         }
557         return validSchema;
558     }
559
560     private static void validateForSingleGreTep(String schemaName, List<BigInteger> lstDpnsForAdd,
561                                                 List<VtepConfigSchema> existingSchemas) {
562         for (VtepConfigSchema existingSchema : emptyIfNull(existingSchemas)) {
563             if (TunnelTypeGre.class.equals(existingSchema.getTunnelType())
564                     && !StringUtils.equalsIgnoreCase(schemaName, existingSchema.getSchemaName())) {
565                 List<BigInteger> lstConflictingDpns = new ArrayList<>(getDpnIdList(existingSchema.getDpnIds()));
566                 lstConflictingDpns.retainAll(emptyIfNull(lstDpnsForAdd));
567                 if (!lstConflictingDpns.isEmpty()) {
568                     String errMsg = "DPN's " + lstConflictingDpns
569                             + " already configured with GRE TEP. Mutiple GRE TEP's on a single DPN are not allowed.";
570                     Preconditions.checkArgument(false, errMsg);
571                 }
572             }
573         }
574     }
575
576     public static VtepConfigSchema validateVtepConfigSchema(VtepConfigSchema schema) {
577         Preconditions.checkNotNull(schema);
578         Preconditions.checkArgument(StringUtils.isNotBlank(schema.getSchemaName()));
579         Preconditions.checkArgument(StringUtils.isNotBlank(schema.getPortName()));
580         Preconditions.checkArgument(schema.getVlanId() >= 0 && schema.getVlanId() < 4095,
581                 "Invalid VLAN ID, range (0-4094)");
582         Preconditions.checkArgument(StringUtils.isNotBlank(schema.getTransportZoneName()));
583         Preconditions.checkNotNull(schema.getSubnet());
584         String subnetCidr = getSubnetCidrAsString(schema.getSubnet());
585         SubnetUtils subnetUtils = new SubnetUtils(subnetCidr);
586         IpAddress gatewayIp = schema.getGatewayIp();
587         if (gatewayIp != null) {
588             String strGatewayIp = String.valueOf(gatewayIp.getValue());
589             if (!strGatewayIp.equals(ITMConstants.DUMMY_IP_ADDRESS) && !subnetUtils.getInfo().isInRange(strGatewayIp)) {
590                 Preconditions.checkArgument(false, "Gateway IP address " + strGatewayIp
591                         + " is not in subnet range " + subnetCidr);
592             }
593         }
594         ItmUtils.getExcludeIpAddresses(schema.getExcludeIpFilter(), subnetUtils.getInfo());
595         return new VtepConfigSchemaBuilder(schema).setTunnelType(schema.getTunnelType()).build();
596     }
597
598     public static String validateTunnelType(String tunnelType) {
599         if (tunnelType == null) {
600             tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
601         } else {
602             tunnelType = StringUtils.upperCase(tunnelType);
603             String error = "Invalid tunnel type. Valid values: "
604                     + ITMConstants.TUNNEL_TYPE_VXLAN + " | " + ITMConstants.TUNNEL_TYPE_GRE;
605             Preconditions.checkArgument(ITMConstants.TUNNEL_TYPE_VXLAN.equals(tunnelType)
606                     || ITMConstants.TUNNEL_TYPE_GRE.equals(tunnelType), error);
607         }
608         return tunnelType;
609     }
610
611     private static List<BigInteger> getConflictingDpnsAlreadyConfiguredWithTz(String schemaName, String tzone,
612                                                                               List<BigInteger> lstDpns,
613                                                                               List<VtepConfigSchema> existingSchemas) {
614         List<BigInteger> lstConflictingDpns = new ArrayList<>();
615         for (VtepConfigSchema schema : emptyIfNull(existingSchemas)) {
616             if (!StringUtils.equalsIgnoreCase(schemaName, schema.getSchemaName())
617                     && StringUtils.equals(schema.getTransportZoneName(), tzone)) {
618                 lstConflictingDpns = new ArrayList<>(getDpnIdList(schema.getDpnIds()));
619                 lstConflictingDpns.retainAll(lstDpns);
620                 if (!lstConflictingDpns.isEmpty()) {
621                     break;
622                 }
623             }
624         }
625         return lstConflictingDpns;
626     }
627
628     public static VtepConfigSchema constructVtepConfigSchema(String schemaName, String portName, Integer vlanId,
629                                                              String subnetMask, String gatewayIp, String transportZone,
630                                                              String tunnelType, List<BigInteger> dpnIds,
631                                                              String excludeIpFilter) {
632         IpAddress gatewayIpObj = StringUtils.isBlank(gatewayIp) ? null : new IpAddress(gatewayIp.toCharArray());
633         IpPrefix subnet = StringUtils.isBlank(subnetMask) ? null : new IpPrefix(subnetMask.toCharArray());
634         Class<? extends TunnelTypeBase> tunType ;
635         if (tunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN)) {
636             tunType = TunnelTypeVxlan.class ;
637         } else {
638             tunType = TunnelTypeGre.class ;
639         }
640         VtepConfigSchemaBuilder schemaBuilder = new VtepConfigSchemaBuilder().setSchemaName(schemaName)
641                 .setPortName(portName).setVlanId(vlanId).setSubnet(subnet).setGatewayIp(gatewayIpObj)
642                 .setTransportZoneName(transportZone).setTunnelType(tunType).setDpnIds(getDpnIdsListFromBigInt(dpnIds))
643                 .setExcludeIpFilter(excludeIpFilter);
644         return schemaBuilder.build();
645     }
646
647     public static List<IpAddress> getExcludeIpAddresses(String excludeIpFilter, SubnetInfo subnetInfo) {
648         final List<IpAddress> lstIpAddress = new ArrayList<>();
649         if (StringUtils.isBlank(excludeIpFilter)) {
650             return lstIpAddress;
651         }
652         final String[] arrIps = StringUtils.split(excludeIpFilter, ',');
653         for (String ip : arrIps) {
654             if (StringUtils.countMatches(ip, "-") == 1) {
655                 final String[] arrIpRange = StringUtils.split(ip, '-');
656                 String strStartIp = StringUtils.trim(arrIpRange[0]);
657                 String strEndIp = StringUtils.trim(arrIpRange[1]);
658                 Preconditions.checkArgument(InetAddresses.isInetAddress(strStartIp),
659                         "Invalid exclude IP filter: invalid IP address value " + strStartIp);
660                 Preconditions.checkArgument(InetAddresses.isInetAddress(strEndIp),
661                         "Invalid exclude IP filter: invalid IP address value " + strEndIp);
662                 Preconditions.checkArgument(subnetInfo.isInRange(strStartIp),
663                         "Invalid exclude IP filter: IP address [" + strStartIp
664                                 + "] not in subnet range " + subnetInfo.getCidrSignature());
665                 Preconditions.checkArgument(subnetInfo.isInRange(strEndIp),
666                         "Invalid exclude IP filter: IP address [" + strEndIp
667                                 + "] not in subnet range " + subnetInfo.getCidrSignature());
668                 int startIp = subnetInfo.asInteger(strStartIp);
669                 int endIp = subnetInfo.asInteger(strEndIp);
670
671                 Preconditions.checkArgument(startIp < endIp,
672                         "Invalid exclude IP filter: Invalid range [" + ip + "] ");
673                 for (int iter = startIp; iter <= endIp; iter++) {
674                     String ipAddress = ipFormat(toIpArray(iter));
675                     validateAndAddIpAddressToList(subnetInfo, lstIpAddress, ipAddress);
676                 }
677             } else {
678                 validateAndAddIpAddressToList(subnetInfo, lstIpAddress, ip);
679             }
680         }
681         return lstIpAddress;
682     }
683
684     private static void validateAndAddIpAddressToList(SubnetInfo subnetInfo, final List<IpAddress> lstIpAddress,
685                                                       String ipAddress) {
686         String ip = StringUtils.trim(ipAddress);
687         Preconditions.checkArgument(InetAddresses.isInetAddress(ip),
688                 "Invalid exclude IP filter: invalid IP address value " + ip);
689         Preconditions.checkArgument(subnetInfo.isInRange(ip),
690                 "Invalid exclude IP filter: IP address [" + ip + "] not in subnet range "
691                         + subnetInfo.getCidrSignature());
692         lstIpAddress.add(new IpAddress(ip.toCharArray()));
693     }
694
695     private static int[] toIpArray(int val) {
696         int[] ret = new int[4];
697         for (int iter = 3; iter >= 0; --iter) {
698             ret[iter] |= val >>> 8 * (3 - iter) & 0xff;
699         }
700         return ret;
701     }
702
703     private static String ipFormat(int[] octets) {
704         StringBuilder str = new StringBuilder();
705         for (int iter = 0; iter < octets.length; ++iter) {
706             str.append(octets[iter]);
707             if (iter != octets.length - 1) {
708                 str.append(".");
709             }
710         }
711         return str.toString();
712     }
713
714     public static VtepConfigSchema validateForUpdateVtepSchema(String schemaName, List<BigInteger> lstDpnsForAdd,
715                                                                List<BigInteger> lstDpnsForDelete,
716                                                                IITMProvider itmProvider) {
717         Preconditions.checkArgument(StringUtils.isNotBlank(schemaName));
718         if ((lstDpnsForAdd == null || lstDpnsForAdd.isEmpty())
719                 && (lstDpnsForDelete == null || lstDpnsForDelete.isEmpty())) {
720             Preconditions.checkArgument(false,
721                     "DPN ID list for add | delete is null or empty in schema " + schemaName);
722         }
723         VtepConfigSchema schema = itmProvider.getVtepConfigSchema(schemaName);
724         if (schema == null) {
725             Preconditions.checkArgument(false, "Specified VTEP Schema [" + schemaName
726                     + "] doesn't exists!");
727         }
728         List<BigInteger> existingDpnIds = getDpnIdList(schema.getDpnIds());
729         if (isNotEmpty(lstDpnsForAdd)) {
730             //  if (isNotEmpty(existingDpnIds)) {
731             List<BigInteger> lstAlreadyExistingDpns = new ArrayList<>(existingDpnIds);
732             lstAlreadyExistingDpns.retainAll(lstDpnsForAdd);
733             Preconditions.checkArgument(lstAlreadyExistingDpns.isEmpty(),
734                     "DPN ID's " + lstAlreadyExistingDpns
735                             + " already exists in VTEP schema [" + schemaName + "]");
736             //    }
737             if (schema.getTunnelType().equals(TunnelTypeGre.class)) {
738                 validateForSingleGreTep(schema.getSchemaName(), lstDpnsForAdd, itmProvider.getAllVtepConfigSchemas());
739             }
740         }
741         if (isNotEmpty(lstDpnsForDelete)) {
742             if (existingDpnIds == null || existingDpnIds.isEmpty()) {
743                 String builder = "DPN ID's " + lstDpnsForDelete
744                         + " specified for delete from VTEP schema [" + schemaName
745                         + "] are not configured in the schema.";
746                 Preconditions.checkArgument(false, builder);
747             } else if (!existingDpnIds.containsAll(lstDpnsForDelete)) {
748                 List<BigInteger> lstConflictingDpns = new ArrayList<>(lstDpnsForDelete);
749                 lstConflictingDpns.removeAll(existingDpnIds);
750                 String builder = "DPN ID's " + lstConflictingDpns
751                         + " specified for delete from VTEP schema [" + schemaName
752                         + "] are not configured in the schema.";
753                 Preconditions.checkArgument(false, builder);
754             }
755         }
756         return schema;
757     }
758
759     public static String getSubnetCidrAsString(IpPrefix subnet) {
760         return subnet == null ? StringUtils.EMPTY : String.valueOf(subnet.getValue());
761     }
762
763     public static <T> List<T> emptyIfNull(List<T> list) {
764         return list == null ? Collections.emptyList() : list;
765     }
766
767     public static <T> boolean isEmpty(Collection<T> collection) {
768         return collection == null || collection.isEmpty();
769     }
770
771     public static <T> boolean isNotEmpty(Collection<T> collection) {
772         return !isEmpty(collection);
773     }
774
775     public static HwVtep createHwVtepObject(String topoId, String nodeId, IpAddress ipAddress, IpPrefix ipPrefix,
776                                             IpAddress gatewayIP, int vlanID,
777                                             Class<? extends TunnelTypeBase> tunneltype, TransportZone transportZone) {
778         HwVtep hwVtep = new HwVtep();
779         hwVtep.setGatewayIP(gatewayIP);
780         hwVtep.setHwIp(ipAddress);
781         hwVtep.setIpPrefix(ipPrefix);
782         hwVtep.setNode_id(nodeId);
783         hwVtep.setTopo_id(topoId);
784         hwVtep.setTransportZone(transportZone.getZoneName());
785         hwVtep.setTunnel_type(tunneltype);
786         hwVtep.setVlanID(vlanID);
787         return hwVtep;
788     }
789
790     public static String getHwParentIf(String topoId, String srcNodeid) {
791         return String.format("%s:%s", topoId, srcNodeid);
792     }
793
794     public static <T extends DataObject> void syncWrite(LogicalDatastoreType datastoreType,
795                                                         InstanceIdentifier<T> path, T data, DataBroker broker) {
796         WriteTransaction tx = broker.newWriteOnlyTransaction();
797         tx.put(datastoreType, path, data, true);
798         CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
799         try {
800             futures.get();
801         } catch (InterruptedException | ExecutionException e) {
802             LOG.error("ITMUtils:SyncWrite , Error writing to datastore (path, data) : ({}, {})", path, data);
803             throw new RuntimeException(e.getMessage());
804         }
805     }
806
807     public static List<BigInteger> getDpnIdList(List<DpnIds> dpnIds) {
808         List<BigInteger> dpnList = new ArrayList<>() ;
809         for (DpnIds dpn : dpnIds) {
810             dpnList.add(dpn.getDPN()) ;
811         }
812         return dpnList ;
813     }
814
815     public static List<DpnIds> getDpnIdsListFromBigInt(List<BigInteger> dpnIds) {
816         List<DpnIds> dpnIdList = new ArrayList<>();
817         DpnIdsBuilder builder = new DpnIdsBuilder();
818         for (BigInteger dpnId : dpnIds) {
819             dpnIdList.add(builder.setKey(new DpnIdsKey(dpnId)).setDPN(dpnId).build());
820         }
821         return dpnIdList;
822     }
823
824     public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
825             .interfaces.state.Interface> buildStateInterfaceId(String interfaceName) {
826         InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
827                 .interfaces.state.Interface> idBuilder = InstanceIdentifier.builder(InterfacesState.class)
828                 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
829                         .interfaces.state.Interface.class,
830                         new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
831                         .interfaces.state.InterfaceKey(interfaceName));
832         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
833                 .interfaces.state.Interface> id = idBuilder.build();
834         return id;
835     }
836
837     public static Boolean readMonitoringStateFromCache(DataBroker dataBroker) {
838         InstanceIdentifier<TunnelMonitorParams> iid = InstanceIdentifier.create(TunnelMonitorParams.class);
839         TunnelMonitorParams tunnelMonitorParams = (TunnelMonitorParams) DataStoreCache
840                 .get(ITMConstants.ITM_MONIRORING_PARAMS_CACHE_NAME,iid,"MonitorParams",dataBroker,true);
841         if (tunnelMonitorParams != null) {
842             return tunnelMonitorParams.isEnabled();
843         } else {
844             return ITMConstants.DEFAULT_MONITOR_ENABLED;
845         }
846     }
847
848     public static Integer readMonitorIntervalfromCache(DataBroker dataBroker) {
849         InstanceIdentifier<TunnelMonitorInterval> iid = InstanceIdentifier.create(TunnelMonitorInterval.class);
850         TunnelMonitorInterval tunnelMonitorIOptional = (TunnelMonitorInterval)DataStoreCache
851                 .get(ITMConstants.ITM_MONIRORING_PARAMS_CACHE_NAME,iid,"Interval",dataBroker,true);
852         if (tunnelMonitorIOptional != null) {
853             return tunnelMonitorIOptional.getInterval();
854         }
855         return null;
856
857     }
858
859     public static Integer determineMonitorInterval(DataBroker dataBroker) {
860         Integer monitorInterval = ItmUtils.readMonitorIntervalfromCache(dataBroker);
861         LOG.debug("determineMonitorInterval: monitorInterval from DS = {}", monitorInterval);
862         if (monitorInterval == null) {
863             Class<? extends TunnelMonitoringTypeBase> monitorProtocol = determineMonitorProtocol(dataBroker);
864             if (monitorProtocol.isAssignableFrom(TunnelMonitoringTypeBfd.class)) {
865                 monitorInterval = ITMConstants.BFD_DEFAULT_MONITOR_INTERVAL;
866             } else {
867                 monitorInterval = ITMConstants.DEFAULT_MONITOR_INTERVAL;
868             }
869         }
870         LOG.debug("determineMonitorInterval: monitorInterval = {}", monitorInterval);
871         InstanceIdentifier<TunnelMonitorInterval> iid = InstanceIdentifier.builder(TunnelMonitorInterval.class).build();
872         TunnelMonitorInterval intervalBuilder = new TunnelMonitorIntervalBuilder().setInterval(monitorInterval).build();
873         ItmUtils.asyncUpdate(LogicalDatastoreType.OPERATIONAL,iid, intervalBuilder, dataBroker,
874                 ItmUtils.DEFAULT_CALLBACK);
875         return monitorInterval;
876     }
877
878     public static List<String> getInternalTunnelInterfaces(DataBroker dataBroker) {
879         List<String> tunnelList = new ArrayList<>();
880         Collection<String> internalInterfaces = itmCache.getAllInternalInterfaces();
881         if (internalInterfaces == null) {
882             updateTunnelsCache(dataBroker);
883             internalInterfaces = itmCache.getAllInternalInterfaces();
884         }
885         LOG.debug("ItmUtils.getTunnelList Cache Internal Interfaces size: {} ", internalInterfaces.size());
886         if (internalInterfaces != null) {
887             tunnelList.addAll(internalInterfaces);
888         }
889         LOG.trace("ItmUtils.getTunnelList Internal: {}", tunnelList);
890         return tunnelList;
891     }
892
893     public static List<String> getTunnelsofTzone(List<HwVtep> hwVteps, String tzone, DataBroker dataBroker,
894                                                  Boolean hwVtepsExist) {
895
896         List<String> tunnels = new ArrayList<>();
897         InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
898                 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
899         Optional<TransportZone> transportZoneOptional =
900                 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
901         if (transportZoneOptional.isPresent()) {
902             TransportZone transportZone = transportZoneOptional.get();
903             Class<? extends TunnelTypeBase> tunType = transportZone.getTunnelType();
904             if (transportZone.getSubnets() != null && !transportZone.getSubnets().isEmpty()) {
905                 for (Subnets sub : transportZone.getSubnets()) {
906                     if (sub.getVteps() != null && !sub.getVteps().isEmpty()) {
907                         for (Vteps vtepLocal : sub.getVteps()) {
908                             for (Vteps vtepRemote : sub.getVteps()) {
909                                 if (!vtepLocal.equals(vtepRemote)) {
910                                     InternalTunnelKey key = new InternalTunnelKey(vtepRemote.getDpnId(),
911                                             vtepLocal.getDpnId(), tunType);
912                                     InstanceIdentifier<InternalTunnel> intIID =
913                                             InstanceIdentifier.builder(TunnelList.class)
914                                                     .child(InternalTunnel.class, key).build();
915                                     Optional<InternalTunnel> tunnelsOptional =
916                                             ItmUtils.read(LogicalDatastoreType.CONFIGURATION, intIID, dataBroker);
917                                     if (tunnelsOptional.isPresent()) {
918                                         List<String> tunnelInterfaceNames = tunnelsOptional
919                                                 .get().getTunnelInterfaceNames();
920                                         if (tunnelInterfaceNames != null && !tunnelInterfaceNames.isEmpty()) {
921                                             String tunnelInterfaceName = tunnelInterfaceNames.get(0);
922                                             LOG.trace("Internal Tunnel added {}", tunnelInterfaceName);
923                                             tunnels.add(tunnelInterfaceName);
924                                         }
925                                     }
926                                 }
927                             }
928                             if (hwVteps != null && !hwVteps.isEmpty()) {
929                                 for (HwVtep hwVtep : hwVteps) {
930                                     tunnels.add(getExtTunnel(hwVtep.getNode_id(), vtepLocal.getDpnId().toString(),
931                                             tunType, dataBroker));
932                                     tunnels.add(getExtTunnel(vtepLocal.getDpnId().toString(), hwVtep.getNode_id(),
933                                             tunType, dataBroker));
934                                 }
935                             }
936                         }
937                     }
938                 }
939             }
940             if (hwVtepsExist) {
941                 for (HwVtep hwVtep : hwVteps) {
942                     for (HwVtep hwVtepOther : hwVteps) {
943                         if (!hwVtep.getHwIp().equals(hwVtepOther.getHwIp())) {
944                             tunnels.add(getExtTunnel(hwVtep.getNode_id(), hwVtepOther.getNode_id(),
945                                     tunType, dataBroker));
946                             tunnels.add(getExtTunnel(hwVtepOther.getNode_id(), hwVtep.getNode_id(),
947                                     tunType, dataBroker));
948                         }
949                     }
950                 }
951             }
952         }
953         return tunnels;
954     }
955
956     public static List<String> getInternalTunnelsofTzone(String tzone, DataBroker dataBroker) {
957         List<String> tunnels = new ArrayList<>();
958         LOG.trace("Getting internal tunnels of {}",tzone);
959         InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
960                 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
961         Optional<TransportZone> transportZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
962                 path, dataBroker);
963         if (transportZoneOptional.isPresent()) {
964             TransportZone transportZone = transportZoneOptional.get();
965             if (transportZone.getSubnets() != null && !transportZone.getSubnets().isEmpty()) {
966                 for (Subnets sub : transportZone.getSubnets()) {
967                     if (sub.getVteps() != null && !sub.getVteps().isEmpty()) {
968                         for (Vteps vtepLocal : sub.getVteps()) {
969                             for (Vteps vtepRemote : sub.getVteps()) {
970                                 if (!vtepLocal.equals(vtepRemote)) {
971                                     InternalTunnelKey key =
972                                             new InternalTunnelKey(vtepRemote.getDpnId(), vtepLocal.getDpnId(),
973                                                     transportZone.getTunnelType());
974                                     InstanceIdentifier<InternalTunnel> intIID =
975                                             InstanceIdentifier.builder(TunnelList.class)
976                                                     .child(InternalTunnel.class, key).build();
977                                     Optional<InternalTunnel> tunnelsOptional =
978                                             ItmUtils.read(LogicalDatastoreType.CONFIGURATION, intIID, dataBroker);
979                                     if (tunnelsOptional.isPresent()) {
980                                         List<String> tunnelInterfaceNames = tunnelsOptional.get()
981                                                 .getTunnelInterfaceNames();
982                                         if (tunnelInterfaceNames != null && !tunnelInterfaceNames.isEmpty()) {
983                                             String tunnelInterfaceName = tunnelInterfaceNames.get(0);
984                                             LOG.trace("Internal Tunnel added {}", tunnelInterfaceName);
985                                             tunnels.add(tunnelInterfaceName);
986                                         }
987                                     }
988                                 }
989                             }
990                         }
991                     }
992                 }
993             }
994         }
995         return tunnels;
996     }
997
998     private static String getExtTunnel(String nodeId, String dpId,Class<? extends TunnelTypeBase> tunType, DataBroker
999             dataBroker) {
1000         LOG.trace("getting ext tunnel for {} and dpId {}",nodeId,dpId);
1001         ExternalTunnelKey key = getExternalTunnelKey(dpId, nodeId, tunType);
1002         InstanceIdentifier<ExternalTunnel> intIID = InstanceIdentifier.builder(ExternalTunnelList.class)
1003                 .child(ExternalTunnel.class, key).build();
1004         Optional<ExternalTunnel> tunnelsOptional =
1005                 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, intIID, dataBroker);
1006         if (tunnelsOptional.isPresent()) {
1007             String tunnelInterfaceName = tunnelsOptional.get().getTunnelInterfaceName();
1008             LOG.trace("ext tunnel returned {} ", tunnelInterfaceName);
1009             return tunnelInterfaceName;
1010         }
1011         return null;
1012     }
1013
1014     public static ExternalTunnelKey getExternalTunnelKey(String dst , String src,
1015                                                          Class<? extends TunnelTypeBase> tunType) {
1016         if (src.indexOf("physicalswitch") > 0) {
1017             src = src.substring(0, src.indexOf("physicalswitch") - 1);
1018         }
1019         if (dst.indexOf("physicalswitch") > 0) {
1020             dst = dst.substring(0, dst.indexOf("physicalswitch") - 1);
1021         }
1022         return new ExternalTunnelKey(dst, src, tunType);
1023     }
1024
1025     public static List<TunnelEndPoints> getTEPsForDpn(BigInteger srcDpn, List<DPNTEPsInfo> dpnList) {
1026         for (DPNTEPsInfo dpn : dpnList) {
1027             if (dpn.getDPNID().equals(srcDpn)) {
1028                 return dpn.getTunnelEndPoints() ;
1029             }
1030         }
1031         return null ;
1032     }
1033
1034     public static TunnelList getAllInternalTunnels(DataBroker broker) {
1035         InstanceIdentifier<TunnelList> tunnelListInstanceIdentifier =
1036                 InstanceIdentifier.builder(TunnelList.class).build();
1037         return read(LogicalDatastoreType.CONFIGURATION, tunnelListInstanceIdentifier, broker).orNull();
1038     }
1039
1040     public static List<InternalTunnel> getAllInternalTunnels(DataBroker dataBroker,
1041                                                              LogicalDatastoreType datastoreType) {
1042         List<InternalTunnel> result = null;
1043         InstanceIdentifier<TunnelList> iid = InstanceIdentifier.builder(TunnelList.class).build();
1044         Optional<TunnelList> tunnelList = read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
1045         if (tunnelList.isPresent()) {
1046             result = tunnelList.get().getInternalTunnel();
1047         }
1048         if (result == null) {
1049             result = Collections.emptyList();
1050         }
1051         return result;
1052     }
1053
1054     public static InternalTunnel getInternalTunnel(String interfaceName, DataBroker broker) {
1055         InternalTunnel internalTunnel = null;
1056         internalTunnel = itmCache.getInternalTunnel(interfaceName);
1057         if (internalTunnel == null) {
1058             updateTunnelsCache(broker);
1059             internalTunnel = itmCache.getInternalTunnel(interfaceName);
1060         }
1061         return internalTunnel;
1062     }
1063
1064     public static ExternalTunnel getExternalTunnel(String interfaceName, DataBroker broker) {
1065         ExternalTunnel externalTunnel = null;
1066         externalTunnel = itmCache.getExternalTunnel(interfaceName);
1067         if (externalTunnel == null) {
1068             updateTunnelsCache(broker);
1069             externalTunnel = itmCache.getExternalTunnel(interfaceName);
1070         }
1071         return externalTunnel;
1072     }
1073
1074     public static List<ExternalTunnel> getAllExternalTunnels(DataBroker broker) {
1075         List<ExternalTunnel> result = null;
1076         InstanceIdentifier<ExternalTunnelList> id = InstanceIdentifier.builder(ExternalTunnelList.class).build();
1077         Optional<ExternalTunnelList> tunnelList = read(LogicalDatastoreType.CONFIGURATION, id, broker);
1078         if (tunnelList.isPresent()) {
1079             result = tunnelList.get().getExternalTunnel();
1080         }
1081         if (result == null) {
1082             result = Collections.emptyList();
1083         }
1084         return result;
1085     }
1086
1087     public static List<ExternalTunnel> getAllExternalTunnels(DataBroker dataBroker,
1088                                                              LogicalDatastoreType datastoreType) {
1089         List<ExternalTunnel> result = null;
1090         InstanceIdentifier<ExternalTunnelList> iid = InstanceIdentifier.builder(ExternalTunnelList.class).build();
1091         Optional<ExternalTunnelList> tunnelList = read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
1092         if (tunnelList.isPresent()) {
1093             result = tunnelList.get().getExternalTunnel();
1094         }
1095         if (result == null) {
1096             result = Collections.emptyList();
1097         }
1098         return result;
1099     }
1100
1101     public static String convertTunnelTypetoString(Class<? extends TunnelTypeBase> tunType) {
1102         String tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
1103         if (tunType.equals(TunnelTypeVxlan.class)) {
1104             tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN ;
1105         } else if (tunType.equals(TunnelTypeGre.class)) {
1106             tunnelType = ITMConstants.TUNNEL_TYPE_GRE ;
1107         } else if (tunType.equals(TunnelTypeMplsOverGre.class)) {
1108             tunnelType = ITMConstants.TUNNEL_TYPE_MPLSoGRE;
1109         }
1110         return tunnelType ;
1111     }
1112
1113
1114     public static boolean isItmIfType(Class<? extends InterfaceType> ifType) {
1115         return ifType != null && ifType.isAssignableFrom(Tunnel.class);
1116     }
1117
1118     public static StateTunnelListKey getTunnelStateKey(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1119                                                                .interfaces.rev140508.interfaces.state.Interface iface) {
1120         StateTunnelListKey key = null;
1121         if (isItmIfType(iface.getType())) {
1122             key = new StateTunnelListKey(iface.getName());
1123         }
1124         return key;
1125     }
1126
1127     public static void updateTunnelsCache(DataBroker broker) {
1128         List<InternalTunnel> internalTunnels = getAllInternalTunnels(broker, LogicalDatastoreType.CONFIGURATION);
1129         for (InternalTunnel tunnel : internalTunnels) {
1130             itmCache.addInternalTunnel(tunnel);
1131         }
1132         List<ExternalTunnel> externalTunnels = getAllExternalTunnels(broker, LogicalDatastoreType.CONFIGURATION);
1133         for (ExternalTunnel tunnel : externalTunnels) {
1134             itmCache.addExternalTunnel(tunnel);
1135         }
1136     }
1137
1138     public static Interface getInterface(
1139             String name, IInterfaceManager ifaceManager) {
1140         Interface result = itmCache.getInterface(name);
1141         if (result == null) {
1142             result = ifaceManager.getInterfaceInfoFromConfigDataStore(name);
1143             if (result != null) {
1144                 itmCache.addInterface(result);
1145             }
1146         }
1147         return result;
1148     }
1149
1150     public static StateTunnelList getTunnelState(DataBroker dataBroker, String ifaceName,
1151                                                  InstanceIdentifier<StateTunnelList> stListId) {
1152         StateTunnelList tunnelState = (StateTunnelList)DataStoreCache
1153                 .get(ITMConstants.TUNNEL_STATE_CACHE_NAME, ifaceName);
1154         if (tunnelState == null) {
1155             Optional<StateTunnelList> tunnelsState = ItmUtils
1156                     .read(LogicalDatastoreType.OPERATIONAL, stListId, dataBroker);
1157             if (tunnelsState.isPresent()) {
1158                 return tunnelState;
1159             }
1160         }
1161         return tunnelState;
1162     }
1163
1164     public static Class<? extends TunnelMonitoringTypeBase> readMonitoringProtocolFromCache(DataBroker dataBroker) {
1165         InstanceIdentifier<TunnelMonitorParams> iid = InstanceIdentifier.create(TunnelMonitorParams.class);
1166         TunnelMonitorParams tunnelMonitorParams = (TunnelMonitorParams) DataStoreCache
1167                 .get(ITMConstants.ITM_MONIRORING_PARAMS_CACHE_NAME,iid,"MonitorParams",dataBroker,true);
1168         if (tunnelMonitorParams != null) {
1169             return tunnelMonitorParams.getMonitorProtocol();
1170         }
1171         return null;
1172     }
1173
1174     public static Class<? extends TunnelMonitoringTypeBase> determineMonitorProtocol(DataBroker dataBroker) {
1175         Class<? extends TunnelMonitoringTypeBase> monitoringProtocol =
1176                 ItmUtils.readMonitoringProtocolFromCache(dataBroker);
1177         LOG.debug("determineMonitorProtocol: monitorProtocol from DS = {}", monitoringProtocol);
1178         if (monitoringProtocol == null) {
1179             monitoringProtocol = ITMConstants.DEFAULT_MONITOR_PROTOCOL;
1180         }
1181         LOG.debug("determineMonitorProtocol: monitorProtocol = {}", monitoringProtocol);
1182         Boolean monitorState = ItmUtils.readMonitoringStateFromCache(dataBroker);
1183         if (monitorState == null) {
1184             monitorState = true;
1185         }
1186         LOG.debug("determineMonitorProtocol: monitorState = {}", monitorState);
1187         InstanceIdentifier<TunnelMonitorParams> iid = InstanceIdentifier.builder(TunnelMonitorParams.class).build();
1188         TunnelMonitorParams protocolBuilder = new TunnelMonitorParamsBuilder().setEnabled(monitorState)
1189                 .setMonitorProtocol(monitoringProtocol).build();
1190         ItmUtils.asyncUpdate(LogicalDatastoreType.OPERATIONAL,iid, protocolBuilder, dataBroker,
1191                 ItmUtils.DEFAULT_CALLBACK);
1192         return monitoringProtocol;
1193     }
1194
1195     public static List<DcGatewayIp> getDcGatewayIpList(DataBroker broker) {
1196         InstanceIdentifier<DcGatewayIpList> dcGatewayIpListid =
1197                 InstanceIdentifier.builder(DcGatewayIpList.class).build();
1198         Optional<DcGatewayIpList> dcGatewayIpListConfig =
1199                 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, dcGatewayIpListid, broker);
1200         if (dcGatewayIpListConfig.isPresent()) {
1201             DcGatewayIpList containerList = dcGatewayIpListConfig.get();
1202             if (containerList != null) {
1203                 return containerList.getDcGatewayIp();
1204             }
1205         }
1206         return null;
1207     }
1208
1209     public static boolean falseIfNull(Boolean value) {
1210         return value == null ? false : value;
1211     }
1212
1213     public static <T> List<T> getIntersection(List<T> list1, List<T> list2) {
1214         List<T> list = new ArrayList<>();
1215         for (T iter : list1) {
1216             if (list2.contains(iter)) {
1217                 list.add(iter);
1218             }
1219         }
1220         LOG.debug(" getIntersection - L1 {}, L2 - {}, Intersection - {}", list1, list2, list);
1221         return list;
1222     }
1223
1224     public static void addTransportZoneMembership(List<TzMembership> zones, String zoneName) {
1225         zones.add(new TzMembershipBuilder().setZoneName(zoneName).build());
1226     }
1227
1228     public static  List<TzMembership> createTransportZoneMembership(String zoneName) {
1229         List<TzMembership> zones = new ArrayList<>();
1230         zones.add(new TzMembershipBuilder().setZoneName(zoneName).build());
1231         return zones;
1232     }
1233
1234     /**
1235      * Returns the transport zone from Configuration datastore.
1236      *
1237      * @param tzName transport zone name
1238      * @param dataBroker data broker handle to perform operations on datastore
1239      */
1240     // FIXME: Better is to implement cache to avoid datastore read.
1241     public static TransportZone getTransportZoneFromConfigDS(String tzName, DataBroker dataBroker) {
1242         InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class)
1243                 .child(TransportZone.class, new TransportZoneKey(tzName)).build();
1244         Optional<TransportZone> transportZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath,
1245             dataBroker);
1246         if (transportZoneOptional.isPresent()) {
1247             return transportZoneOptional.get();
1248         }
1249         return null;
1250     }
1251
1252     /**
1253      * Gets the transport zone in TepsNotHosted list in the Configuration Datastore, based on transport zone name.
1254      *
1255      * @param unknownTz transport zone name
1256      *
1257      * @param dataBroker data broker handle to perform read operations on config datastore
1258      *
1259      * @return the TepsNotHostedInTransportZone object in the TepsNotHosted list in Config DS
1260      */
1261     public static TepsNotHostedInTransportZone getUnknownTransportZoneFromITMConfigDS(
1262         String unknownTz, DataBroker dataBroker) {
1263         InstanceIdentifier<TepsNotHostedInTransportZone> unknownTzPath =
1264             InstanceIdentifier.builder(TransportZones.class)
1265                     .child(TepsNotHostedInTransportZone.class,
1266                     new TepsNotHostedInTransportZoneKey(unknownTz)).build();
1267         Optional<TepsNotHostedInTransportZone> unknownTzOptional =
1268             ItmUtils.read(LogicalDatastoreType.CONFIGURATION, unknownTzPath, dataBroker);
1269         if (unknownTzOptional.isPresent()) {
1270             return unknownTzOptional.get();
1271         }
1272         return null;
1273     }
1274
1275     /**
1276      * Gets the bridge datapath ID from Network topology Node's OvsdbBridgeAugmentation, in the Operational DS.
1277      *
1278      * @param node Network Topology Node
1279      *
1280      * @param bridge bridge name
1281      *
1282      * @param dataBroker data broker handle to perform operations on datastore
1283      *
1284      * @return the datapath ID of bridge in string form
1285      */
1286     public static String getBridgeDpid(Node node, String bridge, DataBroker dataBroker) {
1287         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
1288         Node bridgeNode = null;
1289         String datapathId = null;
1290
1291         NodeId ovsdbNodeId = node.getKey().getNodeId();
1292
1293         NodeId brNodeId = new NodeId(ovsdbNodeId.getValue()
1294             + "/" + ITMConstants.BRIDGE_URI_PREFIX + "/" + bridge);
1295
1296         InstanceIdentifier<Node> bridgeIid =
1297             InstanceIdentifier
1298                 .create(NetworkTopology.class)
1299                 .child(Topology.class, new TopologyKey(IfmConstants.OVSDB_TOPOLOGY_ID))
1300                 .child(Node.class,new NodeKey(brNodeId));
1301
1302         Optional<Node> opBridgeNode = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, bridgeIid, dataBroker);
1303
1304         if (opBridgeNode.isPresent()) {
1305             bridgeNode = opBridgeNode.get();
1306         }
1307         if (bridgeNode != null) {
1308             ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
1309         }
1310
1311         if (ovsdbBridgeAugmentation != null && ovsdbBridgeAugmentation.getDatapathId() != null) {
1312             datapathId = ovsdbBridgeAugmentation.getDatapathId().getValue();
1313         }
1314         return datapathId;
1315     }
1316
1317     /**
1318      * Gets the Network topology Node from Operational Datastore
1319      * based on Bridge Augmentation.
1320      *
1321      * @param bridgeAugmentation bridge augmentation of OVSDB node
1322      *
1323      * @param dataBroker data broker handle to perform operations on datastore
1324      *
1325      * @return the Network Topology Node i.e. OVSDB node which is managing the specified bridge
1326      */
1327     public static Node getOvsdbNode(OvsdbBridgeAugmentation bridgeAugmentation,
1328         DataBroker dataBroker) {
1329         Node ovsdbNode = null;
1330         Optional<Node> opOvsdbNode = null;
1331         if (bridgeAugmentation != null) {
1332             InstanceIdentifier<Node> ovsdbNodeIid =
1333                 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
1334             opOvsdbNode = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid, dataBroker);
1335         }
1336         if (opOvsdbNode.isPresent()) {
1337             ovsdbNode = opOvsdbNode.get();
1338         }
1339         return ovsdbNode;
1340     }
1341
1342     /**
1343      * Gets the bridge datapath ID in string form from
1344      * Network topology Node's OvsdbBridgeAugmentation in the Operational DS.
1345      *
1346      * @param augmentedNode Ovsdb Augmented Network Topology Node
1347      *
1348      * @return the datapath ID of bridge in string form
1349      */
1350     public static String getStrDatapathId(OvsdbBridgeAugmentation augmentedNode) {
1351         String datapathId = null;
1352         if (augmentedNode != null && augmentedNode.getDatapathId() != null) {
1353             datapathId = augmentedNode.getDatapathId().getValue();
1354         }
1355         return datapathId;
1356     }
1357
1358     /**
1359      * Returns the dummy subnet (255.255.255.255/32) as IpPrefix object.
1360      *
1361      * @return the dummy subnet (255.255.255.255/32) in IpPrefix object
1362      */
1363     public static IpPrefix getDummySubnet() {
1364         return DUMMY_IP_PREFIX;
1365     }
1366
1367     /**
1368      * Deletes the transport zone from Configuration datastore.
1369      *
1370      * @param tzName transport zone name
1371      * @param dataBroker data broker handle to perform operations on datastore
1372      */
1373     public static void deleteTransportZoneFromConfigDS(String tzName, DataBroker dataBroker) {
1374         // check whether transport-zone exists in config DS.
1375         TransportZone transportZoneFromConfigDS = ItmUtils.getTransportZoneFromConfigDS(tzName, dataBroker);
1376         if (transportZoneFromConfigDS != null) {
1377             // it exists, delete default-TZ now
1378             InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
1379                     .child(TransportZone.class,
1380                     new TransportZoneKey(tzName)).build();
1381             LOG.debug("Removing {} transport-zone from config DS.", tzName);
1382             ItmUtils.asyncDelete(LogicalDatastoreType.CONFIGURATION, path, dataBroker, ItmUtils.DEFAULT_CALLBACK);
1383         }
1384     }
1385
1386     /**
1387      * Validates the tunnelType argument and returnsTunnelTypeBase class object
1388      * corresponding to tunnelType obtained in String format.
1389      *
1390      * @param tunnelType type of tunnel in string form
1391      *
1392      * @return tunnel-type in TunnelTypeBase object
1393      */
1394     public static Class<? extends TunnelTypeBase> getTunnelType(String tunnelType) {
1395         // validate tunnelType string, in case it is NULL or empty, then
1396         // take VXLAN tunnel type by default
1397         if (tunnelType == null || tunnelType.isEmpty()) {
1398             return TUNNEL_TYPE_MAP.get(ITMConstants.TUNNEL_TYPE_VXLAN);
1399         } else if (!tunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN)
1400                 && !tunnelType.equals(ITMConstants.TUNNEL_TYPE_GRE)) {
1401             // if tunnel type is some incorrect value, then
1402             // take VXLAN tunnel type by default
1403             return TUNNEL_TYPE_MAP.get(ITMConstants.TUNNEL_TYPE_VXLAN);
1404         }
1405
1406         // return TunnelTypeBase object corresponding to tunnel-type
1407         return TUNNEL_TYPE_MAP.get(tunnelType);
1408     }
1409
1410     public static List<TzMembership> removeTransportZoneMembership(TunnelEndPoints endPts, List<TzMembership> zones) {
1411         LOG.trace(" RemoveTransportZoneMembership TEPs {}, Membership to be removed {} ", endPts, zones);
1412         List<TzMembership> existingTzList = new ArrayList<>(endPts.getTzMembership()) ;
1413         for (TzMembership membership : zones) {
1414             existingTzList.remove(new TzMembershipBuilder().setZoneName(membership.getZoneName()).build());
1415         }
1416         LOG.debug("Modified Membership List {}", existingTzList);
1417         return existingTzList;
1418     }
1419
1420     public static List<TzMembership> getOriginalTzMembership(TunnelEndPoints srcTep, BigInteger dpnId,
1421                                                              List<DPNTEPsInfo> meshedDpnList) {
1422         LOG.trace("Original Membership for source DPN {}, source TEP {}", dpnId, srcTep);
1423         for (DPNTEPsInfo dstDpn : meshedDpnList) {
1424             if (dpnId.equals(dstDpn.getDPNID())) {
1425                 List<TunnelEndPoints> endPts = dstDpn.getTunnelEndPoints();
1426                 for (TunnelEndPoints tep : endPts) {
1427                     if (tep.getIpAddress().equals(srcTep.getIpAddress())) {
1428                         LOG.debug("Original Membership size " + tep.getTzMembership().size()) ;
1429                         return tep.getTzMembership();
1430                     }
1431                 }
1432             }
1433         }
1434         return null ;
1435     }
1436
1437     public static StateTunnelList buildStateTunnelList(StateTunnelListKey tlKey, String name, boolean state,
1438                                                        TunnelOperStatus tunOpStatus, IInterfaceManager  ifaceManager,
1439                                                        DataBroker broker) {
1440         StateTunnelListBuilder stlBuilder = new StateTunnelListBuilder();
1441         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
1442                 ItmUtils.getInterface(name, ifaceManager);
1443         IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
1444         ParentRefs parentRefs = iface.getAugmentation(ParentRefs.class);
1445         if (ifTunnel == null && parentRefs == null) {
1446             return null;
1447         }
1448         DstInfoBuilder dstInfoBuilder = new DstInfoBuilder();
1449         SrcInfoBuilder srcInfoBuilder = new SrcInfoBuilder();
1450         dstInfoBuilder.setTepIp(ifTunnel.getTunnelDestination());
1451         srcInfoBuilder.setTepIp(ifTunnel.getTunnelSource());
1452         // TODO: Add/Improve logic for device type
1453         InternalTunnel internalTunnel = ItmUtils.itmCache.getInternalTunnel(name);
1454         ExternalTunnel externalTunnel = ItmUtils.itmCache.getExternalTunnel(name);
1455         if (internalTunnel == null && externalTunnel == null) {
1456             // both not present in cache. let us update and try again.
1457             ItmUtils.updateTunnelsCache(broker);
1458             internalTunnel = ItmUtils.itmCache.getInternalTunnel(name);
1459             externalTunnel = ItmUtils.itmCache.getExternalTunnel(name);
1460         }
1461         if (internalTunnel != null) {
1462             srcInfoBuilder.setTepDeviceId(internalTunnel.getSourceDPN().toString())
1463                     .setTepDeviceType(TepTypeInternal.class);
1464             dstInfoBuilder.setTepDeviceId(internalTunnel.getDestinationDPN().toString())
1465                     .setTepDeviceType(TepTypeInternal.class);
1466             stlBuilder.setTransportType(internalTunnel.getTransportType());
1467         } else if (externalTunnel != null) {
1468             ExternalTunnel tunnel = ItmUtils.itmCache.getExternalTunnel(name);
1469             srcInfoBuilder.setTepDeviceId(tunnel.getSourceDevice())
1470                     .setTepDeviceType(getDeviceType(tunnel.getSourceDevice()));
1471             dstInfoBuilder.setTepDeviceId(tunnel.getDestinationDevice())
1472                     .setTepDeviceType(getDeviceType(tunnel.getDestinationDevice()))
1473                     .setTepIp(ifTunnel.getTunnelDestination());
1474             stlBuilder.setTransportType(tunnel.getTransportType());
1475         }
1476         stlBuilder.setKey(tlKey).setTunnelInterfaceName(name).setOperState(tunOpStatus).setTunnelState(state)
1477                 .setDstInfo(dstInfoBuilder.build()).setSrcInfo(srcInfoBuilder.build());
1478         return stlBuilder.build();
1479     }
1480
1481     public static Class<? extends TepTypeBase> getDeviceType(String device) {
1482         if (device.startsWith("hwvtep")) {
1483             return TepTypeHwvtep.class;
1484         } else if (device.contains("IpAddress")) {
1485             return TepTypeExternal.class;
1486         } else {
1487             return TepTypeInternal.class;
1488         }
1489     }
1490
1491     public static InstanceIdentifier<StateTunnelList> buildStateTunnelListId(StateTunnelListKey tlKey) {
1492         return InstanceIdentifier.builder(TunnelsState.class)
1493                 .child(StateTunnelList.class, tlKey).build();
1494     }
1495 }