DS READ Optimization in NAT
[netvirt.git] / natservice / impl / src / main / java / org / opendaylight / netvirt / natservice / internal / NatVpnMapsChangeListener.java
index 3fc9731761cfcd020f7cd8d41cb49f387e495434..6d71511c30e1e4ee94b5d125d8a003905e946211 100644 (file)
@@ -10,9 +10,11 @@ package org.opendaylight.netvirt.natservice.internal;
 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
 
 import com.google.common.base.Optional;
-import java.math.BigInteger;
+import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.ExecutionException;
+import java.util.stream.Collectors;
+import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
@@ -29,7 +31,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev16011
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.vpnmap.RouterIds;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.Uint32;
+import org.opendaylight.yangtools.yang.common.Uint64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -55,9 +60,11 @@ public class NatVpnMapsChangeListener extends AsyncDataTreeChangeListenerBase<Vp
         this.externalRoutersListener = externalRoutersListener;
     }
 
+    @Override
+    @PostConstruct
     public void init() {
         LOG.info("{} init", getClass().getSimpleName());
-        registerListener(dataBroker);
+        registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
     }
 
     @Override
@@ -65,34 +72,34 @@ public class NatVpnMapsChangeListener extends AsyncDataTreeChangeListenerBase<Vp
         return InstanceIdentifier.create(VpnMaps.class).child(VpnMap.class);
     }
 
-    private void registerListener(final DataBroker db) {
-        registerListener(LogicalDatastoreType.CONFIGURATION, db);
-    }
-
     @Override
     protected void add(InstanceIdentifier<VpnMap> identifier, VpnMap vpnMap) {
         Uuid vpnUuid = vpnMap.getVpnId();
         String vpnName = vpnUuid.getValue();
-        vpnMap.getRouterIds().stream()
+        if (vpnMap.getRouterIds() != null) {
+            vpnMap.getRouterIds().stream()
                 .filter(router -> !(Objects.equals(router.getRouterId(), vpnUuid)))
                 .forEach(router -> {
                     String routerName = router.getRouterId().getValue();
                     LOG.info("REMOVE: Router {} is disassociated from Vpn {}", routerName, vpnName);
                     onRouterAssociatedToVpn(vpnName, routerName);
                 });
+        }
     }
 
     @Override
     protected void remove(InstanceIdentifier<VpnMap> identifier, VpnMap vpnMap) {
         Uuid vpnUuid = vpnMap.getVpnId();
         String vpnName = vpnUuid.getValue();
-        vpnMap.getRouterIds().stream()
+        if (vpnMap.getRouterIds() != null) {
+            vpnMap.getRouterIds().stream()
                 .filter(router -> !(Objects.equals(router.getRouterId(), vpnUuid)))
                 .forEach(router -> {
                     String routerName = router.getRouterId().getValue();
                     LOG.info("REMOVE: Router {} is disassociated from Vpn {}", routerName, vpnName);
                     onRouterDisassociatedFromVpn(vpnName, routerName);
                 });
+        }
     }
 
     @Override
@@ -100,21 +107,44 @@ public class NatVpnMapsChangeListener extends AsyncDataTreeChangeListenerBase<Vp
         Uuid vpnUuid = updated.getVpnId();
         String vpnName = vpnUuid.getValue();
 
-        updated.getRouterIds().stream()
-                .filter(router -> ! original.getRouterIds().contains(router))
+        List<RouterIds> updatedRouterIdList = updated.getRouterIds();
+        List<RouterIds> originalRouterIdList = original.getRouterIds();
+        List<RouterIds> routersAddedList = null;
+        List<RouterIds> routersRemovedList = null;
+
+        if (originalRouterIdList == null && updatedRouterIdList != null) {
+            routersAddedList = updatedRouterIdList;
+        } else if (originalRouterIdList != null && updatedRouterIdList != null) {
+            routersAddedList = updatedRouterIdList.stream()
+                .filter(routerId -> (!originalRouterIdList.contains(routerId)))
+                .collect(Collectors.toList());
+        }
+
+        if (originalRouterIdList != null && updatedRouterIdList == null) {
+            routersRemovedList = originalRouterIdList;
+        } else if (originalRouterIdList != null && updatedRouterIdList != null) {
+            routersRemovedList = originalRouterIdList.stream()
+                .filter(routerId -> (!updatedRouterIdList.contains(routerId)))
+                .collect(Collectors.toList());
+        }
+
+        if (routersAddedList != null) {
+            routersAddedList.stream()
                 .filter(router -> !(Objects.equals(router.getRouterId(), updated.getVpnId())))
                 .forEach(router -> {
                     String routerName = router.getRouterId().getValue();
                     onRouterAssociatedToVpn(vpnName, routerName);
                 });
+        }
 
-        original.getRouterIds().stream()
-                .filter(router -> ! updated.getRouterIds().contains(router))
+        if (routersRemovedList != null) {
+            routersRemovedList.stream()
                 .filter(router -> !(Objects.equals(router.getRouterId(), original.getVpnId())))
                 .forEach(router -> {
                     String routerName = router.getRouterId().getValue();
                     onRouterDisassociatedFromVpn(vpnName, routerName);
                 });
+        }
     }
 
     @Override
@@ -142,10 +172,10 @@ public class NatVpnMapsChangeListener extends AsyncDataTreeChangeListenerBase<Vp
                     LOG.error("onRouterAssociatedToVpn : External Network Provider Type missing");
                     return;
                 }
-                long routerId = NatUtil.getVpnId(dataBroker, routerName);
+                Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
                 txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
-                    tx -> externalRoutersListener.changeLocalVpnIdToBgpVpnId(routerName, routerId, vpnName, tx,
-                                extNwProvType)).get();
+                    tx -> externalRoutersListener.changeLocalVpnIdToBgpVpnId(routerName, routerId, extNetwork,
+                        vpnName, tx, extNwProvType)).get();
             } catch (InterruptedException | ExecutionException e) {
                 LOG.error("Error changling local VPN identifier to BGP VPN identifier", e);
             }
@@ -180,10 +210,10 @@ public class NatVpnMapsChangeListener extends AsyncDataTreeChangeListenerBase<Vp
                     LOG.error("onRouterDisassociatedFromVpn : External Network Provider Type missing");
                     return;
                 }
-                long routerId = NatUtil.getVpnId(dataBroker, routerName);
+                Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
                 txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
-                    tx -> externalRoutersListener.changeBgpVpnIdToLocalVpnId(routerName, routerId, vpnName, tx,
-                                extNwProvType)).get();
+                    tx -> externalRoutersListener.changeBgpVpnIdToLocalVpnId(routerName, routerId, extNetwork,
+                        vpnName, tx, extNwProvType)).get();
             } catch (InterruptedException | ExecutionException e) {
                 LOG.error("Error changing BGP VPN identifier to local VPN identifier", e);
             }
@@ -206,8 +236,8 @@ public class NatVpnMapsChangeListener extends AsyncDataTreeChangeListenerBase<Vp
         Uuid networkId = Uuid.getDefaultInstance(externalNetwork);
         for (Ports port : optRouterPorts.get().nonnullPorts()) {
             String portName = port.getPortName();
-            BigInteger dpnId = NatUtil.getDpnForInterface(interfaceManager, portName);
-            if (dpnId.equals(BigInteger.ZERO)) {
+            Uint64 dpnId = NatUtil.getDpnForInterface(interfaceManager, portName);
+            if (dpnId.equals(Uint64.ZERO)) {
                 LOG.warn("handleDNATConfigurationForRouterAssociation : DPN not found for {}, "
                         + "skip handling of router {} association with vpn {}", portName, routerName, vpnName);
                 continue;
@@ -238,8 +268,8 @@ public class NatVpnMapsChangeListener extends AsyncDataTreeChangeListenerBase<Vp
         Uuid networkId = Uuid.getDefaultInstance(externalNetwork);
         for (Ports port : optRouterPorts.get().nonnullPorts()) {
             String portName = port.getPortName();
-            BigInteger dpnId = NatUtil.getDpnForInterface(interfaceManager, portName);
-            if (dpnId.equals(BigInteger.ZERO)) {
+            Uint64 dpnId = NatUtil.getDpnForInterface(interfaceManager, portName);
+            if (dpnId.equals(Uint64.ZERO)) {
                 LOG.debug("handleDNATConfigurationForRouterDisassociation : DPN not found for {}, "
                         + "skip handling of router {} association with vpn {}", portName, routerName, vpnName);
                 continue;