The WAITING_JOB_LIST functionality was moved to ElanInstanceCache.
Change-Id: I00910628748e59faf34bb19ccfb251f753b961ab
Signed-off-by: Tom Pantelis <tompantelis@gmail.com>
package org.opendaylight.netvirt.elan.cache;
import com.google.common.base.Optional;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
public class ElanInstanceCache extends DataObjectCache<ElanInstance> {
private static final Logger LOG = LoggerFactory.getLogger(ElanInstanceCache.class);
+ private final Map<InstanceIdentifier<ElanInstance>, Collection<Runnable>> waitingJobs = new HashMap<>();
+
@Inject
public ElanInstanceCache(DataBroker dataBroker, CacheProvider cacheProvider) {
super(ElanInstance.class, dataBroker, LogicalDatastoreType.CONFIGURATION,
return Optional.absent();
}
}
+
+ public Optional<ElanInstance> get(String elanInstanceName, Runnable runAfterElanIsAvailable) {
+ Optional<ElanInstance> possibleInstance = get(elanInstanceName);
+ if (!possibleInstance.isPresent()) {
+ synchronized (waitingJobs) {
+ possibleInstance = get(elanInstanceName);
+ if (!possibleInstance.isPresent()) {
+ waitingJobs.computeIfAbsent(ElanHelper.getElanInstanceConfigurationDataPath(elanInstanceName),
+ key -> new ArrayList<>()).add(runAfterElanIsAvailable);
+ }
+ }
+ }
+
+ return possibleInstance;
+ }
+
+ @Override
+ protected void added(InstanceIdentifier<ElanInstance> path, ElanInstance elanInstance) {
+ Collection<Runnable> jobsToRun;
+ synchronized (waitingJobs) {
+ jobsToRun = waitingJobs.remove(path);
+ }
+
+ if (jobsToRun != null) {
+ jobsToRun.forEach(Runnable::run);
+ }
+ }
}
*/
package org.opendaylight.netvirt.elan.l2gw.listeners;
-import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.slf4j.LoggerFactory;
@Singleton
-public class ElanInstanceListener extends AsyncClusteredDataTreeChangeListenerBase<ElanInstance,
- ElanInstanceListener> {
+public class ElanInstanceListener extends AsyncClusteredDataTreeChangeListenerBase<ElanInstance, ElanInstanceListener> {
private static final Logger LOG = LoggerFactory.getLogger(ElanInstanceListener.class);
private final DataBroker broker;
private final ElanClusterUtils elanClusterUtils;
- private static final Map<String, List<Runnable>> WAITING_JOB_LIST = new ConcurrentHashMap<>();
@Inject
public ElanInstanceListener(final DataBroker db, final ElanClusterUtils elanClusterUtils) {
@Override
protected void add(InstanceIdentifier<ElanInstance> identifier, ElanInstance add) {
- List<Runnable> runnables = WAITING_JOB_LIST.get(add.getElanInstanceName());
- if (runnables != null) {
- runnables.forEach(Runnable::run);
- }
- }
-
- public static void runJobAfterElanIsAvailable(String elanName, Runnable runnable) {
- WAITING_JOB_LIST.computeIfAbsent(elanName, (name) -> new ArrayList<>());
- WAITING_JOB_LIST.get(elanName).add(runnable);
}
@Override
import org.opendaylight.netvirt.elan.l2gw.ha.listeners.HAOpClusteredListener;
import org.opendaylight.netvirt.elan.l2gw.jobs.AssociateHwvtepToElanJob;
import org.opendaylight.netvirt.elan.l2gw.jobs.DisAssociateHwvtepFromElanJob;
-import org.opendaylight.netvirt.elan.l2gw.listeners.ElanInstanceListener;
import org.opendaylight.netvirt.elan.l2gw.listeners.HwvtepLogicalSwitchListener;
import org.opendaylight.netvirt.elan.l2gw.listeners.LocalUcastMacListener;
import org.opendaylight.netvirt.elan.utils.ElanClusterUtils;
LOG.info("Adding L2gateway Connection with ID: {}", input.getKey().getUuid());
Uuid networkUuid = input.getNetworkId();
- ElanInstance elanInstance = elanInstanceManager.getElanInstanceByName(networkUuid.getValue());
- //Taking cluster reboot scenario , if Elan instance is not available when l2GatewayConnection add events
- //comes we need to wait for elaninstance to resolve. Hence updating the map with the runnable .
- //When elanInstance add comes , it look in to the map and run the associated runnable associated with it.
+
+ // Taking cluster reboot scenario , if Elan instance is not available when l2GatewayConnection add events
+ // comes we need to wait for elaninstance to resolve. Hence updating the map with the runnable .
+ // When elanInstance add comes , it look in to the map and run the associated runnable associated with it.
+ ElanInstance elanInstance = elanInstanceCache.get(networkUuid.getValue(),
+ () -> addL2GatewayConnection(input, l2GwDeviceName)).orNull();
if (elanInstance == null) {
- LOG.info("Waiting for elan {}", networkUuid.getValue());
- ElanInstanceListener.runJobAfterElanIsAvailable(networkUuid.getValue(),
- () -> addL2GatewayConnection(input, l2GwDeviceName));
return;
}
+
if (!isVxlanNetworkOrVxlanSegment(elanInstance)) {
LOG.error("Neutron network with id {} is not VxlanNetwork", networkUuid.getValue());
} else {