Remove unnecessary generic types
[netvirt.git] / vpnservice / vpnmanager / vpnmanager-impl / src / main / java / org / opendaylight / netvirt / vpnmanager / VpnSubnetRouteHandler.java
index 6a4f0b7e1c4c59271831227cda8cf43a6e66f7ac..fcc90b4fd2fbeb9a40b1a2408cdb452155ba6324 100644 (file)
@@ -10,12 +10,17 @@ package org.opendaylight.netvirt.vpnmanager;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import java.math.BigInteger;
-import java.util.*;
-
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
+import org.opendaylight.netvirt.vpnmanager.VpnOpDataSyncer.VpnOpDataType;
 import org.opendaylight.netvirt.vpnmanager.utilities.InterfaceUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
@@ -52,25 +57,29 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class VpnSubnetRouteHandler implements NeutronvpnListener {
-    private static final Logger logger = LoggerFactory.getLogger(VpnSubnetRouteHandler.class);
+    private static final Logger LOG = LoggerFactory.getLogger(VpnSubnetRouteHandler.class);
     private final DataBroker dataBroker;
     private final SubnetOpDpnManager subOpDpnManager;
     private final IBgpManager bgpManager;
     private final VpnInterfaceManager vpnInterfaceManager;
     private final IdManagerService idManager;
     private LockManagerService lockManager;
+    private final VpnOpDataSyncer vpnOpDataSyncer;
 
     public VpnSubnetRouteHandler(final DataBroker dataBroker, final SubnetOpDpnManager subnetOpDpnManager,
-                                 final IBgpManager bgpManager, final VpnInterfaceManager vpnIntfManager,
-                                 final IdManagerService idManager, LockManagerService lockManagerService) {
+        final IBgpManager bgpManager, final VpnInterfaceManager vpnIntfManager, final IdManagerService idManager,
+        LockManagerService lockManagerService, final VpnOpDataSyncer vpnOpDataSyncer) {
         this.dataBroker = dataBroker;
         this.subOpDpnManager = subnetOpDpnManager;
         this.bgpManager = bgpManager;
         this.vpnInterfaceManager = vpnIntfManager;
         this.idManager = idManager;
         this.lockManager = lockManagerService;
+        this.vpnOpDataSyncer = vpnOpDataSyncer;
     }
 
+    // TODO Clean up the exception handling
+    @SuppressWarnings("checkstyle:IllegalCatch")
     @Override
     public void onSubnetAddedToVpn(SubnetAddedToVpn notification) {
         if (!notification.isExternalVpn()) {
@@ -81,20 +90,23 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
         String vpnName = notification.getVpnName();
         String subnetIp = notification.getSubnetIp();
         Long elanTag = notification.getElanTag();
+        boolean isRouteAdvertised = false;
 
         Preconditions.checkNotNull(subnetId, "SubnetId cannot be null or empty!");
         Preconditions.checkNotNull(subnetIp, "SubnetPrefix cannot be null or empty!");
         Preconditions.checkNotNull(vpnName, "VpnName cannot be null or empty!");
         Preconditions.checkNotNull(elanTag, "ElanTag cannot be null or empty!");
 
-        logger.info("onSubnetAddedToVpn: Subnet " + subnetId.getValue() + " being added to vpn");
+        LOG.info("onSubnetAddedToVpn: Subnet {} being added to vpn", subnetId.getValue());
         long vpnId = VpnUtil.getVpnId(dataBroker, vpnName);
         if (vpnId == VpnConstants.INVALID_ID) {
-            vpnInterfaceManager.waitForVpnInstance(vpnName, VpnConstants.PER_VPN_INSTANCE_MAX_WAIT_TIME_IN_MILLISECONDS, vpnInterfaceManager.getvpnInstanceToIdSynchronizerMap());
+            vpnOpDataSyncer.waitForVpnDataReady(VpnOpDataType.vpnInstanceToId, vpnName,
+                VpnConstants.PER_VPN_INSTANCE_MAX_WAIT_TIME_IN_MILLISECONDS);
             vpnId = VpnUtil.getVpnId(dataBroker, vpnName);
             if (vpnId == VpnConstants.INVALID_ID) {
-                logger.error("onSubnetAddedToVpn: VpnInstance to VPNId mapping not yet available for VpnName {} processing subnet {} with IP {} " +
-                        ", bailing out now.", vpnName, subnetId, subnetIp);
+                LOG.error(
+                    "onSubnetAddedToVpn: VpnInstance to VPNId mapping not yet available for VpnName {} processing "
+                        + "subnet {} with IP {}, bailing out now.", vpnName, subnetId, subnetIp);
                 return;
             }
         }
@@ -105,51 +117,57 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
                 Subnetmap subMap = null;
 
                 // Please check if subnetId belongs to an External Network
-                InstanceIdentifier<Subnetmap> subMapid = InstanceIdentifier.builder(Subnetmaps.class).
-                        child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
+                InstanceIdentifier<Subnetmap> subMapid =
+                    InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class,
+                        new SubnetmapKey(subnetId)).build();
                 Optional<Subnetmap> sm = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, subMapid);
                 if (!sm.isPresent()) {
-                    logger.error("onSubnetAddedToVpn: Unable to retrieve subnetmap entry for subnet : " + subnetId);
+                    LOG.error("onSubnetAddedToVpn: Unable to retrieve subnetmap entry for subnet : " + subnetId);
                     return;
                 }
                 subMap = sm.get();
-                InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class).
-                        child(Networks.class, new NetworksKey(subMap.getNetworkId())).build();
-                Optional<Networks> optionalNets = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, netsIdentifier);
+                InstanceIdentifier<Networks> netsIdentifier =
+                    InstanceIdentifier.builder(ExternalNetworks.class).child(Networks.class,
+                        new NetworksKey(subMap.getNetworkId())).build();
+                Optional<Networks> optionalNets =
+                    VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, netsIdentifier);
                 if (optionalNets.isPresent()) {
-                    logger.info("onSubnetAddedToVpn: subnet {} is an external subnet on external network {}, so ignoring this for SubnetRoute",
-                            subnetId.getValue(), subMap.getNetworkId().getValue());
+                    LOG.info(
+                        "onSubnetAddedToVpn: subnet {} is an external subnet on external network {}, so ignoring this"
+                            + " for SubnetRoute", subnetId.getValue(), subMap.getNetworkId().getValue());
                     return;
                 }
                 //Create and add SubnetOpDataEntry object for this subnet to the SubnetOpData container
-                InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier = InstanceIdentifier.builder(SubnetOpData.class).
-                        child(SubnetOpDataEntry.class, new SubnetOpDataEntryKey(subnetId)).build();
+                InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
+                    InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
+                        new SubnetOpDataEntryKey(subnetId)).build();
                 Optional<SubnetOpDataEntry> optionalSubs = VpnUtil.read(dataBroker,
                         LogicalDatastoreType.OPERATIONAL,
                         subOpIdentifier);
                 if (optionalSubs.isPresent()) {
-                    logger.error("onSubnetAddedToVpn: SubnetOpDataEntry for subnet " + subnetId.getValue() +
-                            " already detected to be present");
+                    LOG.error("onSubnetAddedToVpn: SubnetOpDataEntry for subnet {} already detected to be present",
+                        subnetId.getValue());
                     return;
                 }
-                logger.debug("onSubnetAddedToVpn: Creating new SubnetOpDataEntry node for subnet: " +  subnetId.getValue());
-                Map<BigInteger, SubnetToDpn> subDpnMap = new HashMap<BigInteger, SubnetToDpn>();
-                SubnetOpDataEntry subOpEntry = null;
+                LOG.debug("onSubnetAddedToVpn: Creating new SubnetOpDataEntry node for subnet: " + subnetId.getValue());
+                Map<BigInteger, SubnetToDpn> subDpnMap = new HashMap<>();
                 BigInteger dpnId = null;
                 BigInteger nhDpnId = null;
                 SubnetToDpn subDpn = null;
 
-                SubnetOpDataEntryBuilder subOpBuilder = new SubnetOpDataEntryBuilder().setKey(new SubnetOpDataEntryKey(subnetId));
+                SubnetOpDataEntryBuilder subOpBuilder =
+                    new SubnetOpDataEntryBuilder().setKey(new SubnetOpDataEntryKey(subnetId));
                 subOpBuilder.setSubnetId(subnetId);
                 subOpBuilder.setSubnetCidr(subnetIp);
                 String rd = VpnUtil.getVpnRdFromVpnInstanceConfig(dataBroker, vpnName);
                 if (rd == null) {
-                    logger.error("onSubnetAddedToVpn: The VPN Instance name " + notification.getVpnName() + " does not have RD ");
+                    LOG.error("onSubnetAddedToVpn: The VPN Instance name {} does not have RD",
+                        notification.getVpnName());
                     return;
                 }
                 subOpBuilder.setVrfId(rd);
                 subOpBuilder.setVpnName(vpnName);
-                subOpBuilder.setSubnetToDpn(new ArrayList<SubnetToDpn>());
+                subOpBuilder.setSubnetToDpn(new ArrayList<>());
                 subOpBuilder.setRouteAdvState(TaskState.Na);
                 subOpBuilder.setElanTag(elanTag);
 
@@ -162,18 +180,19 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
                             try {
                                 dpnId = InterfaceUtils.getDpIdFromInterface(intfState);
                             } catch (Exception e) {
-                                logger.error("onSubnetAddedToVpn: Unable to obtain dpnId for interface {},",
+                                LOG.error("onSubnetAddedToVpn: Unable to obtain dpnId for interface {},",
                                         " subnetroute inclusion for this interface failed with exception {}",
                                         port.getValue(), e);
                                 continue;
                             }
                             if (dpnId.equals(BigInteger.ZERO)) {
-                                logger.info("onSubnetAddedToVpn: Port " + port.getValue() + " is not assigned DPN yet, ignoring ");
+                                LOG.info("onSubnetAddedToVpn: Port " + port.getValue()
+                                    + " is not assigned DPN yet, ignoring ");
                                 continue;
                             }
                             subOpDpnManager.addPortOpDataEntry(port.getValue(), subnetId, dpnId);
                             if (intfState.getOperStatus() != OperStatus.Up) {
-                                logger.info("onSubnetAddedToVpn: Port " + port.getValue() + " is not UP yet, ignoring ");
+                                LOG.info("onSubnetAddedToVpn: Port " + port.getValue() + " is not UP yet, ignoring ");
                                 continue;
                             }
                             subDpn = subOpDpnManager.addInterfaceToDpn(subnetId, dpnId, port.getValue());
@@ -189,12 +208,13 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
                         }
                     }
                     if (subDpnMap.size() > 0) {
-                        subOpBuilder.setSubnetToDpn(new ArrayList<SubnetToDpn>(subDpnMap.values()));
+                        subOpBuilder.setSubnetToDpn(new ArrayList<>(subDpnMap.values()));
                     }
                 }
 
                 if (nhDpnId != null) {
-                    logger.info("Next-Hop dpn {} is available for rd {} subnetIp {} vpn {}", nhDpnId, rd, subnetIp, vpnName);
+                    LOG.info("Next-Hop dpn {} is available for rd {} subnetIp {} vpn {}", nhDpnId, rd, subnetIp,
+                        vpnName);
                     subOpBuilder.setNhDpnId(nhDpnId);
                     try {
                         /*
@@ -203,36 +223,47 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
                         */
                         int label = getLabel(rd, subnetIp);
                         if (label == 0) {
-                            logger.error("Unable to fetch label from Id Manager. Bailing out of handling addition of subnet {} to vpn {}", subnetIp, vpnName);
+                            LOG.error(
+                                "Unable to fetch label from Id Manager. Bailing out of handling addition of subnet {}"
+                                    + " to vpn {}",
+                                subnetIp, vpnName);
                             return;
                         }
-                        addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
-                        subOpBuilder.setRouteAdvState(TaskState.Done);
+                        isRouteAdvertised =
+                            addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
+                        if (isRouteAdvertised) {
+                            subOpBuilder.setRouteAdvState(TaskState.Done);
+                        } else {
+                            subOpBuilder.setNhDpnId(null);
+                            subOpBuilder.setRouteAdvState(TaskState.Na);
+                        }
                     } catch (Exception ex) {
-                        logger.error("onSubnetAddedToVpn: FIB rules and Advertising nhDpnId " + nhDpnId +
-                                " information for subnet " + subnetId.getValue() + " to BGP failed {}", ex);
+                        LOG.error(
+                            "onSubnetAddedToVpn: FIB rules and Advertising nhDpnId {} information for subnet {} to "
+                                + "BGP failed",
+                            nhDpnId, subnetId.getValue(), ex);
                         subOpBuilder.setRouteAdvState(TaskState.Pending);
                     }
-                }else{
-                    logger.info("Next-Hop dpn is unavailable for rd {} subnetIp {} vpn {}", rd, subnetIp, vpnName);
+                } else {
+                    LOG.info("Next-Hop dpn is unavailable for rd {} subnetIp {} vpn {}", rd, subnetIp, vpnName);
                 }
 
-                subOpEntry = subOpBuilder.build();
+                SubnetOpDataEntry subOpEntry = subOpBuilder.build();
                 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, subOpIdentifier, subOpEntry);
-                logger.info("onSubnetAddedToVpn: Added subnetopdataentry to OP Datastore for subnet {}",
+                LOG.info("onSubnetAddedToVpn: Added subnetopdataentry to OP Datastore for subnet {}",
                         subnetId.getValue());
             } catch (Exception ex) {
-                logger.error("Creation of SubnetOpDataEntry for subnet " +
-                        subnetId.getValue() + " failed {}", ex);
+                LOG.error("Creation of SubnetOpDataEntry for subnet {} failed", subnetId.getValue(), ex);
             } finally {
                 VpnUtil.unlockSubnet(lockManager, subnetId.getValue());
             }
         } catch (Exception e) {
-            logger.error("Unable to handle subnet {} added to vpn {} {}", subnetIp, vpnName, e);
+            LOG.error("Unable to handle subnet {} added to vpn {} {}", subnetIp, vpnName, e);
         }
-
     }
 
+    // TODO Clean up the exception handling
+    @SuppressWarnings("checkstyle:IllegalCatch")
     @Override
     public void onSubnetDeletedFromVpn(SubnetDeletedFromVpn notification) {
         Uuid subnetId = notification.getSubnetId();
@@ -240,20 +271,21 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
         if (!notification.isExternalVpn()) {
             return;
         }
-        logger.info("onSubnetDeletedFromVpn: Subnet " + subnetId.getValue() + " being removed from vpn");
+        LOG.info("onSubnetDeletedFromVpn: Subnet " + subnetId.getValue() + " being removed from vpn");
         //TODO(vivek): Change this to use more granularized lock at subnetId level
         try {
             VpnUtil.lockSubnet(lockManager, subnetId.getValue());
             try {
-                InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier = InstanceIdentifier.builder(SubnetOpData.class).
-                    child(SubnetOpDataEntry.class, new SubnetOpDataEntryKey(subnetId)).build();
-                logger.trace(" Removing the SubnetOpDataEntry node for subnet: " +  subnetId.getValue());
+                InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
+                    InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
+                        new SubnetOpDataEntryKey(subnetId)).build();
+                LOG.trace(" Removing the SubnetOpDataEntry node for subnet: " +  subnetId.getValue());
                 Optional<SubnetOpDataEntry> optionalSubs = VpnUtil.read(dataBroker,
                         LogicalDatastoreType.OPERATIONAL,
                         subOpIdentifier);
                 if (!optionalSubs.isPresent()) {
-                    logger.error("onSubnetDeletedFromVpn: SubnetOpDataEntry for subnet " + subnetId.getValue() +
-                            " not available in datastore");
+                    LOG.error("onSubnetDeletedFromVpn: SubnetOpDataEntry for subnet {} not available in datastore",
+                        subnetId.getValue());
                     return;
                 }
 
@@ -262,19 +294,21 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
                  * contain only ports that are UP. So here we explicitly cleanup the ports of the subnet by
                  * going through the list of ports on the subnet
                  */
-                InstanceIdentifier<Subnetmap> subMapid = InstanceIdentifier.builder(Subnetmaps.class).
-                        child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
+                InstanceIdentifier<Subnetmap> subMapid =
+                    InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class,
+                        new SubnetmapKey(subnetId)).build();
                 Optional<Subnetmap> sm = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, subMapid);
                 if (!sm.isPresent()) {
-                    logger.error("Stale ports removal: Unable to retrieve subnetmap entry for subnet : " + subnetId);
+                    LOG.error("Stale ports removal: Unable to retrieve subnetmap entry for subnet : " + subnetId);
                 } else {
                     Subnetmap subMap = sm.get();
                     List<Uuid> portList = subMap.getPortList();
                     if (portList != null) {
                         for (Uuid port : portList) {
-                            InstanceIdentifier<PortOpDataEntry> portOpIdentifier = InstanceIdentifier.builder(PortOpData.class).
-                                    child(PortOpDataEntry.class, new PortOpDataEntryKey(port.getValue())).build();
-                            logger.trace("Deleting portOpData entry for port " + port.getValue());
+                            InstanceIdentifier<PortOpDataEntry> portOpIdentifier =
+                                InstanceIdentifier.builder(PortOpData.class).child(PortOpDataEntry.class,
+                                    new PortOpDataEntryKey(port.getValue())).build();
+                            LOG.trace("Deleting portOpData entry for port " + port.getValue());
                             MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
                         }
                     }
@@ -286,23 +320,24 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
                 String vpnName = subOpBuilder.getVpnName();
                 BigInteger nhDpnId = subOpBuilder.getNhDpnId();
                 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, subOpIdentifier);
-                logger.info("onSubnetDeletedFromVpn: Removed subnetopdataentry for subnet {} successfully from Datastore", subnetId.getValue());
+                LOG.info("onSubnetDeletedFromVpn: Removed subnetopdataentry for subnet {} successfully from Datastore",
+                    subnetId.getValue());
                 try {
                     //Withdraw the routes for all the interfaces on this subnet
                     //Remove subnet route entry from FIB
                     deleteSubnetRouteFromFib(rd, subnetIp, vpnName);
                 } catch (Exception ex) {
-                    logger.error("onSubnetAddedToVpn: Withdrawing routes from BGP for subnet " +
-                            subnetId.getValue() + " failed {}" + ex);
+                    LOG.error("onSubnetAddedToVpn: Withdrawing routes from BGP for subnet {} failed",
+                        subnetId.getValue(), ex);
                 }
             } catch (Exception ex) {
-                logger.error("Removal of SubnetOpDataEntry for subnet " +
-                        subnetId.getValue() + " failed {}" + ex);
+                LOG.error("Removal of SubnetOpDataEntry for subnet {} failed", subnetId.getValue(), ex);
             } finally {
                 VpnUtil.unlockSubnet(lockManager, subnetId.getValue());
             }
         } catch (Exception e) {
-            logger.error("Unable to handle subnet {} removed to vpn {} {}", notification.getSubnetIp(), notification.getVpnName(), e);
+            LOG.error("Unable to handle subnet {} removed to vpn {}", notification.getSubnetIp(),
+                notification.getVpnName(), e);
         }
     }
 
@@ -318,11 +353,11 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
         Preconditions.checkNotNull(vpnName, "VpnName cannot be null or empty!");
         Preconditions.checkNotNull(elanTag, "ElanTag cannot be null or empty!");
 
-        InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier = InstanceIdentifier.builder(SubnetOpData.class).
-                child(SubnetOpDataEntry.class, new SubnetOpDataEntryKey(subnetId)).build();
-        Optional<SubnetOpDataEntry> optionalSubs = VpnUtil.read(dataBroker,
-                LogicalDatastoreType.OPERATIONAL,
-                subOpIdentifier);
+        InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
+            InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
+                new SubnetOpDataEntryKey(subnetId)).build();
+        Optional<SubnetOpDataEntry> optionalSubs =
+            VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, subOpIdentifier);
         if (optionalSubs.isPresent()) {
             if (!notification.isExternalVpn()) {
                 SubnetDeletedFromVpnBuilder bldr = new SubnetDeletedFromVpnBuilder().setVpnName(vpnName);
@@ -333,31 +368,35 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
         } else {
             if (notification.isExternalVpn()) {
                 SubnetAddedToVpnBuilder bldr = new SubnetAddedToVpnBuilder().setVpnName(vpnName).setElanTag(elanTag);
-                bldr.setSubnetIp(subnetIp).setSubnetId(subnetId).setExternalVpn(true);;
+                bldr.setSubnetIp(subnetIp).setSubnetId(subnetId).setExternalVpn(true);
                 onSubnetAddedToVpn(bldr.build());
             }
             // TODO(vivek): Something got updated, but we donot know what ?
         }
     }
 
+    // TODO Clean up the exception handling
+    @SuppressWarnings("checkstyle:IllegalCatch")
     @Override
     public void onPortAddedToSubnet(PortAddedToSubnet notification) {
         Uuid subnetId = notification.getSubnetId();
         Uuid portId = notification.getPortId();
+        boolean isRouteAdvertised = false;
 
-        logger.info("onPortAddedToSubnet: Port " + portId.getValue() + " being added to subnet " + subnetId.getValue());
+        LOG.info("onPortAddedToSubnet: Port " + portId.getValue() + " being added to subnet " + subnetId.getValue());
         //TODO(vivek): Change this to use more granularized lock at subnetId level
         try {
             VpnUtil.lockSubnet(lockManager, subnetId.getValue());
             try {
-                InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier = InstanceIdentifier.builder(SubnetOpData.class).
-                    child(SubnetOpDataEntry.class, new SubnetOpDataEntryKey(subnetId)).build();
+                InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
+                    InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
+                        new SubnetOpDataEntryKey(subnetId)).build();
 
                 Optional<SubnetOpDataEntry> optionalSubs = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
                         subOpIdentifier);
                 if (!optionalSubs.isPresent()) {
-                    logger.info("onPortAddedToSubnet: Port " + portId.getValue() + " is part of a subnet " + subnetId.getValue() +
-                            " that is not in VPN, ignoring");
+                    LOG.info("onPortAddedToSubnet: Port {} is part of a subnet {} that is not in VPN, ignoring",
+                        portId.getValue(), subnetId.getValue());
                     return;
                 }
                 Interface intfState = InterfaceUtils.getInterfaceStateFromOperDS(dataBroker,portId.getValue());
@@ -370,21 +409,22 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
                 try {
                     dpnId = InterfaceUtils.getDpIdFromInterface(intfState);
                 } catch (Exception e) {
-                    logger.error("onSubnetAddedToVpn: Unable to obtain dpnId for interface {},",
+                    LOG.error("onSubnetAddedToVpn: Unable to obtain dpnId for interface {},",
                             " subnetroute inclusion for this interface failed with exception {}",
                             portId.getValue(), e);
                     return;
                 }
                 if (dpnId.equals(BigInteger.ZERO)) {
-                    logger.info("onPortAddedToSubnet: Port " + portId.getValue() + " is not assigned DPN yet, ignoring ");
+                    LOG.info("onPortAddedToSubnet: Port " + portId.getValue() + " is not assigned DPN yet, ignoring ");
                     return;
                 }
                 subOpDpnManager.addPortOpDataEntry(portId.getValue(), subnetId, dpnId);
                 if (intfState.getOperStatus() != OperStatus.Up) {
-                    logger.info("onPortAddedToSubnet: Port " + portId.getValue() + " is not UP yet, ignoring ");
+                    LOG.info("onPortAddedToSubnet: Port " + portId.getValue() + " is not UP yet, ignoring ");
                     return;
                 }
-                logger.debug("onPortAddedToSubnet: Updating the SubnetOpDataEntry node for subnet: " + subnetId.getValue());
+                LOG.debug("onPortAddedToSubnet: Updating the SubnetOpDataEntry node for subnet {}",
+                    subnetId.getValue());
                 SubnetToDpn subDpn = subOpDpnManager.addInterfaceToDpn(subnetId, dpnId, portId.getValue());
                 if (subDpn == null) {
                     return;
@@ -401,44 +441,58 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
                 String subnetIp = subOpBuilder.getSubnetCidr();
                 String vpnName = subOpBuilder.getVpnName();
                 Long elanTag = subOpBuilder.getElanTag();
-                if ((subOpBuilder.getRouteAdvState() == TaskState.Pending) ||
-                        (subOpBuilder.getRouteAdvState() == TaskState.Na)) {
+                if ((subOpBuilder.getRouteAdvState() == TaskState.Pending)
+                    || (subOpBuilder.getRouteAdvState() == TaskState.Na)) {
                     try {
                         // Write the Subnet Route Entry to FIB
                         // Advertise BGP Route here and set route_adv_state to DONE
                         int label = getLabel(rd, subnetIp);
                         if (label == 0) {
-                            logger.error("Unable to fetch label from Id Manager. Bailing out of handling addition of port {} to subnet {} in vpn {}", portId.getValue(), subnetIp, vpnName);
+                            LOG.error(
+                                "Unable to fetch label from Id Manager. Bailing out of handling addition of port {} "
+                                    + "to subnet {} in vpn {}",
+                                portId.getValue(), subnetIp, vpnName);
                             return;
                         }
-                        addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
-                        subOpBuilder.setRouteAdvState(TaskState.Done);
+                        isRouteAdvertised =
+                            addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
+                        if (isRouteAdvertised) {
+                            subOpBuilder.setRouteAdvState(TaskState.Done);
+                        } else {
+                            subOpBuilder.setNhDpnId(null);
+                            subOpBuilder.setRouteAdvState(TaskState.Na);
+                        }
                     } catch (Exception ex) {
-                        logger.error("onPortAddedToSubnet: Advertising NextHopDPN "+ nhDpnId +
-                                " information for subnet " + subnetId.getValue() + " to BGP failed {}", ex);
+                        LOG.error(
+                            "onPortAddedToSubnet: Advertising NextHopDPN {} information for subnet {} to BGP failed",
+                            nhDpnId, subnetId.getValue(), ex);
                     }
                 }
                 SubnetOpDataEntry subOpEntry = subOpBuilder.build();
                 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, subOpIdentifier, subOpEntry);
-                logger.info("onPortAddedToSubnet: Updated subnetopdataentry to OP Datastore for port " + portId.getValue());
+                LOG.info("onPortAddedToSubnet: Updated subnetopdataentry to OP Datastore for port {}",
+                    portId.getValue());
 
             } catch (Exception ex) {
-                logger.error("Creation of SubnetOpDataEntry for subnet " +
-                        subnetId.getValue() + " failed {}", ex);
+                LOG.error("Creation of SubnetOpDataEntry for subnet {} failed", subnetId.getValue(), ex);
             } finally {
                 VpnUtil.unlockSubnet(lockManager, subnetId.getValue());
             }
         } catch (Exception e) {
-            logger.error("Unable to handle port {} added to subnet {} {}", portId.getValue(), subnetId.getValue(), e);
+            LOG.error("Unable to handle port {} added to subnet {} {}", portId.getValue(), subnetId.getValue(), e);
         }
     }
 
+    // TODO Clean up the exception handling
+    @SuppressWarnings("checkstyle:IllegalCatch")
     @Override
     public void onPortRemovedFromSubnet(PortRemovedFromSubnet notification) {
         Uuid subnetId = notification.getSubnetId();
         Uuid portId = notification.getPortId();
+        boolean isRouteAdvertised = false;
 
-        logger.info("onPortRemovedFromSubnet: Port " + portId.getValue() + " being removed from subnet " + subnetId.getValue());
+        LOG.info(
+            "onPortRemovedFromSubnet: Port " + portId.getValue() + " being removed from subnet " + subnetId.getValue());
         //TODO(vivek): Change this to use more granularized lock at subnetId level
         try {
             VpnUtil.lockSubnet(lockManager, subnetId.getValue());
@@ -449,18 +503,21 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
                 }
                 BigInteger dpnId = portOpEntry.getDpnId();
                 if (dpnId == null) {
-                    logger.debug("onPortRemovedFromSubnet:  Port {} does not have a DPNId associated, ignoring", portId.getValue());
+                    LOG.debug("onPortRemovedFromSubnet:  Port {} does not have a DPNId associated, ignoring",
+                        portId.getValue());
                     return;
                 }
-                logger.debug("onPortRemovedFromSubnet: Updating the SubnetOpDataEntry node for subnet: " +  subnetId.getValue());
+                LOG.debug(
+                    "onPortRemovedFromSubnet: Updating the SubnetOpDataEntry node for subnet: " + subnetId.getValue());
                 boolean last = subOpDpnManager.removeInterfaceFromDpn(subnetId, dpnId, portId.getValue());
-                InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier = InstanceIdentifier.builder(SubnetOpData.class).
-                        child(SubnetOpDataEntry.class, new SubnetOpDataEntryKey(subnetId)).build();
+                InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
+                    InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
+                        new SubnetOpDataEntryKey(subnetId)).build();
                 Optional<SubnetOpDataEntry> optionalSubs = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
-                        subOpIdentifier);
+                    subOpIdentifier);
                 if (!optionalSubs.isPresent()) {
-                    logger.info("onPortRemovedFromSubnet: Port " + portId.getValue() + " is part of a subnet " + subnetId.getValue() +
-                            " that is not in VPN, ignoring");
+                    LOG.info("onPortRemovedFromSubnet: Port {} is part of a subnet {} that is not in VPN, ignoring",
+                        portId.getValue(), subnetId.getValue());
                     return;
                 }
                 SubnetOpDataEntry subOpEntry = null;
@@ -474,7 +531,8 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
                 if ((nhDpnId != null) && (nhDpnId.equals(dpnId))) {
                     // select another NhDpnId
                     if (last) {
-                        logger.debug("onPortRemovedFromSubnet: Last port " + portId + " on the subnet: " +  subnetId.getValue());
+                        LOG.debug("onPortRemovedFromSubnet: Last port {} on the subnet {}", portId,
+                            subnetId.getValue());
                         // last port on this DPN, so we need to swap the NHDpnId
                         subDpnList = subOpBuilder.getSubnetToDpn();
                         if (subDpnList.isEmpty()) {
@@ -484,29 +542,42 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
                                 deleteSubnetRouteFromFib(rd, subnetIp, vpnName);
                                 subOpBuilder.setRouteAdvState(TaskState.Na);
                             } catch (Exception ex) {
-                                logger.error("onPortRemovedFromSubnet: Withdrawing NextHopDPN " + dpnId + " information for subnet " +
-                                  subnetId.getValue() + " from BGP failed ", ex);
+                                LOG.error(
+                                    "onPortRemovedFromSubnet: Withdrawing NextHopDPN {} information for subnet {} "
+                                        + "from BGP failed ",
+                                    dpnId, subnetId.getValue(), ex);
                                 subOpBuilder.setRouteAdvState(TaskState.Pending);
                             }
                         } else {
                             nhDpnId = subDpnList.get(0).getDpnId();
                             subOpBuilder.setNhDpnId(nhDpnId);
-                            logger.debug("onInterfaceDown: Swapping the Designated DPN to " + nhDpnId + " for subnet " + subnetId.getValue());
+                            LOG.debug("onInterfaceDown: Swapping the Designated DPN to {} for subnet {}", nhDpnId,
+                                subnetId.getValue());
                             try {
                                 // Best effort Withdrawal of route from BGP for this subnet
                                 // Advertise the new NexthopIP to BGP for this subnet
                                 //withdrawSubnetRoutefromBgp(rd, subnetIp);
                                 int label = getLabel(rd, subnetIp);
                                 if (label == 0) {
-                                    logger.error("Unable to fetch label from Id Manager. Bailing out of handling removal  of port {} from subnet {} in vpn {}", portId.getValue(), subnetIp, vpnName);
+                                    LOG.error(
+                                        "Unable to fetch label from Id Manager. Bailing out of handling removal of "
+                                            + "port {} from subnet {} in vpn {}",
+                                        portId.getValue(), subnetIp, vpnName);
                                     return;
                                 }
-                                addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
-                                subOpBuilder.setRouteAdvState(TaskState.Done);
+                                isRouteAdvertised =
+                                    addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
+                                if (isRouteAdvertised) {
+                                    subOpBuilder.setRouteAdvState(TaskState.Done);
+                                } else {
+                                    subOpBuilder.setNhDpnId(null);
+                                    subOpBuilder.setRouteAdvState(TaskState.Na);
+                                }
                             } catch (Exception ex) {
-                                logger.error("onPortRemovedFromSubnet: Swapping Withdrawing NextHopDPN " + dpnId +
-                                        " information for subnet " + subnetId.getValue() +
-                                        " to BGP failed {}" + ex);
+                                LOG.error(
+                                    "onPortRemovedFromSubnet: Swapping Withdrawing NextHopDPN {} information for "
+                                        + "subnet {} to BGP failed",
+                                    dpnId, subnetId.getValue(), ex);
                                 subOpBuilder.setRouteAdvState(TaskState.Pending);
                             }
                         }
@@ -514,59 +585,64 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
                 }
                 subOpEntry = subOpBuilder.build();
                 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, subOpIdentifier, subOpEntry);
-                logger.info("onPortRemovedFromSubnet: Updated subnetopdataentry to OP Datastore removing port " + portId.getValue());
+                LOG.info(
+                    "onPortRemovedFromSubnet: Updated subnetopdataentry to OP Datastore removing port " + portId
+                        .getValue());
             } catch (Exception ex) {
-                logger.error("Creation of SubnetOpDataEntry for subnet " +
-                        subnetId.getValue() + " failed {}" + ex);
+                LOG.error("Creation of SubnetOpDataEntry for subnet {} failed", subnetId.getValue(), ex);
             } finally {
                 VpnUtil.unlockSubnet(lockManager, subnetId.getValue());
             }
         } catch (Exception e) {
-            logger.error("Unable to handle port {} removed from subnet {} {}", portId.getValue(), subnetId.getValue(), e);
+            LOG.error("Unable to handle port {} removed from subnet {} {}", portId.getValue(), subnetId.getValue(),
+                e);
         }
     }
 
+    // TODO Clean up the exception handling
+    @SuppressWarnings("checkstyle:IllegalCatch")
     public void onInterfaceUp(BigInteger dpnId, String intfName) {
-        logger.info("onInterfaceUp: Port " + intfName);
+        LOG.info("onInterfaceUp: Port " + intfName);
         //TODO(vivek): Change this to use more granularized lock at subnetId level
         SubnetToDpn subDpn = null;
+        boolean isRouteAdvertised = false;
         PortOpDataEntry portOpEntry = subOpDpnManager.getPortOpDataEntry(intfName);
         if (portOpEntry == null) {
-            logger.info("onInterfaceUp: Port " + intfName  + "is part of a subnet not in VPN, ignoring");
+            LOG.info("onInterfaceUp: Port " + intfName + "is part of a subnet not in VPN, ignoring");
             return;
         }
         if ((dpnId == null) || (dpnId == BigInteger.ZERO)) {
             dpnId = portOpEntry.getDpnId();
             if (dpnId == null) {
-                logger.error("onInterfaceUp: Unable to determine the DPNID for port " + intfName);
-            return;
+                LOG.error("onInterfaceUp: Unable to determine the DPNID for port " + intfName);
+                return;
             }
         }
         Uuid subnetId = portOpEntry.getSubnetId();
         try {
             VpnUtil.lockSubnet(lockManager, subnetId.getValue());
             try {
-                InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier = InstanceIdentifier.builder(SubnetOpData.class).
-                    child(SubnetOpDataEntry.class, new SubnetOpDataEntryKey(subnetId)).build();
+                InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
+                    InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
+                        new SubnetOpDataEntryKey(subnetId)).build();
                 Optional<SubnetOpDataEntry> optionalSubs = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
-                        subOpIdentifier);
+                    subOpIdentifier);
                 if (!optionalSubs.isPresent()) {
-                    logger.error("onInterfaceUp: SubnetOpDataEntry for subnet " + subnetId.getValue() +
-                            " is not available");
+                    LOG.error("onInterfaceUp: SubnetOpDataEntry for subnet {} is not available", subnetId.getValue());
                     return;
                 }
 
-                SubnetOpDataEntryBuilder subOpBuilder = new SubnetOpDataEntryBuilder(optionalSubs.get());
-                logger.debug("onInterfaceUp: Updating the SubnetOpDataEntry node for subnet: " +  subnetId.getValue());
+                LOG.debug("onInterfaceUp: Updating the SubnetOpDataEntry node for subnet: " + subnetId.getValue());
                 subOpDpnManager.addPortOpDataEntry(intfName, subnetId, dpnId);
                 subDpn = subOpDpnManager.addInterfaceToDpn(subnetId, dpnId, intfName);
                 if (subDpn == null) {
                     return;
                 }
+                SubnetOpDataEntryBuilder subOpBuilder = new SubnetOpDataEntryBuilder(optionalSubs.get());
                 List<SubnetToDpn> subDpnList = subOpBuilder.getSubnetToDpn();
                 subDpnList.add(subDpn);
                 subOpBuilder.setSubnetToDpn(subDpnList);
-                if (subOpBuilder.getNhDpnId()  == null) {
+                if (subOpBuilder.getNhDpnId() == null) {
                     subOpBuilder.setNhDpnId(dpnId);
                 }
                 BigInteger nhDpnId = subOpBuilder.getNhDpnId();
@@ -574,62 +650,75 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
                 String subnetIp = subOpBuilder.getSubnetCidr();
                 String vpnName = subOpBuilder.getVpnName();
                 Long elanTag = subOpBuilder.getElanTag();
-                if ((subOpBuilder.getRouteAdvState() == TaskState.Pending) || (subOpBuilder.getRouteAdvState() == TaskState.Na)) {
+                if ((subOpBuilder.getRouteAdvState() == TaskState.Pending)
+                    || (subOpBuilder.getRouteAdvState() == TaskState.Na)) {
                     try {
                         // Write the Subnet Route Entry to FIB
                         // Advertise BGP Route here and set route_adv_state to DONE
                         int label = getLabel(rd, subnetIp);
                         if (label == 0) {
-                            logger.error("Unable to fetch label from Id Manager. Bailing out of handling interface up event for port {} for subnet {} in vpn {}", intfName, subnetIp, vpnName);
+                            LOG.error(
+                                "Unable to fetch label from Id Manager. Bailing out of handling interface up event "
+                                    + "for port {} for subnet {} in vpn {}",
+                                intfName, subnetIp, vpnName);
                             return;
                         }
-                        addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
-                        subOpBuilder.setRouteAdvState(TaskState.Done);
+                        isRouteAdvertised =
+                            addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
+                        if (isRouteAdvertised) {
+                            subOpBuilder.setRouteAdvState(TaskState.Done);
+                        } else {
+                            subOpBuilder.setNhDpnId(null);
+                            subOpBuilder.setRouteAdvState(TaskState.Na);
+                        }
                     } catch (Exception ex) {
-                        logger.error("onInterfaceUp: Advertising NextHopDPN " + nhDpnId + " information for subnet " +
-                                subnetId.getValue() + " to BGP failed {}" + ex);
+                        LOG.error("onInterfaceUp: Advertising NextHopDPN {} information for subnet {} to BGP failed",
+                            nhDpnId, subnetId.getValue(), ex);
                     }
                 }
                 SubnetOpDataEntry subOpEntry = subOpBuilder.build();
                 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, subOpIdentifier, subOpEntry);
-                logger.info("onInterfaceUp: Updated subnetopdataentry to OP Datastore port up " + intfName);
+                LOG.info("onInterfaceUp: Updated subnetopdataentry to OP Datastore port up " + intfName);
             } catch (Exception ex) {
-                logger.error("Creation of SubnetOpDataEntry for subnet " +
-                        subnetId.getValue() + " failed {}" + ex);
+                LOG.error("Creation of SubnetOpDataEntry for subnet {} failed", subnetId.getValue(), ex);
             } finally {
                 VpnUtil.unlockSubnet(lockManager, subnetId.getValue());
             }
         } catch (Exception e) {
-            logger.error("Unable to handle interface up event for port {} in subnet {} {}", portOpEntry.getPortId(), subnetId.getValue(), e);
+            LOG.error("Unable to handle interface up event for port {} in subnet {} {}", portOpEntry.getPortId(),
+                subnetId.getValue(), e);
         }
     }
 
+    // TODO Clean up the exception handling
+    @SuppressWarnings("checkstyle:IllegalCatch")
     public void onInterfaceDown(final BigInteger dpnId, final String interfaceName) {
-        logger.info("onInterfaceDown: Port " + interfaceName);
+        boolean isRouteAdvertised = false;
+        LOG.info("onInterfaceDown: Port " + interfaceName);
         //TODO(vivek): Change this to use more granularized lock at subnetId level
         PortOpDataEntry portOpEntry = subOpDpnManager.getPortOpDataEntry(interfaceName);
         if (portOpEntry == null) {
-            logger.info("onInterfaceDown: Port " + interfaceName  + "is part of a subnet not in VPN, ignoring");
+            LOG.info("onInterfaceDown: Port " + interfaceName + "is part of a subnet not in VPN, ignoring");
             return;
         }
-        if ((dpnId  == null) ||(dpnId == BigInteger.ZERO)) {
-            logger.error("onInterfaceDown: Unable to determine the DPNID for port " + interfaceName);
+        if ((dpnId == null) || (dpnId == BigInteger.ZERO)) {
+            LOG.error("onInterfaceDown: Unable to determine the DPNID for port " + interfaceName);
             return;
         }
         Uuid subnetId = portOpEntry.getSubnetId();
         try {
             VpnUtil.lockSubnet(lockManager, subnetId.getValue());
             try {
-                logger.debug("onInterfaceDown: Updating the SubnetOpDataEntry node for subnet: " +  subnetId.getValue());
+                LOG.debug("onInterfaceDown: Updating the SubnetOpDataEntry node for subnet: " + subnetId.getValue());
                 boolean last = subOpDpnManager.removeInterfaceFromDpn(subnetId, dpnId, interfaceName);
-                InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier = InstanceIdentifier.builder(SubnetOpData.class).
-                        child(SubnetOpDataEntry.class, new SubnetOpDataEntryKey(subnetId)).build();
+                InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
+                    InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
+                        new SubnetOpDataEntryKey(subnetId)).build();
                 Optional<SubnetOpDataEntry> optionalSubs = VpnUtil.read(dataBroker,
-                        LogicalDatastoreType.OPERATIONAL,
-                        subOpIdentifier);
+                    LogicalDatastoreType.OPERATIONAL,
+                    subOpIdentifier);
                 if (!optionalSubs.isPresent()) {
-                    logger.error("onInterfaceDown: SubnetOpDataEntry for subnet " + subnetId.getValue() +
-                            " is not available");
+                    LOG.error("onInterfaceDown: SubnetOpDataEntry for subnet {} is not available", subnetId.getValue());
                     return;
                 }
                 SubnetOpDataEntry subOpEntry = null;
@@ -643,7 +732,9 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
                 if ((nhDpnId != null) && (nhDpnId.equals(dpnId))) {
                     // select another NhDpnId
                     if (last) {
-                        logger.debug("onInterfaceDown: Last active port " + interfaceName + " on the subnet: " +  subnetId.getValue());
+                        LOG.debug(
+                            "onInterfaceDown: Last active port " + interfaceName + " on the subnet: " + subnetId
+                                .getValue());
                         // last port on this DPN, so we need to swap the NHDpnId
                         subDpnList = subOpBuilder.getSubnetToDpn();
                         if (subDpnList.isEmpty()) {
@@ -653,27 +744,41 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
                                 deleteSubnetRouteFromFib(rd, subnetIp, vpnName);
                                 subOpBuilder.setRouteAdvState(TaskState.Na);
                             } catch (Exception ex) {
-                                logger.error("onInterfaceDown: Withdrawing NextHopDPN " + dpnId + " information for subnet " +
-                                  subnetId.getValue() + " from BGP failed {}" + ex);
+                                LOG.error(
+                                    "onInterfaceDown: Withdrawing NextHopDPN {} information for subnet {} from BGP "
+                                        + "failed",
+                                    dpnId, subnetId.getValue(), ex);
                                 subOpBuilder.setRouteAdvState(TaskState.Pending);
                             }
                         } else {
                             nhDpnId = subDpnList.get(0).getDpnId();
                             subOpBuilder.setNhDpnId(nhDpnId);
-                            logger.debug("onInterfaceDown: Swapping the Designated DPN to " + nhDpnId + " for subnet " + subnetId.getValue());
+                            LOG.debug(
+                                "onInterfaceDown: Swapping the Designated DPN to {} for subnet {}" , nhDpnId,
+                                    subnetId.getValue());
                             try {
                                 // Best effort Withdrawal of route from BGP for this subnet
                                 //withdrawSubnetRoutefromBgp(rd, subnetIp);
                                 int label = getLabel(rd, subnetIp);
                                 if (label == 0) {
-                                    logger.error("Unable to fetch label from Id Manager. Bailing out of handling interface down event for port {} in subnet {} for vpn {}", interfaceName, subnetIp, vpnName);
+                                    LOG.error(
+                                        "Unable to fetch label from Id Manager. Bailing out of handling interface "
+                                            + "down event for port {} in subnet {} for vpn {}",
+                                        interfaceName, subnetIp, vpnName);
                                     return;
                                 }
-                                addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
-                                subOpBuilder.setRouteAdvState(TaskState.Done);
+                                isRouteAdvertised =
+                                    addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
+                                if (isRouteAdvertised) {
+                                    subOpBuilder.setRouteAdvState(TaskState.Done);
+                                } else {
+                                    subOpBuilder.setNhDpnId(null);
+                                    subOpBuilder.setRouteAdvState(TaskState.Na);
+                                }
                             } catch (Exception ex) {
-                                logger.error("onInterfaceDown: Swapping Withdrawing NextHopDPN " + dpnId + " information for subnet " +
-                                        subnetId.getValue() + " to BGP failed {}" + ex);
+                                LOG.error(
+                                    "onInterfaceDown: Swapping Withdrawing NextHopDPN {} information for "
+                                        + "subnet {} to BGP failed", dpnId, subnetId.getValue(), ex);
                                 subOpBuilder.setRouteAdvState(TaskState.Pending);
                             }
                         }
@@ -681,15 +786,15 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
                 }
                 subOpEntry = subOpBuilder.build();
                 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, subOpIdentifier, subOpEntry);
-                logger.info("onInterfaceDown: Updated subnetopdataentry to OP Datastore port down " + interfaceName);
+                LOG.info("onInterfaceDown: Updated subnetopdataentry to OP Datastore port down " + interfaceName);
             } catch (Exception ex) {
-                logger.error("Creation of SubnetOpDataEntry for subnet " +
-                        subnetId.getValue() + " failed {}" + ex);
+                LOG.error("Creation of SubnetOpDataEntry for subnet {} failed", subnetId.getValue(), ex);
             } finally {
                 VpnUtil.unlockSubnet(lockManager, subnetId.getValue());
             }
         } catch (Exception e) {
-            logger.error("Unable to handle interface down event for port {} in subnet {} {}", portOpEntry.getPortId(), subnetId.getValue(), e);
+            LOG.error("Unable to handle interface down event for port {} in subnet {} {}", portOpEntry.getPortId(),
+                subnetId.getValue(), e);
         }
     }
 
@@ -701,19 +806,23 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
     public void onRouterDisassociatedFromVpn(RouterDisassociatedFromVpn notification) {
     }
 
+    // TODO Clean up the exception handling
+    @SuppressWarnings("checkstyle:IllegalCatch")
     public void updateSubnetRouteOnTunnelUpEvent(Uuid subnetId, BigInteger dpnId) {
-        logger.info("updateSubnetRouteOnTunnelUpEvent: Subnet {} Dpn {}", subnetId.getValue(), dpnId.toString());
+        boolean isRouteAdvertised = false;
+        LOG.info("updateSubnetRouteOnTunnelUpEvent: Subnet {} Dpn {}", subnetId.getValue(), dpnId.toString());
         try {
             VpnUtil.lockSubnet(lockManager, subnetId.getValue());
             try {
-                InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier = InstanceIdentifier.builder(SubnetOpData.class).
-                        child(SubnetOpDataEntry.class, new SubnetOpDataEntryKey(subnetId)).build();
+                InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
+                    InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
+                        new SubnetOpDataEntryKey(subnetId)).build();
                 Optional<SubnetOpDataEntry> optionalSubs = VpnUtil.read(dataBroker,
-                        LogicalDatastoreType.OPERATIONAL,
-                        subOpIdentifier);
+                    LogicalDatastoreType.OPERATIONAL,
+                    subOpIdentifier);
                 if (!optionalSubs.isPresent()) {
-                    logger.error("updateSubnetRouteOnTunnelUpEvent: SubnetOpDataEntry for subnet " + subnetId.getValue() +
-                            " is not available");
+                    LOG.error("updateSubnetRouteOnTunnelUpEvent: SubnetOpDataEntry for subnet {} is not available",
+                        subnetId.getValue());
                     return;
                 }
                 SubnetOpDataEntry subOpEntry = null;
@@ -723,121 +832,95 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
                 String vpnName = subOpBuilder.getVpnName();
                 List<SubnetToDpn> subDpnList = subOpBuilder.getSubnetToDpn();
                 long elanTag = subOpBuilder.getElanTag();
-                if ((subOpBuilder.getRouteAdvState() == TaskState.Pending) || (subOpBuilder.getRouteAdvState() == TaskState.Na)) {
+                if ((subOpBuilder.getRouteAdvState() == TaskState.Pending)
+                    || (subOpBuilder.getRouteAdvState() == TaskState.Na)) {
                     for (SubnetToDpn subDpn : subDpnList) {
                         if (subDpn.getDpnId().equals(dpnId)) {
                             if (subOpBuilder.getNhDpnId() == null) {
                                 try {
                                     subOpBuilder.setNhDpnId(dpnId);
                                     int label = getLabel(rd, subnetIp);
-                                    addSubnetRouteToFib(rd, subnetIp, dpnId, vpnName, elanTag, label, subnetId);
-                                    //advertiseSubnetRouteToBgp(rd, subnetIp, dpnId, vpnName, elanTag, label);
-                                    subOpBuilder.setRouteAdvState(TaskState.Done);
-                                } catch(Exception ex) {
-                                    logger.error("updateSubnetRouteOnTunnelUpEvent: Advertising NextHopDPN " + dpnId + " information for subnet " +
-                                            subnetId.getValue() + " to BGP failed {}" + ex);
+                                    isRouteAdvertised =
+                                        addSubnetRouteToFib(rd, subnetIp, dpnId, vpnName, elanTag, label, subnetId);
+                                    if (isRouteAdvertised) {
+                                        subOpBuilder.setRouteAdvState(TaskState.Done);
+                                    } else {
+                                        subOpBuilder.setNhDpnId(null);
+                                        subOpBuilder.setRouteAdvState(TaskState.Na);
+                                    }
+                                } catch (Exception ex) {
+                                    LOG.error(
+                                        "updateSubnetRouteOnTunnelUpEvent: Advertising NextHopDPN {} information for "
+                                            + "subnet {} to BGP failed",
+                                        dpnId, subnetId.getValue(), ex);
                                 }
                             }
                         }
                     }
-                }
-                subOpEntry = subOpBuilder.build();
-                MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, subOpIdentifier, subOpEntry);
-                logger.info("updateSubnetRouteOnTunnelUpEvent: Updated subnetopdataentry to OP Datastore tunnel up on dpn {} for subnet {}",
+                    subOpEntry = subOpBuilder.build();
+                    MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, subOpIdentifier, subOpEntry);
+                    LOG.info(
+                        "updateSubnetRouteOnTunnelUpEvent: Updated subnetopdataentry to OP Datastore tunnel up on dpn"
+                            + " {} for subnet {}",
                         dpnId.toString(), subnetId.getValue());
+                }
             } catch (Exception ex) {
-                logger.error("Creation of SubnetOpDataEntry for subnet " +
-                        subnetId.getValue() + " failed {}" + ex);
+                LOG.error("Creation of SubnetOpDataEntry for subnet {} failed", subnetId.getValue(), ex);
             } finally {
                 VpnUtil.unlockSubnet(lockManager, subnetId.getValue());
             }
         } catch (Exception e) {
-            logger.error("Unable to handle tunnel up event for subnetId {} dpnId {}", subnetId.getValue(), dpnId.toString());
+            LOG.error("Unable to handle tunnel up event for subnetId {} dpnId {}", subnetId.getValue(),
+                dpnId.toString());
         }
     }
 
+    // TODO Clean up the exception handling
+    @SuppressWarnings("checkstyle:IllegalCatch")
     public void updateSubnetRouteOnTunnelDownEvent(Uuid subnetId, BigInteger dpnId) {
-        logger.info("updateSubnetRouteOnTunnelDownEvent: Subnet {} Dpn {}", subnetId.getValue(), dpnId.toString());
+        LOG.info("updateSubnetRouteOnTunnelDownEvent: Subnet {} Dpn {}", subnetId.getValue(), dpnId.toString());
         //TODO(vivek): Change this to use more granularized lock at subnetId level
         try {
             VpnUtil.lockSubnet(lockManager, subnetId.getValue());
             try {
-                InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier = InstanceIdentifier.builder(SubnetOpData.class).
-                        child(SubnetOpDataEntry.class, new SubnetOpDataEntryKey(subnetId)).build();
+                InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
+                    InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
+                        new SubnetOpDataEntryKey(subnetId)).build();
                 Optional<SubnetOpDataEntry> optionalSubs = VpnUtil.read(dataBroker,
-                        LogicalDatastoreType.OPERATIONAL,
-                        subOpIdentifier);
+                    LogicalDatastoreType.OPERATIONAL,
+                    subOpIdentifier);
                 if (!optionalSubs.isPresent()) {
-                    logger.error("updateSubnetRouteOnTunnelDownEvent: SubnetOpDataEntry for subnet " + subnetId.getValue() +
-                            " is not available");
+                    LOG.error("updateSubnetRouteOnTunnelDownEvent: SubnetOpDataEntry for subnet {} is not available",
+                        subnetId.getValue());
                     return;
                 }
                 SubnetOpDataEntry subOpEntry = null;
-                List<SubnetToDpn> subDpnList = null;
                 SubnetOpDataEntryBuilder subOpBuilder = new SubnetOpDataEntryBuilder(optionalSubs.get());
-                String rd = subOpBuilder.getVrfId();
-                String subnetIp = subOpBuilder.getSubnetCidr();
-                String vpnName = subOpBuilder.getVpnName();
-                long elanTag = subOpBuilder.getElanTag();
                 BigInteger nhDpnId = subOpBuilder.getNhDpnId();
                 if ((nhDpnId != null) && (nhDpnId.equals(dpnId))) {
-                    subDpnList = subOpBuilder.getSubnetToDpn();
-                    List<BigInteger> dpnIdList = new ArrayList<BigInteger>();
-
-                    Iterator<SubnetToDpn> subNetIt = subDpnList.iterator();
-                    while (subNetIt.hasNext()) {
-                        SubnetToDpn subnetToDpn = subNetIt.next();
-                        if (!subnetToDpn.getDpnId().equals(dpnId)) {
-                            dpnIdList.add(subnetToDpn.getDpnId());
-                        }
-                    }
-                    if (dpnIdList.isEmpty()) {
-                        subOpBuilder.setNhDpnId(null);
-                        try {
-                            // Withdraw route from BGP for this subnet
-                            deleteSubnetRouteFromFib(rd, subnetIp, vpnName);
-                            //withdrawSubnetRoutefromBgp(rd, subnetIp);
-                            subOpBuilder.setRouteAdvState(TaskState.Na);
-                        } catch (Exception ex) {
-                            logger.error("updateSubnetRouteOnTunnelDownEvent: Withdrawing NextHopDPN " + dpnId.toString() + " information for subnet " +
-                                    subnetId.getValue() + " from BGP failed {}" + ex);
-                            subOpBuilder.setRouteAdvState(TaskState.Pending);
-                        }
-                    } else {
-                        logger.debug("DpnList {} to choose the next bestfit dpn", dpnIdList);
-                        // current nhdpn not reachable from dc-gw, so we need to swap the NHDpnId
-                        nhDpnId = dpnIdList.get(0);
-                        subOpBuilder.setNhDpnId(nhDpnId);
-                        logger.debug("updateSubnetRouteOnTunnelDownEvent: Swapping the Designated DPN to " + nhDpnId.toString() + " for subnet " + subnetId.getValue());
-                        try {
-                            //update the VRF entry for the subnetroute.
-                            int label = getLabel(rd, subnetIp);
-                            addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
-                            subOpBuilder.setRouteAdvState(TaskState.Done);
-                        } catch (Exception ex) {
-                            logger.error("updateSubnetRouteOnTunnelDownEvent: Swapping Withdrawing NextHopDPN " + dpnId.toString() + " information for subnet " +
-                                    subnetId.getValue() + " to BGP failed {}" + ex);
-                            subOpBuilder.setRouteAdvState(TaskState.Pending);
-                        }
-                    }
-                }
-                subOpEntry = subOpBuilder.build();
-                MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, subOpIdentifier, subOpEntry);
-                logger.info("updateSubnetRouteOnTunnelDownEvent: Updated subnetopdataentry to OP Datastore tunnnel down on dpn {} for subnet {}",
+                    electNewDPNForSubNetRoute(subOpBuilder, dpnId, subnetId);
+                    subOpEntry = subOpBuilder.build();
+                    MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, subOpIdentifier, subOpEntry);
+                    LOG.info(
+                        "updateSubnetRouteOnTunnelDownEvent: Updated subnetopdataentry to OP Datastore tunnnel down "
+                            + "on dpn {} for subnet {}",
                         dpnId.toString(), subnetId.getValue());
+                }
             } catch (Exception ex) {
-                logger.error("Updation of SubnetOpDataEntry for subnet " +
-                        subnetId.getValue() + " failed {}" + ex);
+                LOG.error("Updation of SubnetOpDataEntry for subnet {} failed", subnetId.getValue(), ex);
             } finally {
                 VpnUtil.unlockSubnet(lockManager, subnetId.getValue());
             }
         } catch (Exception e) {
-            logger.error("Unable to handle tunnel down event for subnetId {} dpnId {}", subnetId.getValue(), dpnId.toString());
+            LOG.error("Unable to handle tunnel down event for subnetId {} dpnId {}", subnetId.getValue(),
+                dpnId.toString());
         }
     }
 
-    private void addSubnetRouteToFib(String rd, String subnetIp, BigInteger nhDpnId, String vpnName,
-                                     Long elanTag, int label, Uuid subnetId) throws Exception {
+    // TODO Clean up the exception handling
+    @SuppressWarnings("checkstyle:IllegalCatch")
+    private boolean addSubnetRouteToFib(String rd, String subnetIp, BigInteger nhDpnId, String vpnName,
+        Long elanTag, int label, Uuid subnetId) throws Exception {
         Preconditions.checkNotNull(rd, "RouteDistinguisher cannot be null or empty!");
         Preconditions.checkNotNull(subnetIp, "SubnetRouteIp cannot be null or empty!");
         Preconditions.checkNotNull(vpnName, "vpnName cannot be null or empty!");
@@ -846,33 +929,39 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
         try {
             nexthopIp = InterfaceUtils.getEndpointIpAddressForDPN(dataBroker, nhDpnId);
         } catch (Exception e) {
-            logger.warn("Unable to find nexthopip for subnetroute subnetip {}", subnetIp);
-            return;
+            LOG.warn("Unable to find nexthopip for subnetroute subnetip {}", subnetIp);
+            return false;
         }
         if (nexthopIp != null) {
-            VpnUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, VpnUtil.getPrefixToInterfaceIdentifier(VpnUtil.getVpnId(dataBroker, vpnName), subnetIp), VpnUtil.getPrefixToInterface(nhDpnId, subnetId.getValue(), subnetIp));
-            vpnInterfaceManager.addSubnetRouteFibEntryToDS(rd, vpnName, subnetIp, nexthopIp, label, elanTag, nhDpnId, null);
+            VpnUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
+                VpnUtil.getPrefixToInterfaceIdentifier(VpnUtil.getVpnId(dataBroker, vpnName), subnetIp),
+                VpnUtil.getPrefixToInterface(nhDpnId, subnetId.getValue(), subnetIp));
+            vpnInterfaceManager.addSubnetRouteFibEntryToDS(rd, vpnName, subnetIp, nexthopIp, label, elanTag, nhDpnId,
+                null);
             try {
-                // BGPManager (inside ODL) requires a withdraw followed by advertise
-                // due to bugs with ClusterDataChangeListener used by BGPManager.
-                //bgpManager.withdrawPrefix(rd, subnetIp);
+                //BGP manager will handle withdraw and advertise internally if prefix
+                //already exist
                 bgpManager.advertisePrefix(rd, subnetIp, Arrays.asList(nexthopIp), label);
             } catch (Exception e) {
-                logger.error("Fail: Subnet route not advertised for rd {} subnetIp {}", rd, subnetIp, e);
+                LOG.error("Fail: Subnet route not advertised for rd {} subnetIp {}", rd, subnetIp, e);
                 throw e;
             }
         } else {
-            logger.warn("The nexthopip is empty for subnetroute subnetip {}, ignoring fib route addition", subnetIp);
+            LOG.warn("The nexthopip is empty for subnetroute subnetip {}, ignoring fib route addition", subnetIp);
+            return false;
         }
+        return true;
     }
 
     private int getLabel(String rd, String subnetIp) {
         int label = VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME,
-                                        VpnUtil.getNextHopLabelKey(rd, subnetIp));
-        logger.trace("Allocated subnetroute label {} for rd {} prefix {}", label, rd, subnetIp);
+            VpnUtil.getNextHopLabelKey(rd, subnetIp));
+        LOG.trace("Allocated subnetroute label {} for rd {} prefix {}", label, rd, subnetIp);
         return label;
     }
 
+    // TODO Clean up the exception handling
+    @SuppressWarnings("checkstyle:IllegalCatch")
     private void deleteSubnetRouteFromFib(String rd, String subnetIp, String vpnName) throws Exception {
         Preconditions.checkNotNull(rd, "RouteDistinguisher cannot be null or empty!");
         Preconditions.checkNotNull(subnetIp, "SubnetRouteIp cannot be null or empty!");
@@ -880,9 +969,64 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
         try {
             bgpManager.withdrawPrefix(rd, subnetIp);
         } catch (Exception e) {
-            logger.error("Fail: Subnet route not withdrawn for rd {} subnetIp {}", rd, subnetIp, e);
+            LOG.error("Fail: Subnet route not withdrawn for rd {} subnetIp {}", rd, subnetIp, e);
             throw e;
         }
     }
+
+    // TODO Clean up the exception handling
+    @SuppressWarnings("checkstyle:IllegalCatch")
+    private void electNewDPNForSubNetRoute(SubnetOpDataEntryBuilder subOpBuilder, BigInteger dpnId, Uuid subnetId) {
+        List<SubnetToDpn> subDpnList = null;
+        boolean isRouteAdvertised = false;
+        subDpnList = subOpBuilder.getSubnetToDpn();
+        String rd = subOpBuilder.getVrfId();
+        String subnetIp = subOpBuilder.getSubnetCidr();
+        String vpnName = subOpBuilder.getVpnName();
+        long elanTag = subOpBuilder.getElanTag();
+        BigInteger nhDpnId = null;
+        boolean isAlternateDpnSelected = false;
+        Iterator<SubnetToDpn> subNetIt = subDpnList.iterator();
+        int label = getLabel(rd, subnetIp);
+        while (subNetIt.hasNext()) {
+            SubnetToDpn subnetToDpn = subNetIt.next();
+            nhDpnId = subnetToDpn.getDpnId();
+            if (!nhDpnId.equals(dpnId)) {
+                try {
+                    //update the VRF entry for the subnetroute.
+                    isRouteAdvertised = addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
+                    if (isRouteAdvertised) {
+                        subOpBuilder.setRouteAdvState(TaskState.Done);
+                        subOpBuilder.setNhDpnId(nhDpnId);
+                        isAlternateDpnSelected = true;
+                        break;
+                    }
+                } catch (Exception ex) {
+                    LOG.error(
+                        "electNewDPNForSubNetRoute: Swapping and trying to configure NextHopDPN {} for subnet {} "
+                            + "failed ex {}",
+                        dpnId.toString(), subnetId.getValue(), ex);
+                    subOpBuilder.setRouteAdvState(TaskState.Na);
+                }
+            }
+        }
+
+        //If no alternate Dpn is selected as nextHopDpn ,withdraw the subnetroute.
+        if (!isAlternateDpnSelected) {
+            LOG.info("No alternate DPN available for subnet {}.Prefix withdrawn from BGP", subnetIp);
+            try {
+                // Withdraw route from BGP for this subnet
+                deleteSubnetRouteFromFib(rd, subnetIp, vpnName);
+                subOpBuilder.setNhDpnId(null);
+                subOpBuilder.setRouteAdvState(TaskState.Na);
+            } catch (Exception ex) {
+                LOG.error(
+                    "electNewDPNForSubNetRoute: Withdrawing NextHopDPN " + dpnId.toString() + " information for subnet "
+                        +
+                        subnetId.getValue() + " from BGP failed {}" + ex);
+                subOpBuilder.setRouteAdvState(TaskState.Pending);
+            }
+        }
+    }
 }