GENIUS-254 GENIUS-119 GRE and L2GW tunnel missing 45/83045/6
authorNidhi <nidhi.adhvaryu@ericsson.com>
Mon, 15 Jul 2019 11:32:37 +0000 (17:02 +0530)
committerFaseela K <faseela.k@ericsson.com>
Fri, 23 Aug 2019 09:54:44 +0000 (09:54 +0000)
There is a race condition between creation of tun port and
bridge ref, port not created. 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 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: I7f6c0583d90d5aa91e0ae063123680bdece08998
Signed-off-by: Nidhi <nidhi.adhvaryu@ericsson.com>
interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/renderer/ovs/confighelpers/OvsInterfaceConfigAddHelper.java

index f5c5c51ba0b7cd96e23b0a301964bffdff56b4b7..62bf6034e2e4743538049f5bc1ec70a46158b46f 100644 (file)
@@ -16,6 +16,7 @@ import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.MoreExecutors;
 import java.math.BigInteger;
+import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -25,6 +26,8 @@ import org.apache.aries.blueprint.annotation.service.Reference;
 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.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
 import org.opendaylight.genius.infra.Datastore.Configuration;
 import org.opendaylight.genius.infra.Datastore.Operational;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
@@ -41,8 +44,10 @@ import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeRefInfo;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.BridgeEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntryKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
@@ -68,6 +73,7 @@ public final class OvsInterfaceConfigAddHelper {
     private final OvsInterfaceStateAddHelper ovsInterfaceStateAddHelper;
     private final InterfaceMetaUtils interfaceMetaUtils;
     private final SouthboundUtils southboundUtils;
+    private final DataTreeEventCallbackRegistrar eventCallbacks;
 
     @Inject
     public OvsInterfaceConfigAddHelper(@Reference DataBroker dataBroker,
@@ -77,7 +83,8 @@ public final class OvsInterfaceConfigAddHelper {
                                        InterfaceManagerCommonUtils interfaceManagerCommonUtils,
                                        OvsInterfaceStateAddHelper ovsInterfaceStateAddHelper,
                                        InterfaceMetaUtils interfaceMetaUtils,
-                                       SouthboundUtils southboundUtils) {
+                                       SouthboundUtils southboundUtils,
+                                       DataTreeEventCallbackRegistrar eventCallbacks) {
         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
         this.alivenessMonitorUtils = alivenessMonitorUtils;
         this.mdsalApiManager = mdsalApiManager;
@@ -86,6 +93,7 @@ public final class OvsInterfaceConfigAddHelper {
         this.ovsInterfaceStateAddHelper = ovsInterfaceStateAddHelper;
         this.interfaceMetaUtils = interfaceMetaUtils;
         this.southboundUtils = southboundUtils;
+        this.eventCallbacks = eventCallbacks;
     }
 
     public List<ListenableFuture<Void>> addConfiguration(ParentRefs parentRefs, Interface interfaceNew) {
@@ -188,36 +196,21 @@ public final class OvsInterfaceConfigAddHelper {
             if (createTunnelPort) {
                 southboundUtils.addPortToBridge(bridgeIid, interfaceNew, tunnelName);
             }
-
-            // if TEP is already configured on switch, start LLDP monitoring and
-            // program tunnel ingress flow
-            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
-                .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
-                    .getInterfaceState(interfaceNew.getName());
-            if (ifState != null) {
-                NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(ifState);
-                if (ncId != null) {
-                    long portNo = IfmUtil.getPortNumberFromNodeConnectorId(ncId);
-                    interfaceManagerCommonUtils.addTunnelIngressFlow(confTx, ifTunnel, dpId, portNo,
-                            interfaceNew.getName(), ifState.getIfIndex());
-                    ListenableFuture<Void> future =
-                            FlowBasedServicesUtils.bindDefaultEgressDispatcherService(txRunner, interfaceNew,
-                                    Long.toString(portNo), interfaceNew.getName(), ifState.getIfIndex());
-                    futures.add(future);
-                    Futures.addCallback(future, new FutureCallback<Void>() {
-                        @Override
-                        public void onSuccess(@Nullable Void result) {
-                            // start LLDP monitoring for the tunnel interface
-                            alivenessMonitorUtils.startLLDPMonitoring(ifTunnel, interfaceNew.getName());
-                        }
-
-                        @Override
-                        public void onFailure(@NonNull Throwable throwable) {
-                            LOG.error("Unable to add tunnel monitoring", throwable);
-                        }
-                    }, MoreExecutors.directExecutor());
-                }
-            }
+            setupTunnelFlowsAndMonitoring(interfaceNew, confTx, ifTunnel, dpId, futures);
+        } else if (createTunnelPort) {
+            LOG.debug("Bridge not found. Registering eventcallback for dpid {}", dpId);
+            InstanceIdentifier<BridgeRefEntry> bridgeRefEntryInstanceIdentifier =
+                    InstanceIdentifier.builder(BridgeRefInfo.class)
+                            .child(BridgeRefEntry.class, new BridgeRefEntryKey(dpId)).build();
+            eventCallbacks.onAdd(LogicalDatastoreType.OPERATIONAL, bridgeRefEntryInstanceIdentifier,
+                (bridgeRefEntryOnCallback) -> {
+                    LOG.debug("eventcallback triggered on bridge reference entry addition {}", dpId);
+                    southboundUtils.addPortToBridge(bridgeRefEntryOnCallback.getBridgeReference().getValue(),
+                        interfaceNew, tunnelName);
+                    return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
+                }, Duration.ofMillis(5000), (id) -> {
+                    LOG.info("event call back timed-out for bridge creation, {}", dpId);
+                });
         }
     }
 
@@ -249,4 +242,38 @@ public final class OvsInterfaceConfigAddHelper {
                                                                   ifaceName, ifState.getIfIndex(), groupId);
     }
 
+    private void setupTunnelFlowsAndMonitoring(Interface interfaceNew, TypedWriteTransaction<Configuration> confTx,
+                                               IfTunnel ifTunnel, BigInteger dpId,
+                                               List<ListenableFuture<Void>> futures) {
+        // if TEP is already configured on switch, start LLDP monitoring and
+        // program tunnel ingress flow
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+                .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
+                .getInterfaceState(interfaceNew.getName());
+        if (ifState != null) {
+            NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(ifState);
+            if (ncId != null) {
+                long portNo = IfmUtil.getPortNumberFromNodeConnectorId(ncId);
+                interfaceManagerCommonUtils.addTunnelIngressFlow(confTx, ifTunnel, dpId, portNo,
+                        interfaceNew.getName(), ifState.getIfIndex());
+                ListenableFuture<Void> future =
+                        FlowBasedServicesUtils.bindDefaultEgressDispatcherService(txRunner, interfaceNew,
+                                Long.toString(portNo), interfaceNew.getName(), ifState.getIfIndex());
+                futures.add(future);
+                Futures.addCallback(future, new FutureCallback<Void>() {
+                    @Override
+                    public void onSuccess(@Nullable Void result) {
+                        // start LLDP monitoring for the tunnel interface
+                        alivenessMonitorUtils.startLLDPMonitoring(ifTunnel, interfaceNew.getName());
+                    }
+
+                    @Override
+                    public void onFailure(@NonNull Throwable throwable) {
+                        LOG.error("Unable to add tunnel monitoring", throwable);
+                    }
+                }, MoreExecutors.directExecutor());
+            }
+        }
+    }
+
 }