MRI version bumpup for Aluminium
[netvirt.git] / elanmanager / impl / src / main / java / org / opendaylight / netvirt / elan / l2gw / listeners / HwvtepPhysicalSwitchListener.java
index d22e74b3ee802504df9667f8ba7a4cea96afe407..8e0baa8d98efe2d5c4eae1e457cc86238408651d 100644 (file)
@@ -8,20 +8,20 @@
 
 package org.opendaylight.netvirt.elan.l2gw.listeners;
 
-import com.google.common.base.Optional;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.List;
+import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
 import java.util.function.BiPredicate;
 import java.util.function.Predicate;
-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.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.genius.datastoreutils.hwvtep.HwvtepAbstractDataTreeChangeListener;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
@@ -29,9 +29,15 @@ import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
 import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
 import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundUtils;
-import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
+import org.opendaylight.infrautils.utils.concurrent.Executors;
+import org.opendaylight.infrautils.utils.concurrent.LoggingFutures;
+import org.opendaylight.mdsal.binding.api.ClusteredDataTreeChangeListener;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
 import org.opendaylight.netvirt.elan.l2gw.ha.listeners.HAOpClusteredListener;
+import org.opendaylight.netvirt.elan.l2gw.recovery.impl.L2GatewayServiceRecoveryHandler;
 import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayUtils;
 import org.opendaylight.netvirt.elan.l2gw.utils.L2GatewayConnectionUtils;
 import org.opendaylight.netvirt.elan.l2gw.utils.L2GatewayUtils;
@@ -41,11 +47,14 @@ import org.opendaylight.netvirt.elan.utils.ElanClusterUtils;
 import org.opendaylight.netvirt.elanmanager.utils.ElanL2GwCacheUtils;
 import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayCache;
 import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayDevice;
+import org.opendaylight.serviceutils.srm.RecoverableListener;
+import org.opendaylight.serviceutils.srm.ServiceRecoveryRegistry;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentationBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelIps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelIpsKey;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
@@ -62,7 +71,7 @@ import org.slf4j.LoggerFactory;
 @Singleton
 public class HwvtepPhysicalSwitchListener
         extends HwvtepAbstractDataTreeChangeListener<PhysicalSwitchAugmentation, HwvtepPhysicalSwitchListener>
-        implements ClusteredDataTreeChangeListener<PhysicalSwitchAugmentation> {
+        implements ClusteredDataTreeChangeListener<PhysicalSwitchAugmentation>, RecoverableListener {
 
     /** The Constant LOG. */
     private static final Logger LOG = LoggerFactory.getLogger(HwvtepPhysicalSwitchListener.class);
@@ -73,7 +82,7 @@ public class HwvtepPhysicalSwitchListener
                         globalIid.firstKeyOf(Node.class).getNodeId().getValue());
 
     private static final Predicate<PhysicalSwitchAugmentation> TUNNEL_IP_AVAILABLE =
-        phySwitch -> !HwvtepHAUtil.isEmpty(phySwitch.getTunnelIps());
+        phySwitch -> !HwvtepHAUtil.isEmpty(phySwitch.getTunnelIps().values());
 
     private static final Predicate<PhysicalSwitchAugmentation> TUNNEL_IP_NOT_AVAILABLE = TUNNEL_IP_AVAILABLE.negate();
 
@@ -111,12 +120,19 @@ public class HwvtepPhysicalSwitchListener
      * Instantiates a new hwvtep physical switch listener.
      */
     @Inject
-    public HwvtepPhysicalSwitchListener(final DataBroker dataBroker, ItmRpcService itmRpcService,
-            ElanClusterUtils elanClusterUtils, L2gwServiceProvider l2gwServiceProvider,
-            HAOpClusteredListener haListener, L2GatewayCache l2GatewayCache,
-            StaleVlanBindingsCleaner staleVlanBindingsCleaner,
-            HwvtepNodeHACache hwvtepNodeHACache) {
-        super(PhysicalSwitchAugmentation.class, HwvtepPhysicalSwitchListener.class, hwvtepNodeHACache);
+    public HwvtepPhysicalSwitchListener(final L2GatewayServiceRecoveryHandler l2GatewayServiceRecoveryHandler,
+                                        final ServiceRecoveryRegistry serviceRecoveryRegistry,
+                                        final DataBroker dataBroker, ItmRpcService itmRpcService,
+                                        ElanClusterUtils elanClusterUtils, L2gwServiceProvider l2gwServiceProvider,
+                                        HAOpClusteredListener haListener, L2GatewayCache l2GatewayCache,
+                                        StaleVlanBindingsCleaner staleVlanBindingsCleaner,
+                                        HwvtepNodeHACache hwvtepNodeHACache) {
+        super(dataBroker,  DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL,
+                InstanceIdentifier.create(NetworkTopology.class)
+                .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID)).child(Node.class)
+                .augmentation(PhysicalSwitchAugmentation.class)),
+                Executors.newListeningSingleThreadExecutor("HwvtepPhysicalSwitchListener", LOG),
+                hwvtepNodeHACache);
         this.dataBroker = dataBroker;
         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
         this.itmRpcService = itmRpcService;
@@ -145,24 +161,31 @@ public class HwvtepPhysicalSwitchListener
                     .getNodeId().getValue())
                     && Objects.equals(globalIid, hwvtepNodeHACache.getParent(existingIid));
         };
+
+        serviceRecoveryRegistry.addRecoverableListener(l2GatewayServiceRecoveryHandler.buildServiceRegistryKey(),
+                this);
     }
 
-    @Override
-    @PostConstruct
     public void init() {
-        registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
+        registerListener();
     }
 
     @Override
-    protected InstanceIdentifier<PhysicalSwitchAugmentation> getWildCardPath() {
-        return InstanceIdentifier.create(NetworkTopology.class)
-                .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID)).child(Node.class)
-                .augmentation(PhysicalSwitchAugmentation.class);
+    public void registerListener() {
+        super.register();
+        LOG.info("Registering HwvtepPhysicalSwitchListener");
+    }
+
+    public void deregisterListener() {
+        super.close();
+        LOG.info("Deregistering HwvtepPhysicalSwitchListener");
     }
 
     @Override
-    protected HwvtepPhysicalSwitchListener getDataTreeChangeListener() {
-        return HwvtepPhysicalSwitchListener.this;
+    @PreDestroy
+    public void close() {
+        super.close();
+        Executors.shutdownAndAwaitTermination(getExecutorService());
     }
 
     @Override
@@ -296,9 +319,9 @@ public class HwvtepPhysicalSwitchListener
             l2GwDevice.setConnected(true);
             l2GwDevice.setHwvtepNodeId(globalNodeId);
 
-            List<TunnelIps> tunnelIps = phySwitchAdded.getTunnelIps();
+            Map<TunnelIpsKey, TunnelIps> tunnelIps = phySwitchAdded.getTunnelIps();
             if (tunnelIps != null) {
-                for (TunnelIps tunnelIp : tunnelIps) {
+                for (TunnelIps tunnelIp : tunnelIps.values()) {
                     IpAddress tunnelIpAddr = tunnelIp.getTunnelIpsKey();
                     l2GwDevice.addTunnelIp(tunnelIpAddr);
                 }
@@ -346,11 +369,11 @@ public class HwvtepPhysicalSwitchListener
      *            the identifier
      * @return the node id
      */
-    private NodeId getNodeId(InstanceIdentifier<PhysicalSwitchAugmentation> identifier) {
+    private static NodeId getNodeId(InstanceIdentifier<PhysicalSwitchAugmentation> identifier) {
         return identifier.firstKeyOf(Node.class).getNodeId();
     }
 
-    private String getManagedByNodeId(InstanceIdentifier<PhysicalSwitchAugmentation> identifier) {
+    private static String getManagedByNodeId(InstanceIdentifier<PhysicalSwitchAugmentation> identifier) {
         String psNodeId = identifier.firstKeyOf(Node.class).getNodeId().getValue();
         if (psNodeId.contains(HwvtepHAUtil.PHYSICALSWITCH)) {
             return psNodeId.substring(0, psNodeId.indexOf(HwvtepHAUtil.PHYSICALSWITCH));
@@ -358,7 +381,9 @@ public class HwvtepPhysicalSwitchListener
         return psNodeId;
     }
 
-    private InstanceIdentifier<Node> getManagedByNodeIid(InstanceIdentifier<PhysicalSwitchAugmentation> identifier) {
+    @Nullable
+    private static InstanceIdentifier<Node> getManagedByNodeIid(
+            InstanceIdentifier<PhysicalSwitchAugmentation> identifier) {
         String psNodeId = identifier.firstKeyOf(Node.class).getNodeId().getValue();
         if (psNodeId.contains(HwvtepHAUtil.PHYSICALSWITCH)) {
             psNodeId = psNodeId.substring(0, psNodeId.indexOf(HwvtepHAUtil.PHYSICALSWITCH));
@@ -367,7 +392,8 @@ public class HwvtepPhysicalSwitchListener
         return null;
     }
 
-    private String getPsName(InstanceIdentifier<PhysicalSwitchAugmentation> identifier) {
+    @Nullable
+    private static String getPsName(InstanceIdentifier<PhysicalSwitchAugmentation> identifier) {
         String psNodeId = identifier.firstKeyOf(Node.class).getNodeId().getValue();
         if (psNodeId.contains(HwvtepHAUtil.PHYSICALSWITCH)) {
             return psNodeId.substring(psNodeId.indexOf(HwvtepHAUtil.PHYSICALSWITCH) + HwvtepHAUtil.PHYSICALSWITCH
@@ -379,16 +405,15 @@ public class HwvtepPhysicalSwitchListener
     private void updateConfigTunnelIp(InstanceIdentifier<PhysicalSwitchAugmentation> identifier,
                                       PhysicalSwitchAugmentation phySwitchAdded) {
         if (phySwitchAdded.getTunnelIps() != null) {
-            ListenableFutures.addErrorLogging(
-                txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
-                    Optional<PhysicalSwitchAugmentation> existingSwitch = tx.read(
-                            LogicalDatastoreType.CONFIGURATION, identifier).checkedGet();
+            LoggingFutures.addErrorLogging(
+                txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
+                    Optional<PhysicalSwitchAugmentation> existingSwitch = tx.read(identifier).get();
                     PhysicalSwitchAugmentationBuilder psBuilder = new PhysicalSwitchAugmentationBuilder();
                     if (existingSwitch.isPresent()) {
                         psBuilder = new PhysicalSwitchAugmentationBuilder(existingSwitch.get());
                     }
                     psBuilder.setTunnelIps(phySwitchAdded.getTunnelIps());
-                    tx.put(LogicalDatastoreType.CONFIGURATION, identifier, psBuilder.build(), true);
+                    tx.mergeParentStructurePut(identifier, psBuilder.build());
                     LOG.trace("Updating config tunnel ips {}", identifier);
                 }), LOG, "Failed to update the config tunnel ips {}", identifier);
         }