import java.util.concurrent.Future;
import javax.inject.Inject;
import javax.inject.Singleton;
-
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.genius.mdsalutil.packet.ARP;
import org.opendaylight.genius.mdsalutil.packet.Ethernet;
import org.opendaylight.genius.mdsalutil.packet.IPv4;
-import org.opendaylight.infrautils.utils.concurrent.JdkFutures;
-import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
+import org.opendaylight.infrautils.utils.concurrent.LoggingFutures;
+import org.opendaylight.infrautils.utils.concurrent.NamedLocks;
+import org.opendaylight.infrautils.utils.concurrent.NamedSimpleReentrantLock.Acquired;
import org.opendaylight.netvirt.elan.arp.responder.ArpResponderUtil;
import org.opendaylight.netvirt.elan.cache.ElanInterfaceCache;
import org.opendaylight.netvirt.elanmanager.api.ElanHelper;
@Singleton
public class ElanUtils {
+ private static final class ElanLockName {
+ private final String macAddress;
+ private final BigInteger dpnId;
+ private final long elanTag;
+
+ ElanLockName(long elanTag, String macAddress, BigInteger dpnId) {
+ this.elanTag = elanTag;
+ this.macAddress = macAddress;
+ this.dpnId = dpnId;
+ }
+
+ @Override
+ public int hashCode() {
+ return 31 * Long.hashCode(elanTag) + Objects.hash(macAddress, dpnId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof ElanLockName)) {
+ return false;
+ }
+ final ElanLockName other = (ElanLockName) obj;
+ return elanTag == other.elanTag && Objects.equals(macAddress, other.macAddress)
+ && Objects.equals(dpnId, other.dpnId);
+ }
+ }
private static final Logger LOG = LoggerFactory.getLogger(ElanUtils.class);
+ private static final NamedLocks<ElanLockName> ELAN_LOCKS = new NamedLocks<>();
private final DataBroker broker;
private final ManagedNewTransactionRunner txRunner;
public static void releaseId(IdManagerService idManager, String poolName, String idKey) {
ReleaseIdInput releaseIdInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
- JdkFutures.addErrorLogging(idManager.releaseId(releaseIdInput), LOG, "Release Id");
+ LoggingFutures.addErrorLogging(idManager.releaseId(releaseIdInput), LOG, "Release Id");
}
/**
public void setupMacFlows(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
long macTimeout, String macAddress, boolean configureRemoteFlows,
TypedWriteTransaction<Configuration> writeFlowGroupTx) {
- synchronized (getElanMacDPNKey(elanInfo.getElanTag(), macAddress, interfaceInfo.getDpId())) {
+ try (Acquired lock = lockElanMacDPN(elanInfo.getElanTag(), macAddress, interfaceInfo.getDpId())) {
setupKnownSmacFlow(elanInfo, interfaceInfo, macTimeout, macAddress, mdsalManager,
writeFlowGroupTx);
setupOrigDmacFlows(elanInfo, interfaceInfo, macAddress, configureRemoteFlows, mdsalManager,
* @return the Internal tunnel
*/
public static String getIntTunnelTableFlowRef(short tableId, int elanTag) {
- return new StringBuffer().append(tableId).append(elanTag).toString();
+ return new StringBuilder().append(tableId).append(elanTag).toString();
}
/**
return;
}
String macAddress = macEntry.getMacAddress().getValue();
- synchronized (getElanMacDPNKey(elanInfo.getElanTag(), macAddress, interfaceInfo.getDpId())) {
+ try (Acquired lock = lockElanMacDPN(elanInfo.getElanTag(), macAddress, interfaceInfo.getDpId())) {
deleteMacFlows(elanInfo, interfaceInfo, macAddress, /* alsoDeleteSMAC */ true, flowTx);
}
}
public void addDmacRedirectToDispatcherFlows(Long elanTag, String displayName,
String macAddress, List<BigInteger> dpnIds) {
for (BigInteger dpId : dpnIds) {
- ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ LoggingFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
tx -> mdsalManager.addFlow(tx, buildDmacRedirectToDispatcherFlow(dpId, macAddress, displayName,
elanTag))), LOG,
"Error adding DMAC redirect to dispatcher flows");
}
public void removeDmacRedirectToDispatcherFlows(Long elanTag, String macAddress, List<BigInteger> dpnIds) {
- ListenableFutures.addErrorLogging(
+ LoggingFutures.addErrorLogging(
txRunner.callWithNewReadWriteTransactionAndSubmit(Datastore.CONFIGURATION, tx -> {
for (BigInteger dpId : dpnIds) {
String flowId = getKnownDynamicmacFlowRef(NwConstants.ELAN_DMAC_TABLE, dpId, macAddress, elanTag);
return null;
}
- public static String getElanMacDPNKey(long elanTag, String macAddress, BigInteger dpnId) {
- String elanMacDmacDpnKey = "MAC-" + macAddress + " ELAN_TAG-" + elanTag + "DPN_ID-" + dpnId;
- return elanMacDmacDpnKey.intern();
- }
-
- public static String getElanMacKey(long elanTag, String macAddress) {
- String elanMacKey = "MAC-" + macAddress + " ELAN_TAG-" + elanTag;
- return elanMacKey.intern();
+ public static Acquired lockElanMacDPN(long elanTag, String macAddress, BigInteger dpnId) {
+ return ELAN_LOCKS.acquire(new ElanLockName(elanTag, macAddress, dpnId));
}
public static List<ListenableFuture<Void>>
int lportTag) {
LOG.info("Removing the ARP responder flow on DPN {} of Interface {} with IP {}", dpnId, ingressInterfaceName,
ipAddress);
- ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(Datastore.CONFIGURATION,
+ LoggingFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(Datastore.CONFIGURATION,
tx -> mdsalManager.removeFlow(tx, dpnId, ArpResponderUtil.getFlowId(lportTag, ipAddress),
NwConstants.ARP_RESPONDER_TABLE)), LOG, "Error removing ARP responder flow");
}