bug 6578 added mdsal read retry 59/66559/3
authorK.V Suneelu Verma <k.v.suneelu.verma@ericsson.com>
Mon, 18 Dec 2017 11:16:17 +0000 (16:46 +0530)
committerSam Hague <shague@redhat.com>
Fri, 16 Feb 2018 02:45:02 +0000 (02:45 +0000)
Change-Id: I5dba7362bf41ea84baa35dc29a6a4a6a69ba78fa
Signed-off-by: K.V Suneelu Verma <k.v.suneelu.verma@ericsson.com>
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepSouthboundUtil.java
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/AbstractTransactCommand.java
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/HwvtepOperationalState.java
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalSwitchUpdateCommand.java
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactUtils.java
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/UcastMacsLocalUpdateCommand.java
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/AbstractTransactionCommand.java
utils/mdsal-utils/src/main/java/org/opendaylight/ovsdb/utils/mdsal/utils/MdsalUtils.java

index aa6804f07ca59d468e8dc0194ae89af5f83a6792..a2941e134c69cd1f7fe5ba58258b3cc5d472dc79 100644 (file)
@@ -14,6 +14,7 @@ import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.ovsdb.lib.error.SchemaVersionMismatchException;
+import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
 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.HwvtepGlobalRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalSwitchAttributes;
@@ -100,16 +101,12 @@ public class HwvtepSouthboundUtil {
 
     public static Optional<HwvtepGlobalAugmentation> getManagingNode(DataBroker db, HwvtepGlobalRef ref) {
         try {
-            ReadOnlyTransaction transaction = db.newReadOnlyTransaction();
             @SuppressWarnings("unchecked")
             // Note: erasure makes this safe in combination with the typecheck
             // below
             InstanceIdentifier<Node> path = (InstanceIdentifier<Node>) ref.getValue();
 
-            CheckedFuture<Optional<Node>, ReadFailedException> nf =
-                            transaction.read(LogicalDatastoreType.OPERATIONAL, path);
-            transaction.close();
-            Optional<Node> optional = nf.get();
+            Optional<Node> optional = new MdsalUtils(db).readOptional(LogicalDatastoreType.OPERATIONAL, path);
             if (optional != null && optional.isPresent()) {
                 HwvtepGlobalAugmentation hwvtepNode = null;
                 Node node = optional.get();
index 34e1165f286a72473aa06463f4bcb23f7cf29e58..813c54d62c4c154215246bb3c46b1073f1357bdb 100644 (file)
@@ -21,6 +21,7 @@ import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -61,6 +62,10 @@ public abstract class AbstractTransactCommand<T extends Identifiable, A extends
         return threadLocalOperationalState.get();
     }
 
+    public DataBroker getDataBroker() {
+        return getOperationalState().getDataBroker();
+    }
+
     public Collection<DataTreeModification<Node>> getChanges() {
         return changes;
     }
index ea7dee8a183ee10b168e8938d240b5cb908603bc..829777c93c7680a8657de9555b8c959ccdc27bd7 100644 (file)
@@ -14,10 +14,12 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepDeviceInfo;
 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
 import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.EncapsulationTypeBase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
@@ -98,7 +100,7 @@ public class HwvtepOperationalState {
         this.db = connectionInstance.getDataBroker();
         this.changes = null;
         transaction = connectionInstance.getDataBroker().newReadWriteTransaction();
-        Optional<Node> readNode = HwvtepSouthboundUtil.readNode(transaction,
+        Optional<Node> readNode = new MdsalUtils(db).readOptional(LogicalDatastoreType.OPERATIONAL,
                 connectionInstance.getInstanceIdentifier());
         if (readNode.isPresent()) {
             operationalNodes.put(connectionInstance.getInstanceIdentifier(), readNode.get());
@@ -135,7 +137,8 @@ public class HwvtepOperationalState {
         if (nodeCreateOrUpdate != null) {
             transaction = db.newReadWriteTransaction();
             for (Entry<InstanceIdentifier<Node>, Node> entry: nodeCreateOrUpdate.entrySet()) {
-                Optional<Node> readNode = HwvtepSouthboundUtil.readNode(transaction, entry.getKey());
+                Optional<Node> readNode = new MdsalUtils(db).readOptional(LogicalDatastoreType.OPERATIONAL,
+                        entry.getKey());
                 //add related globalNode or physicalSwitchNode to operationalNodes map
                 //for example, when creating physical port, logical switch is needed
                 //but logical switch is in HwvtepGlobalAugmentation rather than PhysicalSwitchAugmentation
@@ -147,7 +150,8 @@ public class HwvtepOperationalState {
                         for (Switches pswitch : hgAugmentation.getSwitches()) {
                             @SuppressWarnings("unchecked")
                             InstanceIdentifier<Node> psNodeIid = (InstanceIdentifier<Node>) pswitch.getSwitchRef().getValue();
-                            Optional<Node> psNode = HwvtepSouthboundUtil.readNode(transaction, psNodeIid);
+                            Optional<Node> psNode = new MdsalUtils(db).readOptional(LogicalDatastoreType.OPERATIONAL,
+                                    psNodeIid);
                             if (psNode.isPresent()) {
                                 operationalNodes.put(psNodeIid, psNode.get());
                             }
@@ -156,7 +160,8 @@ public class HwvtepOperationalState {
                     if (psAugmentation != null) {
                         @SuppressWarnings("unchecked")
                         InstanceIdentifier<Node> hgNodeIid = (InstanceIdentifier<Node>) psAugmentation.getManagedBy().getValue();
-                        Optional<Node> hgNode = HwvtepSouthboundUtil.readNode(transaction, hgNodeIid);
+                        Optional<Node> hgNode = new MdsalUtils(db).readOptional(
+                                LogicalDatastoreType.OPERATIONAL, hgNodeIid);
                         if (hgNode.isPresent()) {
                             operationalNodes.put(hgNodeIid, hgNode.get());
                         }
@@ -369,7 +374,7 @@ public class HwvtepOperationalState {
     }
 
     public Optional<HwvtepPhysicalLocatorAugmentation> getPhysicalLocatorAugmentation(InstanceIdentifier<TerminationPoint> iid) {
-        Optional<TerminationPoint> tp = HwvtepSouthboundUtil.readNode(transaction, iid);
+        Optional<TerminationPoint> tp = new MdsalUtils(db).readOptional(LogicalDatastoreType.OPERATIONAL, iid);
         if (tp.isPresent()) {
             return Optional.fromNullable(tp.get().getAugmentation(HwvtepPhysicalLocatorAugmentation.class));
         }
@@ -377,17 +382,17 @@ public class HwvtepOperationalState {
     }
 
     public Optional<LogicalSwitches> getLogicalSwitches(InstanceIdentifier<LogicalSwitches> iid) {
-        Optional<LogicalSwitches> lswitch = HwvtepSouthboundUtil.readNode(transaction, iid);
+        Optional<LogicalSwitches> lswitch = new MdsalUtils(db).readOptional(LogicalDatastoreType.OPERATIONAL, iid);
         return lswitch;
     }
 
     public Optional<Tunnels> getTunnels(InstanceIdentifier<Tunnels> iid) {
-        Optional<Tunnels> tunnels = HwvtepSouthboundUtil.readNode(transaction, iid);
+        Optional<Tunnels> tunnels = new MdsalUtils(db).readOptional(LogicalDatastoreType.OPERATIONAL, iid);
         return tunnels;
     }
 
     public Optional<Acls> getAcls(InstanceIdentifier<Acls> iid) {
-        Optional<Acls> acl = HwvtepSouthboundUtil.readNode(transaction, iid);
+        Optional<Acls> acl = new MdsalUtils(db).readOptional(LogicalDatastoreType.OPERATIONAL, iid);
         return acl;
     }
 
index 89849d7f81bb859c9162e73ee734acec3c6503c8..d2ece230dee3c6fca2847ce3420d853a85421027 100644 (file)
@@ -22,6 +22,7 @@ import java.util.Set;
 
 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
 import org.opendaylight.ovsdb.lib.error.SchemaVersionMismatchException;
 import org.opendaylight.ovsdb.lib.notation.Mutator;
@@ -31,6 +32,7 @@ import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
 import org.opendaylight.ovsdb.schema.hardwarevtep.Global;
 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
 import org.opendaylight.ovsdb.schema.hardwarevtep.Tunnel;
+import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.ManagementIps;
@@ -284,8 +286,8 @@ public class PhysicalSwitchUpdateCommand extends AbstractTransactCommand {
         } else {
             // TODO/FIXME: Not in operational, do we create a new one?
             LOG.warn("Trying to create tunnel without creating physical locators first");
-            Optional<TerminationPoint> confLocOptional =
-                            TransactUtils.readNodeFromConfig(getOperationalState().getReadWriteTransaction(), iid);
+            Optional<TerminationPoint> confLocOptional = new MdsalUtils(getOperationalState().getDataBroker())
+                    .readOptional(LogicalDatastoreType.CONFIGURATION, iid);
             if (confLocOptional.isPresent()) {
                 HwvtepPhysicalLocatorAugmentation locatorAugmentation =
                                 confLocOptional.get().getAugmentation(HwvtepPhysicalLocatorAugmentation.class);
index 5b6c855be2f115baccda6b932938aced7d676e0f..41c15053c9bfc23dcf876bcb2d3fb342631def0d 100644 (file)
@@ -131,17 +131,6 @@ public class TransactUtils {
         return result;
     }
 
-    public static <D extends org.opendaylight.yangtools.yang.binding.DataObject> Optional<D> readNodeFromConfig(
-            ReadWriteTransaction transaction, final InstanceIdentifier<D> connectionIid) {
-        Optional<D> node = Optional.absent();
-        try {
-            node = transaction.read(LogicalDatastoreType.CONFIGURATION, connectionIid).checkedGet();
-        } catch (final ReadFailedException e) {
-            LOG.warn("Read Configration/DS for Node failed! {}", connectionIid, e);
-        }
-        return node;
-    }
-
     public static UUID createPhysicalLocatorSet(HwvtepOperationalState hwvtepOperationalState, TransactionBuilder transaction, List<LocatorSet> locatorList) {
         Set<UUID> locators = new HashSet<UUID>();
         for (LocatorSet locator: locatorList) {
index 1f5b5cc06cf7d3c5ccbecf9adb31523af9bc7f6b..82c2478e64cc75a39b4619015d077b5e0becc455 100644 (file)
@@ -16,10 +16,12 @@ import java.util.Map;
 import java.util.Map.Entry;
 
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.ovsdb.lib.notation.UUID;
 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
 import org.opendaylight.ovsdb.schema.hardwarevtep.UcastMacsLocal;
+import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
 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.HwvtepPhysicalLocatorAugmentation;
@@ -117,8 +119,8 @@ public class UcastMacsLocalUpdateCommand extends AbstractTransactCommand<LocalUc
                 locatorUuid = new UUID(locatorAugmentation.getPhysicalLocatorUuid().getValue());
             } else {
                 //if no, get it from config DS and create id
-                Optional<TerminationPoint> configLocatorOptional =
-                        TransactUtils.readNodeFromConfig(getOperationalState().getReadWriteTransaction(), iid);
+                Optional<TerminationPoint> configLocatorOptional = new MdsalUtils(
+                        getOperationalState().getDataBroker()).readOptional(LogicalDatastoreType.CONFIGURATION, iid);
                 if (configLocatorOptional.isPresent()) {
                     HwvtepPhysicalLocatorAugmentation locatorAugmentation =
                             configLocatorOptional.get().getAugmentation(HwvtepPhysicalLocatorAugmentation.class);
index ec19f3b5b023c64489fcc78dd50fb46fa5ff8921..d7dca6b95531ceb605988b4ccd6a2adf30db5379 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
 
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepDeviceInfo;
 import org.opendaylight.ovsdb.lib.message.TableUpdates;
@@ -37,7 +38,7 @@ public abstract class AbstractTransactionCommand<T extends DataObject> implement
         return key;
     }
 
-    public AbstractTransactionCommand(HwvtepConnectionInstance key, TableUpdates updates, DatabaseSchema dbSchema) {
+    public AbstractTransactionCommand(HwvtepConnectionInstance key,TableUpdates updates, DatabaseSchema dbSchema) {
         this.updates = updates;
         this.dbSchema = dbSchema;
         this.key = key;
index 642ba080ae2e31a2f23a3ca38b4dab10612d88cd..f5354abf1d8a6ff8ca300ce15347f5185053ade5 100644 (file)
@@ -15,6 +15,7 @@ import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -22,7 +23,8 @@ import org.slf4j.LoggerFactory;
 public class MdsalUtils {
     private static final Logger LOG = LoggerFactory.getLogger(MdsalUtils.class);
     private DataBroker databroker = null;
-
+    private static int MDSAL_MAX_READ_TRIALS = Integer.getInteger("mdsalutil.max.tries", 30);
+    private static int MDSAL_READ_SLEEP_INTERVAL_MS = Integer.getInteger("mdsalutil.sleep.between.mdsal.reads", 1000);
     /**
      * Class constructor setting the data broker.
      *
@@ -109,24 +111,46 @@ public class MdsalUtils {
      * @param <D> the data object type
      * @return the result as the data object requested
      */
-    public <D extends org.opendaylight.yangtools.yang.binding.DataObject> D read(
-            final LogicalDatastoreType store, final InstanceIdentifier<D> path)  {
-        D result = null;
-        final ReadOnlyTransaction transaction = databroker.newReadOnlyTransaction();
-        Optional<D> optionalDataObject;
-        CheckedFuture<Optional<D>, ReadFailedException> future = transaction.read(store, path);
-        try {
-            optionalDataObject = future.checkedGet();
-            if (optionalDataObject.isPresent()) {
-                result = optionalDataObject.get();
-            } else {
-                LOG.debug("{}: Failed to read {}",
-                        Thread.currentThread().getStackTrace()[1], path);
-            }
-        } catch (ReadFailedException e) {
-            LOG.warn("Failed to read {} ", path, e);
+    public <D extends DataObject> D read(
+            final LogicalDatastoreType store, final InstanceIdentifier<? extends DataObject> path) {
+        Optional<D> optionalDataObject = readOptional(store, path);
+        if (optionalDataObject.isPresent()) {
+            return optionalDataObject.get();
         }
-        transaction.close();
-        return result;
+        LOG.debug("{}: Failed to read {}",
+                Thread.currentThread().getStackTrace()[1], path);
+        return null;
+    }
+
+    public <D extends DataObject> Optional<D> readOptional(
+            final LogicalDatastoreType store, final InstanceIdentifier<? extends DataObject> path)  {
+        int trialNo = 0;
+        ReadOnlyTransaction transaction = databroker.newReadOnlyTransaction();
+        do {
+            try {
+                Optional<D> result = transaction.read(store, (InstanceIdentifier<D>)path).checkedGet();
+                transaction.close();
+                return result;
+            } catch (ReadFailedException e) {
+                if (trialNo == 0) {
+                    logReadFailureError(path, " mdsal Read failed exception retrying the read after sleep");
+                }
+                try {
+                    transaction.close();
+                    Thread.sleep(MDSAL_READ_SLEEP_INTERVAL_MS);
+                    transaction = databroker.newReadOnlyTransaction();
+                } catch (InterruptedException e1) {
+                    logReadFailureError(path, " Sleep interrupted");
+                }
+            }
+        } while (trialNo++ < MDSAL_MAX_READ_TRIALS);
+        logReadFailureError(path, " All read trials exceeded");
+        return Optional.absent();
+    }
+
+    private <D extends org.opendaylight.yangtools.yang.binding.DataObject> void logReadFailureError(
+            InstanceIdentifier<D> path, String cause) {
+        LOG.error("{}: Failed to read {} Cause : {}", Thread.currentThread().getStackTrace()[2], path, cause);
+
     }
 }