package org.opendaylight.netvirt.elan.internal;
+import static java.util.Collections.emptyList;
+
import com.google.common.base.Optional;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.math.BigInteger;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Future;
import java.util.function.BiFunction;
-import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.inject.Singleton;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.infra.Datastore;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.interfacemanager.exceptions.InterfaceAlreadyExistsException;
import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
-import org.opendaylight.genius.mdsalutil.MatchInfoBase;
-import org.opendaylight.genius.mdsalutil.MetaDataUtil;
import org.opendaylight.genius.mdsalutil.NwConstants;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
-import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchRegister;
import org.opendaylight.genius.utils.ServiceIndex;
import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
import org.opendaylight.infrautils.inject.AbstractLifecycle;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.mdsal.eos.binding.api.Entity;
import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipCandidateRegistration;
import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
import org.opendaylight.netvirt.elan.utils.ElanUtils;
import org.opendaylight.netvirt.elanmanager.api.ElanHelper;
import org.opendaylight.netvirt.elanmanager.api.IElanService;
-import org.opendaylight.netvirt.elanmanager.exceptions.MacNotFoundException;
import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInstance;
private final IInterfaceManager interfaceManager;
private final ElanBridgeManager bridgeMgr;
private final DataBroker broker;
+ private final ManagedNewTransactionRunner txRunner;
private final ElanUtils elanUtils;
private final SouthboundUtils southboundUtils;
private final IMdsalApiManager mdsalManager;
public ElanServiceProvider(IdManagerService idManager, IInterfaceManager interfaceManager,
ElanBridgeManager bridgeMgr,
DataBroker dataBroker,
- ElanInterfaceManager elanInterfaceManager,
ElanUtils elanUtils,
EntityOwnershipService entityOwnershipService,
SouthboundUtils southboundUtils, ElanInstanceCache elanInstanceCache,
this.interfaceManager = interfaceManager;
this.bridgeMgr = bridgeMgr;
this.broker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.elanUtils = elanUtils;
this.southboundUtils = southboundUtils;
this.elanInstanceCache = elanInstanceCache;
candidateRegistration = registerCandidate(entityOwnershipService);
}
+ @Nullable
private static EntityOwnershipCandidateRegistration registerCandidate(
EntityOwnershipService entityOwnershipService) {
try {
private void createIdPool() throws Exception {
CreateIdPoolInput createPool = new CreateIdPoolInputBuilder().setPoolName(ElanConstants.ELAN_ID_POOL_NAME)
.setLow(ElanConstants.ELAN_ID_LOW_VALUE).setHigh(ElanConstants.ELAN_ID_HIGH_VALUE).build();
- Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
+ Future<RpcResult<CreateIdPoolOutput>> result = idManager.createIdPool(createPool);
if (result != null && result.get().isSuccessful()) {
LOG.debug("ELAN Id Pool is created successfully");
}
} else {
ElanInstance updateElanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName)
.setDescription(description).setMacTimeout(macTimeout)
- .setKey(new ElanInstanceKey(elanInstanceName)).build();
+ .withKey(new ElanInstanceKey(elanInstanceName)).build();
MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
ElanHelper.getElanInstanceConfigurationDataPath(elanInstanceName), updateElanInstance);
- LOG.debug("Updating the Elan Instance {} with MAC TIME-OUT %l and Description %s ",
+ LOG.debug("Updating the Elan Instance {} with MAC TIME-OUT {} and Description {}",
updateElanInstance, macTimeout, description);
}
} else {
ElanInstance elanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName)
- .setMacTimeout(macTimeout).setDescription(description).setKey(new ElanInstanceKey(elanInstanceName))
- .build();
+ .setMacTimeout(macTimeout).setDescription(description)
+ .withKey(new ElanInstanceKey(elanInstanceName)).build();
MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
ElanHelper.getElanInstanceConfigurationDataPath(elanInstanceName), elanInstance);
LOG.debug("Creating the new Elan Instance {}", elanInstance);
EtreeInstance etreeInstance = new EtreeInstanceBuilder().build();
ElanInstance updateElanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName)
.setDescription(description).setMacTimeout(macTimeout)
- .setKey(new ElanInstanceKey(elanInstanceName))
+ .withKey(new ElanInstanceKey(elanInstanceName))
.addAugmentation(EtreeInstance.class, etreeInstance).build();
MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
ElanHelper.getElanInstanceConfigurationDataPath(elanInstanceName), updateElanInstance);
- LOG.debug("Updating the Etree Instance {} with MAC TIME-OUT %l and Description %s ",
+ LOG.debug("Updating the Etree Instance {} with MAC TIME-OUT {} and Description {} ",
updateElanInstance, macTimeout, description);
}
} else {
EtreeInstance etreeInstance = new EtreeInstanceBuilder().build();
ElanInstance elanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName)
- .setMacTimeout(macTimeout).setDescription(description).setKey(new ElanInstanceKey(elanInstanceName))
+ .setMacTimeout(macTimeout).setDescription(description)
+ .withKey(new ElanInstanceKey(elanInstanceName))
.addAugmentation(EtreeInstance.class, etreeInstance).build();
MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
ElanHelper.getElanInstanceConfigurationDataPath(elanInstanceName), elanInstance);
}
@Override
+ @Nullable
public EtreeInterface getEtreeInterfaceByElanInterfaceName(String elanInterface) {
return elanInterfaceCache.getEtreeInterface(elanInterface).orNull();
}
String description) {
boolean isEqual = false;
if (existingElanInstance.getMacTimeout() == macTimeOut
- && existingElanInstance.getDescription().equals(description)) {
+ && Objects.equals(existingElanInstance.getDescription(), description)) {
isEqual = true;
}
return isEqual;
@Override
public boolean deleteElanInstance(String elanInstanceName) {
- boolean isSuccess = false;
Optional<ElanInstance> existingElanInstance = elanInstanceCache.get(elanInstanceName);
if (!existingElanInstance.isPresent()) {
LOG.debug("Elan Instance is not present for {}", elanInstanceName);
- return isSuccess;
+ return false;
}
LOG.debug("Deletion of the existing Elan Instance {}", existingElanInstance);
ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
ElanHelper.getElanInstanceConfigurationDataPath(elanInstanceName));
- isSuccess = true;
- return isSuccess;
+ return true;
}
@Override
List<String> staticMacAddresses, String description) {
Optional<ElanInstance> existingElanInstance = elanInstanceCache.get(etreeInstanceName);
if (existingElanInstance.isPresent()
- && existingElanInstance.get().getAugmentation(EtreeInstance.class) != null) {
+ && existingElanInstance.get().augmentation(EtreeInstance.class) != null) {
EtreeInterface etreeInterface = new EtreeInterfaceBuilder().setEtreeInterfaceType(interfaceType).build();
ElanInterface elanInterface;
if (staticMacAddresses == null) {
elanInterface = new ElanInterfaceBuilder().setElanInstanceName(etreeInstanceName)
- .setDescription(description).setName(interfaceName).setKey(new ElanInterfaceKey(interfaceName))
+ .setDescription(description).setName(interfaceName).withKey(new ElanInterfaceKey(interfaceName))
.addAugmentation(EtreeInterface.class, etreeInterface).build();
} else {
List<StaticMacEntries> staticMacEntries = ElanUtils.getStaticMacEntries(staticMacAddresses);
elanInterface = new ElanInterfaceBuilder().setElanInstanceName(etreeInstanceName)
.setDescription(description).setName(interfaceName)
.setStaticMacEntries(staticMacEntries)
- .setKey(new ElanInterfaceKey(interfaceName))
+ .withKey(new ElanInterfaceKey(interfaceName))
.addAugmentation(EtreeInterface.class, etreeInterface).build();
}
MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
}
@Override
- public void addElanInterface(String elanInstanceName, String interfaceName, List<String> staticMacAddresses,
- String description) {
+ public void addElanInterface(String elanInstanceName, String interfaceName,
+ @Nullable List<String> staticMacAddresses, @Nullable String description) {
Optional<ElanInstance> existingElanInstance = elanInstanceCache.get(elanInstanceName);
if (existingElanInstance.isPresent()) {
ElanInterfaceBuilder elanInterfaceBuilder = new ElanInterfaceBuilder()
.setElanInstanceName(elanInstanceName)
.setDescription(description).setName(interfaceName)
- .setKey(new ElanInterfaceKey(interfaceName));
+ .withKey(new ElanInterfaceKey(interfaceName));
if (staticMacAddresses != null) {
List<StaticMacEntries> staticMacEntries = ElanUtils.getStaticMacEntries(staticMacAddresses);
elanInterfaceBuilder.setStaticMacEntries(staticMacEntries);
LOG.debug("updating the ElanInterface with new Mac Entries {}", updatedStaticMacAddresses);
ElanInterface elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName)
.setName(interfaceName).setDescription(newDescription).setStaticMacEntries(updatedStaticMacEntries)
- .setKey(new ElanInterfaceKey(interfaceName)).build();
+ .withKey(new ElanInterfaceKey(interfaceName)).build();
MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName), elanInterface);
}
@Override
- public void deleteEtreeInterface(String elanInstanceName, String interfaceName) {
- deleteElanInterface(elanInstanceName, interfaceName);
+ public void deleteEtreeInterface(String interfaceName) {
+ deleteElanInterface(interfaceName);
LOG.debug("deleting the Etree Interface {}", interfaceName);
}
@Override
- public void deleteElanInterface(String elanInstanceName, String interfaceName) {
+ public void deleteElanInterface(String interfaceName) {
Optional<ElanInterface> existingElanInterface = elanInterfaceCache.get(interfaceName);
if (existingElanInterface.isPresent()) {
ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
}
@Override
- public void addStaticMacAddress(String elanInstanceName, String interfaceName, String macAddress) {
+ public void addStaticMacAddress(String interfaceName, String macAddress) {
Optional<ElanInterface> existingElanInterface = elanInterfaceCache.get(interfaceName);
if (existingElanInterface.isPresent()) {
StaticMacEntriesBuilder staticMacEntriesBuilder = new StaticMacEntriesBuilder();
}
@Override
- public void deleteStaticMacAddress(String elanInstanceName, String interfaceName, String macAddress)
- throws MacNotFoundException {
+ public void deleteStaticMacAddress(String interfaceName, String macAddress) {
Optional<ElanInterface> existingElanInterface = elanInterfaceCache.get(interfaceName);
if (existingElanInterface.isPresent()) {
InstanceIdentifier<StaticMacEntries> staticMacEntriesIdentifier =
if (elanInterfaceMac.getMacEntry() != null && elanInterfaceMac.getMacEntry().size() > 0) {
List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
for (MacEntry macEntry : macEntries) {
- try {
- deleteStaticMacAddress(elanInstanceName, elanInterface, macEntry.getMacAddress().getValue());
- } catch (MacNotFoundException e) {
- LOG.error("Mac Not Found Exception {}", e);
- }
+ deleteStaticMacAddress(elanInterface, macEntry.getMacAddress().getValue());
}
}
}
}
@Override
+ @Nullable
public ElanInstance getElanInstance(String elanName) {
return elanInstanceCache.get(elanName).orNull();
}
InstanceIdentifier<ElanInstances> elanInstancesIdentifier = InstanceIdentifier.builder(ElanInstances.class)
.build();
return ElanUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanInstancesIdentifier).toJavaUtil().map(
- ElanInstances::getElanInstance).orElse(Collections.emptyList());
+ ElanInstances::getElanInstance).orElse(emptyList());
}
@Override
- @Nonnull
+ @NonNull
public List<String> getElanInterfaces(String elanInstanceName) {
List<String> elanInterfaces = new ArrayList<>();
InstanceIdentifier<ElanInterfaces> elanInterfacesIdentifier = InstanceIdentifier.builder(ElanInterfaces.class)
if (!elanInterfacesOptional.isPresent()) {
return elanInterfaces;
}
- List<ElanInterface> elanInterfaceList = elanInterfacesOptional.get().getElanInterface();
+ List<ElanInterface> elanInterfaceList = elanInterfacesOptional.get().nonnullElanInterface();
for (ElanInterface elanInterface : elanInterfaceList) {
- if (elanInterface.getElanInstanceName().equals(elanInstanceName)) {
+ if (Objects.equals(elanInterface.getElanInstanceName(), elanInstanceName)) {
elanInterfaces.add(elanInterface.getName());
}
}
String intfName = providerIntfName + IfmConstants.OF_URI_SEPARATOR + elanInstance.getSegmentationId();
Interface memberIntf = interfaceManager.getInterfaceInfoFromConfigDataStore(intfName);
if (memberIntf != null) {
- deleteElanInterface(elanInstance.getElanInstanceName(), intfName);
+ deleteElanInterface(intfName);
deleteIetfInterface(intfName);
LOG.debug("delete vlan prv intf {} in elan {}, dpID {}", intfName,
elanInstance.getElanInstanceName(), dpnId);
if (shouldDeleteTrunk(trunkInterfaceName, elanInterface)) {
deleteIetfInterface(trunkInterfaceName);
}
- deleteElanInterface(elanInstanceName, elanInterface);
+ deleteElanInterface(elanInterface);
}
}
}
}
@Override
+ @Nullable
public ElanInterface getElanInterfaceByElanInterfaceName(String interfaceName) {
return elanInterfaceCache.get(interfaceName).orNull();
}
elanUtils.removeDmacRedirectToDispatcherFlows(elanInstance.getElanTag(), macAddress, dpnsIdsForElanInstance);
}
- @Override
- public List<MatchInfoBase> getEgressMatchesForElanInstance(String elanInstanceName) {
- ElanInstance elanInstance = getElanInstance(elanInstanceName);
- if (elanInstance == null) {
- LOG.debug("No ELAN instance found for {}", elanInstanceName);
- return Collections.emptyList();
- }
-
- Long elanTag = elanInstance.getElanTag();
- if (elanTag == null) {
- LOG.debug("No ELAN tag found for {}", elanInstanceName);
- return Collections.emptyList();
- }
- return Collections.singletonList(
- new NxMatchRegister(ElanConstants.ELAN_REG_ID, elanTag, MetaDataUtil.getElanMaskForReg()));
- }
-
/**
* Create ietf-interfaces based on the ELAN segment type.<br>
* For segment type flat - create transparent interface pointing to the
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,
- ingressInterfaceName, macAddress, ipAddress);
+ LOG.debug("addArpResponderFlow: elanInstance is null, Failed to install arp responder flow for dpnId {}"
+ + "for Interface {} with MAC {} & IP {}", dpnId, ingressInterfaceName, macAddress, ipAddress);
return;
}
String flowId = ArpResponderUtil.getFlowId(lportTag, ipAddress);
- ArpResponderUtil.installFlow(mdsalManager, dpnId, flowId, flowId, NwConstants.DEFAULT_ARP_FLOW_PRIORITY,
+ Flow flowEntity =
+ MDSALUtil.buildFlowNew(NwConstants.ARP_RESPONDER_TABLE, flowId, NwConstants.DEFAULT_ARP_FLOW_PRIORITY,
+ flowId, 0, 0,
ArpResponderUtil.generateCookie(lportTag, ipAddress),
ArpResponderUtil.getMatchCriteria(lportTag, elanInstance, ipAddress),
arpResponderInput.getInstructions());
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.CONFIGURATION,
+ tx -> mdsalManager.addFlow(tx, dpnId, flowEntity)), LOG, "Error adding flow {}", flowEntity);
LOG.info("Installed the ARP Responder flow for Interface {}", ingressInterfaceName);
}
int lportTag = arpResponderInput.getLportTag();
String flowId = ArpResponderUtil.getFlowId(lportTag, ipAddress);
- ArpResponderUtil.installFlow(mdsalManager, dpnId, flowId, flowId, NwConstants.DEFAULT_ARP_FLOW_PRIORITY,
- ArpResponderUtil.generateCookie(lportTag, ipAddress), ArpResponderUtil.getMatchCriteria(lportTag,
- elanInstance, ipAddress), arpResponderInput.getInstructions());
+ Flow flowEntity =
+ MDSALUtil.buildFlowNew(NwConstants.ARP_RESPONDER_TABLE, flowId, NwConstants.DEFAULT_ARP_FLOW_PRIORITY,
+ flowId, 0, 0,
+ ArpResponderUtil.generateCookie(lportTag, ipAddress),
+ ArpResponderUtil.getMatchCriteria(lportTag, elanInstance, ipAddress),
+ arpResponderInput.getInstructions());
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.CONFIGURATION,
+ tx -> mdsalManager.addFlow(tx, dpnId, flowEntity)), LOG, "Error adding flow {}", flowEntity);
LOG.trace("Installed the ExternalTunnel ARP Responder flow for ElanInstance {}", elanInstanceName);
}