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