Clean up collections of Futures
[genius.git] / itm / itm-impl / src / main / java / org / opendaylight / genius / itm / confighelpers / ItmExternalTunnelAddWorker.java
1 /*
2  * Copyright (c) 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.confighelpers;
9
10 import com.google.common.base.Optional;
11 import com.google.common.util.concurrent.FutureCallback;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import java.math.BigInteger;
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.List;
17 import org.apache.commons.net.util.SubnetUtils;
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.genius.itm.globals.ITMConstants;
22 import org.opendaylight.genius.itm.impl.ItmUtils;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBase;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptions;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.ExternalTunnelList;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembership;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelKey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Subnets;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.DeviceVteps;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.Vteps;
46 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 public class ItmExternalTunnelAddWorker {
51     private static final Logger LOG = LoggerFactory.getLogger(ItmExternalTunnelAddWorker.class);
52
53     private static Boolean monitorEnabled;
54     private static Integer monitorInterval;
55     private static Class<? extends TunnelMonitoringTypeBase> monitorProtocol;
56
57     private static final FutureCallback<Void> DEFAULT_CALLBACK =
58         new FutureCallback<Void>() {
59             @Override
60             public void onSuccess(Void result) {
61                 LOG.debug("Success in Datastore operation");
62             }
63
64             @Override
65             public void onFailure(Throwable error) {
66                 LOG.error("Error in Datastore operation", error);
67             }
68
69     };
70
71     public static List<ListenableFuture<Void>> buildTunnelsToExternalEndPoint(DataBroker dataBroker,
72                                                                               IdManagerService idManagerService,
73                                                                               List<DPNTEPsInfo> cfgDpnList,
74                                                                               IpAddress extIp,
75                                                                               Class<? extends TunnelTypeBase> tunType,
76                                                                               ItmConfig itmConfig) {
77         if (null != cfgDpnList) {
78             WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
79             for (DPNTEPsInfo teps : cfgDpnList) {
80                 // CHECK -- Assumption -- Only one End Point / Dpn for GRE/Vxlan Tunnels
81                 TunnelEndPoints firstEndPt = teps.getTunnelEndPoints().get(0);
82                 String interfaceName = firstEndPt.getInterfaceName();
83                 String tunTypeStr = tunType.getName();
84                 String trunkInterfaceName = ItmUtils.getTrunkInterfaceName(idManagerService, interfaceName,
85                         new String(firstEndPt.getIpAddress().getValue()),
86                         new String(extIp.getValue()), tunTypeStr);
87                 char[] subnetMaskArray = firstEndPt.getSubnetMask().getValue();
88                 boolean useOfTunnel = ItmUtils.falseIfNull(firstEndPt.isOptionOfTunnel());
89                 List<TunnelOptions> tunOptions = ItmUtils.buildTunnelOptions(firstEndPt, itmConfig);
90                 String subnetMaskStr = String.valueOf(subnetMaskArray);
91                 SubnetUtils utils = new SubnetUtils(subnetMaskStr);
92                 String dcGwyIpStr = String.valueOf(extIp.getValue());
93                 IpAddress gatewayIpObj = new IpAddress("0.0.0.0".toCharArray());
94                 IpAddress gwyIpAddress =
95                         utils.getInfo().isInRange(dcGwyIpStr) ? gatewayIpObj : firstEndPt.getGwIpAddress();
96                 LOG.debug(" Creating Trunk Interface with parameters trunk I/f Name - {}, parent I/f name - {},"
97                         + " source IP - {}, DC Gateway IP - {} gateway IP - {}", trunkInterfaceName, interfaceName,
98                         firstEndPt.getIpAddress(), extIp, gwyIpAddress);
99                 Interface iface = ItmUtils.buildTunnelInterface(teps.getDPNID(), trunkInterfaceName,
100                     String.format("%s %s", ItmUtils.convertTunnelTypetoString(tunType), "Trunk Interface"), true,
101                     tunType, firstEndPt.getIpAddress(), extIp, gwyIpAddress, firstEndPt.getVLANID(), false, false,
102                     ITMConstants.DEFAULT_MONITOR_PROTOCOL, null, useOfTunnel, tunOptions);
103
104                 LOG.debug(" Trunk Interface builder - {} ", iface);
105                 InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(trunkInterfaceName);
106                 LOG.debug(" Trunk Interface Identifier - {} ", trunkIdentifier);
107                 LOG.trace(" Writing Trunk Interface to Config DS {}, {} ", trunkIdentifier, iface);
108                 transaction.merge(LogicalDatastoreType.CONFIGURATION, trunkIdentifier, iface, true);
109                 // update external_tunnel_list ds
110                 InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(ExternalTunnelList.class)
111                         .child(ExternalTunnel.class, new ExternalTunnelKey(extIp.toString(),
112                                 teps.getDPNID().toString(), tunType));
113                 ExternalTunnel tnl = ItmUtils.buildExternalTunnel(teps.getDPNID().toString(), extIp.toString(),
114                         tunType, trunkInterfaceName);
115                 transaction.merge(LogicalDatastoreType.CONFIGURATION, path, tnl, true);
116             }
117             return Collections.singletonList(transaction.submit());
118         }
119         return Collections.emptyList();
120     }
121
122     public static List<ListenableFuture<Void>> buildTunnelsFromDpnToExternalEndPoint(DataBroker dataBroker,
123                                                                                      IdManagerService idManagerService,
124                                                                                      List<BigInteger> dpnId,
125                                                                                      IpAddress extIp,
126                                                                                      Class<? extends TunnelTypeBase>
127                                                                                              tunType,
128                                                                                      ItmConfig itmConfig) {
129         List<DPNTEPsInfo> cfgDpnList = dpnId == null ? ItmUtils.getTunnelMeshInfo(dataBroker)
130                         : ItmUtils.getDpnTepListFromDpnId(dataBroker, dpnId);
131         return buildTunnelsToExternalEndPoint(dataBroker, idManagerService, cfgDpnList, extIp, tunType, itmConfig);
132     }
133
134     public static List<ListenableFuture<Void>> buildHwVtepsTunnels(DataBroker dataBroker,
135                                                                    IdManagerService idManagerService,
136                                                                    List<DPNTEPsInfo> cfgdDpnList,
137                                                                    List<HwVtep> cfgdHwVteps) {
138         List<ListenableFuture<Void>> futures = new ArrayList<>();
139         WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
140         monitorInterval = ITMConstants.BFD_DEFAULT_MONITOR_INTERVAL;
141         monitorProtocol = ITMConstants.DEFAULT_MONITOR_PROTOCOL;
142         monitorEnabled = ItmUtils.readMonitoringStateFromCache(dataBroker);
143         if (null != cfgdDpnList && !cfgdDpnList.isEmpty()) {
144             LOG.trace("calling tunnels from css {}",cfgdDpnList);
145             tunnelsFromCSS(cfgdDpnList, idManagerService , futures, writeTransaction , dataBroker);
146         }
147         if (null != cfgdHwVteps && !cfgdHwVteps.isEmpty()) {
148             LOG.trace("calling tunnels from hwTep {}",cfgdHwVteps);
149             tunnelsFromhWVtep(cfgdHwVteps, idManagerService, futures, writeTransaction, dataBroker);
150         }
151
152         if (cfgdDpnList != null && !cfgdDpnList.isEmpty() || cfgdHwVteps != null && !cfgdHwVteps.isEmpty()) {
153             futures.add(writeTransaction.submit());
154         }
155         return futures;
156     }
157
158     private static void tunnelsFromCSS(List<DPNTEPsInfo> cfgdDpnList, IdManagerService idManagerService,
159                                        List<ListenableFuture<Void>> futures, WriteTransaction transaction,
160                                        DataBroker dataBroker) {
161         Boolean monitorEnabled = ItmUtils.readMonitoringStateFromCache(dataBroker);
162         Class<? extends TunnelMonitoringTypeBase> monitorProtocol = ITMConstants.DEFAULT_MONITOR_PROTOCOL;
163         for (DPNTEPsInfo dpn : cfgdDpnList) {
164             LOG.trace("processing dpn {}" , dpn);
165             if (dpn.getTunnelEndPoints() != null && !dpn.getTunnelEndPoints().isEmpty()) {
166                 for (TunnelEndPoints tep : dpn.getTunnelEndPoints()) {
167                     for (TzMembership zone: tep.getTzMembership()) {
168                         createTunnelsFromOVSinTransportZone(zone.getZoneName(), dpn, tep, idManagerService,
169                                 futures, transaction, dataBroker);
170                     }
171                 }
172             }
173         }
174     }
175
176     private static void createTunnelsFromOVSinTransportZone(String zoneName, DPNTEPsInfo dpn, TunnelEndPoints tep,
177                                                             IdManagerService idManagerService,
178                                                             List<ListenableFuture<Void>> futures,
179                                                             WriteTransaction transaction, DataBroker dataBroker) {
180         InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class)
181                 .child(TransportZone.class, new TransportZoneKey(zoneName)).build();
182         Optional<TransportZone> transportZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
183                 tzonePath, dataBroker);
184         if (transportZoneOptional.isPresent()) {
185             TransportZone transportZone = transportZoneOptional.get();
186             //do we need to check tunnel type?
187             if (transportZone.getSubnets() != null && !transportZone.getSubnets().isEmpty()) {
188                 for (Subnets sub : transportZone.getSubnets()) {
189                     if (sub.getDeviceVteps() != null && !sub.getDeviceVteps().isEmpty()) {
190                         for (DeviceVteps hwVtepDS : sub.getDeviceVteps()) {
191                             //dont mesh if hwVteps and OVS-tep have same ip-address
192                             if (hwVtepDS.getIpAddress().equals(tep.getIpAddress())) {
193                                 continue;
194                             }
195                             final String cssID = dpn.getDPNID().toString();
196                             String nodeId = hwVtepDS.getNodeId();
197                             boolean useOfTunnel = ItmUtils.falseIfNull(tep.isOptionOfTunnel());
198                             LOG.trace("wire up {} and {}",tep, hwVtepDS);
199                             if (!wireUp(dpn.getDPNID(), tep.getPortname(), sub.getVlanId(),
200                                     tep.getIpAddress(), useOfTunnel, nodeId, hwVtepDS.getIpAddress(),
201                                     tep.getSubnetMask(), sub.getGatewayIp(), sub.getPrefix(),
202                                     transportZone.getTunnelType(), false, monitorProtocol, monitorInterval,
203                                     idManagerService, dataBroker, futures, transaction)) {
204                                 LOG.error("Unable to build tunnel {} -- {}",
205                                         tep.getIpAddress(), hwVtepDS.getIpAddress());
206                             }
207                             //TOR-OVS
208                             LOG.trace("wire up {} and {}", hwVtepDS,tep);
209                             if (!wireUp(hwVtepDS.getTopologyId(), hwVtepDS.getNodeId(), hwVtepDS.getIpAddress(),
210                                     cssID, tep.getIpAddress(), sub.getPrefix(), sub.getGatewayIp(),
211                                     tep.getSubnetMask(), transportZone.getTunnelType(), false, monitorProtocol,
212                                     monitorInterval, idManagerService, dataBroker, futures, transaction)) {
213                                 LOG.error("Unable to build tunnel {} -- {}",
214                                         hwVtepDS.getIpAddress(), tep.getIpAddress());
215                             }
216
217                         }
218                     }
219                 }
220             }
221         }
222     }
223
224     private static void tunnelsFromhWVtep(List<HwVtep> cfgdHwVteps, IdManagerService idManagerService,
225                                           List<ListenableFuture<Void>> futures, WriteTransaction transaction,
226                                           DataBroker dataBroker) {
227         for (HwVtep hwTep : cfgdHwVteps) {
228             InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class)
229                     .child(TransportZone.class, new TransportZoneKey(hwTep.getTransportZone())).build();
230             Optional<TransportZone> transportZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
231                     tzonePath, dataBroker);
232             Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
233             Boolean monitorEnabled = ItmUtils.readMonitoringStateFromCache(dataBroker);
234             Class<? extends TunnelMonitoringTypeBase> monitorProtocol = ITMConstants.DEFAULT_MONITOR_PROTOCOL;
235             if (transportZoneOptional.isPresent()) {
236                 TransportZone tzone = transportZoneOptional.get();
237                 //do we need to check tunnel type?
238                 if (tzone.getSubnets() != null && !tzone.getSubnets().isEmpty()) {
239                     for (Subnets sub : tzone.getSubnets()) {
240                         if (sub.getDeviceVteps() != null && !sub.getDeviceVteps().isEmpty()) {
241                             for (DeviceVteps hwVtepDS : sub.getDeviceVteps()) {
242                                 if (hwVtepDS.getIpAddress().equals(hwTep.getHwIp())) {
243                                     continue;//dont mesh with self
244                                 }
245                                 LOG.trace("wire up {} and {}",hwTep, hwVtepDS);
246                                 if (!wireUp(hwTep.getTopoId(), hwTep.getNodeId(), hwTep.getHwIp(),
247                                         hwVtepDS.getNodeId(), hwVtepDS.getIpAddress(), hwTep.getIpPrefix(),
248                                         hwTep.getGatewayIP(), sub.getPrefix(), tunType,false,monitorProtocol,
249                                         monitorInterval, idManagerService, dataBroker, futures, transaction)) {
250                                     LOG.error("Unable to build tunnel {} -- {}",
251                                             hwTep.getHwIp(), hwVtepDS.getIpAddress());
252                                 }
253                                 //TOR2-TOR1
254                                 LOG.trace("wire up {} and {}", hwVtepDS,hwTep);
255                                 if (!wireUp(hwTep.getTopoId(), hwVtepDS.getNodeId(), hwVtepDS.getIpAddress(),
256                                         hwTep.getNodeId(), hwTep.getHwIp(), sub.getPrefix(), sub.getGatewayIp(),
257                                         hwTep.getIpPrefix(), tunType, false, monitorProtocol, monitorInterval,
258                                         idManagerService, dataBroker, futures, transaction)) {
259                                     LOG.error("Unable to build tunnel {} -- {}",
260                                             hwVtepDS.getIpAddress(), hwTep.getHwIp());
261                                 }
262                             }
263                         }
264                         if (sub.getVteps() != null && !sub.getVteps().isEmpty()) {
265                             for (Vteps vtep : sub.getVteps()) {
266                                 if (vtep.getIpAddress().equals(hwTep.getHwIp())) {
267                                     continue;
268                                 }
269                                 //TOR-OVS
270                                 String cssID = vtep.getDpnId().toString();
271                                 LOG.trace("wire up {} and {}",hwTep, vtep);
272                                 if (!wireUp(hwTep.getTopoId(), hwTep.getNodeId(), hwTep.getHwIp(), cssID,
273                                         vtep.getIpAddress(), hwTep.getIpPrefix(), hwTep.getGatewayIP(),
274                                         sub.getPrefix(), tunType,false, monitorProtocol, monitorInterval,
275                                         idManagerService, dataBroker, futures, transaction)) {
276                                     LOG.error("Unable to build tunnel {} -- {}",
277                                             hwTep.getHwIp(), vtep.getIpAddress());
278                                 }
279                                 //OVS-TOR
280                                 LOG.trace("wire up {} and {}", vtep,hwTep);
281                                 boolean useOfTunnel = ItmUtils.falseIfNull(vtep.isOptionOfTunnel());
282                                 if (!wireUp(vtep.getDpnId(), vtep.getPortname(), sub.getVlanId(), vtep.getIpAddress(),
283                                         useOfTunnel, hwTep.getNodeId(),hwTep.getHwIp(),sub.getPrefix(),
284                                         sub.getGatewayIp(),hwTep.getIpPrefix(), tunType,false,monitorProtocol,
285                                         monitorInterval, idManagerService, dataBroker, futures, transaction)) {
286                                     //do nothing
287                                 }
288                             }
289
290                         }
291                     }
292                 }
293             }
294         }
295     }
296
297     //for tunnels from TOR device
298     private static boolean wireUp(String topoId, String srcNodeid, IpAddress srcIp, String dstNodeId, IpAddress dstIp,
299                                   IpPrefix srcSubnet, IpAddress gwIp, IpPrefix dstSubnet,
300                                   Class<? extends TunnelTypeBase> tunType,Boolean monitorEnabled,
301                                   Class<? extends TunnelMonitoringTypeBase> monitorProtocol, Integer monitorInterval,
302                                   IdManagerService idManagerService, DataBroker dataBroker,
303                                   List<ListenableFuture<Void>> futures, WriteTransaction transaction) {
304         IpAddress gatewayIpObj = new IpAddress("0.0.0.0".toCharArray());
305         IpAddress gwyIpAddress = srcSubnet.equals(dstSubnet) ? gatewayIpObj : gwIp;
306         String parentIf =  ItmUtils.getHwParentIf(topoId, srcNodeid);
307         String tunTypeStr = tunType.getName();
308         String tunnelIfName = ItmUtils.getTrunkInterfaceName(idManagerService, parentIf,
309                 new String(srcIp.getValue()), new String(dstIp.getValue()), tunTypeStr);
310         LOG.debug(" Creating ExternalTrunk Interface with parameters Name - {}, parent I/f name - {}, "
311                 + "source IP - {}, destination IP - {} gateway IP - {}", tunnelIfName, parentIf, srcIp,
312                 dstIp, gwyIpAddress);
313         Interface hwTunnelIf = ItmUtils.buildHwTunnelInterface(tunnelIfName,
314                 String.format("%s %s", tunType.getName(), "Trunk Interface"), true, topoId, srcNodeid, tunType, srcIp,
315                 dstIp, gwyIpAddress, monitorEnabled, monitorProtocol, monitorInterval);
316         InstanceIdentifier<Interface> ifIID = InstanceIdentifier.builder(Interfaces.class)
317                 .child(Interface.class, new InterfaceKey(tunnelIfName)).build();
318         LOG.trace(" Writing Trunk Interface to Config DS {}, {} ", ifIID, hwTunnelIf);
319         ItmUtils.itmCache.addInterface(hwTunnelIf);
320         transaction.merge(LogicalDatastoreType.CONFIGURATION, ifIID, hwTunnelIf, true);
321         // also update itm-state ds?
322         InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(ExternalTunnelList.class)
323                 .child(ExternalTunnel.class, new ExternalTunnelKey(getExternalTunnelKey(dstNodeId),
324                         getExternalTunnelKey(srcNodeid), tunType));
325         ExternalTunnel tnl = ItmUtils.buildExternalTunnel(getExternalTunnelKey(srcNodeid),
326                 getExternalTunnelKey(dstNodeId), tunType, tunnelIfName);
327         transaction.merge(LogicalDatastoreType.CONFIGURATION, path, tnl, true);
328         ItmUtils.itmCache.addExternalTunnel(tnl);
329         return true;
330     }
331
332     //for tunnels from OVS
333     private static boolean wireUp(BigInteger dpnId, String portname, Integer vlanId, IpAddress srcIp,
334                                   Boolean remoteIpFlow, String dstNodeId, IpAddress dstIp, IpPrefix srcSubnet,
335                                   IpAddress gwIp, IpPrefix dstSubnet, Class<? extends TunnelTypeBase> tunType,
336                                   Boolean monitorEnabled, Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
337                                   Integer monitorInterval, IdManagerService idManagerService, DataBroker dataBroker,
338                                   List<ListenableFuture<Void>> futures, WriteTransaction transaction) {
339         IpAddress gatewayIpObj = new IpAddress("0.0.0.0".toCharArray());
340         IpAddress gwyIpAddress = srcSubnet.equals(dstSubnet) ? gatewayIpObj : gwIp;
341         String parentIf = ItmUtils.getInterfaceName(dpnId, portname, vlanId);
342         String tunTypeStr = tunType.getName();
343         String tunnelIfName = ItmUtils.getTrunkInterfaceName(idManagerService, parentIf,
344                 new String(srcIp.getValue()), new String(dstIp.getValue()), tunTypeStr);
345         LOG.debug(" Creating ExternalTrunk Interface with parameters Name - {}, parent I/f name - {}, "
346                 + "source IP - {}, destination IP - {} gateway IP - {}", tunnelIfName, parentIf, srcIp,
347                 dstIp, gwyIpAddress);
348         Interface extTunnelIf = ItmUtils.buildTunnelInterface(dpnId, tunnelIfName,
349                 String.format("%s %s", tunType.getName(), "Trunk Interface"), true, tunType, srcIp, dstIp, gwyIpAddress,
350                 vlanId, false,monitorEnabled, monitorProtocol, monitorInterval, remoteIpFlow, null);
351         InstanceIdentifier<Interface> ifIID = InstanceIdentifier.builder(Interfaces.class).child(Interface.class,
352                 new InterfaceKey(tunnelIfName)).build();
353         LOG.trace(" Writing Trunk Interface to Config DS {}, {} ", ifIID, extTunnelIf);
354         transaction.merge(LogicalDatastoreType.CONFIGURATION, ifIID, extTunnelIf, true);
355         ItmUtils.itmCache.addInterface(extTunnelIf);
356         InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(ExternalTunnelList.class)
357                 .child(ExternalTunnel.class, new ExternalTunnelKey(getExternalTunnelKey(dstNodeId),
358                         dpnId.toString(), tunType));
359         ExternalTunnel tnl = ItmUtils.buildExternalTunnel(dpnId.toString(),
360                 getExternalTunnelKey(dstNodeId),
361                 tunType, tunnelIfName);
362         transaction.merge(LogicalDatastoreType.CONFIGURATION, path, tnl, true);
363         ItmUtils.itmCache.addExternalTunnel(tnl);
364         return true;
365     }
366
367     static String getExternalTunnelKey(String nodeid) {
368         if (nodeid.indexOf("physicalswitch") > 0) {
369             nodeid = nodeid.substring(0, nodeid.indexOf("physicalswitch") - 1);
370         }
371         return nodeid;
372     }
373
374 }