X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=vpnmanager%2Fimpl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetvirt%2Fvpnmanager%2FVpnOpStatusListener.java;fp=vpnmanager%2Fimpl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetvirt%2Fvpnmanager%2FVpnOpStatusListener.java;h=031f5d64b73917a3b89f45c11ecee179fae2e6e1;hb=92f74e5e14561bc7681eda9758f5a7ad358bb695;hp=155bbf6f0c80731cddbb8a405e8c985665612818;hpb=8a7e0d088e0c4501b3747ba7f6a781813192fd85;p=netvirt.git diff --git a/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnOpStatusListener.java b/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnOpStatusListener.java index 155bbf6f0c..031f5d64b7 100644 --- a/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnOpStatusListener.java +++ b/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnOpStatusListener.java @@ -8,16 +8,21 @@ package org.opendaylight.netvirt.vpnmanager; import com.google.common.base.Optional; +import com.google.common.util.concurrent.CheckedFuture; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.concurrent.ExecutionException; import javax.annotation.PostConstruct; import javax.inject.Inject; import javax.inject.Singleton; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase; import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager; import org.opendaylight.genius.utils.SystemPropertyReader; @@ -27,7 +32,11 @@ import org.opendaylight.netvirt.fibmanager.api.IFibManager; import org.opendaylight.netvirt.vpnmanager.api.VpnExtraRouteHelper; import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.AddressFamily; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.L3nexthop; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.VpnNexthops; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.VpnNexthopsKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.VpnIds; 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.VpnTarget; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroutes.Vpn; @@ -95,13 +104,18 @@ public class VpnOpStatusListener extends AsyncDataTreeChangeListenerBase { - WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction(); + WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction(); + WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction(); // Clean up VpnInstanceToVpnId from Config DS - VpnUtil.removeVpnIdToVpnInstance(dataBroker, vpnId, writeTxn); - VpnUtil.removeVpnInstanceToVpnId(dataBroker, vpnName, writeTxn); + VpnUtil.removeVpnIdToVpnInstance(dataBroker, vpnId, writeConfigTxn); + VpnUtil.removeVpnInstanceToVpnId(dataBroker, vpnName, writeConfigTxn); LOG.trace("Removed vpnIdentifier for rd{} vpnname {}", primaryRd, vpnName); + // Clean up FIB Entries Config DS - fibManager.removeVrfTable(primaryRd, null); + synchronized (vpnName.intern()) { + fibManager.removeVrfTable(primaryRd, null); + } + // Clean up VPNExtraRoutes Operational DS if (VpnUtil.isBgpVpn(vpnName, primaryRd)) { if (update.getType() == VpnInstanceOpDataEntry.Type.L2) { @@ -118,26 +132,49 @@ public class VpnOpStatusListener extends AsyncDataTreeChangeListenerBase optVpnToExtraroute = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, vpnToExtraroute); if (optVpnToExtraroute.isPresent()) { - VpnUtil.removeVpnExtraRouteForVpn(dataBroker, vpnName, writeTxn); + VpnUtil.removeVpnExtraRouteForVpn(dataBroker, vpnName, writeOperTxn); } if (VpnUtil.isL3VpnOverVxLan(update.getL3vni())) { VpnUtil.removeExternalTunnelDemuxFlows(vpnName, dataBroker, mdsalManager); } - // Clean up VPNInstanceOpDataEntry - VpnUtil.removeVpnOpInstance(dataBroker, primaryRd, writeTxn); // Clean up PrefixToInterface Operational DS - VpnUtil.removePrefixToInterfaceForVpnId(dataBroker, vpnId, writeTxn); + Optional optPrefixToIntf = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, + VpnUtil.getPrefixToInterfaceIdentifier(vpnId)); + if (optPrefixToIntf.isPresent()) { + VpnUtil.removePrefixToInterfaceForVpnId(dataBroker, vpnId, writeOperTxn); + } // Clean up L3NextHop Operational DS - VpnUtil.removeL3nexthopForVpnId(dataBroker, vpnId, writeTxn); + InstanceIdentifier vpnNextHops = InstanceIdentifier.builder(L3nexthop.class).child( + VpnNexthops.class, new VpnNexthopsKey(vpnId)).build(); + Optional optL3nexthopForVpnId = VpnUtil.read(dataBroker, + LogicalDatastoreType.OPERATIONAL, + vpnNextHops); + if (optL3nexthopForVpnId.isPresent()) { + VpnUtil.removeL3nexthopForVpnId(dataBroker, vpnId, writeOperTxn); + } + + // Clean up VPNInstanceOpDataEntry + VpnUtil.removeVpnOpInstance(dataBroker, primaryRd, writeOperTxn); - // Release the ID used for this VPN back to IdManager - VpnUtil.releaseId(idManager, VpnConstants.VPN_IDPOOL_NAME, vpnName); + // Note: Release the of VpnId will happen in PostDeleteVpnInstancWorker only if + // operationalTxn/Config succeeds. + CheckedFuture checkFutures = writeOperTxn.submit(); + try { + checkFutures.get(); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Error deleting vpn {} ", vpnName); + writeConfigTxn.cancel(); + throw new RuntimeException(e); + } List> futures = new ArrayList<>(); - futures.add(writeTxn.submit()); + futures.add(writeConfigTxn.submit()); + ListenableFuture> listenableFuture = Futures.allAsList(futures); + Futures.addCallback(listenableFuture, new VpnOpStatusListener.PostDeleteVpnInstanceWorker(vpnName)); + LOG.info("Removed vpn data for vpnname {}", vpnName); return futures; }, SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries()); } else if (update.getVpnState() == VpnInstanceOpDataEntry.VpnState.Created) { @@ -217,4 +254,32 @@ public class VpnOpStatusListener extends AsyncDataTreeChangeListenerBase> { + private final Logger log = LoggerFactory.getLogger(VpnOpStatusListener.PostDeleteVpnInstanceWorker.class); + String vpnName; + + PostDeleteVpnInstanceWorker(String vpnName) { + this.vpnName = vpnName; + } + + /** + * This implies that all the future instances have returned success. + * Release the ID used for VPN back to IdManager + */ + @Override + public void onSuccess(List voids) { + VpnUtil.releaseId(idManager, VpnConstants.VPN_IDPOOL_NAME, vpnName); + log.info("onSuccess: VpnId for VpnName {} is released to IdManager successfully.", vpnName); + } + + /** + * This method is used to handle failure callbacks. + */ + @Override + public void onFailure(Throwable throwable) { + log.error("onFailure: Job for vpnInstance: {} failed with exception:", + vpnName , throwable); + } + } }