MRI version bumpup for Aluminium
[netvirt.git] / aclservice / impl / src / main / java / org / opendaylight / netvirt / aclservice / listeners / AclEventListener.java
index d939e25275a0bdc2ca636ce11b1e756e5151c34a..c8a40472855f2b88ac730daddc2ba4b3bb6d2a4d 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.netvirt.aclservice.listeners;
 
 import com.google.common.collect.ImmutableSet;
+import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -17,15 +18,14 @@ import java.util.List;
 import java.util.Objects;
 import java.util.Set;
 import java.util.SortedSet;
-import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
-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.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.utils.AclInterface;
@@ -35,6 +35,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.access.control.list.rev160218.AccessLists;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.Acl;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.Ace;
@@ -48,7 +49,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Singleton
-public class AclEventListener extends AsyncDataTreeChangeListenerBase<Acl, AclEventListener> implements
+public class AclEventListener extends AbstractAsyncDataTreeChangeListener<Acl> implements
         ClusteredDataTreeChangeListener<Acl>, RecoverableListener {
 
     private static final Logger LOG = LoggerFactory.getLogger(AclEventListener.class);
@@ -64,7 +65,9 @@ public class AclEventListener extends AsyncDataTreeChangeListenerBase<Acl, AclEv
     public AclEventListener(AclServiceManager aclServiceManager, AclClusterUtil aclClusterUtil, DataBroker dataBroker,
             AclDataUtil aclDataUtil, AclServiceUtils aclServicUtils, AclInterfaceCache aclInterfaceCache,
             ServiceRecoveryRegistry serviceRecoveryRegistry) {
-        super(Acl.class, AclEventListener.class);
+        super(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                InstanceIdentifier.create(AccessLists.class).child(Acl.class),
+                Executors.newListeningSingleThreadExecutor("AclEventListener", LOG));
         this.aclServiceManager = aclServiceManager;
         this.aclClusterUtil = aclClusterUtil;
         this.dataBroker = dataBroker;
@@ -74,25 +77,22 @@ public class AclEventListener extends AsyncDataTreeChangeListenerBase<Acl, AclEv
         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<Acl> getWildCardPath() {
-        return InstanceIdentifier.create(AccessLists.class).child(Acl.class);
+    public void deregisterListener() {
+        super.close();
     }
 
     @Override
-    protected void remove(InstanceIdentifier<Acl> key, Acl acl) {
+    public void remove(InstanceIdentifier<Acl> key, Acl acl) {
         LOG.trace("On remove event, remove ACL: {}", acl);
         String aclName = acl.getAclName();
         this.aclDataUtil.removeAcl(aclName);
@@ -100,21 +100,21 @@ public class AclEventListener extends AsyncDataTreeChangeListenerBase<Acl, AclEv
         if (aclTag != null) {
             this.aclDataUtil.removeAclTag(aclName);
         }
-        updateRemoteAclCache(acl.getAccessListEntries().getAce(), aclName, AclServiceManager.Action.REMOVE);
+
+        updateRemoteAclCache(AclServiceUtils.getAceListFromAcl(acl), aclName, AclServiceManager.Action.REMOVE);
         if (aclClusterUtil.isEntityOwner()) {
-            if (aclTag != null) {
-                this.aclServiceUtils.releaseAclTag(aclName);
-            }
             // Handle Rule deletion If SG Remove event is received before SG Rule delete event
-            List<Ace> aceList = acl.getAccessListEntries().getAce();
-            Collection<AclInterface> aclInterfaces =
-                    ImmutableSet.copyOf(aclDataUtil.getInterfaceList(new Uuid(aclName)));
-            updateAceRules(aclInterfaces, aclName, aceList, AclServiceManager.Action.REMOVE);
+            List<Ace> aceList = AclServiceUtils.aceList(acl);
+            if (!aceList.isEmpty()) {
+                Collection<AclInterface> aclInterfaces =
+                        ImmutableSet.copyOf(aclDataUtil.getInterfaceList(new Uuid(aclName)));
+                updateAceRules(aclInterfaces, aclName, aceList, AclServiceManager.Action.REMOVE);
+            }
         }
     }
 
     @Override
-    protected void update(InstanceIdentifier<Acl> key, Acl aclBefore, Acl aclAfter) {
+    public void update(InstanceIdentifier<Acl> key, Acl aclBefore, Acl aclAfter) {
         String aclName = aclAfter.getAclName();
         Collection<AclInterface> interfacesBefore =
                 ImmutableSet.copyOf(aclDataUtil.getInterfaceList(new Uuid(aclName)));
@@ -127,7 +127,7 @@ public class AclEventListener extends AsyncDataTreeChangeListenerBase<Acl, AclEv
         if (aclClusterUtil.isEntityOwner()) {
             LOG.debug("On update event, remove Ace rules: {} for ACL: {}", deletedAceRules, aclName);
             updateAceRules(interfacesBefore, aclName, deletedAceRules, AclServiceManager.Action.REMOVE);
-            if (null != deletedAceRules && !deletedAceRules.isEmpty()) {
+            if (!deletedAceRules.isEmpty()) {
                 aclServiceUtils.deleteAcesFromConfigDS(aclName, deletedAceRules);
             }
         }
@@ -143,28 +143,33 @@ public class AclEventListener extends AsyncDataTreeChangeListenerBase<Acl, AclEv
 
     private void updateAceRules(Collection<AclInterface> interfaceList, String aclName, List<Ace> aceList,
             AclServiceManager.Action action) {
-        if (null != aceList && !aceList.isEmpty()) {
-            LOG.trace("update ace rules - action: {} , ace rules: {}", action.name(), aceList);
-            for (AclInterface port : interfaceList) {
+        LOG.trace("update ace rules - action: {} , ace rules: {}", action.name(), aceList);
+        for (AclInterface port : interfaceList) {
+            BigInteger dpId = port.getDpId();
+            Long elanId = port.getElanId();
+            if (dpId != null && elanId != null) {
                 for (Ace aceRule : aceList) {
                     aclServiceManager.notifyAce(port, action, aclName, aceRule);
                 }
+            } else {
+                LOG.debug("Skip update ACE rules as DP ID or ELAN ID for interface {} is not present. "
+                        + "DP Id: {} ELAN ID: {}", port.getInterfaceId(), dpId, elanId);
             }
         }
     }
 
     @Override
-    protected void add(InstanceIdentifier<Acl> key, Acl acl) {
+    public void add(InstanceIdentifier<Acl> key, Acl acl) {
         LOG.trace("On add event, add ACL: {}", acl);
         this.aclDataUtil.addAcl(acl);
 
         String aclName = acl.getAclName();
-        Integer aclTag = this.aclServiceUtils.allocateAclTag(aclName);
+        Integer aclTag = AclServiceUtils.getAclTag(acl);
         if (aclTag != null && aclTag != AclConstants.INVALID_ACL_TAG) {
             this.aclDataUtil.addAclTag(aclName, aclTag);
         }
 
-        updateRemoteAclCache(acl.getAccessListEntries().getAce(), aclName, AclServiceManager.Action.ADD);
+        updateRemoteAclCache(AclServiceUtils.getAceListFromAcl(acl), aclName, AclServiceManager.Action.ADD);
     }
 
     /**
@@ -174,10 +179,7 @@ public class AclEventListener extends AsyncDataTreeChangeListenerBase<Acl, AclEv
      * @param aclName the acl name
      * @param action the action
      */
-    private void updateRemoteAclCache(@Nullable List<Ace> aceList, String aclName, AclServiceManager.Action action) {
-        if (null == aceList) {
-            return;
-        }
+    private void updateRemoteAclCache(@NonNull List<Ace> aceList, String aclName, AclServiceManager.Action action) {
         for (Ace ace : aceList) {
             SecurityRuleAttr aceAttributes = ace.augmentation(SecurityRuleAttr.class);
             if (AclServiceUtils.doesAceHaveRemoteGroupId(aceAttributes)) {
@@ -196,7 +198,7 @@ public class AclEventListener extends AsyncDataTreeChangeListenerBase<Acl, AclEv
         String aclName = aclAfter.getAclName();
         Integer aclTag = this.aclDataUtil.getAclTag(aclName);
         if (aclTag == null) {
-            aclTag = this.aclServiceUtils.allocateAclTag(aclName);
+            aclTag = AclServiceUtils.getAclTag(aclAfter);
             if (aclTag != null && aclTag != AclConstants.INVALID_ACL_TAG) {
                 this.aclDataUtil.addAclTag(aclName, aclTag);
             }
@@ -229,45 +231,33 @@ public class AclEventListener extends AsyncDataTreeChangeListenerBase<Acl, AclEv
             return;
         }
 
-        if (aclInterfaces != null) {
-            for (AclInterface aclInterface : aclInterfaces) {
-                AclInterface aclInterfaceInCache =
-                        aclInterfaceCache.addOrUpdate(aclInterface.getInterfaceId(), (prevAclInterface, builder) -> {
-                            SortedSet<Integer> remoteAclTags =
-                                    aclServiceUtils.getRemoteAclTags(aclInterface.getSecurityGroups(), direction);
-                            if (DirectionEgress.class.equals(direction)) {
-                                builder.egressRemoteAclTags(remoteAclTags);
-                            } else {
-                                builder.ingressRemoteAclTags(remoteAclTags);
-                            }
-                        });
-
-                aclDataUtil.addOrUpdateAclInterfaceMap(aclInterface.getSecurityGroups(), aclInterfaceInCache);
-            }
-        }
-    }
+        for (AclInterface aclInterface : aclInterfaces) {
+            AclInterface aclInterfaceInCache =
+                    aclInterfaceCache.addOrUpdate(aclInterface.getInterfaceId(), (prevAclInterface, builder) -> {
+                        SortedSet<Integer> remoteAclTags =
+                                aclServiceUtils.getRemoteAclTags(aclInterface.getSecurityGroups(), direction);
+                        if (DirectionEgress.class.equals(direction)) {
+                            builder.egressRemoteAclTags(remoteAclTags);
+                        } else {
+                            builder.ingressRemoteAclTags(remoteAclTags);
+                        }
+                    });
 
-    @Override
-    protected AclEventListener getDataTreeChangeListener() {
-        return this;
+            aclDataUtil.addOrUpdateAclInterfaceMap(aclInterface.getSecurityGroups(), aclInterfaceInCache);
+        }
     }
 
-    @NonNull
-    private List<Ace> getChangedAceList(Acl updatedAcl, Acl currentAcl) {
+    private static @NonNull List<Ace> getChangedAceList(Acl updatedAcl, Acl currentAcl) {
         if (updatedAcl == null) {
             return Collections.emptyList();
         }
-        List<Ace> updatedAceList =
-            updatedAcl.getAccessListEntries() == null || updatedAcl.getAccessListEntries().getAce() == null
-                ? new ArrayList<>()
-                : new ArrayList<>(updatedAcl.getAccessListEntries().getAce());
+        List<Ace> updatedAceList = AclServiceUtils.aceList(updatedAcl);
         if (currentAcl == null) {
             return updatedAceList;
         }
-        List<Ace> currentAceList =
-            currentAcl.getAccessListEntries() == null || currentAcl.getAccessListEntries().getAce() == null
-                ? new ArrayList<>()
-                : new ArrayList<>(currentAcl.getAccessListEntries().getAce());
+
+        List<Ace> currentAceList = AclServiceUtils.aceList(currentAcl);
+        updatedAceList = new ArrayList<>(updatedAceList);
         for (Iterator<Ace> iterator = updatedAceList.iterator(); iterator.hasNext();) {
             Ace ace1 = iterator.next();
             for (Ace ace2 : currentAceList) {
@@ -281,7 +271,7 @@ public class AclEventListener extends AsyncDataTreeChangeListenerBase<Acl, AclEv
 
     private List<Ace> getDeletedAceList(Acl acl) {
         if (acl == null || acl.getAccessListEntries() == null || acl.getAccessListEntries().getAce() == null) {
-            return null;
+            return Collections.emptyList();
         }
         List<Ace> aceList = acl.getAccessListEntries().getAce();
         List<Ace> deletedAceList = new ArrayList<>();
@@ -292,4 +282,11 @@ public class AclEventListener extends AsyncDataTreeChangeListenerBase<Acl, AclEv
         }
         return deletedAceList;
     }
+
+    @Override
+    @PreDestroy
+    public void close() {
+        super.close();
+        Executors.shutdownAndAwaitTermination(getExecutorService());
+    }
 }