This review is to enhace the HwvtepDeviceInfo to use the Cache.
It has the following changes.
1. Enhanced to include the incoming update objects in the cache.
2. Check in the cache before deleting.
3. Update the cache when the updates are successfully submitted to db.
Signed-off-by: Chandra Shekar S <chandra.shekar.s@ericsson.com>
Change-Id: I70a923f2b58077e780b53c457b05bb2545a87d4f
public void setHasDeviceOwnership(final Boolean hasDeviceOwnership) {
if (hasDeviceOwnership != null) {
+ if (hasDeviceOwnership != this.hasDeviceOwnership) {
+ LOG.info("Ownership status changed for {} old {} new {}", instanceIdentifier,
+ this.hasDeviceOwnership, hasDeviceOwnership);
+ }
this.hasDeviceOwnership = hasDeviceOwnership;
}
}
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
import org.opendaylight.ovsdb.hwvtepsouthbound.transact.DependencyQueue;
import org.opendaylight.ovsdb.hwvtepsouthbound.transact.DependentJob;
import org.opendaylight.ovsdb.hwvtepsouthbound.transact.TransactCommand;
private static final Logger LOG = LoggerFactory.getLogger(HwvtepDeviceInfo.class);
+ private Map<Class<? extends Identifiable>, Map<InstanceIdentifier, Boolean>> availableInOperDs =
+ new ConcurrentHashMap<>();
+
+ public void markAvailableInOperDs(Class<? extends Identifiable> cls, InstanceIdentifier key) {
+ availableInOperDs.putIfAbsent(cls, new ConcurrentHashMap<>());
+ availableInOperDs.get(cls).put(key, Boolean.TRUE);
+ }
+
+ public Boolean isAvailableInOperDs(Class<? extends Identifiable> cls, InstanceIdentifier key) {
+ availableInOperDs.putIfAbsent(cls, new ConcurrentHashMap<>());
+ return availableInOperDs.get(cls).getOrDefault(key, Boolean.FALSE);
+ }
+
+ public Boolean clearOperDsAvailability(Class<? extends Identifiable> cls, InstanceIdentifier key) {
+ availableInOperDs.putIfAbsent(cls, new ConcurrentHashMap<>());
+ return availableInOperDs.get(cls).remove(key);
+ }
+
public enum DeviceDataStatus {
IN_TRANSIT,
UNAVAILABLE,
public boolean isInTransitState() {
return status == DeviceDataStatus.IN_TRANSIT;
}
+
+ public boolean isAvailableInOperDs() {
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return key + " uuid:" + uuid + " data:" + data + " status:" + status;
+ }
}
+ private static AtomicInteger ZERO = new AtomicInteger(0);
private final Map<InstanceIdentifier<?>, Set<InstanceIdentifier>> tepIdReferences = new ConcurrentHashMap<>();
private final Map<InstanceIdentifier<LogicalSwitches>, Map<InstanceIdentifier<RemoteUcastMacs>, RemoteUcastMacs>>
logicalSwitchVsUcasts = new ConcurrentHashMap<>();
}
}
+ public void clearDeviceOperUUID(Class<? extends Identifiable> cls, InstanceIdentifier key, UUID uuid) {
+ LOG.debug("Clearing device data {}", key);
+ if (uuidVsData.containsKey(cls) && uuidVsData.get(cls).containsKey(uuid)) {
+ LOG.debug("Remove {} {} from device data.", connectionInstance.getNodeId().getValue(), cls.getSimpleName());
+ }
+ HwvtepSouthboundUtil.clearData(uuidVsData, cls, uuid);
+ HwvtepSouthboundUtil.clearData(opKeyVsData, cls, key);
+ }
+
public DeviceData getDeviceOperData(Class<? extends Identifiable> cls, UUID uuid) {
return HwvtepSouthboundUtil.getData(uuidVsData, cls, uuid);
}
public Map<Class<? extends Identifiable>, Map<UUID, DeviceData>> getUuidData() {
return Collections.unmodifiableMap(uuidVsData);
}
+
}
LOG.debug("Creating a physical port named: {}", port.getHwvtepNodeName().getValue());
InstanceIdentifier<TerminationPoint> key = getTpIid(psNodeiid, port.getHwvtepNodeName().getValue());
- getOperationalState().getDeviceInfo().updateConfigData(TerminationPoint.class, key, tp);
- HwvtepDeviceInfo.DeviceData deviceOperdata = getDeviceInfo().getDeviceOperData(TerminationPoint.class, key);
+ getOperationalState().getDeviceInfo().updateConfigData(VlanBindings.class, key, tp);
+ HwvtepDeviceInfo.DeviceData deviceOperdata = getDeviceInfo().getDeviceOperData(VlanBindings.class, key);
if (deviceOperdata == null || deviceOperdata.getData() == null) {
LOG.error("Updated the device oper cache for port from actual device {}", key);
- deviceOperdata = super.fetchDeviceData(TerminationPoint.class, key);
+ deviceOperdata = super.fetchDeviceData(VlanBindings.class, key);
}
if (deviceOperdata == null || deviceOperdata.getData() == null) {
//create a physical port always happens from device
package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+import java.util.HashSet;
+import java.util.Set;
+import org.apache.commons.lang3.tuple.Pair;
+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.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.notation.UUID;
import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.ConnectionInfo;
import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.Identifiable;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public abstract class AbstractTransactionCommand<T extends DataObject> implements TransactionCommand {
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractTransactionCommand.class);
private final TableUpdates updates;
private final DatabaseSchema dbSchema;
- private final HwvtepConnectionInstance key;
+ protected final HwvtepConnectionInstance key;
+ protected Set<Pair<Class<? extends Identifiable>, InstanceIdentifier>> addedKeys = new HashSet<>();
+ protected Set<Pair<Class<? extends Identifiable>, InstanceIdentifier>> deletedKeys = new HashSet<>();
+ protected HwvtepDeviceInfo deviceInfo;
+
public TableUpdates getUpdates() {
return updates;
this.updates = updates;
this.dbSchema = dbSchema;
this.key = key;
+ if (key != null) {
+ this.deviceInfo = key.getDeviceInfo();
+ }
}
public HwvtepDeviceInfo getDeviceInfo() {
}
void addToDeviceUpdate(TransactionType transactionType, Object element) {
- key.getDeviceInfo().addToDeviceUpdate(transactionType, element);
+ deviceInfo.addToDeviceUpdate(transactionType, element);
+ }
+
+ public void clearDeviceOpUUID(Class<? extends Identifiable> cls, InstanceIdentifier iid, UUID uuid) {
+ deviceInfo.clearDeviceOperUUID(cls, iid, uuid);
+ }
+
+ public void addToDeleteTx(ReadWriteTransaction tx, Class<? extends Identifiable> cls, InstanceIdentifier iid,
+ UUID uuid) {
+ if (deviceInfo.isAvailableInOperDs(cls, iid)) {
+ tx.delete(LogicalDatastoreType.OPERATIONAL, iid);
+ }
+ deletedKeys.add(Pair.of(cls, iid));
+ clearDeviceOpUUID(cls, iid, uuid);
+ }
+
+ public void addToUpdateTx(Class<? extends Identifiable> cls, InstanceIdentifier iid, UUID uuid,
+ Object southboundData) {
+ addedKeys.add(Pair.of(cls, iid));
+ deviceInfo.updateDeviceOperData(cls, iid, uuid, southboundData);
+ }
+
+ public void onSuccess() {
+ addedKeys.stream().forEach(pair -> {
+ deviceInfo.markAvailableInOperDs(pair.getLeft(), pair.getRight());
+ });
+ deletedKeys.stream().forEach(pair -> {
+ deviceInfo.clearOperDsAvailability(pair.getLeft(), pair.getRight());
+ deviceInfo.clearDeviceOperData(pair.getLeft(), pair.getRight());
+ });
+ }
+
+ public void onFailure() {
+ addedKeys.stream().forEach(pair -> {
+ LOG.error("Failed to add {}", pair.getLeft().getSimpleName());
+ });
+ deletedKeys.stream().forEach(pair -> {
+ LOG.error("Failed to delete {}", pair.getLeft().getSimpleName());
+ });
}
}
import java.util.Collection;
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.lib.message.TableUpdates;
import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
.augmentation(HwvtepGlobalAugmentation.class)
.child(LogicalSwitches.class, new LogicalSwitchesKey(new HwvtepNodeName(logicalSwitch.getName())));
// TODO Delete any references
- transaction.delete(LogicalDatastoreType.OPERATIONAL, switchIid);
- getOvsdbConnectionInstance().getDeviceInfo().clearDeviceOperData(LogicalSwitches.class, switchIid);
+ addToDeleteTx(transaction, LogicalSwitches.class, switchIid, logicalSwitch.getUuid());
addToDeviceUpdate(TransactionType.DELETE, logicalSwitch);
}
}
InstanceIdentifier<LogicalSwitches> switchIid = getOvsdbConnectionInstance().getInstanceIdentifier()
.augmentation(HwvtepGlobalAugmentation.class)
.child(LogicalSwitches.class, new LogicalSwitchesKey(new HwvtepNodeName(logicalSwitch.getName())));
- getOvsdbConnectionInstance().getDeviceInfo().updateDeviceOperData(LogicalSwitches.class, switchIid,
- logicalSwitch.getUuid(), logicalSwitch);
+ addToUpdateTx(LogicalSwitches.class, switchIid, logicalSwitch.getUuid(), logicalSwitch);
addToDeviceUpdate(TransactionType.ADD, logicalSwitch);
// TODO: Delete entries that are no longer needed
}
import java.util.Collection;
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.HwvtepSouthboundConstants;
import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
.augmentation(HwvtepGlobalAugmentation.class).child(LocalUcastMacs.class,
new LocalUcastMacsKey(getLogicalSwitchRef(lum.getLogicalSwitchColumn().getData()),
getMacAddress(lum.getMac())));
- transaction.delete(LogicalDatastoreType.OPERATIONAL, lumId);
+ addToDeleteTx(transaction, LocalUcastMacs.class, lumId, lum.getUuid());
} else {
LOG.debug("Failed to delete UcastMacLocal entry {}", lum.getUuid());
}
.augmentation(HwvtepGlobalAugmentation.class).child(RemoteUcastMacs.class,
new RemoteUcastMacsKey(getLogicalSwitchRef(rum.getLogicalSwitchColumn().getData()),
getMacAddress(rum.getMac())));
- transaction.delete(LogicalDatastoreType.OPERATIONAL, rumId);
- getOvsdbConnectionInstance().getDeviceInfo().clearDeviceOperData(RemoteUcastMacs.class, rumId);
+ addToDeleteTx(transaction, RemoteUcastMacs.class, rumId, rum.getUuid());
} else {
LOG.debug("Failed to delete UcastMacRemote entry {}", rum.getUuid());
}
.child(LocalMcastMacs.class,
new LocalMcastMacsKey(getLogicalSwitchRef(lmm.getLogicalSwitchColumn().getData()),
getMacAddress(lmm.getMac())));
- transaction.delete(LogicalDatastoreType.OPERATIONAL, lumId);
+ addToDeleteTx(transaction, LocalMcastMacs.class, lumId, lmm.getUuid());
} else {
LOG.debug("Failed to delete McastMacLocal entry {}", lmm.getUuid());
}
.child(RemoteMcastMacs.class,
new RemoteMcastMacsKey(getLogicalSwitchRef(rmm.getLogicalSwitchColumn().getData()),
getMacAddress(rmm.getMac())));
- transaction.delete(LogicalDatastoreType.OPERATIONAL, lumId);
+ addToDeleteTx(transaction, RemoteMcastMacs.class, lumId, rmm.getUuid());
getOvsdbConnectionInstance().getDeviceInfo().clearDeviceOperData(RemoteMcastMacs.class, lumId);
} else {
LOG.debug("Failed to delete McastMacRemote entry {}", rmm.getUuid());
connectionNode.addAugmentation(HwvtepGlobalAugmentation.class, hgAugmentationBuilder.build());
InstanceIdentifier<RemoteMcastMacs> macIid = getOvsdbConnectionInstance().getInstanceIdentifier()
.augmentation(HwvtepGlobalAugmentation.class).child(RemoteMcastMacs.class, mac.key());
- getOvsdbConnectionInstance().getDeviceInfo().updateDeviceOperData(RemoteMcastMacs.class,
- macIid, macRemote.getUuid(), macRemote);
+ addToUpdateTx(RemoteMcastMacs.class, macIid, macRemote.getUuid(), macRemote);
return connectionNode.build();
}
import java.util.Collection;
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.HwvtepSouthboundMapper;
import org.opendaylight.ovsdb.lib.message.TableUpdates;
final InstanceIdentifier<Node> connectionIId = getOvsdbConnectionInstance().getInstanceIdentifier();
final InstanceIdentifier<TerminationPoint> nodePath = HwvtepSouthboundMapper
.createInstanceIdentifier(connectionIId, locator);
- transaction.delete(LogicalDatastoreType.OPERATIONAL, nodePath);
- getOvsdbConnectionInstance().getDeviceInfo().clearDeviceOperData(TerminationPoint.class, nodePath);
-
+ addToDeleteTx(transaction, TerminationPoint.class, nodePath, locator.getUuid());
//TODO: Check if any cleanup is required
}
}
transaction.put(LogicalDatastoreType.OPERATIONAL,
tpPath, tpBuilder.build());
}
- getOvsdbConnectionInstance().getDeviceInfo().updateDeviceOperData(
- TerminationPoint.class, tpPath, locator.getUuid(), locator);
+ addToUpdateTx(TerminationPoint.class, tpPath, locator.getUuid(), locator);
}
}
}
import java.util.Collection;
import java.util.Map;
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.HwvtepSouthboundMapper;
import org.opendaylight.ovsdb.hwvtepsouthbound.events.PortEvent;
import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalPort;
import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindings;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(),
updatedPSwitchData).child(TerminationPoint.class,
new TerminationPointKey(new TpId(portName)));
- transaction.delete(LogicalDatastoreType.OPERATIONAL, nodePath);
+ addToDeleteTx(transaction, VlanBindings.class, nodePath, port.getUuid());
addToDeviceUpdate(TransactionType.DELETE,
new PortEvent(port, nodePath.firstKeyOf(Node.class).getNodeId()));
getDeviceInfo().clearDeviceOperData(TerminationPoint.class, nodePath);
addToDeviceUpdate(TransactionType.UPDATE, new PortEvent(portUpdate, psNodeId));
}
reconcileToPort(portUpdate, tpPath);
- getDeviceInfo().updateDeviceOperData(TerminationPoint.class, tpPath,
- portUpdate.getUuid(), portUpdate);
+ addToUpdateTx(VlanBindings.class, tpPath, portUpdate.getUuid(), portUpdate);
// Update with Deleted VlanBindings
if (oldPPRows.get(portUpdateEntry.getKey()) != null
&& oldPPRows.get(portUpdateEntry.getKey()).getVlanBindingsColumn() != null) {
//switch reconciliation will take care of this port along with other ports
return;
}
- if (getDeviceInfo().getDeviceOperData(TerminationPoint.class, tpPath) != null) {
+ if (getDeviceInfo().getDeviceOperData(VlanBindings.class, tpPath) != null) {
//case of port update not new port add
return;
}
//case of individual port add , reconcile to this port
- getDeviceInfo().updateDeviceOperData(TerminationPoint.class, tpPath, portUpdate.getUuid(), portUpdate);
- HwvtepDeviceInfo.DeviceData data = getDeviceInfo().getConfigData(TerminationPoint.class, tpPath);
+ addToUpdateTx(VlanBindings.class, tpPath, portUpdate.getUuid(), portUpdate);
+ HwvtepDeviceInfo.DeviceData data = getDeviceInfo().getConfigData(VlanBindings.class, tpPath);
if (data == null || data.getData() == null) {
LOG.error("No config data present ");
} else {
addToDeviceUpdate(TransactionType.ADD,
new ReconcilePortEvent(portUpdate, tpPath.firstKeyOf(Node.class).getNodeId()));
LOG.info("addToDeviceUpdate {}", portUpdate);
- getDeviceInfo().updateDeviceOperData(TerminationPoint.class, tpPath,
+ getDeviceInfo().updateDeviceOperData(VlanBindings.class, tpPath,
portUpdate.getUuid(), portUpdate);
getDeviceInfo().scheduleTransaction((transactionBuilder) -> {
InstanceIdentifier psIid = tpPath.firstIdentifierOf(Node.class);
ucmlBuilder.setLogicalSwitchRef(new HwvtepLogicalSwitchRef(switchIid));
}
}
- return ucmlBuilder.build();
+ LocalUcastMacs ucastMacsLocal = ucmlBuilder.build();
+ InstanceIdentifier iid = key.getInstanceIdentifier().augmentation(HwvtepGlobalAugmentation.class)
+ .child(LocalUcastMacs.class, ucastMacsLocal.key());
+ addToUpdateTx(LocalUcastMacs.class, iid, ucml.getUuid(), ucastMacsLocal);
+ return ucastMacsLocal;
}
}
}
RemoteUcastMacs remoteUcastMacs = rumBuilder.build();
InstanceIdentifier<RemoteUcastMacs> macIid = getMacIid(remoteUcastMacs);
- getOvsdbConnectionInstance().getDeviceInfo().updateDeviceOperData(RemoteUcastMacs.class, macIid,
- macRemote.getUuid(), macRemote);
+ addToUpdateTx(RemoteUcastMacs.class, macIid, macRemote.getUuid(), macRemote);
return remoteUcastMacs;
}
void execute(ReadWriteTransaction transaction);
+ default void onSuccess() {
+ }
+
+ default void onFailure() {
+ }
+
/**
* Sets the result future of the executed/submitted transaction.
*/