Retry mechanism for Hwvtep failed Transaction commands 41/88741/2
authorChandra Shekar S <chandra.shekar.s@ericsson.com>
Fri, 27 Mar 2020 04:43:49 +0000 (10:13 +0530)
committerChetan Arakere Gowdru <chetan.arakere@altencalsoftlabs.com>
Thu, 2 Apr 2020 06:42:34 +0000 (06:42 +0000)
Signed-off-by: Chandra Shekar S <chandra.shekar.s@ericsson.com>
Change-Id: Ic15829836a316e1f21a0481089ae119cb38e60d1

hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepSouthboundConstants.java
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepTableReader.java
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactCommand.java
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactCommandAggregator.java
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactInvokerImpl.java

index 1bf1c0c756b1de1afb4c0d5bd51d88b642a13386..c0afe20b5845103c37de47975d81bcf57ccdf0a4 100644 (file)
@@ -54,5 +54,6 @@ public interface HwvtepSouthboundConstants {
     long CONFIG_NODE_UPDATE_MAX_DELAY_MS = Integer.getInteger(
             "config.node.update.max.delay.ms", 10000);
     int EOS_TIMEOUT = Integer.getInteger("hwvtep.eos.timeout.delay.secs", 240);
+    int CHAIN_RETRY_COUNT = 10;
 
 }
index cbc0e845cb99061e3bccd9cb5b0e494783dc9ffd..0ecb0e281131e34daa5d79582f4532eb7d256715 100644 (file)
@@ -52,7 +52,10 @@ import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
 import org.opendaylight.ovsdb.schema.hardwarevtep.Tunnel;
 import org.opendaylight.ovsdb.schema.hardwarevtep.UcastMacsLocal;
 import org.opendaylight.ovsdb.schema.hardwarevtep.UcastMacsRemote;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitchesKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacsKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
@@ -354,6 +357,32 @@ public class HwvtepTableReader {
         return new TableUpdates(tableUpdates);
     }
 
+    public void refreshLocators() {
+        List<TypedBaseTable> physicalLocators = connectionInstance.getHwvtepTableReader()
+                .getHwvtepTableEntries(TerminationPoint.class);
+        for (TypedBaseTable row : physicalLocators) {
+            PhysicalLocator physicalLocator = (PhysicalLocator)row;
+            InstanceIdentifier<TerminationPoint> tpPath =
+                    HwvtepSouthboundMapper.createInstanceIdentifier(connectionInstance.getInstanceIdentifier(),
+                            physicalLocator);
+            connectionInstance.getDeviceInfo().updateDeviceOperData(
+                    TerminationPoint.class, tpPath, physicalLocator.getUuid(), physicalLocator);
+        }
+    }
+
+    public void refreshLogicalSwitches() {
+        List<TypedBaseTable> logicalSwitches = connectionInstance.getHwvtepTableReader()
+                .getHwvtepTableEntries(LogicalSwitches.class);
+        for (TypedBaseTable row : logicalSwitches) {
+            LogicalSwitch logicalSwitch = (LogicalSwitch)row;
+            InstanceIdentifier<LogicalSwitches> switchIid = connectionInstance.getInstanceIdentifier()
+                    .augmentation(HwvtepGlobalAugmentation.class)
+                    .child(LogicalSwitches.class, new LogicalSwitchesKey(new HwvtepNodeName(logicalSwitch.getName())));
+            connectionInstance.getDeviceInfo().updateDeviceOperData(LogicalSwitches.class, switchIid,
+                    logicalSwitch.getUuid(), logicalSwitch);
+        }
+    }
+
     private static Select<GenericTableSchema> buildSelectOperationFor(final GenericTableSchema tableSchema) {
         Select<GenericTableSchema> selectOperation = op.select(tableSchema);
         selectOperation.setColumns(tableSchema.getColumnList());
index cad1998f8b38adf3199a8f1b6f6fe21f6e455274..a0cb88ee3946bcc14df30ec39a25f60a270c723e 100644 (file)
@@ -30,4 +30,8 @@ public interface TransactCommand<T extends Identifiable> {
 
     default void onFailure(TransactionBuilder deviceTransaction) {
     }
+
+    default boolean retry() {
+        return false;
+    }
 }
index 0a630ff46c1aacc512e2296ca8dcad46ede4a59e..702cea32f405224e9ab37f781f8fca1de768c3ce 100644 (file)
@@ -14,9 +14,12 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.concurrent.atomic.AtomicInteger;
+
 import org.apache.commons.lang3.tuple.Pair;
 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundConstants;
 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
@@ -32,6 +35,7 @@ public class TransactCommandAggregator implements TransactCommand {
     private static final Logger LOG = LoggerFactory.getLogger(TransactCommandAggregator.class);
 
     private final List<TransactCommand> commands = new ArrayList<>();
+    private AtomicInteger retryCount = new AtomicInteger(HwvtepSouthboundConstants.CHAIN_RETRY_COUNT);
     private final HwvtepOperationalState operationalState;
     /* stores the modified and deleted data for each child type of each node id
        Map<nodeid , Pair < updated, deleted >
@@ -189,4 +193,11 @@ public class TransactCommandAggregator implements TransactCommand {
     public void onSuccess(TransactionBuilder deviceTransaction) {
         commands.forEach(cmd -> cmd.onSuccess(deviceTransaction));
     }
+
+    @Override
+    public boolean retry() {
+        return retryCount.decrementAndGet() > 0;
+    }
+
+
 }
index f4c0f0d586087fa555287473e9f01db5a07a6446..56988d3061fc30d131d20e2e53b28627edcdafac 100644 (file)
@@ -13,7 +13,6 @@ import com.google.common.util.concurrent.ListenableFuture;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.concurrent.ExecutionException;
 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
 import org.opendaylight.ovsdb.lib.operations.Delete;
 import org.opendaylight.ovsdb.lib.operations.Insert;
@@ -22,6 +21,8 @@ import org.opendaylight.ovsdb.lib.operations.OperationResult;
 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
 import org.opendaylight.ovsdb.lib.operations.Update;
 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -36,6 +37,7 @@ public class TransactInvokerImpl implements TransactInvoker {
     }
 
     @Override
+    @SuppressWarnings("checkstyle:IllegalCatch")
     public void invoke(TransactCommand command) {
         TransactionBuilder tb = new TransactionBuilder(connectionInstance.getOvsdbClient(), dbSchema);
         command.execute(tb);
@@ -61,9 +63,28 @@ public class TransactInvokerImpl implements TransactInvoker {
                 } else {
                     command.onSuccess(tb);
                 }
-            } catch (InterruptedException | ExecutionException e) {
-                LOG.warn("Transact execution exception: ", e);
+                if (errorOccured) {
+                    if (!command.retry()) {
+                        LOG.error("Failed on second attempt too aborting the transaction {}", command);
+                        return;
+                    }
+                    LOG.error("Retrying the failed command {}", command);
+                    //Oper data is going to be filled with latest data after monitor callback update comes and is
+                    // processed but do not wait till then , pull the latest data and retry the failing command
+                    //The command could be failing due to reference to stale physical locator/logical switch.
+                    //pull the latest locators and put them in device oper data and retry the command.
+                    connectionInstance.getDeviceInfo().clearDeviceOperData(LogicalSwitches.class);
+                    connectionInstance.getDeviceInfo().clearDeviceOperData(TerminationPoint.class);
+
+                    connectionInstance.getHwvtepTableReader().refreshLogicalSwitches();
+                    connectionInstance.getHwvtepTableReader().refreshLocators();
+                    connectionInstance.transact(command);
+                }
+            } catch (Exception e) {
+                LOG.error("Transact execution exception: {} {}",
+                        tb, connectionInstance.getInstanceIdentifier(), e);
             }
+
             LOG.trace("invoke exit command: {}, tb: {}", command, tb);
         }
     }