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