NETVIRT-1076: refactor arrow anti-patterns 03/68203/17
authorValentina <valentina.krasnobaeva@6wind.com>
Tue, 13 Feb 2018 16:53:06 +0000 (17:53 +0100)
committerSam Hague <shague@redhat.com>
Tue, 20 Mar 2018 11:21:05 +0000 (11:21 +0000)
* NeutronvpnUtils:

    ** getSubnetMapsforNetworkRoute() method is replaced by
       getPrivateSubnetsToExport(), which obtains the list of private
       subnets from router in more simple way;
    ** addExternalNetworkToVpn() and removeExternalNetworkFromVpn() were
       moved to NeutronvpnManager to avoid import collisions.

* NeutronvpnNatManager:

    ** use getPrivateSubnetsToExport() instead of
       getSubnetMapsforNetworkRoute();
    ** fix log messages.

* NeutronvpnManager:

    ** refactor arrow anti-patterns in associateNetworksToVpn() and
       dissociateNetworksFromVpn() methods;
    ** add a support of use-case, when BGPVPN can be associated with more
       than one Provider Network;
    ** fix log messages;

JIRA: NETVIRT-1076
Change-Id: Ifea2e0d2c2631ac87a3883f5a59d5fd3f189f812
Signed-off-by: Valentina <valentina.krasnobaeva@6wind.com>
neutronvpn/impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnManager.java
neutronvpn/impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnNatManager.java
neutronvpn/impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnUtils.java

index 001653bc78d621b1466310ffd7b2ba421bc26764..bee549712b17b4d06cdbbe282cc99a612a438268 100644 (file)
@@ -88,6 +88,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adj
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry.BgpvpnType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksBuilder;
@@ -2147,7 +2148,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
             dissociateRouterFromVpn(id, router);
         }
         // dissociate networks
-        if (!id.equals(router)) {
+        if (!id.equals(router) && vpnMap.getNetworkIds() != null) {
             dissociateNetworksFromVpn(id, vpnMap.getNetworkIds());
         }
         // remove entire vpnMaps node
@@ -2232,205 +2233,248 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         }
     }
 
+    /**
+     * Parses and associates networks list with given VPN.
+     *
+     * @param vpnId Uuid of given VPN.
+     * @param networks List list of network Ids (Uuid), which will be associated.
+     * @return list of formatted strings with detailed error messages.
+     */
     @Nonnull
-    protected List<String> associateNetworksToVpn(Uuid vpn, List<Uuid> networks) {
+    protected List<String> associateNetworksToVpn(@Nonnull Uuid vpnId, @Nonnull List<Uuid> networks) {
         List<String> failedNwList = new ArrayList<>();
-        List<Uuid> passedNwList = new ArrayList<>();
-        if (!networks.isEmpty()) {
-            VpnInstance vpnInstance = VpnHelper.getVpnInstance(dataBroker, vpn.getValue());
-            if (vpnInstance == null) {
-                return Collections.singletonList(
-                        formatAndLog(LOG::error, "Failed to associate network on vpn {} as vpn is not present",
-                                vpn.getValue()));
-            }
-            // process corresponding subnets for VPN
+        HashSet<Uuid> passedNwList = new HashSet<>();
+        if (networks.isEmpty()) {
+            LOG.error("associateNetworksToVpn: Failed as given networks list is empty, VPN Id: {}", vpnId.getValue());
+            failedNwList.add(String.format("Failed to associate networks with VPN %s as given networks list is empty",
+                                           vpnId.getValue()));
+            return failedNwList;
+        }
+        VpnInstance vpnInstance = VpnHelper.getVpnInstance(dataBroker, vpnId.getValue());
+        if (vpnInstance == null) {
+            LOG.error("associateNetworksToVpn: Can not find vpnInstance for VPN {} in ConfigDS", vpnId.getValue());
+            failedNwList.add(String.format("Failed to associate network: can not found vpnInstance for VPN %s "
+                                           + "in ConfigDS", vpnId.getValue()));
+            return failedNwList;
+        }
+        try {
+            if (isVpnOfTypeL2(vpnInstance) && neutronEvpnUtils.isVpnAssociatedWithNetwork(vpnInstance)) {
+                LOG.error("associateNetworksToVpn: EVPN {} supports only one network to be associated with",
+                          vpnId.getValue());
+                failedNwList.add(String.format("Failed to associate network: EVPN %s supports only one network to be "
+                                               + "associated with", vpnId.getValue()));
+                return failedNwList;
+            }
             for (Uuid nw : networks) {
                 Network network = neutronvpnUtils.getNeutronNetwork(nw);
                 if (network == null) {
-                    failedNwList.add("network " + nw.getValue() + " not found");
+                    LOG.error("associateNetworksToVpn: Network {} not found in ConfigDS", nw.getValue());
+                    failedNwList.add(String.format("Failed to associate network: network %s not found in ConfigDS",
+                                                   nw.getValue()));
                     continue;
                 }
-
                 NetworkProviderExtension providerExtension = network.getAugmentation(NetworkProviderExtension.class);
                 if (providerExtension.getSegments() != null && providerExtension.getSegments().size() > 1) {
-                    failedNwList.add(formatAndLog(LOG::error,
-                            "Failed to associate network {} on vpn {} as it is multisegmented.", nw.getValue(),
-                            vpn.getValue()));
+                    LOG.error("associateNetworksToVpn: MultiSegmented network {} not supported in BGPVPN {}",
+                              nw.getValue(), vpnId.getValue());
+                    failedNwList.add(String.format("Failed to associate multisegmented network %s with BGPVPN %s",
+                                                   nw.getValue(), vpnId.getValue()));
                     continue;
                 }
-                try {
-                    Uuid vpnId = neutronvpnUtils.getVpnForNetwork(nw);
-                    if (vpnId != null) {
-                        failedNwList.add(
-                                "network " + nw.getValue() + " already associated to another VPN " + vpnId.getValue());
-                    } else if (isVpnOfTypeL2(vpnInstance)
-                            && neutronEvpnUtils.isVpnAssociatedWithNetwork(vpnInstance)) {
-                        LOG.error("EVPN supports only one network to be associated");
-                        failedNwList.add("EVPN supports only one network to be associated");
+                Uuid networkVpnId = neutronvpnUtils.getVpnForNetwork(nw);
+                if (networkVpnId != null) {
+                    LOG.error("associateNetworksToVpn: Network {} already associated with another VPN {}",
+                              nw.getValue(), networkVpnId.getValue());
+                    failedNwList.add(String.format("Failed to associate network %s as it is already associated to "
+                                                   + "another VPN %s", nw.getValue(), networkVpnId.getValue()));
+                    continue;
+                }
+                if (neutronvpnUtils.getIsExternal(network)) {
+                    if (associateExtNetworkToVpn(vpnId, network)) {
+                        passedNwList.add(nw);
+                        continue;
                     } else {
-                        List<Uuid> networkSubnets = neutronvpnUtils.getSubnetIdsFromNetworkId(nw);
-                        LOG.debug("Adding network subnets...{}", networkSubnets);
-                        if (networkSubnets != null) {
-                            for (Uuid subnet : networkSubnets) {
-                                // check if subnet added as router interface to some router
-                                Uuid subnetVpnId = neutronvpnUtils.getVpnForSubnet(subnet);
-                                if (subnetVpnId == null) {
-                                    Subnetmap sn = neutronvpnUtils.getSubnetmap(subnet);
-                                    if (neutronvpnUtils.shouldVpnHandleIpVersionChangeToAdd(sn, vpn)) {
-                                        neutronvpnUtils.updateVpnInstanceWithIpFamily(vpn.getValue(),
-                                                NeutronvpnUtils.getIpVersionFromString(sn.getSubnetIp()), true);
-                                    }
-                                    if (sn != null && sn.getInternetVpnId() != null) {
-                                        if (neutronvpnUtils.shouldVpnHandleIpVersionChangeToAdd(sn,
-                                                            sn.getInternetVpnId())) {
-                                            neutronvpnUtils.updateVpnInstanceWithIpFamily(sn
-                                                            .getInternetVpnId().getValue(),
-                                                   NeutronvpnUtils.getIpVersionFromString(sn
-                                                            .getSubnetIp()), true);
-                                            neutronvpnUtils.updateVpnInstanceWithFallback(
-                                                          sn.getInternetVpnId().getValue(), true);
-                                        }
-                                    }
-                                    addSubnetToVpn(vpn, subnet, sn != null ? sn.getInternetVpnId() : null);
-                                    passedNwList.add(nw);
-                                } else {
-                                    failedNwList.add("subnet " + subnet.getValue()
-                                            + " already added as router interface bound to internal/external VPN "
-                                            + subnetVpnId.getValue());
-                                }
-                            }
-                        }
-                        if (NeutronvpnUtils.getIsExternal(network)) {
-                            VpnMap vpnMap = neutronvpnUtils.getVpnMap(vpn);
-                            if (vpnMap == null) {
-                                LOG.error("associateNetworksToVpn: external network assoc to vpnId {}"
-                                            + ", vpnMap not found", vpn.getValue());
-                                return failedNwList;
-                            }
-                            addExternalNetworkToVpn(network, vpn);
-                            neutronvpnUtils.updateVpnInstanceOpWithType(VpnInstanceOpDataEntry
-                                                    .BgpvpnType.BGPVPNInternet, vpn);
-                            List<Subnetmap> smList = neutronvpnUtils.getSubnetMapsforNetworkRoute(network);
-                            if (!smList.isEmpty()) {
-                                LOG.debug("Adding IPv6 subnetworks {}, because network is external", smList);
-                                for (Subnetmap sm : smList) {
-                                    IpVersionChoice ipVers = NeutronvpnUtils
-                                         .getIpVersionFromString(sm.getSubnetIp());
-                                    if (ipVers == IpVersionChoice.IPV6) {
-                                        updateVpnInternetForSubnet(sm, vpn, true);
-                                        if (neutronvpnUtils.shouldVpnHandleIpVersionChangeToAdd(sm, vpn)) {
-                                            neutronvpnUtils.updateVpnInstanceWithIpFamily(vpn.getValue(),
-                                                    NeutronvpnUtils.getIpVersionFromString(sm.getSubnetIp()), true);
-                                            neutronvpnUtils.updateVpnInstanceWithFallback(vpn.getValue(),
-                                                    true);
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                        if (networkSubnets == null) {
-                            passedNwList.add(nw);
-                        }
+                        LOG.error("associateNetworksToVpn: Failed to associate Provider Network {} with VPN {}",
+                                  nw.getValue(), vpnId.getValue());
+                        failedNwList.add(String.format("Failed to associate Provider Network %s with VPN %s",
+                                                       nw.getValue(), vpnId.getValue()));
+                        continue;
                     }
-                } catch (ReadFailedException e) {
-                    failedNwList.add(
-                            formatAndLog(LOG::error, "Error determining whether VPN {} is associated", vpn.getValue(),
-                                    e));
+                }
+                List<Uuid> networkSubnets = neutronvpnUtils.getSubnetIdsFromNetworkId(nw);
+                if (networkSubnets == null) {
+                    passedNwList.add(nw);
+                    continue;
+                }
+                for (Uuid subnet : networkSubnets) {
+                    Uuid subnetVpnId = neutronvpnUtils.getVpnForSubnet(subnet);
+                    if (subnetVpnId != null) {
+                        LOG.error("associateNetworksToVpn: Failed to associate subnet {} with VPN {} as it is already "
+                                  + "associated", subnet.getValue(), subnetVpnId.getValue());
+                        failedNwList.add(String.format("Failed to associate subnet %s with VPN %s as it is already "
+                                                       + "associated", subnet.getValue(), vpnId.getValue()));
+                        continue;
+                    }
+                    Subnetmap sm = neutronvpnUtils.getSubnetmap(subnet);
+                    if (neutronvpnUtils.shouldVpnHandleIpVersionChangeToAdd(sm, vpnId)) {
+                        neutronvpnUtils.updateVpnInstanceWithIpFamily(vpnId.getValue(),
+                                NeutronvpnUtils.getIpVersionFromString(sm.getSubnetIp()), true);
+                    }
+                    LOG.debug("associateNetworksToVpn: Add subnet {} to VPN {}", subnet.getValue(), vpnId.getValue());
+                    addSubnetToVpn(vpnId, subnet, null);
+                    passedNwList.add(nw);
                 }
             }
-            updateVpnMaps(vpn, null, null, null, passedNwList);
-        }
+        } catch (ReadFailedException e) {
+            LOG.error("associateNetworksToVpn: Failed to associate VPN {} with networks {}: ", vpnId.getValue(),
+                      networks, e);
+            failedNwList.add(String.format("Failed to associate VPN %s with networks %s: %s", vpnId.getValue(),
+                                           networks, e));
+        }
+        LOG.info("associateNetworksToVpn: update VPN {} with networks list: {}", vpnId.getValue(),
+                 passedNwList.toString());
+        updateVpnMaps(vpnId, null, null, null, new ArrayList<Uuid>(passedNwList));
         return failedNwList;
     }
 
-    protected List<String> dissociateNetworksFromVpn(Uuid vpn, List<Uuid> networks) {
+    private boolean associateExtNetworkToVpn(@Nonnull Uuid vpnId, @Nonnull Network extNet) {
+        VpnInstanceOpDataEntry vpnOpDataEntry = neutronvpnUtils.getVpnInstanceOpDataEntryFromVpnId(vpnId.getValue());
+        if (vpnOpDataEntry == null) {
+            LOG.error("associateExtNetworkToVpn: can not find VpnOpDataEntry for VPN {}", vpnId.getValue());
+            return false;
+        }
+        if (!addExternalNetworkToVpn(extNet, vpnId)) {
+            return false;
+        }
+        for (Uuid snId: neutronvpnUtils.getPrivateSubnetsToExport(extNet)) {
+            Subnetmap sm = neutronvpnUtils.getSubnetmap(snId);
+            if (sm == null) {
+                LOG.error("associateExtNetworkToVpn: can not find subnet with Id {} in ConfigDS", snId.getValue());
+                continue;
+            }
+            updateVpnInternetForSubnet(sm, vpnId, true);
+            if (!(vpnOpDataEntry.isIpv6Configured())
+                    && (NeutronvpnUtils.getIpVersionFromString(sm.getSubnetIp()) == IpVersionChoice.IPV6)) {
+                LOG.info("associateExtNetworkToVpn: add IPv6 Internet default route in VPN {}", vpnId.getValue());
+                neutronvpnUtils.updateVpnInstanceWithFallback(vpnId.getValue(), true);
+            }
+        }
+        if (!vpnOpDataEntry.getBgpvpnType().getName().equals(BgpvpnType.BGPVPNInternet.toString())) {
+            LOG.info("associateExtNetworkToVpn: set type {} for VPN {}", BgpvpnType.BGPVPNInternet, vpnId.getValue());
+            neutronvpnUtils.updateVpnInstanceOpWithType(BgpvpnType.BGPVPNInternet, vpnId);
+        }
+        return true;
+    }
+
+    /**
+     * Parses and disassociates networks list from given VPN.
+     *
+     * @param vpnId Uuid of given VPN.
+     * @param networks List list of network Ids (Uuid), which will be disassociated.
+     * @return list of formatted strings with detailed error messages.
+     */
+    @Nonnull
+    protected List<String> dissociateNetworksFromVpn(@Nonnull Uuid vpnId, @Nonnull List<Uuid> networks) {
         List<String> failedNwList = new ArrayList<>();
-        List<Uuid> passedNwList = new ArrayList<>();
-        if (networks != null && !networks.isEmpty()) {
-            // process corresponding subnets for VPN
-            for (Uuid nw : networks) {
-                Network network = neutronvpnUtils.getNeutronNetwork(nw);
-                if (network == null) {
-                    failedNwList.add("network " + nw.getValue() + " not found");
+        HashSet<Uuid> passedNwList = new HashSet<>();
+        if (networks.isEmpty()) {
+            LOG.error("dissociateNetworksFromVpn: Failed as networks list is empty");
+            failedNwList.add(String.format("Failed to disassociate networks from VPN %s as networks list is empty",
+                             vpnId.getValue()));
+            return failedNwList;
+        }
+        for (Uuid nw : networks) {
+            Network network = neutronvpnUtils.getNeutronNetwork(nw);
+            if (network == null) {
+                LOG.error("dissociateNetworksFromVpn: Network {} not found in ConfigDS");
+                failedNwList.add(String.format("Failed to disassociate network %s as is not found in ConfigDS",
+                                               nw.getValue()));
+                continue;
+            }
+            Uuid networkVpnId = neutronvpnUtils.getVpnForNetwork(nw);
+            if (networkVpnId == null) {
+                LOG.error("dissociateNetworksFromVpn: Network {} is not associated to any VPN", nw.getValue());
+                failedNwList.add(String.format("Failed to disassociate network %s as is not associated to any VPN",
+                                               nw.getValue()));
+                continue;
+            }
+            if (!vpnId.equals(networkVpnId)) {
+                LOG.error("dissociateNetworksFromVpn: Network {} is associated to another VPN {} instead of given {}",
+                          nw.getValue(), networkVpnId.getValue(), vpnId.getValue());
+                failedNwList.add(String.format("Failed to disassociate network %s as it is associated to another "
+                                               + "vpn %s instead of given %s", nw.getValue(), networkVpnId.getValue(),
+                                               vpnId.getValue()));
+                continue;
+            }
+            if (neutronvpnUtils.getIsExternal(network)) {
+                if (disassociateExtNetworkFromVpn(vpnId, network)) {
+                    passedNwList.add(nw);
+                    continue;
                 } else {
-                    Uuid vpnId = neutronvpnUtils.getVpnForNetwork(nw);
-                    if (vpn.equals(vpnId)) {
-                        List<Uuid> networkSubnets = neutronvpnUtils.getSubnetIdsFromNetworkId(nw);
-                        LOG.debug("Removing network subnets...");
-                        if (networkSubnets != null) {
-                            boolean vpnInstanceIpVersionsRemoved = false;
-                            IpVersionChoice vpnInstanceIpVersionsToRemove = IpVersionChoice.UNDEFINED;
-                            boolean vpnInstanceInternetIpVersionRemoved = false;
-                            Uuid vpnIdInternet = null;
-                            for (Uuid subnet : networkSubnets) {
-                                Subnetmap sn = neutronvpnUtils.getSubnetmap(subnet);
-                                if (neutronvpnUtils.shouldVpnHandleIpVersionChangeToRemove(sn, vpn)) {
-                                    vpnInstanceIpVersionsToRemove = vpnInstanceIpVersionsToRemove.addVersion(
-                                            NeutronvpnUtils.getIpVersionFromString(sn.getSubnetIp()));
-                                    vpnInstanceIpVersionsRemoved = true;
-                                }
-                                if (sn.getInternetVpnId() != null
-                                    && neutronvpnUtils.shouldVpnHandleIpVersionChangeToRemove(sn,
-                                                                  sn.getInternetVpnId())) {
-                                    vpnInstanceInternetIpVersionRemoved = true;
-                                    vpnIdInternet = sn.getInternetVpnId();
-                                }
-                                removeSubnetFromVpn(vpn, subnet, null);
-                                passedNwList.add(nw);
-                            }
-                            if (vpnInstanceIpVersionsRemoved) {
-                                neutronvpnUtils.updateVpnInstanceWithIpFamily(vpn.getValue(),
-                                        vpnInstanceIpVersionsToRemove, false);
-                            }
-                            if (vpnInstanceInternetIpVersionRemoved) {
-                                neutronvpnUtils.updateVpnInstanceWithFallback(
-                                               vpnIdInternet.getValue(), false);
-                                neutronvpnUtils.updateVpnInstanceWithIpFamily(vpnIdInternet.getValue(),
-                                                   IpVersionChoice.IPV6, false);
-                            }
-                        }
-                        if (NeutronvpnUtils.getIsExternal(network)) {
-                            neutronvpnUtils.updateVpnInstanceWithFallback(vpn.getValue(),
-                                                    false);
-                            neutronvpnUtils.updateVpnInstanceOpWithType(VpnInstanceOpDataEntry
-                                             .BgpvpnType.VPN, vpn);
-                            LOG.debug("Removing IPv6 network subnets...");
-                            List<Subnetmap> smList = neutronvpnUtils.getSubnetMapsforNetworkRoute(network);
-                            boolean vpnInstanceInternetIpVersionRemoved = false;
-                            if (!smList.isEmpty()) {
-                                for (Subnetmap sm : smList) {
-                                    if (neutronvpnUtils.shouldVpnHandleIpVersionChangeToRemove(sm, vpn)) {
-                                        vpnInstanceInternetIpVersionRemoved = true;
-                                    }
-                                    updateVpnInternetForSubnet(sm, vpn, false);
-                                }
-                            }
-                            if (vpnInstanceInternetIpVersionRemoved) {
-                                neutronvpnUtils.updateVpnInstanceWithIpFamily(vpn.getValue(),
-                                             IpVersionChoice.IPV6, false);
-                            }
-                            if (networkSubnets == null) {
-                                passedNwList.add(nw);
-                            }
-                        }
-                    } else {
-                        if (vpnId == null) {
-                            failedNwList.add("input network " + nw.getValue() + " not associated to any vpn yet");
-                        } else {
-                            failedNwList.add("input network " + nw.getValue() + " associated to a another vpn "
-                                    + vpnId.getValue() + " instead of the one given as input");
-                        }
-                    }
-                    if (NeutronvpnUtils.getIsExternal(network)) {
-                        removeExternalNetworkFromVpn(network);
-                    }
+                    LOG.error("dissociateNetworksFromVpn: Failed to withdraw Provider Network {} from VPN {}",
+                              nw.getValue(), vpnId.getValue());
+                    failedNwList.add(String.format("Failed to withdraw Provider Network %s from VPN %s", nw.getValue(),
+                                                   vpnId.getValue()));
+                    continue;
+                }
+            }
+            List<Uuid> networkSubnets = neutronvpnUtils.getSubnetIdsFromNetworkId(nw);
+            if (networkSubnets == null) {
+                passedNwList.add(nw);
+                continue;
+            }
+            for (Uuid subnet : networkSubnets) {
+                Subnetmap sm = neutronvpnUtils.getSubnetmap(subnet);
+                if (neutronvpnUtils.shouldVpnHandleIpVersionChangeToRemove(sm, vpnId)) {
+                    IpVersionChoice ipVersionsToRemove = IpVersionChoice.UNDEFINED;
+                    IpVersionChoice ipVersion = neutronvpnUtils.getIpVersionFromString(sm.getSubnetIp());
+                    neutronvpnUtils.updateVpnInstanceWithIpFamily(vpnId.getValue(),
+                        ipVersionsToRemove.addVersion(ipVersion), false);
                 }
+                LOG.debug("dissociateNetworksFromVpn: Withdraw subnet {} from VPN {}", subnet.getValue(),
+                          vpnId.getValue());
+                removeSubnetFromVpn(vpnId, subnet, null);
+                passedNwList.add(nw);
             }
-            clearFromVpnMaps(vpn, null, passedNwList);
         }
+        LOG.info("dissociateNetworksFromVpn: Withdraw networks list {} from VPN {}", networks.toString(),
+                 vpnId.getValue());
+        clearFromVpnMaps(vpnId, null, new ArrayList<Uuid>(passedNwList));
         return failedNwList;
     }
 
+    private boolean disassociateExtNetworkFromVpn(@Nonnull Uuid vpnId, @Nonnull Network extNet) {
+        if (!removeExternalNetworkFromVpn(extNet)) {
+            return false;
+        }
+        // check, if there is another Provider Networks associated with given VPN
+        List<Uuid> vpnNets = getNetworksForVpn(vpnId);
+        if (vpnNets != null) {
+            for (Uuid netId : vpnNets) {
+                if (neutronvpnUtils.getIsExternal(getNeutronNetwork(netId))) {
+                    LOG.error("dissociateExtNetworkFromVpn: Internet VPN {} is still associated with Provider Network "
+                              + "{}", vpnId.getValue(), netId.getValue());
+                    return true;
+                }
+            }
+        }
+        for (Uuid snId : neutronvpnUtils.getPrivateSubnetsToExport(extNet)) {
+            Subnetmap sm = neutronvpnUtils.getSubnetmap(snId);
+            if (sm == null) {
+                LOG.error("disassociateExtNetworkFromVpn: can not find subnet with Id {} in ConfigDS", snId.getValue());
+                continue;
+            }
+            updateVpnInternetForSubnet(sm, vpnId, false);
+        }
+        neutronvpnUtils.updateVpnInstanceWithIpFamily(vpnId.getValue(), IpVersionChoice.IPV6, false);
+        LOG.info("disassociateExtNetworkFromVpn: withdraw IPv6 Internet default route from VPN {}", vpnId.getValue());
+        neutronvpnUtils.updateVpnInstanceWithFallback(vpnId.getValue(), false);
+        LOG.info("disassociateExtNetworkFromVpn: set type {} for VPN {}",
+                 VpnInstanceOpDataEntry.BgpvpnType.BGPVPNExternal.toString(), vpnId.getValue());
+        neutronvpnUtils.updateVpnInstanceOpWithType(VpnInstanceOpDataEntry.BgpvpnType.VPN, vpnId);
+        return true;
+    }
+
     /**
      * It handles the invocations to the neutronvpn:associateNetworks RPC method.
      */
@@ -3019,69 +3063,63 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         return neutronEvpnManager.deleteEVPN(input);
     }
 
-    public void addExternalNetworkToVpn(Network network, Uuid vpnId) {
-        Uuid extNetId = network.getUuid();
-
-        // Create and add Networks object for this External Network to the ExternalNetworks list
-        InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
+    private boolean addExternalNetworkToVpn(Network extNet, Uuid vpnId) {
+        Uuid extNetId = extNet.getUuid();
+        InstanceIdentifier<Networks> extNetIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
             .child(Networks.class, new NetworksKey(extNetId)).build();
 
         try {
-            Optional<Networks> optionalNets =
+            Optional<Networks> optionalExtNets =
                     SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
-                            netsIdentifier);
-            LOG.trace("Adding vpn-id into Networks node {}", extNetId.getValue());
-            NetworksBuilder builder = null;
-            if (optionalNets.isPresent()) {
-                builder = new NetworksBuilder(optionalNets.get());
-            } else {
-                LOG.error("External Network {} not present in the NVPN datamodel", extNetId.getValue());
-                return;
+                                                                 extNetIdentifier);
+            if (!optionalExtNets.isPresent()) {
+                LOG.error("addExternalNetworkToVpn: Provider Network {} is not present in ConfigDS",
+                          extNetId.getValue());
+                return false;
             }
+            NetworksBuilder builder = new NetworksBuilder(optionalExtNets.get());
             builder.setVpnid(vpnId);
-            Networks networkss = builder.build();
+            Networks networks = builder.build();
             // Add Networks object to the ExternalNetworks list
-            LOG.trace("Setting VPN-ID for externalnetworks {}", networkss);
-            SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, netsIdentifier,
-                    networkss);
-            LOG.trace("Wrote with VPN-ID successfully to CONFIG Datastore");
-
+            LOG.trace("addExternalNetworkToVpn: Set VPN Id {} for Provider Network {}", vpnId.getValue(),
+                      extNetId.getValue());
+            SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, extNetIdentifier,
+                                                  networks);
+            return true;
         } catch (TransactionCommitFailedException | ReadFailedException ex) {
-            LOG.error("Attaching VPN-ID to externalnetwork {} failed", extNetId.getValue(), ex);
+            LOG.error("addExternalNetworkToVpn: Failed to set VPN Id {} to Provider Network {}: ", vpnId.getValue(),
+                      extNetId.getValue(), ex);
         }
+        return false;
     }
 
-    public void removeExternalNetworkFromVpn(Network network) {
-        Uuid extNetId = network.getUuid();
-
-        // Create and add Networks object for this External Network to the ExternalNetworks list
-        InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
-                .child(Networks.class, new NetworksKey(extNetId)).build();
-
+    private boolean removeExternalNetworkFromVpn(Network extNet) {
+        Uuid extNetId = extNet.getUuid();
+        InstanceIdentifier<Networks> extNetsId = InstanceIdentifier.builder(ExternalNetworks.class)
+            .child(Networks.class, new NetworksKey(extNetId)).build();
         try {
             Optional<Networks> optionalNets =
                     SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
-                            netsIdentifier);
-            LOG.trace("Removing vpn-id from Networks node {}", extNetId.getValue());
+                            extNetsId);
             NetworksBuilder builder = null;
             if (optionalNets.isPresent()) {
                 builder = new NetworksBuilder(optionalNets.get());
             } else {
-                LOG.error("External Network {} not present in the NVPN datamodel", extNetId.getValue());
-                return;
+                LOG.error("removeExternalNetworkFromVpn: Provider Network {} is not present in the ConfigDS",
+                          extNetId.getValue());
+                return false;
             }
-
             builder.setVpnid(null);
-            Networks networkss = builder.build();
-            // Add Networks object to the ExternalNetworks list
-            LOG.trace("Remove vpn-id for externalnetwork {}", networkss);
-            SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, netsIdentifier,
-                    networkss);
-            LOG.trace("Updated extnetworks successfully to CONFIG Datastore");
-
+            Networks networks = builder.build();
+            LOG.info("removeExternalNetworkFromVpn: Withdraw VPN Id from Provider Network {} node",
+                    extNetId.getValue());
+            SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, extNetsId, networks);
+            return true;
         } catch (TransactionCommitFailedException | ReadFailedException ex) {
-            LOG.error("Removing VPN-ID from externalnetworks {} failed", extNetId.getValue(), ex);
+            LOG.error("removeExternalNetworkFromVpn: Failed to withdraw VPN Id from Provider Network node {}: ",
+                      extNetId.getValue(), ex);
         }
+        return false;
     }
 
     private Optional<String> getExistingOperationalVpn(String primaryRd) {
index edfe2afacfe18c0ab74b3d1c2b65f64dc783adb2..d581380272e973f1a447a9f3d06b3aad0366a2f5 100644 (file)
@@ -379,17 +379,17 @@ public class NeutronvpnNatManager implements AutoCloseable {
             optionalNets = SingleTransactionDataBroker.syncReadOptional(dataBroker,
                                             LogicalDatastoreType.CONFIGURATION, netsIdentifier);
         } catch (ReadFailedException ex) {
-            LOG.error("Removing externalnetwork {} from router {} failed", origExtNetId.getValue(),
-                    routerId.getValue(), ex);
+            LOG.error("removeExternalNetworkFromRouter: Failed to remove provider network {} from router {}",
+                      origExtNetId.getValue(), routerId.getValue(), ex);
             return;
         }
         if (!optionalNets.isPresent()) {
-            LOG.error("External Network {} not present in the NVPN datamodel", origExtNetId.getValue());
+            LOG.error("removeExternalNetworkFromRouter: Provider Network {} not present in the NVPN datamodel",
+                      origExtNetId.getValue());
             return;
         }
         Networks nets = optionalNets.get();
         try {
-            LOG.trace("Removing a router from External Networks node: {}", origExtNetId.getValue());
             NetworksBuilder builder = new NetworksBuilder(nets);
             List<Uuid> rtrList = builder.getRouterIds();
             if (rtrList != null) {
@@ -398,28 +398,31 @@ public class NeutronvpnNatManager implements AutoCloseable {
                 Networks networkss = builder.build();
                 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
                         netsIdentifier, networkss);
-                LOG.trace("Removed router {} from externalnetworks {}", routerId, origExtNetId.getValue());
+                LOG.trace("removeExternalNetworkFromRouter: Remove router {} from External Networks node {}",
+                          routerId, origExtNetId.getValue());
             }
         } catch (TransactionCommitFailedException ex) {
-            LOG.error("Removing externalnetwork {} from router {} failed", origExtNetId.getValue(),
-                    routerId.getValue(), ex);
+            LOG.error("removeExternalNetworkFromRouter: Failed to remove provider network {} from router {}",
+                      origExtNetId.getValue(), routerId.getValue(), ex);
         }
 
         // Remove the vpnInternetId fromSubnetmap
-        LOG.trace("Removing a vpnInternetId to SubnetMaps about External Networks node: {}",
-                origExtNetId.getValue());
         Network net = neutronvpnUtils.getNeutronNetwork(nets.getId());
-        List<Subnetmap> submapList = neutronvpnUtils.getSubnetMapsforNetworkRoute(net);
-        for (Subnetmap sn : submapList) {
-            if (sn.getInternetVpnId() == null) {
+        List<Uuid> submapIds = neutronvpnUtils.getPrivateSubnetsToExport(net);
+        for (Uuid snId : submapIds) {
+            Subnetmap subnetMap = neutronvpnUtils.getSubnetmap(snId);
+            if ((subnetMap == null) || (subnetMap.getInternetVpnId() == null)) {
+                LOG.error("removeExternalNetworkFromRouter: Can not find Subnetmap for SubnetId {} in ConfigDS",
+                          snId.getValue());
                 continue;
             }
-            LOG.trace("Removing a vpnInternetId {} to SubnetMap {}", sn.getInternetVpnId(), sn.getId());
-            IpVersionChoice ipVers = NeutronvpnUtils.getIpVersionFromString(sn.getSubnetIp());
+            LOG.trace("removeExternalNetworkFromRouter: Remove Internet VPN Id {} from SubnetMap {}",
+                      subnetMap.getInternetVpnId(), subnetMap.getId());
+            IpVersionChoice ipVers = NeutronvpnUtils.getIpVersionFromString(subnetMap.getSubnetIp());
             if (ipVers == IpVersionChoice.IPV6) {
-                LOG.debug("removeExternalNetworkFromRouter : clear vpnInternet IPv6 for vpnExternal {} "
-                        + "subnetmap {}", sn.getInternetVpnId(), sn);
-                nvpnManager.updateVpnInternetForSubnet(sn, sn.getInternetVpnId(), false);
+                nvpnManager.updateVpnInternetForSubnet(subnetMap, subnetMap.getInternetVpnId(), false);
+                LOG.debug("removeExternalNetworkFromRouter: Withdraw IPv6 routes from VPN {}",
+                          subnetMap.getInternetVpnId());
             }
         }
     }
index 3af9c815b040d04b4e51953700507394f749d746..ed37c0043135c24dbca1c296026a173e8bd33cde 100644 (file)
@@ -114,6 +114,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.ext.rev150712.Ne
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router.ExternalGatewayInfo;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeBase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeFlat;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeGre;
@@ -1112,7 +1113,6 @@ public class NeutronvpnUtils {
         return Optional.absent();
     }
 
-
     public Set<RouterDpnList> getAllRouterDpnList(BigInteger dpid) {
         Set<RouterDpnList> ret = new HashSet<>();
         InstanceIdentifier<NeutronRouterDpns> routerDpnId =
@@ -1553,53 +1553,30 @@ public class NeutronvpnUtils {
     }
 
     /**
-     * Get all subnetmap associate to the belonging router of network.
-     * @param network the network which have router bound
-     * @return a list of Subnetmap of the router (which the network is associated)
+     * Get a list of Private Subnetmap Ids from router to export then its prefixes in Internet VPN.
+     * @param extNet Provider Network, which has a port attached as external network gateway to router
+     * @return a list of Private Subnetmap Ids of the router with external network gateway
      */
-    public @Nonnull List<Subnetmap> getSubnetMapsforNetworkRoute(@Nonnull Network network) {
-        List<Subnetmap> subList = new ArrayList<>();
-        LOG.debug("getSubnetMapsforNetworkRoute for network {}", network.getUuid());
-        Uuid vpnUuid = getVpnForNetwork(network.getUuid());
-        InstanceIdentifier<Subnetmaps> subnetmapsid = InstanceIdentifier.builder(Subnetmaps.class).build();
-        Optional<Subnetmaps> optionalSubnetmaps = read(LogicalDatastoreType.CONFIGURATION,
-                       subnetmapsid);
-        if (!optionalSubnetmaps.isPresent()) {
-            LOG.debug("getSubnetMapsforNetworkRoute: no subnetmaps");
-            return Collections.emptyList();
-        }
-        List<Subnetmap> subnetmapList = optionalSubnetmaps.get().getSubnetmap();
-        if (vpnUuid != null) {
-            for (Subnetmap subnetmap : subnetmapList) {
-                if ((subnetmap.getInternetVpnId() != null)
-                     && subnetmap.getInternetVpnId().getValue().equals(vpnUuid.getValue())) {
-                    subList.add(subnetmap);
-                }
-            }
-        } else {
-            Uuid routerId = null;
-            for (Subnetmap subnetmap : subnetmapList) {
-                if (subnetmap.getRouterId() != null) {
-                    Uuid externalNetworkUuid = getExternalNetworkUuidAttachedFromRouterUuid(subnetmap.getRouterId());
-                    if (externalNetworkUuid != null && externalNetworkUuid.getValue()
-                         .equals(network.getUuid().getValue())) {
-                        routerId = subnetmap.getRouterId();
-                        break;
-                    }
-                }
-            }
-            if (routerId == null) {
-                LOG.debug("getSubnetMapsforNetworkRoute: no subnet in routers using {}", network.getUuid());
-                return Collections.emptyList();
-            }
-            for (Subnetmap subnetmap : subnetmapList) {
-                if (subnetmap.getRouterId() != null
-                        && subnetmap.getRouterId().getValue().matches(routerId.getValue())) {
-                    subList.add(subnetmap);
-                }
-            }
-        }
-        return subList;
+    public @Nonnull List<Uuid> getPrivateSubnetsToExport(@Nonnull Network extNet) {
+        List<Uuid> subList = new ArrayList<>();
+        Uuid extNetVpnId = getVpnForNetwork(extNet.getUuid());
+        if (extNetVpnId == null) {
+            return subList;
+        }
+        Router router = getNeutronRouter(getRouterforVpn(extNetVpnId));
+        ExternalGatewayInfo info = router.getExternalGatewayInfo();
+        if (info == null) {
+            LOG.error("getPrivateSubnetsToExport: can not get info about external gateway for router {}",
+                      router.getUuid().getValue());
+            return subList;
+        }
+        // check that router really has given provider network as its external gateway port
+        if (!extNet.getUuid().equals(info.getExternalNetworkId())) {
+            LOG.error("getPrivateSubnetsToExport: router {} is not attached to given provider network {}",
+                      router.getUuid().getValue(), extNet.getUuid().getValue());
+            return subList;
+        }
+        return getSubnetsforVpn(router.getUuid());
     }
 
     public void updateVpnInstanceWithFallback(String vpnName, boolean add) {