Tunnel mesh was not fully created. 80/81980/3
authorNidhi <nidhi.adhvaryu@ericsson.com>
Fri, 10 May 2019 08:46:42 +0000 (14:16 +0530)
committerHema Gopalakrishnan <hema.gopalkrishnan@ericsson.com>
Thu, 13 Jun 2019 04:36:39 +0000 (04:36 +0000)
There is a timing issue between SB and NB event while
creating bridge. When we are trying to add bridge to
ovsdb from SB, NB is trying to add port for same bridge.
during which NB will check DS/cache for bridge entry,
which will be empty as SB is trying to add it in ovsdb
at the same time. So we are adding eventcallback to
synchronize both events.

Change-Id: I7c33f41591de27972742df14ae913daae7f6889f
Signed-off-by: Nidhi <nidhi.adhvaryu@ericsson.com>
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/confighelpers/ItmInternalTunnelAddWorker.java
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/listeners/TransportZoneListener.java
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/recovery/impl/ItmTepInstanceRecoveryHandler.java
itm/itm-impl/src/test/java/org/opendaylight/genius/itm/impl/ItmInternalTunnelAddTest.java

index ed888054936903d5357104410498c361579f3752..a43cf405159d94d84cfc0552949b1bfc9bff0358 100644 (file)
@@ -14,6 +14,7 @@ import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.ListenableFuture;
 import java.math.BigInteger;
+import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -22,7 +23,9 @@ import java.util.Objects;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 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.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
 import org.opendaylight.genius.infra.Datastore.Configuration;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
@@ -50,7 +53,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptions;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.OvsBridgeRefInfo;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.ovs.bridge.ref.info.OvsBridgeRefEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.ovs.bridge.ref.info.OvsBridgeRefEntryKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpointsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnTepsState;
@@ -89,13 +94,15 @@ public final class ItmInternalTunnelAddWorker {
     private final IInterfaceManager interfaceManager;
     private final OvsBridgeRefEntryCache ovsBridgeRefEntryCache;
     private final OfEndPointCache ofEndPointCache;
+    private final DataTreeEventCallbackRegistrar eventCallbacks;
 
     public ItmInternalTunnelAddWorker(DataBroker dataBroker, JobCoordinator jobCoordinator,
                                       TunnelMonitoringConfig tunnelMonitoringConfig, ItmConfig itmCfg,
                                       DirectTunnelUtils directTunnelUtil,
                                       IInterfaceManager interfaceManager,
                                       OvsBridgeRefEntryCache ovsBridgeRefEntryCache,
-                                      OfEndPointCache ofEndPointCache) {
+                                      OfEndPointCache ofEndPointCache,
+                                      DataTreeEventCallbackRegistrar eventCallbacks) {
         this.dataBroker = dataBroker;
         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
         this.jobCoordinator = jobCoordinator;
@@ -104,6 +111,7 @@ public final class ItmInternalTunnelAddWorker {
         this.interfaceManager = interfaceManager;
         this.ovsBridgeRefEntryCache = ovsBridgeRefEntryCache;
         this.ofEndPointCache = ofEndPointCache;
+        this.eventCallbacks = eventCallbacks;
 
         isTunnelMonitoringEnabled = tunnelMonitoringConfig.isTunnelMonitoringEnabled();
         monitorProtocol = tunnelMonitoringConfig.getMonitorProtocol();
@@ -410,6 +418,27 @@ public final class ItmInternalTunnelAddWorker {
                                 .getOvsBridgeReference().getValue();
                 LOG.debug("adding port to the bridge:{} tunnelName: {}", bridgeIid, tunnelName);
                 addPortToBridge(bridgeIid, iface, tunnelName);
+            } else {
+                LOG.debug("Bridge not found. Registering Eventcallback for dpid {}", dpId);
+
+                InstanceIdentifier<OvsBridgeRefEntry> bridgeRefEntryFromDS =
+                        InstanceIdentifier.builder(OvsBridgeRefInfo.class)
+                                .child(OvsBridgeRefEntry.class, new OvsBridgeRefEntryKey(dpId)).build();
+
+                eventCallbacks.onAdd(LogicalDatastoreType.OPERATIONAL, bridgeRefEntryFromDS, (refEntryIid) -> {
+                    addPortToBridgeOnCallback(iface, iface.getName(), refEntryIid);
+                    return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
+                }, Duration.ofMillis(5000), (id) -> {
+                        try {
+                            Optional<OvsBridgeRefEntry> ovsBridgeRefEntryOnCallback = ovsBridgeRefEntryCache.get(dpId);
+                            InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIidOnCallback =
+                                    (InstanceIdentifier<OvsdbBridgeAugmentation>) ovsBridgeRefEntryOnCallback.get()
+                                            .getOvsBridgeReference().getValue();
+                            addPortToBridge(bridgeIidOnCallback, iface, iface.getName());
+                        }   catch (ReadFailedException e) {
+                            LOG.error("Bridge not found in DS/cache for dpId {}", dpId);
+                        }
+                    });
             }
         }
     }
@@ -427,4 +456,10 @@ public final class ItmInternalTunnelAddWorker {
         }
         return (ofEndPointCache.get(dpId) == null);
     }
+
+    private void addPortToBridgeOnCallback(Interface iface, String portName, OvsBridgeRefEntry bridgeRefEntry) {
+        InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid =
+                (InstanceIdentifier<OvsdbBridgeAugmentation>) bridgeRefEntry.getOvsBridgeReference().getValue();
+        addPortToBridge(bridgeIid, iface, portName);
+    }
 }
index 5d1023d94dd08622a20e31a023ae0c18d42ba6ee..8b2cac7fcf84531f800175488edbb29b79741df3 100644 (file)
@@ -23,6 +23,7 @@ import javax.inject.Singleton;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
 import org.opendaylight.genius.infra.Datastore;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
@@ -98,6 +99,7 @@ public class TransportZoneListener extends AbstractSyncDataTreeChangeListener<Tr
     private final ItmExternalTunnelAddWorker externalTunnelAddWorker;
     private final DPNTEPsInfoCache dpnTEPsInfoCache;
     private final ManagedNewTransactionRunner txRunner;
+    private final DataTreeEventCallbackRegistrar eventCallbacks;
 
     @Inject
     public TransportZoneListener(final DataBroker dataBroker,
@@ -111,7 +113,8 @@ public class TransportZoneListener extends AbstractSyncDataTreeChangeListener<Tr
                                  final OvsBridgeRefEntryCache ovsBridgeRefEntryCache,
                                  final IInterfaceManager interfaceManager,
                                  final OfEndPointCache ofEndPointCache,
-                                 final ServiceRecoveryRegistry serviceRecoveryRegistry) {
+                                 final ServiceRecoveryRegistry serviceRecoveryRegistry,
+                                 final DataTreeEventCallbackRegistrar eventCallbacks) {
         super(dataBroker, LogicalDatastoreType.CONFIGURATION,
               InstanceIdentifier.create(TransportZones.class).child(TransportZone.class));
         this.dataBroker = dataBroker;
@@ -120,13 +123,14 @@ public class TransportZoneListener extends AbstractSyncDataTreeChangeListener<Tr
         this.itmConfig = itmConfig;
         this.dpnTEPsInfoCache = dpnTEPsInfoCache;
         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
+        this.eventCallbacks = eventCallbacks;
         initializeTZNode();
         this.itmInternalTunnelDeleteWorker = new ItmInternalTunnelDeleteWorker(dataBroker, jobCoordinator,
                 tunnelMonitoringConfig, interfaceManager, dpnTepStateCache, ovsBridgeEntryCache,
                 ovsBridgeRefEntryCache, tunnelStateCache, directTunnelUtils);
         this.itmInternalTunnelAddWorker = new ItmInternalTunnelAddWorker(dataBroker, jobCoordinator,
                 tunnelMonitoringConfig, itmConfig, directTunnelUtils, interfaceManager,
-                ovsBridgeRefEntryCache, ofEndPointCache);
+                ovsBridgeRefEntryCache, ofEndPointCache, eventCallbacks);
         this.externalTunnelAddWorker = new ItmExternalTunnelAddWorker(itmConfig, dpnTEPsInfoCache);
         serviceRecoveryRegistry.addRecoverableListener(ItmServiceRecoveryHandler.getServiceRegistryKey(), this);
     }
index 9ed83d0511e1bca18d96a152baf307597bfce38e..3cfbad2874becf47de7c01f6eabd04a6a15f66cc 100644 (file)
@@ -98,7 +98,7 @@ public class ItmTepInstanceRecoveryHandler implements ServiceRecoveryInterface {
         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
         this.itmInternalTunnelAddWorker = new ItmInternalTunnelAddWorker(dataBroker, jobCoordinator,
                 tunnelMonitoringConfig, itmConfig, directTunnelUtils, interfaceManager,
-                ovsBridgeRefEntryCache, ofEndPointCache);
+                ovsBridgeRefEntryCache, ofEndPointCache, eventCallbacks);
         this.itmExternalTunnelAddWorker = new ItmExternalTunnelAddWorker(itmConfig,
                 dpntePsInfoCache);
         this.itmInternalTunnelDeleteWorker = new ItmInternalTunnelDeleteWorker(dataBroker, jobCoordinator,
index 5dc9c1bc7ca21fb6dcfc4a88a58bb8b9465b6639..ad43e89d566b1fc3e4e1553f9b2d9148f5cd4aaa 100644 (file)
@@ -27,6 +27,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.itm.cache.OfEndPointCache;
 import org.opendaylight.genius.itm.cache.OvsBridgeRefEntryCache;
@@ -162,6 +163,7 @@ public class ItmInternalTunnelAddTest {
     @Mock EntityOwnershipUtils entityOwnershipUtils;
     ItmInternalTunnelAddWorker itmInternalTunnelAddWorker;
     DirectTunnelUtils directTunnelUtils;
+    DataTreeEventCallbackRegistrar eventCallbacks;
 
     Optional<TunnelMonitorParams> tunnelMonitorParamsOptional;
     Optional<TunnelMonitorInterval> tunnelMonitorIntervalOptional;
@@ -193,7 +195,7 @@ public class ItmInternalTunnelAddTest {
                 new TunnelMonitoringConfig(dataBroker, new GuavaCacheProvider(new CacheManagersRegistryImpl())),
                 itmConfig, directTunnelUtils, interfaceManager,
                 new OvsBridgeRefEntryCache(dataBroker, new GuavaCacheProvider(new CacheManagersRegistryImpl())),
-                new OfEndPointCache());
+                new OfEndPointCache(), eventCallbacks);
     }
 
     @After