Migrate ListenableFutures.addErrorLogging() users
[netvirt.git] / natservice / impl / src / main / java / org / opendaylight / netvirt / natservice / ha / WeightedCentralizedSwitchScheduler.java
index dce1357832b52e3c6fe648f1299711bf65f612f7..69d93ed215381307b793b8f7e55aa46980eaa912 100644 (file)
@@ -11,30 +11,30 @@ package org.opendaylight.netvirt.natservice.ha;
 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
 import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
 
-import com.google.common.base.Optional;
-
-import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutionException;
-
 import javax.inject.Inject;
 import javax.inject.Singleton;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.genius.datastoreutils.ExpectedDataObjectNotFoundException;
 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
-import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
+import org.opendaylight.infrautils.utils.concurrent.LoggingFutures;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
 import org.opendaylight.netvirt.natservice.api.CentralizedSwitchScheduler;
+import org.opendaylight.netvirt.natservice.api.NatSwitchCache;
+import org.opendaylight.netvirt.natservice.api.NatSwitchCacheListener;
+import org.opendaylight.netvirt.natservice.api.SwitchInfo;
 import org.opendaylight.netvirt.natservice.internal.NatUtil;
 import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
@@ -44,6 +44,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev16011
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIpsKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
@@ -52,15 +53,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev15060
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.Uint64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Singleton
-public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchScheduler {
+public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchScheduler, NatSwitchCacheListener {
     private static final Logger LOG = LoggerFactory.getLogger(WeightedCentralizedSwitchScheduler.class);
     private static final Integer INITIAL_SWITCH_WEIGHT = Integer.valueOf(0);
 
-    private final Map<String, Map<BigInteger,Integer>> providerSwitchWeightsMap = new ConcurrentHashMap<>();
+    private final Map<String, Map<Uint64,Integer>> providerSwitchWeightsMap = new ConcurrentHashMap<>();
     private final Map<String,String> subnetIdToRouterPortMap = new ConcurrentHashMap<>();
     private final Map<String,String> subnetIdToElanInstanceMap = new ConcurrentHashMap<>();
     private final DataBroker dataBroker;
@@ -70,8 +72,10 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
     private final NatserviceConfig.NatMode natMode;
 
     @Inject
-    public WeightedCentralizedSwitchScheduler(DataBroker dataBroker, OdlInterfaceRpcService interfaceManager,
-            IVpnFootprintService vpnFootprintService, final NatserviceConfig config) {
+    public WeightedCentralizedSwitchScheduler(final DataBroker dataBroker,
+            final OdlInterfaceRpcService interfaceManager,
+            final IVpnFootprintService vpnFootprintService, final NatserviceConfig config,
+            final NatSwitchCache natSwitchCache) {
         this.dataBroker = dataBroker;
         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
         this.interfaceManager = interfaceManager;
@@ -81,13 +85,14 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
         } else {
             this.natMode = NatserviceConfig.NatMode.Controller;
         }
+        natSwitchCache.register(this);
     }
 
     @Override
     public boolean scheduleCentralizedSwitch(Routers router) {
         String providerNet = NatUtil.getElanInstancePhysicalNetwok(router.getNetworkId().getValue(),dataBroker);
-        BigInteger nextSwitchId = getSwitchWithLowestWeight(providerNet);
-        if (nextSwitchId == BigInteger.valueOf(0)) {
+        Uint64 nextSwitchId = getSwitchWithLowestWeight(providerNet);
+        if (Uint64.ZERO.equals(nextSwitchId)) {
             LOG.error("In scheduleCentralizedSwitch, unable to schedule the router {} as there is no available switch.",
                     router.getRouterName());
             return false;
@@ -103,7 +108,7 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
         try {
             SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
                     getNaptSwitchesIdentifier(routerName), id);
-            Map<BigInteger,Integer> switchWeightMap = providerSwitchWeightsMap.get(providerNet);
+            Map<Uint64,Integer> switchWeightMap = providerSwitchWeightsMap.get(providerNet);
             switchWeightMap.put(nextSwitchId,switchWeightMap.get(nextSwitchId) + 1);
 
         } catch (TransactionCommitFailedException e) {
@@ -119,7 +124,7 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
         String routerName = newRouter.getRouterName();
         List<Uuid> addedSubnetIds = getUpdatedSubnetIds(newRouter.getSubnetIds(), oldRouter.getSubnetIds());
         List<Uuid> deletedSubnetIds = getUpdatedSubnetIds(oldRouter.getSubnetIds(), newRouter.getSubnetIds());
-        BigInteger primarySwitchId = NatUtil.getPrimaryNaptfromRouterName(dataBroker, newRouter.getRouterName());
+        Uint64 primarySwitchId = NatUtil.getPrimaryNaptfromRouterName(dataBroker, newRouter.getRouterName());
         addToDpnMaps(routerName, addedSubnetIds, primarySwitchId);
         deleteFromDpnMaps(routerName, deletedSubnetIds, primarySwitchId);
         try {
@@ -127,8 +132,8 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
             RouterToNaptSwitch routerToNaptSwitch = SingleTransactionDataBroker.syncRead(dataBroker,
                     LogicalDatastoreType.CONFIGURATION, id);
             boolean isSnatEnabled = newRouter.isEnableSnat();
-            List<ExternalIps> updateExternalIps = newRouter.getExternalIps();
-            if (updateExternalIps == null || updateExternalIps.isEmpty()) {
+            Map<ExternalIpsKey, ExternalIps> updateExternalIpsMap = newRouter.getExternalIps();
+            if (updateExternalIpsMap == null || updateExternalIpsMap.isEmpty()) {
                 isSnatEnabled = false;
             }
             if (isSnatEnabled != routerToNaptSwitch.isEnableSnat()) {
@@ -138,7 +143,7 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
                 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
                         getNaptSwitchesIdentifier(routerName), routerToNaptSwitchBuilder.build());
             }
-        } catch (ReadFailedException e) {
+        } catch (ExpectedDataObjectNotFoundException e) {
             LOG.error("updateCentralizedSwitch ReadFailedException for {}", routerName);
         } catch (TransactionCommitFailedException e) {
             LOG.error("updateCentralizedSwitch TransactionCommitFailedException for {}", routerName);
@@ -150,8 +155,8 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
     public boolean releaseCentralizedSwitch(Routers router) {
         String providerNet = NatUtil.getElanInstancePhysicalNetwok(router.getNetworkId().getValue(),dataBroker);
         String routerName = router.getRouterName();
-        BigInteger primarySwitchId = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
-        if (primarySwitchId == null || primarySwitchId == BigInteger.valueOf(0)) {
+        Uint64 primarySwitchId = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
+        if (primarySwitchId == null || Uint64.ZERO.equals(primarySwitchId)) {
             LOG.info("releaseCentralizedSwitch: NAPT Switch is not allocated for router {}", router.getRouterName());
             return false;
         }
@@ -161,7 +166,7 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
         try {
             SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
                     getNaptSwitchesIdentifier(routerName));
-            Map<BigInteger,Integer> switchWeightMap = providerSwitchWeightsMap.get(providerNet);
+            Map<Uint64,Integer> switchWeightMap = providerSwitchWeightsMap.get(providerNet);
             switchWeightMap.put(primarySwitchId, switchWeightMap.get(primarySwitchId) - 1);
         } catch (TransactionCommitFailedException e) {
             return false;
@@ -169,7 +174,7 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
         return true;
     }
 
-    private void addToDpnMaps(String routerName, List<Uuid> addedSubnetIds, BigInteger primarySwitchId) {
+    private void addToDpnMaps(String routerName, List<Uuid> addedSubnetIds, Uint64 primarySwitchId) {
         if (addedSubnetIds == null || addedSubnetIds.isEmpty()) {
             LOG.debug("addToDpnMaps no subnets associated with {}", routerName);
             return;
@@ -178,14 +183,14 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
         try {
             String primaryRd = txRunner.applyWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
                 for (Uuid subnetUuid : addedSubnetIds) {
-                    Subnetmap subnetMapEntry = tx.read(getSubnetMapIdentifier(subnetUuid)).get().orNull();
+                    Subnetmap subnetMapEntry = tx.read(getSubnetMapIdentifier(subnetUuid)).get().orElse(null);
                     subnetMapEntries.put(subnetUuid, subnetMapEntry);
                     Uuid routerPortUuid = subnetMapEntry.getRouterInterfacePortId();
                     subnetIdToRouterPortMap.put(subnetUuid.getValue(), routerPortUuid.getValue());
                 }
                 return NatUtil.getPrimaryRd(routerName, tx);
             }).get();
-            ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx -> {
+            LoggingFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx -> {
                 for (Uuid subnetUuid : addedSubnetIds) {
                     Subnetmap subnetMapEntry = subnetMapEntries.get(subnetUuid);
                     Uuid routerPortUuid = subnetMapEntry.getRouterInterfacePortId();
@@ -205,9 +210,7 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
         }
     }
 
-
-
-    private void deleteFromDpnMaps(String routerName, List<Uuid> deletedSubnetIds, BigInteger primarySwitchId) {
+    private void deleteFromDpnMaps(String routerName, List<Uuid> deletedSubnetIds, Uint64 primarySwitchId) {
         if (deletedSubnetIds == null || deletedSubnetIds.isEmpty()) {
             LOG.debug("deleteFromDpnMaps no subnets associated with {}", routerName);
             return;
@@ -215,7 +218,7 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
         try {
             String primaryRd = txRunner.applyWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
                 tx -> NatUtil.getPrimaryRd(routerName, tx)).get();
-            ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx -> {
+            LoggingFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx -> {
                 for (Uuid subnetUuid : deletedSubnetIds) {
                     String routerPort = subnetIdToRouterPortMap.remove(subnetUuid.getValue());
                     if (routerPort == null) {
@@ -240,35 +243,33 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
     }
 
     @Override
-    public boolean addSwitch(BigInteger dpnId) {
-        /* Initialize the switch in the map with weight 0 */
-        LOG.info("addSwitch: Retrieving the provider config for {}", dpnId);
+    public void switchAddedToCache(SwitchInfo switchInfo) {
         boolean scheduleRouters = (providerSwitchWeightsMap.size() == 0) ? true : false;
-        Map<String, String> providerMappingsMap = NatUtil.getOpenvswitchOtherConfigMap(dpnId, dataBroker);
-        for (String providerNet : providerMappingsMap.keySet()) {
-            Map<BigInteger,Integer> switchWeightMap = providerSwitchWeightsMap.get(providerNet);
+        for (String providerNet : switchInfo.getProviderNets()) {
+            Map<Uint64,Integer> switchWeightMap = providerSwitchWeightsMap.get(providerNet);
             if (providerSwitchWeightsMap.get(providerNet) == null) {
                 switchWeightMap = new ConcurrentHashMap<>();
                 providerSwitchWeightsMap.put(providerNet, switchWeightMap);
             }
-            LOG.info("addSwitch: Adding {} dpnId with provider mapping {} to switchWeightsMap", dpnId, providerNet);
-            switchWeightMap.put(dpnId, INITIAL_SWITCH_WEIGHT);
+            LOG.info("addSwitch: Adding {} dpnId with provider mapping {} to switchWeightsMap",
+                    switchInfo.getDpnId(), providerNet);
+            switchWeightMap.put(switchInfo.getDpnId(), INITIAL_SWITCH_WEIGHT);
         }
         if (natMode == NatserviceConfig.NatMode.Conntrack && scheduleRouters) {
             Optional<ExtRouters> optRouters;
             try {
                 optRouters = SingleTransactionDataBroker.syncReadOptional(dataBroker,
                         LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(ExtRouters.class));
-            } catch (ReadFailedException e) {
+            } catch (InterruptedException | ExecutionException e) {
                 LOG.error("addSwitch: Error reading external routers", e);
-                return false;
+                return;
             }
 
             if (optRouters.isPresent()) {
                 // Get the list of routers and verify if any routers do not have primarySwitch allocated.
-                for (Routers router : optRouters.get().getRouters()) {
-                    List<ExternalIps> externalIps = router.getExternalIps();
-                    if (router.isEnableSnat() && externalIps != null && !externalIps.isEmpty()) {
+                for (Routers router : optRouters.get().nonnullRouters().values()) {
+                    Map<ExternalIpsKey, ExternalIps> keyExternalIpsMap = router.getExternalIps();
+                    if (router.isEnableSnat() && keyExternalIpsMap != null && !keyExternalIpsMap.isEmpty()) {
                         // Check if the primarySwitch is allocated for the router.
                         if (!isPrimarySwitchAllocatedForRouter(router.getRouterName())) {
                             scheduleCentralizedSwitch(router);
@@ -277,7 +278,7 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
                 }
             }
         }
-        return true;
+        return;
     }
 
     private boolean isPrimarySwitchAllocatedForRouter(String routerName) {
@@ -286,11 +287,11 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
         try {
             RouterToNaptSwitch rtrToNapt = SingleTransactionDataBroker.syncRead(dataBroker,
                     LogicalDatastoreType.CONFIGURATION, routerToNaptSwitch);
-            BigInteger dpnId = rtrToNapt.getPrimarySwitchId();
-            if (dpnId == null || dpnId.equals(BigInteger.ZERO)) {
+            Uint64 dpnId = rtrToNapt.getPrimarySwitchId();
+            if (dpnId == null || dpnId.equals(Uint64.ZERO)) {
                 return false;
             }
-        } catch (ReadFailedException e) {
+        } catch (ExpectedDataObjectNotFoundException e) {
             LOG.error("isPrimarySwitchAllocatedForRouter: Error reading RouterToNaptSwitch model", e);
             return false;
         }
@@ -298,14 +299,15 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
     }
 
     @Override
-    public boolean removeSwitch(BigInteger dpnId) {
+    public void switchRemovedFromCache(SwitchInfo switchInfo) {
+        Uint64 dpnId = switchInfo.getDpnId();
         LOG.info("removeSwitch: Removing {} dpnId to switchWeightsMap", dpnId);
-        for (Map.Entry<String,Map<BigInteger,Integer>> providerNet : providerSwitchWeightsMap.entrySet()) {
-            Map<BigInteger,Integer> switchWeightMap = providerNet.getValue();
+        for (Map.Entry<String,Map<Uint64,Integer>> providerNet : providerSwitchWeightsMap.entrySet()) {
+            Map<Uint64,Integer> switchWeightMap = providerNet.getValue();
             if (natMode == NatserviceConfig.NatMode.Conntrack
                     && !INITIAL_SWITCH_WEIGHT.equals(switchWeightMap.get(dpnId))) {
                 NaptSwitches naptSwitches = getNaptSwitches();
-                for (RouterToNaptSwitch routerToNaptSwitch : naptSwitches.getRouterToNaptSwitch()) {
+                for (RouterToNaptSwitch routerToNaptSwitch : naptSwitches.nonnullRouterToNaptSwitch().values()) {
                     if (dpnId.equals(routerToNaptSwitch.getPrimarySwitchId())) {
                         Routers router = NatUtil.getRoutersFromConfigDS(dataBroker, routerToNaptSwitch.getRouterName());
                         releaseCentralizedSwitch(router);
@@ -316,25 +318,30 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
             }
             switchWeightMap.remove(dpnId);
         }
-        return true;
+        return;
     }
 
     private NaptSwitches getNaptSwitches() {
         InstanceIdentifier<NaptSwitches> id = InstanceIdentifier.builder(NaptSwitches.class).build();
-        return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
-                LogicalDatastoreType.CONFIGURATION, id).orNull();
+        try {
+            return SingleTransactionDataBroker.syncReadOptional(dataBroker,
+                    LogicalDatastoreType.CONFIGURATION, id).orElse(null);
+        } catch (ExecutionException | InterruptedException e) {
+            LOG.error("getNaptSwitches: Exception while reading Napt-Switch DS", e);
+        }
+        return null;
     }
 
-    private BigInteger getSwitchWithLowestWeight(String providerNet) {
+    private Uint64 getSwitchWithLowestWeight(String providerNet) {
         int lowestWeight = Integer.MAX_VALUE;
-        BigInteger nextSwitchId = BigInteger.valueOf(0);
-        Map<BigInteger,Integer> switchWeightMap = providerSwitchWeightsMap.get(providerNet);
+        Uint64 nextSwitchId = Uint64.valueOf(0);
+        Map<Uint64,Integer> switchWeightMap = providerSwitchWeightsMap.get(providerNet);
         if (null == switchWeightMap) {
             LOG.error("No switch have the provider mapping {}", providerNet);
             return nextSwitchId;
         }
-        for (Entry<BigInteger, Integer> entry : switchWeightMap.entrySet()) {
-            BigInteger dpnId = entry.getKey();
+        for (Entry<Uint64, Integer> entry : switchWeightMap.entrySet()) {
+            Uint64 dpnId = entry.getKey();
             Integer weight = entry.getValue();
             if (lowestWeight > weight) {
                 lowestWeight = weight;
@@ -356,7 +363,8 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
                 new SubnetmapKey(subnetId)).build();
     }
 
-    public BigInteger getCentralizedSwitch(String routerName) {
+    @Nullable
+    public Uint64 getCentralizedSwitch(String routerName) {
         try {
             Optional<RouterToNaptSwitch> naptSwitches = SingleTransactionDataBroker
                     .syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
@@ -366,24 +374,14 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
                 return null;
             }
             return naptSwitches.get().getPrimarySwitchId();
-        } catch (ReadFailedException e) {
+        } catch (InterruptedException | ExecutionException e) {
             LOG.error("Error reading RouterToNaptSwitch model", e);
             return null;
         }
     }
 
-    @Override
-    public boolean isSwitchConnectedToExternal(BigInteger dpnId, String providerNet) {
-        Map<BigInteger,Integer> switchWeightMap = providerSwitchWeightsMap.get(providerNet);
-        if (switchWeightMap != null) {
-            return switchWeightMap.containsKey(dpnId);
-        }
-        return false;
-    }
-
-    public static List<Uuid> getUpdatedSubnetIds(
-            List<Uuid> updatedSubnetIds,
-            List<Uuid> currentSubnetIds) {
+    @Nullable
+    private static List<Uuid> getUpdatedSubnetIds(List<Uuid> updatedSubnetIds, List<Uuid> currentSubnetIds) {
         if (updatedSubnetIds == null) {
             return null;
         }