X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=neutronvpn%2Fimpl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetvirt%2Fneutronvpn%2FNeutronvpnUtils.java;h=1b784a2fee4d70d98763563ce42132385942dfd5;hb=cf1ea9172b94fc17e45391b62bf4ca24ac5c5fe0;hp=992ec7e70691247c5411dce9cbd2a21a7e59f760;hpb=368dc8ffb7fb654dbb2c96885eb501b2c0638f46;p=netvirt.git diff --git a/neutronvpn/impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnUtils.java b/neutronvpn/impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnUtils.java index 992ec7e706..1b784a2fee 100644 --- a/neutronvpn/impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnUtils.java +++ b/neutronvpn/impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnUtils.java @@ -5,15 +5,19 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ - package org.opendaylight.netvirt.neutronvpn; +import static org.opendaylight.genius.infra.Datastore.CONFIGURATION; import static org.opendaylight.genius.infra.Datastore.OPERATIONAL; -import com.google.common.base.Optional; +import com.google.common.base.Function; import com.google.common.collect.ImmutableBiMap; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; -import java.math.BigInteger; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.common.util.concurrent.SettableFuture; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; @@ -21,41 +25,37 @@ import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; -import java.util.stream.Collectors; -import javax.annotation.Nonnull; +import java.util.concurrent.locks.ReentrantLock; import javax.inject.Inject; import javax.inject.Singleton; import org.apache.commons.lang3.StringUtils; -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.NonNull; +import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker; import org.opendaylight.genius.infra.Datastore; import org.opendaylight.genius.infra.ManagedNewTransactionRunner; import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl; import org.opendaylight.genius.infra.TypedWriteTransaction; import org.opendaylight.genius.mdsalutil.MDSALUtil; +import org.opendaylight.genius.utils.JvmGlobalLocks; import org.opendaylight.infrautils.jobcoordinator.JobCoordinator; 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.binding.api.ReadTransaction; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.netvirt.neutronvpn.api.enums.IpVersionChoice; +import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants; import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; @@ -64,26 +64,20 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces. import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; 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.idmanager.rev160406.AllocateIdInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.Dhcpv6Base; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAcl; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAclBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpVersionBase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.PortSubnets; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.PortSubnet; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.PortSubnetBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.PortSubnetKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.port.subnet.SubnetInfo; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.port.subnet.SubnetInfoBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.port.subnet.SubnetInfoKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.SubnetInfo; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.SubnetInfoBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.SubnetInfoKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeBase; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeFlat; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeGre; @@ -111,12 +105,22 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev16011 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInstances; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstanceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstanceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterfaceKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortIdSubportData; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.port.id.subport.data.PortIdToSubport; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.port.id.subport.data.PortIdToSubportKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey; @@ -126,6 +130,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev15060 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpn.instance.RouterIdsBuilder; 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.VpnMapKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.vpnmap.RouterIdsKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.ext.rev150712.NetworkL3Extension; 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; @@ -140,12 +145,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712. import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.NetworkKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps; +import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIpsKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.portsecurity.rev150712.PortSecurityExtension; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.NetworkProviderExtension; -import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.qos.rev160613.qos.attributes.qos.policies.QosPolicy; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet; @@ -158,6 +163,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt. import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.Uint64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -174,29 +180,38 @@ public class NeutronvpnUtils { .put(NetworkTypeVxlan.class, SegmentTypeVxlan.class) .build(); - private static final Set> SUPPORTED_NETWORK_TYPES = new HashSet<>(); - - static { - SUPPORTED_NETWORK_TYPES.add(NetworkTypeFlat.class); - SUPPORTED_NETWORK_TYPES.add(NetworkTypeVlan.class); - SUPPORTED_NETWORK_TYPES.add(NetworkTypeVxlan.class); - SUPPORTED_NETWORK_TYPES.add(NetworkTypeGre.class); - } + private static final ImmutableSet> SUPPORTED_NETWORK_TYPES = ImmutableSet.of( + NetworkTypeFlat.class, + NetworkTypeVlan.class, + NetworkTypeVxlan.class, + NetworkTypeGre.class); + + + private static final InstanceIdentifier VPN_INSTANCE_OP_DATA_IID = + InstanceIdentifier.create(VpnInstanceOpData.class); + private static final InstanceIdentifier VPN_MAPS_IID = InstanceIdentifier.create(VpnMaps.class); + private static final InstanceIdentifier SUBNETMAPS_IID = InstanceIdentifier.create(Subnetmaps.class); + private static final InstanceIdentifier NEUTRON_NETWORKS_IID = InstanceIdentifier.builder(Neutron.class) + .child(Networks.class).build(); + private static final InstanceIdentifier NEUTRON_PORTS_IID = InstanceIdentifier.builder(Neutron.class) + .child(Ports.class).build(); + private static final InstanceIdentifier NEUTRON_ROUTERS_IID = InstanceIdentifier.builder(Neutron.class) + .child(Routers.class).build(); + private static final InstanceIdentifier NEUTRON_SUBNETS_IID = InstanceIdentifier.builder(Neutron.class) + .child(Subnets.class).build(); private final ConcurrentMap networkMap = new ConcurrentHashMap<>(); private final ConcurrentMap routerMap = new ConcurrentHashMap<>(); private final ConcurrentMap portMap = new ConcurrentHashMap<>(); private final ConcurrentMap subnetMap = new ConcurrentHashMap<>(); private final Map> subnetGwIpMap = new ConcurrentHashMap<>(); - private final ConcurrentMap qosPolicyMap = new ConcurrentHashMap<>(); - private final ConcurrentMap> qosPortsMap = new ConcurrentHashMap<>(); - private final ConcurrentMap> qosNetworksMap = new ConcurrentHashMap<>(); private final DataBroker dataBroker; private final ManagedNewTransactionRunner txRunner; private final IdManagerService idManager; private final JobCoordinator jobCoordinator; private final IPV6InternetDefaultRouteProgrammer ipV6InternetDefRt; + private static final int JOB_MAX_RETRIES = 3; @Inject public NeutronvpnUtils(final DataBroker dataBroker, final IdManagerService idManager, @@ -208,6 +223,7 @@ public class NeutronvpnUtils { this.ipV6InternetDefRt = ipV6InternetDefRt; } + @Nullable protected Subnetmap getSubnetmap(Uuid subnetId) { InstanceIdentifier id = buildSubnetMapIdentifier(subnetId); Optional sn = read(LogicalDatastoreType.CONFIGURATION, id); @@ -219,10 +235,9 @@ public class NeutronvpnUtils { return null; } + @Nullable public VpnMap getVpnMap(Uuid id) { - InstanceIdentifier vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap.class, - new VpnMapKey(id)).build(); - Optional optionalVpnMap = read(LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier); + Optional optionalVpnMap = read(LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier(id)); if (optionalVpnMap.isPresent()) { return optionalVpnMap.get(); } @@ -230,12 +245,11 @@ public class NeutronvpnUtils { return null; } + @Nullable protected Uuid getVpnForNetwork(Uuid network) { - InstanceIdentifier vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build(); - Optional optionalVpnMaps = read(LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier); - if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) { - List allMaps = optionalVpnMaps.get().getVpnMap(); - for (VpnMap vpnMap : allMaps) { + Optional optionalVpnMaps = read(LogicalDatastoreType.CONFIGURATION, VPN_MAPS_IID); + if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().nonnullVpnMap() != null) { + for (VpnMap vpnMap : new ArrayList<>(optionalVpnMaps.get().nonnullVpnMap().values())) { List netIds = vpnMap.getNetworkIds(); if (netIds != null && netIds.contains(network)) { return vpnMap.getVpnId(); @@ -246,6 +260,7 @@ public class NeutronvpnUtils { return null; } + @Nullable protected Uuid getVpnForSubnet(Uuid subnetId) { InstanceIdentifier subnetmapIdentifier = buildSubnetMapIdentifier(subnetId); Optional optionalSubnetMap = read(LogicalDatastoreType.CONFIGURATION, @@ -257,6 +272,7 @@ public class NeutronvpnUtils { return null; } + @Nullable protected Uuid getNetworkForSubnet(Uuid subnetId) { InstanceIdentifier subnetmapIdentifier = buildSubnetMapIdentifier(subnetId); Optional optionalSubnetMap = read(LogicalDatastoreType.CONFIGURATION, @@ -269,24 +285,26 @@ public class NeutronvpnUtils { } // @param external vpn - true if external vpn being fetched, false for internal vpn - protected Uuid getVpnForRouter(Uuid routerId, boolean externalVpn) { + @Nullable + protected Uuid getVpnForRouter(@Nullable Uuid routerId, boolean externalVpn) { if (routerId == null) { return null; } - InstanceIdentifier vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build(); - Optional optionalVpnMaps = read(LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier); - if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) { - List allMaps = optionalVpnMaps.get().getVpnMap(); - for (VpnMap vpnMap : allMaps) { - List routerIdsList = vpnMap.getRouterIds(); - if (routerIdsList == null || routerIdsList.isEmpty()) { + Optional optionalVpnMaps = read(LogicalDatastoreType.CONFIGURATION, VPN_MAPS_IID); + if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().nonnullVpnMap() != null) { + for (VpnMap vpnMap : new ArrayList<>(optionalVpnMaps.get().nonnullVpnMap().values())) { + Map keyRouterIdsMap = vpnMap.getRouterIds(); + if (keyRouterIdsMap == null || keyRouterIdsMap.isEmpty()) { continue; } - List rtrIdsList = routerIdsList.stream().map(routerIds -> routerIds.getRouterId()) - .collect(Collectors.toList()); - if (rtrIdsList.contains(routerId)) { + // Skip router vpnId fetching from internet BGP-VPN + if (hasExternalNetwork(vpnMap.getNetworkIds())) { + continue; + } + // FIXME: NETVIRT-1503: this check can be replaced by a ReadOnlyTransaction.exists() + if (keyRouterIdsMap.values().stream().anyMatch(routerIds -> routerId.equals(routerIds.getRouterId()))) { if (externalVpn) { if (!routerId.equals(vpnMap.getVpnId())) { return vpnMap.getVpnId(); @@ -303,25 +321,48 @@ public class NeutronvpnUtils { return null; } + // We only need to check the first network; if it’s not an external network there’s no + // need to check the rest of the VPN’s network list. Note that some UUIDs may point to unknown networks, in which + // case we check more and assume false. + private boolean hasExternalNetwork(List uuids) { + if (uuids != null) { + for (Uuid uuid : uuids) { + final Network network = getNeutronNetwork(uuid); + if (network != null) { + if (Boolean.TRUE.equals(getIsExternal(network))) { + return true; + } + } else { + LOG.debug("hasExternalNetwork: cannot find network for {}", uuid); + } + } + } + return false; + } + + + @Nullable protected List getRouterIdListforVpn(Uuid vpnId) { - InstanceIdentifier vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap.class, - new VpnMapKey(vpnId)).build(); - Optional optionalVpnMap = read(LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier); + Optional optionalVpnMap = read(LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier(vpnId)); if (optionalVpnMap.isPresent()) { VpnMap vpnMap = optionalVpnMap.get(); - return NeutronUtils.getVpnMapRouterIdsListUuid(vpnMap.getRouterIds()); + return NeutronUtils.getVpnMapRouterIdsListUuid(new ArrayList(vpnMap.getRouterIds().values())); } LOG.error("getRouterIdListforVpn: Failed as VPNMaps DS is absent for VPN {}", vpnId.getValue()); return null; } + @Nullable protected List getNetworksForVpn(Uuid vpnId) { - InstanceIdentifier vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap.class, - new VpnMapKey(vpnId)).build(); - Optional optionalVpnMap = read(LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier); + Optional optionalVpnMap = read(LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier(vpnId)); if (optionalVpnMap.isPresent()) { VpnMap vpnMap = optionalVpnMap.get(); - return vpnMap.getNetworkIds(); + if (vpnMap.getNetworkIds() != null && !vpnMap.getNetworkIds().isEmpty()) { + return new ArrayList<>(vpnMap.getNetworkIds()); + } else { + return null; + } } LOG.error("getNetworksforVpn: Failed as VPNMaps DS is absent for VPN {}", vpnId.getValue()); return null; @@ -330,11 +371,10 @@ public class NeutronvpnUtils { protected List getSubnetsforVpn(Uuid vpnid) { List subnets = new ArrayList<>(); // read subnetmaps - InstanceIdentifier subnetmapsid = InstanceIdentifier.builder(Subnetmaps.class).build(); - Optional subnetmaps = read(LogicalDatastoreType.CONFIGURATION, subnetmapsid); + Optional subnetmaps = read(LogicalDatastoreType.CONFIGURATION, SUBNETMAPS_IID); if (subnetmaps.isPresent() && subnetmaps.get().getSubnetmap() != null) { - List subnetMapList = subnetmaps.get().getSubnetmap(); - for (Subnetmap candidateSubnetMap : subnetMapList) { + Map keySubnetmapMap = subnetmaps.get().getSubnetmap(); + for (Subnetmap candidateSubnetMap : keySubnetmapMap.values()) { if (candidateSubnetMap.getVpnId() != null && candidateSubnetMap.getVpnId().equals(vpnid)) { subnets.add(candidateSubnetMap.getId()); } @@ -343,6 +383,7 @@ public class NeutronvpnUtils { return subnets; } + @Nullable protected String getNeutronPortNameFromVpnPortFixedIp(String vpnName, String fixedIp) { InstanceIdentifier id = buildVpnPortipToPortIdentifier(vpnName, fixedIp); Optional vpnPortipToPortData = read(LogicalDatastoreType.CONFIGURATION, id); @@ -354,6 +395,7 @@ public class NeutronvpnUtils { return null; } + @Nullable protected List getSubnetIdsFromNetworkId(Uuid networkId) { InstanceIdentifier id = buildNetworkMapIdentifier(networkId); Optional optionalNetworkMap = read(LogicalDatastoreType.CONFIGURATION, id); @@ -364,23 +406,12 @@ public class NeutronvpnUtils { return null; } - protected List getPortIdsFromSubnetId(Uuid subnetId) { - InstanceIdentifier id = buildSubnetMapIdentifier(subnetId); - Optional optionalSubnetmap = read(LogicalDatastoreType.CONFIGURATION, id); - if (optionalSubnetmap.isPresent()) { - return optionalSubnetmap.get().getPortList(); - } - return null; - } - protected Router getNeutronRouter(Uuid routerId) { Router router = routerMap.get(routerId); if (router != null) { return router; } - InstanceIdentifier inst = InstanceIdentifier.create(Neutron.class).child(Routers.class).child(Router - .class, new RouterKey(routerId)); - Optional rtr = read(LogicalDatastoreType.CONFIGURATION, inst); + Optional rtr = read(LogicalDatastoreType.CONFIGURATION, getNeutronRouterIid(routerId)); if (rtr.isPresent()) { router = rtr.get(); } @@ -388,40 +419,52 @@ public class NeutronvpnUtils { } public InstanceIdentifier getNeutronRouterIid(Uuid routerId) { - return InstanceIdentifier.create(Neutron.class).child(Routers.class).child(Router - .class, new RouterKey(routerId)); - + return NEUTRON_ROUTERS_IID.child(Router.class, new RouterKey(routerId)); } - protected Network getNeutronNetwork(Uuid networkId) { - Network network = null; - network = networkMap.get(networkId); + protected @Nullable Network getNeutronNetwork(Uuid networkId) { + Network network = networkMap.get(networkId); if (network != null) { return network; } LOG.debug("getNeutronNetwork for {}", networkId.getValue()); - InstanceIdentifier inst = InstanceIdentifier.create(Neutron.class).child(Networks.class) - .child(Network.class, new NetworkKey(networkId)); - Optional net = read(LogicalDatastoreType.CONFIGURATION, inst); - if (net.isPresent()) { - network = net.get(); - } - return network; + InstanceIdentifier inst = NEUTRON_NETWORKS_IID.child(Network.class, new NetworkKey(networkId)); + return read(LogicalDatastoreType.CONFIGURATION, inst).orElse(null); } - protected Port getNeutronPort(Uuid portId) { + protected @Nullable Port getNeutronPort(Uuid portId) { Port prt = portMap.get(portId); if (prt != null) { return prt; } LOG.debug("getNeutronPort for {}", portId.getValue()); - InstanceIdentifier inst = InstanceIdentifier.create(Neutron.class).child(Ports.class).child(Port.class, - new PortKey(portId)); - Optional port = read(LogicalDatastoreType.CONFIGURATION, inst); - if (port.isPresent()) { - prt = port.get(); + InstanceIdentifier inst = NEUTRON_PORTS_IID.child(Port.class, new PortKey(portId)); + return read(LogicalDatastoreType.CONFIGURATION, inst).orElse(null); + } + + public PortIdToSubport getPortIdToSubport(Uuid portId) { + InstanceIdentifier portIdToSubportIdentifier = buildPortIdSubportMappingIdentifier(portId); + Optional optionalPortIdToSubport = read(LogicalDatastoreType.CONFIGURATION, + portIdToSubportIdentifier); + if (optionalPortIdToSubport.isPresent()) { + return optionalPortIdToSubport.get(); } - return prt; + LOG.error("getPortIdToSubport failed, PortIdToSubport {} not present", portId.getValue()); + return null; + } + + protected static boolean isDhcpServerPort(Port port) { + return port.getDeviceOwner().equals("network:dhcp"); + } + + protected InterfaceAcl getDhcpInterfaceAcl(Port port) { + InterfaceAclBuilder interfaceAclBuilder = new InterfaceAclBuilder(); + interfaceAclBuilder.setPortSecurityEnabled(false); + interfaceAclBuilder.setInterfaceType(InterfaceAcl.InterfaceType.DhcpService); + List aclAllowedAddressPairs = NeutronvpnUtils.getAllowedAddressPairsForAclService( + port.getMacAddress(), new ArrayList(port.getFixedIps().values())); + interfaceAclBuilder.setAllowedAddressPairs(aclAllowedAddressPairs); + return interfaceAclBuilder.build(); } /** @@ -452,8 +495,9 @@ public class NeutronvpnUtils { * @param port2SecurityGroups the port 2 security groups * @return the security groups delta */ - protected static List getSecurityGroupsDelta(List port1SecurityGroups, - List port2SecurityGroups) { + @Nullable + protected static List getSecurityGroupsDelta(@Nullable List port1SecurityGroups, + @Nullable List port2SecurityGroups) { if (port1SecurityGroups == null) { return null; } @@ -513,10 +557,11 @@ public class NeutronvpnUtils { * @param port2AllowedAddressPairs the port 2 allowed address pairs * @return the allowed address pairs delta */ + @Nullable protected static List getAllowedAddressPairsDelta( - List port1AllowedAddressPairs, - List port2AllowedAddressPairs) { if (port1AllowedAddressPairs == null) { return null; @@ -653,9 +698,11 @@ public class NeutronvpnUtils { */ protected static List getAllowedAddressPairsForFixedIps( List aclInterfaceAllowedAddressPairs, MacAddress portMacAddress, - List origFixedIps, List newFixedIps) { - List addedFixedIps = getFixedIpsDelta(newFixedIps, origFixedIps); - List deletedFixedIps = getFixedIpsDelta(origFixedIps, newFixedIps); + @Nullable Map origFixedIps, Collection newFixedIps) { + List addedFixedIps = getFixedIpsDelta(new ArrayList(newFixedIps), + new ArrayList(origFixedIps.values())); + List deletedFixedIps = getFixedIpsDelta(new ArrayList(origFixedIps.values()), + new ArrayList(newFixedIps)); List updatedAllowedAddressPairs = aclInterfaceAllowedAddressPairs != null ? new ArrayList<>(aclInterfaceAllowedAddressPairs) : new ArrayList<>(); @@ -679,13 +726,19 @@ public class NeutronvpnUtils { protected static List getUpdatedAllowedAddressPairs( List aclInterfaceAllowedAddressPairs, List origAllowedAddressPairs, + .AllowedAddressPairs> origAllowedAddressPairs, List newAllowedAddressPairs) { + .AllowedAddressPairs> newAllowedAddressPairs) { List addedAllowedAddressPairs = - getAllowedAddressPairsDelta(newAllowedAddressPairs,origAllowedAddressPairs); + getAllowedAddressPairsDelta(new ArrayList(newAllowedAddressPairs), + new ArrayList(origAllowedAddressPairs)); List deletedAllowedAddressPairs = - getAllowedAddressPairsDelta(origAllowedAddressPairs, newAllowedAddressPairs); + getAllowedAddressPairsDelta(new ArrayList(origAllowedAddressPairs), + new ArrayList(newAllowedAddressPairs)); List updatedAllowedAddressPairs = aclInterfaceAllowedAddressPairs != null ? new ArrayList<>(aclInterfaceAllowedAddressPairs) : new ArrayList<>(); @@ -704,57 +757,50 @@ public class NeutronvpnUtils { * @param interfaceAclBuilder the interface acl builder * @param port the port */ - protected static void populateInterfaceAclBuilder(InterfaceAclBuilder interfaceAclBuilder, Port port) { + protected void populateInterfaceAclBuilder(InterfaceAclBuilder interfaceAclBuilder, Port port) { // Handle security group enabled List securityGroups = port.getSecurityGroups(); if (securityGroups != null) { interfaceAclBuilder.setSecurityGroups(securityGroups); } List aclAllowedAddressPairs = NeutronvpnUtils.getAllowedAddressPairsForAclService( - port.getMacAddress(), port.getFixedIps()); + port.getMacAddress(), new ArrayList(port.getFixedIps().values())); // Update the allowed address pair with the IPv6 LLA that is auto configured on the port. aclAllowedAddressPairs.add(NeutronvpnUtils.updateIPv6LinkLocalAddressForAclService(port.getMacAddress())); List - portAllowedAddressPairs = port.getAllowedAddressPairs(); + portAllowedAddressPairs = new ArrayList(port.getAllowedAddressPairs().values()); if (portAllowedAddressPairs != null) { aclAllowedAddressPairs.addAll(NeutronvpnUtils.getAllowedAddressPairsForAclService(portAllowedAddressPairs)); } interfaceAclBuilder.setAllowedAddressPairs(aclAllowedAddressPairs); + interfaceAclBuilder.setInterfaceType(InterfaceAcl.InterfaceType.AccessPort); + populateSubnetInfo(interfaceAclBuilder, port); } - protected void populateSubnetInfo(Port port) { + protected void populateSubnetInfo(InterfaceAclBuilder interfaceAclBuilder, Port port) { List portSubnetInfo = getSubnetInfo(port); if (portSubnetInfo != null) { - String portId = port.getUuid().getValue(); - InstanceIdentifier portSubnetIdentifier = buildPortSubnetIdentifier(portId); - - PortSubnetBuilder portSubnetBuilder = new PortSubnetBuilder().withKey(new PortSubnetKey(portId)) - .setPortId(portId).setSubnetInfo(portSubnetInfo); - try { - SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, - portSubnetIdentifier, portSubnetBuilder.build()); - } catch (TransactionCommitFailedException e) { - LOG.error("Failed to populate subnet info for port={}", portId, e); - } - LOG.debug("Created Subnet info for port={}", portId); + interfaceAclBuilder.setSubnetInfo(portSubnetInfo); } } + @Nullable protected List getSubnetInfo(Port port) { - List portFixedIps = port.getFixedIps(); - if (portFixedIps == null) { + Map keyFixedIpsMap = port.getFixedIps(); + if (keyFixedIpsMap == null) { LOG.error("Failed to get Fixed IPs for the port {}", port.getName()); return null; } List subnetInfoList = new ArrayList<>(); - for (FixedIps portFixedIp : portFixedIps) { + for (FixedIps portFixedIp : keyFixedIpsMap.values()) { Uuid subnetId = portFixedIp.getSubnetId(); Subnet subnet = getNeutronSubnet(subnetId); if (subnet != null) { Class ipVersion = - NeutronSecurityRuleConstants.IP_VERSION_MAP.get(subnet.getIpVersion()); + NeutronSecurityGroupConstants.IP_VERSION_MAP.get(subnet.getIpVersion()); Class raMode = subnet.getIpv6RaMode() == null ? null - : NeutronSecurityRuleConstants.RA_MODE_MAP.get(subnet.getIpv6RaMode()); + : NeutronSecurityGroupConstants.RA_MODE_MAP.get(subnet.getIpv6RaMode()); SubnetInfo subnetInfo = new SubnetInfoBuilder().withKey(new SubnetInfoKey(subnetId)) .setIpVersion(ipVersion).setIpPrefix(new IpPrefixOrAddress(subnet.getCidr())) .setIpv6RaMode(raMode).setGatewayIp(subnet.getGatewayIp()).build(); @@ -769,8 +815,7 @@ public class NeutronvpnUtils { if (subnet != null) { return subnet; } - InstanceIdentifier inst = InstanceIdentifier.create(Neutron.class).child(Subnets.class).child(Subnet - .class, new SubnetKey(subnetId)); + InstanceIdentifier inst = NEUTRON_SUBNETS_IID.child(Subnet.class, new SubnetKey(subnetId)); Optional sn = read(LogicalDatastoreType.CONFIGURATION, inst); if (sn.isPresent()) { @@ -782,10 +827,9 @@ public class NeutronvpnUtils { protected List getNeutronRouterSubnetMapList(Uuid routerId) { List subnetMapList = new ArrayList<>(); - Optional subnetMaps = read(LogicalDatastoreType.CONFIGURATION, - InstanceIdentifier.builder(Subnetmaps.class).build()); + Optional subnetMaps = read(LogicalDatastoreType.CONFIGURATION, SUBNETMAPS_IID); if (subnetMaps.isPresent() && subnetMaps.get().getSubnetmap() != null) { - for (Subnetmap subnetmap : subnetMaps.get().getSubnetmap()) { + for (Subnetmap subnetmap : subnetMaps.get().getSubnetmap().values()) { if (routerId.equals(subnetmap.getRouterId())) { subnetMapList.add(subnetmap); } @@ -795,14 +839,13 @@ public class NeutronvpnUtils { return subnetMapList; } - @Nonnull + @NonNull protected List getNeutronRouterSubnetIds(Uuid routerId) { LOG.debug("getNeutronRouterSubnetIds for {}", routerId.getValue()); List subnetIdList = new ArrayList<>(); - Optional subnetMaps = read(LogicalDatastoreType.CONFIGURATION, - InstanceIdentifier.builder(Subnetmaps.class).build()); + Optional subnetMaps = read(LogicalDatastoreType.CONFIGURATION, SUBNETMAPS_IID); if (subnetMaps.isPresent() && subnetMaps.get().getSubnetmap() != null) { - for (Subnetmap subnetmap : subnetMaps.get().getSubnetmap()) { + for (Subnetmap subnetmap : subnetMaps.get().getSubnetmap().values()) { if (routerId.equals(subnetmap.getRouterId())) { subnetIdList.add(subnetmap.getId()); } @@ -814,13 +857,13 @@ public class NeutronvpnUtils { // TODO Clean up the exception handling and the console output @SuppressWarnings({"checkstyle:IllegalCatch", "checkstyle:RegexpSinglelineJava"}) + @Nullable protected Short getIPPrefixFromPort(Port port) { try { - Uuid subnetUUID = port.getFixedIps().get(0).getSubnetId(); - SubnetKey subnetkey = new SubnetKey(subnetUUID); - InstanceIdentifier subnetidentifier = InstanceIdentifier.create(Neutron.class).child(Subnets - .class).child(Subnet.class, subnetkey); - Optional subnet = read(LogicalDatastoreType.CONFIGURATION, subnetidentifier); + // FIXME: why are we not using getNeutronSubnet() here? it does caching for us... + Optional subnet = read(LogicalDatastoreType.CONFIGURATION, + NEUTRON_SUBNETS_IID.child(Subnet.class, new SubnetKey( + new ArrayList(port.getFixedIps().values()).get(0).getSubnetId()))); if (subnet.isPresent()) { String cidr = subnet.get().getCidr().stringValue(); // Extract the prefix length from cidr @@ -858,8 +901,8 @@ public class NeutronvpnUtils { LOG.trace("Neutron port with fixedIp: {}, vpn {}, interface {}, mac {}, isSubnetIp {} added to " + "VpnPortipToPort DS", fixedIp, vpnName, portName, macAddress, isSubnetIp); } catch (Exception e) { - LOG.error("Failure while creating VPNPortFixedIpToPort map for vpn {} - fixedIP {}", vpnName, fixedIp, - e); + LOG.error("Failure while creating VPNPortFixedIpToPort map for vpn {} - fixedIP {} for port {} with " + + "macAddress {}", vpnName, fixedIp, portName, macAddress, e); } } @@ -874,7 +917,7 @@ public class NeutronvpnUtils { } else { MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, id); } - LOG.trace("Neutron router port with fixedIp: {}, vpn {} removed from LearntVpnPortipToPort DS", fixedIp, + LOG.trace("Neutron router port with fixedIp: {}, vpn {} removed from VpnPortipToPort DS", fixedIp, vpnName); } catch (Exception e) { LOG.error("Failure while removing VPNPortFixedIpToPort map for vpn {} - fixedIP {}", vpnName, fixedIp, @@ -886,15 +929,18 @@ public class NeutronvpnUtils { @SuppressWarnings("checkstyle:IllegalCatch") protected void removeLearntVpnVipToPort(String vpnName, String fixedIp) { InstanceIdentifier id = NeutronvpnUtils.buildLearntVpnVipToPortIdentifier(vpnName, fixedIp); + // FIXME: can we use 'id' as the lock name? + final ReentrantLock lock = JvmGlobalLocks.getLockForString(vpnName + fixedIp); + lock.lock(); try { - synchronized ((vpnName + fixedIp).intern()) { - MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, id); - } + MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, id); LOG.trace("Neutron router port with fixedIp: {}, vpn {} removed from LearntVpnPortipToPort DS", fixedIp, vpnName); } catch (Exception e) { LOG.error("Failure while removing LearntVpnPortFixedIpToPort map for vpn {} - fixedIP {}", vpnName, fixedIp, e); + } finally { + lock.unlock(); } } @@ -985,52 +1031,8 @@ public class NeutronvpnUtils { } static Boolean getIsExternal(Network network) { - return network.augmentation(NetworkL3Extension.class) != null - && network.augmentation(NetworkL3Extension.class).isExternal(); - } - - public void addToQosPolicyCache(QosPolicy qosPolicy) { - qosPolicyMap.put(qosPolicy.getUuid(),qosPolicy); - } - - public void removeFromQosPolicyCache(QosPolicy qosPolicy) { - qosPolicyMap.remove(qosPolicy.getUuid()); - } - - public void addToQosPortsCache(Uuid qosUuid, Port port) { - if (qosPortsMap.containsKey(qosUuid)) { - if (!qosPortsMap.get(qosUuid).containsKey(port.getUuid())) { - qosPortsMap.get(qosUuid).put(port.getUuid(), port); - } - } else { - HashMap newPortMap = new HashMap<>(); - newPortMap.put(port.getUuid(), port); - qosPortsMap.put(qosUuid, newPortMap); - } - } - - public void removeFromQosPortsCache(Uuid qosUuid, Port port) { - if (qosPortsMap.containsKey(qosUuid) && qosPortsMap.get(qosUuid).containsKey(port.getUuid())) { - qosPortsMap.get(qosUuid).remove(port.getUuid(), port); - } - } - - public void addToQosNetworksCache(Uuid qosUuid, Network network) { - if (qosNetworksMap.containsKey(qosUuid)) { - if (!qosNetworksMap.get(qosUuid).containsKey(network.getUuid())) { - qosNetworksMap.get(qosUuid).put(network.getUuid(), network); - } - } else { - HashMap newNetworkMap = new HashMap<>(); - newNetworkMap.put(network.getUuid(), network); - qosNetworksMap.put(qosUuid, newNetworkMap); - } - } - - public void removeFromQosNetworksCache(Uuid qosUuid, Network network) { - if (qosNetworksMap.containsKey(qosUuid) && qosNetworksMap.get(qosUuid).containsKey(network.getUuid())) { - qosNetworksMap.get(qosUuid).remove(network.getUuid(), network); - } + NetworkL3Extension ext = network.augmentation(NetworkL3Extension.class); + return ext != null && ext.isExternal(); } static InstanceIdentifier buildNetworkMapIdentifier(Uuid networkId) { @@ -1046,9 +1048,7 @@ public class NeutronvpnUtils { } static InstanceIdentifier buildSubnetMapIdentifier(Uuid subnetId) { - InstanceIdentifier id = InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class, new - SubnetmapKey(subnetId)).build(); - return id; + return SUBNETMAPS_IID.child(Subnetmap.class, new SubnetmapKey(subnetId)); } static InstanceIdentifier buildVlanInterfaceIdentifier(String interfaceName) { @@ -1057,6 +1057,12 @@ public class NeutronvpnUtils { return id; } + static InstanceIdentifier buildPortIdSubportMappingIdentifier(Uuid interfaceName) { + InstanceIdentifier id = InstanceIdentifier.builder(NeutronVpnPortIdSubportData.class) + .child(PortIdToSubport.class, new PortIdToSubportKey(interfaceName)).build(); + return id; + } + static InstanceIdentifier buildExtRoutersIdentifier(Uuid routerId) { InstanceIdentifier buildPortSubnetIdentifier(String portId) { - InstanceIdentifier id = InstanceIdentifier.builder(PortSubnets.class) - .child(PortSubnet.class, new PortSubnetKey(portId)).build(); - return id; - } - // TODO Remove this method entirely @SuppressWarnings("checkstyle:IllegalCatch") private Optional read(LogicalDatastoreType datastoreType, InstanceIdentifier path) { try { return SingleTransactionDataBroker.syncReadOptional(dataBroker, datastoreType, path); - } catch (ReadFailedException e) { + } catch (ExecutionException | InterruptedException e) { throw new RuntimeException(e); } } - public static Class getNetworkType(Network network) { - NetworkProviderExtension providerExtension = network.augmentation(NetworkProviderExtension.class); - return providerExtension != null ? providerExtension.getNetworkType() : null; - } - + @Nullable static ProviderTypes getProviderNetworkType(Network network) { if (network == null) { LOG.error("Error in getting provider network type since network is null"); @@ -1119,22 +1115,23 @@ public class NeutronvpnUtils { static boolean isNetworkTypeSupported(Network network) { NetworkProviderExtension npe = network.augmentation(NetworkProviderExtension.class); - return npe != null && npe.getNetworkType() != null && SUPPORTED_NETWORK_TYPES.contains(npe.getNetworkType()); + return npe != null && SUPPORTED_NETWORK_TYPES.contains(npe.getNetworkType()); } - static boolean isNetworkOfType(Network network, Class type) { - NetworkProviderExtension npe = network.augmentation(NetworkProviderExtension.class); - if (npe != null && npe.getNetworkType() != null) { - return type.isAssignableFrom(npe.getNetworkType()); + static boolean isFlatOrVlanNetwork(Network network) { + if (network != null) { + NetworkProviderExtension npe = network.augmentation(NetworkProviderExtension.class); + if (npe != null) { + Class npeType = npe.getNetworkType(); + if (npeType != null) { + return NetworkTypeVlan.class.isAssignableFrom(npeType) + || NetworkTypeFlat.class.isAssignableFrom(npeType); + } + } } return false; } - static boolean isFlatOrVlanNetwork(Network network) { - return network != null - && (isNetworkOfType(network, NetworkTypeVlan.class) || isNetworkOfType(network, NetworkTypeFlat.class)); - } - static boolean isVlanOrVxlanNetwork(Class type) { return type.isAssignableFrom(NetworkTypeVxlan.class) || type.isAssignableFrom(NetworkTypeVlan.class); } @@ -1159,73 +1156,40 @@ public class NeutronvpnUtils { */ public Optional getInterVpnLinkByEndpointIp(String endpointIp) { InstanceIdentifier interVpnLinksIid = InstanceIdentifier.builder(InterVpnLinks.class).build(); - Optional interVpnLinksOpData = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, - interVpnLinksIid); - if (interVpnLinksOpData.isPresent()) { - List allInterVpnLinks = interVpnLinksOpData.get().getInterVpnLink(); - for (InterVpnLink interVpnLink : allInterVpnLinks) { - if (interVpnLink.getFirstEndpoint().getIpAddress().getValue().equals(endpointIp) - || interVpnLink.getSecondEndpoint().getIpAddress().getValue().equals(endpointIp)) { - return Optional.of(interVpnLink); - } - } - } - return Optional.absent(); - } - - public Set getAllRouterDpnList(BigInteger dpid) { - Set ret = new HashSet<>(); - InstanceIdentifier routerDpnId = - InstanceIdentifier.create(NeutronRouterDpns.class); - Optional neutronRouterDpnsOpt = - MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, routerDpnId); - if (neutronRouterDpnsOpt.isPresent()) { - NeutronRouterDpns neutronRouterDpns = neutronRouterDpnsOpt.get(); - List routerDpnLists = neutronRouterDpns.getRouterDpnList(); - for (RouterDpnList routerDpnList : routerDpnLists) { - if (routerDpnList.getDpnVpninterfacesList() != null) { - for (DpnVpninterfacesList dpnInterfaceList : routerDpnList.getDpnVpninterfacesList()) { - if (dpnInterfaceList.getDpnId().equals(dpid)) { - ret.add(routerDpnList); - } + Optional interVpnLinksOpData = null; + try { + interVpnLinksOpData = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, + interVpnLinksIid); + if (interVpnLinksOpData.isPresent()) { + for (InterVpnLink interVpnLink : interVpnLinksOpData.get().nonnullInterVpnLink().values()) { + if (interVpnLink.getFirstEndpoint().getIpAddress().getValue().equals(endpointIp) + || interVpnLink.getSecondEndpoint().getIpAddress().getValue().equals(endpointIp)) { + return Optional.of(interVpnLink); } } } + } catch (ExecutionException | InterruptedException e) { + LOG.error("getInterVpnLinkByEndpointIp: Exception when reading intervpn Links for endpoint Ip {} ", + endpointIp, e); } - return ret; - } - - protected Integer getUniqueRDId(String poolName, String idKey) { - AllocateIdInput getIdInput = new AllocateIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build(); - try { - Future> result = idManager.allocateId(getIdInput); - RpcResult rpcResult = result.get(); - if (rpcResult.isSuccessful()) { - return rpcResult.getResult().getIdValue().intValue(); - } else { - LOG.error("RPC call to get unique ID for pool name {} with ID key {} returned with errors {}", - poolName, idKey, rpcResult.getErrors()); - } - } catch (InterruptedException | ExecutionException e) { - LOG.error("Exception when getting Unique Id for poolname {} and ID Key {}", poolName, idKey, e); - } - LOG.error("getUniqueRdId: Failed to return ID for poolname {} and ID Key {}", poolName, idKey); - return null; + return Optional.empty(); } - protected void releaseRDId(String poolName, String idKey) { + protected Integer releaseId(String poolName, String idKey) { ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build(); try { - RpcResult rpcResult = idManager.releaseId(idInput).get(); - if (!rpcResult.isSuccessful()) { - LOG.error("RPC Call to Get Unique Id returned with errors for poolname {} and ID Key {}: {}", - poolName, idKey, rpcResult.getErrors()); + Future> result = idManager.releaseId(idInput); + if (result == null || result.get() == null || !result.get().isSuccessful()) { + LOG.error("releaseId: RPC Call to release Id from pool {} with key {} returned with Errors {}", + poolName, idKey, (result != null && result.get() != null) ? result.get().getErrors() : + "RpcResult is null"); } else { - LOG.info("ID {} for RD released successfully", idKey); + return result.get().getResult().getIdValues().get(0).intValue(); } } catch (InterruptedException | ExecutionException e) { - LOG.error("Exception when trying to release ID for poolname {} and ID Key {}", poolName, idKey, e); + LOG.error("releaseId: Exception when releasing Id for key {} from pool {}", idKey, poolName, e); } + return NeutronConstants.INVALID_ID; } protected static IpAddress getIpv6LinkLocalAddressFromMac(MacAddress mac) { @@ -1275,11 +1239,8 @@ public class NeutronvpnUtils { InstanceIdentifier path = InstanceIdentifier.builder(VpnInstances.class).build(); Optional vpnInstancesOptional = read(LogicalDatastoreType.CONFIGURATION, path); if (vpnInstancesOptional.isPresent() && vpnInstancesOptional.get().getVpnInstance() != null) { - for (VpnInstance vpnInstance : vpnInstancesOptional.get().getVpnInstance()) { - if (vpnInstance.getIpv4Family() == null) { - continue; - } - List rds = vpnInstance.getIpv4Family().getRouteDistinguisher(); + for (VpnInstance vpnInstance : vpnInstancesOptional.get().getVpnInstance().values()) { + List rds = vpnInstance.getRouteDistinguisher(); if (rds != null) { existingRDs.addAll(rds); } @@ -1289,9 +1250,7 @@ public class NeutronvpnUtils { } protected boolean doesVpnExist(Uuid vpnId) { - InstanceIdentifier vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap.class, - new VpnMapKey(vpnId)).build(); - return read(LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier).isPresent(); + return read(LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier(vpnId)).isPresent(); } protected Optional buildStaticMacEntry(Port port) { PhysAddress physAddress = new PhysAddress(port.getMacAddress().getValue()); - List fixedIps = port.getFixedIps(); + Map keyFixedIpsMap = port.getFixedIps(); IpAddress ipAddress = null; - if (isNotEmpty(fixedIps)) { - ipAddress = port.getFixedIps().get(0).getIpAddress(); + if (isNotEmpty(keyFixedIpsMap.values())) { + ipAddress = new ArrayList(port.getFixedIps().values()).get(0).getIpAddress(); } StaticMacEntriesBuilder staticMacEntriesBuilder = new StaticMacEntriesBuilder(); List staticMacEntries = new ArrayList<>(); @@ -1363,10 +1322,9 @@ public class NeutronvpnUtils { */ protected List getNeutronRouterSubnetMaps(Uuid routerId) { List subnetIdList = new ArrayList<>(); - Optional subnetMaps = read(LogicalDatastoreType.CONFIGURATION, - InstanceIdentifier.builder(Subnetmaps.class).build()); + Optional subnetMaps = read(LogicalDatastoreType.CONFIGURATION, SUBNETMAPS_IID); if (subnetMaps.isPresent() && subnetMaps.get().getSubnetmap() != null) { - for (Subnetmap subnetmap : subnetMaps.get().getSubnetmap()) { + for (Subnetmap subnetmap : subnetMaps.get().getSubnetmap().values()) { if (routerId.equals(subnetmap.getRouterId())) { subnetIdList.add(subnetmap); } @@ -1390,11 +1348,12 @@ public class NeutronvpnUtils { * * @return the route-distinguisher of the VPN */ + @Nullable public String getVpnRd(String vpnName) { InstanceIdentifier id = getVpnInstanceToVpnIdIdentifier(vpnName); return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker, - LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map( + LogicalDatastoreType.CONFIGURATION, id).map( org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id .VpnInstance::getVrfId).orElse(null); } @@ -1432,6 +1391,7 @@ public class NeutronvpnUtils { return IpVersionChoice.UNDEFINED; } + @Nullable public VpnInstanceOpDataEntry getVpnInstanceOpDataEntryFromVpnId(String vpnName) { String primaryRd = getVpnRd(vpnName); if (primaryRd == null) { @@ -1449,8 +1409,7 @@ public class NeutronvpnUtils { } protected InstanceIdentifier getVpnOpDataIdentifier(String primaryRd) { - return InstanceIdentifier.builder(VpnInstanceOpData.class) - .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(primaryRd)).build(); + return VPN_INSTANCE_OP_DATA_IID.child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(primaryRd)); } public boolean shouldVpnHandleIpVersionChoiceChange(IpVersionChoice ipVersion, Uuid routerId, boolean add) { @@ -1482,11 +1441,10 @@ public class NeutronvpnUtils { if (sm == null) { return false; } - InstanceIdentifier subnetMapsId = InstanceIdentifier.builder(Subnetmaps.class).build(); - Optional allSubnetMaps = read(LogicalDatastoreType.CONFIGURATION, subnetMapsId); + Optional allSubnetMaps = read(LogicalDatastoreType.CONFIGURATION, SUBNETMAPS_IID); // calculate and store in list IpVersion for each subnetMap, belonging to current VpnInstance List snIpVersions = new ArrayList<>(); - for (Subnetmap snMap: allSubnetMaps.get().getSubnetmap()) { + for (Subnetmap snMap : allSubnetMaps.get().nonnullSubnetmap().values()) { if (snMap.getId().equals(sm.getId())) { continue; } @@ -1520,41 +1478,47 @@ public class NeutronvpnUtils { } public void updateVpnInstanceWithIpFamily(String vpnName, IpVersionChoice ipVersion, boolean add) { - VpnInstanceOpDataEntry vpnInstanceOpDataEntry = getVpnInstanceOpDataEntryFromVpnId(vpnName); - if (vpnInstanceOpDataEntry == null) { - return; - } - if (vpnInstanceOpDataEntry.getType() == VpnInstanceOpDataEntry.Type.L2) { - LOG.debug("updateVpnInstanceWithIpFamily: Update VpnInstance {} with ipFamily {}." - + "VpnInstanceOpDataEntry is L2 instance. Do nothing.", vpnName, ipVersion); - return; - } - if (ipVersion == IpVersionChoice.UNDEFINED) { - LOG.debug("updateVpnInstanceWithIpFamily: Update VpnInstance {} with Undefined address family" - + "is not allowed. Do nothing", vpnName); - return; - } jobCoordinator.enqueueJob("VPN-" + vpnName, () -> { - VpnInstanceOpDataEntryBuilder builder = new VpnInstanceOpDataEntryBuilder(vpnInstanceOpDataEntry); + VpnInstance vpnInstance = getVpnInstance(dataBroker, new Uuid(vpnName)); + if (vpnInstance == null) { + return Collections.emptyList(); + } + if (vpnInstance.isL2vpn()) { + LOG.debug("updateVpnInstanceWithIpFamily: Update VpnInstance {} with ipFamily {}." + + "VpnInstance is L2 instance. Do nothing.", vpnName, ipVersion); + return Collections.emptyList(); + } + if (ipVersion == IpVersionChoice.UNDEFINED) { + LOG.debug("updateVpnInstanceWithIpFamily: Update VpnInstance {} with Undefined address family" + + "is not allowed. Do nothing", vpnName); + return Collections.emptyList(); + } + VpnInstanceBuilder builder = new VpnInstanceBuilder(vpnInstance); boolean ipConfigured = add; - if (ipVersion.isIpVersionChosen(IpVersionChoice.IPV4AND6)) { - builder.setIpv4Configured(ipConfigured); - builder.setIpv6Configured(ipConfigured); - } else if (ipVersion.isIpVersionChosen(IpVersionChoice.IPV4)) { - builder.setIpv4Configured(ipConfigured); - } else if (ipVersion.isIpVersionChosen(IpVersionChoice.IPV6)) { - builder.setIpv6Configured(ipConfigured); + + int originalValue = vpnInstance.getIpAddressFamilyConfigured().getIntValue(); + int updatedValue = ipVersion.choice; + + if (originalValue != updatedValue) { + if (ipConfigured) { + originalValue = originalValue == 0 ? updatedValue : updatedValue + originalValue; + } else { + originalValue = 10 - updatedValue; + } + } else if (!ipConfigured) { + originalValue = 0; } + + builder.setIpAddressFamilyConfigured(VpnInstance.IpAddressFamilyConfigured.forValue(originalValue)); + + InstanceIdentifier vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class) + .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build(); + LOG.info("updateVpnInstanceWithIpFamily: Successfully {} IP family {} to Vpn {}", + add == true ? "added" : "removed", ipVersion, vpnName); return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit( - OPERATIONAL, tx -> { - InstanceIdentifier id = InstanceIdentifier - .builder(VpnInstanceOpData.class).child(VpnInstanceOpDataEntry.class, - new VpnInstanceOpDataEntryKey(vpnInstanceOpDataEntry.getVrfId())).build(); - tx.merge(id, builder.build(), false); - LOG.info("updateVpnInstanceWithIpFamily: Successfully {} {} to Vpn {}", - add == true ? "added" : "removed", ipVersion, vpnName); - })); + CONFIGURATION, tx -> tx.mergeParentStructureMerge(vpnIdentifier, builder.build()))); }); + return; } /** @@ -1564,6 +1528,7 @@ public class NeutronvpnUtils { * @param vpnId the Uuid of the VPN * @return the VpnInstance or null if unfindable */ + @Nullable public VpnInstance getVpnInstance(DataBroker broker, Uuid vpnId) { if (broker == null || vpnId == null) { return null; @@ -1579,7 +1544,7 @@ public class NeutronvpnUtils { * @param routerId the Uuid of the router which you try to reach the external network * @return Uuid of externalNetwork or null if is not exist */ - protected Uuid getExternalNetworkUuidAttachedFromRouterUuid(@Nonnull Uuid routerId) { + protected Uuid getExternalNetworkUuidAttachedFromRouterUuid(@NonNull Uuid routerId) { LOG.debug("getExternalNetworkUuidAttachedFromRouterUuid for {}", routerId.getValue()); Uuid externalNetworkUuid = null; Router router = getNeutronRouter(routerId); @@ -1589,7 +1554,7 @@ public class NeutronvpnUtils { return externalNetworkUuid; } - public Uuid getInternetvpnUuidBoundToRouterId(@Nonnull Uuid routerId) { + public Uuid getInternetvpnUuidBoundToRouterId(@NonNull Uuid routerId) { Uuid netId = getExternalNetworkUuidAttachedFromRouterUuid(routerId); if (netId == null) { return netId; @@ -1604,7 +1569,8 @@ public class NeutronvpnUtils { * @param subnetUuid Uuid of subnet where you are finding a link to an external network * @return Uuid of externalVpn or null if it is not found */ - public Uuid getInternetvpnUuidBoundToSubnetRouter(@Nonnull Uuid subnetUuid) { + @Nullable + public Uuid getInternetvpnUuidBoundToSubnetRouter(@NonNull Uuid subnetUuid) { Subnetmap subnetmap = getSubnetmap(subnetUuid); Uuid routerUuid = subnetmap.getRouterId(); LOG.debug("getInternetvpnUuidBoundToSubnetRouter for subnetUuid {}", subnetUuid.getValue()); @@ -1620,13 +1586,19 @@ public class NeutronvpnUtils { * @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 getPrivateSubnetsToExport(@Nonnull Network extNet) { + public @NonNull List getPrivateSubnetsToExport(@NonNull Network extNet, Uuid internetVpnId) { List subList = new ArrayList<>(); - Uuid extNetVpnId = getVpnForNetwork(extNet.getUuid()); - if (extNetVpnId == null) { + List rtrList = new ArrayList<>(); + if (internetVpnId != null) { + rtrList.addAll(getRouterIdListforVpn(internetVpnId)); + } else { + Uuid extNwVpnId = getVpnForNetwork(extNet.getUuid()); + rtrList.addAll(getRouterIdListforVpn(extNwVpnId)); + } + if (rtrList.isEmpty()) { return subList; } - for (Uuid rtrId: getRouterIdListforVpn(extNetVpnId)) { + for (Uuid rtrId: rtrList) { Router router = getNeutronRouter(rtrId); ExternalGatewayInfo info = router.getExternalGatewayInfo(); if (info == null) { @@ -1640,19 +1612,26 @@ public class NeutronvpnUtils { router.getUuid().getValue(), extNet.getUuid().getValue()); continue; } - subList.addAll(getSubnetsforVpn(rtrId)); + subList.addAll(getNeutronRouterSubnetIds(rtrId)); } return subList; } - public void updateVpnInstanceWithFallback(String vpnName, boolean add) { - VpnInstanceOpDataEntry vpnInstanceOpDataEntry = getVpnInstanceOpDataEntryFromVpnId(vpnName); + public void updateVpnInstanceWithFallback(Uuid routerId, Uuid vpnName, boolean add) { + VpnInstanceOpDataEntry vpnInstanceOpDataEntry = getVpnInstanceOpDataEntryFromVpnId(vpnName.getValue()); if (vpnInstanceOpDataEntry == null) { LOG.error("updateVpnInstanceWithFallback: vpnInstanceOpDataEntry not found for vpn {}", vpnName); return; } - Long vpnId = vpnInstanceOpDataEntry.getVpnId(); - List routerIds = getRouterIdsfromVpnInstance(vpnInstanceOpDataEntry.getVrfId()); + Long internetBgpVpnId = vpnInstanceOpDataEntry.getVpnId().toJava(); + List routerIds = new ArrayList<>(); + //Handle router specific V6 internet fallback flow else handle all V6 external routers + if (routerId != null) { + routerIds.add(routerId); + } else { + //This block will execute for ext-nw to Internet VPN association/disassociation event. + routerIds = getRouterIdListforVpn(vpnName); + } if (routerIds == null || routerIds.isEmpty()) { LOG.error("updateVpnInstanceWithFallback: router not found for vpn {}", vpnName); return; @@ -1661,31 +1640,45 @@ public class NeutronvpnUtils { if (rtrId == null) { continue; } - List dpnIds = getDpnsForRouter(rtrId.getValue()); + List dpnIds = getDpnsForRouter(rtrId.getValue()); if (dpnIds.isEmpty()) { continue; } VpnInstanceOpDataEntry vpnOpDataEntry = getVpnInstanceOpDataEntryFromVpnId(rtrId.getValue()); - Long routerIdAsLong = vpnOpDataEntry.getVpnId(); - for (BigInteger dpnId : dpnIds) { + Long routerIdAsLong = vpnOpDataEntry.getVpnId().toJava(); + long vpnId; + Uuid rtrVpnId = getVpnForRouter(rtrId, true); + if (rtrVpnId == null) { + //If external BGP-VPN is not associated with router then routerId is same as routerVpnId + vpnId = routerIdAsLong; + } else { + vpnId = getVpnId(rtrVpnId.getValue()); + } + for (Uint64 dpnId : dpnIds) { if (add) { - ipV6InternetDefRt.installDefaultRoute(dpnId, vpnId, routerIdAsLong); + LoggingFutures.addErrorLogging( + txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.CONFIGURATION, + tx -> ipV6InternetDefRt.installDefaultRoute(tx, dpnId, rtrId.getValue(), + internetBgpVpnId, vpnId)), LOG, "Error adding default route"); } else { - ipV6InternetDefRt.removeDefaultRoute(dpnId, vpnId, routerIdAsLong); + LoggingFutures.addErrorLogging( + txRunner.callWithNewReadWriteTransactionAndSubmit(Datastore.CONFIGURATION, + tx -> ipV6InternetDefRt.removeDefaultRoute(tx, dpnId, rtrId.getValue(), + internetBgpVpnId, vpnId)), LOG, + "Error removing default route"); } } } } - public void updateVpnInstanceOpWithType(VpnInstanceOpDataEntry.BgpvpnType choice, @Nonnull Uuid vpn) { + public void updateVpnInstanceOpWithType(VpnInstanceOpDataEntry.BgpvpnType choice, @NonNull Uuid vpn) { String primaryRd = getVpnRd(vpn.getValue()); if (primaryRd == null) { LOG.debug("updateVpnInstanceOpWithType: Update BgpvpnType {} for {}." + "Primary RD not found", choice, vpn.getValue()); return; } - InstanceIdentifier id = InstanceIdentifier.builder(VpnInstanceOpData.class) - .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(primaryRd)).build(); + InstanceIdentifier id = getVpnOpDataIdentifier(primaryRd); Optional vpnInstanceOpDataEntryOptional = read(LogicalDatastoreType.OPERATIONAL, id); @@ -1703,59 +1696,11 @@ public class NeutronvpnUtils { VpnInstanceOpDataEntryBuilder builder = new VpnInstanceOpDataEntryBuilder(vpnInstanceOpDataEntry); builder.setBgpvpnType(choice); ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> { - tx.merge(id, builder.build(), false); + tx.merge(id, builder.build()); LOG.debug("updateVpnInstanceOpWithType: sent merge to operDS BgpvpnType {} for {}", choice, vpn.getValue()); }), LOG, "Error updating VPN instance op {} with type {}", vpn, choice); } - public List getAssociateRouterInputRouterIdsListUuid(List routerIds) { - if (routerIds == null) { - return Collections.emptyList(); - } - return routerIds.stream().map( - routerId -> routerId.getRouterId()).collect(Collectors.toList()); - } - - public List getDisassociateRouterInputRouterIdsListUuid(List routerIds) { - if (routerIds == null) { - return Collections.emptyList(); - } - return routerIds.stream().map( - routerId -> routerId.getRouterId()).collect(Collectors.toList()); - } - - public RouterIds getvpnMapRouterIds(Uuid routerId) { - return new RouterIdsBuilder().setRouterId(routerId).build(); - } - - public void removeVpnMapRouterIdsFromList(Uuid routerId, List vpnRouterIds) { - Iterator vpnRouterIdIter = vpnRouterIds.iterator(); - while (vpnRouterIdIter.hasNext()) { - RouterIds vpnRouterId = vpnRouterIdIter.next(); - if (vpnRouterId.getRouterId().getValue().equals(routerId.getValue())) { - vpnRouterIdIter.remove(); - return; - } - } - return; - } - - public boolean vpnMapRouterIdsContainsRouterId(Uuid routerId, List vpnRouterIds) { - if (routerId == null) { - return false; - } - return vpnRouterIds.stream().anyMatch(vpnRouterId -> - vpnRouterId.getRouterId().getValue().equals(routerId.getValue())); - } - - public List getVpnInstanceRouterIdsListUuid(List routerIds) { - if (routerIds == null) { - return Collections.emptyList(); - } - return routerIds.stream().map( - routerId -> routerId.getRouterId()).collect(Collectors.toList()); - } - public static RouterIds getvpnInstanceRouterIds(Uuid routerId) { return new RouterIdsBuilder().setRouterId(routerId).build(); } @@ -1769,46 +1714,24 @@ public class NeutronvpnUtils { return listRouterIds; } - @Nonnull - public List getDpnsForRouter(String routerUuid) { + @NonNull + public List getDpnsForRouter(String routerUuid) { InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class) .child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build(); Optional routerDpnListData = SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker, LogicalDatastoreType.OPERATIONAL, id); - List dpns = new ArrayList<>(); + List dpns = new ArrayList<>(); if (routerDpnListData.isPresent()) { - List dpnVpninterfacesList = routerDpnListData.get().getDpnVpninterfacesList(); - for (DpnVpninterfacesList dpnVpnInterface : dpnVpninterfacesList) { + for (DpnVpninterfacesList dpnVpnInterface + : routerDpnListData.get().nonnullDpnVpninterfacesList().values()) { dpns.add(dpnVpnInterface.getDpnId()); } } return dpns; } - public List getRouterIdsfromVpnInstance(String vpnName) { - // returns only router, attached to IPv4 networks - InstanceIdentifier vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class) - .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build(); - Optional optionalVpnMap = SingleTransactionDataBroker - .syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker, - LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier); - if (!optionalVpnMap.isPresent()) { - LOG.error("getRouterIdsfromVpnInstance : Router not found for vpn : {}", vpnName); - return null; - } - List rtrIds = optionalVpnMap.get().getRouterIds().stream().map(routerIds -> routerIds.getRouterId()) - .collect(Collectors.toList()); - return rtrIds; - - } - - public InstanceIdentifier buildNeutronRouterIdentifier(Uuid routerUuid) { - InstanceIdentifier routerInstanceIdentifier = InstanceIdentifier.create(Neutron.class) - .child(Routers.class).child(Router.class, new RouterKey(routerUuid)); - return routerInstanceIdentifier; - } - + @Nullable List getSubnetmapListFromNetworkId(Uuid networkId) { List subnetIdList = getSubnetIdsFromNetworkId(networkId); if (subnetIdList != null) { @@ -1828,4 +1751,75 @@ public class NeutronvpnUtils { networkId.getValue()); return null; } + + @Nullable + public long getVpnId(String vpnName) { + InstanceIdentifier id = getVpnInstanceToVpnIdIdentifier(vpnName); + return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker, + LogicalDatastoreType.CONFIGURATION, id).map( + org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id + .VpnInstance::getVpnId).orElse(null).toJava(); + } + + protected boolean isV6SubnetPartOfRouter(Uuid routerId) { + List subnetList = getNeutronRouterSubnetMapList(routerId); + for (Subnetmap sm : subnetList) { + if (sm == null) { + continue; + } + IpVersionChoice ipVers = getIpVersionFromString(sm.getSubnetIp()); + //skip further subnet processing once found first V6 subnet for the router + if (ipVers.isIpVersionChosen(IpVersionChoice.IPV6)) { + return true; + } + } + return false; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public void asyncReadAndExecute(final LogicalDatastoreType datastoreType, + final InstanceIdentifier iid, final String jobKey, + final Function, Void> function) { + jobCoordinator.enqueueJob(jobKey, () -> { + SettableFuture> settableFuture = SettableFuture.create(); + List futures = Collections.singletonList(settableFuture); + try (ReadTransaction tx = dataBroker.newReadOnlyTransaction()) { + Futures.addCallback(tx.read(datastoreType, iid), + new SettableFutureCallback>(settableFuture) { + @Override + public void onSuccess(Optional data) { + function.apply(data); + super.onSuccess(data); + } + }, MoreExecutors.directExecutor()); + + return futures; + } + }, JOB_MAX_RETRIES); + } + + private static InstanceIdentifier vpnMapIdentifier(Uuid uuid) { + return VPN_MAPS_IID.child(VpnMap.class, new VpnMapKey(uuid)); + } + + private class SettableFutureCallback implements FutureCallback { + + private final SettableFuture settableFuture; + + SettableFutureCallback(SettableFuture settableFuture) { + this.settableFuture = settableFuture; + } + + @Override + public void onSuccess(T objT) { + settableFuture.set(objT); + } + + @Override + public void onFailure(Throwable throwable) { + settableFuture.setException(throwable); + } + } } +