*Problem: When a new Extra-route is added and if there are not enough RDs
for the VPN then the new extra-routes are not handled.
These unprocessed extra-routes will be handled during vpninstance update
(ie when new RDs are added(Update) to the existing VPN)
Change-Id: Ic380b6aaabdd0d44484c2ec1a33de7cde9c01366
Signed-off-by: epgoraj <p.govinda.rajulu@ericsson.com>
protected void update(InstanceIdentifier<Bgpvpn> identifier, Bgpvpn original, Bgpvpn update) {
LOG.trace("Update Bgpvpn : key: {}, value={}", identifier, update);
if (isBgpvpnTypeL3(update.getType())) {
+ try {
+ handleVpnInstanceUpdate(original.getUuid().getValue(), original.getRouteDistinguishers(),
+ update.getRouteDistinguishers());
+ } catch (UnsupportedOperationException e) {
+ LOG.error("Error while processing Update Bgpvpn.", e);
+ return;
+ }
List<Uuid> oldNetworks = original.getNetworks();
List<Uuid> newNetworks = update.getNetworks();
Uuid vpnId = update.getUuid();
}
}
+ protected void handleVpnInstanceUpdate(String vpnInstanceName,final List<String> originalRds,
+ List<String> updateRDs) throws UnsupportedOperationException {
+ if (updateRDs == null || updateRDs.isEmpty()) {
+ return;
+ }
+ int oldRdsCount = originalRds.size();
+ Iterator<String> originalRdsInter = originalRds.iterator();
+
+ while (originalRdsInter.hasNext()) {
+ String rd = originalRdsInter.next();
+ //If the existing rd is not present in the updateRds list, not allow to process the updateRDs.
+ if (!updateRDs.contains(rd)) {
+ LOG.error("The existing RD:{} not present in the updatedRDsList:{}", rd, updateRDs);
+ throw new UnsupportedOperationException("The existing RD not present in the updatedRDsList");
+ }
+ }
+ if (updateRDs.size() == oldRdsCount) {
+ LOG.debug("There is no update in the List of Route Distinguisher for the VpnInstance:{}", vpnInstanceName);
+ return;
+ }
+ LOG.debug("update the VpnInstance:{} with the List of RDs: {}", vpnInstanceName, updateRDs);
+ nvpnManager.updateVpnInstanceWithRDs(vpnInstanceName, updateRDs);
+ }
+
protected void handleNetworksUpdate(Uuid vpnId, List<Uuid> oldNetworks, List<Uuid> newNetworks) {
if (newNetworks != null && !newNetworks.isEmpty()) {
if (oldNetworks != null && !oldNetworks.isEmpty()) {
}
}
+ public void updateVpnInstanceWithRDs(String vpnInstanceId, final List<String> rds) {
+ InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class)
+ .child(VpnInstance.class, new VpnInstanceKey(vpnInstanceId)).build();
+ Optional<VpnInstance> vpnInstanceConfig =
+ NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIdentifier);
+ if (!vpnInstanceConfig.isPresent()) {
+ LOG.debug("No VpnInstance present under config vpnInstance:{}", vpnInstanceId);
+ return;
+ }
+ VpnInstance vpnInstance = vpnInstanceConfig.get();
+ VpnInstanceBuilder updateVpnInstanceBuilder = new VpnInstanceBuilder(vpnInstance);
+ Ipv4FamilyBuilder ipv4FamilyBuilder = new Ipv4FamilyBuilder(vpnInstance.getIpv4Family());
+ updateVpnInstanceBuilder.setIpv4Family(ipv4FamilyBuilder.setRouteDistinguisher(rds).build());
+ LOG.debug("Updating Config vpn-instance: {} with the list of RDs: {}", vpnInstanceId,rds);
+ try {
+ SingleTransactionDataBroker.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIdentifier,
+ updateVpnInstanceBuilder.build());
+ } catch (TransactionCommitFailedException ex) {
+ LOG.warn("Error configuring feature ", ex);
+ }
+ }
+
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
private void updateVpnInstanceNode(String vpnName, List<String> rd, List<String> irt, List<String> ert,
protected void update(InstanceIdentifier<VpnInstance> identifier,
VpnInstance original, VpnInstance update) {
LOG.trace("Update VPN event key: {}, value: {}", identifier, update);
+ String vpnName = update.getVpnInstanceName();
+ vpnInterfaceManager.updateVpnInterfacesForUnProcessAdjancencies(dataBroker,vpnName);
}
@Override
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
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.vpn.instance.op.data.entry.VpnTargets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpntargets.VpnTarget;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroutes.vpn.extra.routes.Routes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
return true;
}
}
+
+ public void updateVpnInterfacesForUnProcessAdjancencies(DataBroker dataBroker,
+ String vpnName) {
+ String primaryRd = VpnUtil.getVpnRd(dataBroker, vpnName);
+ VpnInstanceOpDataEntry vpnInstanceOpData = VpnUtil.getVpnInstanceOpData(dataBroker, primaryRd);
+ if (vpnInstanceOpData == null) {
+ return;
+ }
+ List<VpnToDpnList> vpnToDpnLists = vpnInstanceOpData.getVpnToDpnList();
+ if (vpnToDpnLists == null || vpnToDpnLists.isEmpty()) {
+ return;
+ }
+ LOG.debug("Update the VpnInterfaces for Unprocessed Adjancencies for vpnName:{}", vpnName);
+ vpnToDpnLists.forEach(vpnToDpnList -> {
+ vpnToDpnList.getVpnInterfaces().forEach(vpnInterface -> {
+ InstanceIdentifier<VpnInterface> existingVpnInterfaceId =
+ VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getInterfaceName());
+ Optional<VpnInterface> vpnInterfaceOptional = VpnUtil.read(dataBroker,
+ LogicalDatastoreType.OPERATIONAL, existingVpnInterfaceId);
+ if (!vpnInterfaceOptional.isPresent()) {
+ return;
+ }
+ List<Adjacency> configVpnAdjacencies = VpnUtil.getAdjacenciesForVpnInterfaceFromConfig(dataBroker,
+ vpnInterface.getInterfaceName());
+ if (configVpnAdjacencies == null) {
+ LOG.debug("There is no adjacency available for vpnInterface:{}", vpnInterface);
+ return;
+ }
+ List<Adjacency> operationVpnAdjacencies = vpnInterfaceOptional.get()
+ .getAugmentation(Adjacencies.class).getAdjacency();
+ // Due to insufficient rds, some of the extra route wont get processed when it is added.
+ // The unprocessed adjacencies will be present in config vpn interface DS but will be missing
+ // in operational DS. These unprocessed adjacencies will be handled below.
+ // To obtain unprocessed adjacencies, filtering is done by which the missing adjacencies in operational
+ // DS are retrieved which is used to call addNewAdjToVpnInterface method.
+ configVpnAdjacencies.stream()
+ .filter(adjacency -> operationVpnAdjacencies.stream()
+ .noneMatch(operationalAdjacency ->
+ operationalAdjacency.getIpAddress().equals(adjacency.getIpAddress())))
+ .forEach(adjacency -> {
+ LOG.debug("Processing the vpnInterface{} for the Ajacency:{}", vpnInterface, adjacency);
+ DataStoreJobCoordinator dataStoreJobCoordinator = DataStoreJobCoordinator.getInstance();
+ dataStoreJobCoordinator.enqueueJob("VPNINTERFACE-" + vpnInterface.getInterfaceName(),
+ () -> {
+ WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
+ WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
+ addNewAdjToVpnInterface(existingVpnInterfaceId, adjacency,
+ vpnInterfaceOptional.get().getDpnId(), writeConfigTxn, writeOperTxn);
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ ListenableFuture<Void> operFuture = writeOperTxn.submit();
+ try {
+ operFuture.get();
+ } catch (ExecutionException | InterruptedException e) {
+ LOG.error("Exception encountered while submitting operational"
+ + " future for vpnInterface {}: " + "{}", vpnInterface, e);
+ }
+ futures.add(writeConfigTxn.submit());
+ return futures;
+ });
+ });
+ });
+ });
+ }
}
* @return the primary rd of the VPN
*/
public static String getPrimaryRd(DataBroker dataBroker, String vpnName) {
+ // Retrieves the VPN Route Distinguisher by its Vpn instance name
+ String rd = getVpnRd(dataBroker, vpnName);
+ if (rd != null) {
+ return rd;
+ }
InstanceIdentifier<VpnInstance> id = getVpnInstanceIdentifier(vpnName);
Optional<VpnInstance> vpnInstance = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
if (vpnInstance.isPresent()) {