Datastore-constrained txes: elanmanager
[netvirt.git] / elanmanager / impl / src / main / java / org / opendaylight / netvirt / elan / utils / TransportZoneNotificationUtil.java
index 117d012b361e155052794b2c06ec5668d81b2aaa..c4c6898a8cfa8da151a60b73ed349add1f3d250f 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.netvirt.elan.utils;
 
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+
 import com.google.common.base.Optional;
 import com.google.common.collect.MapDifference;
 import com.google.common.collect.MapDifference.ValueDifference;
@@ -19,24 +21,32 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
+import java.util.concurrent.ExecutionException;
 import java.util.stream.Collectors;
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 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.ReadFailedException;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
-import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TypedReadTransaction;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
 import org.opendaylight.netvirt.elan.cache.ElanInstanceCache;
 import org.opendaylight.netvirt.elan.internal.ElanBridgeManager;
 import org.opendaylight.netvirt.elanmanager.api.IElanService;
 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeRefInfo;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntryKey;
@@ -59,7 +69,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transp
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.config.rev150710.ElanConfig;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
@@ -74,8 +83,8 @@ public class TransportZoneNotificationUtil {
     private static final char IP_NETWORK_ZONE_NAME_DELIMITER = '-';
     private static final String ALL_SUBNETS_GW = "0.0.0.0";
     private static final String ALL_SUBNETS = "0.0.0.0/0";
-    private final DataBroker dataBroker;
-    private final MdsalUtils mdsalUtils;
+    private final ManagedNewTransactionRunner txRunner;
+    private final SingleTransactionDataBroker singleTxBroker;
     private final SouthboundUtils southBoundUtils;
     private final IElanService elanService;
     private final ElanConfig elanConfig;
@@ -83,16 +92,16 @@ public class TransportZoneNotificationUtil {
     private final ElanInstanceCache elanInstanceCache;
 
     @Inject
-    public TransportZoneNotificationUtil(final DataBroker dbx, final IInterfaceManager interfaceManager,
+    public TransportZoneNotificationUtil(final DataBroker dbx,
             final IElanService elanService, final ElanConfig elanConfig, final ElanBridgeManager elanBridgeManager,
             final ElanInstanceCache elanInstanceCache) {
-        this.dataBroker = dbx;
-        this.mdsalUtils = new MdsalUtils(dbx);
+        this.txRunner = new ManagedNewTransactionRunnerImpl(dbx);
+        this.singleTxBroker = new SingleTransactionDataBroker(dbx);
         this.elanService = elanService;
         this.elanConfig = elanConfig;
         this.elanBridgeManager = elanBridgeManager;
         this.elanInstanceCache = elanInstanceCache;
-        southBoundUtils = new SouthboundUtils(mdsalUtils);
+        southBoundUtils = new SouthboundUtils(new MdsalUtils(dbx));
     }
 
     public boolean shouldCreateVtep(List<VpnInterfaces> vpnInterfaces) {
@@ -108,10 +117,11 @@ public class TransportZoneNotificationUtil {
                 continue;
             }
 
-            if (ElanUtils.isVxlan(elanInstanceCache.get(elanInt.getElanInstanceName()).orNull())) {
+            if (ElanUtils.isVxlanNetworkOrVxlanSegment(
+                    elanInstanceCache.get(elanInt.getElanInstanceName()).orNull())) {
                 return true;
             } else {
-                LOG.debug("Non-VXLAN elanInstance: " + elanInt.getElanInstanceName());
+                LOG.debug("Non-VXLAN elanInstance: {}", elanInt.getElanInstanceName());
             }
         }
 
@@ -121,51 +131,47 @@ public class TransportZoneNotificationUtil {
     private TransportZone createZone(String subnetIp, String zoneName) {
         List<Subnets> subnets = new ArrayList<>();
         subnets.add(buildSubnets(subnetIp));
-        TransportZoneBuilder tzb = new TransportZoneBuilder().setKey(new TransportZoneKey(zoneName))
+        TransportZoneBuilder tzb = new TransportZoneBuilder().withKey(new TransportZoneKey(zoneName))
                 .setTunnelType(TunnelTypeVxlan.class).setZoneName(zoneName).setSubnets(subnets);
         return tzb.build();
     }
 
-    private void updateTransportZone(TransportZone zone, BigInteger dpnId, WriteTransaction tx)
-            throws TransactionCommitFailedException {
+    private void updateTransportZone(TransportZone zone, BigInteger dpnId,
+            @Nonnull TypedWriteTransaction<Configuration> tx) {
         InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
                 .child(TransportZone.class, new TransportZoneKey(zone.getZoneName())).build();
 
-        if (tx == null) {
-            SingleTransactionDataBroker.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, path, zone);
-        } else {
-            tx.merge(LogicalDatastoreType.CONFIGURATION, path, zone);
-        }
+        tx.merge(path, zone);
         LOG.info("Transport zone {} updated due to dpn {} handling.", zone.getZoneName(), dpnId);
     }
 
     public void updateTransportZone(String zoneNamePrefix, BigInteger dpnId) {
-        Map<String, String> localIps = getDpnLocalIps(dpnId);
-        if (localIps != null && !localIps.isEmpty()) {
-            LOG.debug("Will use local_ips for transport zone update for dpn {} and zone name prefix {}", dpnId,
-                    zoneNamePrefix);
-            for (Entry<String, String> entry : localIps.entrySet()) {
-                String localIp = entry.getKey();
-                String underlayNetworkName = entry.getValue();
-                String zoneName = getTzNameForUnderlayNetwork(zoneNamePrefix, underlayNetworkName);
-                updateTransportZone(zoneName, dpnId, localIp);
+        ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
+            Map<String, String> localIps = getDpnLocalIps(dpnId);
+            if (!localIps.isEmpty()) {
+                LOG.debug("Will use local_ips for transport zone update for dpn {} and zone name prefix {}", dpnId,
+                        zoneNamePrefix);
+                for (Entry<String, String> entry : localIps.entrySet()) {
+                    String localIp = entry.getKey();
+                    String underlayNetworkName = entry.getValue();
+                    String zoneName = getTzNameForUnderlayNetwork(zoneNamePrefix, underlayNetworkName);
+                    updateTransportZone(zoneName, dpnId, localIp, tx);
+                }
+            } else {
+                updateTransportZone(zoneNamePrefix, dpnId, getDpnLocalIp(dpnId), tx);
             }
-        } else {
-            updateTransportZone(zoneNamePrefix, dpnId, getDpnLocalIp(dpnId));
-        }
-    }
-
-    private void updateTransportZone(String zoneName, BigInteger dpnId, String localIp) {
-        updateTransportZone(zoneName, dpnId, localIp, null);
+        }), LOG, "Error updating transport zone");
     }
 
     @SuppressWarnings("checkstyle:IllegalCatch")
-    private void updateTransportZone(String zoneName, BigInteger dpnId, String localIp, WriteTransaction tx) {
+    private void updateTransportZone(String zoneName, BigInteger dpnId, @Nullable String localIp,
+            @Nonnull TypedReadWriteTransaction<Configuration> tx)
+            throws ExecutionException, InterruptedException {
         InstanceIdentifier<TransportZone> inst = InstanceIdentifier.create(TransportZones.class)
                 .child(TransportZone.class, new TransportZoneKey(zoneName));
 
         // FIXME: Read this through a cache
-        TransportZone zone = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, inst);
+        TransportZone zone = tx.read(inst).get().orNull();
 
         if (zone == null) {
             zone = createZone(ALL_SUBNETS, zoneName);
@@ -180,46 +186,38 @@ public class TransportZoneNotificationUtil {
         }
     }
 
-    private void deleteTransportZone(TransportZone zone, BigInteger dpnId, WriteTransaction tx)
-            throws TransactionCommitFailedException {
+    private void deleteTransportZone(TransportZone zone, BigInteger dpnId,
+            @Nonnull TypedWriteTransaction<Configuration> tx) {
         InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
                 .child(TransportZone.class, new TransportZoneKey(zone.getZoneName())).build();
-
-        if (tx == null) {
-            SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
-        } else {
-            tx.delete(LogicalDatastoreType.CONFIGURATION, path);
-        }
+        tx.delete(path);
         LOG.info("Transport zone {} deleted due to dpn {} handling.", zone.getZoneName(), dpnId);
     }
 
     public void deleteTransportZone(String zoneNamePrefix, BigInteger dpnId) {
-        Map<String, String> localIps = getDpnLocalIps(dpnId);
-        if (localIps != null && !localIps.isEmpty()) {
-            LOG.debug("Will use local_ips for transport zone delete for dpn {} and zone name prefix {}", dpnId,
-                    zoneNamePrefix);
-            for (Entry<String, String> entry : localIps.entrySet()) {
-                String localIp = entry.getKey();
-                String underlayNetworkName = entry.getValue();
-                String zoneName = getTzNameForUnderlayNetwork(zoneNamePrefix, underlayNetworkName);
-                deleteTransportZone(zoneName, dpnId, localIp);
+        ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
+            Map<String, String> localIps = getDpnLocalIps(dpnId);
+            if (!localIps.isEmpty()) {
+                LOG.debug("Will use local_ips for transport zone delete for dpn {} and zone name prefix {}", dpnId,
+                        zoneNamePrefix);
+                for (String underlayNetworkName : localIps.values()) {
+                    String zoneName = getTzNameForUnderlayNetwork(zoneNamePrefix, underlayNetworkName);
+                    deleteTransportZone(zoneName, dpnId, tx);
+                }
+            } else {
+                deleteTransportZone(zoneNamePrefix, dpnId, tx);
             }
-        } else {
-            deleteTransportZone(zoneNamePrefix, dpnId, getDpnLocalIp(dpnId));
-        }
-    }
-
-    private void deleteTransportZone(String zoneName, BigInteger dpnId, String localIp) {
-        deleteTransportZone(zoneName, dpnId, localIp, null);
+        }), LOG, "Error deleting transport zone");
     }
 
     @SuppressWarnings("checkstyle:IllegalCatch")
-    private void deleteTransportZone(String zoneName, BigInteger dpnId, String localIp, WriteTransaction tx) {
+    private void deleteTransportZone(String zoneName, BigInteger dpnId,
+            @Nonnull TypedReadWriteTransaction<Configuration> tx) throws ExecutionException, InterruptedException {
         InstanceIdentifier<TransportZone> inst = InstanceIdentifier.create(TransportZones.class)
                 .child(TransportZone.class, new TransportZoneKey(zoneName));
 
         // FIXME: Read this through a cache
-        TransportZone zone = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, inst);
+        TransportZone zone = tx.read(inst).get().orNull();
         if (zone != null) {
             try {
                 deleteTransportZone(zone, dpnId, tx);
@@ -267,54 +265,61 @@ public class TransportZoneNotificationUtil {
             return;
         }
 
-        BigInteger dpId = dpIdOpt.get();
-        Optional<DPNTEPsInfo> dpnTepsInfoOpt = getDpnTepsInfo(dpId);
-        if (!dpnTepsInfoOpt.isPresent()) {
-            LOG.debug("No DPNTEPsInfo found for DPN id {}", dpId);
-            return;
-        }
+        ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
+            BigInteger dpId = dpIdOpt.get();
+            Optional<DPNTEPsInfo> dpnTepsInfoOpt = getDpnTepsInfo(dpId, tx);
+            if (!dpnTepsInfoOpt.isPresent()) {
+                LOG.debug("No DPNTEPsInfo found for DPN id {}", dpId);
+                return;
+            }
 
-        List<TunnelEndPoints> tunnelEndPoints = dpnTepsInfoOpt.get().getTunnelEndPoints();
-        if (tunnelEndPoints == null || tunnelEndPoints.isEmpty()) {
-            LOG.debug("No tunnel endpoints defined for DPN id {}", dpId);
-            return;
-        }
+            List<TunnelEndPoints> tunnelEndPoints = dpnTepsInfoOpt.get().getTunnelEndPoints();
+            if (tunnelEndPoints == null || tunnelEndPoints.isEmpty()) {
+                LOG.debug("No tunnel endpoints defined for DPN id {}", dpId);
+                return;
+            }
 
-        Set<String> zonePrefixes = new HashSet<>();
-        Map<String, List<String>> tepTzMap = tunnelEndPoints.stream().collect(Collectors
-                .toMap(tep -> String.valueOf(tep.getIpAddress().getValue()), this::getTepTransportZoneNames));
-        LOG.trace("Transport zone prefixes {}", tepTzMap);
+            Set<String> zonePrefixes = new HashSet<>();
+            Map<String, List<String>> tepTzMap = tunnelEndPoints.stream().collect(Collectors
+                    .toMap(tep -> tep.getIpAddress().stringValue(), this::getTepTransportZoneNames));
+            LOG.trace("Transport zone prefixes {}", tepTzMap);
 
-        WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
-        handleRemovedLocalIps(mapDiff.entriesOnlyOnLeft(), dpId, zonePrefixes, tepTzMap, tx);
-        handleChangedLocalIps(mapDiff.entriesDiffering(), dpId, zonePrefixes, tepTzMap, tx);
-        handleAddedLocalIps(mapDiff.entriesOnlyOnRight(), dpId, zonePrefixes, tx);
-        tx.submit();
+            handleRemovedLocalIps(mapDiff.entriesOnlyOnLeft(), dpId, zonePrefixes, tepTzMap, tx);
+            handleChangedLocalIps(mapDiff.entriesDiffering(), dpId, zonePrefixes, tepTzMap, tx);
+            handleAddedLocalIps(mapDiff.entriesOnlyOnRight(), dpId, zonePrefixes, tx);
+        }), LOG, "Error handling OVSDB node update");
     }
 
     private void handleAddedLocalIps(Map<String, String> addedEntries, BigInteger dpId, Set<String> zonePrefixes,
-            WriteTransaction tx) {
+            TypedReadWriteTransaction<Configuration> tx) throws ExecutionException, InterruptedException {
         if (addedEntries == null || addedEntries.isEmpty()) {
             LOG.trace("No added local_ips found for DPN {}", dpId);
             return;
         }
 
         LOG.debug("Added local_ips {} on DPN {}", addedEntries.keySet(), dpId);
-        addedEntries.forEach((ipAddress, underlayNetworkName) -> zonePrefixes.forEach(zonePrefix -> {
-            String zoneName = getTzNameForUnderlayNetwork(zonePrefix, underlayNetworkName);
-            updateTransportZone(zoneName, dpId, ipAddress, tx);
-        }));
+        for (Map.Entry<String, String> addedEntry : addedEntries.entrySet()) {
+            String ipAddress = addedEntry.getKey();
+            String underlayNetworkName = addedEntry.getValue();
+            for (String zonePrefix : zonePrefixes) {
+                String zoneName = getTzNameForUnderlayNetwork(zonePrefix, underlayNetworkName);
+                updateTransportZone(zoneName, dpId, ipAddress, tx);
+            }
+        }
     }
 
     private void handleChangedLocalIps(Map<String, ValueDifference<String>> changedEntries, BigInteger dpId,
-            Set<String> zonePrefixes, Map<String, List<String>> tepTzMap, WriteTransaction tx) {
+            Set<String> zonePrefixes, Map<String, List<String>> tepTzMap,
+            @Nonnull TypedReadWriteTransaction<Configuration> tx) throws ExecutionException, InterruptedException {
         if (changedEntries == null || changedEntries.isEmpty()) {
             LOG.trace("No changed local_ips found for DPN {}", dpId);
             return;
         }
 
         LOG.debug("Changing underlay network mapping for local_ips {} on DPN {}", changedEntries.keySet(), dpId);
-        changedEntries.forEach((ipAddress, underlayNetworkDiff) -> {
+        for (Map.Entry<String, ValueDifference<String>> changedEntry : changedEntries.entrySet()) {
+            String ipAddress = changedEntry.getKey();
+            ValueDifference<String> underlayNetworkDiff = changedEntry.getValue();
             List<String> zoneNames = tepTzMap.get(ipAddress);
             if (zoneNames != null) {
                 for (String zoneName : zoneNames) {
@@ -323,18 +328,18 @@ public class TransportZoneNotificationUtil {
                     Optional<String> zonePrefixOpt = getZonePrefixForUnderlayNetwork(zoneName, removedUnderlayNetwork);
                     if (zonePrefixOpt.isPresent()) {
                         String zonePrefix = zonePrefixOpt.get();
-                        removeVtep(zoneName, dpId, ipAddress, tx);
+                        removeVtep(zoneName, dpId, tx);
                         zonePrefixes.add(zonePrefix);
                         String newZoneName = getTzNameForUnderlayNetwork(zonePrefix, addedUnderlayNetwork);
                         updateTransportZone(newZoneName, dpId, ipAddress, tx);
                     }
                 }
             }
-        });
+        }
     }
 
     private void handleRemovedLocalIps(Map<String, String> removedEntries, BigInteger dpId, Set<String> zonePrefixes,
-            Map<String, List<String>> tepTzMap, WriteTransaction tx) {
+            Map<String, List<String>> tepTzMap, @Nonnull TypedWriteTransaction<Configuration> tx) {
         if (removedEntries == null || removedEntries.isEmpty()) {
             LOG.trace("No removed local_ips found on DPN {}", dpId);
             return;
@@ -347,7 +352,7 @@ public class TransportZoneNotificationUtil {
                 for (String zoneName : zoneNames) {
                     Optional<String> zonePrefix = getZonePrefixForUnderlayNetwork(zoneName, underlayNetworkName);
                     if (zonePrefix.isPresent()) {
-                        removeVtep(zoneName, dpId, ipAddress, tx);
+                        removeVtep(zoneName, dpId, tx);
                         zonePrefixes.add(zonePrefix.get());
                     }
                 }
@@ -358,7 +363,7 @@ public class TransportZoneNotificationUtil {
     private List<String> getTepTransportZoneNames(TunnelEndPoints tep) {
         List<TzMembership> tzMembershipList = tep.getTzMembership();
         if (tzMembershipList == null) {
-            LOG.debug("No TZ membership exist for TEP ip {}", tep.getIpAddress().getValue());
+            LOG.debug("No TZ membership exist for TEP ip {}", tep.getIpAddress().stringValue());
             return Collections.emptyList();
         }
 
@@ -366,13 +371,12 @@ public class TransportZoneNotificationUtil {
                 .collect(Collectors.toList());
     }
 
-    private Optional<DPNTEPsInfo> getDpnTepsInfo(BigInteger dpId) {
+    private Optional<DPNTEPsInfo> getDpnTepsInfo(BigInteger dpId, TypedReadTransaction<Configuration> tx) {
         InstanceIdentifier<DPNTEPsInfo> identifier = InstanceIdentifier.builder(DpnEndpoints.class)
                 .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpId)).build();
         try {
-            return SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
-                    identifier);
-        } catch (ReadFailedException e) {
+            return tx.read(identifier).get();
+        } catch (InterruptedException | ExecutionException e) {
             LOG.warn("Failed to read DPNTEPsInfo for DPN id {}", dpId);
             return Optional.absent();
         }
@@ -383,7 +387,7 @@ public class TransportZoneNotificationUtil {
      *
      * @return Whether a vtep was added or not.
      */
-    private boolean addVtep(TransportZone zone, String subnetIp, BigInteger dpnId, String localIp) {
+    private boolean addVtep(TransportZone zone, String subnetIp, BigInteger dpnId, @Nullable String localIp) {
         List<Subnets> zoneSubnets = zone.getSubnets();
         if (zoneSubnets == null) {
             return false;
@@ -397,7 +401,7 @@ public class TransportZoneNotificationUtil {
         }
 
         if (localIp != null) {
-            IpAddress nodeIp = new IpAddress(localIp.toCharArray());
+            IpAddress nodeIp = IpAddressBuilder.getDefaultInstance(localIp);
             VtepsBuilder vtepsBuilder = new VtepsBuilder().setDpnId(dpnId).setIpAddress(nodeIp)
                     .setPortname(TUNNEL_PORT).setOptionOfTunnel(elanConfig.isUseOfTunnels());
             subnets.getVteps().add(vtepsBuilder.build());
@@ -407,26 +411,18 @@ public class TransportZoneNotificationUtil {
         return false;
     }
 
-    private void removeVtep(String zoneName, BigInteger dpId, String localIp, WriteTransaction tx) {
+    private void removeVtep(String zoneName, BigInteger dpId, @Nonnull TypedWriteTransaction<Configuration> tx) {
         InstanceIdentifier<Vteps> path = InstanceIdentifier.builder(TransportZones.class)
                 .child(TransportZone.class, new TransportZoneKey(zoneName))
-                .child(Subnets.class, new SubnetsKey(new IpPrefix(ALL_SUBNETS.toCharArray())))
+                .child(Subnets.class, new SubnetsKey(IpPrefixBuilder.getDefaultInstance(ALL_SUBNETS)))
                 .child(Vteps.class, new VtepsKey(dpId, TUNNEL_PORT)).build();
-        if (tx == null) {
-            try {
-                SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
-            } catch (TransactionCommitFailedException e) {
-                LOG.error("Failed to remove VTEP {} from transport-zone {} for DPN {}", localIp, zoneName, dpId);
-            }
-        } else {
-            tx.delete(LogicalDatastoreType.CONFIGURATION, path);
-        }
+        tx.delete(path);
     }
 
     // search for relevant subnets for the given subnetIP, add one if it is
     // necessary
     private Subnets getOrAddSubnet(@Nonnull List<Subnets> subnets, @Nonnull String subnetIp) {
-        IpPrefix subnetPrefix = new IpPrefix(subnetIp.toCharArray());
+        IpPrefix subnetPrefix = IpPrefixBuilder.getDefaultInstance(subnetIp);
 
         for (Subnets subnet : subnets) {
             if (subnet.getPrefix().equals(subnetPrefix)) {
@@ -442,20 +438,20 @@ public class TransportZoneNotificationUtil {
 
     private Subnets buildSubnets(String subnetIp) {
         SubnetsBuilder subnetsBuilder = new SubnetsBuilder().setDeviceVteps(new ArrayList<>())
-                .setGatewayIp(new IpAddress(ALL_SUBNETS_GW.toCharArray()))
-                .setKey(new SubnetsKey(new IpPrefix(subnetIp.toCharArray()))).setVlanId(0)
-                .setVteps(new ArrayList<Vteps>());
+                .setGatewayIp(IpAddressBuilder.getDefaultInstance(ALL_SUBNETS_GW))
+                .withKey(new SubnetsKey(IpPrefixBuilder.getDefaultInstance(subnetIp))).setVlanId(0)
+                .setVteps(new ArrayList<>());
         return subnetsBuilder.build();
     }
 
-    private String getDpnLocalIp(BigInteger dpId) {
+    private String getDpnLocalIp(BigInteger dpId) throws ReadFailedException {
         Optional<Node> node = getPortsNode(dpId);
 
         if (node.isPresent()) {
             String localIp = southBoundUtils.getOpenvswitchOtherConfig(node.get(), LOCAL_IP);
             if (localIp == null) {
                 LOG.error("missing local_ip key in ovsdb:openvswitch-other-configs in operational"
-                        + " network-topology for node: " + node.get().getNodeId().getValue());
+                        + " network-topology for node: {}", node.get().getNodeId().getValue());
             } else {
                 return localIp;
             }
@@ -464,42 +460,36 @@ public class TransportZoneNotificationUtil {
         return null;
     }
 
-    private Map<String, String> getDpnLocalIps(BigInteger dpId) {
+    @Nonnull
+    private Map<String, String> getDpnLocalIps(BigInteger dpId) throws ReadFailedException {
         // Example of local IPs from other_config:
         // local_ips="10.0.43.159:MPLS,11.11.11.11:DSL,ip:underlay-network"
-        Optional<Node> node;
-        node = getPortsNode(dpId);
-        if (node.isPresent()) {
-            return elanBridgeManager.getOpenvswitchOtherConfigMap(node.get(), LOCAL_IPS);
-        }
-
-        return null;
+        return getPortsNode(dpId).toJavaUtil().map(
+            node -> elanBridgeManager.getOpenvswitchOtherConfigMap(node, LOCAL_IPS)).orElse(Collections.emptyMap());
     }
 
     @SuppressWarnings("unchecked")
-    private Optional<Node> getPortsNode(BigInteger dpnId) {
+    private Optional<Node> getPortsNode(BigInteger dpnId) throws ReadFailedException {
         InstanceIdentifier<BridgeRefEntry> bridgeRefInfoPath = InstanceIdentifier.create(BridgeRefInfo.class)
                 .child(BridgeRefEntry.class, new BridgeRefEntryKey(dpnId));
 
         // FIXME: Read this through a cache
-        BridgeRefEntry bridgeRefEntry = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, bridgeRefInfoPath);
-        if (bridgeRefEntry == null) {
-            LOG.error("no bridge ref entry found for dpnId: " + dpnId);
+        Optional<BridgeRefEntry> optionalBridgeRefEntry =
+            singleTxBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL, bridgeRefInfoPath);
+        if (!optionalBridgeRefEntry.isPresent()) {
+            LOG.error("no bridge ref entry found for dpnId {}", dpnId);
             return Optional.absent();
         }
 
-        InstanceIdentifier<Node> nodeId = ((InstanceIdentifier<OvsdbBridgeAugmentation>) bridgeRefEntry
-                .getBridgeReference().getValue()).firstIdentifierOf(Node.class);
+        InstanceIdentifier<Node> nodeId =
+                optionalBridgeRefEntry.get().getBridgeReference().getValue().firstIdentifierOf(Node.class);
 
         // FIXME: Read this through a cache
-        Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodeId);
-
-        if (node == null) {
-            LOG.error("missing node for dpnId: " + dpnId);
-            return Optional.absent();
+        Optional<Node> optionalNode = singleTxBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL, nodeId);
+        if (!optionalNode.isPresent()) {
+            LOG.error("missing node for dpnId {}", dpnId);
         }
-
-        return Optional.of(node);
+        return optionalNode;
     }
 
     private String getTzNameForUnderlayNetwork(String zoneNamePrefix, String underlayNetworkName) {