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;
}
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;
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());
default void onFailure(TransactionBuilder deviceTransaction) {
}
+
+ default boolean retry() {
+ return false;
+ }
}
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;
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 >
public void onSuccess(TransactionBuilder deviceTransaction) {
commands.forEach(cmd -> cmd.onSuccess(deviceTransaction));
}
+
+ @Override
+ public boolean retry() {
+ return retryCount.decrementAndGet() > 0;
+ }
+
+
}
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;
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;
}
@Override
+ @SuppressWarnings("checkstyle:IllegalCatch")
public void invoke(TransactCommand command) {
TransactionBuilder tb = new TransactionBuilder(connectionInstance.getOvsdbClient(), dbSchema);
command.execute(tb);
} 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);
}
}