refactoring to support delete\update of servics.
[unimgr.git] / netvirt / src / main / java / org / opendaylight / unimgr / mef / netvirt / NetvirtVpnUtils.java
1 /*
2  * Copyright (c) 2016 Hewlett Packard Enterprise, Co. 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.unimgr.mef.netvirt;
10
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.List;
14 import java.util.UUID;
15
16 import org.apache.commons.net.util.SubnetUtils;
17 import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
20 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.genius.mdsalutil.MDSALUtil;
23 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
24 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
25 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargetsBuilder;
26 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTarget;
27 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
28 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceBuilder;
29 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
30 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.vpn.instance.Ipv4FamilyBuilder;
31 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
32 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;
33 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.OdlArputilService;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.SendArpRequestInput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.SendArpRequestInputBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.interfaces.InterfaceAddress;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.interfaces.InterfaceAddressBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.SubnetAddedToVpnBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.SubnetDeletedFromVpnBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
65 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
66 import org.slf4j.Logger;
67 import org.slf4j.LoggerFactory;
68 import com.google.common.base.Optional;
69
70 public class NetvirtVpnUtils {
71     private static final Logger logger = LoggerFactory.getLogger(NetvirtVpnUtils.class);
72     private final static String ELAN_PREFIX = "elan.";
73     private final static String IP_ADDR_SUFFIX = "/32";
74     private final static String IP_MUSK_SEPARATOR = "/";
75
76     public static void createVpnInstance(DataBroker dataBroker, String instanceName) {
77         WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
78         createVpnInstance(instanceName, tx);
79         MdsalUtils.commitTransaction(tx);
80     }
81
82     public static void createVpnInstance(String instanceName, WriteTransaction tx) {
83         VpnInstanceBuilder builder = new VpnInstanceBuilder();
84         builder.setVpnInstanceName(instanceName);
85         Ipv4FamilyBuilder ipv4FamilyBuilder = new Ipv4FamilyBuilder();
86         VpnTargetsBuilder vpnTargetsB = new VpnTargetsBuilder();
87         vpnTargetsB.setVpnTarget(new ArrayList<VpnTarget>());
88         ipv4FamilyBuilder.setVpnTargets(vpnTargetsB.build());
89
90         // WA till netvirt will allow creation of VPN without RD
91         UUID vpnId = UUID.fromString(instanceName);
92         String rd = String.valueOf(Math.abs(vpnId.getLeastSignificantBits()));
93         ipv4FamilyBuilder.setRouteDistinguisher(rd);
94         builder.setIpv4Family(ipv4FamilyBuilder.build());
95
96         tx.put(LogicalDatastoreType.CONFIGURATION, getVpnInstanceInstanceIdentifier(instanceName), builder.build());
97     }
98
99     public static void removeVpnInstance(String instanceName, WriteTransaction tx) {
100         tx.delete(LogicalDatastoreType.CONFIGURATION, getVpnInstanceInstanceIdentifier(instanceName));
101     }
102
103     private static InstanceIdentifier<VpnInstance> getVpnInstanceInstanceIdentifier(String instanceName) {
104         return InstanceIdentifier.builder(VpnInstances.class).child(VpnInstance.class, new VpnInstanceKey(instanceName))
105                 .build();
106     }
107
108     public static void createUpdateVpnInterface(DataBroker dataBroker, String vpnName, String interfaceName,
109             String ifAddr, String macAddress, boolean primary, String gwIpAddress) {
110         WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
111         createUpdateVpnInterface(vpnName, interfaceName, ifAddr, macAddress, primary, gwIpAddress, tx);
112         MdsalUtils.commitTransaction(tx);
113     }
114
115     public static void createUpdateVpnInterface(String vpnName, String interfaceName, IpPrefix ifPrefix,
116             String macAddress, boolean primary, IpPrefix gwIpAddress, WriteTransaction tx) {
117         synchronized (interfaceName.intern()) {
118             String ipAddress = null;
119             String nextHopIp = null;
120             if (primary) {
121                 ipAddress = getAddressFromSubnet(ipPrefixToString(ifPrefix));
122             } else {
123                 ipAddress = ipPrefixToString(ifPrefix);
124                 nextHopIp = getIpAddressFromPrefix(ipPrefixToString(gwIpAddress));
125             }
126             createUpdateVpnInterface(vpnName, interfaceName, ipAddress, macAddress, primary, nextHopIp, tx);
127         }
128     }
129
130     public static void createUpdateVpnInterface(String vpnName, String interfaceName, String ipAddress,
131             String  macAddress, boolean primary, String nextHopIp, WriteTransaction tx) {
132         synchronized (interfaceName.intern()) {
133             Adjacencies adjancencies = buildInterfaceAdjacency(ipAddress, macAddress, primary, nextHopIp);
134             VpnInterfaceBuilder einterfaceBuilder = createVpnInterface(vpnName, interfaceName, adjancencies);
135
136             tx.merge(LogicalDatastoreType.CONFIGURATION, getVpnInterfaceInstanceIdentifier(interfaceName),
137                     einterfaceBuilder.build());
138         }
139     }
140
141     private static VpnInterfaceBuilder createVpnInterface(String instanceName, String interfaceName,
142             Adjacencies adjacencies) {
143         VpnInterfaceBuilder einterfaceBuilder = new VpnInterfaceBuilder();
144         einterfaceBuilder.setVpnInstanceName(instanceName);
145         einterfaceBuilder.setName(interfaceName);
146         einterfaceBuilder.addAugmentation(Adjacencies.class, adjacencies);
147         return einterfaceBuilder;
148     }
149
150     private static Adjacencies buildInterfaceAdjacency(String ipAddress, String macAddress, boolean primary,
151             String nextHopIp) {
152         AdjacenciesBuilder builder = new AdjacenciesBuilder();
153         List<Adjacency> list = new ArrayList<>();
154
155         AdjacencyBuilder aBuilder = new AdjacencyBuilder();
156         aBuilder.setIpAddress(ipAddress);
157         if (macAddress != null) {
158             aBuilder.setMacAddress(macAddress);
159         }
160         aBuilder.setPrimaryAdjacency(primary);
161         if (nextHopIp != null) {
162             aBuilder.setNextHopIpList(Arrays.asList(nextHopIp));
163         }
164         list.add(aBuilder.build());
165
166         builder.setAdjacency(list);
167         return builder.build();
168     }
169
170     public static void removeVpnInterface(String interfaceName, WriteTransaction tx) {
171         synchronized (interfaceName.intern()) {
172             tx.delete(LogicalDatastoreType.CONFIGURATION, getVpnInterfaceInstanceIdentifier(interfaceName));
173         }
174     }
175
176     public static void removeVpnInterfaceAdjacencies(DataBroker dataBroker, String vpnName, String interfaceName) {
177         AdjacenciesBuilder builder = new AdjacenciesBuilder();
178         List<Adjacency> list = new ArrayList<>();
179         builder.setAdjacency(list);
180         VpnInterfaceBuilder einterfaceBuilder = createVpnInterface(vpnName, interfaceName, builder.build());
181
182         MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
183                 getVpnInterfaceInstanceIdentifier(interfaceName), einterfaceBuilder.build());
184
185     }
186
187     public static void removeVpnInterfaceAdjacency(DataBroker dataBroker, String interfaceName, IpPrefix ifPrefix) {
188         WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
189         String ipAddress = ipPrefixToString(ifPrefix);
190         removeVpnInterfaceAdjacency(interfaceName, ipAddress, tx);
191         MdsalUtils.commitTransaction(tx);
192     }
193
194     public static void removeVpnInterfaceAdjacency(DataBroker dataBroker, String interfaceName, IpAddress ifAddress) {
195         WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
196         String ifAddressStr = getAddressFromSubnet(ipAddressToString(ifAddress));
197         removeVpnInterfaceAdjacency(interfaceName, ifAddressStr, tx);
198         MdsalUtils.commitTransaction(tx);
199     }
200
201     private static void removeVpnInterfaceAdjacency(String interfaceName, String ipAddress, WriteTransaction tx) {
202         synchronized (interfaceName.intern()) {
203
204             InstanceIdentifier<Adjacency> adjacencyIdentifier = InstanceIdentifier.builder(VpnInterfaces.class)
205                     .child(VpnInterface.class, new VpnInterfaceKey(interfaceName)).augmentation(Adjacencies.class)
206                     .child(Adjacency.class, new AdjacencyKey(ipAddress)).build();
207
208             tx.delete(LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier);
209         }
210     }
211
212     private static InstanceIdentifier<VpnInterface> getVpnInterfaceInstanceIdentifier(String interfaceName) {
213         return InstanceIdentifier.builder(VpnInterfaces.class)
214                 .child(VpnInterface.class, new VpnInterfaceKey(interfaceName)).build();
215     }
216
217     public static void createVpnPortFixedIp(DataBroker dataBroker, String vpnName, String portName, IpPrefix ipAddress,
218             MacAddress macAddress) {
219         String fixedIpPrefix = ipPrefixToString(ipAddress);
220         String fixedIp = getIpAddressFromPrefix(fixedIpPrefix);
221
222         WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
223         createVpnPortFixedIp(vpnName, portName, fixedIp, macAddress, tx);
224         MdsalUtils.commitTransaction(tx);
225     }
226
227     public static void createVpnPortFixedIp(String vpnName, String portName, IpPrefix ipAddress, MacAddress macAddress,
228             WriteTransaction tx) {
229         String fixedIpPrefix = ipPrefixToString(ipAddress);
230         String fixedIp = getIpAddressFromPrefix(fixedIpPrefix);
231         createVpnPortFixedIp(vpnName, portName, fixedIp, macAddress, tx);
232     }
233
234     private static void createVpnPortFixedIp(String vpnName, String portName, String fixedIp, MacAddress macAddress,
235             WriteTransaction tx) {
236         synchronized ((vpnName + fixedIp).intern()) {
237             InstanceIdentifier<VpnPortipToPort> id = getVpnPortipToPortIdentifier(vpnName, fixedIp);
238             VpnPortipToPortBuilder builder = new VpnPortipToPortBuilder()
239                     .setKey(new VpnPortipToPortKey(fixedIp, vpnName)).setVpnName(vpnName).setPortFixedip(fixedIp)
240                     .setPortName(portName).setMacAddress(macAddress.getValue()).setSubnetIp(true).setConfig(true)
241                     .setLearnt(false);
242             tx.put(LogicalDatastoreType.OPERATIONAL, id, builder.build());
243             logger.debug(
244                     "Interface to fixedIp added: {}, vpn {}, interface {}, mac {} added to " + "VpnPortipToPort DS",
245                     fixedIp, vpnName, portName, macAddress);
246         }
247     }
248
249     public static VpnPortipToPort getVpnPortFixedIp(DataBroker dataBroker, String vpnName, String fixedIp) {
250         InstanceIdentifier<VpnPortipToPort> id = getVpnPortipToPortIdentifier(vpnName, fixedIp);
251         Optional<VpnPortipToPort> opt = MdsalUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
252         return opt != null && opt.isPresent() ? opt.get() : null;
253     }
254
255     public static void removeVpnPortFixedIp(String vpnName, IpPrefix ipAddress, WriteTransaction tx) {
256         String fixedIpPrefix = ipPrefixToString(ipAddress);
257         String fixedIp = getIpAddressFromPrefix(fixedIpPrefix);
258         InstanceIdentifier<VpnPortipToPort> id = getVpnPortipToPortIdentifier(vpnName, fixedIp);
259         tx.delete(LogicalDatastoreType.OPERATIONAL, id);
260     }
261
262     public static void addDirectSubnetToVpn(DataBroker dataBroker,
263             final NotificationPublishService notificationPublishService, String vpnName, String subnetName,
264             IpPrefix subnetIpPrefix, String interfaceName) {
265         InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class)
266                 .child(ElanInstance.class, new ElanInstanceKey(subnetName)).build();
267         Optional<ElanInstance> elanInstance = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
268                 elanIdentifierId);
269         if (!elanInstance.isPresent()) {
270             logger.error("Trying to add invalid elan {} to vpn {}", subnetName, vpnName);
271             return;
272         }
273         Long elanTag = elanInstance.get().getElanTag() != null ? elanInstance.get().getElanTag()
274                 : elanInstance.get().getSegmentationId();
275
276         Uuid subnetId = new Uuid(subnetName);
277         logger.info("Adding subnet {} {} to elan map", subnetId, subnetId);
278         createSubnetToNetworkMapping(dataBroker, subnetId, subnetId);
279
280         String subnetIp = getSubnetFromPrefix(ipPrefixToString(subnetIpPrefix));
281         logger.info("Adding subnet {} {} to vpn {}", subnetName, subnetIp, vpnName);
282         updateSubnetNode(dataBroker, new Uuid(vpnName), subnetId, subnetIp);
283
284         logger.info("Adding port {} to subnet {}", interfaceName, subnetName);
285         updateSubnetmapNodeWithPorts(dataBroker, subnetId, new Uuid(interfaceName), null);
286
287         logger.info("Publish subnet {}", subnetName);
288         publishSubnetAddNotification(notificationPublishService, subnetId, subnetIp, vpnName, elanTag);
289         logger.info("Finished Working on subnet {}", subnetName);
290
291     }
292
293     public static void removeDirectSubnetFromVpn(DataBroker dataBroker,
294             final NotificationPublishService notificationPublishService, String vpnName, String subnetName,
295             String interfaceName) {
296         InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class)
297                 .child(ElanInstance.class, new ElanInstanceKey(subnetName)).build();
298         Optional<ElanInstance> elanInstance = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
299                 elanIdentifierId);
300         if (!elanInstance.isPresent()) {
301             logger.error("Trying to add invalid elan {} to vpn {}", subnetName, vpnName);
302             return;
303         }
304         Long elanTag = elanInstance.get().getElanTag() != null ? elanInstance.get().getElanTag()
305                 : elanInstance.get().getSegmentationId();
306         Uuid subnetId = new Uuid(subnetName);
307
308         logger.info("Publish subnet remove {}", subnetName);
309         publishSubnetRemoveNotification(notificationPublishService, subnetId, vpnName, elanTag);
310
311         logger.info("Removing port {} from subnet {}", interfaceName, subnetName);
312         updateSubnetmapNodeWithPorts(dataBroker, subnetId, null, new Uuid(interfaceName));
313
314         logger.info("Removing subnet {} from vpn {}", subnetName, vpnName);
315         removeSubnetNode(dataBroker, new Uuid(vpnName));
316
317         logger.info("Removing subnet {} to elan map", subnetId);
318         removeSubnetToNetworkMapping(dataBroker, subnetId);
319
320         logger.info("Finished Working on subnet {}", subnetName);
321     }
322
323     private static void createSubnetToNetworkMapping(DataBroker dataBroker, Uuid subnetId, Uuid networkId) {
324         InstanceIdentifier<NetworkMap> networkMapIdentifier = getNetworkMapIdentifier(networkId);
325         Optional<NetworkMap> optionalNetworkMap = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
326                 networkMapIdentifier);
327         NetworkMapBuilder nwMapBuilder = null;
328         if (optionalNetworkMap.isPresent()) {
329             nwMapBuilder = new NetworkMapBuilder(optionalNetworkMap.get());
330         } else {
331             nwMapBuilder = new NetworkMapBuilder().setKey(new NetworkMapKey(networkId)).setNetworkId(networkId);
332             logger.debug("Adding a new network node in NetworkMaps DS for network {}", networkId.getValue());
333         }
334         List<Uuid> subnetIdList = nwMapBuilder.getSubnetIdList();
335         if (subnetIdList == null) {
336             subnetIdList = new ArrayList<>();
337         }
338         subnetIdList.add(subnetId);
339         nwMapBuilder.setSubnetIdList(subnetIdList);
340         MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, networkMapIdentifier, nwMapBuilder.build());
341         logger.debug("Created subnet-network mapping for subnet {} network {}", subnetId.getValue(),
342                 networkId.getValue());
343     }
344
345     private static void removeSubnetToNetworkMapping(DataBroker dataBroker, Uuid networkId) {
346         InstanceIdentifier<NetworkMap> networkMapIdentifier = getNetworkMapIdentifier(networkId);
347         MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, networkMapIdentifier);
348         logger.debug("Deleted subnet-network mapping for  network {}", networkId.getValue());
349     }
350
351     protected static void updateSubnetNode(DataBroker dataBroker, Uuid vpnId, Uuid subnetId, String subnetIp) {
352         Subnetmap subnetmap = null;
353         SubnetmapBuilder builder = null;
354         InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
355                 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
356
357         synchronized (subnetId.getValue().intern()) {
358             Optional<Subnetmap> sn = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
359             if (sn.isPresent()) {
360                 builder = new SubnetmapBuilder(sn.get());
361                 logger.debug("updating existing subnetmap node for subnet ID {}", subnetId.getValue());
362             } else {
363                 builder = new SubnetmapBuilder().setKey(new SubnetmapKey(subnetId)).setId(subnetId);
364                 logger.debug("creating new subnetmap node for subnet ID {}", subnetId.getValue());
365             }
366
367             builder.setSubnetIp(subnetIp);
368             builder.setNetworkId(subnetId);
369             builder.setVpnId(vpnId);
370
371             subnetmap = builder.build();
372             logger.debug("Creating/Updating subnetMap node: {} ", subnetId.getValue());
373             MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
374         }
375     }
376
377     protected static void removeSubnetNode(DataBroker dataBroker, Uuid subnetId) {
378         InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
379                 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
380
381         synchronized (subnetId.getValue().intern()) {
382             logger.debug("Deleting subnetMap node: {} ", subnetId.getValue());
383             MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
384         }
385     }
386
387     private static void updateSubnetmapNodeWithPorts(DataBroker dataBroker, Uuid subnetId, Uuid portIdToAdd,
388             Uuid portIdToRemove) {
389         Subnetmap subnetmap = null;
390         InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
391                 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
392         synchronized (subnetId.getValue().intern()) {
393             Optional<Subnetmap> sn = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
394             if (sn.isPresent()) {
395                 SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
396                 if (null != portIdToAdd) {
397                     List<Uuid> portList = builder.getPortList();
398                     if (null == portList) {
399                         portList = new ArrayList<>();
400                     }
401                     if (portIdToAdd != null) {
402                         portList.add(portIdToAdd);
403                         logger.debug("Updating subnetmap node {} with port {}", subnetId.getValue(),
404                                 portIdToAdd.getValue());
405
406                     }
407                     if (portIdToRemove != null) {
408                         portList.remove(portIdToRemove);
409                         logger.debug("Updating subnetmap node {} removing port {}", subnetId.getValue(),
410                                 portIdToRemove.getValue());
411
412                     }
413                     builder.setPortList(portList);
414                 }
415                 subnetmap = builder.build();
416                 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
417             } else {
418                 logger.error("Trying to update non-existing subnetmap node {} ", subnetId.getValue());
419             }
420         }
421     }
422
423     private static InstanceIdentifier<NetworkMap> getNetworkMapIdentifier(Uuid networkId) {
424         InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
425                 .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
426         return id;
427     }
428
429     private static InstanceIdentifier<VpnPortipToPort> getVpnPortipToPortIdentifier(String vpnName, String fixedIp) {
430         InstanceIdentifier<VpnPortipToPort> id = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
431                 .child(VpnPortipToPort.class, new VpnPortipToPortKey(fixedIp, vpnName)).build();
432         return id;
433     }
434
435     public static InstanceIdentifier<VpnPortipToPort> getVpnPortipToPortIdentifier() {
436         return InstanceIdentifier.builder(NeutronVpnPortipPortData.class).child(VpnPortipToPort.class).build();
437     }
438
439     private static void publishSubnetAddNotification(final NotificationPublishService notificationPublishService,
440             Uuid subnetId, String subnetIp, String vpnName, Long elanTag) {
441         SubnetAddedToVpnBuilder builder = new SubnetAddedToVpnBuilder();
442
443         logger.info("publish notification called for network creation");
444
445         builder.setSubnetId(subnetId);
446         builder.setSubnetIp(subnetIp);
447         builder.setVpnName(vpnName);
448         builder.setExternalVpn(true);
449         builder.setElanTag(elanTag);
450
451         try {
452             notificationPublishService.putNotification(builder.build());
453         } catch (InterruptedException e) {
454             logger.error("Fail to publish notification {}", builder, e);
455             throw new RuntimeException(e.getMessage());
456         }
457     }
458
459     private static void publishSubnetRemoveNotification(final NotificationPublishService notificationPublishService,
460             Uuid subnetId, String vpnName, Long elanTag) {
461         SubnetDeletedFromVpnBuilder builder = new SubnetDeletedFromVpnBuilder();
462
463         logger.info("publish notification called for network deletion");
464
465         builder.setSubnetId(subnetId);
466         builder.setVpnName(vpnName);
467         builder.setExternalVpn(true);
468         builder.setElanTag(elanTag);
469
470         try {
471             notificationPublishService.putNotification(builder.build());
472         } catch (InterruptedException e) {
473             logger.error("Fail to publish notification {}", builder, e);
474             throw new RuntimeException(e.getMessage());
475         }
476     }
477
478     public static void sendArpRequest(OdlArputilService arpUtilService, IpAddress srcIpAddress, IpAddress dstIpAddress,
479             String interf) {
480         try {
481             List<InterfaceAddress> interfaceAddresses = new ArrayList<>();
482             interfaceAddresses
483                     .add(new InterfaceAddressBuilder().setInterface(interf).setIpAddress(srcIpAddress).build());
484
485             SendArpRequestInput sendArpRequestInput = new SendArpRequestInputBuilder().setIpaddress(dstIpAddress)
486                     .setInterfaceAddress(interfaceAddresses).build();
487             arpUtilService.sendArpRequest(sendArpRequestInput);
488         } catch (Exception e) {
489             logger.error("Failed to send ARP request to IP {} from interfaces {}",
490                     dstIpAddress.getIpv4Address().getValue(), interf, e);
491             throw new RuntimeException(e.getMessage());
492         }
493     }
494
495     public static String getIpAddressFromPrefix(String prefix) {
496         return prefix.split(IP_MUSK_SEPARATOR)[0];
497     }
498
499     private static String getMaskFromPrefix(String prefix) {
500         return prefix.split(IP_MUSK_SEPARATOR)[1];
501     }
502
503     public static String getSubnetFromPrefix(String prefix) {
504         SubnetInfo subnet = new SubnetUtils(prefix).getInfo();
505         return subnet.getNetworkAddress() + IP_MUSK_SEPARATOR + getMaskFromPrefix(prefix);
506     }
507
508     public static String getSubnetFromPrefix(IpPrefix prefix) {
509         String prefixStr = ipPrefixToString(prefix);
510         return getSubnetFromPrefix(prefixStr);
511     }
512
513     private static String getAddressFromSubnet(String prefix) {
514         String myAddress = getIpAddressFromPrefix(prefix);
515         return myAddress + IP_ADDR_SUFFIX;
516     }
517
518     public static String getElanNameForVpnPort(String portName) {
519         return getUUidFromString(ELAN_PREFIX + portName);
520     }
521
522     public static String getUUidFromString(String key) {
523         return java.util.UUID.nameUUIDFromBytes(key.getBytes()).toString();
524     }
525
526     public static String ipPrefixToString(IpPrefix ipAddress) {
527         if (ipAddress.getIpv4Prefix() != null) {
528             return ipAddress.getIpv4Prefix().getValue();
529         }
530
531         return ipAddress.getIpv6Prefix().getValue();
532     }
533
534     public static String ipAddressToString(IpAddress ipAddress) {
535         if (ipAddress.getIpv4Address() != null) {
536             return ipAddress.getIpv4Address().getValue();
537         }
538
539         return ipAddress.getIpv6Address().getValue();
540     }
541 }