MRI version bumpup for Aluminium
[netvirt.git] / natservice / impl / src / main / java / org / opendaylight / netvirt / natservice / internal / NatVpnMapsChangeListener.java
index 994c16f37db6e1100ab0dce60b0819272d6b85e1..f30f9aefbc2e1f93d4e50e5d83cea4fb2a512c58 100644 (file)
@@ -8,21 +8,23 @@
 package org.opendaylight.netvirt.natservice.internal;
 
 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
-import static org.opendaylight.netvirt.natservice.internal.NatUtil.requireNonNullElse;
 
-import com.google.common.base.Optional;
-import java.math.BigInteger;
-import java.util.Collections;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.concurrent.ExecutionException;
+import java.util.stream.Collectors;
+import javax.annotation.PreDestroy;
 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.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.infrautils.utils.concurrent.Executors;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.serviceutils.tools.listener.AbstractAsyncDataTreeChangeListener;
 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.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
@@ -31,12 +33,15 @@ 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;
 
 @Singleton
-public class NatVpnMapsChangeListener extends AsyncDataTreeChangeListenerBase<VpnMap, NatVpnMapsChangeListener> {
+public class NatVpnMapsChangeListener extends AbstractAsyncDataTreeChangeListener<VpnMap> {
     private static final Logger LOG = LoggerFactory.getLogger(NatVpnMapsChangeListener.class);
     private final DataBroker dataBroker;
     private final ManagedNewTransactionRunner txRunner;
@@ -49,7 +54,9 @@ public class NatVpnMapsChangeListener extends AsyncDataTreeChangeListenerBase<Vp
                                final FloatingIPListener floatingIpListener,
                                final OdlInterfaceRpcService interfaceManager,
                                final ExternalRoutersListener externalRoutersListener) {
-        super(VpnMap.class, NatVpnMapsChangeListener.class);
+        super(dataBroker, LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(VpnMaps.class)
+                .child(VpnMap.class),
+                Executors.newListeningSingleThreadExecutor("NatVpnMapsChangeListener", LOG));
         this.dataBroker = dataBroker;
         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
         this.floatingIpListener = floatingIpListener;
@@ -59,69 +66,88 @@ public class NatVpnMapsChangeListener extends AsyncDataTreeChangeListenerBase<Vp
 
     public void init() {
         LOG.info("{} init", getClass().getSimpleName());
-        registerListener(dataBroker);
     }
 
     @Override
-    protected InstanceIdentifier<VpnMap> getWildCardPath() {
-        return InstanceIdentifier.create(VpnMaps.class).child(VpnMap.class);
-    }
-
-    private void registerListener(final DataBroker db) {
-        registerListener(LogicalDatastoreType.CONFIGURATION, db);
+    @PreDestroy
+    public void close() {
+        super.close();
+        Executors.shutdownAndAwaitTermination(getExecutorService());
     }
 
     @Override
-    protected void add(InstanceIdentifier<VpnMap> identifier, VpnMap vpnMap) {
+    public void add(InstanceIdentifier<VpnMap> identifier, VpnMap vpnMap) {
         Uuid vpnUuid = vpnMap.getVpnId();
         String vpnName = vpnUuid.getValue();
-        vpnMap.getRouterIds().stream()
+        if (vpnMap.getRouterIds() != null) {
+            vpnMap.getRouterIds().values().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) {
+    public void remove(InstanceIdentifier<VpnMap> identifier, VpnMap vpnMap) {
         Uuid vpnUuid = vpnMap.getVpnId();
         String vpnName = vpnUuid.getValue();
-        vpnMap.getRouterIds().stream()
+        if (vpnMap.getRouterIds() != null) {
+            vpnMap.getRouterIds().values().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
-    protected void update(InstanceIdentifier<VpnMap> identifier, VpnMap original, VpnMap updated) {
+    public void update(InstanceIdentifier<VpnMap> identifier, VpnMap original, VpnMap updated) {
         Uuid vpnUuid = updated.getVpnId();
         String vpnName = vpnUuid.getValue();
 
-        updated.getRouterIds().stream()
-                .filter(router -> ! original.getRouterIds().contains(router))
+        List<RouterIds> updatedRouterIdList = new ArrayList<RouterIds>(updated.getRouterIds().values());
+        List<RouterIds> originalRouterIdList = new ArrayList<RouterIds>(original.getRouterIds().values());
+        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
-    protected NatVpnMapsChangeListener getDataTreeChangeListener() {
-        return this;
+        }
     }
 
     public void onRouterAssociatedToVpn(String vpnName, String routerName) {
@@ -144,10 +170,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);
             }
@@ -182,10 +208,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,17 +232,16 @@ public class NatVpnMapsChangeListener extends AsyncDataTreeChangeListenerBase<Vp
             return;
         }
         Uuid networkId = Uuid.getDefaultInstance(externalNetwork);
-        for (Ports port : requireNonNullElse(optRouterPorts.get().getPorts(), Collections.<Ports>emptyList())) {
+        for (Ports port : optRouterPorts.get().nonnullPorts().values()) {
             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;
             }
 
-            for (InternalToExternalPortMap intExtPortMap : requireNonNullElse(port.getInternalToExternalPortMap(),
-                    Collections.<InternalToExternalPortMap>emptyList())) {
+            for (InternalToExternalPortMap intExtPortMap : port.nonnullInternalToExternalPortMap().values()) {
                 //remove all NAT related entries with routerName
                 //floatingIpListener.removeNATOnlyFlowEntries(dpnId, portName, routerName, null,
                 // intExtPortMap.getInternalIp(), externalIp);
@@ -239,16 +264,15 @@ public class NatVpnMapsChangeListener extends AsyncDataTreeChangeListenerBase<Vp
             return;
         }
         Uuid networkId = Uuid.getDefaultInstance(externalNetwork);
-        for (Ports port : requireNonNullElse(optRouterPorts.get().getPorts(), Collections.<Ports>emptyList())) {
+        for (Ports port : optRouterPorts.get().nonnullPorts().values()) {
             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;
             }
-            for (InternalToExternalPortMap intExtPortMap : requireNonNullElse(port.getInternalToExternalPortMap(),
-                    Collections.<InternalToExternalPortMap>emptyList())) {
+            for (InternalToExternalPortMap intExtPortMap : port.nonnullInternalToExternalPortMap().values()) {
                 //remove all NAT related entries with routerName
                 //floatingIpListener.removeNATOnlyFlowEntries(dpnId, portName, routerName, vpnName,
                 // intExtPortMap.getInternalIp(), externalIp);