Datastore-constrained txes: elanmanager 26/74026/8
authorStephen Kitt <skitt@redhat.com>
Fri, 13 Jul 2018 15:57:42 +0000 (17:57 +0200)
committerSam Hague <shague@redhat.com>
Thu, 23 Aug 2018 13:57:54 +0000 (13:57 +0000)
Change-Id: I92faf670c930604761fbe3506f20c1e5af7a9e21
JIRA: NETVIRT-1339
Signed-off-by: Stephen Kitt <skitt@redhat.com>
35 files changed:
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/internal/ElanDpnInterfaceClusteredListener.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/internal/ElanInstanceManager.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/internal/ElanInterfaceConfigListener.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/internal/ElanInterfaceManager.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/internal/ElanLearntVpnVipToPortListener.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/internal/ElanPacketInHandler.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/ha/HwvtepHAUtil.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/ha/handlers/ConfigNodeUpdatedHandler.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/ha/handlers/HAEventHandler.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/ha/handlers/IHAEventHandler.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/ha/handlers/INodeCopier.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/ha/handlers/NodeConnectedHandler.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/ha/handlers/NodeCopier.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/ha/handlers/OpNodeUpdatedHandler.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/ha/listeners/HAConfigNodeListener.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/ha/listeners/HAListeners.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/ha/listeners/HAOpClusteredListener.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/ha/listeners/HAOpNodeListener.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/ha/listeners/HwvtepNodeBaseListener.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/ha/listeners/HwvtepNodeDataListener.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/ha/merge/MergeCommandsAggregator.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/jobs/HwvtepDeviceMcastMacUpdateJob.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/jobs/LogicalSwitchAddedJob.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/listeners/LocalUcastMacListener.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/utils/ElanL2GatewayMulticastUtils.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/utils/ElanL2GatewayUtils.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/utils/StaleVlanBindingsCleaner.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/utils/ElanForwardingEntriesHandler.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/utils/ElanUtils.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/utils/TransportZoneNotificationUtil.java
elanmanager/impl/src/test/java/org/opendaylight/netvirt/elan/l2gw/nodehandlertest/NodeConnectedHandlerTest.java
elanmanager/impl/src/test/java/org/opendaylight/netvirt/elan/l2gw/nodehandlertest/NodeConnectedHandlerUtils.java
elanmanager/impl/src/test/java/org/opendaylight/netvirt/elan/l2gw/nodehandlertest/PhysicalSwitchHelper.java
elanmanager/impl/src/test/java/org/opendaylight/netvirt/elan/l2gw/nodehandlertest/TestUtil.java
elanmanager/impl/src/test/java/org/opendaylight/netvirt/elanmanager/tests/ElanServiceTestBase.java

index bfa976170743556bb8c496c7f1c0ef6d5a66bb2a..8e843eac716090bdbb27a72ca8bb6d28d5d0ed98 100644 (file)
@@ -82,8 +82,10 @@ public class ElanDpnInterfaceClusteredListener
             return;
         }
         elanClusterUtils.runOnlyInOwnerNode(elanName, "updating mcast mac upon tunnel event",
-            () -> Collections.singletonList(
-                elanL2GatewayMulticastUtils.updateRemoteMcastMacOnElanL2GwDevices(elanName)));
+            () -> {
+                elanL2GatewayMulticastUtils.updateRemoteMcastMacOnElanL2GwDevices(elanName);
+                return Collections.emptyList();
+            });
     }
 
     @Override
index ea952257943165d8498430a1bdc426b9e8a41c83..b6fd5a96d256a963b61c82f765902b1e242435d1 100644 (file)
@@ -8,6 +8,9 @@
 
 package org.opendaylight.netvirt.elan.internal;
 
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
+
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.ListenableFuture;
 import java.util.ArrayList;
@@ -116,10 +119,9 @@ public class ElanInstanceManager extends AsyncDataTreeChangeListenerBase<ElanIns
         }
         elanInterfaceCache.getInterfaceNames(elanName).forEach(
             elanInterfaceName -> jobCoordinator.enqueueJob(ElanUtils.getElanInterfaceJobKey(elanInterfaceName),
-                () -> Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
+                () -> Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
                     LOG.info("Deleting the elanInterface present under ConfigDS:{}", elanInterfaceName);
-                    ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
-                            ElanUtils.getElanInterfaceConfigurationDataPathId(elanInterfaceName));
+                    tx.delete(ElanUtils.getElanInterfaceConfigurationDataPathId(elanInterfaceName));
                     elanInterfaceManager.unbindService(elanInterfaceName, tx);
                     LOG.info("unbind the Interface:{} service bounded to Elan:{}", elanInterfaceName, elanName);
                 })), ElanConstants.JOB_MAX_RETRIES));
@@ -147,9 +149,12 @@ public class ElanInstanceManager extends AsyncDataTreeChangeListenerBase<ElanIns
         if (existingElanTag == null || !existingElanTag.equals(update.getElanTag())) {
             if (update.getElanTag() == null  || update.getElanTag() == 0L) {
                 // update the elan-Instance with new properties
-                ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
-                    tx -> ElanUtils.updateOperationalDataStore(idManager, update, new ArrayList<>(), tx)),
-                    LOG, "Error updating ELAN tag in ELAN instance");
+                ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
+                    operTx -> ListenableFutures.addErrorLogging(
+                        txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+                            confTx -> ElanUtils.updateOperationalDataStore(idManager, update, new ArrayList<>(), confTx,
+                                operTx)), LOG, "Error updating ELAN tag in ELAN instance")), LOG,
+                    "Error updating ELAN tag in ELAN instance");
             } else {
                 jobCoordinator.enqueueJob(elanName, () -> elanInterfaceManager.handleunprocessedElanInterfaces(update),
                     ElanConstants.JOB_MAX_RETRIES);
@@ -159,11 +164,13 @@ public class ElanInstanceManager extends AsyncDataTreeChangeListenerBase<ElanIns
 
     @Override
     protected void add(InstanceIdentifier<ElanInstance> identifier, ElanInstance elanInstanceAdded) {
-        ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
+        ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operTx -> {
             String elanInstanceName  = elanInstanceAdded.getElanInstanceName();
-            Elan elanInfo = ElanUtils.getElanByName(tx, elanInstanceName);
+            Elan elanInfo = ElanUtils.getElanByName(operTx, elanInstanceName);
             if (elanInfo == null) {
-                ElanUtils.updateOperationalDataStore(idManager, elanInstanceAdded, new ArrayList<>(), tx);
+                ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+                    confTx -> ElanUtils.updateOperationalDataStore(idManager, elanInstanceAdded, new ArrayList<>(),
+                        confTx, operTx)), LOG, "Error adding an ELAN instance");
             }
         }), LOG, "Error adding an ELAN instance");
     }
index 3e9b2b440ea35621836501d67d733639466381da..25a6db5d9e787b677426ad101940971f0aacf859 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.netvirt.elan.internal;
 
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+
 import com.google.common.base.Optional;
 import java.util.Collections;
 import javax.annotation.PostConstruct;
@@ -81,7 +83,7 @@ public class ElanInterfaceConfigListener
             return;
         }
         jobCoordinator.enqueueJob(ElanUtils.getElanInterfaceJobKey(interfaceName),
-            () -> Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
+            () -> Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
                 LOG.debug("unbinding elan service on interface {} for its config removal", interfaceName);
                 elanInterfaceManager.unbindService(interfaceName, tx);
             })), ElanConstants.JOB_MAX_RETRIES);
index 114566c3580a588982186b37aa4d516dabd8b165..8b6ab601d89c8a1e665e8d155a11b50994e1d0e0 100644 (file)
@@ -7,7 +7,9 @@
  */
 package org.opendaylight.netvirt.elan.internal;
 
+import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
 import static org.opendaylight.netvirt.elan.utils.ElanUtils.isVxlanNetworkOrVxlanSegment;
 
 import com.google.common.base.Optional;
@@ -31,15 +33,16 @@ import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.apache.commons.lang3.StringUtils;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-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.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
 import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.Datastore.Operational;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TransactionAdapter;
 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.itm.globals.ITMConstants;
@@ -241,68 +244,72 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
         jobCoordinator.enqueueJob(elanInstanceName, configWorker, ElanConstants.JOB_MAX_RETRIES);
     }
 
+    private static class RemoveElanInterfaceHolder {
+        boolean isLastElanInterface = false;
+        boolean isLastInterfaceOnDpn = false;
+        BigInteger dpId = null;
+    }
+
     @SuppressWarnings("checkstyle:ForbidCertainMethod")
     public List<ListenableFuture<Void>> removeElanInterface(ElanInstance elanInfo, String interfaceName,
             InterfaceInfo interfaceInfo) {
         String elanName = elanInfo.getElanInstanceName();
-        boolean isLastElanInterface = false;
-        boolean isLastInterfaceOnDpn = false;
-        BigInteger dpId = null;
         long elanTag = elanInfo.getElanTag();
         // We use two transaction so we don't suffer on multiple shards (interfaces and flows)
-        WriteTransaction interfaceTx = broker.newWriteOnlyTransaction();
-        Elan elanState = removeElanStateForInterface(elanInfo, interfaceName, interfaceTx);
-        if (elanState == null) {
-            interfaceTx.cancel();
-            return Collections.emptyList();
-        }
-        WriteTransaction flowTx = broker.newWriteOnlyTransaction();
-        List<String> elanInterfaces = elanState.getElanInterfaces();
-        if (elanInterfaces.isEmpty()) {
-            isLastElanInterface = true;
-        }
-        if (interfaceInfo != null) {
-            dpId = interfaceInfo.getDpId();
-            DpnInterfaces dpnInterfaces = removeElanDpnInterfaceFromOperationalDataStore(elanName, dpId,
-                    interfaceName, elanTag, interfaceTx);
-            /*
-             * If there are not elan ports, remove the unknown dmac, terminating
-             * service table flows, remote/local bc group
-             */
-            if (dpnInterfaces == null || dpnInterfaces.getInterfaces() == null
-                    || dpnInterfaces.getInterfaces().isEmpty()) {
-                // No more Elan Interfaces in this DPN
-                LOG.debug("deleting the elan: {} present on dpId: {}", elanInfo.getElanInstanceName(), dpId);
-                if (!elanUtils.isOpenstackVniSemanticsEnforced()) {
-                    removeDefaultTermFlow(dpId, elanInfo.getElanTag());
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+        RemoveElanInterfaceHolder holder = new RemoveElanInterfaceHolder();
+        futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, interfaceTx -> {
+            Elan elanState = removeElanStateForInterface(elanInfo, interfaceName, interfaceTx);
+            if (elanState == null) {
+                return;
+            }
+            futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, flowTx -> {
+                List<String> elanInterfaces = elanState.getElanInterfaces();
+                if (elanInterfaces.isEmpty()) {
+                    holder.isLastElanInterface = true;
                 }
-                removeUnknownDmacFlow(dpId, elanInfo, flowTx, elanInfo.getElanTag());
-                removeEtreeUnknownDmacFlow(dpId, elanInfo, flowTx);
-                removeElanBroadcastGroup(elanInfo, interfaceInfo, flowTx);
-                removeLocalBroadcastGroup(elanInfo, interfaceInfo, flowTx);
-                removeEtreeBroadcastGrups(elanInfo, interfaceInfo, flowTx);
-                if (isVxlanNetworkOrVxlanSegment(elanInfo)) {
-                    if (elanUtils.isOpenstackVniSemanticsEnforced()) {
-                        elanUtils.removeTerminatingServiceAction(dpId,
-                                ElanUtils.getVxlanSegmentationId(elanInfo).intValue());
+                if (interfaceInfo != null) {
+                    holder.dpId = interfaceInfo.getDpId();
+                    DpnInterfaces dpnInterfaces = removeElanDpnInterfaceFromOperationalDataStore(elanName, holder.dpId,
+                        interfaceName, elanTag, interfaceTx);
+                    /*
+                     * If there are not elan ports, remove the unknown dmac, terminating
+                     * service table flows, remote/local bc group
+                     */
+                    if (dpnInterfaces == null || dpnInterfaces.getInterfaces() == null
+                        || dpnInterfaces.getInterfaces().isEmpty()) {
+                        // No more Elan Interfaces in this DPN
+                        LOG.debug("deleting the elan: {} present on dpId: {}", elanInfo.getElanInstanceName(),
+                            holder.dpId);
+                        if (!elanUtils.isOpenstackVniSemanticsEnforced()) {
+                            removeDefaultTermFlow(holder.dpId, elanInfo.getElanTag());
+                        }
+                        removeUnknownDmacFlow(holder.dpId, elanInfo, flowTx, elanInfo.getElanTag());
+                        removeEtreeUnknownDmacFlow(holder.dpId, elanInfo, flowTx);
+                        removeElanBroadcastGroup(elanInfo, interfaceInfo, flowTx);
+                        removeLocalBroadcastGroup(elanInfo, interfaceInfo, flowTx);
+                        removeEtreeBroadcastGrups(elanInfo, interfaceInfo, flowTx);
+                        if (isVxlanNetworkOrVxlanSegment(elanInfo)) {
+                            if (elanUtils.isOpenstackVniSemanticsEnforced()) {
+                                elanUtils.removeTerminatingServiceAction(holder.dpId,
+                                    ElanUtils.getVxlanSegmentationId(elanInfo).intValue());
+                            }
+                            unsetExternalTunnelTable(holder.dpId, elanInfo);
+                        }
+                        holder.isLastInterfaceOnDpn = true;
+                    } else {
+                        setupLocalBroadcastGroups(elanInfo, dpnInterfaces, interfaceInfo);
                     }
-                    unsetExternalTunnelTable(dpId, elanInfo);
                 }
-                isLastInterfaceOnDpn = true;
-            } else {
-                setupLocalBroadcastGroups(elanInfo, dpnInterfaces, interfaceInfo);
-            }
-        }
-
-        List<ListenableFuture<Void>> futures = new ArrayList<>();
-        futures.add(ElanUtils.waitForTransactionToComplete(interfaceTx));
-        futures.add(ElanUtils.waitForTransactionToComplete(flowTx));
+            }));
+        }));
+        futures.forEach(ElanUtils::waitForTransactionToComplete);
 
-        if (isLastInterfaceOnDpn && dpId != null && isVxlanNetworkOrVxlanSegment(elanInfo)) {
-            setElanAndEtreeBCGrouponOtherDpns(elanInfo, dpId);
+        if (holder.isLastInterfaceOnDpn && holder.dpId != null && isVxlanNetworkOrVxlanSegment(elanInfo)) {
+            setElanAndEtreeBCGrouponOtherDpns(elanInfo, holder.dpId);
         }
         InterfaceRemoveWorkerOnElanInterface removeInterfaceWorker = new InterfaceRemoveWorkerOnElanInterface(
-                interfaceName, elanInfo, interfaceInfo, this, isLastElanInterface);
+                interfaceName, elanInfo, interfaceInfo, this, holder.isLastElanInterface);
         jobCoordinator.enqueueJob(ElanUtils.getElanInterfaceJobKey(interfaceName), removeInterfaceWorker,
                 ElanConstants.JOB_MAX_RETRIES);
 
@@ -310,7 +317,8 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
     }
 
     private void removeEtreeUnknownDmacFlow(BigInteger dpId, ElanInstance elanInfo,
-            WriteTransaction deleteFlowGroupTx) {
+            TypedReadWriteTransaction<Configuration> deleteFlowGroupTx)
+            throws ExecutionException, InterruptedException {
         EtreeLeafTagName etreeLeafTag = elanEtreeUtils.getEtreeLeafTagByElanTag(elanInfo.getElanTag());
         if (etreeLeafTag != null) {
             long leafTag = etreeLeafTag.getEtreeLeafTag().getValue();
@@ -319,53 +327,41 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
     }
 
     private void removeEtreeBroadcastGrups(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
-            WriteTransaction deleteFlowGroupTx) {
+            TypedReadWriteTransaction<Configuration> deleteFlowGroupTx)
+            throws ExecutionException, InterruptedException {
         removeLeavesEtreeBroadcastGroup(elanInfo, interfaceInfo, deleteFlowGroupTx);
         removeLeavesLocalBroadcastGroup(elanInfo, interfaceInfo, deleteFlowGroupTx);
     }
 
     private void removeLeavesLocalBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
-            WriteTransaction deleteFlowGroupTx) {
+            TypedReadWriteTransaction<Configuration> deleteFlowGroupTx)
+            throws ExecutionException, InterruptedException {
         EtreeInstance etreeInstance = elanInfo.augmentation(EtreeInstance.class);
         if (etreeInstance != null) {
             BigInteger dpnId = interfaceInfo.getDpId();
             long groupId = ElanUtils.getEtreeLeafLocalBCGId(etreeInstance.getEtreeLeafTagVal().getValue());
-            List<Bucket> listBuckets = new ArrayList<>();
-            int bucketId = 0;
-            listBuckets.add(getLocalBCGroupBucketInfo(interfaceInfo, bucketId));
-            Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll,
-                    MDSALUtil.buildBucketLists(listBuckets));
-            LOG.trace("deleted the localBroadCast Group:{}", group);
-            mdsalManager.removeGroupToTx(dpnId, group, deleteFlowGroupTx);
+            LOG.trace("deleted the localBroadCast Group:{}", groupId);
+            mdsalManager.removeGroup(deleteFlowGroupTx, dpnId, groupId);
         }
     }
 
     private void removeLeavesEtreeBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
-            WriteTransaction deleteFlowGroupTx) {
+            TypedReadWriteTransaction<Configuration> deleteFlowGroupTx)
+            throws ExecutionException, InterruptedException {
         EtreeInstance etreeInstance = elanInfo.augmentation(EtreeInstance.class);
         if (etreeInstance != null) {
             long etreeTag = etreeInstance.getEtreeLeafTagVal().getValue();
-            int bucketId = 0;
-            int actionKey = 0;
-            List<Bucket> listBuckets = new ArrayList<>();
-            List<Action> listAction = new ArrayList<>();
-            listAction.add(new ActionGroup(ElanUtils.getEtreeLeafLocalBCGId(etreeTag)).buildAction(++actionKey));
-            listBuckets.add(MDSALUtil.buildBucket(listAction, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT,
-                    MDSALUtil.WATCH_GROUP));
-            bucketId++;
-            listBuckets.addAll(getRemoteBCGroupBucketInfos(elanInfo, bucketId, interfaceInfo, etreeTag));
             BigInteger dpnId = interfaceInfo.getDpId();
             long groupId = ElanUtils.getEtreeLeafRemoteBCGId(etreeTag);
-            Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll,
-                    MDSALUtil.buildBucketLists(listBuckets));
-            LOG.trace("deleting the remoteBroadCast group:{}", group);
-            mdsalManager.removeGroupToTx(dpnId, group, deleteFlowGroupTx);
+            LOG.trace("deleting the remoteBroadCast group:{}", groupId);
+            mdsalManager.removeGroup(deleteFlowGroupTx, dpnId, groupId);
         }
     }
 
-    private Elan removeElanStateForInterface(ElanInstance elanInfo, String interfaceName, WriteTransaction tx) {
+    private Elan removeElanStateForInterface(ElanInstance elanInfo, String interfaceName,
+            TypedReadWriteTransaction<Operational> tx) throws ExecutionException, InterruptedException {
         String elanName = elanInfo.getElanInstanceName();
-        Elan elanState = ElanUtils.getElanByName(broker, elanName);
+        Elan elanState = ElanUtils.getElanByName(tx, elanName);
         if (elanState == null) {
             return elanState;
         }
@@ -376,26 +372,25 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
         }
 
         if (elanInterfaces.isEmpty()) {
-            tx.delete(LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName));
-            tx.delete(LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanMacTableOperationalDataPath(elanName));
-            tx.delete(LogicalDatastoreType.OPERATIONAL,
-                    ElanUtils.getElanInfoEntriesOperationalDataPath(elanInfo.getElanTag()));
+            tx.delete(ElanUtils.getElanInstanceOperationalDataPath(elanName));
+            tx.delete(ElanUtils.getElanMacTableOperationalDataPath(elanName));
+            tx.delete(ElanUtils.getElanInfoEntriesOperationalDataPath(elanInfo.getElanTag()));
         } else {
             Elan updateElanState = new ElanBuilder().setElanInterfaces(elanInterfaces).setName(elanName)
                     .withKey(new ElanKey(elanName)).build();
-            tx.put(LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName),
-                    updateElanState);
+            tx.put(ElanUtils.getElanInstanceOperationalDataPath(elanName), updateElanState);
         }
         return elanState;
     }
 
-    private void deleteElanInterfaceFromConfigDS(String interfaceName, WriteTransaction tx) {
+    private void deleteElanInterfaceFromConfigDS(String interfaceName, TypedReadWriteTransaction<Configuration> tx)
+            throws ReadFailedException {
         // removing the ElanInterface from the config data_store if interface is
         // not present in Interface config DS
-        if (interfaceManager.getInterfaceInfoFromConfigDataStore(interfaceName) == null
+        if (interfaceManager.getInterfaceInfoFromConfigDataStore(TransactionAdapter.toReadWriteTransaction(tx),
+            interfaceName) == null
                 && elanInterfaceCache.get(interfaceName).isPresent()) {
-            tx.delete(LogicalDatastoreType.CONFIGURATION,
-                    ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName));
+            tx.delete(ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName));
         }
     }
 
@@ -404,11 +399,10 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
         String elanName = elanInfo.getElanInstanceName();
         List<ListenableFuture<Void>> futures = new ArrayList<>();
         futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, flowTx -> {
-            futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(interfaceTx -> {
+            futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, interfaceTx -> {
                 InstanceIdentifier<ElanInterfaceMac> elanInterfaceId = ElanUtils
                         .getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
-                Optional<ElanInterfaceMac> existingElanInterfaceMac =
-                        interfaceTx.read(LogicalDatastoreType.OPERATIONAL, elanInterfaceId).checkedGet();
+                Optional<ElanInterfaceMac> existingElanInterfaceMac = interfaceTx.read(elanInterfaceId).get();
                 LOG.debug("Removing the Interface:{} from elan:{}", interfaceName, elanName);
                 if (interfaceInfo != null) {
                     if (existingElanInterfaceMac.isPresent()) {
@@ -422,8 +416,7 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
                                 Optional<MacEntry> macEntryOptional =
                                         elanUtils.getMacEntryForElanInstance(interfaceTx, elanName, macAddress);
                                 if (!isLastElanInterface && macEntryOptional.isPresent()) {
-                                    interfaceTx.delete(LogicalDatastoreType.OPERATIONAL,
-                                            ElanUtils.getMacEntryOperationalDataPath(elanName, macAddress));
+                                    interfaceTx.delete(ElanUtils.getMacEntryOperationalDataPath(elanName, macAddress));
                                 }
                                 elanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry, flowTx);
                                 macAddresses.add(macAddress);
@@ -446,17 +439,16 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
                         for (MacEntry macEntry : macEntries) {
                             PhysAddress macAddress = macEntry.getMacAddress();
                             if (elanUtils.getMacEntryForElanInstance(elanName, macAddress).isPresent()) {
-                                interfaceTx.delete(LogicalDatastoreType.OPERATIONAL,
-                                        ElanUtils.getMacEntryOperationalDataPath(elanName, macAddress));
+                                interfaceTx.delete(ElanUtils.getMacEntryOperationalDataPath(elanName, macAddress));
                             }
                         }
                     }
                 }
                 if (existingElanInterfaceMac.isPresent()) {
-                    interfaceTx.delete(LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
+                    interfaceTx.delete(elanInterfaceId);
                 }
-                unbindService(interfaceName, interfaceTx);
-                deleteElanInterfaceFromConfigDS(interfaceName, interfaceTx);
+                unbindService(interfaceName, flowTx);
+                deleteElanInterfaceFromConfigDS(interfaceName, flowTx);
             }));
         }));
         return futures;
@@ -464,7 +456,8 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
 
     private DpnInterfaces removeElanDpnInterfaceFromOperationalDataStore(String elanName, BigInteger dpId,
                                                                          String interfaceName, long elanTag,
-                                                                         WriteTransaction tx) {
+                                                                         TypedReadWriteTransaction<Operational> tx)
+            throws ExecutionException, InterruptedException {
         synchronized (elanName.intern()) {
 
             DpnInterfaces dpnInterfaces = elanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
@@ -556,25 +549,24 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
         for (StaticMacEntries staticMacEntry : updatedEntries) {
             InstanceIdentifier<MacEntry> macEntryIdentifier = getMacEntryOperationalDataPath(elanName,
                     staticMacEntry.getMacAddress());
-            Optional<MacEntry> existingMacEntry = ElanUtils.read(broker,
-                    LogicalDatastoreType.OPERATIONAL, macEntryIdentifier);
-            WriteTransaction tx = broker.newWriteOnlyTransaction();
-            if (existingMacEntry.isPresent()) {
-                elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(
-                        elanName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get(),
-                        tx);
-            } else {
-                elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(
-                        elanName, interfaceName, staticMacEntry, tx);
-            }
-            ListenableFutures.addErrorLogging(ElanUtils.waitForTransactionToComplete(tx), LOG,
-                    "Error in update: identifier={}, original={}, update={}", identifier, original, update);
+            ListenableFutures.addErrorLogging(ElanUtils.waitForTransactionToComplete(
+                txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx -> {
+                    Optional<MacEntry> existingMacEntry = tx.read(macEntryIdentifier).get();
+                    if (existingMacEntry.isPresent()) {
+                        elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(
+                            elanName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get(),
+                            tx);
+                    } else {
+                        elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(
+                            elanName, interfaceName, staticMacEntry, tx);
+                    }
+                })), LOG, "Error in update: identifier={}, original={}, update={}", identifier, original, update);
         }
     }
 
     @Override
     protected void add(InstanceIdentifier<ElanInterface> identifier, ElanInterface elanInterfaceAdded) {
-        ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+        ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, operTx -> {
             String elanInstanceName = elanInterfaceAdded.getElanInstanceName();
             String interfaceName = elanInterfaceAdded.getName();
             InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
@@ -585,12 +577,13 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
             ElanInstance elanInstance = elanInstanceCache.get(elanInstanceName).orNull();
 
             if (elanInstance == null) {
-                elanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName)
-                        .setDescription(elanInterfaceAdded.getDescription()).build();
                 // Add the ElanInstance in the Configuration data-store
                 List<String> elanInterfaces = new ArrayList<>();
                 elanInterfaces.add(interfaceName);
-                elanInstance = ElanUtils.updateOperationalDataStore(idManager, elanInstance, elanInterfaces, tx);
+                elanInstance = txRunner.applyWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+                    confTx -> ElanUtils.updateOperationalDataStore(idManager,
+                        new ElanInstanceBuilder().setElanInstanceName(elanInstanceName).setDescription(
+                            elanInterfaceAdded.getDescription()).build(), elanInterfaces, confTx, operTx)).get();
             }
 
             Long elanTag = elanInstance.getElanTag();
@@ -611,7 +604,7 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
             InterfaceAddWorkerOnElan addWorker = new InterfaceAddWorkerOnElan(elanInstanceName, elanInterfaceAdded,
                     interfaceInfo, elanInstance, this);
             jobCoordinator.enqueueJob(elanInstanceName, addWorker, ElanConstants.JOB_MAX_RETRIES);
-        }), LOG, "Error procedding added ELAN interface");
+        }), LOG, "Error processing added ELAN interface");
     }
 
     List<ListenableFuture<Void>> handleunprocessedElanInterfaces(ElanInstance elanInstance) {
@@ -630,7 +623,7 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
     }
 
     void programRemoteDmacFlow(ElanInstance elanInstance, InterfaceInfo interfaceInfo,
-            WriteTransaction writeFlowGroupTx) {
+            TypedWriteTransaction<Configuration> writeFlowGroupTx) {
         ElanDpnInterfacesList elanDpnInterfacesList = elanUtils
                 .getElanDpnInterfacesList(elanInstance.getElanInstanceName());
         List<DpnInterfaces> dpnInterfaceLists = null;
@@ -667,6 +660,12 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
         }
     }
 
+    private static class AddElanInterfaceHolder {
+        private DpnInterfaces dpnInterfaces = null;
+        private boolean isFirstInterfaceInDpn = false;
+        private BigInteger dpId;
+    }
+
     @SuppressWarnings("checkstyle:ForbidCertainMethod")
     List<ListenableFuture<Void>> addElanInterface(ElanInterface elanInterface,
             InterfaceInfo interfaceInfo, ElanInstance elanInstance) {
@@ -677,89 +676,96 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
         String interfaceName = elanInterface.getName();
         String elanInstanceName = elanInterface.getElanInstanceName();
 
-        Elan elanInfo = ElanUtils.getElanByName(broker, elanInstanceName);
-        WriteTransaction tx = broker.newWriteOnlyTransaction();
-        if (elanInfo == null) {
-            List<String> elanInterfaces = new ArrayList<>();
-            elanInterfaces.add(interfaceName);
-            ElanUtils.updateOperationalDataStore(idManager, elanInstance, elanInterfaces, tx);
-        } else {
-            createElanStateList(elanInstanceName, interfaceName, tx);
-        }
-        boolean isFirstInterfaceInDpn = false;
-        // Specific actions to the DPN where the ElanInterface has been added,
-        // for example, programming the
-        // External tunnel table if needed or adding the ElanInterface to the
-        // DpnInterfaces in the operational DS.
-        BigInteger dpId = interfaceInfo.getDpId();
-        DpnInterfaces dpnInterfaces = null;
-        if (dpId != null && !dpId.equals(ElanConstants.INVALID_DPN)) {
-            synchronized (elanInstanceName.intern()) {
-                InstanceIdentifier<DpnInterfaces> elanDpnInterfaces = ElanUtils
-                        .getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId);
-                Optional<DpnInterfaces> existingElanDpnInterfaces = ElanUtils.read(broker,
-                        LogicalDatastoreType.OPERATIONAL, elanDpnInterfaces);
-                if (ElanUtils.isVlan(elanInstance)) {
-                    isFirstInterfaceInDpn =  checkIfFirstInterface(interfaceName,
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+        AddElanInterfaceHolder holder = new AddElanInterfaceHolder();
+        futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operTx -> {
+            Elan elanInfo = ElanUtils.getElanByName(broker, elanInstanceName);
+            if (elanInfo == null) {
+                List<String> elanInterfaces = new ArrayList<>();
+                elanInterfaces.add(interfaceName);
+                futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+                    confTx -> ElanUtils.updateOperationalDataStore(idManager, elanInstance, elanInterfaces, confTx,
+                        operTx)));
+            } else {
+                createElanStateList(elanInstanceName, interfaceName, operTx);
+            }
+            // Specific actions to the DPN where the ElanInterface has been added,
+            // for example, programming the
+            // External tunnel table if needed or adding the ElanInterface to the
+            // DpnInterfaces in the operational DS.
+            holder.dpId = interfaceInfo.getDpId();
+            if (holder.dpId != null && !holder.dpId.equals(ElanConstants.INVALID_DPN)) {
+                synchronized (elanInstanceName.intern()) {
+                    InstanceIdentifier<DpnInterfaces> elanDpnInterfaces = ElanUtils
+                        .getElanDpnInterfaceOperationalDataPath(elanInstanceName, holder.dpId);
+                    Optional<DpnInterfaces> existingElanDpnInterfaces = operTx.read(elanDpnInterfaces).get();
+                    if (ElanUtils.isVlan(elanInstance)) {
+                        holder.isFirstInterfaceInDpn =  checkIfFirstInterface(interfaceName,
                             elanInstanceName, existingElanDpnInterfaces);
-                } else {
-                    isFirstInterfaceInDpn = !existingElanDpnInterfaces.isPresent();
-                }
-                if (isFirstInterfaceInDpn) {
-                    // ELAN's 1st ElanInterface added to this DPN
-                    if (!existingElanDpnInterfaces.isPresent()) {
-                        dpnInterfaces = createElanInterfacesList(elanInstanceName, interfaceName, dpId, tx);
+                    } else {
+                        holder.isFirstInterfaceInDpn = !existingElanDpnInterfaces.isPresent();
+                    }
+                    if (holder.isFirstInterfaceInDpn) {
+                        // ELAN's 1st ElanInterface added to this DPN
+                        if (!existingElanDpnInterfaces.isPresent()) {
+                            holder.dpnInterfaces =
+                                createElanInterfacesList(elanInstanceName, interfaceName, holder.dpId, operTx);
+                        } else {
+                            List<String> elanInterfaces = existingElanDpnInterfaces.get().getInterfaces();
+                            elanInterfaces.add(interfaceName);
+                            holder.dpnInterfaces = updateElanDpnInterfacesList(elanInstanceName, holder.dpId,
+                                elanInterfaces, operTx);
+                        }
+                        // The 1st ElanInterface in a DPN must program the Ext Tunnel
+                        // table, but only if Elan has VNI
+                        if (isVxlanNetworkOrVxlanSegment(elanInstance)) {
+                            setExternalTunnelTable(holder.dpId, elanInstance);
+                        }
+                        elanL2GatewayUtils.installElanL2gwDevicesLocalMacsInDpn(holder.dpId, elanInstance,
+                            interfaceName);
                     } else {
                         List<String> elanInterfaces = existingElanDpnInterfaces.get().getInterfaces();
                         elanInterfaces.add(interfaceName);
-                        dpnInterfaces = updateElanDpnInterfacesList(elanInstanceName, dpId,
-                                elanInterfaces, tx);
-                    }
-                    // The 1st ElanInterface in a DPN must program the Ext Tunnel
-                    // table, but only if Elan has VNI
-                    if (isVxlanNetworkOrVxlanSegment(elanInstance)) {
-                        setExternalTunnelTable(dpId, elanInstance);
-                    }
-                    elanL2GatewayUtils.installElanL2gwDevicesLocalMacsInDpn(dpId, elanInstance, interfaceName);
-                } else {
-                    List<String> elanInterfaces = existingElanDpnInterfaces.get().getInterfaces();
-                    elanInterfaces.add(interfaceName);
-                    if (elanInterfaces.size() == 1) { // 1st dpn interface
-                        elanL2GatewayUtils.installElanL2gwDevicesLocalMacsInDpn(dpId, elanInstance, interfaceName);
+                        if (elanInterfaces.size() == 1) { // 1st dpn interface
+                            elanL2GatewayUtils.installElanL2gwDevicesLocalMacsInDpn(holder.dpId, elanInstance,
+                                interfaceName);
+                        }
+                        holder.dpnInterfaces =
+                            updateElanDpnInterfacesList(elanInstanceName, holder.dpId, elanInterfaces, operTx);
                     }
-                    dpnInterfaces = updateElanDpnInterfacesList(elanInstanceName, dpId, elanInterfaces, tx);
                 }
             }
-        }
 
-        // add code to install Local/Remote BC group, unknow DMAC entry,
-        // terminating service table flow entry
-        // call bindservice of interfacemanager to create ingress table flow
-        // enty.
-        // Add interface to the ElanInterfaceForwardingEntires Container
-        createElanInterfaceTablesList(interfaceName, tx);
-        List<ListenableFuture<Void>> futures = new ArrayList<>();
-        futures.add(ElanUtils.waitForTransactionToComplete(tx));
-        installEntriesForFirstInterfaceonDpn(elanInstance, interfaceInfo, dpnInterfaces, isFirstInterfaceInDpn);
+            // add code to install Local/Remote BC group, unknow DMAC entry,
+            // terminating service table flow entry
+            // call bindservice of interfacemanager to create ingress table flow
+            // enty.
+            // Add interface to the ElanInterfaceForwardingEntires Container
+            createElanInterfaceTablesList(interfaceName, operTx);
+        }));
+        futures.forEach(ElanUtils::waitForTransactionToComplete);
+        installEntriesForFirstInterfaceonDpn(elanInstance, interfaceInfo, holder.dpnInterfaces,
+            holder.isFirstInterfaceInDpn);
 
         // add the vlan provider interface to remote BC group for the elan
         // for internal vlan networks
         if (ElanUtils.isVlan(elanInstance) && !elanInstance.isExternal()) {
             if (interfaceManager.isExternalInterface(interfaceName)) {
                 LOG.debug("adding vlan prv intf {} to elan {} BC group", interfaceName, elanInstanceName);
-                handleExternalInterfaceEvent(elanInstance, dpnInterfaces, dpId);
+                handleExternalInterfaceEvent(elanInstance, holder.dpnInterfaces, holder.dpId);
             }
         }
 
-        if (isFirstInterfaceInDpn && isVxlanNetworkOrVxlanSegment(elanInstance)) {
+        if (holder.isFirstInterfaceInDpn && isVxlanNetworkOrVxlanSegment(elanInstance)) {
             //update the remote-DPNs remoteBC group entry with Tunnels
-            LOG.trace("update remote bc group for elan {} on other DPNs for newly added dpn {}", elanInstance, dpId);
-            setElanAndEtreeBCGrouponOtherDpns(elanInstance, dpId);
+            LOG.trace("update remote bc group for elan {} on other DPNs for newly added dpn {}", elanInstance,
+                holder.dpId);
+            setElanAndEtreeBCGrouponOtherDpns(elanInstance, holder.dpId);
         }
 
         String jobKey = ElanUtils.getElanInterfaceJobKey(interfaceName);
         InterfaceAddWorkerOnElanInterface addWorker = new InterfaceAddWorkerOnElanInterface(jobKey,
-                elanInterface, interfaceInfo, elanInstance, isFirstInterfaceInDpn, this);
+                elanInterface, interfaceInfo, elanInstance, holder.isFirstInterfaceInDpn, this);
         jobCoordinator.enqueueJob(jobKey, addWorker, ElanConstants.JOB_MAX_RETRIES);
         return futures;
     }
@@ -769,55 +775,58 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
             ElanInterface elanInterface, InterfaceInfo interfaceInfo, boolean isFirstInterfaceInDpn) {
         String elanInstanceName = elanInstance.getElanInstanceName();
         String interfaceName = elanInterface.getName();
-        WriteTransaction tx = broker.newWriteOnlyTransaction();
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
         BigInteger dpId = interfaceInfo.getDpId();
-        WriteTransaction writeFlowGroupTx = broker.newWriteOnlyTransaction();
-        installEntriesForElanInterface(elanInstance, elanInterface, interfaceInfo,
-                isFirstInterfaceInDpn, tx, writeFlowGroupTx);
-
-        List<StaticMacEntries> staticMacEntriesList = elanInterface.getStaticMacEntries();
-        List<PhysAddress> staticMacAddresses = Lists.newArrayList();
-
         boolean isInterfaceOperational = isOperational(interfaceInfo);
-        if (ElanUtils.isNotEmpty(staticMacEntriesList)) {
-            for (StaticMacEntries staticMacEntry : staticMacEntriesList) {
-                InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanInstanceName,
-                        staticMacEntry.getMacAddress());
-                Optional<MacEntry> existingMacEntry = ElanUtils.read(broker,
-                        LogicalDatastoreType.OPERATIONAL, macId);
-                if (existingMacEntry.isPresent()) {
-                    elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(
-                            elanInstanceName, interfaceName, existingMacEntry.get().getInterface(),
-                            existingMacEntry.get(), tx);
-                } else {
-                    elanForwardingEntriesHandler
-                            .addElanInterfaceForwardingTableList(elanInstanceName, interfaceName, staticMacEntry, tx);
-                }
+        futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, confTx -> {
+            futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operTx -> {
+                installEntriesForElanInterface(elanInstance, elanInterface, interfaceInfo,
+                    isFirstInterfaceInDpn, confTx, operTx);
+
+                List<StaticMacEntries> staticMacEntriesList = elanInterface.getStaticMacEntries();
+                List<PhysAddress> staticMacAddresses = Lists.newArrayList();
+
+                if (ElanUtils.isNotEmpty(staticMacEntriesList)) {
+                    for (StaticMacEntries staticMacEntry : staticMacEntriesList) {
+                        InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanInstanceName,
+                            staticMacEntry.getMacAddress());
+                        Optional<MacEntry> existingMacEntry = ElanUtils.read(broker,
+                            LogicalDatastoreType.OPERATIONAL, macId);
+                        if (existingMacEntry.isPresent()) {
+                            elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(
+                                elanInstanceName, interfaceName, existingMacEntry.get().getInterface(),
+                                existingMacEntry.get(), operTx);
+                        } else {
+                            elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(elanInstanceName,
+                                interfaceName, staticMacEntry, operTx);
+                        }
 
-                if (isInterfaceOperational) {
-                    // Setting SMAC, DMAC, UDMAC in this DPN and also in other
-                    // DPNs
-                    String macAddress = staticMacEntry.getMacAddress().getValue();
-                    LOG.info("programming smac and dmacs for {} on source and other DPNs for elan {} and interface {}",
-                            macAddress, elanInstanceName, interfaceName);
-                    elanUtils.setupMacFlows(elanInstance, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT,
-                            staticMacEntry.getMacAddress().getValue(), true, writeFlowGroupTx);
-                }
-            }
+                        if (isInterfaceOperational) {
+                            // Setting SMAC, DMAC, UDMAC in this DPN and also in other
+                            // DPNs
+                            String macAddress = staticMacEntry.getMacAddress().getValue();
+                            LOG.info(
+                                "programming smac and dmacs for {} on source and other DPNs for elan {} and interface"
+                                    + " {}",
+                                macAddress, elanInstanceName, interfaceName);
+                            elanUtils.setupMacFlows(elanInstance, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT,
+                                staticMacEntry.getMacAddress().getValue(), true, confTx);
+                        }
+                    }
 
-            if (isInterfaceOperational) {
-                // Add MAC in TOR's remote MACs via OVSDB. Outside of the loop
-                // on purpose.
-                for (StaticMacEntries staticMacEntry : staticMacEntriesList) {
-                    staticMacAddresses.add(staticMacEntry.getMacAddress());
+                    if (isInterfaceOperational) {
+                        // Add MAC in TOR's remote MACs via OVSDB. Outside of the loop
+                        // on purpose.
+                        for (StaticMacEntries staticMacEntry : staticMacEntriesList) {
+                            staticMacAddresses.add(staticMacEntry.getMacAddress());
+                        }
+                        elanL2GatewayUtils.scheduleAddDpnMacInExtDevices(elanInstance.getElanInstanceName(), dpId,
+                            staticMacAddresses);
+                    }
                 }
-                elanL2GatewayUtils.scheduleAddDpnMacInExtDevices(elanInstance.getElanInstanceName(), dpId,
-                        staticMacAddresses);
-            }
-        }
-        List<ListenableFuture<Void>> futures = new ArrayList<>();
-        futures.add(ElanUtils.waitForTransactionToComplete(tx));
-        futures.add(ElanUtils.waitForTransactionToComplete(writeFlowGroupTx));
+            }));
+        }));
+        futures.forEach(ElanUtils::waitForTransactionToComplete);
         if (isInterfaceOperational && !interfaceManager.isExternalInterface(interfaceName)) {
             //At this point, the interface is operational and D/SMAC flows have been configured, mark the port active
             try {
@@ -866,10 +875,7 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
         if (dpnInterfaces.getInterfaces().contains(elanInstanceName)) {
             dummyInterfaceCount++;
         }
-        if (dpnInterfaces.getInterfaces().size() - dummyInterfaceCount == 0) {
-            return true;
-        }
-        return false;
+        return dpnInterfaces.getInterfaces().size() - dummyInterfaceCount == 0;
     }
 
     private InstanceIdentifier<MacEntry> getMacEntryOperationalDataPath(String elanName, PhysAddress physAddress) {
@@ -878,24 +884,24 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
     }
 
     private void installEntriesForElanInterface(ElanInstance elanInstance, ElanInterface elanInterface,
-            InterfaceInfo interfaceInfo, boolean isFirstInterfaceInDpn, WriteTransaction tx,
-            WriteTransaction writeFlowGroupTx) {
+            InterfaceInfo interfaceInfo, boolean isFirstInterfaceInDpn, TypedWriteTransaction<Configuration> confTx,
+            TypedWriteTransaction<Operational> operTx) {
         if (!isOperational(interfaceInfo)) {
             return;
         }
         BigInteger dpId = interfaceInfo.getDpId();
         if (!elanUtils.isOpenstackVniSemanticsEnforced()) {
-            elanUtils.setupTermDmacFlows(interfaceInfo, mdsalManager, writeFlowGroupTx);
+            elanUtils.setupTermDmacFlows(interfaceInfo, mdsalManager, confTx);
         }
-        setupFilterEqualsTable(elanInstance, interfaceInfo, writeFlowGroupTx);
+        setupFilterEqualsTable(elanInstance, interfaceInfo, confTx);
         if (isFirstInterfaceInDpn) {
             // Terminating Service , UnknownDMAC Table.
             // The 1st ELAN Interface in a DPN must program the INTERNAL_TUNNEL_TABLE, but only if the network type
             // for ELAN Instance is VxLAN
             if (isVxlanNetworkOrVxlanSegment(elanInstance)) {
-                setupTerminateServiceTable(elanInstance, dpId, writeFlowGroupTx);
+                setupTerminateServiceTable(elanInstance, dpId, confTx);
             }
-            setupUnknownDMacTable(elanInstance, dpId, writeFlowGroupTx);
+            setupUnknownDMacTable(elanInstance, dpId, confTx);
             /*
              * Install remote DMAC flow. This is required since this DPN is
              * added later to the elan instance and remote DMACs of other
@@ -905,11 +911,11 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
             if (!interfaceManager.isExternalInterface(interfaceInfo.getInterfaceName())) {
                 LOG.info("Programming remote dmac flows on the newly connected dpn {} for elan {} ", dpId,
                         elanInstance.getElanInstanceName());
-                programRemoteDmacFlow(elanInstance, interfaceInfo, writeFlowGroupTx);
+                programRemoteDmacFlow(elanInstance, interfaceInfo, confTx);
             }
         }
         // bind the Elan service to the Interface
-        bindService(elanInstance, elanInterface, interfaceInfo.getInterfaceTag(), tx);
+        bindService(elanInstance, elanInterface, interfaceInfo.getInterfaceTag(), confTx);
     }
 
     public void installEntriesForFirstInterfaceonDpn(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
@@ -938,7 +944,7 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
     }
 
     public void setupFilterEqualsTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
-            WriteTransaction writeFlowGroupTx) {
+            TypedWriteTransaction<Configuration> writeFlowGroupTx) {
         int ifTag = interfaceInfo.getInterfaceTag();
         Flow flow = MDSALUtil.buildFlowNew(NwConstants.ELAN_FILTER_EQUALS_TABLE,
                 getFlowRef(NwConstants.ELAN_FILTER_EQUALS_TABLE, ifTag, "group"), 9, elanInfo.getElanInstanceName(), 0,
@@ -946,14 +952,14 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
                 ElanUtils.getTunnelIdMatchForFilterEqualsLPortTag(ifTag),
                 elanUtils.getInstructionsInPortForOutGroup(interfaceInfo.getInterfaceName()));
 
-        mdsalManager.addFlowToTx(interfaceInfo.getDpId(), flow, writeFlowGroupTx);
+        mdsalManager.addFlow(writeFlowGroupTx, interfaceInfo.getDpId(), flow);
 
         Flow flowEntry = MDSALUtil.buildFlowNew(NwConstants.ELAN_FILTER_EQUALS_TABLE,
                 getFlowRef(NwConstants.ELAN_FILTER_EQUALS_TABLE, ifTag, "drop"), 10, elanInfo.getElanInstanceName(), 0,
                 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)),
                 getMatchesForFilterEqualsLPortTag(ifTag), MDSALUtil.buildInstructionsDrop());
 
-        mdsalManager.addFlowToTx(interfaceInfo.getDpId(), flowEntry, writeFlowGroupTx);
+        mdsalManager.addFlow(writeFlowGroupTx, interfaceInfo.getDpId(), flowEntry);
     }
 
     public void removeFilterEqualsTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
@@ -972,12 +978,6 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
         mdsalManager.removeFlow(flowTx, interfaceInfo.getDpId(), flowEntity);
     }
 
-    private List<Bucket> getRemoteBCGroupBucketInfos(ElanInstance elanInfo, int bucketKeyStart,
-                                                     InterfaceInfo interfaceInfo, long elanTag) {
-        return elanL2GatewayMulticastUtils.getRemoteBCGroupBuckets(elanInfo, null, interfaceInfo.getDpId(),
-                bucketKeyStart, elanTag);
-    }
-
     private void setElanAndEtreeBCGrouponOtherDpns(ElanInstance elanInfo, BigInteger dpId) {
         int elanTag = elanInfo.getElanTag().intValue();
         long groupId = ElanUtils.getElanRemoteBCGId(elanTag);
@@ -1050,14 +1050,6 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
         }
     }
 
-    /**
-     * Returns the bucket info with the given interface as the only bucket.
-     */
-    private Bucket getLocalBCGroupBucketInfo(InterfaceInfo interfaceInfo, int bucketIdStart) {
-        return MDSALUtil.buildBucket(getInterfacePortActions(interfaceInfo), MDSALUtil.GROUP_WEIGHT, bucketIdStart,
-                MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP);
-    }
-
     private List<MatchInfo> buildMatchesForVni(Long vni) {
         List<MatchInfo> mkMatches = new ArrayList<>();
         MatchInfo match = new MatchTunnelId(BigInteger.valueOf(vni));
@@ -1106,18 +1098,20 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
         ElanInterfaceMac elanInterfaceMac = elanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
         if (elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
             List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
-            WriteTransaction writeFlowTx = broker.newWriteOnlyTransaction();
-            for (MacEntry macEntry : macEntries) {
-                String macAddress = macEntry.getMacAddress().getValue();
-                LOG.info("Installing remote dmac for mac address {} and interface {}", macAddress, interfaceName);
-                synchronized (ElanUtils.getElanMacDPNKey(elanInfo.getElanTag(), macAddress,
-                        interfaceInfo.getDpId())) {
-                    LOG.info("Acquired lock for mac : {}, proceeding with remote dmac install operation", macAddress);
-                    elanUtils.setupDMacFlowOnRemoteDpn(elanInfo, interfaceInfo, dstDpId, macAddress,
-                            writeFlowTx);
-                }
-            }
-            return Collections.singletonList(ElanUtils.waitForTransactionToComplete(writeFlowTx));
+            return Collections.singletonList(ElanUtils.waitForTransactionToComplete(
+                txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
+                    for (MacEntry macEntry : macEntries) {
+                        String macAddress = macEntry.getMacAddress().getValue();
+                        LOG.info("Installing remote dmac for mac address {} and interface {}", macAddress,
+                            interfaceName);
+                        synchronized (ElanUtils.getElanMacDPNKey(elanInfo.getElanTag(), macAddress,
+                            interfaceInfo.getDpId())) {
+                            LOG.info("Acquired lock for mac : {}, proceeding with remote dmac install operation",
+                                macAddress);
+                            elanUtils.setupDMacFlowOnRemoteDpn(elanInfo, interfaceInfo, dstDpId, macAddress, tx);
+                        }
+                    }
+                })));
         }
         return Collections.emptyList();
     }
@@ -1220,38 +1214,21 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
     }
 
     public void removeLocalBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
-            WriteTransaction deleteFlowGroupTx) {
+            TypedReadWriteTransaction<Configuration> deleteFlowGroupTx)
+            throws ExecutionException, InterruptedException {
         BigInteger dpnId = interfaceInfo.getDpId();
         long groupId = ElanUtils.getElanLocalBCGId(elanInfo.getElanTag());
-        List<Bucket> listBuckets = new ArrayList<>();
-        int bucketId = 0;
-        listBuckets.add(getLocalBCGroupBucketInfo(interfaceInfo, bucketId));
-        // listBuckets.addAll(getRemoteBCGroupBucketInfos(elanInfo, 1,
-        // interfaceInfo));
-        Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll,
-                MDSALUtil.buildBucketLists(listBuckets));
-        LOG.trace("deleted the localBroadCast Group:{}", group);
-        mdsalManager.removeGroupToTx(dpnId, group, deleteFlowGroupTx);
+        LOG.trace("deleted the localBroadCast Group:{}", groupId);
+        mdsalManager.removeGroup(deleteFlowGroupTx, dpnId, groupId);
     }
 
     public void removeElanBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
-            WriteTransaction deleteFlowGroupTx) {
-        int bucketId = 0;
-        int actionKey = 0;
-        Long elanTag = elanInfo.getElanTag();
-        List<Bucket> listBuckets = new ArrayList<>();
-        List<Action> listAction = new ArrayList<>();
-        listAction.add(new ActionGroup(++actionKey, ElanUtils.getElanLocalBCGId(elanTag)).buildAction());
-        listBuckets.add(MDSALUtil.buildBucket(listAction, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT,
-                MDSALUtil.WATCH_GROUP));
-        bucketId++;
-        listBuckets.addAll(getRemoteBCGroupBucketInfos(elanInfo, bucketId, interfaceInfo, elanTag));
+            TypedReadWriteTransaction<Configuration> deleteFlowGroupTx)
+            throws ExecutionException, InterruptedException {
         BigInteger dpnId = interfaceInfo.getDpId();
         long groupId = ElanUtils.getElanRemoteBCGId(elanInfo.getElanTag());
-        Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll,
-                MDSALUtil.buildBucketLists(listBuckets));
-        LOG.trace("deleting the remoteBroadCast group:{}", group);
-        mdsalManager.removeGroupToTx(dpnId, group, deleteFlowGroupTx);
+        LOG.trace("deleting the remoteBroadCast group:{}", groupId);
+        mdsalManager.removeGroup(deleteFlowGroupTx, dpnId, groupId);
     }
 
     /**
@@ -1303,13 +1280,14 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
         mdsalManager.removeFlow(flowEntity);
     }
 
-    public void setupTerminateServiceTable(ElanInstance elanInfo, BigInteger dpId, WriteTransaction writeFlowGroupTx) {
+    public void setupTerminateServiceTable(ElanInstance elanInfo, BigInteger dpId,
+            TypedWriteTransaction<Configuration> writeFlowGroupTx) {
         setupTerminateServiceTable(elanInfo, dpId, elanInfo.getElanTag(), writeFlowGroupTx);
         setupEtreeTerminateServiceTable(elanInfo, dpId, writeFlowGroupTx);
     }
 
     public void setupTerminateServiceTable(ElanInstance elanInfo, BigInteger dpId, long elanTag,
-            WriteTransaction writeFlowGroupTx) {
+            TypedWriteTransaction<Configuration> writeFlowGroupTx) {
         List<? extends MatchInfoBase> listMatchInfoBase;
         List<InstructionInfo> instructionInfos;
         long serviceId;
@@ -1326,18 +1304,19 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
                 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, serviceId), 5, String.format("%s:%d", "ITM Flow Entry ",
                 elanTag), 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(elanTag)), listMatchInfoBase,
                 instructionInfos);
-        mdsalManager.addFlowToTx(flowEntity, writeFlowGroupTx);
+        mdsalManager.addFlow(writeFlowGroupTx, flowEntity);
     }
 
     private void setupEtreeTerminateServiceTable(ElanInstance elanInfo, BigInteger dpId,
-            WriteTransaction writeFlowGroupTx) {
+            TypedWriteTransaction<Configuration> writeFlowGroupTx) {
         EtreeInstance etreeInstance = elanInfo.augmentation(EtreeInstance.class);
         if (etreeInstance != null) {
             setupTerminateServiceTable(elanInfo, dpId, etreeInstance.getEtreeLeafTagVal().getValue(), writeFlowGroupTx);
         }
     }
 
-    public void setupUnknownDMacTable(ElanInstance elanInfo, BigInteger dpId, WriteTransaction writeFlowGroupTx) {
+    public void setupUnknownDMacTable(ElanInstance elanInfo, BigInteger dpId,
+            TypedWriteTransaction<Configuration> writeFlowGroupTx) {
         long elanTag = elanInfo.getElanTag();
         installLocalUnknownFlow(elanInfo, dpId, elanTag, writeFlowGroupTx);
         installRemoteUnknownFlow(elanInfo, dpId, elanTag, writeFlowGroupTx);
@@ -1345,7 +1324,7 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
     }
 
     private void setupEtreeUnknownDMacTable(ElanInstance elanInfo, BigInteger dpId, long elanTag,
-            WriteTransaction writeFlowGroupTx) {
+            TypedWriteTransaction<Configuration> writeFlowGroupTx) {
         EtreeLeafTagName etreeLeafTag = elanEtreeUtils.getEtreeLeafTagByElanTag(elanTag);
         if (etreeLeafTag != null) {
             long leafTag = etreeLeafTag.getEtreeLeafTag().getValue();
@@ -1355,7 +1334,7 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
     }
 
     private void installLocalUnknownFlow(ElanInstance elanInfo, BigInteger dpId, long elanTag,
-            WriteTransaction writeFlowGroupTx) {
+            TypedWriteTransaction<Configuration> writeFlowGroupTx) {
         FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.ELAN_UNKNOWN_DMAC_TABLE,
                 getUnknownDmacFlowRef(NwConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag,/* SH flag */false),
                 5, elanInfo.getElanInstanceName(), 0, 0,
@@ -1363,11 +1342,11 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
                 getMatchesForElanTag(elanTag, /* SH flag */false),
                 getInstructionsForOutGroup(ElanUtils.getElanRemoteBCGId(elanTag)));
 
-        mdsalManager.addFlowToTx(flowEntity, writeFlowGroupTx);
+        mdsalManager.addFlow(writeFlowGroupTx, flowEntity);
     }
 
     private void installRemoteUnknownFlow(ElanInstance elanInfo, BigInteger dpId, long elanTag,
-            WriteTransaction writeFlowGroupTx) {
+            TypedWriteTransaction<Configuration> writeFlowGroupTx) {
         // only if ELAN can connect to external network, perform the following
 
         if (isVxlanNetworkOrVxlanSegment(elanInfo) || ElanUtils.isVlan(elanInfo) || ElanUtils.isFlat(elanInfo)) {
@@ -1377,22 +1356,23 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
                     ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)),
                     getMatchesForElanTag(elanTag, /* SH flag */true),
                     getInstructionsForOutGroup(ElanUtils.getElanLocalBCGId(elanTag)));
-            mdsalManager.addFlowToTx(flowEntity, writeFlowGroupTx);
+            mdsalManager.addFlow(writeFlowGroupTx, flowEntity);
         }
     }
 
 
-    private void removeUnknownDmacFlow(BigInteger dpId, ElanInstance elanInfo, WriteTransaction deleteFlowGroupTx,
-            long elanTag) {
+    private void removeUnknownDmacFlow(BigInteger dpId, ElanInstance elanInfo,
+            TypedReadWriteTransaction<Configuration> deleteFlowGroupTx, long elanTag)
+            throws ExecutionException, InterruptedException {
         Flow flow = new FlowBuilder().setId(new FlowId(getUnknownDmacFlowRef(NwConstants.ELAN_UNKNOWN_DMAC_TABLE,
                 elanTag, SH_FLAG_UNSET))).setTableId(NwConstants.ELAN_UNKNOWN_DMAC_TABLE).build();
-        mdsalManager.removeFlowToTx(dpId, flow, deleteFlowGroupTx);
+        mdsalManager.removeFlow(deleteFlowGroupTx, dpId, flow);
 
         if (isVxlanNetworkOrVxlanSegment(elanInfo)) {
             Flow flow2 = new FlowBuilder().setId(new FlowId(getUnknownDmacFlowRef(NwConstants.ELAN_UNKNOWN_DMAC_TABLE,
                     elanTag, SH_FLAG_SET))).setTableId(NwConstants.ELAN_UNKNOWN_DMAC_TABLE)
                     .build();
-            mdsalManager.removeFlowToTx(dpId, flow2, deleteFlowGroupTx);
+            mdsalManager.removeFlow(deleteFlowGroupTx, dpId, flow2);
         }
     }
 
@@ -1400,7 +1380,8 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
         elanUtils.removeTerminatingServiceAction(dpId, (int) elanTag);
     }
 
-    private void bindService(ElanInstance elanInfo, ElanInterface elanInterface, int lportTag, WriteTransaction tx) {
+    private void bindService(ElanInstance elanInfo, ElanInterface elanInterface, int lportTag,
+            TypedWriteTransaction<Configuration> tx) {
         if (isStandardElanService(elanInterface)) {
             bindElanService(elanInfo.getElanTag(), elanInfo.getElanInstanceName(),
                     elanInterface.getName(), lportTag, tx);
@@ -1410,7 +1391,7 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
     }
 
     private void bindElanService(long elanTag, String elanInstanceName, String interfaceName, int lportTag,
-            WriteTransaction tx) {
+            TypedWriteTransaction<Configuration> tx) {
         int instructionKey = 0;
         List<Instruction> instructions = new ArrayList<>();
         instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(ElanHelper.getElanMetadataLabel(elanTag),
@@ -1434,13 +1415,12 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
         Optional<BoundServices> existingElanService = ElanUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
                 bindServiceId);
         if (!existingElanService.isPresent()) {
-            tx.put(LogicalDatastoreType.CONFIGURATION, bindServiceId, serviceInfo,
-                    WriteTransaction.CREATE_MISSING_PARENTS);
+            tx.put(bindServiceId, serviceInfo, CREATE_MISSING_PARENTS);
         }
     }
 
     private void bindEtreeService(ElanInstance elanInfo, ElanInterface elanInterface, int lportTag,
-            WriteTransaction tx) {
+            TypedWriteTransaction<Configuration> tx) {
         if (elanInterface.augmentation(EtreeInterface.class).getEtreeInterfaceType() == EtreeInterfaceType.Root) {
             bindElanService(elanInfo.getElanTag(), elanInfo.getElanInstanceName(), elanInterface.getName(),
                     lportTag, tx);
@@ -1460,11 +1440,12 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
         return elanInterface.augmentation(EtreeInterface.class) == null;
     }
 
-    protected void unbindService(String interfaceName, ReadWriteTransaction tx) throws ReadFailedException {
+    protected void unbindService(String interfaceName, TypedReadWriteTransaction<Configuration> tx)
+            throws ExecutionException, InterruptedException {
         short elanServiceIndex = ServiceIndex.getIndex(NwConstants.ELAN_SERVICE_NAME, NwConstants.ELAN_SERVICE_INDEX);
         InstanceIdentifier<BoundServices> bindServiceId = ElanUtils.buildServiceId(interfaceName, elanServiceIndex);
-        if (tx.read(LogicalDatastoreType.CONFIGURATION, bindServiceId).checkedGet().isPresent()) {
-            tx.delete(LogicalDatastoreType.CONFIGURATION, bindServiceId);
+        if (tx.read(bindServiceId).get().isPresent()) {
+            tx.delete(bindServiceId);
         }
     }
 
@@ -1492,12 +1473,11 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
     }
 
     private DpnInterfaces updateElanDpnInterfacesList(String elanInstanceName, BigInteger dpId,
-            List<String> interfaceNames, WriteTransaction tx) {
+            List<String> interfaceNames, TypedWriteTransaction<Operational> tx) {
         DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId).setInterfaces(interfaceNames)
                 .withKey(new DpnInterfacesKey(dpId)).build();
-        tx.put(LogicalDatastoreType.OPERATIONAL,
-                ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId), dpnInterface,
-                WriteTransaction.CREATE_MISSING_PARENTS);
+        tx.put(ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId), dpnInterface,
+                CREATE_MISSING_PARENTS);
         return dpnInterface;
     }
 
@@ -1509,48 +1489,46 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
      * @param dpId
      *            the dp id
      */
-    private void deleteElanDpnInterface(String elanInstanceName, BigInteger dpId, WriteTransaction tx) {
+    private void deleteElanDpnInterface(String elanInstanceName, BigInteger dpId,
+            TypedReadWriteTransaction<Operational> tx) throws ExecutionException, InterruptedException {
         InstanceIdentifier<DpnInterfaces> dpnInterfacesId = ElanUtils
                 .getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId);
-        Optional<DpnInterfaces> dpnInterfaces = ElanUtils.read(broker,
-                LogicalDatastoreType.OPERATIONAL, dpnInterfacesId);
+        Optional<DpnInterfaces> dpnInterfaces = tx.read(dpnInterfacesId).get();
         if (dpnInterfaces.isPresent()) {
-            tx.delete(LogicalDatastoreType.OPERATIONAL, dpnInterfacesId);
+            tx.delete(dpnInterfacesId);
         }
     }
 
     private DpnInterfaces createElanInterfacesList(String elanInstanceName, String interfaceName, BigInteger dpId,
-            WriteTransaction tx) {
+            TypedWriteTransaction<Operational> tx) {
         List<String> interfaceNames = new ArrayList<>();
         interfaceNames.add(interfaceName);
         DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId).setInterfaces(interfaceNames)
                 .withKey(new DpnInterfacesKey(dpId)).build();
-        tx.put(LogicalDatastoreType.OPERATIONAL,
-                ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId), dpnInterface,
-                WriteTransaction.CREATE_MISSING_PARENTS);
+        tx.put(ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId), dpnInterface,
+                CREATE_MISSING_PARENTS);
         return dpnInterface;
     }
 
-    private void createElanInterfaceTablesList(String interfaceName, WriteTransaction tx) {
+    private void createElanInterfaceTablesList(String interfaceName, TypedReadWriteTransaction<Operational> tx)
+            throws ExecutionException, InterruptedException {
         InstanceIdentifier<ElanInterfaceMac> elanInterfaceMacTables = ElanUtils
                 .getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
-        Optional<ElanInterfaceMac> interfaceMacTables = ElanUtils.read(broker,
-                LogicalDatastoreType.OPERATIONAL, elanInterfaceMacTables);
+        Optional<ElanInterfaceMac> interfaceMacTables = tx.read(elanInterfaceMacTables).get();
         // Adding new Elan Interface Port to the operational DataStore without
         // Static-Mac Entries..
         if (!interfaceMacTables.isPresent()) {
             ElanInterfaceMac elanInterfaceMacTable = new ElanInterfaceMacBuilder().setElanInterface(interfaceName)
                     .withKey(new ElanInterfaceMacKey(interfaceName)).build();
-            tx.put(LogicalDatastoreType.OPERATIONAL,
-                    ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName), elanInterfaceMacTable,
-                    WriteTransaction.CREATE_MISSING_PARENTS);
+            tx.put(ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName), elanInterfaceMacTable,
+                    CREATE_MISSING_PARENTS);
         }
     }
 
-    private void createElanStateList(String elanInstanceName, String interfaceName, WriteTransaction tx) {
+    private void createElanStateList(String elanInstanceName, String interfaceName,
+            TypedReadWriteTransaction<Operational> tx) throws ExecutionException, InterruptedException {
         InstanceIdentifier<Elan> elanInstance = ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName);
-        Optional<Elan> elanInterfaceLists = ElanUtils.read(broker,
-                LogicalDatastoreType.OPERATIONAL, elanInstance);
+        Optional<Elan> elanInterfaceLists = tx.read(elanInstance).get();
         // Adding new Elan Interface Port to the operational DataStore without
         // Static-Mac Entries..
         if (elanInterfaceLists.isPresent()) {
@@ -1561,8 +1539,7 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
             interfaceLists.add(interfaceName);
             Elan elanState = new ElanBuilder().setName(elanInstanceName).setElanInterfaces(interfaceLists)
                     .withKey(new ElanKey(elanInstanceName)).build();
-            tx.put(LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName),
-                    elanState, WriteTransaction.CREATE_MISSING_PARENTS);
+            tx.put(ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName), elanState, CREATE_MISSING_PARENTS);
         }
     }
 
index 912558c1be0dd23091dee729498ea916e31ce122..bb391562e1d507be2bdf3b1a829eaa3c75b1d7c2 100644 (file)
@@ -31,7 +31,6 @@ import org.opendaylight.genius.infra.Datastore.Configuration;
 import org.opendaylight.genius.infra.Datastore.Operational;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
-import org.opendaylight.genius.infra.TransactionAdapter;
 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 import org.opendaylight.genius.infra.TypedWriteTransaction;
 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
@@ -158,7 +157,7 @@ public class ElanLearntVpnVipToPortListener extends
             interfaceTx.put(elanMacEntryId, macEntry);
             ElanInstance elanInstance = elanInstanceCache.get(elanName).orNull();
             elanUtils.setupMacFlows(elanInstance, interfaceManager.getInterfaceInfo(interfaceName), macTimeOut,
-                    macAddress, true, TransactionAdapter.toWriteTransaction(flowTx));
+                    macAddress, true, flowTx);
         }
     }
 
index 3ab0a41775335d0fbfe1f7f645f78c65f3347b19..07767fdc309b394c3e97361dac48393b6bdc9564 100755 (executable)
@@ -25,7 +25,6 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
-import org.opendaylight.genius.infra.TransactionAdapter;
 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
@@ -215,7 +214,7 @@ public class ElanPacketInHandler implements PacketProcessingListener {
             futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
                 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, operTx -> {
                     elanUtils.setupMacFlows(elanInstance, interfaceInfo, elanInstance.getMacTimeout(),
-                        macAddress, !isVlanOrFlatProviderIface, TransactionAdapter.toWriteTransaction(tx));
+                        macAddress, !isVlanOrFlatProviderIface, tx);
                     InstanceIdentifier<MacEntry> macEntryId =
                         ElanUtils.getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, physAddress);
                     operTx.put(macEntryId, newMacEntry, WriteTransaction.CREATE_MISSING_PARENTS);
index 48c67bd36125cda3abee09330ed65f384f96d194..4124b82e9ca8258901bd4668baf75922e135b883 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.netvirt.elan.l2gw.ha;
 
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
+import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
 import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
 
 import com.google.common.base.Optional;
@@ -19,11 +19,16 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.ExecutionException;
 import java.util.stream.Collectors;
 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.infra.Datastore;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
 import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
 import org.opendaylight.netvirt.elan.l2gw.ha.commands.SwitchesCmd;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
@@ -156,16 +161,6 @@ public final class HwvtepHAUtil {
         return otherConfigsBuilder;
     }
 
-    public static Node readNode(ReadWriteTransaction tx, LogicalDatastoreType storeType,
-                                InstanceIdentifier<Node> nodeId)
-            throws ReadFailedException {
-        Optional<Node> optional = tx.read(storeType, nodeId).checkedGet();
-        if (optional.isPresent()) {
-            return optional.get();
-        }
-        return null;
-    }
-
     public static String convertToGlobalNodeId(String psNodeId) {
         int idx = psNodeId.indexOf(PHYSICALSWITCH);
         if (idx > 0) {
@@ -213,10 +208,7 @@ public final class HwvtepHAUtil {
     }
 
     public static boolean isEmpty(Collection collection) {
-        if (collection == null || collection.isEmpty()) {
-            return true;
-        }
-        return false;
+        return collection == null || collection.isEmpty();
     }
 
     public static Node getOriginal(DataObjectModification<Node> mod) {
@@ -457,7 +449,7 @@ public final class HwvtepHAUtil {
      * @param haNodePath Ha node path
      * @param haGlobalCfg HA global node object
      */
-    public static void buildGlobalConfigForHANode(ReadWriteTransaction tx,
+    public static void buildGlobalConfigForHANode(TypedWriteTransaction<Configuration> tx,
                                                   Node childNode,
                                                   InstanceIdentifier<Node> haNodePath,
                                                   Optional<Node> haGlobalCfg) {
@@ -470,15 +462,14 @@ public final class HwvtepHAUtil {
         nodeBuilder.setNodeId(haNodePath.firstKeyOf(Node.class).getNodeId());
         nodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, hwvtepGlobalBuilder.build());
         Node configHANode = nodeBuilder.build();
-        tx.merge(CONFIGURATION, haNodePath, configHANode,Boolean.TRUE);
+        tx.merge(haNodePath, configHANode, CREATE_MISSING_PARENTS);
     }
 
-    public static void deleteNodeIfPresent(ReadWriteTransaction tx,
-                                           LogicalDatastoreType logicalDatastoreType,
-                                           InstanceIdentifier<?> iid) throws ReadFailedException {
-        if (tx.read(logicalDatastoreType, iid).checkedGet().isPresent()) {
+    public static <D extends Datastore> void deleteNodeIfPresent(TypedReadWriteTransaction<D> tx,
+            InstanceIdentifier<?> iid) throws ExecutionException, InterruptedException {
+        if (tx.read(iid).get().isPresent()) {
             LOG.info("Deleting child node {}", getNodeIdVal(iid));
-            tx.delete(logicalDatastoreType, iid);
+            tx.delete(iid);
         }
     }
 
@@ -488,12 +479,9 @@ public final class HwvtepHAUtil {
      * @param key Node object
      * @param haNode Ha Node from which to be deleted
      * @param tx Transaction
-     * @throws ReadFailedException  Exception thrown if read fails
      */
-    public static void deletePSNodesOfNode(InstanceIdentifier<Node> key,
-                                           Node haNode,
-                                           ReadWriteTransaction tx)
-            throws ReadFailedException {
+    public static void deletePSNodesOfNode(InstanceIdentifier<Node> key, Node haNode,
+            TypedReadWriteTransaction<Configuration> tx) throws ExecutionException, InterruptedException {
         //read from switches attribute and clean up them
         HwvtepGlobalAugmentation globalAugmentation = haNode.augmentation(HwvtepGlobalAugmentation.class);
         if (globalAugmentation == null) {
@@ -504,13 +492,12 @@ public final class HwvtepHAUtil {
         if (switches != null) {
             for (Switches switche : switches) {
                 InstanceIdentifier<Node> psId = (InstanceIdentifier<Node>)switche.getSwitchRef().getValue();
-                deleteNodeIfPresent(tx, CONFIGURATION, psId);
+                deleteNodeIfPresent(tx, psId);
                 deleted.put(psId, Boolean.TRUE);
             }
         }
         //also read from managed by attribute of switches and cleanup them as a back up if the above cleanup fails
-        Optional<Topology> topologyOptional = tx
-                .read(CONFIGURATION, key.firstIdentifierOf(Topology.class)).checkedGet();
+        Optional<Topology> topologyOptional = tx .read(key.firstIdentifierOf(Topology.class)).get();
         String deletedNodeId = key.firstKeyOf(Node.class).getNodeId().getValue();
         if (topologyOptional.isPresent()) {
             Topology topology = topologyOptional.get();
@@ -524,7 +511,7 @@ public final class HwvtepHAUtil {
                             InstanceIdentifier<Node> psNodeId =
                                     convertToInstanceIdentifier(psNode.getNodeId().getValue());
                             if (deleted.containsKey(psNodeId)) {
-                                deleteNodeIfPresent(tx, CONFIGURATION, psNodeId);
+                                deleteNodeIfPresent(tx, psNodeId);
                             }
                         }
                     }
@@ -538,13 +525,11 @@ public final class HwvtepHAUtil {
      *
      * @param haPath HA node path from whih switches will be deleted
      * @param tx  Transaction object
-     * @throws ReadFailedException  Exception thrown if read fails
      */
     public static void deleteSwitchesManagedByNode(InstanceIdentifier<Node> haPath,
-                                                   ReadWriteTransaction tx)
-            throws ReadFailedException {
+            TypedReadWriteTransaction<Operational> tx) throws ExecutionException, InterruptedException {
 
-        Optional<Node> nodeOptional = tx.read(OPERATIONAL, haPath).checkedGet();
+        Optional<Node> nodeOptional = tx.read(haPath).get();
         if (!nodeOptional.isPresent()) {
             return;
         }
@@ -557,7 +542,7 @@ public final class HwvtepHAUtil {
         if (switches != null) {
             for (Switches switche : switches) {
                 InstanceIdentifier<Node> id = (InstanceIdentifier<Node>)switche.getSwitchRef().getValue();
-                deleteNodeIfPresent(tx, OPERATIONAL, id);
+                deleteNodeIfPresent(tx, id);
             }
         }
     }
index b890bc1dcea7f71832d666801f90e6b0b23b7282..78e28a113e498ef8600cbfaec8e5a8e0e0d10db7 100644 (file)
@@ -8,7 +8,8 @@
 package org.opendaylight.netvirt.elan.l2gw.ha.handlers;
 
 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 import org.opendaylight.netvirt.elan.l2gw.ha.merge.GlobalAugmentationMerger;
 import org.opendaylight.netvirt.elan.l2gw.ha.merge.GlobalNodeMerger;
 import org.opendaylight.netvirt.elan.l2gw.ha.merge.PSAugmentationMerger;
@@ -33,7 +34,7 @@ public class ConfigNodeUpdatedHandler {
      */
     public void copyHAGlobalUpdateToChild(InstanceIdentifier<Node> haChildNodeId,
                                           DataObjectModification<Node> mod,
-                                          ReadWriteTransaction tx) {
+                                          TypedReadWriteTransaction<Configuration> tx) {
         globalAugmentationMerger.mergeConfigUpdate(haChildNodeId,
                 mod.getModifiedAugmentation(HwvtepGlobalAugmentation.class), tx);
         globalNodeMerger.mergeConfigUpdate(haChildNodeId, mod, tx);
@@ -48,7 +49,7 @@ public class ConfigNodeUpdatedHandler {
      */
     public void copyHAPSUpdateToChild(InstanceIdentifier<Node> haChildNodeId,
                                       DataObjectModification<Node> mod,
-                                      ReadWriteTransaction tx) {
+                                      TypedReadWriteTransaction<Configuration> tx) {
 
         psAugmentationMerger.mergeConfigUpdate(haChildNodeId,
                 mod.getModifiedAugmentation(PhysicalSwitchAugmentation.class), tx);
index 1aebf23ce04e7a9c2e15677a5229844720a77f8d..d06ad39c4aa314b1c6bd7f71a72046f05b381fca 100644 (file)
@@ -8,12 +8,15 @@
 package org.opendaylight.netvirt.elan.l2gw.ha.handlers;
 
 import com.google.common.base.Optional;
+import java.util.concurrent.ExecutionException;
 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.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
 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;
@@ -34,13 +37,14 @@ public class HAEventHandler implements IHAEventHandler {
     public void handleChildNodeConnected(Node connectedNode,
                                          InstanceIdentifier<Node> connectedNodePath,
                                          InstanceIdentifier<Node> haNodePath,
-                                         ReadWriteTransaction tx)
-            throws ReadFailedException {
+                                         TypedReadWriteTransaction<Configuration> confTx,
+                                         TypedReadWriteTransaction<Operational> operTx)
+            throws ReadFailedException, ExecutionException, InterruptedException {
         if (haNodePath == null) {
             return;
         }
         nodeConnectedHandler.handleNodeConnected(connectedNode, connectedNodePath, haNodePath,
-                Optional.absent(), Optional.absent(), tx);
+                Optional.absent(), Optional.absent(), confTx, operTx);
     }
 
     @Override
@@ -49,19 +53,20 @@ public class HAEventHandler implements IHAEventHandler {
                                            InstanceIdentifier<Node> haNodePath,
                                            Optional<Node> haGlobalCfg,
                                            Optional<Node> haPSCfg,
-                                           ReadWriteTransaction tx)
-            throws ReadFailedException {
+                                           TypedReadWriteTransaction<Configuration> confTx,
+                                           TypedReadWriteTransaction<Operational> operTx)
+            throws ReadFailedException, ExecutionException, InterruptedException {
         if (haNodePath == null) {
             return;
         }
         nodeConnectedHandler.handleNodeConnected(connectedNode, connectedNodePath, haNodePath,
-                haGlobalCfg, haPSCfg, tx);
+                haGlobalCfg, haPSCfg, confTx, operTx);
     }
 
     @Override
     public void copyChildGlobalOpUpdateToHAParent(InstanceIdentifier<Node> haPath,
                                                   DataObjectModification<Node> mod,
-                                                  ReadWriteTransaction tx) {
+                                                  TypedReadWriteTransaction<Operational> tx) {
         if (haPath == null) {
             return;
         }
@@ -72,7 +77,7 @@ public class HAEventHandler implements IHAEventHandler {
     public void copyChildPsOpUpdateToHAParent(Node updatedSrcPSNode,
                                               InstanceIdentifier<Node> haPath,
                                               DataObjectModification<Node> mod,
-                                              ReadWriteTransaction tx) {
+                                              TypedReadWriteTransaction<Operational> tx) {
         if (haPath == null) {
             return;
         }
@@ -82,7 +87,7 @@ public class HAEventHandler implements IHAEventHandler {
     @Override
     public void copyHAPSUpdateToChild(InstanceIdentifier<Node> haChildNodeId,
                                       DataObjectModification<Node> mod,
-                                      ReadWriteTransaction tx) {
+                                      TypedReadWriteTransaction<Configuration> tx) {
         if (haChildNodeId == null) {
             return;
         }
@@ -92,7 +97,7 @@ public class HAEventHandler implements IHAEventHandler {
     @Override
     public void copyHAGlobalUpdateToChild(InstanceIdentifier<Node> haChildNodeId,
                                           DataObjectModification<Node> mod,
-                                          ReadWriteTransaction tx) {
+                                          TypedReadWriteTransaction<Configuration> tx) {
         if (haChildNodeId == null) {
             return;
         }
index e65caecb256e0a738b5dd307e5a0468defe252eb..55ab0caed10067fbad13363e2bc5c5392d58aa1e 100644 (file)
@@ -9,9 +9,12 @@ package org.opendaylight.netvirt.elan.l2gw.ha.handlers;
 
 import com.google.common.base.Optional;
 
+import java.util.concurrent.ExecutionException;
 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 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;
 
@@ -21,34 +24,36 @@ public interface IHAEventHandler {
     void handleChildNodeConnected(Node connectedNode,
                                   InstanceIdentifier<Node> connectedNodePath,
                                   InstanceIdentifier<Node> haNodePath,
-                                  ReadWriteTransaction tx)
-            throws ReadFailedException;
+                                  TypedReadWriteTransaction<Configuration> confTx,
+                                  TypedReadWriteTransaction<Operational> operTx)
+            throws ReadFailedException, ExecutionException, InterruptedException;
 
     void handleChildNodeReConnected(Node connectedNode,
                                     InstanceIdentifier<Node> connectedNodePath,
                                     InstanceIdentifier<Node> haNodePath,
                                     Optional<Node> haGlobalCfg,
                                     Optional<Node> haPSCfg,
-                                    ReadWriteTransaction tx)
-            throws ReadFailedException;
+                                    TypedReadWriteTransaction<Configuration> confTx,
+                                    TypedReadWriteTransaction<Operational> operTx)
+            throws ReadFailedException, ExecutionException, InterruptedException;
 
 
     void copyChildGlobalOpUpdateToHAParent(InstanceIdentifier<Node> haPath,
                                            DataObjectModification<Node> mod,
-                                           ReadWriteTransaction tx);
+                                           TypedReadWriteTransaction<Operational> tx);
 
     void copyChildPsOpUpdateToHAParent(Node updatedSrcPSNode,
                                        InstanceIdentifier<Node> haPath,
                                        DataObjectModification<Node> mod,
-                                       ReadWriteTransaction tx);
+                                       TypedReadWriteTransaction<Operational> tx);
 
     void copyHAPSUpdateToChild(InstanceIdentifier<Node> haChildPath,
                                DataObjectModification<Node> mod,
-                               ReadWriteTransaction tx)
+                               TypedReadWriteTransaction<Configuration> tx)
             ;
 
     void copyHAGlobalUpdateToChild(InstanceIdentifier<Node> haChildPath,
                                    DataObjectModification<Node> mod,
-                                   ReadWriteTransaction tx)
+                                   TypedReadWriteTransaction<Configuration> tx)
             ;
 }
index 41c06081150b27c113005ef0c5bf13303dc61b37..744d523faafbba437bda81eb15cb2ac35b771021 100644 (file)
@@ -8,24 +8,26 @@
 package org.opendaylight.netvirt.elan.l2gw.ha.handlers;
 
 import com.google.common.base.Optional;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import java.util.concurrent.ExecutionException;
+import org.opendaylight.genius.infra.Datastore;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 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;
 
 public interface INodeCopier {
 
-    void copyGlobalNode(Optional<Node> globalNodeOptional,
+    <D extends Datastore> void copyGlobalNode(Optional<Node> globalNodeOptional,
                         InstanceIdentifier<Node> srcPath,
                         InstanceIdentifier<Node> dstPath,
-                        LogicalDatastoreType logicalDatastoreType,
-                        ReadWriteTransaction tx) throws ReadFailedException;
+                        Class<D> datastoreType,
+                        TypedReadWriteTransaction<D> tx)
+        throws ExecutionException, InterruptedException;
 
-    void copyPSNode(Optional<Node> psNodeOptional,
+    <D extends Datastore> void copyPSNode(Optional<Node> psNodeOptional,
                     InstanceIdentifier<Node> srcPsPath,
                     InstanceIdentifier<Node> dstPsPath,
                     InstanceIdentifier<Node> dstGlobalPath,
-                    LogicalDatastoreType logicalDatastoreType,
-                    ReadWriteTransaction tx) throws ReadFailedException;
+                    Class<D> datastoreType,
+                    TypedReadWriteTransaction<D> tx)
+        throws ExecutionException, InterruptedException;
 }
index 3c84463193e4531bba7343490dadc329a3cb3fa3..1efffc6f4f484b1098adc406887a5817438db47d 100644 (file)
@@ -7,17 +7,20 @@
  */
 package org.opendaylight.netvirt.elan.l2gw.ha.handlers;
 
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
+import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
 
 import com.google.common.base.Optional;
 import java.util.List;
+import java.util.concurrent.ExecutionException;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
 import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
 import org.opendaylight.netvirt.elan.l2gw.ha.listeners.HAJobScheduler;
 import org.opendaylight.netvirt.elan.l2gw.ha.merge.GlobalAugmentationMerger;
@@ -44,11 +47,11 @@ public class NodeConnectedHandler {
     private final PSAugmentationMerger psAugmentationMerger = PSAugmentationMerger.getInstance();
     private final GlobalNodeMerger globalNodeMerger = GlobalNodeMerger.getInstance();
     private final PSNodeMerger psNodeMerger = PSNodeMerger.getInstance();
-    private final DataBroker db;
+    private final ManagedNewTransactionRunner txRunner;
     private final HwvtepNodeHACache hwvtepNodeHACache;
 
     public NodeConnectedHandler(final DataBroker db, final HwvtepNodeHACache hwvtepNodeHACache) {
-        this.db = db;
+        this.txRunner = new ManagedNewTransactionRunnerImpl(db);
         this.hwvtepNodeHACache = hwvtepNodeHACache;
     }
 
@@ -65,20 +68,19 @@ public class NodeConnectedHandler {
      * @param haNodePath  Ha Iid
      * @param haGlobalCfg Ha Global Config Node
      * @param haPSCfg Ha Physical Config Node
-     * @param tx Transaction
-     * @throws ReadFailedException  Exception thrown if read fails
+     * @param operTx Transaction
      */
-    @SuppressWarnings("checkstyle:ForbidCertainMethod")
     public void handleNodeConnected(Node childNode,
                                     InstanceIdentifier<Node> childNodePath,
                                     InstanceIdentifier<Node> haNodePath,
                                     Optional<Node> haGlobalCfg,
                                     Optional<Node> haPSCfg,
-                                    ReadWriteTransaction tx)
-            throws ReadFailedException {
-        HwvtepHAUtil.buildGlobalConfigForHANode(tx, childNode, haNodePath, haGlobalCfg);
-        copyChildOpToHA(childNode, haNodePath, tx);
-        readAndCopyChildPSOpToHAPS(childNode, haNodePath, tx);
+                                    TypedReadWriteTransaction<Configuration> confTx,
+                                    TypedReadWriteTransaction<Operational> operTx)
+            throws ExecutionException, InterruptedException {
+        HwvtepHAUtil.buildGlobalConfigForHANode(confTx, childNode, haNodePath, haGlobalCfg);
+        copyChildOpToHA(childNode, haNodePath, operTx);
+        readAndCopyChildPSOpToHAPS(childNode, haNodePath, operTx);
         if (haGlobalCfg.isPresent()) {
             //copy ha config to newly connected child case of reconnected child
             if (haPSCfg.isPresent()) {
@@ -90,27 +92,25 @@ public class NodeConnectedHandler {
                  (created in the device)
                  */
                 HAJobScheduler.getInstance().submitJob(() -> {
-                    try {
-                        hwvtepNodeHACache.updateConnectedNodeStatus(childNodePath);
-                        LOG.info("HA child reconnected handleNodeReConnected {}",
+                    ListenableFutures.addErrorLogging(
+                        txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, jobTx -> {
+                            hwvtepNodeHACache.updateConnectedNodeStatus(childNodePath);
+                            LOG.info("HA child reconnected handleNodeReConnected {}",
                                 childNode.getNodeId().getValue());
-                        ReadWriteTransaction tx1 = db.newReadWriteTransaction();
-                        copyHAPSConfigToChildPS(haPSCfg.get(), childNodePath, tx1);
-                        tx1.submit().checkedGet();
-                    } catch (TransactionCommitFailedException e) {
-                        LOG.error("Failed to process ", e);
-                    }
+                            copyHAPSConfigToChildPS(haPSCfg.get(), childNodePath, jobTx);
+                        }), LOG, "Failed to process");
                 });
 
             }
-            copyHANodeConfigToChild(haGlobalCfg.get(), childNodePath, tx);
+            copyHANodeConfigToChild(haGlobalCfg.get(), childNodePath, confTx);
         }
-        deleteChildPSConfigIfHAPSConfigIsMissing(haGlobalCfg, childNode, tx);
+        deleteChildPSConfigIfHAPSConfigIsMissing(haGlobalCfg, childNode, confTx);
     }
 
     private void deleteChildPSConfigIfHAPSConfigIsMissing(Optional<Node> haPSCfg,
                                                           Node childNode,
-                                                          ReadWriteTransaction tx) throws ReadFailedException {
+                                                          TypedReadWriteTransaction<Configuration> tx)
+            throws ExecutionException, InterruptedException {
         if (haPSCfg.isPresent()) {
             return;
         }
@@ -120,7 +120,7 @@ public class NodeConnectedHandler {
             List<Switches> switches = augmentation.getSwitches();
             if (switches != null) {
                 for (Switches ps : switches) {
-                    HwvtepHAUtil.deleteNodeIfPresent(tx, CONFIGURATION, ps.getSwitchRef().getValue());
+                    HwvtepHAUtil.deleteNodeIfPresent(tx, ps.getSwitchRef().getValue());
                 }
             }
         } else {
@@ -134,12 +134,11 @@ public class NodeConnectedHandler {
      * @param childGlobalNode Ha Global Child node
      * @param haNodePath Ha node path
      * @param tx  Transaction
-     * @throws ReadFailedException  Exception thrown if read fails
      */
     void readAndCopyChildPSOpToHAPS(Node childGlobalNode,
                                     InstanceIdentifier<Node> haNodePath,
-                                    ReadWriteTransaction tx)
-            throws ReadFailedException {
+                                    TypedReadWriteTransaction<Operational> tx)
+            throws ExecutionException, InterruptedException {
 
         if (childGlobalNode == null || childGlobalNode.augmentation(HwvtepGlobalAugmentation.class) == null) {
             return;
@@ -149,8 +148,7 @@ public class NodeConnectedHandler {
             return;
         }
         for (Switches ps : switches) {
-            Node childPsNode = HwvtepHAUtil.readNode(tx, OPERATIONAL,
-                    (InstanceIdentifier<Node>) ps.getSwitchRef().getValue());
+            Node childPsNode = tx.read((InstanceIdentifier<Node>) ps.getSwitchRef().getValue()).get().orNull();
             if (childPsNode != null) {
                 InstanceIdentifier<Node> haPsPath = HwvtepHAUtil.convertPsPath(childPsNode, haNodePath);
                 copyChildPSOpToHAPS(childPsNode, haNodePath, haPsPath, tx);
@@ -167,7 +165,7 @@ public class NodeConnectedHandler {
      */
     private void copyHANodeConfigToChild(Node srcNode,
                                          InstanceIdentifier<Node> childPath,
-                                         ReadWriteTransaction tx) {
+                                         TypedReadWriteTransaction<Configuration> tx) {
         if (srcNode == null) {
             return;
         }
@@ -182,7 +180,7 @@ public class NodeConnectedHandler {
         globalNodeMerger.mergeConfigData(nodeBuilder, srcNode, childPath);
         nodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, dstBuilder.build());
         Node dstNode = nodeBuilder.build();
-        tx.put(CONFIGURATION, childPath, dstNode, WriteTransaction.CREATE_MISSING_PARENTS);
+        tx.put(childPath, dstNode, CREATE_MISSING_PARENTS);
     }
 
     /**
@@ -191,12 +189,11 @@ public class NodeConnectedHandler {
      * @param childNode HA Child Node
      * @param haNodePath HA node path
      * @param tx Transaction
-     * @throws ReadFailedException  Exception thrown if read fails
      */
     private void copyChildOpToHA(Node childNode,
                                  InstanceIdentifier<Node> haNodePath,
-                                 ReadWriteTransaction tx)
-            throws ReadFailedException {
+                                 TypedReadWriteTransaction<Operational> tx)
+            throws ExecutionException, InterruptedException {
         if (childNode == null) {
             return;
         }
@@ -207,7 +204,7 @@ public class NodeConnectedHandler {
         NodeBuilder haNodeBuilder = HwvtepHAUtil.getNodeBuilderForPath(haNodePath);
         HwvtepGlobalAugmentationBuilder haBuilder = new HwvtepGlobalAugmentationBuilder();
 
-        Optional<Node> existingHANodeOptional = tx.read(OPERATIONAL, haNodePath).checkedGet();
+        Optional<Node> existingHANodeOptional = tx.read(haNodePath).get();
         Node existingHANode = existingHANodeOptional.isPresent() ? existingHANodeOptional.get() : null;
         HwvtepGlobalAugmentation existingHAData = HwvtepHAUtil.getGlobalAugmentationOfNode(existingHANode);
 
@@ -219,7 +216,7 @@ public class NodeConnectedHandler {
         haBuilder.setDbVersion(childData.getDbVersion());
         haNodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, haBuilder.build());
         Node haNode = haNodeBuilder.build();
-        tx.merge(OPERATIONAL, haNodePath, haNode, true);
+        tx.merge(haNodePath, haNode, CREATE_MISSING_PARENTS);
     }
 
     /**
@@ -248,7 +245,7 @@ public class NodeConnectedHandler {
      */
     public void copyHAPSConfigToChildPS(Node haPsNode,
                                         InstanceIdentifier<Node> childPath,
-                                        ReadWriteTransaction tx) {
+                                        TypedReadWriteTransaction<Configuration> tx) {
         InstanceIdentifier<Node> childPsPath = HwvtepHAUtil.convertPsPath(haPsNode, childPath);
 
         NodeBuilder childPsBuilder = HwvtepHAUtil.getNodeBuilderForPath(childPsPath);
@@ -260,7 +257,7 @@ public class NodeConnectedHandler {
 
         childPsBuilder.addAugmentation(PhysicalSwitchAugmentation.class, dstBuilder.build());
         Node childPSNode = childPsBuilder.build();
-        tx.put(CONFIGURATION, childPsPath, childPSNode, WriteTransaction.CREATE_MISSING_PARENTS);
+        tx.put(childPsPath, childPSNode, CREATE_MISSING_PARENTS);
     }
 
     /**
@@ -270,20 +267,19 @@ public class NodeConnectedHandler {
      * @param haPath  HA node path
      * @param haPspath Ha Physical Switch Node path
      * @param tx Transaction
-     * @throws ReadFailedException  Exception thrown if read fails
      */
     public void copyChildPSOpToHAPS(Node childPsNode,
                                     InstanceIdentifier<Node> haPath,
                                     InstanceIdentifier<Node> haPspath,
-                                    ReadWriteTransaction tx)
-            throws ReadFailedException {
+                                    TypedReadWriteTransaction<Operational> tx)
+            throws ExecutionException, InterruptedException {
 
         NodeBuilder haPSNodeBuilder = HwvtepHAUtil.getNodeBuilderForPath(haPspath);
         PhysicalSwitchAugmentationBuilder dstBuilder = new PhysicalSwitchAugmentationBuilder();
 
         PhysicalSwitchAugmentation src = childPsNode.augmentation(PhysicalSwitchAugmentation.class);
 
-        Node existingHAPSNode = HwvtepHAUtil.readNode(tx, OPERATIONAL, haPspath);
+        Node existingHAPSNode = tx.read(haPspath).get().orNull();
         PhysicalSwitchAugmentation existingHAPSAugumentation =
                 HwvtepHAUtil.getPhysicalSwitchAugmentationOfNode(existingHAPSNode);
 
@@ -293,7 +289,7 @@ public class NodeConnectedHandler {
 
         haPSNodeBuilder.addAugmentation(PhysicalSwitchAugmentation.class, dstBuilder.build());
         Node haPsNode = haPSNodeBuilder.build();
-        tx.merge(OPERATIONAL, haPspath, haPsNode, true);
+        tx.merge(haPspath, haPsNode, CREATE_MISSING_PARENTS);
     }
 
 }
index 629b67a0818bb72918af7e97c4c39946be2c19c8..d03465597f28491c2f0cf35afc115862bafa7d42 100644 (file)
@@ -7,19 +7,24 @@
  */
 package org.opendaylight.netvirt.elan.l2gw.ha.handlers;
 
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
+import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
 
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.MoreExecutors;
+import java.util.concurrent.ExecutionException;
 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.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.netvirt.elan.l2gw.ha.BatchedTransaction;
+import org.opendaylight.genius.infra.Datastore;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
 import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
 import org.opendaylight.netvirt.elan.l2gw.ha.listeners.HAJobScheduler;
 import org.opendaylight.netvirt.elan.l2gw.ha.merge.GlobalAugmentationMerger;
@@ -47,66 +52,64 @@ public class NodeCopier implements INodeCopier {
     private final PSAugmentationMerger psAugmentationMerger = PSAugmentationMerger.getInstance();
     private final GlobalNodeMerger globalNodeMerger = GlobalNodeMerger.getInstance();
     private final PSNodeMerger psNodeMerger = PSNodeMerger.getInstance();
-    private final DataBroker db;
+    private final ManagedNewTransactionRunner txRunner;
 
     @Inject
     public NodeCopier(DataBroker db) {
-        this.db = db;
+        this.txRunner = new ManagedNewTransactionRunnerImpl(db);
     }
 
     @Override
-    public void copyGlobalNode(Optional<Node> srcGlobalNodeOptional,
+    public <D extends Datastore> void copyGlobalNode(Optional<Node> srcGlobalNodeOptional,
                                InstanceIdentifier<Node> srcPath,
                                InstanceIdentifier<Node> dstPath,
-                               LogicalDatastoreType logicalDatastoreType,
-                               ReadWriteTransaction tx) throws ReadFailedException {
-        if (!srcGlobalNodeOptional.isPresent() && logicalDatastoreType == CONFIGURATION) {
-            Futures.addCallback(tx.read(logicalDatastoreType, srcPath), new FutureCallback<Optional<Node>>() {
+                               Class<D> datastoreType,
+                               TypedReadWriteTransaction<D> tx)
+            throws ExecutionException, InterruptedException {
+        if (!srcGlobalNodeOptional.isPresent() && Configuration.class.equals(datastoreType)) {
+            Futures.addCallback(tx.read(srcPath), new FutureCallback<Optional<Node>>() {
                 @Override
                 public void onSuccess(Optional<Node> nodeOptional) {
-                    HAJobScheduler.getInstance().submitJob(() -> {
-                        try {
-                            ReadWriteTransaction tx1 = new BatchedTransaction();
+                    HAJobScheduler.getInstance().submitJob(() -> ListenableFutures.addErrorLogging(
+                        txRunner.callWithNewReadWriteTransactionAndSubmit(datastoreType, tx -> {
                             if (nodeOptional.isPresent()) {
-                                copyGlobalNode(nodeOptional, srcPath, dstPath, logicalDatastoreType, tx1);
+                                copyGlobalNode(nodeOptional, srcPath, dstPath, datastoreType, tx);
                             } else {
-                                /**
+                                /*
                                  * In case the Parent HA Global Node is not present and Child HA node is present
-                                 * It means that both the child are disconnected/removed hence the parent is deleted.
+                                 * It means that both the child are disconnected/removed hence the parent is
+                                 * deleted.
                                  * @see org.opendaylight.netvirt.elan.l2gw.ha.listeners.HAOpNodeListener
                                  * OnGLobalNode() delete function
                                  * So we should delete the existing config child node as cleanup
                                  */
-                                HwvtepHAUtil.deleteNodeIfPresent(tx1, logicalDatastoreType, dstPath);
+                                HwvtepHAUtil.deleteNodeIfPresent(tx, dstPath);
                             }
-                        } catch (ReadFailedException e) {
-                            LOG.error("Failed to read source node {}",srcPath);
-                        }
-                    });
+                        }), LOG, "Failed to read source node {}", srcPath));
                 }
 
                 @Override
                 public void onFailure(Throwable throwable) {
                 }
-            });
+            }, MoreExecutors.directExecutor());
             return;
         }
         HwvtepGlobalAugmentation srcGlobalAugmentation =
                 srcGlobalNodeOptional.get().augmentation(HwvtepGlobalAugmentation.class);
         if (srcGlobalAugmentation == null) {
-            /**
+            /*
              * If Source HA Global Node is not present
              * It means that both the child are disconnected/removed hence the parent is deleted.
              * @see org.opendaylight.netvirt.elan.l2gw.ha.listeners.HAOpNodeListener OnGLobalNode() delete function
              * So we should delete the existing config child node as cleanup
              */
-            HwvtepHAUtil.deleteNodeIfPresent(tx, logicalDatastoreType, dstPath);
+            HwvtepHAUtil.deleteNodeIfPresent(tx, dstPath);
             return;
         }
         NodeBuilder haNodeBuilder = HwvtepHAUtil.getNodeBuilderForPath(dstPath);
         HwvtepGlobalAugmentationBuilder haBuilder = new HwvtepGlobalAugmentationBuilder();
 
-        Optional<Node> existingDstGlobalNodeOptional = tx.read(logicalDatastoreType, dstPath).checkedGet();
+        Optional<Node> existingDstGlobalNodeOptional = tx.read(dstPath).get();
         Node existingDstGlobalNode =
                 existingDstGlobalNodeOptional.isPresent() ? existingDstGlobalNodeOptional.get() : null;
         HwvtepGlobalAugmentation existingHAGlobalData = HwvtepHAUtil.getGlobalAugmentationOfNode(existingDstGlobalNode);
@@ -116,53 +119,54 @@ public class NodeCopier implements INodeCopier {
                 existingDstGlobalNode, srcGlobalNodeOptional.get(), dstPath);
 
 
-        if (OPERATIONAL == logicalDatastoreType) {
+        if (Operational.class.equals(datastoreType)) {
             haBuilder.setManagers(HwvtepHAUtil.buildManagersForHANode(srcGlobalNodeOptional.get(),
                     existingDstGlobalNodeOptional));
             //Also update the manager section in config which helps in cluster reboot scenarios
-            haBuilder.getManagers().forEach((manager) -> {
-                InstanceIdentifier<Managers> managerIid = dstPath.augmentation(HwvtepGlobalAugmentation.class)
-                        .child(Managers.class, manager.key());
-                tx.put(CONFIGURATION, managerIid, manager, true);
-            });
+            ListenableFutures.addErrorLogging(
+                txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+                    confTx -> haBuilder.getManagers().forEach(manager -> {
+                        InstanceIdentifier<Managers> managerIid =
+                            dstPath.augmentation(HwvtepGlobalAugmentation.class).child(Managers.class, manager.key());
+                        confTx.put(managerIid, manager, CREATE_MISSING_PARENTS);
+                    })), LOG, "Error updating the manager section in config");
 
         }
         haBuilder.setDbVersion(srcGlobalAugmentation.getDbVersion());
         haNodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, haBuilder.build());
         Node haNode = haNodeBuilder.build();
-        if (OPERATIONAL == logicalDatastoreType) {
-            tx.merge(logicalDatastoreType, dstPath, haNode, true);
+        if (Operational.class.equals(datastoreType)) {
+            tx.merge(dstPath, haNode, CREATE_MISSING_PARENTS);
         } else {
-            tx.put(logicalDatastoreType, dstPath, haNode, true);
+            tx.put(dstPath, haNode, CREATE_MISSING_PARENTS);
         }
     }
 
     @Override
-    public void copyPSNode(Optional<Node> srcPsNodeOptional,
+    public <D extends Datastore> void copyPSNode(Optional<Node> srcPsNodeOptional,
                            InstanceIdentifier<Node> srcPsPath,
                            InstanceIdentifier<Node> dstPsPath,
                            InstanceIdentifier<Node> dstGlobalPath,
-                           LogicalDatastoreType logicalDatastoreType,
-                           ReadWriteTransaction tx) throws ReadFailedException {
-        if (!srcPsNodeOptional.isPresent() && logicalDatastoreType == CONFIGURATION) {
-            Futures.addCallback(tx.read(logicalDatastoreType, srcPsPath), new FutureCallback<Optional<Node>>() {
+                           Class<D> datastoreType,
+                           TypedReadWriteTransaction<D> tx)
+            throws ExecutionException, InterruptedException {
+        if (!srcPsNodeOptional.isPresent() && Configuration.class.equals(datastoreType)) {
+            Futures.addCallback(tx.read(srcPsPath), new FutureCallback<Optional<Node>>() {
                 @Override
                 public void onSuccess(Optional<Node> nodeOptional) {
                     HAJobScheduler.getInstance().submitJob(() -> {
-                        try {
-                            ReadWriteTransaction tx1 = new BatchedTransaction();
-                            if (nodeOptional.isPresent()) {
-                                copyPSNode(nodeOptional,
-                                        srcPsPath, dstPsPath, dstGlobalPath, logicalDatastoreType, tx1);
-                            } else {
-                                /**
-                                 * Deleting node please refer @see #copyGlobalNode for explanation
-                                 */
-                                HwvtepHAUtil.deleteNodeIfPresent(tx1, logicalDatastoreType, dstPsPath);
-                            }
-                        } catch (ReadFailedException e) {
-                            LOG.error("Failed to read src node {}", srcPsNodeOptional.get());
-                        }
+                        ListenableFutures.addErrorLogging(
+                            txRunner.callWithNewReadWriteTransactionAndSubmit(datastoreType, tx -> {
+                                if (nodeOptional.isPresent()) {
+                                    copyPSNode(nodeOptional,
+                                        srcPsPath, dstPsPath, dstGlobalPath, datastoreType, tx);
+                                } else {
+                                    /*
+                                     * Deleting node please refer @see #copyGlobalNode for explanation
+                                     */
+                                    HwvtepHAUtil.deleteNodeIfPresent(tx, dstPsPath);
+                                }
+                            }), LOG, "Failed to read source node {}", srcPsNodeOptional.get());
                     });
                 }
 
@@ -178,10 +182,10 @@ public class NodeCopier implements INodeCopier {
         PhysicalSwitchAugmentation srcPsAugmenatation =
                 srcPsNodeOptional.get().augmentation(PhysicalSwitchAugmentation.class);
 
-        Node existingDstPsNode = HwvtepHAUtil.readNode(tx, logicalDatastoreType, dstPsPath);
+        Node existingDstPsNode = tx.read(dstPsPath).get().orNull();
         PhysicalSwitchAugmentation existingDstPsAugmentation =
                 HwvtepHAUtil.getPhysicalSwitchAugmentationOfNode(existingDstPsNode);
-        if (OPERATIONAL == logicalDatastoreType) {
+        if (Operational.class.equals(datastoreType)) {
             psAugmentationMerger.mergeOperationalData(dstPsAugmentationBuilder, existingDstPsAugmentation,
                     srcPsAugmenatation, dstPsPath);
             psNodeMerger.mergeOperationalData(dstPsNodeBuilder, existingDstPsNode, srcPsNodeOptional.get(), dstPsPath);
@@ -193,8 +197,8 @@ public class NodeCopier implements INodeCopier {
 
         dstPsNodeBuilder.addAugmentation(PhysicalSwitchAugmentation.class, dstPsAugmentationBuilder.build());
         Node dstPsNode = dstPsNodeBuilder.build();
-        tx.merge(logicalDatastoreType, dstPsPath, dstPsNode, true);
-        LOG.debug("Copied {} physical switch node from {} to {}", logicalDatastoreType, srcPsPath, dstPsPath);
+        tx.merge(dstPsPath, dstPsNode, CREATE_MISSING_PARENTS);
+        LOG.debug("Copied {} physical switch node from {} to {}", datastoreType, srcPsPath, dstPsPath);
     }
 
     public void mergeOpManagedByAttributes(PhysicalSwitchAugmentation psAugmentation,
index 2c215f49f3afe7dfea750fb5bd431ea63970eca6..ff718b5af77a0297f5e28245cdd608f719696420 100644 (file)
@@ -8,7 +8,8 @@
 package org.opendaylight.netvirt.elan.l2gw.ha.handlers;
 
 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
 import org.opendaylight.netvirt.elan.l2gw.ha.merge.GlobalAugmentationMerger;
 import org.opendaylight.netvirt.elan.l2gw.ha.merge.GlobalNodeMerger;
@@ -37,7 +38,7 @@ public class OpNodeUpdatedHandler {
     public void copyChildPsOpUpdateToHAParent(Node updatedSrcPSNode,
                                               InstanceIdentifier<Node> haPath,
                                               DataObjectModification<Node> mod,
-                                              ReadWriteTransaction tx) {
+                                              TypedReadWriteTransaction<Operational> tx) {
 
         InstanceIdentifier<Node> haPSPath = HwvtepHAUtil.convertPsPath(updatedSrcPSNode, haPath);
 
@@ -55,7 +56,7 @@ public class OpNodeUpdatedHandler {
      */
     public void copyChildGlobalOpUpdateToHAParent(InstanceIdentifier<Node> haPath,
                                                   DataObjectModification<Node> mod,
-                                                  ReadWriteTransaction tx) {
+                                                  TypedReadWriteTransaction<Operational> tx) {
 
         globalAugmentationMerger.mergeOpUpdate(haPath,
                 mod.getModifiedAugmentation(HwvtepGlobalAugmentation.class), tx);
index 7f0e01b2d65792e4fa50eb228c05b1bff300c299..8a491b97c58341caee0185c1b65e25fb2bad0433 100644 (file)
@@ -7,19 +7,19 @@
  */
 package org.opendaylight.netvirt.elan.l2gw.ha.listeners;
 
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
 
 import com.google.common.base.Optional;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.concurrent.ExecutionException;
 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.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
 import org.opendaylight.infrautils.metrics.MetricProvider;
 import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
@@ -32,7 +32,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Singleton
-public class HAConfigNodeListener extends HwvtepNodeBaseListener {
+public class HAConfigNodeListener extends HwvtepNodeBaseListener<Configuration> {
 
     private static final Logger LOG = LoggerFactory.getLogger(HAConfigNodeListener.class);
 
@@ -43,7 +43,7 @@ public class HAConfigNodeListener extends HwvtepNodeBaseListener {
     public HAConfigNodeListener(DataBroker db, HAEventHandler haEventHandler,
                                 NodeCopier nodeCopier, HwvtepNodeHACache hwvtepNodeHACache,
                                 MetricProvider metricProvider) throws Exception {
-        super(LogicalDatastoreType.CONFIGURATION, db, hwvtepNodeHACache, metricProvider, true);
+        super(CONFIGURATION, db, hwvtepNodeHACache, metricProvider, true);
         this.haEventHandler = haEventHandler;
         this.nodeCopier = nodeCopier;
     }
@@ -51,7 +51,8 @@ public class HAConfigNodeListener extends HwvtepNodeBaseListener {
     @Override
     void onPsNodeAdd(InstanceIdentifier<Node> haPsPath,
                      Node haPSNode,
-                     ReadWriteTransaction tx) throws ReadFailedException {
+                     TypedReadWriteTransaction<Configuration> tx)
+             throws ExecutionException, InterruptedException {
         //copy the ps node data to children
         String psId = haPSNode.getNodeId().getValue();
         Set<InstanceIdentifier<Node>> childSwitchIds = getPSChildrenIdsForHAPSNode(psId);
@@ -64,7 +65,7 @@ public class HAConfigNodeListener extends HwvtepNodeBaseListener {
                     HwvtepHAUtil.convertToGlobalNodeId(childPsPath.firstKeyOf(Node.class).getNodeId().getValue());
             InstanceIdentifier<Node> childGlobalPath = HwvtepHAUtil.convertToInstanceIdentifier(nodeId);
             nodeCopier.copyPSNode(Optional.fromNullable(haPSNode), haPsPath, childPsPath, childGlobalPath,
-                    LogicalDatastoreType.CONFIGURATION, tx);
+                    CONFIGURATION, tx);
         }
         LOG.trace("Handle config ps node add {}", psId);
     }
@@ -73,7 +74,7 @@ public class HAConfigNodeListener extends HwvtepNodeBaseListener {
     void onPsNodeUpdate(Node haPSUpdated,
             Node haPSOriginal,
             DataObjectModification<Node> mod,
-            ReadWriteTransaction tx) {
+            TypedReadWriteTransaction<Configuration> tx) {
         //copy the ps node data to children
         String psId = haPSUpdated.getNodeId().getValue();
         Set<InstanceIdentifier<Node>> childSwitchIds = getPSChildrenIdsForHAPSNode(psId);
@@ -87,7 +88,7 @@ public class HAConfigNodeListener extends HwvtepNodeBaseListener {
                             Node haUpdated,
                             Node haOriginal,
                             DataObjectModification<Node> mod,
-                            ReadWriteTransaction tx) {
+                            TypedReadWriteTransaction<Configuration> tx) {
         Set<InstanceIdentifier<Node>> childNodeIds = getHwvtepNodeHACache().getChildrenForHANode(key);
         for (InstanceIdentifier<Node> haChildNodeId : childNodeIds) {
             haEventHandler.copyHAGlobalUpdateToChild(haChildNodeId, mod, tx);
@@ -97,24 +98,25 @@ public class HAConfigNodeListener extends HwvtepNodeBaseListener {
     @Override
     void onPsNodeDelete(InstanceIdentifier<Node> key,
                         Node deletedPsNode,
-                        ReadWriteTransaction tx) throws ReadFailedException {
+                        TypedReadWriteTransaction<Configuration> tx)
+            throws ExecutionException, InterruptedException {
         //delete ps children nodes
         String psId = deletedPsNode.getNodeId().getValue();
         Set<InstanceIdentifier<Node>> childPsIds = getPSChildrenIdsForHAPSNode(psId);
         for (InstanceIdentifier<Node> childPsId : childPsIds) {
-            HwvtepHAUtil.deleteNodeIfPresent(tx, CONFIGURATION, childPsId);
+            HwvtepHAUtil.deleteNodeIfPresent(tx, childPsId);
         }
     }
 
     @Override
     void onGlobalNodeDelete(InstanceIdentifier<Node> key,
                             Node haNode,
-                            ReadWriteTransaction tx)
-            throws ReadFailedException {
+                            TypedReadWriteTransaction<Configuration> tx)
+            throws ExecutionException, InterruptedException {
         //delete child nodes
         Set<InstanceIdentifier<Node>> children = getHwvtepNodeHACache().getChildrenForHANode(key);
         for (InstanceIdentifier<Node> childId : children) {
-            HwvtepHAUtil.deleteNodeIfPresent(tx, CONFIGURATION, childId);
+            HwvtepHAUtil.deleteNodeIfPresent(tx, childId);
         }
         HwvtepHAUtil.deletePSNodesOfNode(key, haNode, tx);
     }
index c8ba9206c32f6a59b556aad8b5ba3d7e5956cc09..ee16a55f3be605e719b785c6d9ce191ade01166a 100644 (file)
@@ -7,13 +7,16 @@
  */
 package org.opendaylight.netvirt.elan.l2gw.ha.listeners;
 
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
+
 import java.util.ArrayList;
 import java.util.List;
 import javax.annotation.PreDestroy;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.infra.Datastore;
 import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
 import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
 import org.opendaylight.netvirt.elan.l2gw.ha.commands.LocalMcastCmd;
@@ -47,7 +50,7 @@ public class HAListeners implements AutoCloseable {
             .child(Node.class).child(TerminationPoint.class);
 
     private final DataBroker broker;
-    private final List<HwvtepNodeDataListener<?>> listeners = new ArrayList<>();
+    private final List<HwvtepNodeDataListener<?, ?>> listeners = new ArrayList<>();
 
     @Inject
     public HAListeners(DataBroker broker, HwvtepNodeHACache hwvtepNodeHACache) {
@@ -59,10 +62,8 @@ public class HAListeners implements AutoCloseable {
         registerListener(LogicalSwitches.class, new LogicalSwitchesCmd(), hwvtepNodeHACache);
 
         PhysicalLocatorCmd physicalLocatorCmd = new PhysicalLocatorCmd();
-        listeners.add(new PhysicalLocatorListener(broker, hwvtepNodeHACache, physicalLocatorCmd,
-                LogicalDatastoreType.CONFIGURATION));
-        listeners.add(new PhysicalLocatorListener(broker, hwvtepNodeHACache, physicalLocatorCmd,
-                LogicalDatastoreType.OPERATIONAL));
+        listeners.add(new PhysicalLocatorListener(broker, hwvtepNodeHACache, physicalLocatorCmd, CONFIGURATION));
+        listeners.add(new PhysicalLocatorListener(broker, hwvtepNodeHACache, physicalLocatorCmd, OPERATIONAL));
     }
 
     @Override
@@ -76,18 +77,18 @@ public class HAListeners implements AutoCloseable {
     private <T extends ChildOf<HwvtepGlobalAttributes>> void registerListener(Class<T> clazz,
             MergeCommand<T, ?, ?> mergeCommand, HwvtepNodeHACache hwvtepNodeHACache) {
         listeners.add(new GlobalAugmentationListener(broker, hwvtepNodeHACache, clazz, HwvtepNodeDataListener.class,
-                mergeCommand, LogicalDatastoreType.CONFIGURATION));
+                mergeCommand, CONFIGURATION));
         listeners.add(new GlobalAugmentationListener(broker, hwvtepNodeHACache, clazz, HwvtepNodeDataListener.class,
-                mergeCommand, LogicalDatastoreType.OPERATIONAL));
+                mergeCommand, OPERATIONAL));
     }
 
-    private static class GlobalAugmentationListener<T extends DataObject
-            & ChildOf<HwvtepGlobalAttributes>> extends HwvtepNodeDataListener<T> {
+    private static class GlobalAugmentationListener<D extends Datastore, T extends DataObject
+            & ChildOf<HwvtepGlobalAttributes>> extends HwvtepNodeDataListener<D, T> {
 
         GlobalAugmentationListener(DataBroker broker, HwvtepNodeHACache hwvtepNodeHACache,
-                                   Class<T> clazz, Class<HwvtepNodeDataListener<T>> eventClazz,
+                                   Class<T> clazz, Class<HwvtepNodeDataListener<D, T>> eventClazz,
                                    MergeCommand<T, ?, ?> mergeCommand,
-                                   LogicalDatastoreType datastoreType) {
+                                   Class<D> datastoreType) {
             super(broker, hwvtepNodeHACache, clazz, eventClazz, mergeCommand, datastoreType);
         }
 
@@ -99,10 +100,11 @@ public class HAListeners implements AutoCloseable {
         }
     }
 
-    private static class PhysicalLocatorListener extends HwvtepNodeDataListener<TerminationPoint> {
+    private static class PhysicalLocatorListener<D extends Datastore>
+            extends HwvtepNodeDataListener<D, TerminationPoint> {
 
         PhysicalLocatorListener(DataBroker broker, HwvtepNodeHACache hwvtepNodeHACache,
-                MergeCommand<TerminationPoint, ?, ?> mergeCommand, LogicalDatastoreType datastoreType) {
+                MergeCommand<TerminationPoint, ?, ?> mergeCommand, Class<D> datastoreType) {
             super(broker, hwvtepNodeHACache, TerminationPoint.class, (Class)PhysicalLocatorListener.class,
                     mergeCommand, datastoreType);
         }
index 73b77204155577476e931b07ceaa7c3b2972c567..c11a4ddc6dede1fcc139499304e114373bf5a98c 100644 (file)
@@ -7,12 +7,15 @@
  */
 package org.opendaylight.netvirt.elan.l2gw.ha.listeners;
 
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
+
 import com.google.common.base.Optional;
 import com.google.common.collect.Sets;
 import java.util.Collections;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
 import javax.inject.Inject;
@@ -21,9 +24,10 @@ import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeLis
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
 import org.opendaylight.infrautils.metrics.MetricProvider;
 import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
@@ -33,7 +37,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Singleton
-public class HAOpClusteredListener extends HwvtepNodeBaseListener implements ClusteredDataTreeChangeListener<Node> {
+public class HAOpClusteredListener extends HwvtepNodeBaseListener<Operational>
+        implements ClusteredDataTreeChangeListener<Node> {
     private static final Logger LOG = LoggerFactory.getLogger(HAOpClusteredListener.class);
 
     private final Set<InstanceIdentifier<Node>> connectedNodes = ConcurrentHashMap.newKeySet();
@@ -42,7 +47,7 @@ public class HAOpClusteredListener extends HwvtepNodeBaseListener implements Clu
     @Inject
     public HAOpClusteredListener(DataBroker db, HwvtepNodeHACache hwvtepNodeHACache,
                                  MetricProvider metricProvider) throws Exception {
-        super(LogicalDatastoreType.OPERATIONAL, db, hwvtepNodeHACache, metricProvider, false);
+        super(OPERATIONAL, db, hwvtepNodeHACache, metricProvider, false);
         LOG.info("Registering HAOpClusteredListener");
     }
 
@@ -51,32 +56,34 @@ public class HAOpClusteredListener extends HwvtepNodeBaseListener implements Clu
     }
 
     @Override
-    synchronized  void onGlobalNodeDelete(InstanceIdentifier<Node> key, Node added, ReadWriteTransaction tx)  {
+    synchronized  void onGlobalNodeDelete(InstanceIdentifier<Node> key, Node added,
+            TypedReadWriteTransaction<Operational> tx)  {
         connectedNodes.remove(key);
         getHwvtepNodeHACache().updateDisconnectedNodeStatus(key);
     }
 
     @Override
-    void onPsNodeDelete(InstanceIdentifier<Node> key, Node addedPSNode, ReadWriteTransaction tx)  {
+    void onPsNodeDelete(InstanceIdentifier<Node> key, Node addedPSNode, TypedReadWriteTransaction<Operational> tx)  {
         connectedNodes.remove(key);
         getHwvtepNodeHACache().updateDisconnectedNodeStatus(key);
     }
 
     @Override
-    void onPsNodeAdd(InstanceIdentifier<Node> key, Node addedPSNode, ReadWriteTransaction tx)    {
+    void onPsNodeAdd(InstanceIdentifier<Node> key, Node addedPSNode, TypedReadWriteTransaction<Operational> tx)    {
         connectedNodes.add(key);
         getHwvtepNodeHACache().updateConnectedNodeStatus(key);
     }
 
     @Override
-    public synchronized void onGlobalNodeAdd(InstanceIdentifier<Node> key, Node updated, ReadWriteTransaction tx) {
+    public synchronized void onGlobalNodeAdd(InstanceIdentifier<Node> key, Node updated,
+            TypedReadWriteTransaction<Operational> tx) {
         connectedNodes. add(key);
         HwvtepHAUtil.addToCacheIfHAChildNode(key, updated, getHwvtepNodeHACache());
         getHwvtepNodeHACache().updateConnectedNodeStatus(key);
         if (waitingJobs.containsKey(key) && !waitingJobs.get(key).isEmpty()) {
             try {
                 HAJobScheduler jobScheduler = HAJobScheduler.getInstance();
-                Optional<Node> nodeOptional = tx.read(LogicalDatastoreType.OPERATIONAL, key).checkedGet();
+                Optional<Node> nodeOptional = tx.read(key).get();
                 if (nodeOptional.isPresent()) {
                     waitingJobs.get(key).forEach(
                         (waitingJob) -> jobScheduler.submitJob(() -> waitingJob.accept(nodeOptional)));
@@ -84,7 +91,7 @@ public class HAOpClusteredListener extends HwvtepNodeBaseListener implements Clu
                 } else {
                     LOG.error("Failed to read oper node {}", key);
                 }
-            } catch (ReadFailedException e) {
+            } catch (InterruptedException | ExecutionException e) {
                 LOG.error("Failed to read oper node {}", key);
             }
         }
@@ -95,7 +102,7 @@ public class HAOpClusteredListener extends HwvtepNodeBaseListener implements Clu
                             Node updatedChildNode,
                             Node beforeChildNode,
                             DataObjectModification<Node> mod,
-                            ReadWriteTransaction tx) {
+                            TypedReadWriteTransaction<Operational> tx) {
         boolean wasHAChild = getHwvtepNodeHACache().isHAEnabledDevice(childPath);
         addToHACacheIfBecameHAChild(childPath, updatedChildNode, beforeChildNode);
         boolean isHAChild = getHwvtepNodeHACache().isHAEnabledDevice(childPath);
index bd10bbfce9465c7d8e390c578a459e81f224fa37..49ef723ebf59c78e647159591642f2fcff50b8c6 100644 (file)
@@ -7,24 +7,27 @@
  */
 package org.opendaylight.netvirt.elan.l2gw.ha.listeners;
 
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Strings;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.ExecutionException;
 import java.util.function.BiPredicate;
 import java.util.stream.Collectors;
 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.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
 import org.opendaylight.infrautils.metrics.MetricProvider;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
 import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
 import org.opendaylight.netvirt.elan.l2gw.ha.handlers.HAEventHandler;
 import org.opendaylight.netvirt.elan.l2gw.ha.handlers.IHAEventHandler;
@@ -36,14 +39,15 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Singleton
-public class HAOpNodeListener extends HwvtepNodeBaseListener {
+public class HAOpNodeListener extends HwvtepNodeBaseListener<Operational> {
 
     private static final Logger LOG = LoggerFactory.getLogger(HAOpNodeListener.class);
 
-    static BiPredicate<String, InstanceIdentifier<Node>> IS_PS_CHILD_TO_GLOBAL_NODE = (globalNodeId, iid) -> {
-        String psNodeId = iid.firstKeyOf(Node.class).getNodeId().getValue();
-        return psNodeId.startsWith(globalNodeId) && psNodeId.contains("physicalswitch");
-    };
+    private static final BiPredicate<String, InstanceIdentifier<Node>> IS_PS_CHILD_TO_GLOBAL_NODE =
+        (globalNodeId, iid) -> {
+            String psNodeId = iid.firstKeyOf(Node.class).getNodeId().getValue();
+            return psNodeId.startsWith(globalNodeId) && psNodeId.contains("physicalswitch");
+        };
 
     private final IHAEventHandler haEventHandler;
     private final HAOpClusteredListener haOpClusteredListener;
@@ -67,7 +71,7 @@ public class HAOpNodeListener extends HwvtepNodeBaseListener {
     @Override
     public void onGlobalNodeAdd(InstanceIdentifier<Node> childGlobalPath,
                                 Node childNode,
-                                ReadWriteTransaction tx) {
+                                TypedReadWriteTransaction<Operational> tx) {
         //copy child global node to ha global node
         //create ha global config node if not present
         //copy ha global config node to child global config node
@@ -79,11 +83,11 @@ public class HAOpNodeListener extends HwvtepNodeBaseListener {
         InstanceIdentifier<Node> haNodePath = getHwvtepNodeHACache().getParent(childGlobalPath);
         LOG.trace("Ha enabled child node connected {}", childNode.getNodeId().getValue());
         try {
-            nodeCopier.copyGlobalNode(Optional.fromNullable(childNode),
-                    childGlobalPath, haNodePath, LogicalDatastoreType.OPERATIONAL, tx);
-            nodeCopier.copyGlobalNode(Optional.fromNullable(null),
-                    haNodePath, childGlobalPath, LogicalDatastoreType.CONFIGURATION, tx);
-        } catch (ReadFailedException e) {
+            nodeCopier.copyGlobalNode(Optional.fromNullable(childNode), childGlobalPath, haNodePath, OPERATIONAL, tx);
+            ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+                confTx -> nodeCopier.copyGlobalNode(Optional.fromNullable(null), haNodePath, childGlobalPath,
+                    CONFIGURATION, confTx)), LOG, "Error copying to configuration");
+        } catch (InterruptedException | ExecutionException e) {
             LOG.error("Failed to read nodes {} , {} ", childGlobalPath, haNodePath);
         }
         readAndCopyChildPsOpToParent(childNode, tx);
@@ -95,7 +99,7 @@ public class HAOpNodeListener extends HwvtepNodeBaseListener {
                             Node updatedChildNode,
                             Node originalChildNode,
                             DataObjectModification<Node> mod,
-                            ReadWriteTransaction tx) {
+                            TypedReadWriteTransaction<Operational> tx) throws ReadFailedException {
 
         String oldHAId = HwvtepHAUtil.getHAIdFromManagerOtherConfig(originalChildNode);
         if (!Strings.isNullOrEmpty(oldHAId)) { //was already ha child
@@ -116,8 +120,8 @@ public class HAOpNodeListener extends HwvtepNodeBaseListener {
     @Override
     void onGlobalNodeDelete(InstanceIdentifier<Node> childGlobalPath,
                             Node childNode,
-                            ReadWriteTransaction tx) throws
-            ReadFailedException {
+                            TypedReadWriteTransaction<Operational> tx)
+            throws ExecutionException, InterruptedException {
         haOpClusteredListener.onGlobalNodeDelete(childGlobalPath, childNode, tx);
         if (isNotHAChild(childGlobalPath)) {
             LOG.info("non ha child global delete {} ", getNodeId(childGlobalPath));
@@ -130,7 +134,7 @@ public class HAOpNodeListener extends HwvtepNodeBaseListener {
             LOG.info("All child deleted for ha node {} ", HwvtepHAUtil.getNodeIdVal(haNodePath));
             //ha ps delete is taken care by ps node delete
             //HwvtepHAUtil.deleteSwitchesManagedBy-Node(haNodePath, tx);
-            HwvtepHAUtil.deleteNodeIfPresent(tx, OPERATIONAL, haNodePath);
+            HwvtepHAUtil.deleteNodeIfPresent(tx, haNodePath);
         } else {
             LOG.info("not all child deleted {} connected {}", getNodeId(childGlobalPath),
                     haOpClusteredListener.getConnected(children));
@@ -140,7 +144,7 @@ public class HAOpNodeListener extends HwvtepNodeBaseListener {
     @Override
     void onPsNodeAdd(InstanceIdentifier<Node> childPsPath,
                      Node childPsNode,
-                     ReadWriteTransaction tx) {
+                     TypedReadWriteTransaction<Operational> tx) {
         //copy child ps oper node to ha ps oper node
         //copy ha ps config node to child ps config
         haOpClusteredListener.onPsNodeAdd(childPsPath, childPsNode, tx);
@@ -156,10 +160,11 @@ public class HAOpNodeListener extends HwvtepNodeBaseListener {
         InstanceIdentifier<Node> haPsPath = HwvtepHAUtil.convertPsPath(childPsNode, haGlobalPath);
         try {
             nodeCopier.copyPSNode(Optional.fromNullable(childPsNode), childPsPath, haPsPath, haGlobalPath,
-                    LogicalDatastoreType.OPERATIONAL, tx);
-            nodeCopier.copyPSNode(Optional.fromNullable(null), haPsPath, childPsPath, childGlobalPath,
-                    LogicalDatastoreType.CONFIGURATION, tx);
-        } catch (ReadFailedException e) {
+                    OPERATIONAL, tx);
+            ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+                confTx -> nodeCopier.copyPSNode(Optional.fromNullable(null), haPsPath, childPsPath, childGlobalPath,
+                    CONFIGURATION, confTx)), LOG, "Error copying to configuration");
+        } catch (InterruptedException | ExecutionException e) {
             LOG.error("Failed to read nodes {} , {} ", childPsPath, haGlobalPath);
         }
     }
@@ -168,7 +173,7 @@ public class HAOpNodeListener extends HwvtepNodeBaseListener {
     void onPsNodeUpdate(Node updatedChildPSNode,
             Node originalChildPSNode,
             DataObjectModification<Node> mod,
-            ReadWriteTransaction tx) {
+            TypedReadWriteTransaction<Operational> tx) {
         InstanceIdentifier<Node> childGlobalPath = HwvtepHAUtil.getGlobalNodePathFromPSNode(updatedChildPSNode);
         if (isNotHAChild(childGlobalPath)) {
             return;
@@ -180,7 +185,8 @@ public class HAOpNodeListener extends HwvtepNodeBaseListener {
     @Override
     void onPsNodeDelete(InstanceIdentifier<Node> childPsPath,
                         Node childPsNode,
-                        ReadWriteTransaction tx) throws ReadFailedException {
+                        TypedReadWriteTransaction<Operational> tx)
+            throws ExecutionException, InterruptedException {
         //one child ps node disconnected
         //find if all child ps nodes disconnected then delete parent ps node
         haOpClusteredListener.onPsNodeDelete(childPsPath, childPsNode, tx);
@@ -197,7 +203,7 @@ public class HAOpNodeListener extends HwvtepNodeBaseListener {
         if (haOpClusteredListener.getConnected(childPsPaths).isEmpty()) {
             InstanceIdentifier<Node> haPsPath = HwvtepHAUtil.convertPsPath(childPsNode, haGlobalPath);
             LOG.info("All child deleted for ha ps node {} ", HwvtepHAUtil.getNodeIdVal(haPsPath));
-            HwvtepHAUtil.deleteNodeIfPresent(tx, LogicalDatastoreType.OPERATIONAL, haPsPath);
+            HwvtepHAUtil.deleteNodeIfPresent(tx, haPsPath);
             //HwvtepHAUtil.deleteGlobalNodeSwitches(haGlobalPath, haPsPath, LogicalDatastoreType.OPERATIONAL, tx);
         } else {
             LOG.info("not all ha ps child deleted {} connected {}", getNodeId(childPsPath),
@@ -205,7 +211,7 @@ public class HAOpNodeListener extends HwvtepNodeBaseListener {
         }
     }
 
-    private void readAndCopyChildPsOpToParent(Node childNode, ReadWriteTransaction tx) {
+    private void readAndCopyChildPsOpToParent(Node childNode, TypedReadWriteTransaction<Operational> tx) {
         String childGlobalNodeId = childNode.getNodeId().getValue();
         List<InstanceIdentifier> childPsIids = new ArrayList<>();
         HwvtepGlobalAugmentation hwvtepGlobalAugmentation = childNode.augmentation(HwvtepGlobalAugmentation.class);
@@ -224,14 +230,14 @@ public class HAOpNodeListener extends HwvtepNodeBaseListener {
         childPsIids.forEach((psIid) -> {
             try {
                 InstanceIdentifier<Node> childPsIid = psIid;
-                Optional<Node> childPsNode = tx.read(LogicalDatastoreType.OPERATIONAL, childPsIid).checkedGet();
+                Optional<Node> childPsNode = tx.read(childPsIid).get();
                 if (childPsNode.isPresent()) {
                     LOG.debug("Child oper PS node found");
                     onPsNodeAdd(childPsIid, childPsNode.get(), tx);
                 } else {
                     LOG.debug("Child oper ps node not found {}", childPsIid);
                 }
-            } catch (ReadFailedException e) {
+            } catch (InterruptedException | ExecutionException e) {
                 LOG.error("Failed to read child ps node {}", psIid);
             }
         });
index 58f87b03e8e7264fb172acf940c92dbd17b83ff0..3c6ed7b857f9b706682d4e69aed921fcccf944ed 100644 (file)
@@ -18,17 +18,19 @@ import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.genius.datastoreutils.TaskRetryLooper;
+import org.opendaylight.genius.infra.Datastore;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
 import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
 import org.opendaylight.infrautils.metrics.Labeled;
 import org.opendaylight.infrautils.metrics.Meter;
 import org.opendaylight.infrautils.metrics.MetricDescriptor;
 import org.opendaylight.infrautils.metrics.MetricProvider;
-import org.opendaylight.netvirt.elan.l2gw.ha.BatchedTransaction;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
 import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
@@ -46,7 +48,8 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public abstract class HwvtepNodeBaseListener implements DataTreeChangeListener<Node>, AutoCloseable {
+public abstract class HwvtepNodeBaseListener<D extends Datastore>
+    implements DataTreeChangeListener<Node>, AutoCloseable {
 
     private static final Logger LOG = LoggerFactory.getLogger(HwvtepNodeBaseListener.class);
     private static final int STARTUP_LOOP_TICK = 500;
@@ -54,35 +57,31 @@ public abstract class HwvtepNodeBaseListener implements DataTreeChangeListener<N
 
     private final ListenerRegistration<HwvtepNodeBaseListener> registration;
     private final DataBroker dataBroker;
+    final ManagedNewTransactionRunner txRunner;
     private final HwvtepNodeHACache hwvtepNodeHACache;
-    private final MetricProvider metricProvider;
-    private final LogicalDatastoreType datastoreType;
+    private final Class<D> datastoreType;
     private final Function<DataObject, String> noLogicalSwitch = (data) -> "No_Ls";
 
     private final Labeled<Labeled<Labeled<Labeled<Labeled<Meter>>>>> childModCounter;
     private final Labeled<Labeled<Labeled<Meter>>> nodeModCounter;
     private final boolean updateMetrics;
 
-    ImmutableMap<Class, Function<DataObject, String>> logicalSwitchExtractor =
-            new ImmutableMap.Builder<Class, Function<DataObject, String>>()
-                    .put(LogicalSwitches.class, data -> ((LogicalSwitches) data).getHwvtepNodeName().getValue())
-                    .put(RemoteMcastMacs.class, data -> {
-                        return logicalSwitchNameFromIid(((RemoteMcastMacs) data).key().getLogicalSwitchRef()
-                                .getValue());
-                    })
-                    .put(RemoteUcastMacs.class, data -> {
-                        return logicalSwitchNameFromIid(((RemoteUcastMacs) data).key().getLogicalSwitchRef()
-                                .getValue());
-                    }).build();
+    private static final ImmutableMap<Class, Function<DataObject, String>> LOGICAL_SWITCH_EXTRACTOR =
+        new ImmutableMap.Builder<Class, Function<DataObject, String>>()
+            .put(LogicalSwitches.class, data -> ((LogicalSwitches) data).getHwvtepNodeName().getValue())
+            .put(RemoteMcastMacs.class,
+                data -> logicalSwitchNameFromIid(((RemoteMcastMacs) data).key().getLogicalSwitchRef().getValue()))
+            .put(RemoteUcastMacs.class, data -> logicalSwitchNameFromIid(
+                ((RemoteUcastMacs) data).key().getLogicalSwitchRef().getValue())).build();
 
 
-    public HwvtepNodeBaseListener(LogicalDatastoreType datastoreType, DataBroker dataBroker,
+    public HwvtepNodeBaseListener(Class<D> datastoreType, DataBroker dataBroker,
                                   HwvtepNodeHACache hwvtepNodeHACache, MetricProvider metricProvider,
                                   boolean updateMetrics) throws Exception {
         this.dataBroker = dataBroker;
+        this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
         this.datastoreType = datastoreType;
         this.hwvtepNodeHACache = hwvtepNodeHACache;
-        this.metricProvider = metricProvider;
         this.updateMetrics = updateMetrics;
         this.childModCounter = metricProvider.newMeter(
                 MetricDescriptor.builder().anchor(this).project("netvirt").module("l2gw").id("child").build(),
@@ -90,7 +89,8 @@ public abstract class HwvtepNodeBaseListener implements DataTreeChangeListener<N
         this.nodeModCounter = metricProvider.newMeter(
                 MetricDescriptor.builder().anchor(this).project("netvirt").module("l2gw").id("node").build(),
                 "datastore", "modification", "nodeid");
-        final DataTreeIdentifier<Node> treeId = new DataTreeIdentifier<>(datastoreType, getWildcardPath());
+        final DataTreeIdentifier<Node> treeId =
+            new DataTreeIdentifier<>(Datastore.toType(datastoreType), getWildcardPath());
         TaskRetryLooper looper = new TaskRetryLooper(STARTUP_LOOP_TICK, STARTUP_LOOP_MAX_RETRIES);
         registration = looper.loopUntilNoException(() ->
                 dataBroker.registerDataTreeChangeListener(treeId, HwvtepNodeBaseListener.this));
@@ -139,21 +139,17 @@ public abstract class HwvtepNodeBaseListener implements DataTreeChangeListener<N
 
     @Override
     public void onDataTreeChanged(final Collection<DataTreeModification<Node>> changes) {
-        HAJobScheduler.getInstance().submitJob(() -> {
-            ReadWriteTransaction tx = getTx();
-            try {
+        HAJobScheduler.getInstance().submitJob(() -> ListenableFutures.addErrorLogging(
+            txRunner.callWithNewReadWriteTransactionAndSubmit(datastoreType, tx -> {
                 processConnectedNodes(changes, tx);
                 processUpdatedNodes(changes, tx);
                 processDisconnectedNodes(changes, tx);
-                tx.submit().get();
-            } catch (InterruptedException | ExecutionException | ReadFailedException e) {
-                LOG.error("Error processing data-tree changes", e);
-            }
-        });
+            }), LOG, "Error processing data-tree changes"));
     }
 
     private void processUpdatedNodes(Collection<DataTreeModification<Node>> changes,
-                                     ReadWriteTransaction tx) {
+                                     TypedReadWriteTransaction<D> tx)
+            throws ReadFailedException, ExecutionException, InterruptedException {
         for (DataTreeModification<Node> change : changes) {
             final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
             final DataObjectModification<Node> mod = change.getRootNode();
@@ -179,7 +175,7 @@ public abstract class HwvtepNodeBaseListener implements DataTreeChangeListener<N
 
     private String logicalSwitchNameFromChildMod(DataObjectModification<? extends DataObject> childMod) {
         DataObject data = childMod.getDataAfter() != null ? childMod.getDataAfter() : childMod.getDataBefore();
-        return logicalSwitchExtractor.getOrDefault(childMod.getModificationType().getClass(), noLogicalSwitch)
+        return LOGICAL_SWITCH_EXTRACTOR.getOrDefault(childMod.getModificationType().getClass(), noLogicalSwitch)
                 .apply(data);
     }
 
@@ -197,7 +193,7 @@ public abstract class HwvtepNodeBaseListener implements DataTreeChangeListener<N
             String childClsName = childMod.getDataType().getClass().getSimpleName();
             String modificationType = childMod.getModificationType().toString();
             String logicalSwitchName = logicalSwitchNameFromChildMod(childMod);
-            childModCounter.label(datastoreType.name())
+            childModCounter.label(Datastore.toType(datastoreType).name())
                     .label(modificationType)
                     .label(childClsName)
                     .label(nodeId)
@@ -206,8 +202,8 @@ public abstract class HwvtepNodeBaseListener implements DataTreeChangeListener<N
     }
 
     private void processDisconnectedNodes(Collection<DataTreeModification<Node>> changes,
-                                          ReadWriteTransaction tx)
-            throws ReadFailedException {
+                                          TypedReadWriteTransaction<D> tx)
+            throws InterruptedException, ExecutionException, ReadFailedException {
         for (DataTreeModification<Node> change : changes) {
             final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
             final DataObjectModification<Node> mod = change.getRootNode();
@@ -215,7 +211,7 @@ public abstract class HwvtepNodeBaseListener implements DataTreeChangeListener<N
             String nodeId = key.firstKeyOf(Node.class).getNodeId().getValue();
             if (deleted != null) {
                 if (updateMetrics) {
-                    nodeModCounter.label(datastoreType.name())
+                    nodeModCounter.label(Datastore.toType(datastoreType).name())
                             .label(DataObjectModification.ModificationType.DELETE.name()).label(nodeId).mark();
                 }
                 if (!nodeId.contains(HwvtepHAUtil.PHYSICALSWITCH)) {
@@ -230,8 +226,8 @@ public abstract class HwvtepNodeBaseListener implements DataTreeChangeListener<N
     }
 
     void processConnectedNodes(Collection<DataTreeModification<Node>> changes,
-                               ReadWriteTransaction tx)
-            throws ReadFailedException {
+                               TypedReadWriteTransaction<D> tx)
+            throws ExecutionException, InterruptedException {
         for (DataTreeModification<Node> change : changes) {
             InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
             DataObjectModification<Node> mod = change.getRootNode();
@@ -239,7 +235,7 @@ public abstract class HwvtepNodeBaseListener implements DataTreeChangeListener<N
             String nodeId = key.firstKeyOf(Node.class).getNodeId().getValue();
             if (node != null) {
                 if (updateMetrics) {
-                    nodeModCounter.label(datastoreType.name())
+                    nodeModCounter.label(Datastore.toType(datastoreType).name())
                             .label(DataObjectModification.ModificationType.WRITE.name()).label(nodeId).mark();
                 }
                 if (!nodeId.contains(HwvtepHAUtil.PHYSICALSWITCH)) {
@@ -269,36 +265,34 @@ public abstract class HwvtepNodeBaseListener implements DataTreeChangeListener<N
         }
     }
 
-    ReadWriteTransaction getTx() {
-        return new BatchedTransaction();
-    }
-
     //default methods
-    void onGlobalNodeDelete(InstanceIdentifier<Node> key, Node added, ReadWriteTransaction tx)
-            throws ReadFailedException {
+    void onGlobalNodeDelete(InstanceIdentifier<Node> key, Node added, TypedReadWriteTransaction<D> tx)
+        throws ReadFailedException, ExecutionException, InterruptedException {
     }
 
-    void onPsNodeDelete(InstanceIdentifier<Node> key, Node addedPSNode, ReadWriteTransaction tx)
-            throws ReadFailedException {
+    void onPsNodeDelete(InstanceIdentifier<Node> key, Node addedPSNode, TypedReadWriteTransaction<D> tx)
+        throws ReadFailedException, ExecutionException, InterruptedException {
 
     }
 
-    void onGlobalNodeAdd(InstanceIdentifier<Node> key, Node added, ReadWriteTransaction tx) {
+    void onGlobalNodeAdd(InstanceIdentifier<Node> key, Node added, TypedReadWriteTransaction<D> tx) {
 
     }
 
-    void onPsNodeAdd(InstanceIdentifier<Node> key, Node addedPSNode, ReadWriteTransaction tx)
-            throws ReadFailedException {
+    void onPsNodeAdd(InstanceIdentifier<Node> key, Node addedPSNode, TypedReadWriteTransaction<D> tx)
+            throws InterruptedException, ExecutionException {
 
     }
 
     void onGlobalNodeUpdate(InstanceIdentifier<Node> key, Node updated, Node original,
-                            DataObjectModification<Node> mod, ReadWriteTransaction tx) {
+                            DataObjectModification<Node> mod, TypedReadWriteTransaction<D> tx)
+            throws ReadFailedException, InterruptedException, ExecutionException {
 
     }
 
     void onPsNodeUpdate(Node updated, Node original,
-                        DataObjectModification<Node> mod, ReadWriteTransaction tx) {
+                        DataObjectModification<Node> mod, TypedReadWriteTransaction<D> tx)
+            throws ReadFailedException, InterruptedException, ExecutionException {
 
     }
 
index 04cfefd7d435892d46d10b89d7dc20e404baa87c..c7ea093ea56040e77524dc359dbfd94454753ffc 100644 (file)
@@ -10,15 +10,18 @@ package org.opendaylight.netvirt.elan.l2gw.ha.listeners;
 import com.google.common.base.Optional;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.ExecutionException;
 import java.util.function.BiConsumer;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
+import org.opendaylight.genius.infra.Datastore;
+import org.opendaylight.genius.infra.Datastore.Operational;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
 import org.opendaylight.netvirt.elan.l2gw.ha.commands.MergeCommand;
@@ -34,14 +37,15 @@ import org.slf4j.LoggerFactory;
  * When an operational child node data is updated, it is copied to parent
  * When a config parent node data is updated , it is copied to all its children.
  */
-public abstract class HwvtepNodeDataListener<T extends DataObject>
-        extends AsyncDataTreeChangeListenerBase<T, HwvtepNodeDataListener<T>> {
+public abstract class HwvtepNodeDataListener<D extends Datastore, T extends DataObject>
+        extends AsyncDataTreeChangeListenerBase<T, HwvtepNodeDataListener<D, T>> {
 
     private static final Logger LOG = LoggerFactory.getLogger(HwvtepNodeDataListener.class);
 
     private final ManagedNewTransactionRunner txRunner;
+    private final SingleTransactionDataBroker singleTxBroker;
     private final MergeCommand<T, ?, ?> mergeCommand;
-    private final LogicalDatastoreType datastoreType;
+    private final Class<D> datastoreType;
     private final BiConsumer<InstanceIdentifier<T>, T> addOperation;
     private final BiConsumer<InstanceIdentifier<T>, T> removeOperation;
     private final HwvtepNodeHACache hwvtepNodeHACache;
@@ -49,15 +53,16 @@ public abstract class HwvtepNodeDataListener<T extends DataObject>
     public HwvtepNodeDataListener(DataBroker broker,
                                   HwvtepNodeHACache hwvtepNodeHACache,
                                   Class<T> clazz,
-                                  Class<HwvtepNodeDataListener<T>> eventClazz,
+                                  Class<HwvtepNodeDataListener<D, T>> eventClazz,
                                   MergeCommand<T, ?, ?> mergeCommand,
-                                  LogicalDatastoreType datastoreType) {
+                                  Class<D> datastoreType) {
         super(clazz, eventClazz);
         this.hwvtepNodeHACache = hwvtepNodeHACache;
         this.txRunner = new ManagedNewTransactionRunnerImpl(broker);
+        this.singleTxBroker = new SingleTransactionDataBroker(broker);
         this.mergeCommand = mergeCommand;
         this.datastoreType = datastoreType;
-        if (LogicalDatastoreType.OPERATIONAL == datastoreType) {
+        if (Operational.class.equals(datastoreType)) {
             this.addOperation = this::copyToParent;
             this.removeOperation = this::deleteFromParent;
         } else {
@@ -90,10 +95,10 @@ public abstract class HwvtepNodeDataListener<T extends DataObject>
         HAJobScheduler.getInstance().submitJob(() -> removeOperation.accept(identifier, dataRemoved));
     }
 
-    private boolean isNodeConnected(InstanceIdentifier<T> identifier, ReadTransaction tx)
+    private boolean isNodeConnected(InstanceIdentifier<T> identifier)
             throws ReadFailedException {
-        return tx.read(LogicalDatastoreType.OPERATIONAL, identifier.firstIdentifierOf(Node.class))
-                .checkedGet().isPresent();
+        return singleTxBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL,
+            identifier.firstIdentifierOf(Node.class)).isPresent();
     }
 
     private static <T extends DataObject> boolean isDataUpdated(Optional<T> existingDataOptional, T newData) {
@@ -110,7 +115,7 @@ public abstract class HwvtepNodeDataListener<T extends DataObject>
             LOG.trace("Copy child op data {} to parent {}", mergeCommand.getDescription(), getNodeId(parent));
             T parentData = mergeCommand.transform(parent, data);
             InstanceIdentifier<T> parentIdentifier = mergeCommand.generateId(parent, parentData);
-            ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(
+            ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(datastoreType,
                 tx -> writeToMdsal(tx, parentData, parentIdentifier)), LOG, "Error copying to parent");
         }
     }
@@ -122,8 +127,8 @@ public abstract class HwvtepNodeDataListener<T extends DataObject>
         }
         InstanceIdentifier<Node> parent = getHAParent(identifier);
         if (parent != null) {
-            ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
-                if (isNodeConnected(identifier, tx)) {
+            ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(datastoreType, tx -> {
+                if (isNodeConnected(identifier)) {
                     LOG.trace("Copy child op data {} to parent {} create:{}", mergeCommand.getDescription(),
                             getNodeId(parent), false);
                     T parentData = mergeCommand.transform(parent, data);
@@ -137,7 +142,7 @@ public abstract class HwvtepNodeDataListener<T extends DataObject>
     private void copyToChildren(final InstanceIdentifier<T> parentIdentifier, final T parentData) {
         Set<InstanceIdentifier<Node>> children = getChildrenForHANode(parentIdentifier);
         if (children != null) {
-            ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
+            ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(datastoreType, tx -> {
                 for (InstanceIdentifier<Node> child : children) {
                     LOG.trace("Copy parent config data {} to child {}", mergeCommand.getDescription(),
                             getNodeId(child));
@@ -152,7 +157,7 @@ public abstract class HwvtepNodeDataListener<T extends DataObject>
     private void deleteFromChildren(final InstanceIdentifier<T> parentIdentifier, final T parentData) {
         Set<InstanceIdentifier<Node>> children = getChildrenForHANode(parentIdentifier);
         if (children != null) {
-            ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
+            ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(datastoreType, tx -> {
                 for (InstanceIdentifier<Node> child : children) {
                     LOG.trace("Delete parent config data {} to child {}", mergeCommand.getDescription(),
                             getNodeId(child));
@@ -164,17 +169,17 @@ public abstract class HwvtepNodeDataListener<T extends DataObject>
         }
     }
 
-    private void writeToMdsal(final ReadWriteTransaction tx, final T data, final InstanceIdentifier<T> identifier)
-            throws ReadFailedException {
-        if (isDataUpdated(tx.read(datastoreType, identifier).checkedGet(), data)) {
-            tx.put(datastoreType, identifier, data);
+    private void writeToMdsal(final TypedReadWriteTransaction<D> tx, final T data,
+            final InstanceIdentifier<T> identifier) throws ExecutionException, InterruptedException {
+        if (isDataUpdated(tx.read(identifier).get(), data)) {
+            tx.put(identifier, data);
         }
     }
 
-    private void deleteFromMdsal(final ReadWriteTransaction tx,
-            final InstanceIdentifier<T> identifier) throws ReadFailedException {
-        if (tx.read(datastoreType, identifier).checkedGet().isPresent()) {
-            tx.delete(datastoreType, identifier);
+    private void deleteFromMdsal(final TypedReadWriteTransaction<D> tx,
+            final InstanceIdentifier<T> identifier) throws ExecutionException, InterruptedException {
+        if (tx.read(identifier).get().isPresent()) {
+            tx.delete(identifier);
         }
     }
 
@@ -183,16 +188,16 @@ public abstract class HwvtepNodeDataListener<T extends DataObject>
     }
 
     @Override
-    protected HwvtepNodeDataListener<T> getDataTreeChangeListener() {
+    protected HwvtepNodeDataListener<D, T> getDataTreeChangeListener() {
         return HwvtepNodeDataListener.this;
     }
 
-    protected Set<InstanceIdentifier<Node>> getChildrenForHANode(InstanceIdentifier identifier) {
+    protected Set<InstanceIdentifier<Node>> getChildrenForHANode(InstanceIdentifier<T> identifier) {
         InstanceIdentifier<Node> parent = identifier.firstIdentifierOf(Node.class);
         return hwvtepNodeHACache.getChildrenForHANode(parent);
     }
 
-    protected InstanceIdentifier<Node> getHAParent(InstanceIdentifier identifier) {
+    protected InstanceIdentifier<Node> getHAParent(InstanceIdentifier<T> identifier) {
         InstanceIdentifier<Node> child = identifier.firstIdentifierOf(Node.class);
         return hwvtepNodeHACache.getParent(child);
     }
index 271829605919e12c2121df2faa74af84301ca239..1cc4d8936782f1ec9f434c949fa8c060b608d086 100644 (file)
@@ -7,20 +7,23 @@
  */
 package org.opendaylight.netvirt.elan.l2gw.ha.merge;
 
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
+import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
 
 import com.google.common.base.Optional;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
+import java.util.concurrent.ExecutionException;
 import java.util.function.BiPredicate;
 
 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.infra.Datastore;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 import org.opendaylight.genius.utils.SuperTypeUtil;
 import org.opendaylight.netvirt.elan.l2gw.ha.commands.LocalUcastCmd;
 import org.opendaylight.netvirt.elan.l2gw.ha.commands.MergeCommand;
@@ -38,8 +41,8 @@ public abstract class MergeCommandsAggregator<BuilderTypeT extends Builder, AugT
 
     protected Map<Class<?>, MergeCommand> commands = new HashMap<>();
 
-    private final BiPredicate<LogicalDatastoreType, Class> skipCopy =
-        (dsType, cmdType) -> (dsType == CONFIGURATION ? commands.get(cmdType) instanceof LocalUcastCmd
+    private final BiPredicate<Class<? extends Datastore>, Class> skipCopy =
+        (dsType, cmdType) -> (Configuration.class.equals(dsType) ? commands.get(cmdType) instanceof LocalUcastCmd
                 : commands.get(cmdType) instanceof RemoteUcastCmd);
 
     protected MergeCommandsAggregator() {
@@ -73,20 +76,20 @@ public abstract class MergeCommandsAggregator<BuilderTypeT extends Builder, AugT
 
     public void mergeConfigUpdate(InstanceIdentifier<Node> dstPath,
                                   DataObjectModification mod,
-                                  ReadWriteTransaction tx) {
+                                  TypedReadWriteTransaction<Configuration> tx) {
         mergeUpdate(dstPath, mod, CONFIGURATION, tx);
     }
 
     public void mergeOpUpdate(InstanceIdentifier<Node> dstPath,
                               DataObjectModification mod,
-                              ReadWriteTransaction tx) {
+                              TypedReadWriteTransaction<Operational> tx) {
         mergeUpdate(dstPath, mod, OPERATIONAL, tx);
     }
 
-    public void mergeUpdate(InstanceIdentifier<Node> dstPath,
+    public <D extends Datastore> void mergeUpdate(InstanceIdentifier<Node> dstPath,
                             DataObjectModification mod,
-                            LogicalDatastoreType datastoreType,
-                            ReadWriteTransaction tx) {
+                            Class<D> datastoreType,
+                            TypedReadWriteTransaction<D> tx) {
         if (mod == null) {
             return;
         }
@@ -105,24 +108,24 @@ public abstract class MergeCommandsAggregator<BuilderTypeT extends Builder, AugT
 
                 Optional<DataObject> existingDataOptional = null;
                 try {
-                    existingDataOptional = tx.read(datastoreType, transformedId).checkedGet();
-                } catch (ReadFailedException ex) {
+                    existingDataOptional = tx.read(transformedId).get();
+                } catch (InterruptedException | ExecutionException ex) {
                     LOG.error("Failed to read data {} from {}", transformedId, datastoreType);
                     return;
                 }
 
-                String destination = datastoreType == CONFIGURATION ? "child" : "parent";
+                String destination = Configuration.class.equals(datastoreType) ? "child" : "parent";
                 if (create) {
                     if (isDataUpdated(existingDataOptional, transformedItem)) {
                         LOG.debug("Copy to {} {} {}", destination, datastoreType, transformedId);
-                        tx.put(datastoreType, transformedId, transformedItem, true);
+                        tx.put(transformedId, transformedItem, CREATE_MISSING_PARENTS);
                     } else {
                         LOG.debug("Data not updated skip copy to {}", transformedId);
                     }
                 } else {
                     if (existingDataOptional.isPresent()) {
                         LOG.debug("Delete from {} {} {}", destination, datastoreType, transformedId);
-                        tx.delete(datastoreType, transformedId);
+                        tx.delete(transformedId);
                     } else {
                         LOG.debug("Delete skipped for {}", transformedId);
                     }
index 0afacb1df349504a46427eecbdcf0e7441fefa5e..4c2eee97ca533dd80355e0ccb4d18cc9e889c6d7 100644 (file)
@@ -38,8 +38,8 @@ public class HwvtepDeviceMcastMacUpdateJob implements Callable<List<ListenableFu
     public List<ListenableFuture<Void>> call() {
         LOG.info("running update mcast mac entry job for {} {}",
                 elanName, l2GatewayDevice.getHwvtepNodeId());
-        return Collections.singletonList(
-                elanL2GatewayMulticastUtils.updateRemoteMcastMacOnElanL2GwDevice(elanName, l2GatewayDevice));
+        elanL2GatewayMulticastUtils.updateRemoteMcastMacOnElanL2GwDevice(elanName, l2GatewayDevice);
+        return Collections.emptyList();
     }
 
 }
index 4d6b4aa06a53a4eeb0a6d8fddeb9728e24ec79f8..1da0b0c9a0072aa795faa555abbd35403b5c5d88 100644 (file)
@@ -73,8 +73,7 @@ public class LogicalSwitchAddedJob implements Callable<List<ListenableFuture<Voi
         futures.add(elanL2GatewayUtils.updateVlanBindingsInL2GatewayDevice(
             new NodeId(elanL2GwDevice.getHwvtepNodeId()), logicalSwitchName, physicalDevice, defaultVlanId));
         LOG.info("creating mast mac entries for {} {}", logicalSwitchName, elanL2GwDevice.getHwvtepNodeId());
-        futures.add(elanL2GatewayMulticastUtils.handleMcastForElanL2GwDeviceAdd(logicalSwitchName,
-                elanL2GwDevice));
+        elanL2GatewayMulticastUtils.handleMcastForElanL2GwDeviceAdd(logicalSwitchName, elanL2GwDevice);
         futures.add(elanL2GatewayUtils.installElanMacsInL2GatewayDevice(
                 logicalSwitchName, elanL2GwDevice));
         return futures;
index 3cc8d60d546091af6ca42b46289bea62c20845c2..00a77653c92e7227ef81fa26fbb5b0f9d7be54b1 100644 (file)
@@ -7,6 +7,9 @@
  */
 package org.opendaylight.netvirt.elan.l2gw.listeners;
 
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
+
 import com.google.common.collect.Sets;
 import java.util.Collections;
 import java.util.HashMap;
@@ -22,7 +25,6 @@ import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeLis
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
 import org.opendaylight.genius.utils.batching.ResourceBatchingManager;
@@ -200,18 +202,20 @@ public class LocalUcastMacListener extends ChildListener<Node, LocalUcastMacs, S
         if (IS_PS_NODE_IID.test(nodeIid)) {
             return;
         }
-        ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
-            haOpClusteredListener.onGlobalNodeAdd(nodeIid, modification.getRootNode().getDataAfter(), tx);
-            if (!isHAChild(nodeIid)) {
+        // TODO skitt we're only using read transactions here
+        ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL,
+            tx -> haOpClusteredListener.onGlobalNodeAdd(nodeIid, modification.getRootNode().getDataAfter(), tx)), LOG,
+            "Error processing added parent");
+        if (!isHAChild(nodeIid)) {
+            ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
                 LOG.trace("On parent add {}", nodeIid);
                 Node operNode = modification.getRootNode().getDataAfter();
-                Set<LocalUcastMacs> configMacs =
-                        getMacs(tx.read(LogicalDatastoreType.CONFIGURATION, nodeIid).checkedGet().orNull());
+                Set<LocalUcastMacs> configMacs = getMacs(tx.read(nodeIid).get().orNull());
                 Set<LocalUcastMacs> operMacs = getMacs(operNode);
                 Set<LocalUcastMacs> staleMacs = Sets.difference(configMacs, operMacs);
                 staleMacs.forEach(staleMac -> removed(getMacIid(nodeIid, staleMac), staleMac));
-            }
-        }), LOG, "Error processing added parent");
+            }), LOG, "Error processing added parent");
+        }
     }
 
     InstanceIdentifier<LocalUcastMacs> getMacIid(InstanceIdentifier<Node> nodeIid, LocalUcastMacs mac) {
index 6a4417800ab41686d6dc1dae8eb11e30b427805e..91c7db351efc7f9420e598ed359bb26c8fac3565 100644 (file)
@@ -113,14 +113,13 @@ public class ElanL2GatewayMulticastUtils {
      * Handle mcast for elan l2 gw device add.
      * @param elanName the elan name
      * @param device the device
-     * @return the listenable future
      */
-    public ListenableFuture<Void> handleMcastForElanL2GwDeviceAdd(String elanName, L2GatewayDevice device) {
+    public void handleMcastForElanL2GwDeviceAdd(String elanName, L2GatewayDevice device) {
         InstanceIdentifier<ExternalTeps> tepPath = buildExternalTepPath(elanName, device.getTunnelIp());
-        JdkFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
-            tx.put(tepPath, buildExternalTeps(device));
-        }), LOG, "Failed to write to config external tep {}", tepPath);
-        return updateMcastMacsForAllElanDevices(elanName, device, true/* updateThisDevice */);
+        JdkFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+            tx -> tx.put(tepPath, buildExternalTeps(device))), LOG, "Failed to write to config external tep {}",
+            tepPath);
+        updateMcastMacsForAllElanDevices(elanName, device, true/* updateThisDevice */);
     }
 
     public static InstanceIdentifier<ExternalTeps> buildExternalTepPath(String elan, IpAddress tepIp) {
@@ -139,15 +138,11 @@ public class ElanL2GatewayMulticastUtils {
      *
      * @param elanName
      *            the elan to be updated
-     * @return the listenable future
      */
-    @SuppressWarnings("checkstyle:IllegalCatch")
-    public ListenableFuture<Void> updateRemoteMcastMacOnElanL2GwDevices(String elanName) {
-        return txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
-            for (L2GatewayDevice device : ElanL2GwCacheUtils.getInvolvedL2GwDevices(elanName).values()) {
-                prepareRemoteMcastMacUpdateOnDevice(elanName, device);
-            }
-        });
+    public void updateRemoteMcastMacOnElanL2GwDevices(String elanName) {
+        for (L2GatewayDevice device : ElanL2GwCacheUtils.getInvolvedL2GwDevices(elanName).values()) {
+            prepareRemoteMcastMacUpdateOnDevice(elanName, device);
+        }
     }
 
     public void scheduleMcastMacUpdateJob(String elanName, L2GatewayDevice device) {
@@ -162,11 +157,9 @@ public class ElanL2GatewayMulticastUtils {
      *            the elan name
      * @param device
      *            the device
-     * @return the listenable future
      */
-    public ListenableFuture<Void> updateRemoteMcastMacOnElanL2GwDevice(String elanName, L2GatewayDevice device) {
-        return txRunner.callWithNewWriteOnlyTransactionAndSubmit(
-            tx -> prepareRemoteMcastMacUpdateOnDevice(elanName, device));
+    public void updateRemoteMcastMacOnElanL2GwDevice(String elanName, L2GatewayDevice device) {
+        prepareRemoteMcastMacUpdateOnDevice(elanName, device);
     }
 
     public void prepareRemoteMcastMacUpdateOnDevice(String elanName,
@@ -176,7 +169,7 @@ public class ElanL2GatewayMulticastUtils {
         List<DpnInterfaces> dpns = elanUtils.getElanDPNByName(elanName);
         List<IpAddress> dpnsTepIps = getAllTepIpsOfDpns(device, dpns);
         List<IpAddress> l2GwDevicesTepIps = getAllTepIpsOfL2GwDevices(elanL2gwDevices);
-        preapareRemoteMcastMacEntry(elanName, device, dpnsTepIps, l2GwDevicesTepIps);
+        prepareRemoteMcastMacEntry(elanName, device, dpnsTepIps, l2GwDevicesTepIps);
     }
 
     /**
@@ -190,9 +183,8 @@ public class ElanL2GatewayMulticastUtils {
      *            the device
      * @param updateThisDevice
      *            the update this device
-     * @return the listenable future
      */
-    private ListenableFuture<Void> updateMcastMacsForAllElanDevices(String elanName, L2GatewayDevice device,
+    private void updateMcastMacsForAllElanDevices(String elanName, L2GatewayDevice device,
                                                                     boolean updateThisDevice) {
 
         SettableFuture<Void> ft = SettableFuture.create();
@@ -210,20 +202,17 @@ public class ElanL2GatewayMulticastUtils {
         // return ft;
         // }
 
-        return txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
-            if (updateThisDevice) {
-                preapareRemoteMcastMacEntry(elanName, device, dpnsTepIps, l2GwDevicesTepIps);
-            }
+        if (updateThisDevice) {
+            prepareRemoteMcastMacEntry(elanName, device, dpnsTepIps, l2GwDevicesTepIps);
+        }
 
-            // TODO: Need to revisit below logic as logical switches might not be
-            // present to configure RemoteMcastMac entry
-            for (L2GatewayDevice otherDevice : devices.values()) {
-                if (!otherDevice.getDeviceName().equals(device.getDeviceName())) {
-                    preapareRemoteMcastMacEntry(elanName, otherDevice, dpnsTepIps, l2GwDevicesTepIps);
-                }
+        // TODO: Need to revisit below logic as logical switches might not be
+        // present to configure RemoteMcastMac entry
+        for (L2GatewayDevice otherDevice : devices.values()) {
+            if (!otherDevice.getDeviceName().equals(device.getDeviceName())) {
+                prepareRemoteMcastMacEntry(elanName, otherDevice, dpnsTepIps, l2GwDevicesTepIps);
             }
-        });
-
+        }
     }
 
     public void updateRemoteBroadcastGroupForAllElanDpns(ElanInstance elanInfo) {
@@ -435,7 +424,7 @@ public class ElanL2GatewayMulticastUtils {
      *            the l2 gw devices tep ips
      * @return the write transaction
      */
-    private void preapareRemoteMcastMacEntry(String elanName,
+    private void prepareRemoteMcastMacEntry(String elanName,
                                              L2GatewayDevice device, List<IpAddress> dpnsTepIps,
                                              List<IpAddress> l2GwDevicesTepIps) {
         NodeId nodeId = new NodeId(device.getHwvtepNodeId());
@@ -559,15 +548,13 @@ public class ElanL2GatewayMulticastUtils {
      */
     public List<ListenableFuture<Void>> handleMcastForElanL2GwDeviceDelete(String elanName,
                                                                            L2GatewayDevice l2GatewayDevice) {
-        ListenableFuture<Void> deleteTepFuture = txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
-            tx.delete(LogicalDatastoreType.CONFIGURATION,
-                    buildExternalTepPath(elanName, l2GatewayDevice.getTunnelIp()));
-        });
-        ListenableFuture<Void> updateMcastMacsFuture = updateMcastMacsForAllElanDevices(
-                elanName, l2GatewayDevice, false/* updateThisDevice */);
+        ListenableFuture<Void> deleteTepFuture =
+            txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+                tx -> tx.delete(buildExternalTepPath(elanName, l2GatewayDevice.getTunnelIp())));
+        updateMcastMacsForAllElanDevices(elanName, l2GatewayDevice, false/* updateThisDevice */);
         ListenableFuture<Void> deleteRemoteMcastMacFuture = deleteRemoteMcastMac(
                 new NodeId(l2GatewayDevice.getHwvtepNodeId()), elanName);
-        return Arrays.asList(updateMcastMacsFuture, deleteRemoteMcastMacFuture, deleteTepFuture);
+        return Arrays.asList(deleteRemoteMcastMacFuture, deleteTepFuture);
     }
 
     /**
index b345a2ef9dcc836e415b8c1ce273b0df2cc6ac04..3d22638c90ec388580602e4a89d073c65f6c66bf 100644 (file)
@@ -807,7 +807,7 @@ public class ElanL2GatewayUtils {
             return Futures.immediateFailedFuture(new RuntimeException(errMsg));
         }
 
-        return txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+        return txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
             for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712
                     .l2gateway.attributes.devices.Interfaces deviceInterface : hwVtepDevice.getInterfaces()) {
                 //Removed the check for checking terminationPoint present in OP or not
@@ -847,7 +847,7 @@ public class ElanL2GatewayUtils {
      */
     public ListenableFuture<Void> updateVlanBindingsInL2GatewayDevice(NodeId nodeId, String psName,
             String interfaceName, List<VlanBindings> vlanBindings) {
-        return txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+        return txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
             HwvtepUtils.mergeVlanBindings(tx, nodeId, psName, interfaceName, vlanBindings);
             LOG.info("Updated Hwvtep VlanBindings in config DS. NodeID: {}", nodeId.getValue());
         });
@@ -873,7 +873,7 @@ public class ElanL2GatewayUtils {
         }
         NodeId physicalSwitchNodeId = HwvtepSouthboundUtils.createManagedNodeId(nodeId, hwVtepDevice.getDeviceName());
 
-        return txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+        return txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
             for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712
                     .l2gateway.attributes.devices.Interfaces deviceInterface : hwVtepDevice.getInterfaces()) {
                 String phyPortName = deviceInterface.getInterfaceName();
index 95f54369d14a453f7c4dcacc5afff653f48c5b41..9a2d7639fec1c061a05f11be7b7890fda81cb06d 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.netvirt.elan.l2gw.utils;
 
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -108,9 +108,10 @@ public class StaleVlanBindingsCleaner {
                 () -> {
                     L2GatewayDevice l2GwDevice = l2GatewayCache.get(deviceName);
                     NodeId globalNodeId = globalNodeIid.firstKeyOf(Node.class).getNodeId();
-                    Node configNode = MDSALUtil.read(broker, CONFIGURATION, globalNodeIid)
+                    Node configNode = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, globalNodeIid)
                             .or(defaultNode(globalNodeId));
-                    Node configPsNode = MDSALUtil.read(broker, CONFIGURATION, psNodeIid).or(defaultNode(psNodeId));
+                    Node configPsNode =
+                        MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, psNodeIid).or(defaultNode(psNodeId));
                     cleanupStaleLogicalSwitches(l2GwDevice, configNode, configPsNode);
                     cleanupTasks.remove(psNodeIid.firstKeyOf(Node.class).getNodeId());
                 }, getCleanupDelay(), TimeUnit.SECONDS);
@@ -187,10 +188,9 @@ public class StaleVlanBindingsCleaner {
 
         LOG.trace("CleanupStaleBindings for logical switch {}", staleLogicalSwitch);
         ListenableFutures.addErrorLogging(
-            txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
+            txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
                 if (vlans.containsKey(staleLogicalSwitch)) {
-                    vlans.get(staleLogicalSwitch)
-                            .forEach((vlanIid) -> tx.delete(LogicalDatastoreType.CONFIGURATION, vlanIid));
+                    vlans.get(staleLogicalSwitch).forEach((vlanIid) -> tx.delete(vlanIid));
                 }
             }),
             LOG, "Failed to delete stale vlan bindings from node {}", globalNodeId);
index f3a90f497618a58298436bde2f33e0fd4480344b..d6599a9c50a0778275ff1fb23945f66df4fb9b30 100644 (file)
@@ -7,7 +7,9 @@
  */
 package org.opendaylight.netvirt.elan.utils;
 
+import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
 
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -15,14 +17,17 @@ import com.google.common.util.concurrent.ListenableFuture;
 import java.util.ArrayList;
 import java.util.List;
 
+import java.util.concurrent.ExecutionException;
 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.genius.infra.Datastore.Operational;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
@@ -40,19 +45,18 @@ public class ElanForwardingEntriesHandler {
 
     private static final Logger LOG = LoggerFactory.getLogger(ElanForwardingEntriesHandler.class);
 
-    private final DataBroker broker;
     private final ManagedNewTransactionRunner txRunner;
     private final ElanUtils elanUtils;
 
     @Inject
     public ElanForwardingEntriesHandler(DataBroker dataBroker, ElanUtils elanUtils) {
-        this.broker = dataBroker;
         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
         this.elanUtils = elanUtils;
     }
 
     public void updateElanInterfaceForwardingTablesList(String elanInstanceName, String interfaceName,
-            String existingInterfaceName, MacEntry mac, WriteTransaction tx) {
+            String existingInterfaceName, MacEntry mac, TypedReadWriteTransaction<Operational> tx)
+            throws ExecutionException, InterruptedException {
         if (existingInterfaceName.equals(interfaceName)) {
             LOG.error("Static MAC address {} has already been added for the same ElanInstance "
                             + "{} on the same Logical Interface Port {}."
@@ -73,7 +77,8 @@ public class ElanForwardingEntriesHandler {
     }
 
     public void addElanInterfaceForwardingTableList(String elanInstanceName, String interfaceName,
-                                                    StaticMacEntries staticMacEntries, WriteTransaction tx) {
+            StaticMacEntries staticMacEntries, TypedReadWriteTransaction<Operational> tx)
+            throws ExecutionException, InterruptedException {
         MacEntry macEntry = new MacEntryBuilder().setIsStaticAddress(true)
                 .setMacAddress(staticMacEntries.getMacAddress())
                 .setIpPrefix(staticMacEntries.getIpPrefix())
@@ -84,63 +89,64 @@ public class ElanForwardingEntriesHandler {
     }
 
     public void deleteElanInterfaceForwardingTablesList(String interfaceName, MacEntry mac,
-                                                        WriteTransaction interfaceTx) {
+                                                        TypedReadWriteTransaction<Operational> interfaceTx)
+            throws ExecutionException, InterruptedException {
         InstanceIdentifier<MacEntry> existingMacEntryId = ElanUtils
                 .getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, mac.getMacAddress());
         MacEntry existingInterfaceMacEntry = elanUtils
-                .getInterfaceMacEntriesOperationalDataPathFromId(existingMacEntryId);
+                .getInterfaceMacEntriesOperationalDataPathFromId(interfaceTx, existingMacEntryId);
         if (existingInterfaceMacEntry != null) {
-            interfaceTx.delete(LogicalDatastoreType.OPERATIONAL, existingMacEntryId);
+            interfaceTx.delete(existingMacEntryId);
         }
     }
 
-    public void createElanInterfaceForwardingTablesList(String interfaceName, MacEntry mac, WriteTransaction tx) {
+    public void createElanInterfaceForwardingTablesList(String interfaceName, MacEntry mac,
+            TypedReadWriteTransaction<Operational> tx) throws ExecutionException, InterruptedException {
         InstanceIdentifier<MacEntry> existingMacEntryId = ElanUtils
                 .getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, mac.getMacAddress());
         MacEntry existingInterfaceMacEntry = elanUtils
-                .getInterfaceMacEntriesOperationalDataPathFromId(existingMacEntryId);
+                .getInterfaceMacEntriesOperationalDataPathFromId(tx, existingMacEntryId);
         if (existingInterfaceMacEntry == null) {
             MacEntry macEntry = new MacEntryBuilder().setMacAddress(mac.getMacAddress()).setIpPrefix(mac.getIpPrefix())
                     .setInterface(interfaceName)
                     .setIsStaticAddress(true).withKey(new MacEntryKey(mac.getMacAddress())).build();
-            tx.put(LogicalDatastoreType.OPERATIONAL, existingMacEntryId, macEntry,
-                    WriteTransaction.CREATE_MISSING_PARENTS);
+            tx.put(existingMacEntryId, macEntry, CREATE_MISSING_PARENTS);
         }
     }
 
     public void updateElanForwardingTablesList(String elanName, String interfaceName, MacEntry mac,
-            WriteTransaction tx) {
+            TypedReadWriteTransaction<Operational> tx) throws ExecutionException, InterruptedException {
         InstanceIdentifier<MacEntry> macEntryId = ElanUtils.getMacEntryOperationalDataPath(elanName,
                 mac.getMacAddress());
-        MacEntry existingMacEntry = elanUtils.getMacEntryFromElanMacId(macEntryId);
+        MacEntry existingMacEntry = elanUtils.getMacEntryFromElanMacId(tx, macEntryId);
         if (existingMacEntry != null && elanUtils.getElanMacTable(elanName) != null) {
             MacEntry newMacEntry = new MacEntryBuilder().setInterface(interfaceName).setIsStaticAddress(true)
                     .setMacAddress(mac.getMacAddress()).setIpPrefix(mac.getIpPrefix())
                     .withKey(new MacEntryKey(mac.getMacAddress())).build();
-            tx.put(LogicalDatastoreType.OPERATIONAL, macEntryId, newMacEntry);
+            tx.put(macEntryId, newMacEntry);
         }
     }
 
-    private void createElanForwardingTablesList(String elanName, MacEntry macEntry, WriteTransaction tx) {
+    private void createElanForwardingTablesList(String elanName, MacEntry macEntry,
+            TypedReadWriteTransaction<Operational> tx) throws ExecutionException, InterruptedException {
         InstanceIdentifier<MacEntry> macEntryId = ElanUtils.getMacEntryOperationalDataPath(elanName,
                 macEntry.getMacAddress());
-        Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macEntryId);
+        Optional<MacEntry> existingMacEntry = tx.read(macEntryId).get();
         if (!existingMacEntry.isPresent() && elanUtils.getElanMacTable(elanName) != null) {
-            tx.put(LogicalDatastoreType.OPERATIONAL, macEntryId, macEntry, WriteTransaction.CREATE_MISSING_PARENTS);
+            tx.put(macEntryId, macEntry, CREATE_MISSING_PARENTS);
         }
     }
 
     public void deleteElanInterfaceForwardingEntries(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
             MacEntry macEntry) {
         List<ListenableFuture<Void>> futures = new ArrayList<>();
-        futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(interfaceTx -> {
+        futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, interfaceTx -> {
             InstanceIdentifier<MacEntry> macEntryId = ElanUtils
                     .getMacEntryOperationalDataPath(elanInfo.getElanInstanceName(), macEntry.getMacAddress());
-            interfaceTx.delete(LogicalDatastoreType.OPERATIONAL, macEntryId);
+            interfaceTx.delete(macEntryId);
             deleteElanInterfaceForwardingTablesList(interfaceInfo.getInterfaceName(), macEntry, interfaceTx);
-            futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, flowTx -> {
-                elanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry, flowTx);
-            }));
+            futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+                flowTx -> elanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry, flowTx)));
         }));
         for (ListenableFuture<Void> future : futures) {
             ListenableFutures.addErrorLogging(future, LOG, "Error deleting ELAN interface forwarding entries");
index aaeb5d416e2a4a39c21909cdb8929a2a5c93acff..4f9312209c525da8489570e532b5604fcf18b085 100755 (executable)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.netvirt.elan.utils;
 
+import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
 
 import com.google.common.base.Optional;
@@ -37,15 +38,17 @@ import javax.inject.Singleton;
 import org.apache.commons.lang3.StringUtils;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
 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.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.Datastore.Operational;
 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.genius.interfacemanager.globals.InterfaceInfo;
 import org.opendaylight.genius.interfacemanager.globals.InterfaceServiceUtil;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
@@ -333,9 +336,9 @@ public class ElanUtils {
     }
 
     @Nullable
-    public static Elan getElanByName(ReadTransaction tx, String elanInstanceName) throws ReadFailedException {
-        return tx.read(LogicalDatastoreType.OPERATIONAL,
-                getElanInstanceOperationalDataPath(elanInstanceName)).checkedGet().orNull();
+    public static Elan getElanByName(TypedReadTransaction<Operational> tx, String elanInstanceName)
+            throws ExecutionException, InterruptedException {
+        return tx.read(getElanInstanceOperationalDataPath(elanInstanceName)).get().orNull();
     }
 
     public static InstanceIdentifier<Elan> getElanInstanceOperationalDataPath(String elanInstanceName) {
@@ -355,6 +358,11 @@ public class ElanUtils {
         return existingInterfaceMacEntry.orNull();
     }
 
+    public MacEntry getInterfaceMacEntriesOperationalDataPathFromId(TypedReadTransaction<Operational> tx,
+            InstanceIdentifier<MacEntry> identifier) throws ExecutionException, InterruptedException {
+        return tx.read(identifier).get().orNull();
+    }
+
     public static InstanceIdentifier<MacEntry> getInterfaceMacEntriesIdentifierOperationalDataPath(String interfaceName,
             PhysAddress physAddress) {
         return InstanceIdentifier.builder(ElanInterfaceForwardingEntries.class)
@@ -369,10 +377,10 @@ public class ElanUtils {
         return read(broker, LogicalDatastoreType.OPERATIONAL, macId);
     }
 
-    public Optional<MacEntry> getMacEntryForElanInstance(ReadTransaction tx, String elanName, PhysAddress physAddress)
-            throws ReadFailedException {
+    public Optional<MacEntry> getMacEntryForElanInstance(TypedReadTransaction<Operational> tx, String elanName,
+            PhysAddress physAddress) throws ExecutionException, InterruptedException {
         InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanName, physAddress);
-        return tx.read(LogicalDatastoreType.OPERATIONAL, macId).checkedGet();
+        return tx.read(macId).get();
     }
 
     public MacEntry getMacEntryFromElanMacId(InstanceIdentifier identifier) {
@@ -381,6 +389,11 @@ public class ElanUtils {
         return existingInterfaceMacEntry.orNull();
     }
 
+    public MacEntry getMacEntryFromElanMacId(TypedReadTransaction<Operational> tx,
+            InstanceIdentifier<MacEntry> identifier) throws ExecutionException, InterruptedException {
+        return tx.read(identifier).get().orNull();
+    }
+
     public static InstanceIdentifier<MacEntry> getMacEntryOperationalDataPath(String elanName,
             PhysAddress physAddress) {
         return InstanceIdentifier.builder(ElanForwardingTables.class).child(MacTable.class, new MacTableKey(elanName))
@@ -621,7 +634,7 @@ public class ElanUtils {
      */
     public void setupMacFlows(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
                               long macTimeout, String macAddress, boolean configureRemoteFlows,
-                              WriteTransaction writeFlowGroupTx) {
+                              TypedWriteTransaction<Configuration> writeFlowGroupTx) {
         synchronized (getElanMacDPNKey(elanInfo.getElanTag(), macAddress, interfaceInfo.getDpId())) {
             setupKnownSmacFlow(elanInfo, interfaceInfo, macTimeout, macAddress, mdsalManager,
                 writeFlowGroupTx);
@@ -631,7 +644,7 @@ public class ElanUtils {
     }
 
     public void setupDMacFlowOnRemoteDpn(ElanInstance elanInfo, InterfaceInfo interfaceInfo, BigInteger dstDpId,
-                                         String macAddress, WriteTransaction writeFlowTx) {
+                                         String macAddress, TypedWriteTransaction<Configuration> writeFlowTx) {
         String elanInstanceName = elanInfo.getElanInstanceName();
         setupRemoteDmacFlow(dstDpId, interfaceInfo.getDpId(), interfaceInfo.getInterfaceTag(), elanInfo.getElanTag(),
                 macAddress, elanInstanceName, writeFlowTx, interfaceInfo.getInterfaceName(), elanInfo);
@@ -645,9 +658,10 @@ public class ElanUtils {
      * learnt.
      */
     private void setupKnownSmacFlow(ElanInstance elanInfo, InterfaceInfo interfaceInfo, long macTimeout,
-            String macAddress, IMdsalApiManager mdsalApiManager, WriteTransaction writeFlowGroupTx) {
+            String macAddress, IMdsalApiManager mdsalApiManager,
+            TypedWriteTransaction<Configuration> writeFlowGroupTx) {
         FlowEntity flowEntity = buildKnownSmacFlow(elanInfo, interfaceInfo, macTimeout, macAddress);
-        mdsalApiManager.addFlowToTx(flowEntity, writeFlowGroupTx);
+        mdsalApiManager.addFlow(writeFlowGroupTx, flowEntity);
         LOG.debug("Known Smac flow entry created for elan Name:{}, logical Interface port:{} and mac address:{}",
                 elanInfo.getElanInstanceName(), elanInfo.getDescription(), macAddress);
     }
@@ -710,7 +724,7 @@ public class ElanUtils {
      *            the writeFLowGroup tx
      */
     public void setupTermDmacFlows(InterfaceInfo interfaceInfo, IMdsalApiManager mdsalApiManager,
-                                   WriteTransaction writeFlowGroupTx) {
+                                   TypedWriteTransaction<Configuration> writeFlowGroupTx) {
         BigInteger dpId = interfaceInfo.getDpId();
         int lportTag = interfaceInfo.getInterfaceTag();
         Flow flow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE,
@@ -719,7 +733,7 @@ public class ElanUtils {
                 ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(lportTag)),
                 getTunnelIdMatchForFilterEqualsLPortTag(lportTag),
                 getInstructionsInPortForOutGroup(interfaceInfo.getInterfaceName()));
-        mdsalApiManager.addFlowToTx(dpId, flow, writeFlowGroupTx);
+        mdsalApiManager.addFlow(writeFlowGroupTx, dpId, flow);
         LOG.debug("Terminating service table flow entry created on dpn:{} for logical Interface port:{}", dpId,
                 interfaceInfo.getPortName());
     }
@@ -808,7 +822,7 @@ public class ElanUtils {
 
     private void setupOrigDmacFlows(ElanInstance elanInfo, InterfaceInfo interfaceInfo, String macAddress,
                                     boolean configureRemoteFlows, IMdsalApiManager mdsalApiManager,
-                                    WriteTransaction writeFlowGroupTx) {
+                                    TypedWriteTransaction<Configuration> writeFlowGroupTx) {
         BigInteger dpId = interfaceInfo.getDpId();
         String ifName = interfaceInfo.getInterfaceName();
         long ifTag = interfaceInfo.getInterfaceTag();
@@ -866,15 +880,15 @@ public class ElanUtils {
     }
 
     private void setupLocalDmacFlow(long elanTag, BigInteger dpId, String ifName, String macAddress,
-            ElanInstance elanInfo, IMdsalApiManager mdsalApiManager, long ifTag, WriteTransaction writeFlowGroupTx) {
+            ElanInstance elanInfo, IMdsalApiManager mdsalApiManager, long ifTag,
+            TypedWriteTransaction<Configuration> writeFlowGroupTx) {
         Flow flowEntity = buildLocalDmacFlowEntry(elanTag, dpId, ifName, macAddress, elanInfo, ifTag);
-        mdsalApiManager.addFlowToTx(dpId, flowEntity, writeFlowGroupTx);
-        installEtreeLocalDmacFlow(elanTag, dpId, ifName, macAddress, elanInfo,
-                ifTag, writeFlowGroupTx);
+        mdsalApiManager.addFlow(writeFlowGroupTx, dpId, flowEntity);
+        installEtreeLocalDmacFlow(elanTag, dpId, ifName, macAddress, elanInfo, ifTag, writeFlowGroupTx);
     }
 
     private void installEtreeLocalDmacFlow(long elanTag, BigInteger dpId, String ifName, String macAddress,
-            ElanInstance elanInfo, long ifTag, WriteTransaction writeFlowGroupTx) {
+            ElanInstance elanInfo, long ifTag, TypedWriteTransaction<Configuration> writeFlowGroupTx) {
         EtreeInterface etreeInterface = elanInterfaceCache.getEtreeInterface(ifName).orNull();
         if (etreeInterface != null && etreeInterface.getEtreeInterfaceType() == EtreeInterfaceType.Root) {
             EtreeLeafTagName etreeTagName = elanEtreeUtils.getEtreeLeafTagByElanTag(elanTag);
@@ -884,7 +898,7 @@ public class ElanUtils {
             } else {
                 Flow flowEntity = buildLocalDmacFlowEntry(etreeTagName.getEtreeLeafTag().getValue(), dpId, ifName,
                         macAddress, elanInfo, ifTag);
-                mdsalManager.addFlowToTx(dpId, flowEntity, writeFlowGroupTx);
+                mdsalManager.addFlow(writeFlowGroupTx, dpId, flowEntity);
             }
         }
     }
@@ -948,9 +962,9 @@ public class ElanUtils {
         return flow;
     }
 
-    public void setupRemoteDmacFlow(BigInteger srcDpId, BigInteger destDpId, int lportTag, long elanTag, String
-            macAddress, String displayName, WriteTransaction writeFlowGroupTx, String interfaceName, ElanInstance
-            elanInstance) {
+    public void setupRemoteDmacFlow(BigInteger srcDpId, BigInteger destDpId, int lportTag, long elanTag,
+            String macAddress, String displayName, TypedWriteTransaction<Configuration> writeFlowGroupTx,
+            String interfaceName, ElanInstance elanInstance) {
         if (interfaceManager.isExternalInterface(interfaceName)) {
             LOG.debug("Ignoring install remote DMAC {} flow on provider interface {} elan {}",
                     macAddress, interfaceName, elanInstance.getElanInstanceName());
@@ -963,14 +977,15 @@ public class ElanUtils {
                 ? getVxlanSegmentationId(elanInstance) : 0;
         flowEntity = buildRemoteDmacFlowEntry(srcDpId, destDpId, lportTagOrVni, elanTag, macAddress, displayName,
                 elanInstance);
-        mdsalManager.addFlowToTx(srcDpId, flowEntity, writeFlowGroupTx);
+        mdsalManager.addFlow(writeFlowGroupTx, srcDpId, flowEntity);
         setupEtreeRemoteDmacFlow(srcDpId, destDpId, lportTagOrVni, elanTag, macAddress, displayName, interfaceName,
                 writeFlowGroupTx, elanInstance);
     }
 
     private void setupEtreeRemoteDmacFlow(BigInteger srcDpId, BigInteger destDpId, long lportTagOrVni, long elanTag,
                                           String macAddress, String displayName, String interfaceName,
-                                          WriteTransaction writeFlowGroupTx, ElanInstance elanInstance) {
+                                          TypedWriteTransaction<Configuration> writeFlowGroupTx,
+                                          ElanInstance elanInstance) {
         Flow flowEntity;
         EtreeInterface etreeInterface = elanInterfaceCache.getEtreeInterface(interfaceName).orNull();
         if (etreeInterface != null && etreeInterface.getEtreeInterfaceType() == EtreeInterfaceType.Root) {
@@ -981,7 +996,7 @@ public class ElanUtils {
             } else {
                 flowEntity = buildRemoteDmacFlowEntry(srcDpId, destDpId, lportTagOrVni,
                         etreeTagName.getEtreeLeafTag().getValue(), macAddress, displayName, elanInstance);
-                mdsalManager.addFlowToTx(srcDpId, flowEntity, writeFlowGroupTx);
+                mdsalManager.addFlow(writeFlowGroupTx, srcDpId, flowEntity);
             }
         }
     }
@@ -1139,13 +1154,14 @@ public class ElanUtils {
      *            the elan instance added
      * @param elanInterfaces
      *            the elan interfaces
-     * @param tx
+     * @param operTx
      *            transaction
      *
      * @return the updated ELAN instance.
      */
     public static ElanInstance updateOperationalDataStore(IdManagerService idManager,
-            ElanInstance elanInstanceAdded, List<String> elanInterfaces, WriteTransaction tx) {
+            ElanInstance elanInstanceAdded, List<String> elanInterfaces, TypedWriteTransaction<Configuration> confTx,
+            TypedWriteTransaction<Operational> operTx) {
         String elanInstanceName = elanInstanceAdded.getElanInstanceName();
         Long elanTag = elanInstanceAdded.getElanTag();
         if (elanTag == null || elanTag == 0L) {
@@ -1155,13 +1171,11 @@ public class ElanUtils {
                 .withKey(new ElanKey(elanInstanceName)).build();
 
         // Add the ElanState in the elan-state operational data-store
-        tx.put(LogicalDatastoreType.OPERATIONAL, getElanInstanceOperationalDataPath(elanInstanceName),
-                elanInfo, WriteTransaction.CREATE_MISSING_PARENTS);
+        operTx.put(getElanInstanceOperationalDataPath(elanInstanceName), elanInfo, CREATE_MISSING_PARENTS);
 
         // Add the ElanMacTable in the elan-mac-table operational data-store
         MacTable elanMacTable = new MacTableBuilder().withKey(new MacTableKey(elanInstanceName)).build();
-        tx.put(LogicalDatastoreType.OPERATIONAL, getElanMacTableOperationalDataPath(elanInstanceName),
-                elanMacTable, WriteTransaction.CREATE_MISSING_PARENTS);
+        operTx.put(getElanMacTableOperationalDataPath(elanInstanceName), elanMacTable, CREATE_MISSING_PARENTS);
 
         ElanTagNameBuilder elanTagNameBuilder = new ElanTagNameBuilder().setElanTag(elanTag)
                 .withKey(new ElanTagNameKey(elanTag)).setName(elanInstanceName);
@@ -1172,14 +1186,13 @@ public class ElanUtils {
             EtreeLeafTagName etreeLeafTagName = new EtreeLeafTagNameBuilder()
                     .setEtreeLeafTag(new EtreeLeafTag(etreeLeafTag)).build();
             elanTagNameBuilder.addAugmentation(EtreeLeafTagName.class, etreeLeafTagName);
-            addTheLeafTagAsElanTag(elanInstanceName, etreeLeafTag, tx);
+            addTheLeafTagAsElanTag(elanInstanceName, etreeLeafTag, operTx);
         }
         ElanTagName elanTagName = elanTagNameBuilder.build();
 
         // Add the ElanTag to ElanName in the elan-tag-name Operational
         // data-store
-        tx.put(LogicalDatastoreType.OPERATIONAL,
-                getElanInfoEntriesOperationalDataPath(elanTag), elanTagName);
+        operTx.put(getElanInfoEntriesOperationalDataPath(elanTag), elanTagName);
 
         // Updates the ElanInstance Config DS by setting the just acquired
         // elanTag
@@ -1194,16 +1207,16 @@ public class ElanUtils {
             elanInstanceBuilder.addAugmentation(EtreeInstance.class, etreeInstance);
         }
         ElanInstance elanInstanceWithTag = elanInstanceBuilder.build();
-        tx.merge(LogicalDatastoreType.CONFIGURATION, ElanHelper.getElanInstanceConfigurationDataPath(elanInstanceName),
-                elanInstanceWithTag, WriteTransaction.CREATE_MISSING_PARENTS);
+        confTx.merge(ElanHelper.getElanInstanceConfigurationDataPath(elanInstanceName), elanInstanceWithTag,
+            CREATE_MISSING_PARENTS);
         return elanInstanceWithTag;
     }
 
-    private static void addTheLeafTagAsElanTag(String elanInstanceName, long etreeLeafTag, WriteTransaction tx) {
+    private static void addTheLeafTagAsElanTag(String elanInstanceName, long etreeLeafTag,
+            TypedWriteTransaction<Operational> tx) {
         ElanTagName etreeTagAsElanTag = new ElanTagNameBuilder().setElanTag(etreeLeafTag)
                 .withKey(new ElanTagNameKey(etreeLeafTag)).setName(elanInstanceName).build();
-        tx.put(LogicalDatastoreType.OPERATIONAL,
-                getElanInfoEntriesOperationalDataPath(etreeLeafTag), etreeTagAsElanTag);
+        tx.put(getElanInfoEntriesOperationalDataPath(etreeLeafTag), etreeTagAsElanTag);
     }
 
     private static boolean isEtreeInstance(ElanInstance elanInstanceAdded) {
@@ -1404,6 +1417,17 @@ public class ElanUtils {
         return futures;
     }
 
+    @CheckReturnValue
+    public static ListenableFuture<Void> waitForTransactionToComplete(ListenableFuture<Void> future) {
+        try {
+            future.get();
+        } catch (InterruptedException | ExecutionException e) {
+            // NETVIRT-1215: Do not log.error() here, only debug(); but callers *MUST* @CheckReturnValue
+            LOG.debug("Error writing to datastore", e);
+        }
+        return future;
+    }
+
     public static boolean isVxlan(@Nullable ElanInstance elanInstance) {
         return elanInstance != null && elanInstance.getSegmentType() != null
                 && elanInstance.getSegmentType().isAssignableFrom(SegmentTypeVxlan.class)
@@ -1646,9 +1670,7 @@ public class ElanUtils {
         IfTunnel ifTunnel = configIface.augmentation(IfTunnel.class);
         if (ifTunnel != null && ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class)) {
             ParentRefs refs = configIface.augmentation(ParentRefs.class);
-            if (refs != null && !Strings.isNullOrEmpty(refs.getParentInterface())) {
-                return true; //multiple VxLAN tunnels enabled, i.e. only logical tunnel should be treated
-            }
+            return refs != null && !Strings.isNullOrEmpty(refs.getParentInterface());
         }
         return false;
     }
index aa196121d8bdb9abf7842fd7b570b52fef7254ad..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,19 +21,22 @@ 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.ReadTransaction;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-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.genius.datastoreutils.SingleTransactionDataBroker;
+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;
@@ -79,6 +84,7 @@ public class TransportZoneNotificationUtil {
     private static final String ALL_SUBNETS_GW = "0.0.0.0";
     private static final String ALL_SUBNETS = "0.0.0.0/0";
     private final ManagedNewTransactionRunner txRunner;
+    private final SingleTransactionDataBroker singleTxBroker;
     private final SouthboundUtils southBoundUtils;
     private final IElanService elanService;
     private final ElanConfig elanConfig;
@@ -90,6 +96,7 @@ public class TransportZoneNotificationUtil {
             final IElanService elanService, final ElanConfig elanConfig, final ElanBridgeManager elanBridgeManager,
             final ElanInstanceCache elanInstanceCache) {
         this.txRunner = new ManagedNewTransactionRunnerImpl(dbx);
+        this.singleTxBroker = new SingleTransactionDataBroker(dbx);
         this.elanService = elanService;
         this.elanConfig = elanConfig;
         this.elanBridgeManager = elanBridgeManager;
@@ -129,17 +136,18 @@ public class TransportZoneNotificationUtil {
         return tzb.build();
     }
 
-    private void updateTransportZone(TransportZone zone, BigInteger dpnId, @Nonnull WriteTransaction tx) {
+    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();
 
-        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) {
-        ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
-            Map<String, String> localIps = getDpnLocalIps(dpnId, tx);
+        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);
@@ -150,19 +158,20 @@ public class TransportZoneNotificationUtil {
                     updateTransportZone(zoneName, dpnId, localIp, tx);
                 }
             } else {
-                updateTransportZone(zoneNamePrefix, dpnId, getDpnLocalIp(dpnId, tx), tx);
+                updateTransportZone(zoneNamePrefix, dpnId, getDpnLocalIp(dpnId), tx);
             }
         }), LOG, "Error updating transport zone");
     }
 
     @SuppressWarnings("checkstyle:IllegalCatch")
     private void updateTransportZone(String zoneName, BigInteger dpnId, @Nullable String localIp,
-            @Nonnull ReadWriteTransaction tx) throws ReadFailedException {
+            @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 = tx.read(LogicalDatastoreType.CONFIGURATION, inst).checkedGet().orNull();
+        TransportZone zone = tx.read(inst).get().orNull();
 
         if (zone == null) {
             zone = createZone(ALL_SUBNETS, zoneName);
@@ -177,16 +186,17 @@ public class TransportZoneNotificationUtil {
         }
     }
 
-    private void deleteTransportZone(TransportZone zone, BigInteger dpnId, @Nonnull WriteTransaction tx) {
+    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();
-        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) {
-        ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
-            Map<String, String> localIps = getDpnLocalIps(dpnId, tx);
+        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);
@@ -201,13 +211,13 @@ public class TransportZoneNotificationUtil {
     }
 
     @SuppressWarnings("checkstyle:IllegalCatch")
-    private void deleteTransportZone(String zoneName, BigInteger dpnId, @Nonnull ReadWriteTransaction tx)
-            throws ReadFailedException {
+    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 = tx.read(LogicalDatastoreType.CONFIGURATION, inst).checkedGet().orNull();
+        TransportZone zone = tx.read(inst).get().orNull();
         if (zone != null) {
             try {
                 deleteTransportZone(zone, dpnId, tx);
@@ -255,7 +265,7 @@ public class TransportZoneNotificationUtil {
             return;
         }
 
-        ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
+        ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
             BigInteger dpId = dpIdOpt.get();
             Optional<DPNTEPsInfo> dpnTepsInfoOpt = getDpnTepsInfo(dpId, tx);
             if (!dpnTepsInfoOpt.isPresent()) {
@@ -281,7 +291,7 @@ public class TransportZoneNotificationUtil {
     }
 
     private void handleAddedLocalIps(Map<String, String> addedEntries, BigInteger dpId, Set<String> zonePrefixes,
-            ReadWriteTransaction tx) throws ReadFailedException {
+            TypedReadWriteTransaction<Configuration> tx) throws ExecutionException, InterruptedException {
         if (addedEntries == null || addedEntries.isEmpty()) {
             LOG.trace("No added local_ips found for DPN {}", dpId);
             return;
@@ -299,8 +309,8 @@ public class TransportZoneNotificationUtil {
     }
 
     private void handleChangedLocalIps(Map<String, ValueDifference<String>> changedEntries, BigInteger dpId,
-            Set<String> zonePrefixes, Map<String, List<String>> tepTzMap, @Nonnull ReadWriteTransaction tx)
-            throws ReadFailedException {
+            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;
@@ -329,7 +339,7 @@ public class TransportZoneNotificationUtil {
     }
 
     private void handleRemovedLocalIps(Map<String, String> removedEntries, BigInteger dpId, Set<String> zonePrefixes,
-            Map<String, List<String>> tepTzMap, @Nonnull 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;
@@ -361,12 +371,12 @@ public class TransportZoneNotificationUtil {
                 .collect(Collectors.toList());
     }
 
-    private Optional<DPNTEPsInfo> getDpnTepsInfo(BigInteger dpId, ReadTransaction tx) {
+    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 tx.read(LogicalDatastoreType.CONFIGURATION, identifier).checkedGet();
-        } 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();
         }
@@ -401,12 +411,12 @@ public class TransportZoneNotificationUtil {
         return false;
     }
 
-    private void removeVtep(String zoneName, BigInteger dpId, @Nonnull 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(IpPrefixBuilder.getDefaultInstance(ALL_SUBNETS)))
                 .child(Vteps.class, new VtepsKey(dpId, TUNNEL_PORT)).build();
-        tx.delete(LogicalDatastoreType.CONFIGURATION, path);
+        tx.delete(path);
     }
 
     // search for relevant subnets for the given subnetIP, add one if it is
@@ -434,8 +444,8 @@ public class TransportZoneNotificationUtil {
         return subnetsBuilder.build();
     }
 
-    private String getDpnLocalIp(BigInteger dpId, ReadTransaction tx) throws ReadFailedException {
-        Optional<Node> node = getPortsNode(dpId, tx);
+    private String getDpnLocalIp(BigInteger dpId) throws ReadFailedException {
+        Optional<Node> node = getPortsNode(dpId);
 
         if (node.isPresent()) {
             String localIp = southBoundUtils.getOpenvswitchOtherConfig(node.get(), LOCAL_IP);
@@ -451,21 +461,21 @@ public class TransportZoneNotificationUtil {
     }
 
     @Nonnull
-    private Map<String, String> getDpnLocalIps(BigInteger dpId, ReadTransaction tx) throws ReadFailedException {
+    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"
-        return getPortsNode(dpId, tx).toJavaUtil().map(
+        return getPortsNode(dpId).toJavaUtil().map(
             node -> elanBridgeManager.getOpenvswitchOtherConfigMap(node, LOCAL_IPS)).orElse(Collections.emptyMap());
     }
 
     @SuppressWarnings("unchecked")
-    private Optional<Node> getPortsNode(BigInteger dpnId, ReadTransaction tx) throws ReadFailedException {
+    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
         Optional<BridgeRefEntry> optionalBridgeRefEntry =
-                tx.read(LogicalDatastoreType.OPERATIONAL, bridgeRefInfoPath).checkedGet();
+            singleTxBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL, bridgeRefInfoPath);
         if (!optionalBridgeRefEntry.isPresent()) {
             LOG.error("no bridge ref entry found for dpnId {}", dpnId);
             return Optional.absent();
@@ -475,7 +485,7 @@ public class TransportZoneNotificationUtil {
                 optionalBridgeRefEntry.get().getBridgeReference().getValue().firstIdentifierOf(Node.class);
 
         // FIXME: Read this through a cache
-        Optional<Node> optionalNode = tx.read(LogicalDatastoreType.OPERATIONAL, nodeId).checkedGet();
+        Optional<Node> optionalNode = singleTxBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL, nodeId);
         if (!optionalNode.isPresent()) {
             LOG.error("missing node for dpnId {}", dpnId);
         }
index aab49cb7c9527e5b0edf0c3288615810c8704017..95bc6119d1c9ff3c6e56e556b82d709d7ae6777b 100644 (file)
@@ -7,8 +7,8 @@
  */
 package org.opendaylight.netvirt.elan.l2gw.nodehandlertest;
 
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
 
 import com.google.common.base.Optional;
 import java.util.UUID;
@@ -17,8 +17,10 @@ import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mockito;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.binding.test.AbstractConcurrentDataBrokerTest;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
 import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
 import org.opendaylight.netvirt.elan.l2gw.ha.handlers.NodeConnectedHandler;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
@@ -107,29 +109,33 @@ public class NodeConnectedHandlerTest extends AbstractConcurrentDataBrokerTest {
 
     @Test
     public void testD1Connect() throws Exception {
-        ReadWriteTransaction tx = getDataBroker().newReadWriteTransaction();
-        handlerUtils.addPsNode(d1PsNodePath, d1NodePath, DataProvider.getPortNameListD1(), tx).checkedGet();
+        ManagedNewTransactionRunner txRunner = new ManagedNewTransactionRunnerImpl(getDataBroker());
+        txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
+            tx -> handlerUtils.addPsNode(d1PsNodePath, d1NodePath, DataProvider.getPortNameListD1(), tx)).get();
 
-        tx = getDataBroker().newReadWriteTransaction();
-        handlerUtils.addNode(d1NodePath, d1PsNodePath, DataProvider.getLogicalSwitchDataD1(),
+        txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
+            tx -> handlerUtils.addNode(d1NodePath, d1PsNodePath, DataProvider.getLogicalSwitchDataD1(),
                 DataProvider.getLocalUcasMacDataD1(), DataProvider.getLocalMcastDataD1(),
                 DataProvider.getRemoteMcastDataD1(), DataProvider.getRemoteUcasteMacDataD1(),
-                DataProvider.getGlobalTerminationPointIpD1(), tx).checkedGet();
+                DataProvider.getGlobalTerminationPointIpD1(), tx)).get();
 
         readNodes();
-        tx = getDataBroker().newReadWriteTransaction();
-        nodeConnectedHandler.handleNodeConnected(d1GlobalOpNode.get(), d1NodePath, haNodePath, haGlobalConfigNode,
-                haPsConfigNode, tx);
-        tx.submit().checkedGet();
+        txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+            confTx -> txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL,
+                operTx -> nodeConnectedHandler.handleNodeConnected(d1GlobalOpNode.get(), d1NodePath, haNodePath,
+                    haGlobalConfigNode, haPsConfigNode, confTx, operTx)).get()).get();
         readNodes();
         //verify global ha manager config should have ha_children
-        Assert.assertTrue(haGlobalConfigNode.isPresent() && d1GlobalOpNode.isPresent());
+        Assert.assertTrue(haGlobalConfigNode.isPresent());
+        Assert.assertTrue(d1GlobalOpNode.isPresent());
         TestUtil.verifyHAconfigNode(haGlobalConfigNode.get(), d1GlobalOpNode.get());
 
-        Assert.assertTrue(d1GlobalOpNode.isPresent() && haGlobalOpNode.isPresent() && d1PsOpNode.isPresent()
-                && haPsOpNode.isPresent());
+        Assert.assertTrue(d1GlobalOpNode.isPresent());
+        Assert.assertTrue(haGlobalOpNode.isPresent());
+        Assert.assertTrue(d1PsOpNode.isPresent());
+        Assert.assertTrue(haPsOpNode.isPresent());
         TestUtil.verifyHAOpNode(d1GlobalOpNode.get(), haGlobalOpNode.get(),
-                d1PsOpNode.get(), haPsOpNode.get(), haNodePath, d1PsNodePath, haPsNodePath, haNodeId, getDataBroker());
+                d1PsOpNode.get(), haPsOpNode.get(), haNodePath, d1PsNodePath, haPsNodePath, getDataBroker());
     }
 
     public static InstanceIdentifier<Node> createInstanceIdentifier(String nodeIdString) {
@@ -159,21 +165,21 @@ public class NodeConnectedHandlerTest extends AbstractConcurrentDataBrokerTest {
 
     public void readNodes() throws Exception {
         ReadOnlyTransaction tx = getDataBroker().newReadOnlyTransaction();
-        d1GlobalOpNode = TestUtil.readNode(OPERATIONAL, d1NodePath, tx);
-        d2GlobalOpNode = TestUtil.readNode(OPERATIONAL, d2NodePath, tx);
-        haGlobalOpNode = TestUtil.readNode(OPERATIONAL, haNodePath, tx);
+        d1GlobalOpNode = TestUtil.readNode(LogicalDatastoreType.OPERATIONAL, d1NodePath, tx);
+        d2GlobalOpNode = TestUtil.readNode(LogicalDatastoreType.OPERATIONAL, d2NodePath, tx);
+        haGlobalOpNode = TestUtil.readNode(LogicalDatastoreType.OPERATIONAL, haNodePath, tx);
 
-        d1PsOpNode = TestUtil.readNode(OPERATIONAL, d1PsNodePath, tx);
-        d2PsOpNode = TestUtil.readNode(OPERATIONAL, d2PsNodePath, tx);
-        haPsOpNode = TestUtil.readNode(OPERATIONAL, haPsNodePath, tx);
+        d1PsOpNode = TestUtil.readNode(LogicalDatastoreType.OPERATIONAL, d1PsNodePath, tx);
+        d2PsOpNode = TestUtil.readNode(LogicalDatastoreType.OPERATIONAL, d2PsNodePath, tx);
+        haPsOpNode = TestUtil.readNode(LogicalDatastoreType.OPERATIONAL, haPsNodePath, tx);
 
-        haGlobalConfigNode = TestUtil.readNode(CONFIGURATION, haNodePath, tx);
-        d1GlobalConfigNode = TestUtil.readNode(CONFIGURATION, d1NodePath, tx);
-        d2GlobalConfigNode = TestUtil.readNode(CONFIGURATION, d2NodePath, tx);
+        haGlobalConfigNode = TestUtil.readNode(LogicalDatastoreType.CONFIGURATION, haNodePath, tx);
+        d1GlobalConfigNode = TestUtil.readNode(LogicalDatastoreType.CONFIGURATION, d1NodePath, tx);
+        d2GlobalConfigNode = TestUtil.readNode(LogicalDatastoreType.CONFIGURATION, d2NodePath, tx);
 
-        haPsConfigNode = TestUtil.readNode(CONFIGURATION, haPsNodePath, tx);
-        d1PsConfigNode = TestUtil.readNode(CONFIGURATION, d1PsNodePath, tx);
-        d2PsConfigNode = TestUtil.readNode(CONFIGURATION, d2PsNodePath, tx);
+        haPsConfigNode = TestUtil.readNode(LogicalDatastoreType.CONFIGURATION, haPsNodePath, tx);
+        d1PsConfigNode = TestUtil.readNode(LogicalDatastoreType.CONFIGURATION, d1PsNodePath, tx);
+        d2PsConfigNode = TestUtil.readNode(LogicalDatastoreType.CONFIGURATION, d2PsNodePath, tx);
 
         tx.close();
     }
index 440e16482c4cdd6b0d690535606d9450a72780b6..a1423d95482962c6a36d4add4b28b5f92ec3e721 100644 (file)
@@ -7,15 +7,14 @@
  */
 package org.opendaylight.netvirt.elan.l2gw.nodehandlertest;
 
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
+import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
 
-import com.google.common.util.concurrent.CheckedFuture;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.UUID;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
 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.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
@@ -37,14 +36,12 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
  */
 public class NodeConnectedHandlerUtils {
 
-    CheckedFuture<Void, TransactionCommitFailedException> addNode(InstanceIdentifier<Node> path,
+    void addNode(InstanceIdentifier<Node> path,
             InstanceIdentifier<Node> psPath, String logicalSwitchData, String localUcasMacData, String localMcastData,
             String remoteMcastData, String remoteUcasteMacData, String globalTerminationPointIp,
-            WriteTransaction transaction) throws Exception {
-        NodeBuilder nodeBuilder = null;
-        HwvtepGlobalAugmentationBuilder augmentationBuilder = null;
-        nodeBuilder = prepareOperationalNode(path);
-        augmentationBuilder = prepareAugmentationBuilder();
+            TypedWriteTransaction<Operational> tx) {
+        NodeBuilder nodeBuilder = prepareOperationalNode(path);
+        HwvtepGlobalAugmentationBuilder augmentationBuilder = prepareAugmentationBuilder();
 
         GlobalAugmentationHelper.addLogicalSwitches(augmentationBuilder, getData(logicalSwitchData));
 
@@ -62,15 +59,11 @@ public class NodeConnectedHandlerUtils {
 
         nodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, augmentationBuilder.build());
 
-        return TestUtil.submitNode(OPERATIONAL, path, nodeBuilder.build(), transaction);
+        tx.put(path, nodeBuilder.build());
     }
 
-    CheckedFuture<Void, TransactionCommitFailedException> addPsNode(InstanceIdentifier<Node> path,
-            InstanceIdentifier<Node> parentPath, List<String> portNameList, WriteTransaction transaction)
-            throws Exception {
-        NodeBuilder nodeBuilder = null;
-
-        nodeBuilder = prepareOperationalNode(path);
+    void addPsNode(InstanceIdentifier<Node> path, InstanceIdentifier<Node> parentPath, List<String> portNameList,
+            TypedWriteTransaction<Operational> tx) {
         PhysicalSwitchAugmentationBuilder physicalSwitchAugmentationBuilder = new PhysicalSwitchAugmentationBuilder();
         physicalSwitchAugmentationBuilder.setManagedBy(new HwvtepGlobalRef(parentPath));
         physicalSwitchAugmentationBuilder.setPhysicalSwitchUuid(getUUid("d1s3"));
@@ -82,27 +75,28 @@ public class NodeConnectedHandlerUtils {
         tunnelIps.add(new TunnelIpsBuilder().withKey(new TunnelIpsKey(ip)).setTunnelIpsKey(ip).build());
         physicalSwitchAugmentationBuilder.setTunnelIps(tunnelIps);
 
+        NodeBuilder nodeBuilder = prepareOperationalNode(path);
         nodeBuilder.addAugmentation(PhysicalSwitchAugmentation.class, physicalSwitchAugmentationBuilder.build());
         PhysicalSwitchHelper.dId = parentPath;
         nodeBuilder.setTerminationPoint(PhysicalSwitchHelper
-                .addPhysicalSwitchTerminationPoints(path, transaction, portNameList));
+                .addPhysicalSwitchTerminationPoints(path, portNameList));
 
-        return TestUtil.submitNode(OPERATIONAL, path, nodeBuilder.build(), transaction);
+        tx.put(path, nodeBuilder.build(), CREATE_MISSING_PARENTS);
     }
 
-    NodeBuilder prepareOperationalNode(InstanceIdentifier<Node> iid) {
+    private NodeBuilder prepareOperationalNode(InstanceIdentifier<Node> iid) {
         NodeBuilder nodeBuilder = new NodeBuilder();
         nodeBuilder.setNodeId(iid.firstKeyOf(Node.class).getNodeId());
         return nodeBuilder;
     }
 
-    HwvtepGlobalAugmentationBuilder prepareAugmentationBuilder() {
+    private HwvtepGlobalAugmentationBuilder prepareAugmentationBuilder() {
         HwvtepGlobalAugmentationBuilder builder = new HwvtepGlobalAugmentationBuilder();
         builder.setManagers(TestBuilders.buildManagers());
         return builder;
     }
 
-    public List<String> getData(String data) {
+    private List<String> getData(String data) {
         return Arrays.asList(data.split(","));
     }
 
index f840487dd33448842113a60770f6473d46fd2634..35f7f6264e4887386066bb6bbe5b87f6dad49752 100644 (file)
@@ -12,7 +12,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
@@ -38,15 +37,11 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Created by eaksahu on 8/8/2016.
  */
 public final class PhysicalSwitchHelper {
-    static Logger LOG = LoggerFactory.getLogger(PhysicalSwitchHelper.class);
-
     static InstanceIdentifier<Node> dId;
 
     private PhysicalSwitchHelper() { }
@@ -64,26 +59,22 @@ public final class PhysicalSwitchHelper {
                 .build();
     }
 
-    public static List<TerminationPoint> addPhysicalSwitchTerminationPoints(InstanceIdentifier<Node> switchIid,
-                                                                            WriteTransaction transaction,
-                                                                            List<String> portNames) {
+    static List<TerminationPoint> addPhysicalSwitchTerminationPoints(InstanceIdentifier<Node> switchIid,
+        List<String> portNames) {
         List<TerminationPoint> tps = new ArrayList<>();
         for (String portName : portNames) {
-            tps.add(buildTerminationPointForPhysicalSwitch(switchIid, portName, transaction, getVlanBindingData(1)));
+            tps.add(buildTerminationPointForPhysicalSwitch(switchIid, portName, getVlanBindingData(1)));
         }
         return tps;
     }
 
-    public static TerminationPoint buildTerminationPointForPhysicalSwitch(InstanceIdentifier<Node> switchIid,
-                                                                          String portName, WriteTransaction transaction,
-                                                                          Map<Long, String> vlanBindingData) {
+    private static TerminationPoint buildTerminationPointForPhysicalSwitch(InstanceIdentifier<Node> switchIid,
+        String portName, Map<Long, String> vlanBindingData) {
         TerminationPointKey tpKey = new TerminationPointKey(new TpId(portName));
         TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
         tpBuilder.withKey(tpKey);
         tpBuilder.setTpId(tpKey.getTpId());
         switchIid.firstKeyOf(Node.class);
-        InstanceIdentifier<TerminationPoint> tpPath = switchIid.child(TerminationPoint.class,
-                new TerminationPointKey(new TpId(portName)));
         HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder =
                 new HwvtepPhysicalPortAugmentationBuilder();
         buildTerminationPoint(tpAugmentationBuilder, portName, vlanBindingData);
@@ -91,26 +82,26 @@ public final class PhysicalSwitchHelper {
         return tpBuilder.build();
     }
 
-    public static void buildTerminationPoint(HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder,
-                                             String portName, Map<Long, String> vlanBindingData) {
+    private static void buildTerminationPoint(HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder,
+            String portName, Map<Long, String> vlanBindingData) {
         updatePhysicalPortId(portName, tpAugmentationBuilder);
-        updatePort(portName, tpAugmentationBuilder, vlanBindingData);
+        updatePort(tpAugmentationBuilder, vlanBindingData);
     }
 
-    public static void updatePhysicalPortId(String portName,
-                                            HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder) {
+    private static void updatePhysicalPortId(String portName,
+            HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder) {
         tpAugmentationBuilder.setHwvtepNodeName(new HwvtepNodeName(portName));
         tpAugmentationBuilder.setHwvtepNodeDescription("");
     }
 
-    public static void updatePort(String portName, HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder,
-                                  Map<Long, String> vlanBindings) {
+    private static void updatePort(HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder,
+            Map<Long, String> vlanBindings) {
         updateVlanBindings(vlanBindings, tpAugmentationBuilder);
         tpAugmentationBuilder.setPhysicalPortUuid(new Uuid(UUID.randomUUID().toString()));
     }
 
-    public static void updateVlanBindings(Map<Long, String> vlanBindings,
-                                          HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder) {
+    private static void updateVlanBindings(Map<Long, String> vlanBindings,
+            HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder) {
         List<VlanBindings> vlanBindingsList = new ArrayList<>();
         for (Map.Entry<Long, String> vlanBindingEntry : vlanBindings.entrySet()) {
             Long vlanBindingKey = vlanBindingEntry.getKey();
@@ -122,7 +113,7 @@ public final class PhysicalSwitchHelper {
         tpAugmentationBuilder.setVlanBindings(vlanBindingsList);
     }
 
-    public static VlanBindings createVlanBinding(Long key, String logicalSwitch) {
+    private static VlanBindings createVlanBinding(Long key, String logicalSwitch) {
         VlanBindingsBuilder vbBuilder = new VlanBindingsBuilder();
         VlanBindingsKey vbKey = new VlanBindingsKey(new VlanId(key.intValue()));
         vbBuilder.withKey(vbKey);
@@ -133,23 +124,21 @@ public final class PhysicalSwitchHelper {
         return vbBuilder.build();
     }
 
-    public static InstanceIdentifier<LogicalSwitches> createInstanceIdentifier(String logicalSwitch) {
+    private static InstanceIdentifier<LogicalSwitches> createInstanceIdentifier(String logicalSwitch) {
         NodeId id = dId.firstKeyOf(Node.class).getNodeId();
         NodeKey nodeKey = new NodeKey(id);
-        InstanceIdentifier<LogicalSwitches> iid = null;
-        iid = InstanceIdentifier.builder(NetworkTopology.class)
+        return InstanceIdentifier.builder(NetworkTopology.class)
                 .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID))
                 .child(Node.class, nodeKey).augmentation(HwvtepGlobalAugmentation.class)
                 .child(LogicalSwitches.class, new LogicalSwitchesKey(new HwvtepNodeName(logicalSwitch)))
                 .build();
-        return iid;
     }
 
-    public static Map<Long, String> getVlanBindingData(int mapSize) {
+    private static Map<Long, String> getVlanBindingData(int mapSize) {
         Map<Long, String> vlanBindings = new HashMap<>();
-        for (Integer i = 0; i < mapSize; i++) {
+        for (long i = 0; i < mapSize; i++) {
             i = i * 100;
-            vlanBindings.put(Long.valueOf(i), "9227c228-6bba-4bbe-bdb8-6942768ff0f1");
+            vlanBindings.put(i, "9227c228-6bba-4bbe-bdb8-6942768ff0f1");
         }
         return vlanBindings;
     }
index 4b5f20bfca5c2d4cda9b548538c322824c30feaf..a3ffa638d2df06ee2a0df97ab9431172d246c616 100644 (file)
@@ -8,45 +8,27 @@
 package org.opendaylight.netvirt.elan.l2gw.nodehandlertest;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
 
 import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import java.util.Arrays;
-import java.util.List;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 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;
-import org.slf4j.LoggerFactory;
 
 /**
  * Created by eaksahu on 8/12/2016.
  */
-public final class TestUtil {
-    static Logger LOG = LoggerFactory.getLogger(TestUtil.class);
+final class TestUtil {
 
     private TestUtil() { }
 
-    public static void deleteNode(ReadWriteTransaction tx, InstanceIdentifier<Node> id) throws Exception {
-        tx.delete(OPERATIONAL, id);
-        tx.submit().checkedGet();
-    }
-
-    public static void verifyHAOpNode(Node d1GlobalOpNode, Node haGlobalOpNode, Node d1PsOpNode, Node haPsOpNode,
-                                      InstanceIdentifier<Node> haId, InstanceIdentifier<Node> d1PsId,
-                                      InstanceIdentifier<Node> haPsId, NodeId haNodeId, DataBroker dataBroker)
-            throws ReadFailedException {
+    static void verifyHAOpNode(Node d1GlobalOpNode, Node haGlobalOpNode, Node d1PsOpNode, Node haPsOpNode,
+            InstanceIdentifier<Node> haId, InstanceIdentifier<Node> d1PsId, InstanceIdentifier<Node> haPsId,
+            DataBroker dataBroker) throws ReadFailedException {
         ReadWriteTransaction transaction = dataBroker.newReadWriteTransaction();
         TestComparators.compareLogicalSwitches(d1GlobalOpNode, haGlobalOpNode, haId);
         TestComparators.compareRemoteUcastMacs(d1GlobalOpNode, haGlobalOpNode, haId);
@@ -59,95 +41,16 @@ public final class TestUtil {
                 d1GlobalOpNode, haGlobalOpNode);
     }
 
-    public static void verifyHAOpNode(Node d1GlobalOpNode, Node d2GlobalOpNode, Node haGlobalOpNode,
-                                      Node d1PsOpNode, Node d2PsOpNode, Node haPsOpNode,
-                                      InstanceIdentifier<Node> haId, InstanceIdentifier<Node> d1PsId,
-                                      InstanceIdentifier<Node> d2PsId, InstanceIdentifier<Node> haPsId,
-                                      NodeId haNodeId, DataBroker dataBroker) throws ReadFailedException {
-        ReadWriteTransaction transaction = dataBroker.newReadWriteTransaction();
-        TestComparators.compareLogicalSwitches(d1GlobalOpNode, d2GlobalOpNode, haGlobalOpNode, haId);
-        TestComparators.compareRemoteUcastMacs(d1GlobalOpNode, d2GlobalOpNode, haGlobalOpNode, haId);
-        TestComparators.compareRemoteMcastMacs(d1GlobalOpNode, d2GlobalOpNode, haGlobalOpNode, haId);
-        TestComparators.compareLocalUcastMacs(d1GlobalOpNode, d2GlobalOpNode, haGlobalOpNode, haId);
-        TestComparators.compareLocalMcastMacs(d1GlobalOpNode, d2GlobalOpNode, haGlobalOpNode, haId);
-        TestComparators.verifySwitches(haGlobalOpNode, haPsOpNode);
-        TestComparators.verifySwitches(d1GlobalOpNode, d1PsOpNode);
-        TestComparators.verifySwitches(d2GlobalOpNode, d2PsOpNode);
-        TestComparators.comparePhysicalSwitches(d1PsOpNode, d2PsOpNode, haPsOpNode, d1PsId, d2PsId, haPsId,
-                transaction, "s3", d1GlobalOpNode, d2GlobalOpNode, haGlobalOpNode);
-    }
-
-    public static Node readNode(LogicalDatastoreType datastoreType, InstanceIdentifier<Node> id, DataBroker dataBroker)
-            throws Exception {
-        if (dataBroker.newReadWriteTransaction().read(datastoreType, id).checkedGet().isPresent()) {
-            return dataBroker.newReadWriteTransaction().read(datastoreType, id).checkedGet().get();
-        }
-        return null;
-    }
-
-    public static Optional<Node> readNode(LogicalDatastoreType datastoreType, InstanceIdentifier<Node> id,
-                                          ReadOnlyTransaction tx) throws Exception {
+    static Optional<Node> readNode(LogicalDatastoreType datastoreType, InstanceIdentifier<Node> id,
+        ReadOnlyTransaction tx) throws Exception {
         return tx.read(datastoreType, id).checkedGet();
     }
 
-    static void updateNode(LogicalDatastoreType datastoreType, InstanceIdentifier<Node> id, Node node,
-                           DataBroker dataBroker) throws Exception {
-        WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
-        transaction.merge(datastoreType, id, node, WriteTransaction.CREATE_MISSING_PARENTS);
-        transaction.submit();
-    }
-
-
-    static CheckedFuture<Void, TransactionCommitFailedException> submitNode(LogicalDatastoreType datastoreType,
-            InstanceIdentifier<Node> id, Node node, WriteTransaction transaction) throws Exception {
-        transaction.put(datastoreType, id, node, WriteTransaction.CREATE_MISSING_PARENTS);
-        return transaction.submit();
-    }
 
-    static Optional<Node> readNodeOptional(LogicalDatastoreType datastoreType, InstanceIdentifier<Node> id,
-                                           DataBroker dataBroker) throws Exception {
-        return dataBroker.newReadWriteTransaction().read(datastoreType, id).checkedGet();
-    }
-
-    public static void verifyHaAfterDelete(InstanceIdentifier<Node> nodeId, LogicalDatastoreType datastoreType,
-                                           String message, DataBroker dataBroker) throws Exception {
-        Optional<Node> nodeOptional = TestUtil.readNodeOptional(datastoreType, nodeId, dataBroker);
-        if (!message.contains("D2")) {
-            assertTrue(message, nodeOptional.isPresent());
-        } else {
-            assertFalse(message, nodeOptional.isPresent());
-        }
-        if (nodeOptional.isPresent()) {
-            LOG.info("Node data{}", nodeOptional.get());
-        }
-    }
-
-    public static void verifyHAconfigNode(InstanceIdentifier<Node> nodeId, DataBroker dataBroker, String message)
-            throws Exception {
-        Optional<Node> nodeOptional = TestUtil.readNodeOptional(LogicalDatastoreType.CONFIGURATION, nodeId, dataBroker);
-        assertTrue(message, nodeOptional.isPresent());
-        if (nodeOptional.isPresent()) {
-            nodeOptional.get().augmentation(HwvtepGlobalAugmentation.class).getManagers();
-        }
-    }
-
-    public static void verifyHAconfigNode(Node haConfig, Node d1Node) throws Exception {
+    static void verifyHAconfigNode(Node haConfig, Node d1Node) {
         String haid = haConfig.augmentation(HwvtepGlobalAugmentation.class).getManagers()
                 .get(0).getManagerOtherConfigs().get(0).getOtherConfigValue();
         String d1id = d1Node.getNodeId().getValue();
         assertEquals("Other config should contain D1 as child manager", haid, d1id);
     }
-
-    public static void verifyHAconfigNode(Node haConfig, Node d1Node, Node d2Node) throws Exception {
-        String haid = haConfig.augmentation(HwvtepGlobalAugmentation.class).getManagers()
-                .get(0).getManagerOtherConfigs().get(0).getOtherConfigValue();
-        String[] haids = haid.split(",");
-        List<String> haidSlist = Arrays.asList(haids);
-        assertEquals("Ha Other config size should be 2 after creationg of D2 Node", 2, haids.length);
-        String d1id = d1Node.getNodeId().getValue();
-        String d2id = d2Node.getNodeId().getValue();
-        assertTrue("ha should contain d1/d2 id as other config", haidSlist.contains(d1id));
-        assertTrue("ha should contain d1/d2 id as other config", haidSlist.contains(d2id));
-    }
-
 }
index 84f1b4aaafc019153dfeb8e32601763fb350c6c1..2416d2a96c08279784f19fdfadab5ddc2f506514 100644 (file)
@@ -11,6 +11,7 @@ import com.google.common.collect.Lists;
 import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -38,6 +39,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.Ordered;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
@@ -178,32 +180,32 @@ public class ElanServiceTestBase {
         /*ELAN1+":"+DPN1MAC1 ->
         (vlanInterfaceInfo(String interfaceName, BigInteger dpId, int portNo, int lportTag, String mac), vmPrefix)*/
         ELAN_INTERFACES.put(ELAN1 + ":" + DPN1MAC1 ,
-                new ImmutablePair(InterfaceHelper
+                ImmutablePair.of(InterfaceHelper
                         .buildVlanInterfaceInfo("23701c04-1118-4c65-9425-78a80d49a211",
                 DPN1_ID, 1, 10, DPN1MAC1), DPN1IP1));
 
         ELAN_INTERFACES.put(ELAN1 + ":" + DPN1MAC2 ,
-                new ImmutablePair(InterfaceHelper
+                ImmutablePair.of(InterfaceHelper
                         .buildVlanInterfaceInfo("23701c04-1218-4c65-9425-78a80d49a211",
                 DPN1_ID, 2, 11, DPN1MAC2), DPN1IP2));
 
         ELAN_INTERFACES.put(ELAN1 + ":" + DPN2MAC1 ,
-                new ImmutablePair(InterfaceHelper
+                ImmutablePair.of(InterfaceHelper
                         .buildVlanInterfaceInfo("23701c04-2118-4c65-9425-78a80d49a211",
                         DPN2_ID, 3, 12, DPN2MAC1), DPN2IP1));
 
         ELAN_INTERFACES.put(ELAN1 + ":" + DPN2MAC2 ,
-                new ImmutablePair(InterfaceHelper
+                ImmutablePair.of(InterfaceHelper
                         .buildVlanInterfaceInfo("23701c04-2218-4c65-9425-78a80d49a211",
                         DPN2_ID, 4, 13, DPN2MAC2), DPN2IP2));
 
         ELAN_INTERFACES.put(ELAN1 + ":" + DPN3MAC1 ,
-                new ImmutablePair(InterfaceHelper
+                ImmutablePair.of(InterfaceHelper
                         .buildVlanInterfaceInfo("23701c04-3118-4c65-9425-78a80d49a211",
                         DPN3_ID, 5, 14, DPN3MAC1), DPN3IP1));
 
         ELAN_INTERFACES.put(ELAN1 + ":" + DPN3MAC2 ,
-                new ImmutablePair(InterfaceHelper
+                ImmutablePair.of(InterfaceHelper
                         .buildVlanInterfaceInfo("23701c04-3218-4c65-9425-78a80d49a211",
                         DPN3_ID, 6, 15, DPN3MAC2), DPN3IP2));
 
@@ -291,7 +293,7 @@ public class ElanServiceTestBase {
         sortActions(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction input) {
         if (input instanceof  ApplyActionsCase) {
             List<Action> action = new ArrayList<>(((ApplyActionsCase)input).getApplyActions().getAction());
-            Collections.sort(action, (o1, o2) -> o1.getOrder().compareTo(o2.getOrder()));
+            action.sort(Comparator.comparing(Ordered::getOrder));
 
             ApplyActions actions = new ApplyActionsBuilder().setAction(action).build();
             return new ApplyActionsCaseBuilder().setApplyActions(actions).build();