NETVIRT-1630 migrate to md-sal APIs
[netvirt.git] / elanmanager / impl / src / main / java / org / opendaylight / netvirt / elan / evpn / utils / EvpnMacVrfUtils.java
index d7994d9605e4093145f798dfac734caf75ddec06..b25486c63b0d3b6a6d5ee9fafd31c037cfe2ac6f 100644 (file)
@@ -7,20 +7,23 @@
  */
 package org.opendaylight.netvirt.elan.evpn.utils;
 
-import com.google.common.base.Optional;
 import com.google.common.util.concurrent.ListenableFuture;
-import java.math.BigInteger;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
-import javax.annotation.Nullable;
+import java.util.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.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.genius.infra.Datastore;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.api.ReadTransaction;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.netvirt.elan.cache.ElanInstanceCache;
 import org.opendaylight.netvirt.elan.utils.ElanConstants;
 import org.opendaylight.netvirt.elan.utils.ElanUtils;
@@ -38,6 +41,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Evp
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.evpn.rd.to.networks.EvpnRdToNetwork;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.evpn.rd.to.networks.EvpnRdToNetworkKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.Uint32;
+import org.opendaylight.yangtools.yang.common.Uint64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -46,6 +51,7 @@ public class EvpnMacVrfUtils {
 
     private static final Logger LOG = LoggerFactory.getLogger(EvpnMacVrfUtils.class);
     private final DataBroker dataBroker;
+    private final ManagedNewTransactionRunner txRunner;
     private final IdManagerService idManager;
     private final ElanEvpnFlowUtils elanEvpnFlowUtils;
     private final IMdsalApiManager mdsalManager;
@@ -59,6 +65,7 @@ public class EvpnMacVrfUtils {
             final ElanEvpnFlowUtils elanEvpnFlowUtils, final IMdsalApiManager mdsalManager, final EvpnUtils evpnUtils,
             final JobCoordinator jobCoordinator, final ElanUtils elanUtils, final ElanInstanceCache elanInstanceCache) {
         this.dataBroker = dataBroker;
+        this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
         this.idManager = idManager;
         this.elanEvpnFlowUtils = elanEvpnFlowUtils;
         this.mdsalManager = mdsalManager;
@@ -69,45 +76,46 @@ public class EvpnMacVrfUtils {
     }
 
     @Nullable
-    private Long getElanTagByMacvrfiid(InstanceIdentifier<MacVrfEntry> macVrfEntryIid) {
+    private Uint32 getElanTagByMacvrfiid(InstanceIdentifier<MacVrfEntry> macVrfEntryIid) {
         String elanName = getElanNameByMacvrfiid(macVrfEntryIid);
         if (elanName == null) {
             LOG.error("getElanTag: elanName is NULL for iid = {}", macVrfEntryIid);
         }
-        ElanInstance elanInstance = elanInstanceCache.get(elanName).orNull();
+        ElanInstance elanInstance = elanInstanceCache.get(elanName).orElse(null);
         if (elanInstance == null) {
             return null;
         }
 
-        Long elanTag = elanInstance.getElanTag();
-        if (elanTag == null || elanTag == 0L) {
+        Uint32 elanTag = elanInstance.getElanTag();
+        if (elanTag == null || elanTag.longValue() == 0L) {
             elanTag = ElanUtils.retrieveNewElanTag(idManager, elanName);
         }
         return elanTag;
     }
 
     public String getElanNameByMacvrfiid(InstanceIdentifier<MacVrfEntry> instanceIdentifier) {
-        ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
-        String rd = instanceIdentifier.firstKeyOf(VrfTables.class).getRouteDistinguisher();
-        String elanName = null;
-        InstanceIdentifier<EvpnRdToNetwork> iidEvpnRdToNet =
-                InstanceIdentifier.builder(EvpnRdToNetworks.class).child(EvpnRdToNetwork.class,
-                        new EvpnRdToNetworkKey(rd)).build();
-        try {
-            Optional<EvpnRdToNetwork> evpnRdToNetwork =
-                    tx.read(LogicalDatastoreType.CONFIGURATION, iidEvpnRdToNet).checkedGet();
-            if (evpnRdToNetwork.isPresent()) {
-                elanName = evpnRdToNetwork.get().getNetworkId();
+        try (ReadTransaction tx = dataBroker.newReadOnlyTransaction()) {
+            String rd = instanceIdentifier.firstKeyOf(VrfTables.class).getRouteDistinguisher();
+            String elanName = null;
+            InstanceIdentifier<EvpnRdToNetwork> iidEvpnRdToNet =
+                    InstanceIdentifier.builder(EvpnRdToNetworks.class).child(EvpnRdToNetwork.class,
+                            new EvpnRdToNetworkKey(rd)).build();
+            try {
+                Optional<EvpnRdToNetwork> evpnRdToNetwork =
+                        tx.read(LogicalDatastoreType.CONFIGURATION, iidEvpnRdToNet).get();
+                if (evpnRdToNetwork.isPresent()) {
+                    elanName = evpnRdToNetwork.get().getNetworkId();
+                }
+            } catch (InterruptedException | ExecutionException e) {
+                LOG.error("getElanName: unable to read elanName, exception ", e);
             }
-        } catch (ReadFailedException e) {
-            LOG.error("getElanName: unable to read elanName, exception ", e);
+            return elanName;
         }
-        return elanName;
     }
 
     public InstanceIdentifier<MacVrfEntry> getMacVrfEntryIid(String rd, MacVrfEntry macVrfEntry) {
         return InstanceIdentifier.create(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd))
-                .child(MacVrfEntry.class, macVrfEntry.getKey());
+                .child(MacVrfEntry.class, macVrfEntry.key());
     }
 
     public void updateEvpnDmacFlows(final ElanInstance elanInstance, final boolean install) {
@@ -140,7 +148,7 @@ public class EvpnMacVrfUtils {
     }
 
     public boolean checkEvpnAttachedToNet(String elanName) {
-        ElanInstance elanInfo = elanInstanceCache.get(elanName).orNull();
+        ElanInstance elanInfo = elanInstanceCache.get(elanName).orElse(null);
         String evpnName = EvpnUtils.getEvpnNameFromElan(elanInfo);
         if (evpnName == null) {
             LOG.error("Error : evpnName is null for elanName {}", elanName);
@@ -161,29 +169,29 @@ public class EvpnMacVrfUtils {
             //TODO(Riyaz) : Check if accessing first nexthop address is right solution
             String nexthopIP = macVrfEntry.getRoutePaths().get(0).getNexthopAddress();
             IpAddress ipAddress = new IpAddress(new Ipv4Address(nexthopIP));
-            Long elanTag = getElanTagByMacvrfiid(instanceIdentifier);
+            Uint32 elanTag = getElanTagByMacvrfiid(instanceIdentifier);
             if (elanTag == null) {
                 return;
             }
 
             String dstMacAddress = macVrfEntry.getMac();
-            long vni = macVrfEntry.getL2vni();
-            jobCoordinator.enqueueJob(dstMacAddress, () -> {
-                List<ListenableFuture<Void>> futures = new ArrayList<>();
-                dpnInterfaceLists.forEach(dpnInterfaces -> {
-                    BigInteger dpId = dpnInterfaces.getDpId();
-                    LOG.info("ADD: Build DMAC flow with dpId {}, nexthopIP {}, elanTag {},"
-                                    + "vni {}, dstMacAddress {}, elanName {} ",
+            long vni = macVrfEntry.getL2vni().toJava();
+            jobCoordinator.enqueueJob(dstMacAddress, () -> Collections.singletonList(
+                txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.CONFIGURATION,
+                    tx -> dpnInterfaceLists.forEach(dpnInterfaces -> {
+                        Uint64 dpId = dpnInterfaces.getDpId();
+                        LOG.info("ADD: Build DMAC flow with dpId {}, nexthopIP {}, elanTag {},"
+                                + "vni {}, dstMacAddress {}, elanName {} ",
                             dpId, nexthopIP, elanTag, vni, dstMacAddress, elanName);
-                    ElanEvpnFlowUtils.EvpnDmacFlowBuilder dmacFlowBuilder = new ElanEvpnFlowUtils.EvpnDmacFlowBuilder();
-                    dmacFlowBuilder.setDpId(dpId).setNexthopIP(ipAddress.toString()).setElanTag(elanTag).setVni(vni)
-                            .setDstMacAddress(dstMacAddress).setElanName(elanName);
-                    Flow flow = elanEvpnFlowUtils.evpnBuildDmacFlowForExternalRemoteMac(dmacFlowBuilder.build());
+                        ElanEvpnFlowUtils.EvpnDmacFlowBuilder dmacFlowBuilder =
+                            new ElanEvpnFlowUtils.EvpnDmacFlowBuilder();
+                        dmacFlowBuilder.setDpId(dpId).setNexthopIP(ipAddress.toString()).setElanTag(elanTag.longValue())
+                            .setVni(vni).setDstMacAddress(dstMacAddress).setElanName(elanName);
+                        Flow flow =
+                            elanEvpnFlowUtils.evpnBuildDmacFlowForExternalRemoteMac(dmacFlowBuilder.build());
 
-                    futures.add(mdsalManager.installFlow(dpId, flow));
-                });
-                return futures;
-            }, ElanConstants.JOB_MAX_RETRIES);
+                        mdsalManager.addFlow(tx, dpId, flow);
+                    }))), ElanConstants.JOB_MAX_RETRIES);
         }
     }
 
@@ -199,7 +207,7 @@ public class EvpnMacVrfUtils {
         //TODO(Riyaz) : Check if accessing first nexthop address is right
         String nexthopIP = macVrfEntry.getRoutePaths().get(0).getNexthopAddress();
         IpAddress ipAddress = new IpAddress(new Ipv4Address(nexthopIP));
-        Long elanTag = getElanTagByMacvrfiid(instanceIdentifier);
+        Uint32 elanTag = getElanTagByMacvrfiid(instanceIdentifier);
         if (elanTag == null) {
             return;
         }
@@ -208,9 +216,9 @@ public class EvpnMacVrfUtils {
         jobCoordinator.enqueueJob(macToRemove, () -> {
             List<ListenableFuture<Void>> futures = new ArrayList<>();
             dpnInterfaceLists.forEach(dpnInterfaces -> {
-                BigInteger dpId = dpnInterfaces.getDpId();
+                Uint64 dpId = dpnInterfaces.getDpId();
                 ElanEvpnFlowUtils.EvpnDmacFlowBuilder dmacFlowBuilder = new ElanEvpnFlowUtils.EvpnDmacFlowBuilder();
-                dmacFlowBuilder.setDpId(dpId).setNexthopIP(ipAddress.toString()).setElanTag(elanTag)
+                dmacFlowBuilder.setDpId(dpId).setNexthopIP(ipAddress.toString()).setElanTag(elanTag.longValue())
                         .setDstMacAddress(macToRemove);
                 LOG.info("REMOVE: Deleting DMAC Flows for external MAC. elanTag {}, dpId {},"
                         + "nexthopIP {}, macToRemove {}", elanTag, dpId, nexthopIP, macToRemove);
@@ -238,27 +246,27 @@ public class EvpnMacVrfUtils {
                 return;
             }
             IpAddress ipAddress = new IpAddress(new Ipv4Address(nexthopIP));
-            Long elanTag = elanInstance.getElanTag();
+            Uint32 elanTag = elanInstance.getElanTag();
             String dstMacAddress = macVrfEntry.getMac();
-            long vni = macVrfEntry.getL2vni();
-            jobCoordinator.enqueueJob(dstMacAddress, () -> {
-                List<ListenableFuture<Void>> futures = new ArrayList<>();
-                dpnInterfaceLists.forEach(dpnInterfaces -> {
-                    BigInteger dpId = dpnInterfaces.getDpId();
-                    LOG.info("ADD: Build DMAC flow with dpId {}, nexthopIP {}, elanTag {},"
-                                    + "vni {}, dstMacAddress {}, elanName {} ",
+            long vni = macVrfEntry.getL2vni().toJava();
+            jobCoordinator.enqueueJob(dstMacAddress, () -> Collections.singletonList(
+                txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.CONFIGURATION,
+                    tx -> dpnInterfaceLists.forEach(dpnInterfaces -> {
+                        Uint64 dpId = dpnInterfaces.getDpId();
+                        LOG.info("ADD: Build DMAC flow with dpId {}, nexthopIP {}, elanTag {},"
+                                + "vni {}, dstMacAddress {}, elanName {} ",
                             dpId, nexthopIP, elanTag, vni, dstMacAddress, elanName);
-                    ElanEvpnFlowUtils.EvpnDmacFlowBuilder dmacFlowBuilder = new ElanEvpnFlowUtils.EvpnDmacFlowBuilder();
-                    dmacFlowBuilder.setDpId(dpId).setNexthopIP(ipAddress.toString()).setElanTag(elanTag).setVni(vni)
-                            .setDstMacAddress(dstMacAddress).setElanName(elanName);
-                    Flow flow = elanEvpnFlowUtils.evpnBuildDmacFlowForExternalRemoteMac(dmacFlowBuilder.build());
-                    futures.add(mdsalManager.installFlow(dpId, flow));
-                });
-                return futures;
-            }, ElanConstants.JOB_MAX_RETRIES);
+                        ElanEvpnFlowUtils.EvpnDmacFlowBuilder dmacFlowBuilder =
+                            new ElanEvpnFlowUtils.EvpnDmacFlowBuilder();
+                        dmacFlowBuilder.setDpId(dpId).setNexthopIP(ipAddress.toString()).setElanTag(elanTag.longValue())
+                            .setVni(vni).setDstMacAddress(dstMacAddress).setElanName(elanName);
+                        Flow flow = elanEvpnFlowUtils.evpnBuildDmacFlowForExternalRemoteMac(dmacFlowBuilder.build());
+                        mdsalManager.addFlow(tx, dpId, flow);
+                    }))), ElanConstants.JOB_MAX_RETRIES);
         }
     }
 
+    @Nullable
     public String getRoutePathNexthopIp(MacVrfEntry macVrfEntry) {
         if (macVrfEntry.getRoutePaths() == null || macVrfEntry.getRoutePaths().isEmpty()) {
             LOG.debug("RoutePaths is null or empty for macvrfentry {}", macVrfEntry);
@@ -283,14 +291,14 @@ public class EvpnMacVrfUtils {
             return;
         }
         IpAddress ipAddress = new IpAddress(new Ipv4Address(nexthopIP));
-        Long elanTag = elanInstance.getElanTag();
+        Uint32 elanTag = elanInstance.getElanTag();
         String macToRemove = macVrfEntry.getMac();
         jobCoordinator.enqueueJob(macToRemove, () -> {
             List<ListenableFuture<Void>> futures = new ArrayList<>();
             dpnInterfaceLists.forEach(dpnInterfaces -> {
-                BigInteger dpId = dpnInterfaces.getDpId();
+                Uint64 dpId = dpnInterfaces.getDpId();
                 ElanEvpnFlowUtils.EvpnDmacFlowBuilder dmacFlowBuilder = new ElanEvpnFlowUtils.EvpnDmacFlowBuilder();
-                dmacFlowBuilder.setDpId(dpId).setNexthopIP(ipAddress.toString()).setElanTag(elanTag)
+                dmacFlowBuilder.setDpId(dpId).setNexthopIP(ipAddress.toString()).setElanTag(elanTag.longValue())
                         .setDstMacAddress(macToRemove);
                 LOG.info("REMOVE: Deleting DMAC Flows for external MAC. elanTag {}, dpId {},"
                         + "nexthopIP {}, macToRemove {}", elanTag, dpId, nexthopIP, macToRemove);