Bulk merge of l2gw changes
[netvirt.git] / elanmanager / impl / src / main / java / org / opendaylight / netvirt / elan / internal / ElanServiceProvider.java
index 44a4e463d7f0774cf526be5a8c77f2e09425fb2f..d5cd91fea24d1151597e09d6310fba751b780feb 100644 (file)
@@ -8,43 +8,40 @@
 
 package org.opendaylight.netvirt.elan.internal;
 
-import static java.util.Collections.emptyList;
+import static java.util.Collections.emptyMap;
+import static org.opendaylight.mdsal.binding.util.Datastore.CONFIGURATION;
 
-import com.google.common.base.Optional;
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.Future;
 import java.util.function.BiFunction;
-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.common.api.data.LogicalDatastoreType;
-import org.opendaylight.genius.infra.Datastore;
-import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
-import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.genius.interfacemanager.exceptions.InterfaceAlreadyExistsException;
 import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
-import org.opendaylight.genius.mdsalutil.MatchInfoBase;
-import org.opendaylight.genius.mdsalutil.MetaDataUtil;
 import org.opendaylight.genius.mdsalutil.NwConstants;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
-import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchRegister;
 import org.opendaylight.genius.utils.ServiceIndex;
 import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
 import org.opendaylight.infrautils.inject.AbstractLifecycle;
-import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
+import org.opendaylight.infrautils.utils.concurrent.LoggingFutures;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
+import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.mdsal.eos.binding.api.Entity;
 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipCandidateRegistration;
 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
@@ -87,9 +84,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.elan._interface.StaticMacEntriesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.state.Elan;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.forwarding.entries.MacEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.forwarding.entries.MacEntryKey;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.Uint32;
+import org.opendaylight.yangtools.yang.common.Uint64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -220,7 +221,7 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
                 ElanInstance updateElanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName)
                         .setDescription(description).setMacTimeout(macTimeout)
                         .withKey(new ElanInstanceKey(elanInstanceName))
-                        .addAugmentation(EtreeInstance.class, etreeInstance).build();
+                        .addAugmentation(etreeInstance).build();
                 MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
                         ElanHelper.getElanInstanceConfigurationDataPath(elanInstanceName), updateElanInstance);
                 LOG.debug("Updating the Etree Instance {} with MAC TIME-OUT {} and Description {} ",
@@ -231,7 +232,7 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
             ElanInstance elanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName)
                     .setMacTimeout(macTimeout).setDescription(description)
                     .withKey(new ElanInstanceKey(elanInstanceName))
-                    .addAugmentation(EtreeInstance.class, etreeInstance).build();
+                    .addAugmentation(etreeInstance).build();
             MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
                     ElanHelper.getElanInstanceConfigurationDataPath(elanInstanceName), elanInstance);
             LOG.debug("Creating the new Etree Instance {}", elanInstance);
@@ -242,13 +243,13 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
     @Override
     @Nullable
     public EtreeInterface getEtreeInterfaceByElanInterfaceName(String elanInterface) {
-        return elanInterfaceCache.getEtreeInterface(elanInterface).orNull();
+        return elanInterfaceCache.getEtreeInterface(elanInterface).orElse(null);
     }
 
     public static boolean compareWithExistingElanInstance(ElanInstance existingElanInstance, long macTimeOut,
             String description) {
         boolean isEqual = false;
-        if (existingElanInstance.getMacTimeout() == macTimeOut
+        if (existingElanInstance.getMacTimeout().longValue() == macTimeOut
                 && Objects.equals(existingElanInstance.getDescription(), description)) {
             isEqual = true;
         }
@@ -289,14 +290,14 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
             if (staticMacAddresses == null) {
                 elanInterface = new ElanInterfaceBuilder().setElanInstanceName(etreeInstanceName)
                         .setDescription(description).setName(interfaceName).withKey(new ElanInterfaceKey(interfaceName))
-                        .addAugmentation(EtreeInterface.class, etreeInterface).build();
+                        .addAugmentation(etreeInterface).build();
             } else {
                 List<StaticMacEntries> staticMacEntries = ElanUtils.getStaticMacEntries(staticMacAddresses);
                 elanInterface = new ElanInterfaceBuilder().setElanInstanceName(etreeInstanceName)
                         .setDescription(description).setName(interfaceName)
                         .setStaticMacEntries(staticMacEntries)
                         .withKey(new ElanInterfaceKey(interfaceName))
-                        .addAugmentation(EtreeInterface.class, etreeInterface).build();
+                        .addAugmentation(etreeInterface).build();
             }
             MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
                     ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName), elanInterface);
@@ -394,7 +395,7 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
                 ElanInterfaceMac elanInterfaceMac = elanUtils.getElanInterfaceMacByInterfaceName(elanInterface);
                 if (elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null
                         && elanInterfaceMac.getMacEntry().size() > 0) {
-                    macAddress.addAll(elanInterfaceMac.getMacEntry());
+                    macAddress.addAll(elanInterfaceMac.nonnullMacEntry().values());
                 }
             }
         }
@@ -414,8 +415,8 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
         for (String elanInterface : elanInterfaces) {
             ElanInterfaceMac elanInterfaceMac = elanUtils.getElanInterfaceMacByInterfaceName(elanInterface);
             if (elanInterfaceMac.getMacEntry() != null && elanInterfaceMac.getMacEntry().size() > 0) {
-                List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
-                for (MacEntry macEntry : macEntries) {
+                Map<MacEntryKey, MacEntry> macEntries = elanInterfaceMac.nonnullMacEntry();
+                for (MacEntry macEntry : macEntries.values()) {
                     deleteStaticMacAddress(elanInterface, macEntry.getMacAddress().getValue());
                 }
             }
@@ -426,19 +427,19 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
     @Override
     @Nullable
     public ElanInstance getElanInstance(String elanName) {
-        return elanInstanceCache.get(elanName).orNull();
+        return elanInstanceCache.get(elanName).orElse(null);
     }
 
     @Override
     public List<ElanInstance> getElanInstances() {
         InstanceIdentifier<ElanInstances> elanInstancesIdentifier = InstanceIdentifier.builder(ElanInstances.class)
                 .build();
-        return ElanUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanInstancesIdentifier).toJavaUtil().map(
-                ElanInstances::getElanInstance).orElse(emptyList());
+        return new ArrayList<>(ElanUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanInstancesIdentifier).map(
+                ElanInstances::nonnullElanInstance).orElse(emptyMap()).values());
     }
 
     @Override
-    @Nonnull
+    @NonNull
     public List<String> getElanInterfaces(String elanInstanceName) {
         List<String> elanInterfaces = new ArrayList<>();
         InstanceIdentifier<ElanInterfaces> elanInterfacesIdentifier = InstanceIdentifier.builder(ElanInterfaces.class)
@@ -448,8 +449,8 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
         if (!elanInterfacesOptional.isPresent()) {
             return elanInterfaces;
         }
-        List<ElanInterface> elanInterfaceList = elanInterfacesOptional.get().nonnullElanInterface();
-        for (ElanInterface elanInterface : elanInterfaceList) {
+        Map<ElanInterfaceKey, ElanInterface> elanInterfaceList = elanInterfacesOptional.get().nonnullElanInterface();
+        for (ElanInterface elanInterface : elanInterfaceList.values()) {
             if (Objects.equals(elanInterface.getElanInstanceName(), elanInstanceName)) {
                 elanInterfaces.add(elanInterface.getName());
             }
@@ -473,7 +474,7 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
         });
     }
 
-    protected void createExternalElanNetwork(ElanInstance elanInstance, BigInteger dpId) {
+    protected void createExternalElanNetwork(ElanInstance elanInstance, Uint64 dpId) {
         String providerIntfName = bridgeMgr.getProviderInterfaceName(dpId, elanInstance.getPhysicalNetworkName());
         String intfName = providerIntfName + IfmConstants.OF_URI_SEPARATOR + elanInstance.getSegmentationId();
         Interface memberIntf = interfaceManager.getInterfaceInfoFromConfigDataStore(intfName);
@@ -518,7 +519,7 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
         });
     }
 
-    protected void deleteExternalElanNetwork(ElanInstance elanInstance, BigInteger dpnId) {
+    protected void deleteExternalElanNetwork(ElanInstance elanInstance, Uint64 dpnId) {
         String providerIntfName = bridgeMgr.getProviderInterfaceName(dpnId, elanInstance.getPhysicalNetworkName());
         String intfName = providerIntfName + IfmConstants.OF_URI_SEPARATOR + elanInstance.getSegmentationId();
         Interface memberIntf = interfaceManager.getInterfaceInfoFromConfigDataStore(intfName);
@@ -577,7 +578,7 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
             return;
         }
 
-        LOG.debug("updateExternalElanNetworks, orig bridge {} . updated bridge {}", origNode, updatedNode);
+        LOG.trace("updateExternalElanNetworks, orig bridge {} . updated bridge {}", origNode, updatedNode);
 
         Map<String, String> origProviderMappping = getMapFromOtherConfig(origNode,
                 ElanBridgeManager.PROVIDER_MAPPINGS_KEY);
@@ -586,7 +587,7 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
 
         boolean hasDatapathIdOnOrigNode = bridgeMgr.hasDatapathID(origNode);
         boolean hasDatapathIdOnUpdatedNode = bridgeMgr.hasDatapathID(updatedNode);
-        BigInteger origDpnID = bridgeMgr.getDatapathId(origNode);
+        Uint64 origDpnID = bridgeMgr.getDatapathId(origNode);
 
         for (ElanInstance elanInstance : elanInstances) {
             String physicalNetworkName = elanInstance.getPhysicalNetworkName();
@@ -621,15 +622,15 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
         }
     }
 
-    private boolean hasDatapathIdAdded(boolean hasDatapathIdOnOrigNode, boolean hasDatapathIdOnUpdatedNode) {
+    private static boolean hasDatapathIdAdded(boolean hasDatapathIdOnOrigNode, boolean hasDatapathIdOnUpdatedNode) {
         return !hasDatapathIdOnOrigNode && hasDatapathIdOnUpdatedNode;
     }
 
-    private boolean hasPortNameUpdated(String origPortName, String updatedPortName) {
+    private static boolean hasPortNameUpdated(String origPortName, String updatedPortName) {
         return updatedPortName != null && !updatedPortName.equals(origPortName);
     }
 
-    private boolean hasPortNameRemoved(String origPortName, String updatedPortName) {
+    private static boolean hasPortNameRemoved(String origPortName, String updatedPortName) {
         return origPortName != null && !origPortName.equals(updatedPortName);
     }
 
@@ -656,7 +657,7 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
     }
 
     @Override
-    public String getExternalElanInterface(String elanInstanceName, BigInteger dpnId) {
+    public String getExternalElanInterface(String elanInstanceName, Uint64 dpnId) {
         return elanUtils.getExternalElanInterface(elanInstanceName, dpnId);
     }
 
@@ -668,7 +669,7 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
     @Override
     @Nullable
     public ElanInterface getElanInterfaceByElanInterfaceName(String interfaceName) {
-        return elanInterfaceCache.get(interfaceName).orNull();
+        return elanInterfaceCache.get(interfaceName).orElse(null);
     }
 
     @Override
@@ -686,13 +687,13 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
             LOG.trace("ELAN service is after L3VPN in the Netvirt pipeline skip known L3DMAC flows installation");
             return;
         }
-        ElanInstance elanInstance = elanInstanceCache.get(elanInstanceName).orNull();
+        ElanInstance elanInstance = elanInstanceCache.get(elanInstanceName).orElse(null);
         if (elanInstance == null) {
             LOG.warn("Null elan instance {}", elanInstanceName);
             return;
         }
 
-        List<BigInteger> dpnsIdsForElanInstance = elanUtils.getParticipatingDpnsInElanInstance(elanInstanceName);
+        List<Uint64> dpnsIdsForElanInstance = elanUtils.getParticipatingDpnsInElanInstance(elanInstanceName);
         if (dpnsIdsForElanInstance.isEmpty()) {
             LOG.warn("No DPNs for elan instance {}", elanInstance);
             return;
@@ -708,36 +709,20 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
             LOG.trace("ELAN service is after L3VPN in the Netvirt pipeline skip known L3DMAC flows installation");
             return;
         }
-        ElanInstance elanInstance = elanInstanceCache.get(elanInstanceName).orNull();
+        ElanInstance elanInstance = elanInstanceCache.get(elanInstanceName).orElse(null);
         if (elanInstance == null) {
             LOG.warn("Null elan instance {}", elanInstanceName);
             return;
         }
 
-        List<BigInteger> dpnsIdsForElanInstance = elanUtils.getParticipatingDpnsInElanInstance(elanInstanceName);
+        List<Uint64> dpnsIdsForElanInstance = elanUtils.getParticipatingDpnsInElanInstance(elanInstanceName);
         if (dpnsIdsForElanInstance.isEmpty()) {
             LOG.warn("No DPNs for elan instance {}", elanInstance);
             return;
         }
 
-        elanUtils.removeDmacRedirectToDispatcherFlows(elanInstance.getElanTag(), macAddress, dpnsIdsForElanInstance);
-    }
-
-    @Override
-    public List<MatchInfoBase> getEgressMatchesForElanInstance(String elanInstanceName) {
-        ElanInstance elanInstance = getElanInstance(elanInstanceName);
-        if (elanInstance == null) {
-            LOG.debug("No ELAN instance found for {}", elanInstanceName);
-            return emptyList();
-        }
-
-        Long elanTag = elanInstance.getElanTag();
-        if (elanTag == null) {
-            LOG.debug("No ELAN tag found for {}", elanInstanceName);
-            return emptyList();
-        }
-        return Collections.singletonList(
-                new NxMatchRegister(ElanConstants.ELAN_REG_ID, elanTag, MetaDataUtil.getElanMaskForReg()));
+        elanUtils.removeDmacRedirectToDispatcherFlows(elanInstance.getElanTag(),
+            macAddress, dpnsIdsForElanInstance);
     }
 
     /**
@@ -770,7 +755,7 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
             if (ElanUtils.isFlat(elanInstance)) {
                 interfaceName = trunkName;
             } else if (ElanUtils.isVlan(elanInstance)) {
-                Long segmentationId = elanInstance.getSegmentationId();
+                Long segmentationId = elanInstance.getSegmentationId().toJava();
                 interfaceName = parentRef + IfmConstants.OF_URI_SEPARATOR + segmentationId;
                 interfaceManager.createVLANInterface(interfaceName, trunkName, segmentationId.intValue(), null,
                         IfL2vlan.L2vlanMode.TrunkMember, true);
@@ -816,19 +801,26 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
     private void handleExternalElanNetwork(ElanInstance elanInstance, boolean update,
                                            BiFunction<ElanInstance, String, Void> function) {
         String elanInstanceName = elanInstance.getElanInstanceName();
+        boolean isFlatOrVlanNetwork = (ElanUtils.isFlat(elanInstance) || ElanUtils.isVlan(elanInstance));
+        if (!isFlatOrVlanNetwork) {
+            LOG.error("Network is not of type FLAT/VLAN."
+                    + "Ignoring Elan-interface creation for given ProviderInterface {}",
+                elanInstance.getPhysicalNetworkName());
+            return;
+        }
         if (elanInstance.getPhysicalNetworkName() == null) {
             LOG.trace("No physical network attached to {}", elanInstanceName);
             return;
         }
 
-        List<Node> nodes = southboundUtils.getOvsdbNodes();
+        Map<NodeKey, Node> nodes = southboundUtils.getOvsdbNodes();
         if (nodes == null || nodes.isEmpty()) {
             LOG.trace("No OVS nodes found while creating external network for ELAN {}",
                     elanInstance.getElanInstanceName());
             return;
         }
 
-        for (Node node : nodes) {
+        for (Node node : nodes.values()) {
             if (bridgeMgr.isIntegrationBridge(node)) {
                 if (update && !elanInstance.isExternal()) {
                     DpnInterfaces dpnInterfaces = elanUtils.getElanInterfaceInfoByElanDpn(elanInstanceName,
@@ -843,7 +835,7 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
         }
     }
 
-    private String getTrunkInterfaceName(String parentRef) {
+    private static String getTrunkInterfaceName(String parentRef) {
         return parentRef + IfmConstants.OF_URI_SEPARATOR + "trunk";
     }
 
@@ -867,40 +859,49 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
         String macAddress = arpResponderInput.getSha();
         String ipAddress = arpResponderInput.getSpa();
         int lportTag = arpResponderInput.getLportTag();
-        BigInteger dpnId = arpResponderInput.getDpId();
+        Uint64 dpnId = Uint64.valueOf(arpResponderInput.getDpId());
 
         LOG.info("Installing the ARP responder flow on DPN {} for Interface {} with MAC {} & IP {}", dpnId,
                 ingressInterfaceName, macAddress, ipAddress);
         Optional<ElanInterface> elanIface = elanInterfaceCache.get(ingressInterfaceName);
         ElanInstance elanInstance = elanIface.isPresent()
-                ? elanInstanceCache.get(elanIface.get().getElanInstanceName()).orNull() : null;
+                ? elanInstanceCache.get(elanIface.get().getElanInstanceName()).orElse(null) : null;
         if (elanInstance == null) {
             LOG.debug("addArpResponderFlow: elanInstance is null, Failed to install arp responder flow for dpnId {}"
                     + "for Interface {} with MAC {} & IP {}", dpnId, ingressInterfaceName, macAddress, ipAddress);
             return;
         }
         String flowId = ArpResponderUtil.getFlowId(lportTag, ipAddress);
+        Map<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey,
+                org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction>
+                arpResponderInputInstructionsMap = new HashMap<>();
+        int instructionKey = 0;
+        for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
+                instructionObj : arpResponderInput.getInstructions()) {
+            arpResponderInputInstructionsMap.put(new org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types
+                    .rev131026.instruction.list.InstructionKey(++instructionKey), instructionObj);
+        }
         Flow flowEntity =
             MDSALUtil.buildFlowNew(NwConstants.ARP_RESPONDER_TABLE, flowId, NwConstants.DEFAULT_ARP_FLOW_PRIORITY,
                 flowId, 0, 0,
                 ArpResponderUtil.generateCookie(lportTag, ipAddress),
                 ArpResponderUtil.getMatchCriteria(lportTag, elanInstance, ipAddress),
-                arpResponderInput.getInstructions());
-        ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.CONFIGURATION,
+                    arpResponderInputInstructionsMap);
+        LoggingFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
             tx -> mdsalManager.addFlow(tx, dpnId, flowEntity)), LOG, "Error adding flow {}", flowEntity);
         LOG.info("Installed the ARP Responder flow for Interface {}", ingressInterfaceName);
     }
 
     @Override
     public void addExternalTunnelArpResponderFlow(ArpResponderInput arpResponderInput, String elanInstanceName) {
-        BigInteger dpnId = arpResponderInput.getDpId();
+        Uint64 dpnId = Uint64.valueOf(arpResponderInput.getDpId());
         String ipAddress = arpResponderInput.getSpa();
         String macAddress = arpResponderInput.getSha();
 
         LOG.trace("Installing the ExternalTunnel ARP responder flow on DPN {} for ElanInstance {} with MAC {} & IP {}",
                 dpnId, elanInstanceName, macAddress, ipAddress);
 
-        ElanInstance elanInstance = elanInstanceCache.get(elanInstanceName).orNull();
+        ElanInstance elanInstance = elanInstanceCache.get(elanInstanceName).orElse(null);
         if (elanInstance == null) {
             LOG.warn("Null elan instance {}", elanInstanceName);
             return;
@@ -908,20 +909,32 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
 
         int lportTag = arpResponderInput.getLportTag();
         String flowId = ArpResponderUtil.getFlowId(lportTag, ipAddress);
+
+        Map<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey,
+                org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction>
+                arpResponderInputInstructionsMap = new HashMap<>();
+        int instructionKey = 0;
+        for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
+                instructionObj : arpResponderInput.getInstructions()) {
+            arpResponderInputInstructionsMap.put(new org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types
+                    .rev131026.instruction.list.InstructionKey(++instructionKey), instructionObj);
+        }
+
         Flow flowEntity =
             MDSALUtil.buildFlowNew(NwConstants.ARP_RESPONDER_TABLE, flowId, NwConstants.DEFAULT_ARP_FLOW_PRIORITY,
                 flowId, 0, 0,
                 ArpResponderUtil.generateCookie(lportTag, ipAddress),
                 ArpResponderUtil.getMatchCriteria(lportTag, elanInstance, ipAddress),
-                arpResponderInput.getInstructions());
-        ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.CONFIGURATION,
+                    arpResponderInputInstructionsMap);
+        LoggingFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
             tx -> mdsalManager.addFlow(tx, dpnId, flowEntity)), LOG, "Error adding flow {}", flowEntity);
         LOG.trace("Installed the ExternalTunnel ARP Responder flow for ElanInstance {}", elanInstanceName);
     }
 
     @Override
     public void removeArpResponderFlow(ArpResponderInput arpResponderInput) {
-        elanUtils.removeArpResponderFlow(arpResponderInput.getDpId(), arpResponderInput.getInterfaceName(),
+        elanUtils.removeArpResponderFlow(Uint64.valueOf(arpResponderInput.getDpId()),
+                arpResponderInput.getInterfaceName(),
                 arpResponderInput.getSpa(), arpResponderInput.getLportTag());
     }
 
@@ -933,18 +946,18 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
      * @return the integer
      */
     @Override
-    public Long retrieveNewElanTag(String idKey) {
-        return elanUtils.retrieveNewElanTag(idManager, idKey);
+    public Uint32 retrieveNewElanTag(String idKey) {
+        return ElanUtils.retrieveNewElanTag(idManager, idKey);
     }
 
     @Override
     public InstanceIdentifier<DpnInterfaces> getElanDpnInterfaceOperationalDataPath(
-                                                                String elanInstanceName, BigInteger dpnId) {
+                                                                String elanInstanceName, Uint64 dpnId) {
         return ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpnId);
     }
 
     @Override
-    public DpnInterfaces getElanInterfaceInfoByElanDpn(String elanInstanceName, BigInteger dpId) {
+    public DpnInterfaces getElanInterfaceInfoByElanDpn(String elanInstanceName, Uint64 dpId) {
         return elanUtils.getElanInterfaceInfoByElanDpn(elanInstanceName, dpId);
     }