Merge "pom cleanup, odlparent-lite"
[netvirt.git] / vpnservice / neutronvpn / neutronvpn-impl / src / main / java / org / opendaylight / netvirt / neutronvpn / NeutronPortChangeListener.java
1 /*
2  * Copyright (c) 2015 - 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 package org.opendaylight.netvirt.neutronvpn;
9
10 import com.google.common.base.Optional;
11 import com.google.common.collect.Lists;
12 import java.util.ArrayList;
13 import java.util.Iterator;
14 import java.util.List;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
17 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
18 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.genius.mdsalutil.AbstractDataChangeListener;
21 import org.opendaylight.genius.mdsalutil.MDSALUtil;
22 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
23 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.LockManagerService;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAcl;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAclBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstanceKey;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.PortAddedToSubnetBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.PortRemovedFromSubnetBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
56 import org.opendaylight.yangtools.concepts.ListenerRegistration;
57 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60
61 public class NeutronPortChangeListener extends AbstractDataChangeListener<Port> implements AutoCloseable {
62     private static final Logger LOG = LoggerFactory.getLogger(NeutronPortChangeListener.class);
63     private ListenerRegistration<DataChangeListener> listenerRegistration;
64     private final DataBroker dataBroker;
65     private final NeutronvpnManager nvpnManager;
66     private final NeutronvpnNatManager nvpnNatManager;
67     private final LockManagerService lockManager;
68     private final NotificationPublishService notificationPublishService;
69     private final NeutronSubnetGwMacResolver gwMacResolver;
70
71     public NeutronPortChangeListener(final DataBroker dataBroker,
72                                      final NeutronvpnManager nVpnMgr, final NeutronvpnNatManager nVpnNatMgr,
73                                      final NotificationPublishService notiPublishService,
74                                      final LockManagerService lockManager, NeutronSubnetGwMacResolver gwMacResolver) {
75         super(Port.class);
76         this.dataBroker = dataBroker;
77         nvpnManager = nVpnMgr;
78         nvpnNatManager = nVpnNatMgr;
79         notificationPublishService = notiPublishService;
80         this.lockManager = lockManager;
81         this.gwMacResolver = gwMacResolver;
82     }
83
84     public void start() {
85         LOG.info("{} start", getClass().getSimpleName());
86         listenerRegistration = dataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
87                 getWildCardPath(), this, DataChangeScope.SUBTREE);
88     }
89
90     private InstanceIdentifier<Port> getWildCardPath() {
91         return InstanceIdentifier.create(Neutron.class).child(Ports.class).child(Port.class);
92     }
93
94     @Override
95     public void close() throws Exception {
96         if (listenerRegistration != null) {
97             listenerRegistration.close();
98             listenerRegistration = null;
99         }
100         LOG.info("{} close", getClass().getSimpleName());
101     }
102
103     @Override
104     protected void add(InstanceIdentifier<Port> identifier, Port input) {
105         if (LOG.isTraceEnabled()) {
106             LOG.trace("Adding Port : key: " + identifier + ", value=" + input);
107         }
108         Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, input.getNetworkId());
109         if (network == null || !NeutronvpnUtils.isNetworkTypeSupported(network)) {
110             //FIXME: This should be removed when support for VLAN and GRE network types is added
111             LOG.error("neutron vpn doesn't support vlan/gre network provider type for the port {} "
112                     + "which is part of network {}.", input.getName(), network);
113             return;
114         }
115         NeutronvpnUtils.addToPortCache(input);
116
117         /* check if router interface has been created */
118         if ((input.getDeviceOwner() != null) && (input.getDeviceId() != null)) {
119             if (input.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF)) {
120                 handleRouterInterfaceAdded(input);
121                 /* nothing else to do here */
122                 return;
123             }
124             if (NeutronConstants.DEVICE_OWNER_GATEWAY_INF.equals(input.getDeviceOwner())) {
125                 handleRouterGatewayUpdated(input);
126             }
127         }
128         if (input.getFixedIps() != null && !input.getFixedIps().isEmpty()) {
129             handleNeutronPortCreated(input);
130         }
131     }
132
133     @Override
134     protected void remove(InstanceIdentifier<Port> identifier, Port input) {
135         if (LOG.isTraceEnabled()) {
136             LOG.trace("Removing Port : key: " + identifier + ", value=" + input);
137         }
138         Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, input.getNetworkId());
139         if (network == null || !NeutronvpnUtils.isNetworkTypeSupported(network)) {
140             //FIXME: This should be removed when support for VLAN and GRE network types is added
141             LOG.error("neutron vpn doesn't support vlan/gre network provider type for the port {} which is part of " +
142                     "network {}.", input.getName(), network);
143             return;
144         }
145         NeutronvpnUtils.removeFromPortCache(input);
146
147         if ((input.getDeviceOwner() != null) && (input.getDeviceId() != null)) {
148             if (input.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF)) {
149                 handleRouterInterfaceRemoved(input);
150                 /* nothing else to do here */
151                 return;
152             }
153         }
154         if (input.getFixedIps() != null && !input.getFixedIps().isEmpty()) {
155             handleNeutronPortDeleted(input);
156         }
157     }
158
159     @Override
160     protected void update(InstanceIdentifier<Port> identifier, Port original, Port update) {
161         if (LOG.isTraceEnabled()) {
162             LOG.trace("Updating Port : key: " + identifier + ", original value=" + original + ", update value=" +
163                     update);
164         }
165         Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, update.getNetworkId());
166         if (network == null || !NeutronvpnUtils.isNetworkTypeSupported(network)) {
167             LOG.error("neutron vpn doesn't support vlan/gre network provider type for the port {} which is part of network {}."
168                     + " Skipping the processing of Port update DCN", update.getName(), network);
169             return;
170         }
171         List<FixedIps> oldIPs = (original.getFixedIps() != null) ? original.getFixedIps() : new ArrayList<>();
172         List<FixedIps> newIPs = (update.getFixedIps() != null) ? update.getFixedIps() : new ArrayList<>();
173
174         /* check if VIF type updated as part of port binding */
175         if(NeutronvpnUtils.isPortVifTypeUpdated(original, update)) {
176             updateOfPortInterface(original, update);
177         }
178         NeutronvpnUtils.addToPortCache(update);
179
180         /* check if router interface has been updated */
181         if ((update.getDeviceOwner() != null) && (update.getDeviceId() != null)) {
182             if (update.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF)) {
183                 handleRouterInterfaceAdded(update);
184                 /* nothing else to do here */
185                 return;
186             }
187             if (NeutronConstants.DEVICE_OWNER_GATEWAY_INF.equals(update.getDeviceOwner())) {
188                 handleRouterGatewayUpdated(update);
189             }
190         }
191
192         handlePortSecurityUpdated(original, update);
193
194         if (!oldIPs.equals(newIPs)) {
195             Iterator<FixedIps> iterator = newIPs.iterator();
196             while (iterator.hasNext()) {
197                 FixedIps ip = iterator.next();
198                 if (oldIPs.remove(ip)) {
199                     iterator.remove();
200                 }
201             }
202             handleNeutronPortUpdated(original, update);
203         }
204     }
205
206     private void handleRouterInterfaceAdded(Port routerPort) {
207         if (routerPort.getDeviceId() != null) {
208             Uuid routerId = new Uuid(routerPort.getDeviceId());
209             Uuid infNetworkId = routerPort.getNetworkId();
210             Uuid existingVpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, infNetworkId);
211             if (existingVpnId == null) {
212                 for (FixedIps portIP : routerPort.getFixedIps()) {
213                     if (portIP.getIpAddress().getIpv4Address() != null) {
214                         Uuid vpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
215                         if (vpnId == null) {
216                             vpnId = routerId;
217                         }
218                         nvpnManager.addSubnetToVpn(vpnId, portIP.getSubnetId());
219                         String ipValue = portIP.getIpAddress().getIpv4Address().getValue();
220                         nvpnManager.updateSubnetNodeWithFixedIps(portIP.getSubnetId(), routerId,
221                                 routerPort.getUuid(), ipValue, routerPort.getMacAddress().getValue());
222                         nvpnNatManager.handleSubnetsForExternalRouter(routerId, dataBroker);
223                         PhysAddress mac = new PhysAddress(routerPort.getMacAddress().getValue());
224                         LOG.trace("NeutronPortChangeListener Add Subnet Gateway IP {} MAC {} Interface {} VPN {}",
225                                 portIP.getIpAddress().getIpv4Address(),routerPort.getMacAddress(),
226                                 routerPort.getUuid().getValue(), vpnId.getValue());
227                         NeutronvpnUtils.createVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue, routerPort
228                                 .getUuid().getValue(), routerPort.getMacAddress().getValue(), true, true, false);
229                     } else {
230                         LOG.error("No IPv4 address assigned to port {)", routerPort.getUuid().getValue());
231                     }
232                 }
233             } else {
234                 LOG.error("Neutron network {} corresponding to router interface port {} for neutron router {} already" +
235                         " associated to VPN {}", infNetworkId.getValue(), routerPort.getUuid().getValue(), routerId
236                         .getValue(), existingVpnId.getValue());
237             }
238         }
239     }
240
241     private void handleRouterInterfaceRemoved(Port routerPort) {
242         if (routerPort.getDeviceId() != null) {
243             Uuid routerId = new Uuid(routerPort.getDeviceId());
244             for (FixedIps portIP : routerPort.getFixedIps()) {
245                 if (portIP.getIpAddress().getIpv4Address() != null) {
246                     Uuid vpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
247                     if(vpnId == null) {
248                         vpnId = routerId;
249                     }
250                     nvpnManager.removeSubnetFromVpn(vpnId, portIP.getSubnetId());
251                     nvpnManager.updateSubnetNodeWithFixedIps(portIP.getSubnetId(), null,
252                             null, null, null);
253                     nvpnNatManager.handleSubnetsForExternalRouter(routerId, dataBroker);
254                     String ipValue = portIP.getIpAddress().getIpv4Address().getValue();
255                     NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue);
256                 } else {
257                     LOG.error("No IPv4 address assigned to port {)", routerPort.getUuid().getValue());
258                 }
259             }
260         }
261     }
262
263     private void handleRouterGatewayUpdated(Port routerGwPort) {
264         Uuid routerId = new Uuid(routerGwPort.getDeviceId());
265         Router router = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
266         if (router == null) {
267             LOG.warn("No router found for router GW port {} router id {}", routerGwPort.getUuid(), routerId.getValue());
268             return;
269         }
270
271         gwMacResolver.sendArpRequestsToExtGateways(router);
272     }
273
274     private Long getVpnIdFromUuid(Uuid vpnId) {
275         long vpn = 1;
276         InstanceIdentifier<VpnInstance> id = InstanceIdentifier.builder(VpnInstanceToVpnId.class).
277                 child(VpnInstance.class, new VpnInstanceKey(vpnId.getValue())).build();
278         try {
279             Optional<VpnInstance> optional = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
280                     id);
281             if (optional.isPresent()) {
282                 vpn = optional.get().getVpnId();
283             }
284         } catch (Exception e) {
285             LOG.error("Failed to retrieve vpn instance for the Subnet .", e.getMessage());
286         }
287         return vpn;
288     }
289
290     private void handleNeutronPortCreated(Port port) {
291         if (!NeutronUtils.isPortVnicTypeNormal(port)) {
292             nvpnManager.updateSubnetmapNodeWithPorts(port.getFixedIps().get(0).getSubnetId(), null, port.getUuid());
293             LOG.info("Port {} is not a NORMAL VNIC Type port; OF Port interfaces are not created",
294                     port.getUuid().getValue());
295             return;
296         }
297         LOG.info("Of-port-interface creation");
298         // Create of-port interface for this neutron port
299         String portInterfaceName = createOfPortInterface(port);
300         LOG.debug("Creating ELAN Interface");
301         createElanInterface(port, portInterfaceName);
302         LOG.debug("Add port to subnet");
303         // add port to local Subnets DS
304         Uuid vpnId = addPortToSubnets(port);
305
306         if (vpnId != null) {
307             // create vpn-interface on this neutron port
308             LOG.debug("Adding VPN Interface");
309             nvpnManager.createVpnInterface(vpnId, port);
310             Uuid routerId = NeutronvpnUtils.getVpnMap(dataBroker, vpnId).getRouterId();
311             if(routerId != null) {
312                 nvpnManager.addToNeutronRouterInterfacesMap(routerId, port.getUuid().getValue());
313             }
314         }
315     }
316
317     private void handleNeutronPortDeleted(Port port) {
318         if (!NeutronUtils.isPortVnicTypeNormal(port)) {
319             nvpnManager.removePortsFromSubnetmapNode(port.getFixedIps().get(0).getSubnetId(), null, port.getUuid());
320             LOG.info("Port {} is not a NORMAL VNIC Type port; OF Port interfaces are not created",
321                     port.getUuid().getValue());
322             return;
323         }
324         //dissociate fixedIP from floatingIP if associated
325         nvpnManager.dissociatefixedIPFromFloatingIP(port.getUuid().getValue());
326         LOG.debug("Remove port from subnet");
327         // remove port from local Subnets DS
328         Uuid vpnId = removePortFromSubnets(port);
329
330         if (vpnId != null) {
331             // remove vpn-interface for this neutron port
332             LOG.debug("removing VPN Interface");
333             nvpnManager.deleteVpnInterface(vpnId, port);
334         }
335
336         // Remove of-port interface for this neutron port
337         // ELAN interface is also implicitly deleted as part of this operation
338         LOG.debug("Of-port-interface removal");
339         deleteOfPortInterface(port);
340         if (vpnId != null) {
341             Uuid routerId = NeutronvpnUtils.getVpnMap(dataBroker, vpnId).getRouterId();
342             if (routerId != null) {
343                 nvpnManager.removeFromNeutronRouterInterfacesMap(routerId, port.getUuid().getValue());
344             }
345         }
346     }
347
348     private void handleNeutronPortUpdated(Port portoriginal, Port portupdate) {
349         if (portoriginal.getFixedIps() == null || portoriginal.getFixedIps().isEmpty()) {
350             handleNeutronPortCreated(portupdate);
351             return;
352         }
353         LOG.debug("Add port to subnet");
354         // add port FixedIP to local Subnets DS
355         Uuid vpnIdup = addPortToSubnets(portupdate);
356
357         if (vpnIdup != null) {
358             nvpnManager.createVpnInterface(vpnIdup, portupdate);
359             Uuid routerId = NeutronvpnUtils.getVpnMap(dataBroker, vpnIdup).getRouterId();
360             if(routerId != null) {
361                 nvpnManager.addToNeutronRouterInterfacesMap(routerId, portupdate.getUuid().getValue());
362             }
363         }
364
365         // remove port FixedIP from local Subnets DS
366         Uuid vpnIdor = removePortFromSubnets(portoriginal);
367
368         if (vpnIdor != null) {
369             nvpnManager.deleteVpnInterface(vpnIdor, portoriginal);
370             Uuid routerId = NeutronvpnUtils.getVpnMap(dataBroker, vpnIdor).getRouterId();
371             if(routerId != null) {
372                 nvpnManager.removeFromNeutronRouterInterfacesMap(routerId, portoriginal.getUuid().getValue());
373             }
374         }
375     }
376
377     private void handlePortSecurityUpdated(Port portOriginal, Port portUpdated) {
378         Boolean origSecurityEnabled = NeutronvpnUtils.getPortSecurityEnabled(portOriginal);
379         Boolean updatedSecurityEnabled = NeutronvpnUtils.getPortSecurityEnabled(portUpdated);
380         String interfaceName = portUpdated.getUuid().getValue();
381         Interface portInterface = NeutronvpnUtils.getOfPortInterface(dataBroker, portUpdated);
382         if (portInterface != null) {
383             InterfaceAclBuilder interfaceAclBuilder = null;
384             if (origSecurityEnabled != updatedSecurityEnabled) {
385                 interfaceAclBuilder = new InterfaceAclBuilder();
386                 interfaceAclBuilder.setPortSecurityEnabled(updatedSecurityEnabled);
387                 if (updatedSecurityEnabled) {
388                     // Handle security group enabled
389                     NeutronvpnUtils.populateInterfaceAclBuilder(interfaceAclBuilder, portUpdated);
390                 } else {
391                     // Handle security group disabled
392                     interfaceAclBuilder.setSecurityGroups(Lists.newArrayList());
393                     interfaceAclBuilder.setAllowedAddressPairs(Lists.newArrayList());
394                 }
395             } else {
396                 if (updatedSecurityEnabled) {
397                     // handle SG add/delete delta
398                     InterfaceAcl interfaceAcl = portInterface.getAugmentation(InterfaceAcl.class);
399                     interfaceAclBuilder = new InterfaceAclBuilder(interfaceAcl);
400                     interfaceAclBuilder.setSecurityGroups(
401                             NeutronvpnUtils.getUpdatedSecurityGroups(interfaceAcl.getSecurityGroups(),
402                                     portOriginal.getSecurityGroups(), portUpdated.getSecurityGroups()));
403                     List<AllowedAddressPairs> updatedAddressPairs = NeutronvpnUtils.getUpdatedAllowedAddressPairs(
404                             interfaceAcl.getAllowedAddressPairs(), portOriginal.getAllowedAddressPairs(),
405                             portUpdated.getAllowedAddressPairs());
406                     interfaceAclBuilder.setAllowedAddressPairs(NeutronvpnUtils.getAllowedAddressPairsForFixedIps(
407                             updatedAddressPairs, portOriginal.getMacAddress(), portOriginal.getFixedIps(),
408                             portUpdated.getFixedIps()));
409                 }
410             }
411
412             if (interfaceAclBuilder != null) {
413                 InterfaceBuilder builder = new InterfaceBuilder(portInterface).addAugmentation(InterfaceAcl.class,
414                         interfaceAclBuilder.build());
415                 InstanceIdentifier interfaceIdentifier = NeutronvpnUtils.buildVlanInterfaceIdentifier(interfaceName);
416                 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, interfaceIdentifier, builder.build());
417             }
418         } else {
419             LOG.error("Interface {} is not present", interfaceName);
420         }
421     }
422
423     private String createOfPortInterface(Port port) {
424         Interface inf = createInterface(port);
425         String infName = inf.getName();
426
427         LOG.debug("Creating OFPort Interface {}", infName);
428         InstanceIdentifier interfaceIdentifier = NeutronvpnUtils.buildVlanInterfaceIdentifier(infName);
429         try {
430             Optional<Interface> optionalInf = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
431                     interfaceIdentifier);
432             if (!optionalInf.isPresent()) {
433                 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, interfaceIdentifier, inf);
434             } else {
435                 LOG.error("Interface {} is already present", infName);
436             }
437         } catch (Exception e) {
438             LOG.error("failed to create interface {} due to the exception {} ", infName, e.getMessage());
439         }
440
441         return infName;
442     }
443
444     private Interface createInterface(Port port) {
445         String parentRefName = NeutronvpnUtils.getVifPortName(port);
446         String interfaceName = port.getUuid().getValue();
447         IfL2vlan.L2vlanMode l2VlanMode = IfL2vlan.L2vlanMode.Trunk;
448         InterfaceBuilder interfaceBuilder = new InterfaceBuilder();
449         IfL2vlanBuilder ifL2vlanBuilder = new IfL2vlanBuilder();
450
451         Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, port.getNetworkId());
452         ifL2vlanBuilder.setL2vlanMode(l2VlanMode);
453
454         if(parentRefName != null) {
455             ParentRefsBuilder parentRefsBuilder = new ParentRefsBuilder().setParentInterface(parentRefName);
456             interfaceBuilder.addAugmentation(ParentRefs.class, parentRefsBuilder.build());
457         }
458
459         interfaceBuilder.setEnabled(true).setName(interfaceName).setType(L2vlan.class)
460                 .addAugmentation(IfL2vlan.class, ifL2vlanBuilder.build());
461
462         if (NeutronvpnUtils.isPortSecurityEnabled(port)) {
463             InterfaceAclBuilder interfaceAclBuilder = new InterfaceAclBuilder();
464             interfaceAclBuilder.setPortSecurityEnabled(true);
465             NeutronvpnUtils.populateInterfaceAclBuilder(interfaceAclBuilder, port);
466             interfaceBuilder.addAugmentation(InterfaceAcl.class, interfaceAclBuilder.build());
467         }
468         return interfaceBuilder.build();
469     }
470
471     private void deleteOfPortInterface(Port port) {
472         String name = port.getUuid().getValue();
473         LOG.debug("Removing OFPort Interface {}", name);
474         InstanceIdentifier interfaceIdentifier = NeutronvpnUtils.buildVlanInterfaceIdentifier(name);
475         try {
476             Optional<Interface> optionalInf = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
477                     interfaceIdentifier);
478             if (optionalInf.isPresent()) {
479                 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, interfaceIdentifier);
480             } else {
481                 LOG.error("Interface {} is not present", name);
482             }
483         } catch (Exception e) {
484             LOG.error("Failed to delete interface {} due to the exception {}", name, e.getMessage());
485         }
486     }
487
488     private Interface updateInterface(Port original, Port update) {
489         String parentRefName = NeutronvpnUtils.getVifPortName(update);
490         String interfaceName = original.getUuid().getValue();
491         InterfaceBuilder interfaceBuilder = new InterfaceBuilder();
492
493         if(parentRefName != null) {
494             ParentRefsBuilder parentRefsBuilder = new ParentRefsBuilder().setParentInterface(parentRefName);
495             interfaceBuilder.addAugmentation(ParentRefs.class, parentRefsBuilder.build());
496         }
497
498         interfaceBuilder.setName(interfaceName);
499         return interfaceBuilder.build();
500     }
501
502     private String updateOfPortInterface(Port original, Port updated) {
503         Interface inf = updateInterface(original, updated);
504         String infName = inf.getName();
505
506         LOG.debug("Updating OFPort Interface {}", infName);
507         InstanceIdentifier interfaceIdentifier = NeutronvpnUtils.buildVlanInterfaceIdentifier(infName);
508         try {
509             Optional<Interface> optionalInf = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
510                     interfaceIdentifier);
511             if (optionalInf.isPresent()) {
512                 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, interfaceIdentifier, inf);
513             } else {
514                 LOG.error("Interface {} doesn't exist", infName);
515             }
516         } catch (Exception e) {
517             LOG.error("failed to update interface {} due to the exception {} ", infName, e.getMessage());
518         }
519
520         return infName;
521     }
522
523     private void createElanInterface(Port port, String name) {
524         String elanInstanceName = port.getNetworkId().getValue();
525         List<PhysAddress> physAddresses = new ArrayList<>();
526         physAddresses.add(new PhysAddress(port.getMacAddress().getValue()));
527
528         InstanceIdentifier<ElanInterface> id = InstanceIdentifier.builder(ElanInterfaces.class).child(ElanInterface
529                 .class, new ElanInterfaceKey(name)).build();
530         ElanInterface elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName)
531                 .setName(name).setStaticMacEntries(physAddresses).setKey(new ElanInterfaceKey(name)).build();
532         MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, elanInterface);
533         LOG.debug("Creating new ELan Interface {}", elanInterface);
534     }
535
536     // adds port to subnet list and creates vpnInterface
537     private Uuid addPortToSubnets(Port port) {
538         Uuid subnetId = null;
539         Uuid vpnId = null;
540         String infName = port.getUuid().getValue();
541         Subnetmap subnetmap = null;
542         boolean isLockAcquired = false;
543         String lockName = port.getUuid().getValue();
544         String elanInstanceName = port.getNetworkId().getValue();
545         InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child
546                 (ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
547         Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
548                 elanIdentifierId);
549         long elanTag = elanInstance.get().getElanTag();
550
551         // find the subnet to which this port is associated
552         FixedIps ip = port.getFixedIps().get(0);
553         subnetId = ip.getSubnetId();
554         subnetmap = nvpnManager.updateSubnetmapNodeWithPorts(subnetId, port.getUuid(), null);
555         if (subnetmap != null) {
556             vpnId = subnetmap.getVpnId();
557         }
558         if (vpnId != null) {
559             try {
560                 isLockAcquired = NeutronvpnUtils.lock(lockManager, lockName);
561                 checkAndPublishPortAddNotification(subnetmap.getSubnetIp(), subnetId, port.getUuid(), elanTag);
562                 LOG.debug("Port added to subnet notification sent");
563             } catch (Exception e) {
564                 LOG.error("Port added to subnet notification failed", e);
565             } finally {
566                 if (isLockAcquired) {
567                     NeutronvpnUtils.unlock(lockManager, lockName);
568                 }
569             }
570         }
571         return vpnId;
572     }
573
574     private Uuid removePortFromSubnets(Port port) {
575         Uuid subnetId = null;
576         Uuid vpnId = null;
577         Subnetmap subnetmap = null;
578         boolean isLockAcquired = false;
579         String lockName = port.getUuid().getValue();
580         String elanInstanceName = port.getNetworkId().getValue();
581         InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child
582                 (ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
583         Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
584                 elanIdentifierId);
585         long elanTag = elanInstance.get().getElanTag();
586
587         // find the subnet to which this port is associated
588         FixedIps ip = port.getFixedIps().get(0);
589         subnetId = ip.getSubnetId();
590         subnetmap = nvpnManager.removePortsFromSubnetmapNode(subnetId, port.getUuid(), null);
591         if (subnetmap != null) {
592             vpnId = subnetmap.getVpnId();
593         }
594         if (vpnId != null) {
595             try {
596                 isLockAcquired = NeutronvpnUtils.lock(lockManager, lockName);
597                 checkAndPublishPortRemoveNotification(subnetmap.getSubnetIp(), subnetId, port.getUuid(), elanTag);
598                 LOG.debug("Port removed from subnet notification sent");
599             } catch (Exception e) {
600                 LOG.error("Port removed from subnet notification failed", e);
601             } finally {
602                 if (isLockAcquired) {
603                     NeutronvpnUtils.unlock(lockManager, lockName);
604                 }
605             }
606         }
607         return vpnId;
608     }
609
610     private void checkAndPublishPortAddNotification(String subnetIp, Uuid subnetId, Uuid portId, Long elanTag) throws
611             InterruptedException {
612         PortAddedToSubnetBuilder builder = new PortAddedToSubnetBuilder();
613
614         LOG.info("publish notification called");
615
616         builder.setSubnetIp(subnetIp);
617         builder.setSubnetId(subnetId);
618         builder.setPortId(portId);
619         builder.setElanTag(elanTag);
620
621         notificationPublishService.putNotification(builder.build());
622     }
623
624     private void checkAndPublishPortRemoveNotification(String subnetIp, Uuid subnetId, Uuid portId, Long elanTag)
625             throws InterruptedException {
626         PortRemovedFromSubnetBuilder builder = new PortRemovedFromSubnetBuilder();
627
628         LOG.info("publish notification called");
629
630         builder.setPortId(portId);
631         builder.setSubnetIp(subnetIp);
632         builder.setSubnetId(subnetId);
633         builder.setElanTag(elanTag);
634
635         notificationPublishService.putNotification(builder.build());
636     }
637
638 }