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