import java.util.Collection;
import java.util.Collections;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
Set<DpnInterfaces> dpns = elanInstanceToDpnsCache.get(elanInstanceName);
return dpns != null ? Collections.unmodifiableCollection(dpns) : Collections.emptyList();
}
+
+ @NonNull
+ public Map<String, Set<DpnInterfaces>> getElanDpns() {
+ return elanInstanceToDpnsCache;
+ }
}
import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
import org.opendaylight.netvirt.elan.cache.ElanInstanceCache;
import org.opendaylight.netvirt.elan.cache.ElanInstanceDpnsCache;
+import org.opendaylight.netvirt.elan.l2gw.jobs.BcGroupUpdateJob;
import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayMulticastUtils;
import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayUtils;
+import org.opendaylight.netvirt.elan.l2gw.utils.ElanRefUtil;
import org.opendaylight.netvirt.elan.utils.ElanClusterUtils;
import org.opendaylight.netvirt.elanmanager.utils.ElanL2GwCacheUtils;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces;
private final JobCoordinator jobCoordinator;
private final ElanInstanceCache elanInstanceCache;
private final ElanInstanceDpnsCache elanInstanceDpnsCache;
+ private final ElanRefUtil elanRefUtil;
@Inject
public ElanDpnInterfaceClusteredListener(DataBroker broker, EntityOwnershipUtils entityOwnershipUtils,
ElanClusterUtils elanClusterUtils, JobCoordinator jobCoordinator,
ElanL2GatewayMulticastUtils elanL2GatewayMulticastUtils,
ElanInstanceCache elanInstanceCache,
- ElanInstanceDpnsCache elanInstanceDpnsCache) {
+ ElanInstanceDpnsCache elanInstanceDpnsCache,
+ ElanRefUtil elanRefUtil) {
this.broker = broker;
this.entityOwnershipUtils = entityOwnershipUtils;
this.elanL2GatewayUtils = elanL2GatewayUtils;
this.jobCoordinator = jobCoordinator;
this.elanInstanceCache = elanInstanceCache;
this.elanInstanceDpnsCache = elanInstanceDpnsCache;
+ this.elanRefUtil = elanRefUtil;
}
@PostConstruct
// updating remote mcast mac on l2gw devices
elanL2GatewayMulticastUtils.updateRemoteMcastMacOnElanL2GwDevices(elanName);
+ BcGroupUpdateJob.updateAllBcGroups(elanName, elanRefUtil, elanL2GatewayMulticastUtils, broker);
}
} finally {
elanInstanceDpnsCache.remove(getElanName(identifier), dpnInterfaces);
List<String> interfaces = dpnInterfaces.getInterfaces();
if (interfaces != null && !interfaces.isEmpty()) {
LOG.debug("dpninterfaces update fired new size {}", interfaces.size());
- elanInstanceDpnsCache.remove(getElanName(identifier), dpnInterfaces);
+ elanInstanceDpnsCache.remove(getElanName(identifier), original);
+ elanInstanceDpnsCache.add(getElanName(identifier), dpnInterfaces);
LOG.debug("dpninterfaces last dpn interface on this elan {} ", dpnInterfaces.key());
// this is the last dpn interface on this elan
handleUpdate(identifier, dpnInterfaces);
@Override
protected void add(InstanceIdentifier<DpnInterfaces> identifier, final DpnInterfaces dpnInterfaces) {
final String elanName = getElanName(identifier);
-
jobCoordinator.enqueueJob(elanName + ":l2gw", () -> {
elanInstanceDpnsCache.add(getElanName(identifier), dpnInterfaces);
if (entityOwnershipUtils.isEntityOwner(HwvtepSouthboundConstants.ELAN_ENTITY_TYPE,
HwvtepSouthboundConstants.ELAN_ENTITY_NAME)) {
ElanInstance elanInstance = elanInstanceCache.get(elanName).orNull();
if (elanInstance != null) {
+ BcGroupUpdateJob.updateAllBcGroups(elanName, elanRefUtil, elanL2GatewayMulticastUtils, broker);
elanL2GatewayUtils.installElanL2gwDevicesLocalMacsInDpn(
dpnInterfaces.getDpId(), elanInstance, dpnInterfaces.getInterfaces().get(0));
*/
package org.opendaylight.netvirt.elan.internal;
-import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
-
-import java.util.Collections;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.genius.datastoreutils.AsyncClusteredDataTreeChangeListenerBase;
import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
import org.opendaylight.netvirt.elan.cache.ElanInstanceCache;
+import org.opendaylight.netvirt.elan.l2gw.jobs.BcGroupUpdateJob;
import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayMulticastUtils;
-import org.opendaylight.netvirt.elan.utils.ElanConstants;
+import org.opendaylight.netvirt.elan.l2gw.utils.ElanRefUtil;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.elan.instance.ExternalTeps;
import org.slf4j.LoggerFactory;
@Singleton
-public class ElanExtnTepListener extends AsyncDataTreeChangeListenerBase<ExternalTeps, ElanExtnTepListener> {
+public class ElanExtnTepListener extends AsyncClusteredDataTreeChangeListenerBase<ExternalTeps, ElanExtnTepListener> {
private static final Logger LOG = LoggerFactory.getLogger(ElanExtnTepListener.class);
private final ElanL2GatewayMulticastUtils elanL2GatewayMulticastUtils;
private final JobCoordinator jobCoordinator;
private final ElanInstanceCache elanInstanceCache;
+ private final ElanRefUtil elanRefUtil;
@Inject
public ElanExtnTepListener(DataBroker dataBroker, ElanL2GatewayMulticastUtils elanL2GatewayMulticastUtils,
- JobCoordinator jobCoordinator, ElanInstanceCache elanInstanceCache) {
+ JobCoordinator jobCoordinator, ElanInstanceCache elanInstanceCache, ElanRefUtil elanRefUtil) {
super(ExternalTeps.class, ElanExtnTepListener.class);
this.broker = dataBroker;
this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.elanL2GatewayMulticastUtils = elanL2GatewayMulticastUtils;
this.jobCoordinator = jobCoordinator;
this.elanInstanceCache = elanInstanceCache;
+ this.elanRefUtil = elanRefUtil;
}
- @Override
@PostConstruct
public void init() {
registerListener(LogicalDatastoreType.OPERATIONAL, broker);
@Override
protected void add(InstanceIdentifier<ExternalTeps> instanceIdentifier, ExternalTeps tep) {
LOG.trace("ExternalTeps add received {}", instanceIdentifier);
- updateElanRemoteBroadCastGroup(instanceIdentifier);
+ updateBcGroupOfElan(instanceIdentifier, tep);
}
@Override
@Override
protected void remove(InstanceIdentifier<ExternalTeps> instanceIdentifier, ExternalTeps tep) {
LOG.trace("ExternalTeps remove received {}", instanceIdentifier);
- updateElanRemoteBroadCastGroup(instanceIdentifier);
+ updateBcGroupOfElan(instanceIdentifier, tep);
}
- @SuppressWarnings("checkstyle:IllegalCatch")
- private void updateElanRemoteBroadCastGroup(final InstanceIdentifier<ExternalTeps> iid) {
- String elanName = iid.firstKeyOf(ElanInstance.class).getElanInstanceName();
- ElanInstance elanInfo = elanInstanceCache.get(elanName).orNull();
- if (elanInfo == null) {
- return;
- }
-
- jobCoordinator.enqueueJob(elanName,
- () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
- confTx -> elanL2GatewayMulticastUtils.updateRemoteBroadcastGroupForAllElanDpns(elanInfo, confTx))),
- ElanConstants.JOB_MAX_RETRIES);
+ protected void updateBcGroupOfElan(InstanceIdentifier<ExternalTeps> instanceIdentifier, ExternalTeps tep) {
+ String elanName = instanceIdentifier.firstKeyOf(ElanInstance.class).getElanInstanceName();
+ BcGroupUpdateJob.updateAllBcGroups(elanName, elanRefUtil, elanL2GatewayMulticastUtils, broker);
}
@Override
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
+import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Singleton;
private final Scheduler scheduler;
private final Map<InstanceIdentifier<Group>, Group> groupsById = new ConcurrentHashMap<>();
private final Map<InstanceIdentifier<Group>, Collection<Runnable>> waitingJobs = new ConcurrentHashMap<>();
- private volatile boolean initialized = false;
@Inject
public ElanGroupCache(final DataBroker dataBroker, final Scheduler scheduler) {
this.scheduler = scheduler;
}
+ @PostConstruct
public synchronized void init() {
- if (!initialized) {
- initialized = true;
- this.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
- }
+ this.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
}
@Override
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
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.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
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;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInstance;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface.EtreeInterfaceType;
private final JobCoordinator jobCoordinator;
private final ElanInstanceCache elanInstanceCache;
private final ElanInterfaceCache elanInterfaceCache;
+ private final ElanGroupCache elanGroupCache;
private final Map<String, ConcurrentLinkedQueue<ElanInterface>>
unProcessedElanInterfaces = new ConcurrentHashMap<>();
final ElanInstanceCache elanInstanceCache,
final ElanInterfaceCache elanInterfaceCache,
final ElanServiceRecoveryHandler elanServiceRecoveryHandler,
+ ElanGroupCache elanGroupCache,
final ServiceRecoveryRegistry serviceRecoveryRegistry) {
super(ElanInterface.class, ElanInterfaceManager.class);
this.broker = dataBroker;
this.elanL2GatewayMulticastUtils = elanL2GatewayMulticastUtils;
this.elanInstanceCache = elanInstanceCache;
this.elanInterfaceCache = elanInterfaceCache;
+ this.elanGroupCache = elanGroupCache;
serviceRecoveryRegistry.addRecoverableListener(elanServiceRecoveryHandler.buildServiceRegistryKey(), this);
}
private static class RemoveElanInterfaceHolder {
boolean isLastElanInterface = false;
- boolean isLastInterfaceOnDpn = false;
BigInteger dpId = null;
}
}
unsetExternalTunnelTable(holder.dpId, elanInfo, flowTx);
}
- holder.isLastInterfaceOnDpn = true;
} else {
setupLocalBroadcastGroups(elanInfo, dpnInterfaces, interfaceInfo, flowTx);
}
}));
futures.forEach(ElanUtils::waitForTransactionToComplete);
- if (holder.isLastInterfaceOnDpn && holder.dpId != null && isVxlanNetworkOrVxlanSegment(elanInfo)) {
- futures.add(
- ElanUtils.waitForTransactionToComplete(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
- confTx -> setElanAndEtreeBCGrouponOtherDpns(elanInfo, holder.dpId, confTx))));
- }
InterfaceRemoveWorkerOnElanInterface removeInterfaceWorker = new InterfaceRemoveWorkerOnElanInterface(
interfaceName, elanInfo, interfaceInfo, this, holder.isLastElanInterface);
jobCoordinator.enqueueJob(ElanUtils.getElanInterfaceJobKey(interfaceName), removeInterfaceWorker,
handleExternalInterfaceEvent(elanInstance, holder.dpnInterfaces, holder.dpId);
}
}
-
- if (holder.isFirstInterfaceInDpn && isVxlanNetworkOrVxlanSegment(elanInstance)) {
- //update the remote-DPNs remoteBC group entry with Tunnels
- LOG.trace("update remote bc group for elan {} on other DPNs for newly added dpn {}", elanInstance,
- holder.dpId);
- futures.add(
- ElanUtils.waitForTransactionToComplete(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
- confTx -> setElanAndEtreeBCGrouponOtherDpns(elanInstance, holder.dpId, confTx))));
+ if (holder.isFirstInterfaceInDpn) {
+ // ELAN's 1st ElanInterface added to this DPN
+ LOG.debug("Adding dpn into operational dpn list {}", holder.dpId);
+ futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operTx -> {
+ operTx.put(ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, holder.dpId),
+ holder.dpnInterfaces, CREATE_MISSING_PARENTS);
+ }));
+ } else {
+ LOG.debug("Updated dpn into operational dpn list {}", holder.dpId);
}
- String jobKey = ElanUtils.getElanInterfaceJobKey(interfaceName);
- InterfaceAddWorkerOnElanInterface addWorker = new InterfaceAddWorkerOnElanInterface(jobKey,
- elanInterface, interfaceInfo, elanInstance, holder.isFirstInterfaceInDpn, this);
- jobCoordinator.enqueueJob(jobKey, addWorker, ElanConstants.JOB_MAX_RETRIES);
+ scheduleElanInterfaceWorkerAfterRemoteBcGroup(elanInstance, interfaceInfo, holder.dpnInterfaces,
+ holder.isFirstInterfaceInDpn, elanInterface);
return futures;
}
setupLocalBroadcastGroups(elanInfo, dpnInterfaces, interfaceInfo, confTx);
if (isFirstInterfaceInDpn) {
LOG.trace("waitTimeForSyncInstall is {}", WAIT_TIME_FOR_SYNC_INSTALL);
- BigInteger dpId = interfaceInfo.getDpId();
- // RemoteBroadcast Group creation
- try {
- Thread.sleep(WAIT_TIME_FOR_SYNC_INSTALL);
- } catch (InterruptedException e1) {
- LOG.warn("Error while waiting for local BC group for ELAN {} to install", elanInfo);
- }
- elanL2GatewayMulticastUtils.setupElanBroadcastGroups(elanInfo, dpnInterfaces, dpId, confTx);
try {
Thread.sleep(WAIT_TIME_FOR_SYNC_INSTALL);
} catch (InterruptedException e1) {
}
}
+ public InstanceIdentifier<Group> getGroupIid(ElanInstance elanInfo, BigInteger dpnId) {
+ long remoteBcGroupId = ElanUtils.getElanRemoteBCGId(elanInfo.getElanTag());
+ return InstanceIdentifier.builder(Nodes.class)
+ .child(Node.class, new NodeKey(new org.opendaylight.yang.gen.v1.urn.opendaylight
+ .inventory.rev130819.NodeId("openflow:" + dpnId.toString())))
+ .augmentation(FlowCapableNode.class)
+ .child(Group.class, new GroupKey(new GroupId(remoteBcGroupId))).build();
+ }
+
+ public void scheduleElanInterfaceWorkerAfterRemoteBcGroup(ElanInstance elanInfo,
+ InterfaceInfo interfaceInfo,
+ DpnInterfaces dpnInterfaces,
+ boolean isFirstInterfaceInDpn,
+ ElanInterface elanInterface) {
+ if (!isOperational(interfaceInfo)) {
+ LOG.debug("Interface {} is not operational", elanInterface.getName());
+ return;
+ }
+ String elanInterfaceJobKey = ElanUtils.getElanInterfaceJobKey(interfaceInfo.getInterfaceName());
+ InterfaceAddWorkerOnElanInterface addWorker = new InterfaceAddWorkerOnElanInterface(elanInterfaceJobKey,
+ elanInterface, interfaceInfo, elanInfo, isFirstInterfaceInDpn, this);
+ InstanceIdentifier<Group> groupInstanceId = getGroupIid(elanInfo, dpnInterfaces.getDpId());
+ elanGroupCache.addJobToWaitList(groupInstanceId, () -> {
+ jobCoordinator.enqueueJob(elanInterfaceJobKey, addWorker, ElanConstants.JOB_MAX_RETRIES);
+ });
+ }
+
public void setupFilterEqualsTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
TypedWriteTransaction<Configuration> writeFlowGroupTx) {
int ifTag = interfaceInfo.getInterfaceTag();
mdsalManager.removeFlow(flowTx, interfaceInfo.getDpId(), flowEntity);
}
- private void setElanAndEtreeBCGrouponOtherDpns(ElanInstance elanInfo, BigInteger dpId,
- TypedWriteTransaction<Configuration> confTx) {
- int elanTag = elanInfo.getElanTag().intValue();
- long groupId = ElanUtils.getElanRemoteBCGId(elanTag);
- setBCGrouponOtherDpns(elanInfo, dpId, elanTag, groupId, confTx);
- EtreeInstance etreeInstance = elanInfo.augmentation(EtreeInstance.class);
- if (etreeInstance != null) {
- int etreeLeafTag = etreeInstance.getEtreeLeafTagVal().getValue().intValue();
- long etreeLeafGroupId = ElanUtils.getEtreeLeafRemoteBCGId(etreeLeafTag);
- setBCGrouponOtherDpns(elanInfo, dpId, etreeLeafTag, etreeLeafGroupId, confTx);
- }
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- private void setBCGrouponOtherDpns(ElanInstance elanInfo, BigInteger dpId, int elanTag, long groupId,
- TypedWriteTransaction<Configuration> confTx) {
- int bucketId = 0;
- ElanDpnInterfacesList elanDpns = elanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
- if (elanDpns != null) {
- List<DpnInterfaces> dpnInterfaces = elanDpns.nonnullDpnInterfaces();
- for (DpnInterfaces dpnInterface : dpnInterfaces) {
- List<Bucket> remoteListBucketInfo = new ArrayList<>();
- if (elanUtils.isDpnPresent(dpnInterface.getDpId()) && !Objects.equals(dpnInterface.getDpId(), dpId)
- && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
- List<Action> listAction = new ArrayList<>();
- int actionKey = 0;
- listAction.add(new ActionGroup(ElanUtils.getElanLocalBCGId(elanTag)).buildAction(++actionKey));
- remoteListBucketInfo.add(MDSALUtil.buildBucket(listAction, MDSALUtil.GROUP_WEIGHT, bucketId,
- MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
- bucketId++;
- for (DpnInterfaces otherFes : dpnInterfaces) {
- if (elanUtils.isDpnPresent(otherFes.getDpId()) && !Objects.equals(otherFes.getDpId(),
- dpnInterface.getDpId()) && otherFes.getInterfaces() != null
- && !otherFes.getInterfaces().isEmpty()) {
- try {
- List<Action> remoteListActionInfo = elanItmUtils.getInternalTunnelItmEgressAction(
- dpnInterface.getDpId(), otherFes.getDpId(),
- elanUtils.isOpenstackVniSemanticsEnforced()
- ? ElanUtils.getVxlanSegmentationId(elanInfo) : elanTag);
- if (!remoteListActionInfo.isEmpty()) {
- remoteListBucketInfo.add(MDSALUtil.buildBucket(remoteListActionInfo, MDSALUtil
- .GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
- bucketId++;
- }
- } catch (Exception ex) {
- LOG.error("setElanBCGrouponOtherDpns failed due to Exception caught; "
- + "Logical Group Interface not found between source Dpn - {}, "
- + "destination Dpn - {} ", dpnInterface.getDpId(), otherFes.getDpId(), ex);
- return;
- }
- }
- }
- List<Bucket> elanL2GwDevicesBuckets = elanL2GatewayMulticastUtils
- .getRemoteBCGroupBucketsOfElanL2GwDevices(elanInfo, dpnInterface.getDpId(), bucketId);
- remoteListBucketInfo.addAll(elanL2GwDevicesBuckets);
-
- if (remoteListBucketInfo.isEmpty()) {
- LOG.debug("No ITM is present on Dpn - {} ", dpnInterface.getDpId());
- continue;
- }
- Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll,
- MDSALUtil.buildBucketLists(remoteListBucketInfo));
- LOG.trace("Installing remote bc group {} on dpnId {}", group, dpnInterface.getDpId());
- mdsalManager.addGroup(confTx, dpnInterface.getDpId(), group);
- }
- }
- try {
- Thread.sleep(WAIT_TIME_FOR_SYNC_INSTALL);
- } catch (InterruptedException e1) {
- LOG.warn("Error while waiting for remote BC group on other DPNs for ELAN {} to install", elanInfo);
- }
- }
- }
-
private static List<MatchInfo> buildMatchesForVni(Long vni) {
List<MatchInfo> mkMatches = new ArrayList<>();
MatchInfo match = new MatchTunnelId(BigInteger.valueOf(vni));
interfaceNames.add(interfaceName);
DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId).setInterfaces(interfaceNames)
.withKey(new DpnInterfacesKey(dpId)).build();
- tx.put(ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId), dpnInterface,
- CREATE_MISSING_PARENTS);
- LOG.trace("Created operational dpn interfaces for elan: {} with interfaces: {}", elanInstanceName,
- interfaceNames);
return dpnInterface;
}
--- /dev/null
+/*
+ * Copyright (c) 2019 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.l2gw.jobs;
+
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.ListenableFuture;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayMulticastUtils;
+import org.opendaylight.netvirt.elan.l2gw.utils.ElanRefUtil;
+import org.opendaylight.netvirt.elan.utils.ElanUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BcGroupUpdateJob implements Callable<List<ListenableFuture<Void>>> {
+
+ private static final Logger LOG = LoggerFactory.getLogger("HwvtepEventLogger");
+
+ private final String elanName;
+ private final ElanL2GatewayMulticastUtils elanL2GatewayMulticastUtils;
+ private final ElanRefUtil elanRefUtil;
+ private final ManagedNewTransactionRunner txRunner;
+ protected String jobKey;
+
+ public BcGroupUpdateJob(String elanName,
+ ElanRefUtil elanRefUtil,
+ ElanL2GatewayMulticastUtils elanL2GatewayMulticastUtils,
+ DataBroker dataBroker) {
+ this.jobKey = ElanUtils.getBcGroupUpdateKey(elanName);
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
+ this.elanName = elanName;
+ this.elanRefUtil = elanRefUtil;
+ this.elanL2GatewayMulticastUtils = elanL2GatewayMulticastUtils;
+ }
+
+ public void submit() {
+ elanRefUtil.getElanClusterUtils().runOnlyInOwnerNode(this.jobKey, "BC Group Update Job", this);
+ }
+
+ @Override
+ public List<ListenableFuture<Void>> call() throws Exception {
+ Optional<ElanInstance> elanInstanceOptional = elanRefUtil.getElanInstanceCache().get(elanName);
+ if (elanInstanceOptional.isPresent()) {
+ return Lists.newArrayList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ confTx -> elanL2GatewayMulticastUtils.updateRemoteBroadcastGroupForAllElanDpns(
+ elanInstanceOptional.get(), confTx)));
+ }
+ return null;
+ }
+
+ public static void updateAllBcGroups(String elanName,
+ ElanRefUtil elanRefUtil,
+ ElanL2GatewayMulticastUtils elanL2GatewayMulticastUtils,
+ DataBroker dataBroker) {
+ new BcGroupUpdateJob(elanName, elanRefUtil, elanL2GatewayMulticastUtils, dataBroker).submit();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 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.l2gw.utils;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
+import org.opendaylight.netvirt.elan.cache.ElanInstanceCache;
+import org.opendaylight.netvirt.elan.cache.ElanInstanceDpnsCache;
+import org.opendaylight.netvirt.elan.cache.ElanInterfaceCache;
+import org.opendaylight.netvirt.elan.utils.ElanClusterUtils;
+import org.opendaylight.netvirt.elan.utils.Scheduler;
+
+@Singleton
+public class ElanRefUtil {
+
+ private final DataBroker dataBroker;
+ private final ElanClusterUtils elanClusterUtils;
+ private final Scheduler scheduler;
+ private final JobCoordinator jobCoordinator;
+ private final ElanInstanceCache elanInstanceCache;
+ private final ElanInstanceDpnsCache elanInstanceDpnsCache;
+ private final ElanInterfaceCache elanInterfaceCache;
+
+ @Inject
+ public ElanRefUtil(DataBroker dataBroker,
+ ElanClusterUtils elanClusterUtils,
+ ElanInstanceCache elanInstanceCache,
+ ElanInstanceDpnsCache elanInstanceDpnsCache,
+ ElanInterfaceCache elanInterfaceCache,
+ JobCoordinator jobCoordinator,
+ Scheduler scheduler) {
+ this.dataBroker = dataBroker;
+ this.elanClusterUtils = elanClusterUtils;
+ this.elanInstanceCache = elanInstanceCache;
+ this.elanInstanceDpnsCache = elanInstanceDpnsCache;
+ this.elanInterfaceCache = elanInterfaceCache;
+ this.jobCoordinator = jobCoordinator;
+ this.scheduler = scheduler;
+ }
+
+ public DataBroker getDataBroker() {
+ return dataBroker;
+ }
+
+ public ElanClusterUtils getElanClusterUtils() {
+ return elanClusterUtils;
+ }
+
+ public ElanInstanceCache getElanInstanceCache() {
+ return elanInstanceCache;
+ }
+
+ public ElanInstanceDpnsCache getElanInstanceDpnsCache() {
+ return elanInstanceDpnsCache;
+ }
+
+ public ElanInterfaceCache getElanInterfaceCache() {
+ return elanInterfaceCache;
+ }
+
+ public JobCoordinator getJobCoordinator() {
+ return jobCoordinator;
+ }
+
+ public Scheduler getScheduler() {
+ return scheduler;
+ }
+}
\ No newline at end of file
return InstanceIdentifier.builder(Nodes.class).child(Node.class, new NodeKey(new NodeId("openflow:" + dpnId)))
.augmentation(FlowCapableNode.class).child(Group.class, new GroupKey(new GroupId(groupId))).build();
}
+
+ public static String getBcGroupUpdateKey(String elanName) {
+ return "bc.group.update." + elanName;
+ }
}