--- /dev/null
+/*
+ * 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;
+ });
+ }
+}
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;
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
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);
*/
package org.opendaylight.netvirt.elan.internal;
+import com.google.common.base.Optional;
import java.util.Collections;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
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;
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
}
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;
}
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;
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<>();
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;
this.jobCoordinator = jobCoordinator;
this.elanL2GatewayMulticastUtils = elanL2GatewayMulticastUtils;
this.elanInstanceCache = elanInstanceCache;
+ this.elanInterfaceCache = elanInterfaceCache;
}
@Override
// 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));
}
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++;
*/
package org.opendaylight.netvirt.elan.internal;
+import com.google.common.base.Optional;
import java.math.BigInteger;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
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;
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
}
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;
}
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);
}
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
*/
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;
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;
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
@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());
@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());
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;
private final SouthboundUtils southboundUtils;
private final IMdsalApiManager mdsalManager;
private final ElanInstanceCache elanInstanceCache;
+ private final ElanInterfaceCache elanInterfaceCache;
private boolean isL2BeforeL3;
private final EntityOwnershipCandidateRegistration candidateRegistration;
ElanUtils elanUtils,
EntityOwnershipService entityOwnershipService,
SouthboundUtils southboundUtils, ElanInstanceCache elanInstanceCache,
- IMdsalApiManager mdsalManager) {
+ ElanInterfaceCache elanInterfaceCache, IMdsalApiManager mdsalManager) {
this.idManager = idManager;
this.interfaceManager = interfaceManager;
this.elanInstanceManager = elanInstanceManager;
this.elanUtils = elanUtils;
this.southboundUtils = southboundUtils;
this.elanInstanceCache = elanInstanceCache;
+ this.elanInterfaceCache = elanInterfaceCache;
this.mdsalManager = mdsalManager;
candidateRegistration = registerCandidate(entityOwnershipService);
@Override
public EtreeInterface getEtreeInterfaceByElanInterfaceName(String elanInterface) {
- return ElanUtils.getEtreeInterfaceByElanInterfaceName(broker, elanInterface);
+ return elanInterfaceCache.getEtreeInterface(elanInterface).orNull();
}
public static boolean compareWithExistingElanInstance(ElanInstance existingElanInstance, long macTimeOut,
@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;
}
@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);
@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);
@Override
public ElanInterface getElanInterfaceByElanInterfaceName(String interfaceName) {
- return ElanUtils.getElanInterfaceByElanInterfaceName(broker, interfaceName);
+ return elanInterfaceCache.get(interfaceName).orNull();
}
@Override
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,
*/
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;
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
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;
+++ /dev/null
-/*
- * 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());
- }
- }
- }
-
-}
*/
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;
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;
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;
}
/**
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,
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,
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;
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;
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;
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
@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;
this.elanConfig = elanConfig;
this.elanEtreeUtils = elanEtreeUtils;
this.elanItmUtils = elanItmUtils;
+ this.elanInterfaceCache = elanInterfaceCache;
}
public final Boolean isOpenstackVniSemanticsEnforced() {
? 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.
*
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();
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)
.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
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);
}
}
}
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);
}
}
}
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 =