Refactor ElanUtil interface maps to a non-static singleton 66/66766/8
authorTom Pantelis <tompantelis@gmail.com>
Tue, 26 Dec 2017 16:40:23 +0000 (11:40 -0500)
committerTom Pantelis <tompantelis@gmail.com>
Mon, 19 Feb 2018 15:37:29 +0000 (10:37 -0500)
Created an ElanInterfaceCache class to replace the static
elanInterfaceLocalCache and elanInstanceToInterfacesCache Maps
in ElanUtils.

Change-Id: I0f362fe749e1ab9e13ac2f0a92667d4336d43e72
Signed-off-by: Tom Pantelis <tompantelis@gmail.com>
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/cache/ElanInterfaceCache.java [new file with mode: 0644]
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/ElanInterfaceStateChangeListener.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/internal/ElanLearntVpnVipToPortListener.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/internal/ElanServiceProvider.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/statisitcs/ElanStatisticsImpl.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/utils/CacheElanInterfaceListener.java [deleted file]
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/utils/ElanDmacUtils.java
elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/utils/ElanUtils.java

diff --git a/elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/cache/ElanInterfaceCache.java b/elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/cache/ElanInterfaceCache.java
new file mode 100644 (file)
index 0000000..546d238
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2017 Inocybe Technologies and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netvirt.elan.cache;
+
+import com.google.common.base.Optional;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.annotation.Nonnull;
+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.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.mdsalutil.cache.DataObjectCache;
+import org.opendaylight.infrautils.caches.CacheProvider;
+import org.opendaylight.netvirt.elan.utils.ElanUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Caches ElanInterface instances by name and the set of ElanInterfacenames by elen instance name.
+ *
+ * @author Thomas Pantelis
+ */
+@Singleton
+public class ElanInterfaceCache extends DataObjectCache<ElanInterface> {
+    private static final Logger LOG = LoggerFactory.getLogger(ElanInterface.class);
+
+    private final Map<String, Set<String>> elanInstanceToInterfacesCache = new ConcurrentHashMap<>();
+
+    @Inject
+    public ElanInterfaceCache(DataBroker dataBroker, CacheProvider cacheProvider) {
+        super(ElanInterface.class, dataBroker, LogicalDatastoreType.CONFIGURATION,
+                InstanceIdentifier.create(ElanInterfaces.class).child(ElanInterface.class), cacheProvider);
+    }
+
+    @Nonnull
+    public Optional<ElanInterface> get(@Nonnull String interfaceName) {
+        try {
+            return get(ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName));
+        } catch (ReadFailedException e) {
+            LOG.warn("Error reading ElanInterface {}", interfaceName, e);
+            return Optional.absent();
+        }
+    }
+
+    @Nonnull
+    public Optional<EtreeInterface> getEtreeInterface(@Nonnull String interfaceName) {
+        Optional<ElanInterface> elanInterface = get(interfaceName);
+        return elanInterface.isPresent() ? Optional.fromNullable(
+                elanInterface.get().getAugmentation(EtreeInterface.class)) : Optional.absent();
+    }
+
+    @Nonnull
+    public Collection<String> getInterfaceNames(@Nonnull String elanInstanceName) {
+        Set<String> removed = elanInstanceToInterfacesCache.remove(elanInstanceName);
+        return removed != null ? Collections.unmodifiableCollection(removed) : Collections.emptySet();
+    }
+
+    @Override
+    protected void added(InstanceIdentifier<ElanInterface> path, ElanInterface elanInterface) {
+        elanInstanceToInterfacesCache.computeIfAbsent(elanInterface.getElanInstanceName(),
+            key -> ConcurrentHashMap.newKeySet()).add(elanInterface.getName());
+    }
+
+    @Override
+    protected void removed(InstanceIdentifier<ElanInterface> path, ElanInterface elanInterface) {
+        String elanInstanceName = elanInterface.getElanInstanceName();
+        elanInstanceToInterfacesCache.computeIfPresent(elanInstanceName , (key, prevInterfacesSet) -> {
+            prevInterfacesSet.remove(elanInterface.getName());
+            return !prevInterfacesSet.isEmpty() ? prevInterfacesSet : null;
+        });
+    }
+}
index 5a55dd6219420099d5570c2aa2a5eb8bf5d1b5cc..c155057cdfefc03e42dc33f6afeb849c1d1581a1 100644 (file)
@@ -26,6 +26,7 @@ import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
 import org.opendaylight.netvirt.elan.ElanException;
+import org.opendaylight.netvirt.elan.cache.ElanInterfaceCache;
 import org.opendaylight.netvirt.elan.utils.ElanConstants;
 import org.opendaylight.netvirt.elan.utils.ElanUtils;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
@@ -52,17 +53,20 @@ public class ElanInstanceManager extends AsyncDataTreeChangeListenerBase<ElanIns
     private final IInterfaceManager interfaceManager;
     private final ElanInterfaceManager elanInterfaceManager;
     private final JobCoordinator jobCoordinator;
+    private final ElanInterfaceCache elanInterfaceCache;
 
     @Inject
     public ElanInstanceManager(final DataBroker dataBroker, final IdManagerService managerService,
                                final ElanInterfaceManager elanInterfaceManager,
-                               final IInterfaceManager interfaceManager, final JobCoordinator jobCoordinator) {
+                               final IInterfaceManager interfaceManager, final JobCoordinator jobCoordinator,
+                               final ElanInterfaceCache elanInterfaceCache) {
         super(ElanInstance.class, ElanInstanceManager.class);
         this.broker = dataBroker;
         this.idManager = managerService;
         this.elanInterfaceManager = elanInterfaceManager;
         this.interfaceManager = interfaceManager;
         this.jobCoordinator = jobCoordinator;
+        this.elanInterfaceCache = elanInterfaceCache;
     }
 
     @Override
@@ -103,14 +107,13 @@ public class ElanInstanceManager extends AsyncDataTreeChangeListenerBase<ElanIns
             ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL,
                     ElanUtils.getElanInfoEntriesOperationalDataPath(elanTag));
         }
-        ElanUtils.removeAndGetElanInterfaces(elanName).forEach(elanInterfaceName -> {
+        elanInterfaceCache.getInterfaceNames(elanName).forEach(elanInterfaceName -> {
             jobCoordinator.enqueueJob(ElanUtils.getElanInterfaceJobKey(elanInterfaceName), () -> {
                 WriteTransaction writeConfigTxn = broker.newWriteOnlyTransaction();
                 LOG.info("Deleting the elanInterface present under ConfigDS:{}", elanInterfaceName);
                 ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
                         ElanUtils.getElanInterfaceConfigurationDataPathId(elanInterfaceName));
                 elanInterfaceManager.unbindService(elanInterfaceName, writeConfigTxn);
-                ElanUtils.removeElanInterfaceToElanInstanceCache(elanName, elanInterfaceName);
                 LOG.info("unbind the Interface:{} service bounded to Elan:{}", elanInterfaceName, elanName);
                 return Collections.singletonList(writeConfigTxn.submit());
             }, ElanConstants.JOB_MAX_RETRIES);
index c5ab4442ab08ed1a4b61733bc5d9803449b503bc..868617c967fedcb2c5173c92ff71408e537ae50e 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.netvirt.elan.internal;
 
+import com.google.common.base.Optional;
 import java.util.Collections;
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
@@ -16,6 +17,7 @@ import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
+import org.opendaylight.netvirt.elan.cache.ElanInterfaceCache;
 import org.opendaylight.netvirt.elan.utils.ElanConstants;
 import org.opendaylight.netvirt.elan.utils.ElanUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
@@ -35,14 +37,16 @@ public class ElanInterfaceConfigListener
     private final DataBroker dataBroker;
     private final ElanInterfaceManager elanInterfaceManager;
     private final JobCoordinator jobCoordinator;
+    private final ElanInterfaceCache elanInterfaceCache;
 
     @Inject
     public ElanInterfaceConfigListener(DataBroker dataBroker, ElanInterfaceManager elanInterfaceManager,
-            JobCoordinator jobCoordinator) {
+            JobCoordinator jobCoordinator, ElanInterfaceCache elanInterfaceCache) {
         super(Interface.class, ElanInterfaceConfigListener.class);
         this.dataBroker = dataBroker;
         this.elanInterfaceManager = elanInterfaceManager;
         this.jobCoordinator = jobCoordinator;
+        this.elanInterfaceCache = elanInterfaceCache;
     }
 
     @Override
@@ -68,8 +72,8 @@ public class ElanInterfaceConfigListener
         }
 
         String interfaceName = intrf.getName();
-        ElanInterface elanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(dataBroker, interfaceName);
-        if (elanInterface == null) {
+        Optional<ElanInterface> elanInterface = elanInterfaceCache.get(interfaceName);
+        if (!elanInterface.isPresent()) {
             LOG.debug("There is no ELAN service for interface {}. Ignoring it", interfaceName);
             return;
         }
index 8b77a03a00adf8439b496754bc75e19350c98b75..65ad1ae979dccc67175aa64214ba6faca85c96ca 100644 (file)
@@ -60,6 +60,7 @@ import org.opendaylight.genius.utils.ServiceIndex;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
 import org.opendaylight.netvirt.elan.ElanException;
 import org.opendaylight.netvirt.elan.cache.ElanInstanceCache;
+import org.opendaylight.netvirt.elan.cache.ElanInterfaceCache;
 import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayMulticastUtils;
 import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayUtils;
 import org.opendaylight.netvirt.elan.utils.ElanConstants;
@@ -146,6 +147,7 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
     private final ElanUtils elanUtils;
     private final JobCoordinator jobCoordinator;
     private final ElanInstanceCache elanInstanceCache;
+    private final ElanInterfaceCache elanInterfaceCache;
 
     private final Map<String, ConcurrentLinkedQueue<ElanInterface>>
         unProcessedElanInterfaces = new ConcurrentHashMap<>();
@@ -158,7 +160,8 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
                                 final ElanEtreeUtils elanEtreeUtils, final ElanL2GatewayUtils elanL2GatewayUtils,
                                 final ElanUtils elanUtils, final JobCoordinator jobCoordinator,
                                 final ElanL2GatewayMulticastUtils elanL2GatewayMulticastUtils,
-                                final ElanInstanceCache elanInstanceCache) {
+                                final ElanInstanceCache elanInstanceCache,
+                                final ElanInterfaceCache elanInterfaceCache) {
         super(ElanInterface.class, ElanInterfaceManager.class);
         this.broker = dataBroker;
         this.idManager = managerService;
@@ -173,6 +176,7 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
         this.jobCoordinator = jobCoordinator;
         this.elanL2GatewayMulticastUtils = elanL2GatewayMulticastUtils;
         this.elanInstanceCache = elanInstanceCache;
+        this.elanInterfaceCache = elanInterfaceCache;
     }
 
     @Override
@@ -360,7 +364,7 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
         // removing the ElanInterface from the config data_store if interface is
         // not present in Interface config DS
         if (interfaceManager.getInterfaceInfoFromConfigDataStore(interfaceName) == null
-                && ElanUtils.getElanInterfaceByElanInterfaceName(broker, interfaceName) != null) {
+                && elanInterfaceCache.get(interfaceName).isPresent()) {
             tx.delete(LogicalDatastoreType.CONFIGURATION,
                     ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName));
         }
@@ -1140,8 +1144,8 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
 
     private int addInterfaceIfRootInterface(int bucketId, String ifName, List<Bucket> listBucket,
             InterfaceInfo ifInfo) {
-        EtreeInterface etreeInterface = ElanUtils.getEtreeInterfaceByElanInterfaceName(broker, ifName);
-        if (etreeInterface != null && etreeInterface.getEtreeInterfaceType() == EtreeInterfaceType.Root) {
+        Optional<EtreeInterface> etreeInterface = elanInterfaceCache.getEtreeInterface(ifName);
+        if (etreeInterface.isPresent() && etreeInterface.get().getEtreeInterfaceType() == EtreeInterfaceType.Root) {
             listBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId,
                     MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
             bucketId++;
index a4dfd14649411d9c1eaf76fa8686385965a2fbd1..19d3a279243c3011e0b1d7e40c2c1fe9b448f4ad 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.netvirt.elan.internal;
 
+import com.google.common.base.Optional;
 import java.math.BigInteger;
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
@@ -18,6 +19,7 @@ import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
 import org.opendaylight.netvirt.elan.cache.ElanInstanceCache;
+import org.opendaylight.netvirt.elan.cache.ElanInterfaceCache;
 import org.opendaylight.netvirt.elan.utils.ElanConstants;
 import org.opendaylight.netvirt.elan.utils.ElanUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
@@ -40,15 +42,18 @@ public class ElanInterfaceStateChangeListener
     private final ElanInterfaceManager elanInterfaceManager;
     private final JobCoordinator jobCoordinator;
     private final ElanInstanceCache elanInstanceCache;
+    private final ElanInterfaceCache elanInterfaceCache;
 
     @Inject
     public ElanInterfaceStateChangeListener(final DataBroker db, final ElanInterfaceManager ifManager,
-            final JobCoordinator jobCoordinator, final ElanInstanceCache elanInstanceCache) {
+            final JobCoordinator jobCoordinator, final ElanInstanceCache elanInstanceCache,
+            final ElanInterfaceCache elanInterfaceCache) {
         super(Interface.class, ElanInterfaceStateChangeListener.class);
         broker = db;
         elanInterfaceManager = ifManager;
         this.jobCoordinator = jobCoordinator;
         this.elanInstanceCache = elanInstanceCache;
+        this.elanInterfaceCache = elanInterfaceCache;
     }
 
     @Override
@@ -64,8 +69,8 @@ public class ElanInterfaceStateChangeListener
         }
         LOG.trace("Received interface {} Down event", delIf);
         String interfaceName =  delIf.getName();
-        ElanInterface elanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(broker, interfaceName);
-        if (elanInterface == null) {
+        Optional<ElanInterface> elanInterface = elanInterfaceCache.get(interfaceName);
+        if (!elanInterface.isPresent()) {
             LOG.debug("No Elan Interface is created for the interface:{} ", interfaceName);
             return;
         }
@@ -75,7 +80,7 @@ public class ElanInterfaceStateChangeListener
         interfaceInfo.setInterfaceName(interfaceName);
         interfaceInfo.setInterfaceType(InterfaceInfo.InterfaceType.VLAN_INTERFACE);
         interfaceInfo.setInterfaceTag(delIf.getIfIndex());
-        String elanInstanceName = elanInterface.getElanInstanceName();
+        String elanInstanceName = elanInterface.get().getElanInstanceName();
         ElanInstance elanInstance = elanInstanceCache.get(elanInstanceName).orNull();
         if (elanInstance == null) {
             LOG.debug("No Elan instance is available for the interface:{} ", interfaceName);
@@ -97,13 +102,13 @@ public class ElanInterfaceStateChangeListener
         }
         LOG.trace("Received interface {} up event", intrf);
         String interfaceName =  intrf.getName();
-        ElanInterface elanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(broker, interfaceName);
-        if (elanInterface == null) {
+        Optional<ElanInterface> elanInterface = elanInterfaceCache.get(interfaceName);
+        if (!elanInterface.isPresent()) {
             return;
         }
         InstanceIdentifier<ElanInterface> elanInterfaceId = ElanUtils
                 .getElanInterfaceConfigurationDataPathId(interfaceName);
-        elanInterfaceManager.add(elanInterfaceId, elanInterface);
+        elanInterfaceManager.add(elanInterfaceId, elanInterface.get());
     }
 
     @Override
index 96882d4072c24b2440755e823eb16a4eef36f99b..60c36eb3bb9cce1c8967155e526af6140dcd74c3 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.netvirt.elan.internal;
 
+import com.google.common.base.Optional;
 import com.google.common.util.concurrent.ListenableFuture;
 import java.math.BigInteger;
 import java.util.ArrayList;
@@ -25,6 +26,7 @@ import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
 import org.opendaylight.netvirt.elan.ElanException;
 import org.opendaylight.netvirt.elan.cache.ElanInstanceCache;
+import org.opendaylight.netvirt.elan.cache.ElanInterfaceCache;
 import org.opendaylight.netvirt.elan.utils.ElanConstants;
 import org.opendaylight.netvirt.elan.utils.ElanUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
@@ -48,16 +50,18 @@ public class ElanLearntVpnVipToPortListener extends
     private final ElanUtils elanUtils;
     private final JobCoordinator jobCoordinator;
     private final ElanInstanceCache elanInstanceCache;
+    private final ElanInterfaceCache elanInterfaceCache;
 
     @Inject
     public ElanLearntVpnVipToPortListener(DataBroker broker, IInterfaceManager interfaceManager, ElanUtils elanUtils,
-            JobCoordinator jobCoordinator, ElanInstanceCache elanInstanceCache) {
+            JobCoordinator jobCoordinator, ElanInstanceCache elanInstanceCache, ElanInterfaceCache elanInterfaceCache) {
         super(LearntVpnVipToPort.class, ElanLearntVpnVipToPortListener.class);
         this.broker = broker;
         this.interfaceManager = interfaceManager;
         this.elanUtils = elanUtils;
         this.jobCoordinator = jobCoordinator;
         this.elanInstanceCache = elanInstanceCache;
+        this.elanInterfaceCache = elanInterfaceCache;
     }
 
     @Override
@@ -110,15 +114,15 @@ public class ElanLearntVpnVipToPortListener extends
 
         @Override
         public List<ListenableFuture<Void>> call() throws Exception {
-            ElanInterface elanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(broker, interfaceName);
-            if (elanInterface == null) {
+            Optional<ElanInterface> elanInterface = elanInterfaceCache.get(interfaceName);
+            if (!elanInterface.isPresent()) {
                 LOG.debug("ElanInterface Not present for interfaceName {} for add event", interfaceName);
                 return Collections.emptyList();
             }
             WriteTransaction interfaceTx = broker.newWriteOnlyTransaction();
             WriteTransaction flowTx = broker.newWriteOnlyTransaction();
-            addMacEntryToDsAndSetupFlows(elanInterface.getElanInstanceName(), interfaceTx,
-                    flowTx, ElanConstants.STATIC_MAC_TIMEOUT);
+            addMacEntryToDsAndSetupFlows(elanInterface.get().getElanInstanceName(), interfaceTx, flowTx,
+                    ElanConstants.STATIC_MAC_TIMEOUT);
             List<ListenableFuture<Void>> futures = new ArrayList<>();
             futures.add(interfaceTx.submit());
             futures.add(flowTx.submit());
@@ -157,15 +161,14 @@ public class ElanLearntVpnVipToPortListener extends
 
         @Override
         public List<ListenableFuture<Void>> call() throws Exception {
-            ElanInterface elanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(broker, interfaceName);
-            if (elanInterface == null) {
+            Optional<ElanInterface> elanInterface = elanInterfaceCache.get(interfaceName);
+            if (!elanInterface.isPresent()) {
                 LOG.debug("ElanInterface Not present for interfaceName {} for delete event", interfaceName);
                 return Collections.emptyList();
             }
             WriteTransaction interfaceTx = broker.newWriteOnlyTransaction();
             WriteTransaction flowTx = broker.newWriteOnlyTransaction();
-            deleteMacEntryFromDsAndRemoveFlows(elanInterface.getElanInstanceName(), interfaceTx,
-                    flowTx);
+            deleteMacEntryFromDsAndRemoveFlows(elanInterface.get().getElanInstanceName(), interfaceTx, flowTx);
             List<ListenableFuture<Void>> futures = new ArrayList<>();
             futures.add(interfaceTx.submit());
             futures.add(flowTx.submit());
index d696419ea59eb81c9936e21674e0621d585bbe44..924ea32f3d6ff683698fa3b80a1a9af85897a6ec 100644 (file)
@@ -44,6 +44,7 @@ import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException
 import org.opendaylight.netvirt.elan.arp.responder.ArpResponderInput;
 import org.opendaylight.netvirt.elan.arp.responder.ArpResponderUtil;
 import org.opendaylight.netvirt.elan.cache.ElanInstanceCache;
+import org.opendaylight.netvirt.elan.cache.ElanInterfaceCache;
 import org.opendaylight.netvirt.elan.utils.ElanConstants;
 import org.opendaylight.netvirt.elan.utils.ElanUtils;
 import org.opendaylight.netvirt.elanmanager.api.ElanHelper;
@@ -97,6 +98,7 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
     private final SouthboundUtils southboundUtils;
     private final IMdsalApiManager mdsalManager;
     private final ElanInstanceCache elanInstanceCache;
+    private final ElanInterfaceCache elanInterfaceCache;
     private boolean isL2BeforeL3;
 
     private final EntityOwnershipCandidateRegistration candidateRegistration;
@@ -109,7 +111,7 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
                                ElanUtils elanUtils,
                                EntityOwnershipService entityOwnershipService,
                                SouthboundUtils southboundUtils, ElanInstanceCache elanInstanceCache,
-                               IMdsalApiManager mdsalManager) {
+                               ElanInterfaceCache elanInterfaceCache, IMdsalApiManager mdsalManager) {
         this.idManager = idManager;
         this.interfaceManager = interfaceManager;
         this.elanInstanceManager = elanInstanceManager;
@@ -118,6 +120,7 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
         this.elanUtils = elanUtils;
         this.southboundUtils = southboundUtils;
         this.elanInstanceCache = elanInstanceCache;
+        this.elanInterfaceCache = elanInterfaceCache;
         this.mdsalManager = mdsalManager;
 
         candidateRegistration = registerCandidate(entityOwnershipService);
@@ -228,7 +231,7 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
 
     @Override
     public EtreeInterface getEtreeInterfaceByElanInterfaceName(String elanInterface) {
-        return ElanUtils.getEtreeInterfaceByElanInterfaceName(broker, elanInterface);
+        return elanInterfaceCache.getEtreeInterface(elanInterface).orNull();
     }
 
     public static boolean compareWithExistingElanInstance(ElanInstance existingElanInstance, long macTimeOut,
@@ -314,8 +317,8 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
     @Override
     public void updateElanInterface(String elanInstanceName, String interfaceName,
             List<String> updatedStaticMacAddresses, String newDescription) {
-        ElanInterface existingElanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(broker, interfaceName);
-        if (existingElanInterface == null) {
+        Optional<ElanInterface> existingElanInterface = elanInterfaceCache.get(interfaceName);
+        if (!existingElanInterface.isPresent()) {
             return;
         }
 
@@ -336,8 +339,8 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
 
     @Override
     public void deleteElanInterface(String elanInstanceName, String interfaceName) {
-        ElanInterface existingElanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(broker, interfaceName);
-        if (existingElanInterface != null) {
+        Optional<ElanInterface> existingElanInterface = elanInterfaceCache.get(interfaceName);
+        if (existingElanInterface.isPresent()) {
             ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
                     ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName));
             LOG.debug("deleting the Elan Interface {}", existingElanInterface);
@@ -346,26 +349,22 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
 
     @Override
     public void addStaticMacAddress(String elanInstanceName, String interfaceName, String macAddress) {
-        ElanInterface existingElanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(broker, interfaceName);
-        PhysAddress updateStaticMacAddress = new PhysAddress(macAddress);
-        if (existingElanInterface != null) {
+        Optional<ElanInterface> existingElanInterface = elanInterfaceCache.get(interfaceName);
+        if (existingElanInterface.isPresent()) {
             StaticMacEntriesBuilder staticMacEntriesBuilder = new StaticMacEntriesBuilder();
-            StaticMacEntries staticMacEntry = staticMacEntriesBuilder.setMacAddress(updateStaticMacAddress).build();
+            StaticMacEntries staticMacEntry = staticMacEntriesBuilder.setMacAddress(
+                    new PhysAddress(macAddress)).build();
             InstanceIdentifier<StaticMacEntries> staticMacEntriesIdentifier =
-                    ElanUtils.getStaticMacEntriesCfgDataPathIdentifier(interfaceName,
-                    macAddress);
+                    ElanUtils.getStaticMacEntriesCfgDataPathIdentifier(interfaceName, macAddress);
             MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, staticMacEntriesIdentifier, staticMacEntry);
-            return;
         }
-
-        return;
     }
 
     @Override
     public void deleteStaticMacAddress(String elanInstanceName, String interfaceName, String macAddress)
             throws MacNotFoundException {
-        ElanInterface existingElanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(broker, interfaceName);
-        if (existingElanInterface != null) {
+        Optional<ElanInterface> existingElanInterface = elanInterfaceCache.get(interfaceName);
+        if (existingElanInterface.isPresent()) {
             InstanceIdentifier<StaticMacEntries> staticMacEntriesIdentifier =
                     ElanUtils.getStaticMacEntriesCfgDataPathIdentifier(interfaceName,
                     macAddress);
@@ -662,7 +661,7 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
 
     @Override
     public ElanInterface getElanInterfaceByElanInterfaceName(String interfaceName) {
-        return ElanUtils.getElanInterfaceByElanInterfaceName(broker, interfaceName);
+        return elanInterfaceCache.get(interfaceName).orNull();
     }
 
     @Override
@@ -865,8 +864,9 @@ public class ElanServiceProvider extends AbstractLifecycle implements IElanServi
 
         LOG.info("Installing the ARP responder flow on DPN {} for Interface {} with MAC {} & IP {}", dpnId,
                 ingressInterfaceName, macAddress, ipAddress);
-        ElanInterface elanIface = ElanUtils.getElanInterfaceByElanInterfaceName(broker, ingressInterfaceName);
-        ElanInstance elanInstance = elanInstanceCache.get(elanIface.getElanInstanceName()).orNull();
+        Optional<ElanInterface> elanIface = elanInterfaceCache.get(ingressInterfaceName);
+        ElanInstance elanInstance = elanIface.isPresent()
+                ? elanInstanceCache.get(elanIface.get().getElanInstanceName()).orNull() : null;
         if (elanInstance == null) {
             LOG.debug("addArpResponderFlow: elanInstance is null, Failed to install arp responder flow for Interface {}"
                       + " with MAC {} & IP {}", dpnId,
index 6c6a081a9503b08465a608afa725eeb70ce75408..e080e0082f2e414d2545aa5ab192a7f689973b10 100755 (executable)
@@ -7,14 +7,14 @@
  */
 package org.opendaylight.netvirt.elan.statisitcs;
 
+import com.google.common.base.Optional;
 import com.google.common.util.concurrent.Futures;
 import java.util.concurrent.Future;
 import javax.inject.Inject;
 import javax.inject.Singleton;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
-import org.opendaylight.netvirt.elan.utils.ElanUtils;
+import org.opendaylight.netvirt.elan.cache.ElanInterfaceCache;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius._interface.statistics.rev150824.ResultCode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.statistics.rev150824.ElanStatisticsService;
@@ -32,13 +32,14 @@ import org.slf4j.LoggerFactory;
 public class ElanStatisticsImpl implements ElanStatisticsService {
     private static final Logger LOG = LoggerFactory.getLogger(ElanStatisticsImpl.class);
 
-    private final DataBroker dataBroker;
     private final IInterfaceManager interfaceManager;
+    private final ElanInterfaceCache elanInterfaceCache;
 
     @Inject
-    public ElanStatisticsImpl(DataBroker dataBroker, IInterfaceManager interfaceManager) {
-        this.dataBroker = dataBroker;
+    public ElanStatisticsImpl(IInterfaceManager interfaceManager,
+            ElanInterfaceCache elanInterfaceCache) {
         this.interfaceManager = interfaceManager;
+        this.elanInterfaceCache = elanInterfaceCache;
     }
 
     @Override
@@ -51,13 +52,13 @@ public class ElanStatisticsImpl implements ElanStatisticsService {
             rpcResultBuilder = RpcResultBuilder.failed();
             return getFutureWithAppErrorMessage(rpcResultBuilder, "Interface name is not provided");
         }
-        ElanInterface elanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(dataBroker, interfaceName);
-        if (elanInterface == null) {
+        Optional<ElanInterface> elanInterface = elanInterfaceCache.get(interfaceName);
+        if (!elanInterface.isPresent()) {
             rpcResultBuilder = RpcResultBuilder.failed();
             return getFutureWithAppErrorMessage(rpcResultBuilder,
                     String.format("Interface %s is not a ELAN interface", interfaceName));
         }
-        String elanInstanceName = elanInterface.getElanInstanceName();
+        String elanInstanceName = elanInterface.get().getElanInstanceName();
         InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
         //FIXME [ELANBE] Get this API Later
         short tableId = 0;
diff --git a/elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/utils/CacheElanInterfaceListener.java b/elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/utils/CacheElanInterfaceListener.java
deleted file mode 100644 (file)
index 5e17337..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.netvirt.elan.utils;
-
-import java.util.Collection;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
-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.DataTreeIdentifier;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Singleton
-public class CacheElanInterfaceListener implements ClusteredDataTreeChangeListener<ElanInterface> {
-
-    private ListenerRegistration<CacheElanInterfaceListener> registration;
-    private static final Logger LOG = LoggerFactory.getLogger(CacheElanInterfaceListener.class);
-    private final DataBroker broker;
-
-    @Inject
-    public CacheElanInterfaceListener(DataBroker dataBroker) {
-        this.broker = dataBroker;
-    }
-
-    @PostConstruct
-    public void init() {
-        registerListener();
-    }
-
-    private void registerListener() {
-        final DataTreeIdentifier<ElanInterface> treeId =
-                new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, getWildcardPath());
-        LOG.trace("Registering on path: {}", treeId);
-        registration = broker.registerDataTreeChangeListener(treeId, CacheElanInterfaceListener.this);
-    }
-
-    protected InstanceIdentifier<ElanInterface> getWildcardPath() {
-        return InstanceIdentifier.create(ElanInterfaces.class).child(ElanInterface.class);
-    }
-
-    @PreDestroy
-    public void close() throws Exception {
-        if (registration != null) {
-            registration.close();
-        }
-    }
-
-    @Override
-    public void onDataTreeChanged(Collection<DataTreeModification<ElanInterface>> changes) {
-        for (DataTreeModification<ElanInterface> change : changes) {
-            DataObjectModification<ElanInterface> mod = change.getRootNode();
-            switch (mod.getModificationType()) {
-                case DELETE:
-                    ElanUtils.removeElanInterfaceFromCache(mod.getDataBefore().getName());
-                    ElanUtils.removeElanInterfaceToElanInstanceCache(mod.getDataBefore().getElanInstanceName(),
-                            mod.getDataBefore().getName());
-                    break;
-                case SUBTREE_MODIFIED:
-                case WRITE:
-                    ElanInterface elanInterface = mod.getDataAfter();
-                    ElanUtils.addElanInterfaceIntoCache(elanInterface.getName(), elanInterface);
-                    ElanUtils.addElanInterfaceToElanInstanceCache(elanInterface.getElanInstanceName(),
-                            elanInterface.getName());
-                    break;
-                default:
-                    throw new IllegalArgumentException("Unhandled modification type " + mod.getModificationType());
-            }
-        }
-    }
-
-}
index cdf3487fe67e4391fb13dab85225c97f4c7717e8..67081547d841e696d19ef8847679adeea4f2854b 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.netvirt.elan.utils;
 
+import com.google.common.base.Optional;
 import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -22,6 +23,7 @@ import org.opendaylight.genius.mdsalutil.MatchInfo;
 import org.opendaylight.genius.mdsalutil.NwConstants;
 import org.opendaylight.genius.utils.batching.ResourceBatchingManager;
 import org.opendaylight.netvirt.elan.ElanException;
+import org.opendaylight.netvirt.elan.cache.ElanInterfaceCache;
 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.FlowId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
@@ -43,12 +45,15 @@ public class ElanDmacUtils {
     private final DataBroker broker;
     private final ElanItmUtils elanItmUtils;
     private final ElanEtreeUtils elanEtreeUtils;
+    private final ElanInterfaceCache elanInterfaceCache;
 
     @Inject
-    public ElanDmacUtils(DataBroker broker, ElanItmUtils elanItmUtils, ElanEtreeUtils elanEtreeUtils) {
+    public ElanDmacUtils(DataBroker broker, ElanItmUtils elanItmUtils, ElanEtreeUtils elanEtreeUtils,
+            ElanInterfaceCache elanInterfaceCache) {
         this.broker = broker;
         this.elanItmUtils = elanItmUtils;
         this.elanEtreeUtils = elanEtreeUtils;
+        this.elanInterfaceCache = elanInterfaceCache;
     }
 
     /**
@@ -246,16 +251,13 @@ public class ElanDmacUtils {
             BigInteger dpnId, String extDeviceNodeId, Long vni,
             String macAddress, String displayName, String interfaceName,
             EtreeLeafTagName etreeLeafTag) throws ElanException {
-        boolean isRoot = false;
+        boolean isRoot;
         if (interfaceName == null) {
             isRoot = true;
         } else {
-            EtreeInterface etreeInterface = ElanUtils.getEtreeInterfaceByElanInterfaceName(broker, interfaceName);
-            if (etreeInterface != null) {
-                if (etreeInterface.getEtreeInterfaceType() == EtreeInterface.EtreeInterfaceType.Root) {
-                    isRoot = true;
-                }
-            }
+            Optional<EtreeInterface> etreeInterface = elanInterfaceCache.getEtreeInterface(interfaceName);
+            isRoot = etreeInterface.isPresent() ? etreeInterface.get().getEtreeInterfaceType()
+                    == EtreeInterface.EtreeInterfaceType.Root : false;
         }
         if (isRoot) {
             Flow flow = buildDmacFlowForExternalRemoteMac(dpnId, extDeviceNodeId,
@@ -310,16 +312,13 @@ public class ElanDmacUtils {
             BigInteger dpnId, String extDeviceNodeId, Long vni, String macAddress, String displayName,
             String interfaceName, EtreeLeafTagName etreeLeafTag)throws ElanException {
 
-        boolean isRoot = false;
+        boolean isRoot;
         if (interfaceName == null) {
             isRoot = true;
         } else {
-            EtreeInterface etreeInterface = ElanUtils.getEtreeInterfaceByElanInterfaceName(broker, interfaceName);
-            if (etreeInterface != null) {
-                if (etreeInterface.getEtreeInterfaceType() == EtreeInterface.EtreeInterfaceType.Root) {
-                    isRoot = true;
-                }
-            }
+            Optional<EtreeInterface> etreeInterface = elanInterfaceCache.getEtreeInterface(interfaceName);
+            isRoot = etreeInterface.isPresent() ? etreeInterface.get().getEtreeInterfaceType()
+                    == EtreeInterface.EtreeInterfaceType.Root : false;
         }
         if (isRoot) {
             Flow flow = buildDmacFlowForExternalRemoteMac(dpnId, extDeviceNodeId,
index ed092f23add369cc0b0ca2ce173558a1297f83e7..3c1f3d579253b8498aa19b1d923ca730baf17549 100755 (executable)
@@ -21,11 +21,7 @@ import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import javax.annotation.Nonnull;
@@ -66,6 +62,7 @@ import org.opendaylight.genius.mdsalutil.packet.IPv4;
 import org.opendaylight.infrautils.utils.concurrent.JdkFutures;
 import org.opendaylight.netvirt.elan.ElanException;
 import org.opendaylight.netvirt.elan.arp.responder.ArpResponderUtil;
+import org.opendaylight.netvirt.elan.cache.ElanInterfaceCache;
 import org.opendaylight.netvirt.elanmanager.api.ElanHelper;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
@@ -176,9 +173,6 @@ public class ElanUtils {
 
     private static final Logger LOG = LoggerFactory.getLogger(ElanUtils.class);
 
-    private static Map<String, ElanInterface> elanInterfaceLocalCache = new ConcurrentHashMap<>();
-    private static Map<String, Set<String>> elanInstanceToInterfacesCache = new ConcurrentHashMap<>();
-
     private final DataBroker broker;
     private final IMdsalApiManager mdsalManager;
     private final OdlInterfaceRpcService interfaceManagerRpcService;
@@ -187,6 +181,7 @@ public class ElanUtils {
     private final ElanConfig elanConfig;
     private final ElanItmUtils elanItmUtils;
     private final ElanEtreeUtils elanEtreeUtils;
+    private final ElanInterfaceCache elanInterfaceCache;
 
     public static final FutureCallback<Void> DEFAULT_CALLBACK = new FutureCallback<Void>() {
         @Override
@@ -203,7 +198,8 @@ public class ElanUtils {
     @Inject
     public ElanUtils(DataBroker dataBroker, IMdsalApiManager mdsalManager,
             OdlInterfaceRpcService interfaceManagerRpcService, ItmRpcService itmRpcService, ElanConfig elanConfig,
-            IInterfaceManager interfaceManager, ElanEtreeUtils elanEtreeUtils, ElanItmUtils elanItmUtils) {
+            IInterfaceManager interfaceManager, ElanEtreeUtils elanEtreeUtils, ElanItmUtils elanItmUtils,
+            ElanInterfaceCache elanInterfaceCache) {
         this.broker = dataBroker;
         this.mdsalManager = mdsalManager;
         this.interfaceManagerRpcService = interfaceManagerRpcService;
@@ -212,6 +208,7 @@ public class ElanUtils {
         this.elanConfig = elanConfig;
         this.elanEtreeUtils = elanEtreeUtils;
         this.elanItmUtils = elanItmUtils;
+        this.elanInterfaceCache = elanInterfaceCache;
     }
 
     public final Boolean isOpenstackVniSemanticsEnforced() {
@@ -219,18 +216,6 @@ public class ElanUtils {
                 ? elanConfig.isOpenstackVniSemanticsEnforced() : false;
     }
 
-    public static void addElanInterfaceIntoCache(String interfaceName, ElanInterface elanInterface) {
-        elanInterfaceLocalCache.put(interfaceName, elanInterface);
-    }
-
-    public static void removeElanInterfaceFromCache(String interfaceName) {
-        elanInterfaceLocalCache.remove(interfaceName);
-    }
-
-    public static ElanInterface getElanInterfaceFromCache(String interfaceName) {
-        return elanInterfaceLocalCache.get(interfaceName);
-    }
-
     /**
      * Uses the IdManager to retrieve a brand new ElanTag.
      *
@@ -312,25 +297,6 @@ public class ElanUtils {
         return InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class).build();
     }
 
-    // elan-interfaces Config Container
-    public static ElanInterface getElanInterfaceByElanInterfaceName(DataBroker broker, String elanInterfaceName) {
-        ElanInterface elanInterfaceObj = getElanInterfaceFromCache(elanInterfaceName);
-        if (elanInterfaceObj != null) {
-            return elanInterfaceObj;
-        }
-        InstanceIdentifier<ElanInterface> elanInterfaceId = getElanInterfaceConfigurationDataPathId(elanInterfaceName);
-        return MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, elanInterfaceId).orNull();
-    }
-
-    public static EtreeInterface getEtreeInterfaceByElanInterfaceName(DataBroker broker, String elanInterfaceName) {
-        ElanInterface elanInterface = getElanInterfaceByElanInterfaceName(broker, elanInterfaceName);
-        if (elanInterface == null) {
-            return null;
-        } else {
-            return elanInterface.getAugmentation(EtreeInterface.class);
-        }
-    }
-
     public static InstanceIdentifier<ElanInterface> getElanInterfaceConfigurationDataPathId(String interfaceName) {
         return InstanceIdentifier.builder(ElanInterfaces.class)
                 .child(ElanInterface.class, new ElanInterfaceKey(interfaceName)).build();
@@ -662,7 +628,7 @@ public class ElanUtils {
         List<InstructionInfo> mkInstructions = new ArrayList<>();
         mkInstructions.add(new InstructionGotoTable(NwConstants.ELAN_DMAC_TABLE));
         BigInteger dpId = interfaceInfo.getDpId();
-        long elanTag = getElanTag(broker, elanInfo, interfaceInfo);
+        long elanTag = getElanTag(elanInfo, interfaceInfo);
         return new FlowEntityBuilder()
             .setDpnId(dpId)
             .setTableId(NwConstants.ELAN_SMAC_TABLE)
@@ -680,8 +646,8 @@ public class ElanUtils {
             .build();
     }
 
-    private static Long getElanTag(DataBroker broker, ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
-        EtreeInterface etreeInterface = getEtreeInterfaceByElanInterfaceName(broker, interfaceInfo.getInterfaceName());
+    private Long getElanTag(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+        EtreeInterface etreeInterface = elanInterfaceCache.getEtreeInterface(interfaceInfo.getInterfaceName()).orNull();
         if (etreeInterface == null || etreeInterface.getEtreeInterfaceType() == EtreeInterfaceType.Root) {
             return elanInfo.getElanTag();
         } else { // Leaf
@@ -870,23 +836,21 @@ public class ElanUtils {
         Flow flowEntity = buildLocalDmacFlowEntry(elanTag, dpId, ifName, macAddress, elanInfo, ifTag);
         mdsalApiManager.addFlowToTx(dpId, flowEntity, writeFlowGroupTx);
         installEtreeLocalDmacFlow(elanTag, dpId, ifName, macAddress, elanInfo,
-                mdsalApiManager, ifTag, writeFlowGroupTx);
+                ifTag, writeFlowGroupTx);
     }
 
     private void installEtreeLocalDmacFlow(long elanTag, BigInteger dpId, String ifName, String macAddress,
-            ElanInstance elanInfo, IMdsalApiManager mdsalApiManager, long ifTag, WriteTransaction writeFlowGroupTx) {
-        EtreeInterface etreeInterface = getEtreeInterfaceByElanInterfaceName(broker, ifName);
-        if (etreeInterface != null) {
-            if (etreeInterface.getEtreeInterfaceType() == EtreeInterfaceType.Root) {
-                EtreeLeafTagName etreeTagName = elanEtreeUtils.getEtreeLeafTagByElanTag(elanTag);
-                if (etreeTagName == null) {
-                    LOG.warn("Interface {} seems like it belongs to Etree but etreeTagName from elanTag {} is null",
-                             ifName, elanTag);
-                } else {
-                    Flow flowEntity = buildLocalDmacFlowEntry(etreeTagName.getEtreeLeafTag().getValue(), dpId, ifName,
-                            macAddress, elanInfo, ifTag);
-                    mdsalApiManager.addFlowToTx(dpId, flowEntity, writeFlowGroupTx);
-                }
+            ElanInstance elanInfo, long ifTag, WriteTransaction writeFlowGroupTx) {
+        EtreeInterface etreeInterface = elanInterfaceCache.getEtreeInterface(ifName).orNull();
+        if (etreeInterface != null && etreeInterface.getEtreeInterfaceType() == EtreeInterfaceType.Root) {
+            EtreeLeafTagName etreeTagName = elanEtreeUtils.getEtreeLeafTagByElanTag(elanTag);
+            if (etreeTagName == null) {
+                LOG.warn("Interface {} seems like it belongs to Etree but etreeTagName from elanTag {} is null",
+                        ifName, elanTag);
+            } else {
+                Flow flowEntity = buildLocalDmacFlowEntry(etreeTagName.getEtreeLeafTag().getValue(), dpId, ifName,
+                        macAddress, elanInfo, ifTag);
+                mdsalManager.addFlowToTx(dpId, flowEntity, writeFlowGroupTx);
             }
         }
     }
@@ -978,18 +942,16 @@ public class ElanUtils {
                                           WriteTransaction writeFlowGroupTx, ElanInstance elanInstance)
                                           throws ElanException {
         Flow flowEntity;
-        EtreeInterface etreeInterface = getEtreeInterfaceByElanInterfaceName(broker, interfaceName);
-        if (etreeInterface != null) {
-            if (etreeInterface.getEtreeInterfaceType() == EtreeInterfaceType.Root) {
-                EtreeLeafTagName etreeTagName = elanEtreeUtils.getEtreeLeafTagByElanTag(elanTag);
-                if (etreeTagName == null) {
-                    LOG.warn("Interface " + interfaceName
-                            + " seems like it belongs to Etree but etreeTagName from elanTag " + elanTag + " is null.");
-                } else {
-                    flowEntity = buildRemoteDmacFlowEntry(srcDpId, destDpId, lportTagOrVni,
-                            etreeTagName.getEtreeLeafTag().getValue(), macAddress, displayName, elanInstance);
-                    mdsalManager.addFlowToTx(srcDpId, flowEntity, writeFlowGroupTx);
-                }
+        EtreeInterface etreeInterface = elanInterfaceCache.getEtreeInterface(interfaceName).orNull();
+        if (etreeInterface != null && etreeInterface.getEtreeInterfaceType() == EtreeInterfaceType.Root) {
+            EtreeLeafTagName etreeTagName = elanEtreeUtils.getEtreeLeafTagByElanTag(elanTag);
+            if (etreeTagName == null) {
+                LOG.warn("Interface " + interfaceName
+                        + " seems like it belongs to Etree but etreeTagName from elanTag " + elanTag + " is null.");
+            } else {
+                flowEntity = buildRemoteDmacFlowEntry(srcDpId, destDpId, lportTagOrVni,
+                        etreeTagName.getEtreeLeafTag().getValue(), macAddress, displayName, elanInstance);
+                mdsalManager.addFlowToTx(srcDpId, flowEntity, writeFlowGroupTx);
             }
         }
     }
@@ -1655,23 +1617,6 @@ public class ElanUtils {
         return false;
     }
 
-    public static void addElanInterfaceToElanInstanceCache(String elanInstanceName, String elanInterfaceName) {
-        elanInstanceToInterfacesCache.computeIfAbsent(elanInstanceName, key -> new HashSet<>()).add(elanInterfaceName);
-    }
-
-    public static void removeElanInterfaceToElanInstanceCache(String elanInstanceName, String interfaceName) {
-        Set<String> elanInterfaces = elanInstanceToInterfacesCache.get(elanInstanceName);
-        if (elanInterfaces == null || elanInterfaces.isEmpty()) {
-            return;
-        }
-        elanInterfaces.remove(interfaceName);
-    }
-
-    @Nonnull public static Set<String> removeAndGetElanInterfaces(String elanInstanceName) {
-        Set<String> removed = elanInstanceToInterfacesCache.remove(elanInstanceName);
-        return removed != null ? removed : Collections.emptySet();
-    }
-
     public static InstanceIdentifier<Flow> getFlowIid(Flow flow, BigInteger dpnId) {
         FlowKey flowKey = new FlowKey(new FlowId(flow.getId()));
         org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId nodeId =