make sure ovsdb connected node appears in operds 58/88958/4
authorChetan Arakere Gowdru <chetan.arakere@altencalsoftlabs.com>
Wed, 8 Apr 2020 05:37:56 +0000 (11:07 +0530)
committerChetan Arakere Gowdru <chetan.arakere@altencalsoftlabs.com>
Thu, 16 Apr 2020 05:28:14 +0000 (05:28 +0000)
if the conected node does not appear in oper ds
disconnect the node, upon reconnection it may succeed in getting into
operds.

Signed-off-by: Chetan Arakere Gowdru <chetan.arakere@altencalsoftlabs.com>
Change-Id: I1091e0a1a644141467e6d4bda5a058af60110a62
Signed-off-by: Chetan Arakere Gowdru <chetan.arakere@altencalsoftlabs.com>
library/impl/src/main/java/org/opendaylight/ovsdb/lib/impl/OvsdbConnectionService.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/OvsdbConnectionManager.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/OvsdbOperGlobalListener.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/SouthboundConstants.java

index cd76a00fb0e18695a75ba0d2a5435afa7e90bfe3..8d03975f95a520bce1811d5a074a50edf04fa08f 100644 (file)
@@ -407,19 +407,28 @@ public class OvsdbConnectionService implements AutoCloseable, OvsdbConnection {
             });
     }
 
+    @SuppressWarnings("checkstyle:IllegalCatch")
     private static void handleNewPassiveConnection(final OvsdbClient client) {
         ListenableFuture<List<String>> echoFuture = client.echo();
         LOG.debug("Send echo message to probe the OVSDB switch {}",client.getConnectionInfo());
         Futures.addCallback(echoFuture, new FutureCallback<List<String>>() {
             @Override
-            public void onSuccess(@Nullable final List<String> result) {
-                LOG.debug("Probe was successful to OVSDB switch {}",client.getConnectionInfo());
-                List<OvsdbClient> clientsFromSameNode = getPassiveClientsFromSameNode(client);
+            public void onSuccess(@Nullable List<String> result) {
+                LOG.info("Probe was successful to OVSDB switch {}",client.getConnectionInfo());
+                //List<OvsdbClient> clientsFromSameNode = getPassiveClientsFromSameNode(client);
+                try {
+                    getPassiveClientsFromSameNode(client);
+                } catch (Throwable throwable) {
+                    LOG.error("Failed to get passive clients from same node", throwable);
+                }
+                notifyListenerForPassiveConnection(client);
+                /*
                 if (clientsFromSameNode.size() == 0) {
                     notifyListenerForPassiveConnection(client);
                 } else {
                     STALE_PASSIVE_CONNECTION_SERVICE.handleNewPassiveConnection(client, clientsFromSameNode);
                 }
+                */
             }
 
             @Override
index b020a8bf3dd581b813f13dcb041fdb19e030b8db..82c0d026e94abbca99b22ba4c5314305c06b60bc 100644 (file)
@@ -119,7 +119,7 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
         }
         alreadyProcessedClients.put(externalClient, externalClient);
 
-        LOG.info("Library connected {} from {}:{} to {}:{}",
+        LOG.info("OvsdbConnectionManager connected {} from {}:{} to {}:{}",
                 externalClient.getConnectionInfo().getType(),
                 externalClient.getConnectionInfo().getRemoteAddress(),
                 externalClient.getConnectionInfo().getRemotePort(),
@@ -131,10 +131,14 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
                 OvsdbConnectionInstance client = connectedButCallBacksNotRegistered(externalClient);
                 // Register Cluster Ownership for ConnectionInfo
                 registerEntityForOwnership(client);
+                OvsdbOperGlobalListener.runAfterTimeoutIfNodeNotCreated(client.getInstanceIdentifier(), () -> {
+                    externalClient.disconnect();
+                    disconnected(externalClient);
+                });
             }
         } catch (InterruptedException | ExecutionException | TimeoutException e) {
-            LOG.warn("Unable to fetch Database list from device {}. Disconnecting from the device.",
-                    externalClient.getConnectionInfo().getRemoteAddress(), e);
+            LOG.warn("OvsdbConnectionManager Unable to fetch Database list from device {}."
+                    + "Disconnecting from the device.", externalClient.getConnectionInfo().getRemoteAddress(), e);
             externalClient.disconnect();
         }
 
@@ -175,7 +179,7 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
     @Override
     public void disconnected(final OvsdbClient client) {
         alreadyProcessedClients.remove(client);
-        LOG.info("Library disconnected {} from {}:{} to {}:{}. Cleaning up the operational data store",
+        LOG.info("Ovsdb Library disconnected {} from {}:{} to {}:{}. Cleaning up the operational data store",
                 client.getConnectionInfo().getType(),
                 client.getConnectionInfo().getRemoteAddress(),
                 client.getConnectionInfo().getRemotePort(),
@@ -189,10 +193,10 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
             // about to disconnect as well), if current owner get disconnected from
             // OVSDB device.
             if (ovsdbConnectionInstance.getHasDeviceOwnership()) {
-                LOG.info("Library disconnected {} this controller instance has ownership", key);
+                LOG.info("Ovsdb Library disconnected {} this controller instance has ownership", key);
                 deleteOperNodeAndReleaseOwnership(ovsdbConnectionInstance);
             } else {
-                LOG.info("Library disconnected {} this controller does not have ownership", key);
+                LOG.info("Ovsdb Library disconnected {} this controller does not have ownership", key);
                 unregisterEntityForOwnership(ovsdbConnectionInstance);
             }
             removeConnectionInstance(key);
@@ -207,7 +211,7 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
                     ovsdbConnectionInstance.getOvsdbNodeAugmentation(),
                     ConnectionReconciliationTriggers.ON_DISCONNECT);
         } else {
-            LOG.warn("disconnected : Connection instance not found for OVSDB Node {} ", key);
+            LOG.warn("Ovsdb disconnected : Connection instance not found for OVSDB Node {} ", key);
         }
         LOG.trace("OvsdbConnectionManager: exit disconnected client: {}", client);
     }
@@ -430,13 +434,13 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
             justification = "https://github.com/spotbugs/spotbugs/issues/811")
     private void handleOwnershipChanged(final EntityOwnershipChange ownershipChange) {
         OvsdbConnectionInstance ovsdbConnectionInstance = getConnectionInstanceFromEntity(ownershipChange.getEntity());
-        LOG.debug("handleOwnershipChanged: {} event received for device {}",
+        LOG.debug("Ovsdb handleOwnershipChanged: {} event received for device {}",
                 ownershipChange, ovsdbConnectionInstance != null ? ovsdbConnectionInstance.getConnectionInfo()
                         : "that's currently NOT registered by *this* southbound plugin instance");
 
         if (ovsdbConnectionInstance == null) {
             if (ownershipChange.getState().isOwner()) {
-                LOG.warn("handleOwnershipChanged: *this* instance is elected as an owner of the device {} but it "
+                LOG.warn("Ovsdb handleOwnershipChanged: *this* instance is elected as an owner of the device {} but it "
                         + "is NOT registered for ownership", ownershipChange.getEntity());
             } else {
                 // EntityOwnershipService sends notification to all the nodes, irrespective of whether
@@ -444,13 +448,14 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
                 // If all the controller instance that was connected to the device are down, so the
                 // running instance can clear up the operational data store even though it was not
                 // connected to the device.
-                LOG.debug("handleOwnershipChanged: No connection instance found for {}", ownershipChange.getEntity());
+                LOG.debug("Ovsdb handleOwnershipChanged: No connection instance found for {}",
+                    ownershipChange.getEntity());
             }
 
             // If entity has no owner, clean up the operational data store (it's possible because owner controller
             // might went down abruptly and didn't get a chance to clean up the operational data store.
             if (!ownershipChange.getState().hasOwner()) {
-                LOG.info("{} has no owner, cleaning up the operational data store", ownershipChange.getEntity());
+                LOG.info("Ovsdb {} has no owner, cleaning up the operational data store", ownershipChange.getEntity());
                 cleanEntityOperationalData(ownershipChange.getEntity());
             }
             return;
@@ -459,7 +464,7 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
         putConnectionInstance(ovsdbConnectionInstance.getMDConnectionInfo(),ovsdbConnectionInstance);
 
         if (ownershipChange.getState().isOwner() == ovsdbConnectionInstance.getHasDeviceOwnership()) {
-            LOG.info("handleOwnershipChanged: no change in ownership for {}. Ownership status is : {}",
+            LOG.info("Ovsdb handleOwnershipChanged: no change in ownership for {}. Ownership status is : {}",
                     ovsdbConnectionInstance.getConnectionInfo(), ovsdbConnectionInstance.getHasDeviceOwnership()
                             ? SouthboundConstants.OwnershipStates.OWNER.getState()
                             : SouthboundConstants.OwnershipStates.NONOWNER.getState());
@@ -469,13 +474,13 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
         ovsdbConnectionInstance.setHasDeviceOwnership(ownershipChange.getState().isOwner());
         // You were not an owner, but now you are
         if (ownershipChange.getState().isOwner()) {
-            LOG.info("handleOwnershipChanged: *this* southbound plugin instance is an OWNER of the device {}",
+            LOG.info("Ovsdb handleOwnershipChanged: *this* southbound plugin instance is an OWNER of the device {}",
                     ovsdbConnectionInstance.getConnectionInfo());
 
             //*this* instance of southbound plugin is owner of the device,
             //so register for monitor callbacks
             ovsdbConnectionInstance.registerCallbacks(instanceIdentifierCodec);
-            LOG.trace("isUpgradeInProgress {}", upgradeState.isUpgradeInProgress());
+            LOG.trace("Ovsdb isUpgradeInProgress {}", upgradeState.isUpgradeInProgress());
             if (!upgradeState.isUpgradeInProgress()) {
                 reconcileBridgeConfigurations(ovsdbConnectionInstance);
             }
@@ -487,8 +492,8 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
             //when clustering service implement a ownership grant strategy which can revoke the
             //device ownership for load balancing the devices across the instances.
             //Once this condition occur, we should unregister the callback.
-            LOG.error("handleOwnershipChanged: *this* southbound plugin instance is no longer the owner of device {}."
-                    + "This should NOT happen.",
+            LOG.error("Ovsdb handleOwnershipChanged: *this* southbound plugin instance is no longer"
+                    + " the owner of device {}.This should NOT happen.",
                     ovsdbConnectionInstance.getNodeId().getValue());
         }
     }
@@ -528,7 +533,7 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
         try {
             dbSchema = connectionInstance.getSchema(OvsdbSchemaContants.DATABASE_NAME).get();
         } catch (InterruptedException | ExecutionException e) {
-            LOG.warn("Not able to fetch schema for database {} from device {}",
+            LOG.warn("Ovsdb Not able to fetch schema for database {} from device {}",
                     OvsdbSchemaContants.DATABASE_NAME,connectionInstance.getConnectionInfo(),e);
             return null;
         }
@@ -544,8 +549,8 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
         try {
             results = connectionInstance.transact(dbSchema, operations).get();
         } catch (InterruptedException | ExecutionException e) {
-            LOG.warn("Not able to fetch OpenVswitch table row from device {}", connectionInstance.getConnectionInfo(),
-                e);
+            LOG.warn("Ovsdb Not able to fetch OpenVswitch table row from device {}",
+                connectionInstance.getConnectionInfo(), e);
             return null;
         }
 
@@ -562,12 +567,12 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
              */
             OpenVSwitch openvswitchRow = getOpenVswitchTableEntry(ovsdbConnectionInstance);
             iid = SouthboundMapper.getInstanceIdentifier(instanceIdentifierCodec, openvswitchRow);
-            LOG.info("InstanceIdentifier {} generated for device "
+            LOG.info("Ovsdb InstanceIdentifier {} generated for device "
                     + "connection {}",iid,ovsdbConnectionInstance.getConnectionInfo());
             ovsdbConnectionInstance.setInstanceIdentifier(iid);
         }
         Entity deviceEntity = new Entity(ENTITY_TYPE, iid);
-        LOG.debug("Entity {} created for device connection {}",
+        LOG.debug("Ovsdb Entity {} created for device connection {}",
                 deviceEntity, ovsdbConnectionInstance.getConnectionInfo());
         return deviceEntity;
     }
@@ -581,7 +586,7 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
 
         Entity candidateEntity = getEntityFromConnectionInstance(ovsdbConnectionInstance);
         if (entityConnectionMap.containsKey(candidateEntity)) {
-            LOG.error("Old connection still hanging for {}", candidateEntity);
+            LOG.error("Ovsdb Old connection still hanging for {}", candidateEntity);
             disconnected(ovsdbConnectionInstance.getOvsdbClient());
             //TODO do cleanup for old connection or stale check
         }
index 0f06697a885e625f01a6894216f4fca47029f3ba..5d4607fe55a82f29c589c11c9bfe586d69bf36d0 100644 (file)
@@ -9,9 +9,12 @@
 package org.opendaylight.ovsdb.southbound;
 
 import java.util.Collection;
+import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
@@ -19,6 +22,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.ovsdb.southbound.transactions.md.TransactionInvoker;
+import org.opendaylight.ovsdb.utils.mdsal.utils.Scheduler;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
@@ -101,7 +105,21 @@ public class OvsdbOperGlobalListener implements ClusteredDataTreeChangeListener<
         });
     }
 
+    private static final Map<InstanceIdentifier<Node>, ScheduledFuture> TIMEOUT_FTS = new ConcurrentHashMap<>();
 
+    public static void runAfterTimeoutIfNodeNotCreated(InstanceIdentifier<Node> iid, Runnable job) {
+        ScheduledFuture<?> ft = TIMEOUT_FTS.get(iid);
+        if (ft != null) {
+            ft.cancel(false);
+        }
+        ft = Scheduler.getScheduledExecutorService().schedule(() -> {
+            TIMEOUT_FTS.remove(iid);
+            if (!OPER_NODE_CACHE.containsKey(iid)) {
+                job.run();
+            }
+        }, SouthboundConstants.EOS_TIMEOUT, TimeUnit.SECONDS);
+        TIMEOUT_FTS.put(iid, ft);
+    }
 
     private Node getCreated(DataObjectModification<Node> mod) {
         if ((mod.getModificationType() == DataObjectModification.ModificationType.WRITE)
index 824cb23809fcd074477797c3475ebcc2e0919b7f..55370d17f3c85dcc2bc2a8942a61cb4c9bf541b5 100755 (executable)
@@ -213,4 +213,6 @@ public interface SouthboundConstants {
             return this.state;
         }
     }
+
+    int EOS_TIMEOUT = Integer.getInteger("southbound.eos.timeout.delay.secs", 240);
 }