Bug 7120 : NAT Support For GRE TEP add/del is missing
[netvirt.git] / vpnservice / natservice / natservice-impl / src / main / java / org / opendaylight / netvirt / natservice / internal / NatUtil.java
1 /*
2  * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.netvirt.natservice.internal;
10
11 import java.math.BigInteger;
12
13 import com.google.common.collect.Lists;
14 import com.google.common.collect.Sets;
15
16 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
17 import org.opendaylight.genius.mdsalutil.MDSALUtil;
18 import org.opendaylight.genius.mdsalutil.NwConstants;
19 import org.opendaylight.genius.mdsalutil.ActionInfo;
20 import org.opendaylight.genius.mdsalutil.ActionType;
21 import org.opendaylight.genius.mdsalutil.FlowEntity;
22 import org.opendaylight.genius.mdsalutil.MatchInfo;
23 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
24 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
25 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
26 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
27 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
28 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalIpsCounter;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProtocolTypes;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterIdName;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.SnatintIpPortMap;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.ip.port.map.IpPortExternal;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNodesNodeTableFlowApplyActionsCase;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
107
108 import org.opendaylight.yangtools.yang.binding.DataObject;
109 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
110 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
111 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
112 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
113 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
114
115 import com.google.common.base.Optional;
116
117 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
118 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.IpMapping;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.IpMappingKey;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
140 import org.opendaylight.yangtools.yang.common.RpcResult;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersList;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListKey;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersList;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesBuilder;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListBuilder;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListKey;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListBuilder;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListBuilder;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListKey;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.DpnRouters;
152 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
153 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
154 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
155
156 import org.slf4j.Logger;
157 import org.slf4j.LoggerFactory;
158
159 import java.net.InetAddress;
160 import java.net.UnknownHostException;
161 import java.util.ArrayList;
162 import java.util.Arrays;
163 import java.util.Collections;
164 import java.util.HashMap;
165 import java.util.HashSet;
166 import java.util.List;
167 import java.util.Objects;
168 import java.util.Set;
169 import java.util.concurrent.ExecutionException;
170 import java.util.concurrent.Future;
171 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
172 import com.google.common.util.concurrent.FutureCallback;
173 import com.google.common.util.concurrent.Futures;
174
175 public class NatUtil {
176
177     private static String OF_URI_SEPARATOR = ":";
178     private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
179
180     /*
181         getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the reference value.
182      */
183     public static BigInteger getCookieSnatFlow(long routerId) {
184         return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0110000", 16)).add(
185                 BigInteger.valueOf(routerId));
186     }
187
188     /*
189         getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the reference value.
190     */
191     public static BigInteger getCookieNaptFlow(long routerId) {
192         return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0111000", 16)).add(
193                 BigInteger.valueOf(routerId));
194     }
195
196     /*
197         getVpnId() returns the VPN ID from the VPN name
198      */
199     public static long getVpnId(DataBroker broker, String vpnName) {
200         if(vpnName == null) {
201             return NatConstants.INVALID_ID;
202         }
203
204         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> id
205                 = getVpnInstanceToVpnIdIdentifier(vpnName);
206         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> vpnInstance
207                 = read(broker, LogicalDatastoreType.CONFIGURATION, id);
208
209
210         long vpnId = NatConstants.INVALID_ID;
211         if(vpnInstance.isPresent()) {
212             Long vpnIdAsLong = vpnInstance.get().getVpnId();
213             if(vpnIdAsLong != null){
214                 vpnId = vpnIdAsLong;
215             }
216         }
217         return vpnId;
218     }
219
220     public static Long getVpnId(DataBroker broker, long routerId){
221         //Get the external network ID from the ExternalRouter model
222         Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
223         if(networkId == null ){
224             LOG.error("NAT Service : networkId is null");
225             return null;
226         }
227
228         //Get the VPN ID from the ExternalNetworks model
229         Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId);
230         if(vpnUuid == null ){
231             LOG.error("NAT Service : vpnUuid is null");
232             return null;
233         }
234         Long vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue());
235         return vpnId;
236     }
237
238     static InstanceIdentifier<RouterPorts> getRouterPortsId(String routerId) {
239         return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId)).build();
240     }
241
242     static InstanceIdentifier<Routermapping> getRouterVpnMappingId(String routerId) {
243         return InstanceIdentifier.builder(RouterToVpnMapping.class).child(Routermapping.class, new RoutermappingKey(routerId)).build();
244     }
245
246     static InstanceIdentifier<Ports> getPortsIdentifier(String routerId, String portName) {
247         return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
248                 .child(Ports.class, new PortsKey(portName)).build();
249     }
250
251     static InstanceIdentifier<IpMapping> getIpMappingIdentifier(String routerId, String portName, String internalIp) {
252         return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
253                 .child(Ports.class, new PortsKey(portName))
254                 .child(IpMapping.class, new IpMappingKey(internalIp)).build();
255     }
256
257     /*
258         getVpnInstanceToVpnIdIdentifier() returns the VPN instance from the below model using the VPN name as the key.
259             list vpn-instance {
260                 key "vpn-instance-name"
261                 leaf vpn-instance-name {
262                     type string;
263                 }
264                 leaf vpn-id {
265                     type uint32;
266                 }
267                 leaf vrf-id {
268                     type string;
269                 }
270             }
271     */
272
273     static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance>
274     getVpnInstanceToVpnIdIdentifier(String vpnName) {
275         return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
276                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance.class,
277                         new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
278     }
279
280     static String getVpnInstanceFromVpnIdentifier(DataBroker broker, long vpnId) {
281         InstanceIdentifier<VpnIds> id = InstanceIdentifier.builder(VpnIdToVpnInstance.class)
282                 .child(VpnIds.class, new VpnIdsKey(Long.valueOf(vpnId))).build();
283         Optional<VpnIds> vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id);
284         return vpnInstance.isPresent() ? vpnInstance.get().getVpnInstanceName() : null;
285     }
286
287     /*
288        getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference.
289     */
290     public static String getFlowRef(BigInteger dpnId, short tableId, long routerID, String ip) {
291         return new StringBuffer().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId).append(NatConstants.FLOWID_SEPARATOR).
292                 append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID)
293                 .append(NatConstants.FLOWID_SEPARATOR).append(ip).toString();
294     }
295
296     public static String getNaptFlowRef(BigInteger dpnId, short tableId, String routerID, String ip, int port) {
297         return new StringBuffer().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId).append(NatConstants.FLOWID_SEPARATOR).
298                 append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID).append(NatConstants.FLOWID_SEPARATOR).append(ip).
299                 append(NatConstants.FLOWID_SEPARATOR).append(port).toString();
300     }
301
302     /*
303         getNetworkIdFromRouterId() returns the network-id from the below model using the router-id as the key
304                container ext-routers {
305                    list routers {
306                        key router-name;
307                        leaf router-name { type string; }
308                        leaf network-id { type yang:uuid; }
309                        leaf enable-snat { type boolean; }
310                        leaf-list external-ips {
311                             type string; //format - ipaddress\prefixlength
312                        }
313                        leaf-list subnet-ids { type yang:uuid; }
314                    }
315                }
316
317     */
318     static Uuid getNetworkIdFromRouterId(DataBroker broker, long routerId) {
319         String routerName = getRouterName(broker, routerId);
320         InstanceIdentifier id = buildRouterIdentifier(routerName);
321         Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
322         if (routerData.isPresent()) {
323             return routerData.get().getNetworkId();
324         }
325         return null;
326     }
327
328     static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
329         InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class).child
330                 (Routers.class, new RoutersKey(routerId)).build();
331         return routerInstanceIndentifier;
332     }
333
334     /*
335      * getEnableSnatFromRouterId() returns IsSnatEnabled true is routerID is present in external n/w otherwise returns false
336      */
337     static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId){
338         InstanceIdentifier id = buildRouterIdentifier(routerId);
339         Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
340         if (routerData.isPresent()) {
341             return routerData.get().isEnableSnat();
342         }
343         return false;
344     }
345     /*
346         getVpnIdfromNetworkId() returns the vpnid from the below model using the network ID as the key.
347             container external-networks {
348                 list networks  {
349                     key id;
350                     leaf id {
351                         type yang:uuid;
352                     }
353                     leaf vpnid { type yang:uuid; }
354                     leaf-list router-ids { type yang:uuid; }
355                     leaf-list subnet-ids{ type yang:uuid; }
356                 }
357             }
358     */
359     public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
360         InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
361         Optional<Networks> networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
362         if (networkData.isPresent()) {
363             return networkData.get().getVpnid();
364         }
365         return null;
366     }
367
368     public static ProviderTypes getProviderTypefromNetworkId(DataBroker broker, Uuid networkId) {
369         InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
370         Optional<Networks> networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
371         if ((networkData.isPresent()) && (networkData.get() != null)) {
372             return networkData.get().getProviderNetworkType();
373         }
374         return null;
375     }
376
377     public static List<Uuid> getRouterIdsfromNetworkId(DataBroker broker, Uuid networkId) {
378         InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
379         Optional<Networks> networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
380         return networkData.isPresent() ? networkData.get().getRouterIds() : Collections.emptyList();
381     }
382
383     static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
384         InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
385         Optional<Routers> routerData = NatUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
386         if (routerData.isPresent()) {
387             Uuid networkId = routerData.get().getNetworkId();
388             if(networkId != null) {
389                 return networkId.getValue();
390             }
391         }
392         return null;
393     }
394
395     private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
396         InstanceIdentifier<Networks> network = InstanceIdentifier.builder(ExternalNetworks.class).child
397                 (Networks.class, new NetworksKey(networkId)).build();
398         return network;
399     }
400
401
402
403
404     /*
405         getNaptSwitchesDpnIdsfromRouterId() returns the primary-switch-id and the secondary-switch-id in a array using the router-id; as the key.
406             container napt-switches {
407                 list router-to-napt-switch {
408                     key router-id;
409                     leaf router-id { type uint32; }
410                     leaf primary-switch-id { type uint64; }
411                     leaf secondary-switch-id { type uint64; }
412                 }
413             }
414     */
415     public static BigInteger getPrimaryNaptfromRouterId(DataBroker broker, Long routerId) {
416         // convert routerId to Name
417         String routerName = getRouterName(broker, routerId);
418         InstanceIdentifier id = buildNaptSwitchIdentifier(routerName);
419         Optional<RouterToNaptSwitch> routerToNaptSwitchData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
420         if (routerToNaptSwitchData.isPresent()) {
421             RouterToNaptSwitch routerToNaptSwitchInstance = routerToNaptSwitchData.get();
422             return routerToNaptSwitchInstance.getPrimarySwitchId();
423         }
424         return null;
425     }
426
427     private static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
428         InstanceIdentifier<RouterToNaptSwitch> rtrNaptSw = InstanceIdentifier.builder(NaptSwitches.class).child
429                 (RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId)).build();
430         return rtrNaptSw;
431     }
432
433     public static String getRouterName(DataBroker broker, Long routerId) {
434         InstanceIdentifier id = buildRouterIdentifier(routerId);
435         Optional<RouterIds> routerIdsData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
436         if (routerIdsData.isPresent()) {
437             RouterIds routerIdsInstance = routerIdsData.get();
438             return routerIdsInstance.getRouterName();
439         }
440         return null;
441     }
442
443     private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Long routerId) {
444         InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class).child
445                 (RouterIds.class, new RouterIdsKey(routerId)).build();
446         return routerIds;
447     }
448
449     public static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
450                                                           InstanceIdentifier<T> path) {
451
452         ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
453
454         Optional<T> result = Optional.absent();
455         try {
456             result = tx.read(datastoreType, path).get();
457         } catch (Exception e) {
458             throw new RuntimeException(e);
459         }
460
461         return result;
462     }
463
464     static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
465         return InstanceIdentifier.builder(VpnInstanceOpData.class)
466                 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
467     }
468
469     public static long readVpnId(DataBroker broker, String vpnName) {
470
471         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> id
472                 = getVpnInstanceToVpnIdIdentifier(vpnName);
473         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> vpnInstance
474                 = read(broker, LogicalDatastoreType.CONFIGURATION, id);
475
476         long vpnId = NatConstants.INVALID_ID;
477         if(vpnInstance.isPresent()) {
478             vpnId = vpnInstance.get().getVpnId();
479         }
480         return vpnId;
481     }
482
483     public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie) {
484         FlowEntity flowEntity = new FlowEntity(dpnId);
485         flowEntity.setTableId(tableId);
486         flowEntity.setCookie(cookie);
487         return flowEntity;
488     }
489
490     public static long getIpAddress(byte[] rawIpAddress) {
491         return (((rawIpAddress[0] & 0xFF) << (3 * 8)) + ((rawIpAddress[1] & 0xFF) << (2 * 8))
492                 + ((rawIpAddress[2] & 0xFF) << (1 * 8)) + (rawIpAddress[3] & 0xFF)) & 0xffffffffL;
493     }
494
495     public static String getFlowRef(BigInteger dpnId, short tableId, InetAddress destPrefix) {
496         return new StringBuilder(64).append(NatConstants.FLOWID_PREFIX).append(dpnId).append(NwConstants.FLOWID_SEPARATOR)
497                 .append(tableId).append(NwConstants.FLOWID_SEPARATOR)
498                 .append(destPrefix.getHostAddress()).toString();
499     }
500
501     public static String getEndpointIpAddressForDPN(DataBroker broker, BigInteger dpnId) {
502         String nextHopIp = null;
503         InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
504                 InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build();
505         Optional<DPNTEPsInfo> tunnelInfo = read(broker, LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
506         if (tunnelInfo.isPresent()) {
507             List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
508             if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
509                 nextHopIp = nexthopIpList.get(0).getIpAddress().getIpv4Address().getValue();
510             }
511         }
512         return nextHopIp;
513     }
514
515     /*
516         getVpnRd returns the rd (route distinguisher) which is the VRF ID from the below model using the vpnName
517             list vpn-instance {
518                 key "vpn-instance-name"
519                 leaf vpn-instance-name {
520                     type string;
521                 }
522                 leaf vpn-id {
523                     type uint32;
524                 }
525                 leaf vrf-id {
526                     type string;
527                 }
528             }
529     */
530     public static String getVpnRd(DataBroker broker, String vpnName) {
531
532         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> id
533                 = getVpnInstanceToVpnIdIdentifier(vpnName);
534         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> vpnInstance
535                 = read(broker, LogicalDatastoreType.CONFIGURATION, id);
536
537         String rd = null;
538         if(vpnInstance.isPresent()) {
539             rd = vpnInstance.get().getVrfId();
540         }
541         return rd;
542     }
543
544     /*  getExternalIPPortMap() returns the internal IP and the port for the querried router ID, external IP and the port.
545         container intext-ip-port-map {
546         config true;
547         list ip-port-mapping {
548             key router-id;
549             leaf router-id { type uint32; }
550             list intext-ip-protocol-type {
551                 key protocol;
552                 leaf protocol { type protocol-types; }
553                 list ip-port-map {
554                     key ip-port-internal;
555                     description "internal to external ip-port mapping";
556                     leaf ip-port-internal { type string; }
557                     container ip-port-external {
558                        uses ip-port-entity;
559                     }
560                 }
561             }
562          }
563        }
564     */
565     public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress, String internalPort, NAPTEntryEvent.Protocol protocol) {
566         ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
567         InstanceIdentifier ipPortMapId = buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
568         Optional<IpPortMap> ipPortMapData = read(broker, LogicalDatastoreType.CONFIGURATION, ipPortMapId);
569         if (ipPortMapData.isPresent()) {
570             IpPortMap ipPortMapInstance = ipPortMapData.get();
571             return ipPortMapInstance.getIpPortExternal();
572         }
573         return null;
574     }
575
576     private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Long routerId, String internalIpAddress, String internalPort , ProtocolTypes protocolType) {
577         InstanceIdentifier<IpPortMap> ipPortMapId = InstanceIdentifier.builder(IntextIpPortMap.class).child
578                 (IpPortMapping.class, new IpPortMappingKey(routerId)).child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
579                 .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
580         return ipPortMapId;
581     }
582
583     public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId, int priority, String flowName,
584                                              BigInteger cookie, List<MatchInfo> listMatchInfo) {
585
586         FlowEntity flowEntity = new FlowEntity(dpnId);
587         flowEntity.setTableId(tableId);
588         flowEntity.setFlowId(flowId);
589         flowEntity.setPriority(priority);
590         flowEntity.setFlowName(flowName);
591         flowEntity.setCookie(cookie);
592         flowEntity.setMatchInfoList(listMatchInfo);
593         return flowEntity;
594     }
595
596     static boolean isVpnInterfaceConfigured(DataBroker broker, String interfaceName)
597     {
598         InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
599         Optional<VpnInterface> configuredVpnInterface = read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId);
600
601         if (configuredVpnInterface.isPresent()) {
602             return true;
603         }
604         return false;
605     }
606
607     static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
608         return InstanceIdentifier.builder(VpnInterfaces.class)
609                 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
610     }
611
612     static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) {
613         InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
614         Optional<VpnInterface> configuredVpnInterface = read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId);
615
616         if (configuredVpnInterface.isPresent()) {
617             return configuredVpnInterface.get();
618         }
619         return null;
620     }
621
622     public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
623         /*
624          * NodeConnectorId is of form 'openflow:dpnid:portnum'
625          */
626         String[] split = portId.getValue().split(OF_URI_SEPARATOR);
627         if (split == null || split.length != 3) {
628             return null;
629         }
630         return split[1];
631     }
632
633     public static BigInteger getDpIdFromInterface(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
634         String lowerLayerIf = ifState.getLowerLayerIf().get(0);
635         if (lowerLayerIf == null) {
636             return BigInteger.ZERO;
637         }
638         NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
639         String dpnFromNodeConnectorId = getDpnFromNodeConnectorId(nodeConnectorId);
640         if (dpnFromNodeConnectorId == null) {
641             return BigInteger.ZERO;
642         }
643         return new BigInteger(dpnFromNodeConnectorId);
644     }
645
646
647     /*
648     container vpnMaps {
649         list vpnMap {
650             key vpn-id;
651             leaf vpn-id {
652                 type    yang:uuid;
653                 description "vpn-id";
654             }
655             leaf name {
656                 type  string;
657                 description "vpn name";
658             }
659             leaf tenant-id {
660                 type    yang:uuid;
661                 description "The UUID of the tenant that will own the subnet.";
662             }
663
664             leaf router-id {
665               type    yang:uuid;
666               description "UUID of router ";
667             }
668             leaf-list network_ids {
669               type    yang:uuid;
670               description "UUID representing the network ";
671             }
672         }
673     }
674     Method returns router Id associated to a VPN
675      */
676
677     public static String getRouterIdfromVpnInstance(DataBroker broker,String vpnName){
678         InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
679                 .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build();
680         Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION,
681                 vpnMapIdentifier);
682         if (optionalVpnMap.isPresent()) {
683             Uuid routerId = optionalVpnMap.get().getRouterId();
684             if (routerId != null) {
685                 return routerId.getValue();
686             }
687         }
688         return null;
689     }
690
691     public static String getRouterIdfromVpnId(DataBroker broker, long vpnId){
692         String vpnName = getVpnInstanceFromVpnIdentifier(broker, vpnId);
693         if (vpnName == null) {
694             LOG.trace("No VPN instance found for vpn id {}", vpnId);
695             return null;
696         }
697
698         return getRouterIdfromVpnInstance(broker, vpnName);
699     }
700
701     static Uuid getVpnForRouter(DataBroker broker, String routerId) {
702         InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
703         Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION,
704                 vpnMapsIdentifier);
705         if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
706             List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
707             if (routerId != null) {
708                 for (VpnMap vpnMap : allMaps) {
709                     if (vpnMap.getRouterId() != null &&
710                             routerId.equals(vpnMap.getRouterId().getValue()) &&
711                             !routerId.equals(vpnMap.getVpnId().getValue())) {
712                         return vpnMap.getVpnId();
713                     }
714                 }
715             }
716         }
717         return null;
718     }
719
720     static long getAssociatedVpn(DataBroker broker, String routerName) {
721         InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
722         Optional<Routermapping> optRouterMapping = NatUtil.read(broker, LogicalDatastoreType.OPERATIONAL, routerMappingId);
723         if(optRouterMapping.isPresent()) {
724             Routermapping routerMapping = optRouterMapping.get();
725             return routerMapping.getVpnId();
726         }
727         return NatConstants.INVALID_ID;
728     }
729
730
731     public static List<VpnToDpnList> getVpnToDpnList(DataBroker dataBroker, String vrfId )
732     {
733         List<VpnToDpnList> vpnDpnList = null;
734
735         InstanceIdentifier<VpnInstanceOpDataEntry> id = InstanceIdentifier
736                 .builder(VpnInstanceOpData.class)
737                 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId))
738                 .build();
739
740         Optional<VpnInstanceOpDataEntry> vpnInstanceOpData = read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
741
742         if(vpnInstanceOpData.isPresent())
743         {
744             VpnInstanceOpDataEntry vpnInstanceOpDataEntry = vpnInstanceOpData.get();
745             vpnDpnList = vpnInstanceOpDataEntry.getVpnToDpnList();
746         }
747
748         return vpnDpnList;
749     }
750
751     public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId, Logger log) {
752         Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
753         if(vpnUuid == null ){
754             log.error("No VPN instance associated with ext network {}", networkId);
755             return null;
756         }
757         return vpnUuid.getValue();
758     }
759
760     public static void addPrefixToBGP(DataBroker broker,
761                                       IBgpManager bgpManager,
762                                       IFibManager fibManager,
763                                       String rd,
764                                       String prefix,
765                                       String nextHopIp,
766                                       long label,
767                                       Logger log,
768                                       RouteOrigin origin) {
769         try {
770             LOG.info("ADD: Adding Fib entry rd {} prefix {} nextHop {} label {}", rd, prefix, nextHopIp, label);
771             if (nextHopIp == null)
772             {
773                 log.error("addPrefix failed since nextHopIp cannot be null.");
774                 return;
775             }
776             fibManager.addOrUpdateFibEntry(broker, rd, prefix, Arrays.asList(nextHopIp), (int)label, origin, null);
777             bgpManager.advertisePrefix(rd, prefix, Arrays.asList(nextHopIp), (int)label);
778             LOG.info("ADD: Added Fib entry rd {} prefix {} nextHop {} label {}", rd, prefix, nextHopIp, label);
779         } catch(Exception e) {
780             log.error("Add prefix failed", e);
781         }
782     }
783
784     static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
785         InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class).child
786                 (RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
787         return ipPortMapId;
788     }
789
790     static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
791         InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class).child
792                 (RouterPorts.class, new RouterPortsKey(routerId)).build();
793         return routerInstanceIndentifier;
794     }
795
796     /* container snatint-ip-port-map {
797         list intip-port-map {
798             key router-id;
799             leaf router-id { type uint32; }
800             list ip-port {
801                 key internal-ip;
802                 leaf internal-ip { type string; }
803                 list int-ip-proto-type {
804                     key protocol;
805                     leaf protocol { type protocol-types; }
806                     leaf-list ports { type uint16; }
807                 }
808             }
809         }
810     }
811     Method returns InternalIp port List
812     */
813
814     public static List<Integer> getInternalIpPortListInfo(DataBroker dataBroker,Long routerId, String internalIpAddress, ProtocolTypes protocolType){
815         Optional<IntIpProtoType> optionalIpProtoType = read(dataBroker, LogicalDatastoreType.CONFIGURATION, buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType));
816         if (optionalIpProtoType.isPresent()) {
817             return optionalIpProtoType.get().getPorts();
818         }
819         return null;
820     }
821
822     public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Long routerId, String internalIpAddress, ProtocolTypes protocolType) {
823         InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId = InstanceIdentifier.builder(SnatintIpPortMap.class).child
824                 (IntipPortMap.class, new IntipPortMapKey(routerId)).child(IpPort.class, new IpPortKey(internalIpAddress)).child
825                 (IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
826         return intIpProtocolTypeId;
827     }
828
829     public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
830         ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString()) ? ProtocolTypes.TCP : ProtocolTypes.UDP;
831         return protocolType;
832     }
833
834     public static NaptSwitches getNaptSwitch(DataBroker broker) {
835         Optional<NaptSwitches> switchesOptional = read(broker, LogicalDatastoreType.CONFIGURATION, getNaptSwitchesIdentifier());
836         if(switchesOptional.isPresent()) {
837             return switchesOptional.get();
838         }
839         return null;
840     }
841
842     public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
843         return InstanceIdentifier.create(NaptSwitches.class);
844     }
845
846     public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
847         return InstanceIdentifier.create(NaptSwitches.class).child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
848     }
849
850     public static String toStringIpAddress(byte[] ipAddress, Logger log)
851     {
852         String ip = "";
853         if (ipAddress == null) {
854             return ip;
855         }
856
857         try {
858             ip = InetAddress.getByAddress(ipAddress).getHostAddress();
859         } catch(UnknownHostException e) {
860             log.error("NAT Service : Caught exception during toStringIpAddress()");
861         }
862
863         return ip;
864     }
865
866     public static String getGroupIdKey(String routerName){
867         String groupIdKey = new String("snatmiss." + routerName);
868         return groupIdKey;
869     }
870
871     public static long createGroupId(String groupIdKey,IdManagerService idManager) {
872         AllocateIdInput getIdInput = new AllocateIdInputBuilder()
873                 .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey)
874                 .build();
875         try {
876             Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
877             RpcResult<AllocateIdOutput> rpcResult = result.get();
878             return rpcResult.getResult().getIdValue();
879         } catch (NullPointerException | InterruptedException | ExecutionException e) {
880             LOG.trace("", e);
881         }
882         return 0;
883     }
884
885     public static void removePrefixFromBGP(DataBroker broker , IBgpManager bgpManager, IFibManager fibManager, String rd, String prefix, Logger log) {
886         try {
887             LOG.info("REMOVE: Removing Fib entry rd {} prefix {}", rd, prefix);
888             fibManager.removeFibEntry(broker, rd, prefix, null);
889             bgpManager.withdrawPrefix(rd, prefix);
890             LOG.info("REMOVE: Removed Fib entry rd {} prefix {}", rd, prefix);
891         } catch(Exception e) {
892             log.error("Delete prefix failed", e);
893         }
894     }
895
896     public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie, String flowId) {
897         FlowEntity flowEntity = new FlowEntity(dpnId);
898         flowEntity.setTableId(tableId);
899         flowEntity.setCookie(cookie);
900         flowEntity.setFlowId(flowId);
901         return flowEntity;
902     }
903
904     public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) {
905         FlowEntity flowEntity = new FlowEntity(dpnId);
906         flowEntity.setTableId(tableId);
907         flowEntity.setFlowId(flowId);
908         return flowEntity;
909     }
910
911     public static IpPortMapping getIportMapping(DataBroker broker, long routerId) {
912         Optional<IpPortMapping> getIportMappingData = read(broker, LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId));
913         if(getIportMappingData.isPresent()) {
914             return getIportMappingData.get();
915         }
916         return null;
917     }
918
919     public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(long routerId) {
920         return InstanceIdentifier.builder(IntextIpPortMap.class).child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
921     }
922
923     public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Long routerId) {
924         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping> idBuilder = InstanceIdentifier.builder(IntextIpMap.class)
925                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMappingKey(routerId)).build();
926         return idBuilder;
927     }
928
929     public static List<String> getExternalIpsForRouter(DataBroker dataBroker,Long routerId) {
930         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping> ipMappingOptional = read(dataBroker,
931                 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
932         List<String> externalIps = new ArrayList<>();
933         if (ipMappingOptional.isPresent()) {
934             List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
935             for (IpMap ipMap : ipMaps) {
936                 externalIps.add(ipMap.getExternalIp());
937             }
938             //remove duplicates
939             Set<String> uniqueExternalIps = Sets.newHashSet(externalIps);
940             externalIps = Lists.newArrayList(uniqueExternalIps);
941             return externalIps;
942         }
943         return null;
944     }
945
946     public static HashMap<String,Long> getExternalIpsLabelForRouter(DataBroker dataBroker,Long routerId) {
947         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping> ipMappingOptional = read(dataBroker,
948                 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
949         HashMap<String,Long> externalIpsLabel = new HashMap<>();
950         if (ipMappingOptional.isPresent()) {
951             List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
952             for (IpMap ipMap : ipMaps) {
953                 externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel());
954             }
955             return externalIpsLabel;
956         }
957         return null;
958     }
959     /*
960     container external-ips-counter {
961         config false;
962         list external-counters{
963             key segment-id;
964             leaf segment-id { type uint32; }
965             list external-ip-counter {
966                 key external-ip;
967                 leaf external-ip { type string; }
968                 leaf counter { type uint8; }
969             }
970         }
971     }
972     */
973
974     public static String getLeastLoadedExternalIp(DataBroker dataBroker, long segmentId){
975         String leastLoadedExternalIp =  null;
976         InstanceIdentifier<ExternalCounters> id = InstanceIdentifier.builder(ExternalIpsCounter.class).child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
977         Optional <ExternalCounters> externalCountersData = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
978         if (externalCountersData.isPresent()) {
979             ExternalCounters externalCounter = externalCountersData.get();
980             List<ExternalIpCounter> externalIpCounterList = externalCounter.getExternalIpCounter();
981             short countOfLstLoadExtIp = 32767;
982             for(ExternalIpCounter externalIpCounter : externalIpCounterList){
983                 String curExternalIp = externalIpCounter.getExternalIp();
984                 short countOfCurExtIp  = externalIpCounter.getCounter();
985                 if( countOfCurExtIp < countOfLstLoadExtIp ){
986                     countOfLstLoadExtIp = countOfCurExtIp;
987                     leastLoadedExternalIp = curExternalIp;
988                 }
989             }
990         }
991         return leastLoadedExternalIp;
992     }
993
994     public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId){
995         String subnetIP = getSubnetIp(dataBroker, subnetId);
996         if(subnetId != null){
997             return getSubnetIpAndPrefix(subnetIP);
998         }
999         return null;
1000     }
1001
1002     public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId){
1003         InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
1004                 .builder(Subnetmaps.class)
1005                 .child(Subnetmap.class, new SubnetmapKey(subnetId))
1006                 .build();
1007         Optional<Subnetmap> removedSubnet = read(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetmapId);
1008         if(removedSubnet.isPresent()) {
1009             Subnetmap subnetMapEntry = removedSubnet.get();
1010             return subnetMapEntry.getSubnetIp();
1011         }
1012         return null;
1013
1014     }
1015     public static String[] getSubnetIpAndPrefix(String subnetString){
1016         String[] subnetSplit = subnetString.split("/");
1017         String subnetIp = subnetSplit[0];
1018         String subnetPrefix = "0";
1019         if (subnetSplit.length == 2) {
1020             subnetPrefix = subnetSplit[1];
1021         }
1022         return new String[] {subnetIp, subnetPrefix};
1023     }
1024
1025     public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr){
1026         String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
1027         String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
1028         String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
1029         if (leastLoadedExtIpAddrSplit.length == 2) {
1030             leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
1031         }
1032         return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
1033     }
1034
1035     public static List<BigInteger> getDpnsForRouter(DataBroker dataBroker, String routerUuid){
1036         InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class).child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
1037         Optional<RouterDpnList> routerDpnListData = read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1038         List<BigInteger> dpns = new ArrayList<>();
1039         if (routerDpnListData.isPresent()) {
1040             List<DpnVpninterfacesList> dpnVpninterfacesList = routerDpnListData.get().getDpnVpninterfacesList();
1041             for (DpnVpninterfacesList dpnVpnInterface : dpnVpninterfacesList) {
1042                 dpns.add(dpnVpnInterface.getDpnId());
1043             }
1044             return dpns;
1045         }
1046         return null;
1047     }
1048
1049     public static long getBgpVpnId(DataBroker dataBroker, String routerName){
1050         long bgpVpnId = NatConstants.INVALID_ID;
1051         Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
1052         if(bgpVpnUuid != null){
1053             bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
1054         }
1055         return bgpVpnId;
1056     }
1057
1058     static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces.RouterInterface
1059     getConfiguredRouterInterface(DataBroker broker, String interfaceName) {
1060         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces.RouterInterface> optRouterInterface =
1061                 read(broker, LogicalDatastoreType.CONFIGURATION, NatUtil
1062                 .getRouterInterfaceId(interfaceName));
1063         if(optRouterInterface.isPresent()) {
1064             return optRouterInterface.get();
1065         }
1066         return null;
1067     }
1068
1069     static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces.RouterInterface>
1070     getRouterInterfaceId(String interfaceName) {
1071         return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RouterInterfaces.class)
1072                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces.RouterInterface.class,
1073                         new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces.RouterInterfaceKey(interfaceName)).build();
1074     }
1075
1076     static void addToNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
1077                                      OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1078         BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, interfaceName);
1079         if(dpId.equals(BigInteger.ZERO)) {
1080             LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} association model", interfaceName, routerName);
1081             return;
1082         }
1083
1084         LOG.debug("NAT Service : Adding the Router {} and DPN {} for the Interface {} in the ODL-L3VPN : NeutronRouterDpn map",
1085                 routerName, dpId, interfaceName);
1086         InstanceIdentifier<DpnVpninterfacesList> dpnVpnInterfacesListIdentifier = getRouterDpnId(routerName, dpId);
1087
1088         Optional<DpnVpninterfacesList> optionalDpnVpninterfacesList = read(broker, LogicalDatastoreType
1089                 .OPERATIONAL, dpnVpnInterfacesListIdentifier);
1090         org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1091                 new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(interfaceName)).setInterface(interfaceName).build();
1092         if (optionalDpnVpninterfacesList.isPresent()) {
1093             LOG.debug("NAT Service : RouterDpnList already present for the Router {} and DPN {} for the Interface {} in the " +
1094                     "ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1095             writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL, dpnVpnInterfacesListIdentifier.child(
1096                     org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class, new RouterInterfacesKey(interfaceName)), routerInterface, true);
1097         } else {
1098             LOG.debug("NAT Service : Building new RouterDpnList for the Router {} and DPN {} for the Interface {} in the " +
1099                     "ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1100             RouterDpnListBuilder routerDpnListBuilder = new RouterDpnListBuilder();
1101             routerDpnListBuilder.setRouterId(routerName);
1102             DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId);
1103             List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =  new ArrayList<>();
1104             routerInterfaces.add(routerInterface);
1105             dpnVpnList.setRouterInterfaces(routerInterfaces);
1106             routerDpnListBuilder.setDpnVpninterfacesList(Arrays.asList(dpnVpnList.build()));
1107             writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1108                     getRouterId(routerName),
1109                     routerDpnListBuilder.build(), true);
1110         }
1111     }
1112
1113     static void addToDpnRoutersMap(DataBroker broker, String routerName, String interfaceName,
1114                                           OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1115         BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, interfaceName);
1116         if(dpId.equals(BigInteger.ZERO)) {
1117             LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} association model", interfaceName, routerName);
1118             return;
1119         }
1120
1121         LOG.debug("NAT Service : Adding the DPN {} and router {} for the Interface {} in the ODL-L3VPN : " +
1122                         "DPNRouters map",
1123                 dpId, routerName, interfaceName);
1124         InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(dpId);
1125
1126         Optional<DpnRoutersList> optionalDpnRoutersList = read(broker, LogicalDatastoreType.OPERATIONAL, dpnRoutersListIdentifier);
1127
1128         if (optionalDpnRoutersList.isPresent()) {
1129             RoutersList routersList = new RoutersListBuilder().setKey(new RoutersListKey(routerName)).setRouter(routerName)
1130                     .build();
1131             List<RoutersList> routersListFromDs = optionalDpnRoutersList.get().getRoutersList();
1132             if(!routersListFromDs.contains(routersList)) {
1133                 LOG.debug("NAT Service : Router {} not present for the DPN {}" +
1134                         " in the ODL-L3VPN : DPNRouters map", routerName, dpId);
1135                 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL, dpnRoutersListIdentifier.child(RoutersList.class, new
1136                         RoutersListKey(routerName)), routersList, true);
1137             }else{
1138                 LOG.debug("NAT Service : Router {} already mapped to the DPN {} in the ODL-L3VPN : DPNRouters map",
1139                         routerName, dpId);
1140             }
1141         } else {
1142             LOG.debug("NAT Service : Building new DPNRoutersList for the Router {} present in the DPN {} " +
1143                     "ODL-L3VPN : DPNRouters map", routerName, dpId);
1144             DpnRoutersListBuilder dpnRoutersListBuilder = new DpnRoutersListBuilder();
1145             dpnRoutersListBuilder.setDpnId(dpId);
1146             RoutersListBuilder routersListBuilder = new RoutersListBuilder();
1147             routersListBuilder.setRouter(routerName);
1148             dpnRoutersListBuilder.setRoutersList(Arrays.asList(routersListBuilder.build()));
1149             writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1150                     getDpnRoutersId(dpId),
1151                     dpnRoutersListBuilder.build(), true);
1152         }
1153     }
1154
1155     static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
1156                                                   BigInteger dpId, WriteTransaction writeOperTxn) {
1157         if(dpId.equals(BigInteger.ZERO)) {
1158             LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} dissociation model", interfaceName, routerName);
1159             return;
1160         }
1161         InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1162         Optional<DpnVpninterfacesList> optionalRouterDpnList = NatUtil.read(broker, LogicalDatastoreType
1163                 .OPERATIONAL, routerDpnListIdentifier);
1164         if (optionalRouterDpnList.isPresent()) {
1165             List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = optionalRouterDpnList.get().getRouterInterfaces();
1166             org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface = new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(interfaceName)).setInterface(interfaceName).build();
1167             if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1168                 if (routerInterfaces.isEmpty()) {
1169                     writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1170                 } else {
1171                     writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1172                             org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1173                             new RouterInterfacesKey(interfaceName)));
1174                 }
1175             }
1176         }
1177     }
1178
1179     static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName,
1180                                                BigInteger dpId, WriteTransaction writeOperTxn) {
1181         if(dpId.equals(BigInteger.ZERO)) {
1182             LOG.warn("NAT Service : DPN ID is invalid for the router {} ", routerName);
1183             return;
1184         }
1185
1186         InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1187         Optional<DpnVpninterfacesList> optionalRouterDpnList = NatUtil.read(broker, LogicalDatastoreType
1188                 .OPERATIONAL, routerDpnListIdentifier);
1189         if (optionalRouterDpnList.isPresent()) {
1190             LOG.debug("NAT Service : Removing the dpn-vpninterfaces-list from the odl-l3vpn:neutron-router-dpns model " +
1191                             "for the router {}", routerName);
1192             writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1193         }else{
1194             LOG.debug("NAT Service : dpn-vpninterfaces-list does not exist in the odl-l3vpn:neutron-router-dpns model " +
1195                     "for the router {}", routerName);
1196         }
1197     }
1198
1199     static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName, String vpnInterfaceName,
1200                                                   OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1201         BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
1202         if(dpId.equals(BigInteger.ZERO)) {
1203             LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} dissociation model", vpnInterfaceName, routerName);
1204             return;
1205         }
1206         InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1207         Optional<DpnVpninterfacesList> optionalRouterDpnList = read(broker, LogicalDatastoreType
1208                 .OPERATIONAL, routerDpnListIdentifier);
1209         if (optionalRouterDpnList.isPresent()) {
1210             List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = optionalRouterDpnList.get().getRouterInterfaces();
1211             org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface = new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(vpnInterfaceName)).setInterface(vpnInterfaceName).build();
1212
1213             if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1214                 if (routerInterfaces.isEmpty()) {
1215                     if (writeOperTxn != null) {
1216                         writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1217                     } else {
1218                         MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1219                     }
1220                 } else {
1221                     if (writeOperTxn != null) {
1222                         writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1223                                 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1224                                 new RouterInterfacesKey(vpnInterfaceName)));
1225                     } else {
1226                         MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1227                                 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1228                                 new RouterInterfacesKey(vpnInterfaceName)));
1229                     }
1230                 }
1231             }
1232         }
1233     }
1234
1235     static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1236                                         OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1237         BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
1238         if (dpId.equals(BigInteger.ZERO)) {
1239             LOG.warn("NAT Service : removeFromDpnRoutersMap() : Could not retrieve DPN ID for interface {} to handle router {} dissociation model",
1240                     vpnInterfaceName, routerName);
1241             return;
1242         }
1243         removeFromDpnRoutersMap(broker, routerName, vpnInterfaceName, dpId, ifaceMgrRpcService, writeOperTxn);
1244     }
1245
1246     static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName, BigInteger curDpnId,
1247                                            OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1248         /*
1249             1) Get the DpnRoutersList for the DPN.
1250             2) Get the RoutersList identifier for the DPN and router.
1251             3) Get the VPN interfaces for the router (routerList) through which it is connected to the DPN.
1252             4) If the removed VPN interface is the only interface through which the router is connected to the DPN,
1253              then remove RouterList.
1254          */
1255
1256         LOG.debug("NAT Service : removeFromDpnRoutersMap() : Removing the DPN {} and router {} for the Interface {}" +
1257                 " in the ODL-L3VPN : DPNRouters map", curDpnId, routerName, vpnInterfaceName);
1258
1259         //Get the dpn-routers-list instance for the current DPN.
1260         InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(curDpnId);
1261         Optional<DpnRoutersList> dpnRoutersListData = read(broker, LogicalDatastoreType.OPERATIONAL,
1262                 dpnRoutersListIdentifier);
1263
1264         if (dpnRoutersListData == null || !dpnRoutersListData.isPresent()) {
1265             LOG.debug("NAT Service : dpn-routers-list is not present for DPN {} in the ODL-L3VPN:dpn-routers model",
1266                     curDpnId);
1267             return;
1268         }
1269
1270         //Get the routers-list instance for the router on the current DPN only
1271         InstanceIdentifier<RoutersList> routersListIdentifier = getRoutersList(curDpnId, routerName);
1272         Optional<RoutersList> routersListData = read(broker, LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1273
1274         if (routersListData == null || !routersListData.isPresent()) {
1275             LOG.debug("NAT Service : routers-list is not present for the DPN {} in the ODL-L3VPN:dpn-routers model",
1276                     curDpnId);
1277             return;
1278         }
1279
1280         LOG.debug("NAT Service : Get the interfaces for the router {} from the NeutronVPN - router-interfaces-map",
1281                 routerName);
1282         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.
1283                 interfaces.map.RouterInterfaces> routerInterfacesId = getRoutersInterfacesIdentifier(routerName);
1284         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.
1285                 RouterInterfaces> routerInterfacesData = read(broker, LogicalDatastoreType.CONFIGURATION,
1286                 routerInterfacesId);
1287
1288         if (routerInterfacesData == null || !routerInterfacesData.isPresent()) {
1289             LOG.debug("NAT Service : Unable to get the routers list for the DPN {}. Possibly all subnets removed" +
1290                     " from router {} OR Router {} has been deleted. Hence DPN router model WILL be cleared ", curDpnId,
1291                     routerName, routerName);
1292             writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1293             return;
1294         }
1295
1296         //Get the VM interfaces for the router on the current DPN only.
1297         List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.Interfaces> vmInterfaces =
1298                 routerInterfacesData.get().getInterfaces();
1299         if (vmInterfaces == null) {
1300             LOG.debug("NAT Service : VM interfaces are not present for the router {} in the NeutronVPN - router-interfaces-map", routerName);
1301             return;
1302         }
1303
1304         //If the removed VPN interface is the only interface through which the router is connected to the DPN, then remove RouterList.
1305         for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.Interfaces vmInterface :
1306                 vmInterfaces) {
1307             String vmInterfaceName = vmInterface.getInterfaceId();
1308             BigInteger vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName);
1309             if (vmDpnId.equals(BigInteger.ZERO) || !vmDpnId.equals(curDpnId)) {
1310                 LOG.debug("NAT Service : DPN ID {} for the removed interface {} is not the same as that of the DPN ID for the checked interface {} ",
1311                         curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName);
1312                 continue;
1313             }
1314             if(!vmInterfaceName.equalsIgnoreCase(vpnInterfaceName)) {
1315                 LOG.debug("NAT Service : Router {} is present in the DPN {} through the other interface {} " +
1316                         "Hence DPN router model WOULD NOT be cleared", routerName, curDpnId, vmInterfaceName);
1317                 return;
1318             }
1319         }
1320         LOG.debug("NAT Service : Router {} is present in the DPN {} only through the interface {} " +
1321                 "Hence DPN router model WILL be cleared. Possibly last VM for the router " +
1322                 "deleted in the DPN", routerName, curDpnId);
1323         writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1324
1325     }
1326
1327     private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfaces>
1328         getRoutersInterfacesIdentifier(String routerName){
1329         return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterInterfacesMap.class)
1330                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfaces.class,
1331                         new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfacesKey(new Uuid(routerName)))
1332                 .build();
1333     }
1334
1335     private static InstanceIdentifier<RoutersList> getRoutersList(BigInteger dpnId, String routerName) {
1336         return InstanceIdentifier.builder(DpnRouters.class)
1337                 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId))
1338                 .child(RoutersList.class, new RoutersListKey(routerName)).build();
1339     }
1340
1341     public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
1342         BigInteger nodeId = BigInteger.ZERO;
1343         try {
1344             GetDpidFromInterfaceInput
1345                     dpIdInput =
1346                     new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
1347             Future<RpcResult<GetDpidFromInterfaceOutput>>
1348                     dpIdOutput =
1349                     interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
1350             RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
1351             if (dpIdResult.isSuccessful()) {
1352                 nodeId = dpIdResult.getResult().getDpid();
1353             } else {
1354                 LOG.error("NAT Service : Could not retrieve DPN Id for interface {}", ifName);
1355             }
1356         } catch (NullPointerException | InterruptedException | ExecutionException e) {
1357             LOG.error("NAT Service : Exception when getting dpn for interface {}", ifName,  e);
1358         }
1359         return nodeId;
1360     }
1361
1362     public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService interfaceManager, String ifName,
1363             Long tunnelKey) {
1364         return getEgressActionsForInterface(interfaceManager, ifName, tunnelKey, 0);
1365     }
1366
1367     public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService interfaceManager, String ifName,
1368             Long tunnelKey, int pos) {
1369         LOG.debug("NAT Service : getEgressActionsForInterface called for interface {}", ifName);
1370         GetEgressActionsForInterfaceInputBuilder egressActionsBuilder = new GetEgressActionsForInterfaceInputBuilder()
1371                 .setIntfName(ifName);
1372         if (tunnelKey != null) {
1373             egressActionsBuilder.setTunnelKey(tunnelKey);
1374         }
1375
1376         List<ActionInfo> listActionInfo = new ArrayList<>();
1377         try {
1378             Future<RpcResult<GetEgressActionsForInterfaceOutput>> result = interfaceManager
1379                     .getEgressActionsForInterface(egressActionsBuilder.build());
1380             RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
1381             if (!rpcResult.isSuccessful()) {
1382                 LOG.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", ifName,
1383                         rpcResult.getErrors());
1384             } else {
1385                 List<Action> actions = rpcResult.getResult().getAction();
1386                 for (Action action : actions) {
1387                     org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionClass = action
1388                             .getAction();
1389                     if (actionClass instanceof OutputActionCase) {
1390                         listActionInfo
1391                                 .add(new ActionInfo(ActionType.output, new String[] { ((OutputActionCase) actionClass)
1392                                         .getOutputAction().getOutputNodeConnector().getValue() }, pos++));
1393                     } else if (actionClass instanceof PushVlanActionCase) {
1394                         listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] {}, pos++));
1395                     } else if (actionClass instanceof SetFieldCase) {
1396                         if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
1397                             int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId()
1398                                     .getVlanId().getValue();
1399                             listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid,
1400                                     new String[] { Long.toString(vlanVid) }, pos++));
1401                         }
1402                     } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
1403                         Short tableId = ((NxActionResubmitRpcAddGroupCase)actionClass).getNxResubmit().getTable();
1404                         listActionInfo.add(new ActionInfo(ActionType.nx_resubmit,
1405                             new String[] { tableId.toString() }, pos++));
1406                     } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
1407                         NxRegLoad nxRegLoad =
1408                             ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase)actionClass).getNxRegLoad();
1409                         listActionInfo.add(new ActionInfo(ActionType.nx_load_reg_6,
1410                             new String[] { nxRegLoad.getDst().getStart().toString(),
1411                                 nxRegLoad.getDst().getEnd().toString(),
1412                                 nxRegLoad.getValue().toString(10)}, pos++));
1413                     }
1414                 }
1415             }
1416         } catch (InterruptedException | ExecutionException e) {
1417             LOG.warn("Exception when egress actions for interface {}", ifName, e);
1418         }
1419         return listActionInfo;
1420     }
1421
1422     public static Port getNeutronPortForFloatingIp(DataBroker broker, IpAddress targetIP) {
1423         return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_FLOATING_IP);
1424     }
1425
1426     public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) {
1427         return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
1428     }
1429
1430     public static List<Port> getNeutronPorts(DataBroker broker) {
1431         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1432         portsIdentifier = InstanceIdentifier
1433                 .create(Neutron.class)
1434                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class);
1435         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports> portsOptional = read(
1436                 broker, LogicalDatastoreType.CONFIGURATION, portsIdentifier);
1437
1438         if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) {
1439             LOG.trace("No neutron ports found");
1440             return Collections.EMPTY_LIST;
1441         }
1442
1443         return portsOptional.get().getPort();
1444
1445     }
1446
1447     public static Port getNeutronPortForIp(DataBroker broker,
1448         IpAddress targetIP, String deviceType) {
1449         List<Port> ports = getNeutronPorts(
1450                 broker);
1451
1452         for (Port port : ports) {
1453             if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) {
1454                 for (FixedIps ip : port.getFixedIps()) {
1455                     if (Objects.equals(ip.getIpAddress(), targetIP)) {
1456                         return port;
1457                     }
1458                 }
1459             }
1460         }
1461
1462         return null;
1463     }
1464
1465     public static Uuid getSubnetIdForFloatingIp(Port port,
1466             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress targetIP) {
1467         if (port == null) {
1468             return null;
1469         }
1470
1471         for (FixedIps ip : port.getFixedIps()) {
1472             if (Objects.equals(ip.getIpAddress(), targetIP)) {
1473                 return ip.getSubnetId();
1474             }
1475         }
1476
1477         return null;
1478     }
1479
1480     public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) {
1481         InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
1482                 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1483         Optional<Subnetmap> subnetOpt = read(broker, LogicalDatastoreType.CONFIGURATION, subnetmapId);
1484         return subnetOpt.isPresent() ? subnetOpt.get() : null;
1485     }
1486
1487     public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
1488         InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
1489                 .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
1490         Optional<NetworkMap> optionalNetworkMap = read(broker, LogicalDatastoreType.CONFIGURATION, id);
1491         return optionalNetworkMap.isPresent() ? optionalNetworkMap.get().getSubnetIdList() : null;
1492     }
1493
1494     public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) {
1495         if (subnetId == null) {
1496             return null;
1497         }
1498
1499         InstanceIdentifier<Subnet> subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class)
1500                 .child(Subnet.class, new SubnetKey(subnetId));
1501         Optional<Subnet> subnetOpt = read(broker, LogicalDatastoreType.CONFIGURATION, subnetInst);
1502         if (!subnetOpt.isPresent()) {
1503             return null;
1504         }
1505
1506         IpAddress gatewayIp = subnetOpt.get().getGatewayIp();
1507         if (gatewayIp == null) {
1508             LOG.trace("No GW ip found for subnet {}", subnetId.getValue());
1509             return null;
1510         }
1511
1512         InstanceIdentifier<VpnPortipToPort> portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
1513                 .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1514                 .build();
1515         Optional<VpnPortipToPort> portIpToPortOpt = read(broker, LogicalDatastoreType.OPERATIONAL, portIpInst);
1516         if (!portIpToPortOpt.isPresent()) {
1517             LOG.trace("No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue());
1518             return null;
1519         }
1520
1521         return portIpToPortOpt.get().getMacAddress();
1522     }
1523
1524     public static Set<RouterDpnList> getAllRouterDpnList(DataBroker broker, BigInteger dpid) {
1525         Set<RouterDpnList> ret = new HashSet<>();
1526         InstanceIdentifier<NeutronRouterDpns> routerDpnId = InstanceIdentifier.create(NeutronRouterDpns.class);
1527         Optional<NeutronRouterDpns> neutronRouterDpnsOpt = MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
1528                 routerDpnId);
1529         if (neutronRouterDpnsOpt.isPresent()) {
1530             NeutronRouterDpns neutronRouterDpns = neutronRouterDpnsOpt.get();
1531             List<RouterDpnList> routerDpnLists = neutronRouterDpns.getRouterDpnList();
1532             for (RouterDpnList routerDpnList : routerDpnLists) {
1533                 if (routerDpnList.getDpnVpninterfacesList() != null) {
1534                     for (DpnVpninterfacesList dpnInterfaceList : routerDpnList.getDpnVpninterfacesList()) {
1535                         if (dpnInterfaceList.getDpnId().equals(dpid)) {
1536                             ret.add(routerDpnList);
1537                         }
1538                     }
1539                 }
1540             }
1541         }
1542         return ret;
1543     }
1544
1545     public static boolean isIPv6Subnet(String prefix) {
1546         IpPrefix ipPrefix = new IpPrefix(prefix.toCharArray());
1547         if (ipPrefix.getIpv6Prefix() != null) {
1548             return true;
1549         }
1550         return false;
1551     }
1552
1553     static InstanceIdentifier<DpnRoutersList> getDpnRoutersId(BigInteger dpnId) {
1554         return InstanceIdentifier.builder(DpnRouters.class)
1555                 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build();
1556     }
1557
1558     static InstanceIdentifier<DpnVpninterfacesList> getRouterDpnId(String routerName, BigInteger dpnId) {
1559         return InstanceIdentifier.builder(NeutronRouterDpns.class)
1560                 .child(RouterDpnList.class, new RouterDpnListKey(routerName))
1561                 .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build();
1562     }
1563
1564     static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface getInterface(DataBroker broker, String interfaceName) {
1565         Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface> optInterface =
1566                 read(broker, LogicalDatastoreType.CONFIGURATION, getInterfaceIdentifier(interfaceName));
1567         if(optInterface.isPresent()) {
1568             return optInterface.get();
1569         }
1570         return null;
1571     }
1572
1573     static InstanceIdentifier<RouterDpnList> getRouterId(String routerName) {
1574         return InstanceIdentifier.builder(NeutronRouterDpns.class)
1575                 .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build();
1576     }
1577
1578     static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface> getInterfaceIdentifier(String interfaceName) {
1579         return InstanceIdentifier.builder(Interfaces.class)
1580                 .child(
1581                         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface.class, new InterfaceKey(interfaceName)).build();
1582     }
1583     static final FutureCallback<Void> DEFAULT_CALLBACK =
1584             new FutureCallback<Void>() {
1585                 @Override
1586                 public void onSuccess(Void result) {
1587                     LOG.debug("NAT Service : Success in Datastore operation");
1588                 }
1589
1590                 @Override
1591                 public void onFailure(Throwable error) {
1592                     LOG.error("NAT Service : Error in Datastore operation", error);
1593                 }
1594
1595                 ;
1596             };
1597
1598     static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType,
1599                                                      InstanceIdentifier<T> path) {
1600         delete(broker, datastoreType, path, DEFAULT_CALLBACK);
1601     }
1602
1603    static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType,
1604                                                      InstanceIdentifier<T> path, FutureCallback<Void> callback) {
1605         WriteTransaction tx = broker.newWriteOnlyTransaction();
1606         tx.delete(datastoreType, path);
1607         Futures.addCallback(tx.submit(), callback);
1608     }
1609     static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
1610         InstanceIdentifier<Interface> ifStateId =
1611                 buildStateInterfaceId(interfaceName);
1612         Optional<Interface> ifStateOptional = read(dataBroker, LogicalDatastoreType.OPERATIONAL, ifStateId);
1613         if (ifStateOptional.isPresent()) {
1614             return ifStateOptional.get();
1615         }
1616
1617         return null;
1618     }
1619
1620     static InstanceIdentifier<Interface>
1621     buildStateInterfaceId(String interfaceName) {
1622         InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
1623                 InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState.class)
1624                         .child(Interface.class,
1625                                 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName));
1626         InstanceIdentifier<Interface> id = idBuilder.build();
1627         return id;
1628     }
1629 }