NETVIRT-1630 migrate to md-sal APIs
[netvirt.git] / elanmanager / impl / src / main / java / org / opendaylight / netvirt / elan / l2gw / utils / ElanL2GatewayMulticastUtils.java
index 82bc998e8a576ebe59c078877e27460ba131d38a..c68a1d747d4cc907dbb2d899306909e4bffe7fee 100644 (file)
@@ -11,24 +11,22 @@ import static java.util.Collections.emptyList;
 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
 import static org.opendaylight.netvirt.elan.utils.ElanUtils.isVxlanNetworkOrVxlanSegment;
 
-import com.google.common.base.Optional;
+import com.google.common.util.concurrent.FluentFuture;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
-import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
+import java.util.concurrent.ExecutionException;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-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;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
@@ -43,6 +41,10 @@ import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundUtils;
 import org.opendaylight.genius.utils.hwvtep.HwvtepUtils;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
 import org.opendaylight.infrautils.utils.concurrent.LoggingFutures;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.common.api.CommitInfo;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.common.api.ReadFailedException;
 import org.opendaylight.netvirt.elan.l2gw.jobs.HwvtepDeviceMcastMacUpdateJob;
 import org.opendaylight.netvirt.elan.l2gw.jobs.McastUpdateJob;
 import org.opendaylight.netvirt.elan.utils.ElanClusterUtils;
@@ -84,6 +86,7 @@ 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.TerminationPoint;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.Uint64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -210,13 +213,17 @@ public class ElanL2GatewayMulticastUtils {
     private ListenableFuture<Void> deleteLocatorFromMcast(String elanName, NodeId dstNodeId,
                                                           IpAddress removedDstTep,
                                                           RemoteMcastMacs existingMac) {
-        InstanceIdentifier<RemoteMcastMacs> macIid = HwvtepSouthboundUtils
-                .createRemoteMcastMacsInstanceIdentifier(dstNodeId, existingMac.key());
+
         LocatorSet tobeDeleted = buildLocatorSet(dstNodeId, removedDstTep);
         RemoteMcastMacsBuilder newMacBuilder = new RemoteMcastMacsBuilder(existingMac);
-        newMacBuilder.getLocatorSet().remove(tobeDeleted);
+
+        List<LocatorSet> locatorList = new ArrayList<>(existingMac.nonnullLocatorSet());
+        locatorList.remove(tobeDeleted);
+        newMacBuilder.setLocatorSet(locatorList);
         RemoteMcastMacs mac = newMacBuilder.build();
         //configMcastCache.add(macIid, mac);
+        InstanceIdentifier<RemoteMcastMacs> macIid = HwvtepSouthboundUtils
+                .createRemoteMcastMacsInstanceIdentifier(dstNodeId, existingMac.key());
         return ResourceBatchingManager.getInstance().put(
                 ResourceBatchingManager.ShardResource.CONFIG_TOPOLOGY, macIid, mac);
     }
@@ -258,28 +265,28 @@ public class ElanL2GatewayMulticastUtils {
         }
     }
 
-    public void setupElanBroadcastGroups(ElanInstance elanInfo, BigInteger dpnId,
+    public void setupElanBroadcastGroups(ElanInstance elanInfo, Uint64 dpnId,
             TypedWriteTransaction<Datastore.Configuration> confTx) {
         setupElanBroadcastGroups(elanInfo, null, dpnId, confTx);
     }
 
-    public void setupElanBroadcastGroups(ElanInstance elanInfo, @Nullable DpnInterfaces dpnInterfaces, BigInteger dpnId,
+    public void setupElanBroadcastGroups(ElanInstance elanInfo, @Nullable DpnInterfaces dpnInterfaces, Uint64 dpnId,
                                          TypedWriteTransaction<Datastore.Configuration> confTx) {
         setupStandardElanBroadcastGroups(elanInfo, dpnInterfaces, dpnId, confTx);
         setupLeavesEtreeBroadcastGroups(elanInfo, dpnInterfaces, dpnId, confTx);
     }
 
-    public void setupStandardElanBroadcastGroups(ElanInstance elanInfo, DpnInterfaces dpnInterfaces, BigInteger dpnId,
+    public void setupStandardElanBroadcastGroups(ElanInstance elanInfo, DpnInterfaces dpnInterfaces, Uint64 dpnId,
                                                  TypedWriteTransaction<Datastore.Configuration> confTx) {
         setupStandardElanBroadcastGroups(elanInfo, dpnInterfaces, dpnId, true, confTx);
     }
 
     public void setupStandardElanBroadcastGroups(ElanInstance elanInfo, @Nullable DpnInterfaces dpnInterfaces,
-            BigInteger dpnId, boolean createCase, TypedWriteTransaction<Datastore.Configuration> confTx) {
+            Uint64 dpnId, boolean createCase, TypedWriteTransaction<Datastore.Configuration> confTx) {
         List<Bucket> listBucket = new ArrayList<>();
         int bucketId = 0;
         int actionKey = 0;
-        Long elanTag = elanInfo.getElanTag();
+        Long elanTag = elanInfo.getElanTag().toJava();
         List<Action> listAction = new ArrayList<>();
         listAction.add(new ActionGroup(ElanUtils.getElanLocalBCGId(elanTag)).buildAction(++actionKey));
         listBucket.add(MDSALUtil.buildBucket(listAction, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT,
@@ -299,10 +306,10 @@ public class ElanL2GatewayMulticastUtils {
     }
 
     public void setupLeavesEtreeBroadcastGroups(ElanInstance elanInfo, @Nullable DpnInterfaces dpnInterfaces,
-            BigInteger dpnId, TypedWriteTransaction<Datastore.Configuration> confTx) {
+            Uint64 dpnId, TypedWriteTransaction<Datastore.Configuration> confTx) {
         EtreeInstance etreeInstance = elanInfo.augmentation(EtreeInstance.class);
         if (etreeInstance != null) {
-            long etreeLeafTag = etreeInstance.getEtreeLeafTagVal().getValue();
+            long etreeLeafTag = etreeInstance.getEtreeLeafTagVal().getValue().toJava();
             List<Bucket> listBucket = new ArrayList<>();
             int bucketId = 0;
             int actionKey = 0;
@@ -323,7 +330,7 @@ public class ElanL2GatewayMulticastUtils {
     }
 
     @Nullable
-    private static DpnInterfaces getDpnInterfaces(ElanDpnInterfacesList elanDpns, BigInteger dpnId) {
+    private static DpnInterfaces getDpnInterfaces(ElanDpnInterfacesList elanDpns, Uint64 dpnId) {
         if (elanDpns != null) {
             for (DpnInterfaces dpnInterface : elanDpns.nonnullDpnInterfaces()) {
                 if (Objects.equals(dpnInterface.getDpId(), dpnId)) {
@@ -335,7 +342,7 @@ public class ElanL2GatewayMulticastUtils {
     }
 
     private List<Bucket> getRemoteBCGroupExternalPortBuckets(ElanDpnInterfacesList elanDpns,
-            DpnInterfaces dpnInterfaces, BigInteger dpnId, int bucketId) {
+            DpnInterfaces dpnInterfaces, Uint64 dpnId, int bucketId) {
         DpnInterfaces currDpnInterfaces = dpnInterfaces != null ? dpnInterfaces : getDpnInterfaces(elanDpns, dpnId);
         if (currDpnInterfaces == null || !elanUtils.isDpnPresent(currDpnInterfaces.getDpId())
                 || currDpnInterfaces.getInterfaces() == null || currDpnInterfaces.getInterfaces().isEmpty()) {
@@ -357,14 +364,16 @@ public class ElanL2GatewayMulticastUtils {
 
     @NonNull
     public List<Bucket> getRemoteBCGroupBuckets(ElanInstance elanInfo, @Nullable DpnInterfaces dpnInterfaces,
-                                                BigInteger dpnId, int bucketId, long elanTag) {
+                                                Uint64 dpnId, int bucketId, long elanTag) {
         List<Bucket> listBucketInfo = new ArrayList<>();
         ElanDpnInterfacesList elanDpns = elanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
 
         if (isVxlanNetworkOrVxlanSegment(elanInfo)) {
+            // Adding 270000 to avoid collision between LPort and elan for broadcast group actions
             listBucketInfo.addAll(getRemoteBCGroupTunnelBuckets(elanDpns, dpnId, bucketId,
                     elanUtils.isOpenstackVniSemanticsEnforced()
-                            ? ElanUtils.getVxlanSegmentationId(elanInfo) : elanTag));
+                            ? ElanUtils.getVxlanSegmentationId(elanInfo).longValue() : elanTag
+                            + ElanConstants.ELAN_TAG_ADDEND));
         }
         listBucketInfo.addAll(getRemoteBCGroupExternalPortBuckets(elanDpns, dpnInterfaces, dpnId,
                 getNextAvailableBucketId(listBucketInfo.size())));
@@ -373,7 +382,7 @@ public class ElanL2GatewayMulticastUtils {
         return listBucketInfo;
     }
 
-    public List<Bucket> getRemoteBCGroupBucketsOfElanL2GwDevices(ElanInstance elanInfo, BigInteger dpnId,
+    public List<Bucket> getRemoteBCGroupBucketsOfElanL2GwDevices(ElanInstance elanInfo, Uint64 dpnId,
             int bucketId) {
         List<Bucket> listBucketInfo = new ArrayList<>();
         for (L2GatewayDevice device : ElanL2GwCacheUtils.getInvolvedL2GwDevices(elanInfo.getElanInstanceName())) {
@@ -383,7 +392,7 @@ public class ElanL2GatewayMulticastUtils {
                 continue;
             }
             List<Action> listActionInfo = elanItmUtils.buildTunnelItmEgressActions(interfaceName,
-                    ElanUtils.getVxlanSegmentationId(elanInfo), true);
+                    ElanUtils.getVxlanSegmentationId(elanInfo).longValue(), true);
             listBucketInfo.add(MDSALUtil.buildBucket(listActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId,
                     MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
             bucketId++;
@@ -391,15 +400,15 @@ public class ElanL2GatewayMulticastUtils {
         return listBucketInfo;
     }
 
-    public List<Bucket> getRemoteBCGroupBucketsOfElanExternalTeps(ElanInstance elanInfo, BigInteger dpnId,
+    public List<Bucket> getRemoteBCGroupBucketsOfElanExternalTeps(ElanInstance elanInfo, Uint64 dpnId,
             int bucketId) {
         ElanInstance operElanInstance = null;
         try {
             operElanInstance = new SingleTransactionDataBroker(broker).syncReadOptional(
                 LogicalDatastoreType.OPERATIONAL,
                 InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class, elanInfo.key())
-                    .build()).orNull();
-        } catch (ReadFailedException e) {
+                    .build()).orElse(null);
+        } catch (InterruptedException | ExecutionException e) {
             LOG.error("Failed to read elan instance operational path {}", elanInfo, e);
             return emptyList();
         }
@@ -420,7 +429,7 @@ public class ElanL2GatewayMulticastUtils {
                 continue;
             }
             List<Action> listActionInfo = elanItmUtils.buildTunnelItmEgressActions(interfaceName,
-                    ElanUtils.getVxlanSegmentationId(elanInfo), false);
+                    ElanUtils.getVxlanSegmentationId(elanInfo).longValue(), false);
             listBucketInfo.add(MDSALUtil.buildBucket(listActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId,
                     MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
             bucketId++;
@@ -433,7 +442,7 @@ public class ElanL2GatewayMulticastUtils {
     }
 
     @SuppressWarnings("checkstyle:IllegalCatch")
-    private List<Bucket> getRemoteBCGroupTunnelBuckets(ElanDpnInterfacesList elanDpns, BigInteger dpnId, int bucketId,
+    private List<Bucket> getRemoteBCGroupTunnelBuckets(ElanDpnInterfacesList elanDpns, Uint64 dpnId, int bucketId,
             long elanTagOrVni) {
         List<Bucket> listBucketInfo = new ArrayList<>();
         if (elanDpns != null) {
@@ -443,6 +452,8 @@ public class ElanL2GatewayMulticastUtils {
                     try {
                         List<Action> listActionInfo = elanItmUtils.getInternalTunnelItmEgressAction(dpnId,
                                 dpnInterface.getDpId(), elanTagOrVni);
+                        LOG.trace("configuring broadcast group for elan {} for source DPN {} and destination DPN {} "
+                                + "with actions {}", elanTagOrVni, dpnId, dpnInterface.getDpId(), listActionInfo);
                         if (listActionInfo.isEmpty()) {
                             continue;
                         }
@@ -627,13 +638,13 @@ public class ElanL2GatewayMulticastUtils {
      *            the l2 gateway device
      * @return the listenable future
      */
-    public List<ListenableFuture<Void>> handleMcastForElanL2GwDeviceDelete(String elanName,
+    public List<FluentFuture<?>> handleMcastForElanL2GwDeviceDelete(String elanName,
                                                                            L2GatewayDevice l2GatewayDevice) {
-        ListenableFuture<Void> deleteTepFuture =
+        FluentFuture<?> deleteTepFuture =
             txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
                 tx -> tx.delete(buildExternalTepPath(elanName, l2GatewayDevice.getTunnelIp())));
         updateMcastMacsForAllElanDevices(elanName, l2GatewayDevice, false/* updateThisDevice */);
-        ListenableFuture<Void> deleteRemoteMcastMacFuture = deleteRemoteMcastMac(
+        FluentFuture<?> deleteRemoteMcastMacFuture = deleteRemoteMcastMac(
                 new NodeId(l2GatewayDevice.getHwvtepNodeId()), elanName);
         return Arrays.asList(deleteRemoteMcastMacFuture, deleteTepFuture);
     }
@@ -647,7 +658,7 @@ public class ElanL2GatewayMulticastUtils {
      *            the logical switch name
      * @return the listenable future
      */
-    public ListenableFuture<Void> deleteRemoteMcastMac(NodeId nodeId, String logicalSwitchName) {
+    public FluentFuture<? extends @NonNull CommitInfo> deleteRemoteMcastMac(NodeId nodeId, String logicalSwitchName) {
         InstanceIdentifier<LogicalSwitches> logicalSwitch = HwvtepSouthboundUtils
                 .createLogicalSwitchesInstanceIdentifier(nodeId, new HwvtepNodeName(logicalSwitchName));
         RemoteMcastMacsKey remoteMcastMacsKey = new RemoteMcastMacsKey(new HwvtepLogicalSwitchRef(logicalSwitch),
@@ -677,7 +688,7 @@ public class ElanL2GatewayMulticastUtils {
         DesignatedSwitchForTunnel desgSwitch = getDesignatedSwitchForExternalTunnel(l2GwDevice.getTunnelIp(),
                 elanInstanceName);
         if (desgSwitch != null) {
-            tepIp = elanItmUtils.getSourceDpnTepIp(BigInteger.valueOf(desgSwitch.getDpId()),
+            tepIp = elanItmUtils.getSourceDpnTepIp(Uint64.valueOf(desgSwitch.getDpId()),
                     new NodeId(l2GwDevice.getHwvtepNodeId()));
         }
         return tepIp;
@@ -694,11 +705,22 @@ public class ElanL2GatewayMulticastUtils {
      */
     public DesignatedSwitchForTunnel getDesignatedSwitchForExternalTunnel(IpAddress tunnelIp,
             String elanInstanceName) {
-        InstanceIdentifier<DesignatedSwitchForTunnel> instanceIdentifier = InstanceIdentifier
+        try {
+            InstanceIdentifier<DesignatedSwitchForTunnel> instanceIdentifier = InstanceIdentifier
                 .builder(DesignatedSwitchesForExternalTunnels.class)
-                .child(DesignatedSwitchForTunnel.class, new DesignatedSwitchForTunnelKey(elanInstanceName, tunnelIp))
+                .child(DesignatedSwitchForTunnel.class,
+                    new DesignatedSwitchForTunnelKey(elanInstanceName, tunnelIp))
                 .build();
-        return MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, instanceIdentifier).orNull();
+            return MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, instanceIdentifier)
+                .orElse(null);
+        } catch (ExecutionException e) {
+            LOG.error("Exception while retriving DesignatedSwitch for elan {} and tunnel {}",
+                elanInstanceName, tunnelIp, e);
+        } catch (InterruptedException e) {
+            LOG.error("Exception while retriving DesignatedSwitch for elan {} and tunnel {}",
+                elanInstanceName, tunnelIp, e);
+        }
+        return null;
     }
 
 }