Service-Recovery: Below service recovery actions are supported for ACL 02/69802/2
authorShashidhar Raja <shashidharr@altencalsoftlabs.com>
Thu, 22 Mar 2018 10:36:46 +0000 (16:06 +0530)
committerSam Hague <shague@redhat.com>
Fri, 23 Mar 2018 04:00:38 +0000 (04:00 +0000)
(a) ACL service recovery: As part of this, all ACL listeners are
re-registered (unregistered and registerd again)
(b) ACL Interface recovery
(c) ACL Instance recovery

Updated with ACL-Instance recovery changes.

Service recovery actions supported are defined in SRM module with below
patch set:
https://git.opendaylight.org/gerrit/#/c/68987/

Depends-On: I4c91cd52e7595b92b494356dfa715dbdf15da3c5

Change-Id: I5517effbec7f00e8fd48e656d9443f525fc74eeb
Signed-off-by: Shashidhar Raja <shashidharr@altencalsoftlabs.com>
Signed-off-by: kiranvasudeva <kirankumar.v@altencalsoftlabs.com>
Signed-off-by: Shashidhar Raja <shashidharr@altencalsoftlabs.com>
12 files changed:
aclservice/impl/pom.xml
aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/listeners/AclElanInterfaceListener.java
aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/listeners/AclEventListener.java
aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/listeners/AclInterfaceListener.java
aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/listeners/AclInterfaceStateListener.java
aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/listeners/AclNodeListener.java
aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/recovery/AclInstanceRecoveryHandler.java [new file with mode: 0644]
aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/recovery/AclInterfaceRecoveryHandler.java [new file with mode: 0644]
aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/recovery/AclServiceRecoveryHandler.java [new file with mode: 0644]
aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/utils/AclServiceUtils.java
aclservice/impl/src/main/resources/org/opendaylight/blueprint/aclservice.xml
aclservice/impl/src/test/java/org/opendaylight/netvirt/aclservice/tests/AclServiceTestModule.java

index 7a6506c37fe10a23f71a0cd3b6f5fb6b1c801e6d..66f7fdbc7f9af652a73ed392ff2954a2a740c938 100644 (file)
@@ -55,6 +55,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
             <artifactId>idmanager-api</artifactId>
             <version>${genius.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.genius</groupId>
+            <artifactId>srm-api</artifactId>
+            <version>${genius.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.infrautils</groupId>
             <artifactId>inject</artifactId>
index 1b8a024c17e3400cf23cce080e6eddb93817b402..d681180c72d342906c80773793ac1a4656b6550b 100644 (file)
@@ -14,6 +14,8 @@ import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeLis
 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.genius.srm.RecoverableListener;
+import org.opendaylight.genius.srm.ServiceRecoveryRegistry;
 import org.opendaylight.netvirt.aclservice.api.AclInterfaceCache;
 import org.opendaylight.netvirt.aclservice.api.AclServiceManager;
 import org.opendaylight.netvirt.aclservice.api.AclServiceManager.Action;
@@ -29,7 +31,7 @@ import org.slf4j.LoggerFactory;
 
 @Singleton
 public class AclElanInterfaceListener extends AsyncDataTreeChangeListenerBase<ElanInterface, AclElanInterfaceListener>
-        implements ClusteredDataTreeChangeListener<ElanInterface> {
+        implements ClusteredDataTreeChangeListener<ElanInterface>, RecoverableListener {
     private static final Logger LOG = LoggerFactory.getLogger(AclElanInterfaceListener.class);
 
     private final AclServiceManager aclServiceManager;
@@ -39,18 +41,25 @@ public class AclElanInterfaceListener extends AsyncDataTreeChangeListenerBase<El
 
     @Inject
     public AclElanInterfaceListener(AclServiceManager aclServiceManager, AclClusterUtil aclClusterUtil,
-            DataBroker dataBroker, AclInterfaceCache aclInterfaceCache) {
+            DataBroker dataBroker, AclInterfaceCache aclInterfaceCache,
+            ServiceRecoveryRegistry serviceRecoveryRegistry) {
         super(ElanInterface.class, AclElanInterfaceListener.class);
         this.aclServiceManager = aclServiceManager;
         this.aclClusterUtil = aclClusterUtil;
         this.dataBroker = dataBroker;
         this.aclInterfaceCache = aclInterfaceCache;
+        serviceRecoveryRegistry.addRecoverableListener(AclServiceUtils.getRecoverServiceRegistryKey(), this);
     }
 
     @Override
     @PostConstruct
     public void init() {
         LOG.info("{} start", getClass().getSimpleName());
+        registerListener();
+    }
+
+    @Override
+    public void registerListener() {
         registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
     }
 
index 0942df937ac6593284c4aba9d0f2a2b694c6c726..bd437ecdd48151cf2f69ecbb77192213756ffc7c 100644 (file)
@@ -22,6 +22,8 @@ import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeLis
 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.genius.srm.RecoverableListener;
+import org.opendaylight.genius.srm.ServiceRecoveryRegistry;
 import org.opendaylight.netvirt.aclservice.api.AclInterfaceCache;
 import org.opendaylight.netvirt.aclservice.api.AclServiceManager;
 import org.opendaylight.netvirt.aclservice.api.utils.AclInterface;
@@ -43,7 +45,7 @@ import org.slf4j.LoggerFactory;
 
 @Singleton
 public class AclEventListener extends AsyncDataTreeChangeListenerBase<Acl, AclEventListener> implements
-        ClusteredDataTreeChangeListener<Acl> {
+        ClusteredDataTreeChangeListener<Acl>, RecoverableListener {
 
     private static final Logger LOG = LoggerFactory.getLogger(AclEventListener.class);
 
@@ -56,7 +58,8 @@ public class AclEventListener extends AsyncDataTreeChangeListenerBase<Acl, AclEv
 
     @Inject
     public AclEventListener(AclServiceManager aclServiceManager, AclClusterUtil aclClusterUtil, DataBroker dataBroker,
-            AclDataUtil aclDataUtil, AclServiceUtils aclServicUtils, AclInterfaceCache aclInterfaceCache) {
+            AclDataUtil aclDataUtil, AclServiceUtils aclServicUtils, AclInterfaceCache aclInterfaceCache,
+            ServiceRecoveryRegistry serviceRecoveryRegistry) {
         super(Acl.class, AclEventListener.class);
         this.aclServiceManager = aclServiceManager;
         this.aclClusterUtil = aclClusterUtil;
@@ -64,12 +67,18 @@ public class AclEventListener extends AsyncDataTreeChangeListenerBase<Acl, AclEv
         this.aclDataUtil = aclDataUtil;
         this.aclServiceUtils = aclServicUtils;
         this.aclInterfaceCache = aclInterfaceCache;
+        serviceRecoveryRegistry.addRecoverableListener(AclServiceUtils.getRecoverServiceRegistryKey(), this);
     }
 
     @Override
     @PostConstruct
     public void init() {
         LOG.info("{} start", getClass().getSimpleName());
+        registerListener();
+    }
+
+    @Override
+    public void registerListener() {
         registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
     }
 
index 3df9bd3dd776d0c156b980a069a9465f9ba8acf7..c32514988ee29f294ef8071a45926b98b06ba865 100644 (file)
@@ -19,6 +19,8 @@ import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeLis
 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.genius.srm.RecoverableListener;
+import org.opendaylight.genius.srm.ServiceRecoveryRegistry;
 import org.opendaylight.netvirt.aclservice.api.AclInterfaceCache;
 import org.opendaylight.netvirt.aclservice.api.AclServiceManager;
 import org.opendaylight.netvirt.aclservice.api.AclServiceManager.Action;
@@ -39,7 +41,7 @@ import org.slf4j.LoggerFactory;
 
 @Singleton
 public class AclInterfaceListener extends AsyncDataTreeChangeListenerBase<Interface, AclInterfaceListener>
-        implements ClusteredDataTreeChangeListener<Interface> {
+        implements ClusteredDataTreeChangeListener<Interface>, RecoverableListener {
     private static final Logger LOG = LoggerFactory.getLogger(AclInterfaceListener.class);
 
     private final AclServiceManager aclServiceManager;
@@ -52,7 +54,7 @@ public class AclInterfaceListener extends AsyncDataTreeChangeListenerBase<Interf
     @Inject
     public AclInterfaceListener(AclServiceManager aclServiceManager, AclClusterUtil aclClusterUtil,
             DataBroker dataBroker, AclDataUtil aclDataUtil, AclInterfaceCache aclInterfaceCache,
-            AclServiceUtils aclServicUtils) {
+            AclServiceUtils aclServicUtils, ServiceRecoveryRegistry serviceRecoveryRegistry) {
         super(Interface.class, AclInterfaceListener.class);
         this.aclServiceManager = aclServiceManager;
         this.aclClusterUtil = aclClusterUtil;
@@ -60,12 +62,18 @@ public class AclInterfaceListener extends AsyncDataTreeChangeListenerBase<Interf
         this.aclDataUtil = aclDataUtil;
         this.aclInterfaceCache = aclInterfaceCache;
         this.aclServiceUtils = aclServicUtils;
+        serviceRecoveryRegistry.addRecoverableListener(AclServiceUtils.getRecoverServiceRegistryKey(), this);
     }
 
     @Override
     @PostConstruct
     public void init() {
         LOG.info("{} start", getClass().getSimpleName());
+        registerListener();
+    }
+
+    @Override
+    public void registerListener() {
         registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
     }
 
@@ -75,7 +83,7 @@ public class AclInterfaceListener extends AsyncDataTreeChangeListenerBase<Interf
     }
 
     @Override
-    protected void remove(InstanceIdentifier<Interface> key, Interface port) {
+    public void remove(InstanceIdentifier<Interface> key, Interface port) {
         LOG.trace("Received AclInterface remove event, port={}", port);
         String interfaceId = port.getName();
         AclInterface aclInterface = aclInterfaceCache.remove(interfaceId);
@@ -92,7 +100,7 @@ public class AclInterfaceListener extends AsyncDataTreeChangeListenerBase<Interf
     }
 
     @Override
-    protected void update(InstanceIdentifier<Interface> key, Interface portBefore, Interface portAfter) {
+    public void update(InstanceIdentifier<Interface> key, Interface portBefore, Interface portAfter) {
         if (portBefore.getAugmentation(ParentRefs.class) == null
                 && portAfter.getAugmentation(ParentRefs.class) != null) {
             LOG.trace("Ignoring event for update in ParentRefs for {} ", portAfter.getName());
@@ -229,7 +237,7 @@ public class AclInterfaceListener extends AsyncDataTreeChangeListenerBase<Interf
     }
 
     @Override
-    protected void add(InstanceIdentifier<Interface> key, Interface port) {
+    public void add(InstanceIdentifier<Interface> key, Interface port) {
         LOG.trace("Received AclInterface add event, port={}", port);
         InterfaceAcl aclInPort = port.getAugmentation(InterfaceAcl.class);
         if (aclInPort != null && aclInPort.isPortSecurityEnabled()) {
index 94eda89e860ff9205285ad914ece0b2e398ccd7a..52f29c1d9cc45d9e70ab462144d6739e08ed75f9 100644 (file)
@@ -17,6 +17,8 @@ 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.genius.interfacemanager.interfaces.IInterfaceManager;
+import org.opendaylight.genius.srm.RecoverableListener;
+import org.opendaylight.genius.srm.ServiceRecoveryRegistry;
 import org.opendaylight.netvirt.aclservice.api.AclInterfaceCache;
 import org.opendaylight.netvirt.aclservice.api.AclServiceManager;
 import org.opendaylight.netvirt.aclservice.api.AclServiceManager.Action;
@@ -38,7 +40,7 @@ import org.slf4j.LoggerFactory;
 
 @Singleton
 public class AclInterfaceStateListener extends AsyncDataTreeChangeListenerBase<Interface,
-        AclInterfaceStateListener> implements ClusteredDataTreeChangeListener<Interface> {
+        AclInterfaceStateListener> implements ClusteredDataTreeChangeListener<Interface>, RecoverableListener {
 
     private static final Logger LOG = LoggerFactory.getLogger(AclInterfaceStateListener.class);
 
@@ -54,7 +56,8 @@ public class AclInterfaceStateListener extends AsyncDataTreeChangeListenerBase<I
     @Inject
     public AclInterfaceStateListener(AclServiceManager aclServiceManger, AclClusterUtil aclClusterUtil,
             DataBroker dataBroker, AclDataUtil aclDataUtil, IInterfaceManager interfaceManager,
-            AclInterfaceCache aclInterfaceCache, AclServiceUtils aclServicUtils) {
+            AclInterfaceCache aclInterfaceCache, AclServiceUtils aclServicUtils,
+            ServiceRecoveryRegistry serviceRecoveryRegistry) {
         super(Interface.class, AclInterfaceStateListener.class);
         this.aclServiceManger = aclServiceManger;
         this.aclClusterUtil = aclClusterUtil;
@@ -63,12 +66,18 @@ public class AclInterfaceStateListener extends AsyncDataTreeChangeListenerBase<I
         this.interfaceManager = interfaceManager;
         this.aclInterfaceCache = aclInterfaceCache;
         this.aclServiceUtils = aclServicUtils;
+        serviceRecoveryRegistry.addRecoverableListener(AclServiceUtils.getRecoverServiceRegistryKey(), this);
     }
 
     @Override
     @PostConstruct
     public void init() {
         LOG.info("{} start", getClass().getSimpleName());
+        registerListener();
+    }
+
+    @Override
+    public void registerListener() {
         registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
     }
 
index 03241afc24dca3fea02fc8a3c8a8fb1dcbc0823b..6747f5d609a20b04b7c844732cbc89e9cc89588d 100644 (file)
@@ -20,6 +20,8 @@ import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.genius.srm.RecoverableListener;
+import org.opendaylight.genius.srm.ServiceRecoveryRegistry;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
 import org.opendaylight.netvirt.aclservice.utils.AclConstants;
 import org.opendaylight.netvirt.aclservice.utils.AclNodeDefaultFlowsTxBuilder;
@@ -39,7 +41,8 @@ import org.slf4j.LoggerFactory;
  * during when node is discovered.
  */
 @Singleton
-public class AclNodeListener extends AsyncDataTreeChangeListenerBase<FlowCapableNode, AclNodeListener> {
+public class AclNodeListener extends AsyncDataTreeChangeListenerBase<FlowCapableNode, AclNodeListener>
+        implements RecoverableListener {
 
     private static final Logger LOG = LoggerFactory.getLogger(AclNodeListener.class);
 
@@ -54,7 +57,8 @@ public class AclNodeListener extends AsyncDataTreeChangeListenerBase<FlowCapable
 
     @Inject
     public AclNodeListener(final IMdsalApiManager mdsalManager, DataBroker dataBroker, AclserviceConfig config,
-            AclServiceUtils aclServiceUtils, JobCoordinator jobCoordinator) {
+            AclServiceUtils aclServiceUtils, JobCoordinator jobCoordinator,
+            ServiceRecoveryRegistry serviceRecoveryRegistry) {
         super(FlowCapableNode.class, AclNodeListener.class);
 
         this.mdsalManager = mdsalManager;
@@ -63,6 +67,7 @@ public class AclNodeListener extends AsyncDataTreeChangeListenerBase<FlowCapable
         this.config = config;
         this.aclServiceUtils = aclServiceUtils;
         this.jobCoordinator = jobCoordinator;
+        serviceRecoveryRegistry.addRecoverableListener(AclServiceUtils.getRecoverServiceRegistryKey(), this);
     }
 
     @Override
@@ -72,9 +77,20 @@ public class AclNodeListener extends AsyncDataTreeChangeListenerBase<FlowCapable
         if (config != null) {
             this.securityGroupMode = config.getSecurityGroupMode();
         }
+        registerListener();
+        LOG.info("AclserviceConfig: {}", this.config);
+    }
+
+    @Override
+    public void registerListener() {
         this.aclServiceUtils.createRemoteAclIdPool();
         registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
-        LOG.info("AclserviceConfig: {}", this.config);
+    }
+
+    @Override
+    public  void deregisterListener() {
+        super.deregisterListener();
+        this.aclServiceUtils.deleteRemoteAclIdPool();
     }
 
     @Override
diff --git a/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/recovery/AclInstanceRecoveryHandler.java b/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/recovery/AclInstanceRecoveryHandler.java
new file mode 100644 (file)
index 0000000..8a0cb3e
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2018 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netvirt.aclservice.recovery;
+
+import com.google.common.base.Optional;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.genius.srm.ServiceRecoveryInterface;
+import org.opendaylight.genius.srm.ServiceRecoveryRegistry;
+import org.opendaylight.netvirt.aclservice.api.utils.AclInterface;
+import org.opendaylight.netvirt.aclservice.listeners.AclInterfaceListener;
+import org.opendaylight.netvirt.aclservice.utils.AclDataUtil;
+import org.opendaylight.netvirt.aclservice.utils.AclServiceUtils;
+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.interfaces.rev140508.interfaces.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.srm.types.rev170711.NetvirtAclInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAcl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAclBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+@Singleton
+public class AclInstanceRecoveryHandler implements ServiceRecoveryInterface {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AclInstanceRecoveryHandler.class);
+    private final DataBroker dataBroker;
+    private final AclDataUtil aclDataUtil;
+    private final AclInterfaceListener aclInterfaceListener;
+
+    @Inject
+    public AclInstanceRecoveryHandler(ServiceRecoveryRegistry serviceRecoveryRegistry, DataBroker dataBroker,
+             AclDataUtil aclDataUtil, AclInterfaceListener aclInterfaceListener) {
+        this.dataBroker = dataBroker;
+        this.aclDataUtil = aclDataUtil;
+        this.aclInterfaceListener = aclInterfaceListener;
+        serviceRecoveryRegistry.registerServiceRecoveryRegistry(buildServiceRegistryKey(), this);
+    }
+
+    @Override
+    public void recoverService(String entityId) {
+        LOG.info("Recover ACL instance {}", entityId);
+        Uuid aclId = new Uuid(entityId);
+        Collection<AclInterface> aclInterfaces = aclDataUtil.getInterfaceList(aclId);
+        for (AclInterface aclInterface : aclInterfaces) {
+            String aclInterfaceId = aclInterface.getInterfaceId();
+            Optional<Interface> interfaceOptional = AclServiceUtils.getInterface(dataBroker,
+                    aclInterfaceId);
+            if (interfaceOptional.isPresent()) {
+                Interface interfaceBefore = interfaceOptional.get();
+                LOG.debug("Starting Recovery of acl Instance {} for interface {}", entityId, interfaceBefore.getName());
+                InterfaceAcl interfaceAclBefore = interfaceBefore.getAugmentation(InterfaceAcl.class);
+                List<Uuid> sgList = new ArrayList<>(interfaceAclBefore.getSecurityGroups());
+                sgList.remove(aclId);
+                InterfaceAcl interfaceAclAfter = new InterfaceAclBuilder(interfaceAclBefore).setSecurityGroups(sgList)
+                        .build();
+                Interface interfaceAfter = new InterfaceBuilder(interfaceBefore)
+                        .addAugmentation(InterfaceAcl.class,interfaceAclAfter).build();
+                aclInterfaceListener.update(null, interfaceBefore, interfaceAfter);
+                aclInterfaceListener.update(null, interfaceAfter, interfaceBefore);
+            } else {
+                LOG.error("Interfaces not present for aclInterface {} ", aclInterfaceId);
+            }
+        }
+    }
+
+    private String buildServiceRegistryKey() {
+        return NetvirtAclInstance.class.toString();
+    }
+}
diff --git a/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/recovery/AclInterfaceRecoveryHandler.java b/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/recovery/AclInterfaceRecoveryHandler.java
new file mode 100644 (file)
index 0000000..9cd5d2b
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2018 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netvirt.aclservice.recovery;
+
+import com.google.common.base.Optional;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.genius.srm.ServiceRecoveryInterface;
+import org.opendaylight.genius.srm.ServiceRecoveryRegistry;
+import org.opendaylight.netvirt.aclservice.listeners.AclInterfaceListener;
+import org.opendaylight.netvirt.aclservice.utils.AclServiceUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.srm.types.rev170711.NetvirtAclInterface;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class AclInterfaceRecoveryHandler implements ServiceRecoveryInterface {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AclInterfaceRecoveryHandler.class);
+
+    private final DataBroker dataBroker;
+    private final AclInterfaceListener aclInterfaceListener;
+
+    @Inject
+    public AclInterfaceRecoveryHandler(ServiceRecoveryRegistry serviceRecoveryRegistry, DataBroker dataBroker,
+            AclInterfaceListener aclInterfaceListener) {
+        serviceRecoveryRegistry.registerServiceRecoveryRegistry(buildServiceRegistryKey(), this);
+        this.dataBroker = dataBroker;
+        this.aclInterfaceListener = aclInterfaceListener;
+    }
+
+    @Override
+    public void recoverService(String entityId) {
+        LOG.info("Recover ACL interface {}", entityId);
+        Optional<Interface> interfaceOp = AclServiceUtils.getInterface(dataBroker, entityId);
+        if (interfaceOp.isPresent()) {
+            Interface aclInterface = interfaceOp.get();
+            InstanceIdentifier<Interface> interfaceIdentifier = AclServiceUtils.getInterfaceIdentifier(entityId);
+            aclInterfaceListener.remove(interfaceIdentifier, aclInterface);
+            aclInterfaceListener.add(interfaceIdentifier, aclInterface);
+        } else {
+            LOG.warn("{} is not valid ACL interface", entityId);
+        }
+    }
+
+    private String buildServiceRegistryKey() {
+        return NetvirtAclInterface.class.toString();
+    }
+}
diff --git a/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/recovery/AclServiceRecoveryHandler.java b/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/recovery/AclServiceRecoveryHandler.java
new file mode 100644 (file)
index 0000000..ee493eb
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2018 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netvirt.aclservice.recovery;
+
+import java.util.Queue;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.opendaylight.genius.srm.RecoverableListener;
+import org.opendaylight.genius.srm.ServiceRecoveryInterface;
+import org.opendaylight.genius.srm.ServiceRecoveryRegistry;
+import org.opendaylight.netvirt.aclservice.utils.AclServiceUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class AclServiceRecoveryHandler implements ServiceRecoveryInterface {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AclServiceRecoveryHandler.class);
+    private final ServiceRecoveryRegistry serviceRecoveryRegistry;
+
+    @Inject
+    public AclServiceRecoveryHandler(final ServiceRecoveryRegistry serviceRecoveryRegistry) {
+        LOG.info("Registering IFM service recovery handlers");
+        this.serviceRecoveryRegistry = serviceRecoveryRegistry;
+        serviceRecoveryRegistry.registerServiceRecoveryRegistry(AclServiceUtils.getRecoverServiceRegistryKey(), this);
+    }
+
+    private void deregisterListeners() {
+        Queue<RecoverableListener> recoverableListeners =
+                serviceRecoveryRegistry.getRecoverableListeners(AclServiceUtils.getRecoverServiceRegistryKey());
+        recoverableListeners.forEach((recoverableListener -> recoverableListener.deregisterListener()));
+    }
+
+    private void registerListeners() {
+        Queue<RecoverableListener> recoverableListeners =
+                serviceRecoveryRegistry.getRecoverableListeners(AclServiceUtils.getRecoverServiceRegistryKey());
+        recoverableListeners.forEach((recoverableListener -> recoverableListener.registerListener()));
+    }
+
+    @Override
+    public void recoverService(final String entityId) {
+        LOG.info("Recover IFM service by deregistering and registering all relevant listeners");
+        deregisterListeners();
+        registerListeners();
+    }
+}
index a477cd0604cbd94ff3b5b0608c5687e3ba0205ad..5836f80f4ee46793d655792c385b2418f1a47459 100644 (file)
@@ -114,6 +114,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.ser
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.srm.types.rev170711.NetvirtAcl;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.config.rev160806.AclserviceConfig;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.AclPortsLookup;
@@ -1468,6 +1469,10 @@ public final class AclServiceUtils {
         return filteredAAPs;
     }
 
+    public static String getRecoverServiceRegistryKey() {
+        return NetvirtAcl.class.toString();
+    }
+
     private static InetAddress getInetAddress(IpPrefixOrAddress ipPrefixOrAddress) {
         InetAddress inetAddress = null;
         String addr = null;
index 11bbb2cb9dde9f6e6804f1e27c29275dead775f5..1490283fda117e1cc4178ab6fc6a362b62e2d810 100644 (file)
@@ -37,4 +37,6 @@
   <service ref="aclInterfaceCacheImpl"
            interface="org.opendaylight.netvirt.aclservice.api.AclInterfaceCache" />
 
+    <reference id="serviceRecoveryRegistry"
+               interface="org.opendaylight.genius.srm.ServiceRecoveryRegistry"/>
 </blueprint>
index d31495fd33278cf77a49839727a7b6edd1290381..b15fc5d295bb3012b8cbf735e8010731d5e9728c 100644 (file)
@@ -20,6 +20,7 @@ import org.opendaylight.genius.datastoreutils.testutils.JobCoordinatorEventsWait
 import org.opendaylight.genius.datastoreutils.testutils.TestableJobCoordinatorEventsWaiter;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.genius.mdsalutil.interfaces.testutils.TestIMdsalApiManager;
+import org.opendaylight.genius.srm.ServiceRecoveryRegistry;
 import org.opendaylight.netvirt.aclservice.AclInterfaceCacheImpl;
 import org.opendaylight.netvirt.aclservice.api.AclInterfaceCache;
 import org.opendaylight.netvirt.aclservice.stats.TestOdlDirectStatisticsService;
@@ -72,6 +73,7 @@ public class AclServiceTestModule extends AbstractModule {
         bind(JobCoordinatorEventsWaiter.class).to(TestableJobCoordinatorEventsWaiter.class);
 
         bind(AclInterfaceCache.class).toInstance(new AclInterfaceCacheImpl());
+        bind(ServiceRecoveryRegistry.class).toInstance(mock(ServiceRecoveryRegistry.class));
     }
 
     private AclserviceConfig aclServiceConfig() {