MRI version bumpup for Aluminium
[netvirt.git] / aclservice / impl / src / main / java / org / opendaylight / netvirt / aclservice / listeners / AclInterfaceListener.java
index f36b7a5a1b73e96657a11b79e8d5ea5b1f7fd7a8..dec684b56eba8929a10369c5346ac4456bc7aabb 100644 (file)
@@ -9,14 +9,14 @@ package org.opendaylight.netvirt.aclservice.listeners;
 
 import java.util.ArrayList;
 import java.util.List;
-import javax.annotation.Nullable;
-import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
 import javax.inject.Inject;
 import javax.inject.Singleton;
-import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.infrautils.utils.concurrent.Executors;
+import org.opendaylight.mdsal.binding.api.ClusteredDataTreeChangeListener;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.netvirt.aclservice.api.AclInterfaceCache;
 import org.opendaylight.netvirt.aclservice.api.AclServiceManager;
 import org.opendaylight.netvirt.aclservice.api.AclServiceManager.Action;
@@ -26,6 +26,7 @@ import org.opendaylight.netvirt.aclservice.utils.AclDataUtil;
 import org.opendaylight.netvirt.aclservice.utils.AclServiceUtils;
 import org.opendaylight.serviceutils.srm.RecoverableListener;
 import org.opendaylight.serviceutils.srm.ServiceRecoveryRegistry;
+import org.opendaylight.serviceutils.tools.listener.AbstractAsyncDataTreeChangeListener;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
@@ -33,12 +34,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionEgress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionIngress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAcl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.SubnetInfo;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Singleton
-public class AclInterfaceListener extends AsyncDataTreeChangeListenerBase<Interface, AclInterfaceListener>
+public class AclInterfaceListener extends AbstractAsyncDataTreeChangeListener<Interface>
         implements ClusteredDataTreeChangeListener<Interface>, RecoverableListener {
     private static final Logger LOG = LoggerFactory.getLogger(AclInterfaceListener.class);
 
@@ -53,7 +56,9 @@ public class AclInterfaceListener extends AsyncDataTreeChangeListenerBase<Interf
     public AclInterfaceListener(AclServiceManager aclServiceManager, AclClusterUtil aclClusterUtil,
             DataBroker dataBroker, AclDataUtil aclDataUtil, AclInterfaceCache aclInterfaceCache,
             AclServiceUtils aclServicUtils, ServiceRecoveryRegistry serviceRecoveryRegistry) {
-        super(Interface.class, AclInterfaceListener.class);
+        super(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                InstanceIdentifier.create(Interfaces.class).child(Interface.class),
+                Executors.newListeningSingleThreadExecutor("AclEventListener", LOG));
         this.aclServiceManager = aclServiceManager;
         this.aclClusterUtil = aclClusterUtil;
         this.dataBroker = dataBroker;
@@ -63,21 +68,18 @@ public class AclInterfaceListener extends AsyncDataTreeChangeListenerBase<Interf
         serviceRecoveryRegistry.addRecoverableListener(AclServiceUtils.getRecoverServiceRegistryKey(), this);
     }
 
-    @Override
-    @PostConstruct
     public void init() {
         LOG.info("{} start", getClass().getSimpleName());
-        registerListener();
     }
 
     @Override
     public void registerListener() {
-        registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
+        super.register();
     }
 
     @Override
-    protected InstanceIdentifier<Interface> getWildCardPath() {
-        return InstanceIdentifier.create(Interfaces.class).child(Interface.class);
+    public void deregisterListener() {
+        super.close();
     }
 
     @Override
@@ -92,7 +94,6 @@ public class AclInterfaceListener extends AsyncDataTreeChangeListenerBase<Interf
                 if (aclInterface.getDpId() != null) {
                     aclServiceManager.notify(aclInterface, null, Action.REMOVE);
                 }
-                aclServiceUtils.deleteSubnetInfo(interfaceId);
             }
         }
     }
@@ -118,8 +119,7 @@ public class AclInterfaceListener extends AsyncDataTreeChangeListenerBase<Interf
             // port-security-enable=false
             aclInterfaceBefore = addOrUpdateAclInterfaceCache(interfaceId, aclInPortBefore, true, interfaceState);
         }
-        if (aclInPortAfter != null && aclInPortAfter.isPortSecurityEnabled()
-                || aclInPortBefore != null && aclInPortBefore.isPortSecurityEnabled()) {
+        if (AclServiceUtils.isOfInterest(aclInPortAfter) || AclServiceUtils.isOfInterest(aclInPortBefore)) {
             List<Uuid> sgsBefore = null;
             if (aclInPortBefore != null) {
                 sgsBefore = aclInPortBefore.getSecurityGroups();
@@ -127,6 +127,7 @@ public class AclInterfaceListener extends AsyncDataTreeChangeListenerBase<Interf
             boolean isSgChanged = isSecurityGroupsChanged(sgsBefore, aclInPortAfter.getSecurityGroups());
             AclInterface aclInterfaceAfter =
                     addOrUpdateAclInterfaceCache(interfaceId, aclInPortAfter, isSgChanged, interfaceState);
+            updateCacheWithAddedAcls(aclInterfaceBefore, aclInterfaceAfter);
 
             if (aclClusterUtil.isEntityOwner()) {
                 // Handle bind/unbind service irrespective of interface state (up/down)
@@ -161,14 +162,26 @@ public class AclInterfaceListener extends AsyncDataTreeChangeListenerBase<Interf
     }
 
     private void updateCacheWithAclChange(AclInterface aclInterfaceBefore, AclInterface aclInterfaceAfter) {
-        List<Uuid> addedAcls = AclServiceUtils.getUpdatedAclList(aclInterfaceAfter.getSecurityGroups(),
-                aclInterfaceBefore.getSecurityGroups());
         List<Uuid> deletedAcls = AclServiceUtils.getUpdatedAclList(aclInterfaceBefore.getSecurityGroups(),
                 aclInterfaceAfter.getSecurityGroups());
-        if (deletedAcls != null && !deletedAcls.isEmpty()) {
+        if (!deletedAcls.isEmpty()) {
             aclDataUtil.removeAclInterfaceMap(deletedAcls, aclInterfaceAfter);
         }
+        List<AllowedAddressPairs> addedAap = AclServiceUtils.getUpdatedAllowedAddressPairs(aclInterfaceAfter
+                .getAllowedAddressPairs(), aclInterfaceBefore.getAllowedAddressPairs());
+        List<AllowedAddressPairs> deletedAap = AclServiceUtils.getUpdatedAllowedAddressPairs(aclInterfaceBefore
+                .getAllowedAddressPairs(), aclInterfaceAfter.getAllowedAddressPairs());
+        if (!deletedAap.isEmpty() || !addedAap.isEmpty()) {
+            LOG.debug("Update cache with new AAP = {}", aclInterfaceAfter.getInterfaceId());
+            aclDataUtil.addOrUpdateAclInterfaceMap(aclInterfaceAfter.getSecurityGroups(), aclInterfaceAfter);
+        }
+    }
+
+    private void updateCacheWithAddedAcls(AclInterface aclInterfaceBefore, AclInterface aclInterfaceAfter) {
+        List<Uuid> addedAcls = AclServiceUtils.getUpdatedAclList(aclInterfaceAfter.getSecurityGroups(),
+                aclInterfaceBefore.getSecurityGroups());
         if (addedAcls != null && !addedAcls.isEmpty()) {
+            LOG.debug("Update cache by adding interface={}", aclInterfaceAfter.getInterfaceId());
             aclDataUtil.addOrUpdateAclInterfaceMap(addedAcls, aclInterfaceAfter);
         }
     }
@@ -193,14 +206,17 @@ public class AclInterfaceListener extends AsyncDataTreeChangeListenerBase<Interf
     }
 
     private AclInterface addOrUpdateAclInterfaceCache(String interfaceId, InterfaceAcl aclInPort, boolean isSgChanged,
-            @Nullable org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
-                .state.Interface interfaceState) {
+            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state
+                .@Nullable Interface interfaceState) {
         AclInterface aclInterface = aclInterfaceCache.addOrUpdate(interfaceId, (prevAclInterface, builder) -> {
             List<Uuid> sgs = new ArrayList<>();
             if (aclInPort != null) {
                 sgs = aclInPort.getSecurityGroups();
-                builder.portSecurityEnabled(aclInPort.isPortSecurityEnabled()).securityGroups(sgs)
-                        .allowedAddressPairs(aclInPort.getAllowedAddressPairs());
+                builder.portSecurityEnabled(aclInPort.isPortSecurityEnabled())
+                        .interfaceType(aclInPort.getInterfaceType()).securityGroups(sgs)
+                        .allowedAddressPairs(new ArrayList<AllowedAddressPairs>(aclInPort
+                                .getAllowedAddressPairs().values())).subnetInfo(new ArrayList<SubnetInfo>(aclInPort
+                        .getSubnetInfo().values()));
             }
 
             if ((prevAclInterface == null || prevAclInterface.getLPortTag() == null) && interfaceState != null) {
@@ -208,7 +224,6 @@ public class AclInterfaceListener extends AsyncDataTreeChangeListenerBase<Interf
                         .lPortTag(interfaceState.getIfIndex()).isMarkedForDelete(false);
             }
 
-            builder.subnetInfo(aclServiceUtils.getSubnetInfo(interfaceId));
             if (prevAclInterface == null || prevAclInterface.getElanId() == null) {
                 builder.elanId(AclServiceUtils.getElanIdFromInterface(interfaceId, dataBroker));
             }
@@ -225,7 +240,7 @@ public class AclInterfaceListener extends AsyncDataTreeChangeListenerBase<Interf
     public void add(InstanceIdentifier<Interface> key, Interface port) {
         LOG.trace("Received AclInterface add event, port={}", port);
         InterfaceAcl aclInPort = port.augmentation(InterfaceAcl.class);
-        if (aclInPort != null && aclInPort.isPortSecurityEnabled()) {
+        if (AclServiceUtils.isOfInterest(aclInPort)) {
             String interfaceId = port.getName();
             AclInterface aclInterface = addOrUpdateAclInterfaceCache(interfaceId, aclInPort);
 
@@ -239,7 +254,9 @@ public class AclInterfaceListener extends AsyncDataTreeChangeListenerBase<Interf
     }
 
     @Override
-    protected AclInterfaceListener getDataTreeChangeListener() {
-        return this;
+    @PreDestroy
+    public void close() {
+        super.close();
+        Executors.shutdownAndAwaitTermination(getExecutorService());
     }
 }