package org.opendaylight.ovsdb.hwvtepsouthbound;
+import com.google.common.collect.Sets;
import org.opendaylight.ovsdb.hwvtepsouthbound.transact.DependencyQueue;
import org.opendaylight.ovsdb.hwvtepsouthbound.transact.DependentJob;
import org.opendaylight.ovsdb.hwvtepsouthbound.transact.TransactCommand;
import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalLocator;
import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
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.RemoteMcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
+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;
+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 java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/*
private final UUID uuid;
private final Object data;
private final DeviceDataStatus status;
+ private long intransitTimeStamp;
DeviceData(InstanceIdentifier key, UUID uuid, Object data, DeviceDataStatus status) {
this.data = data;
this.key = key;
this.status = status;
this.uuid = uuid;
+ if (status == DeviceDataStatus.IN_TRANSIT) {
+ intransitTimeStamp = System.currentTimeMillis();
+ }
}
public Object getData() {
public UUID getUuid() {
return uuid;
}
+
+ public InstanceIdentifier getKey() {
+ return key;
+ }
+
+ public boolean isIntransitTimeExpired() {
+ return System.currentTimeMillis()
+ > intransitTimeStamp + HwvtepSouthboundConstants.IN_TRANSIT_STATE_EXPIRY_TIME_MILLIS;
+ }
+
+ public boolean isInTransitState() {
+ return status == DeviceDataStatus.IN_TRANSIT;
+ }
}
- //TODO remove this
+ private Map<InstanceIdentifier, Set<InstanceIdentifier>> tepIdReferences;
+ private Map<InstanceIdentifier<LogicalSwitches>, Map<InstanceIdentifier<RemoteUcastMacs>, RemoteUcastMacs>> logicalSwitchVsUcasts;
+ private Map<InstanceIdentifier<LogicalSwitches>, Map<InstanceIdentifier<RemoteMcastMacs>, RemoteMcastMacs>> logicalSwitchVsMcasts;
private Map<UUID, LogicalSwitch> logicalSwitches = null;
private Map<UUID, PhysicalSwitch> physicalSwitches = null;
private Map<UUID, PhysicalLocator> physicalLocators = null;
public HwvtepDeviceInfo(HwvtepConnectionInstance hwvtepConnectionInstance) {
this.connectionInstance = hwvtepConnectionInstance;
- this.logicalSwitches = new HashMap<>();
- this.physicalSwitches = new HashMap<>();
- this.physicalLocators = new HashMap<>();
- this.mapTunnelToPhysicalSwitch = new HashMap<>();
+ this.logicalSwitches = new ConcurrentHashMap<>();
+ this.physicalSwitches = new ConcurrentHashMap<>();
+ this.physicalLocators = new ConcurrentHashMap<>();
+ this.mapTunnelToPhysicalSwitch = new ConcurrentHashMap<>();
+ this.tepIdReferences = new ConcurrentHashMap<>();
+ this.logicalSwitchVsUcasts = new ConcurrentHashMap<>();
+ this.logicalSwitchVsMcasts = new ConcurrentHashMap<>();
this.dependencyQueue = new DependencyQueue(this);
}
}
public Map<UUID, PhysicalLocator> getPhysicalLocators() {
- Map<UUID, Object> locators = uuidVsData.get(LogicalSwitches.class);
+ Map<UUID, Object> locators = uuidVsData.get(TerminationPoint.class);
Map<UUID, PhysicalLocator> result = new HashMap<>();
if (locators != null) {
for (Map.Entry<UUID, Object> entry : locators.entrySet()) {
}
public Object getConfigData(Class<? extends Identifiable> cls, InstanceIdentifier key) {
- return HwvtepSouthboundUtil.getData(configKeyVsData, cls, key);
+ DeviceData deviceData = HwvtepSouthboundUtil.getData(configKeyVsData, cls, key);
+ if (deviceData != null) {
+ return deviceData.getData();
+ }
+ return null;
}
public void clearConfigData(Class<? extends Identifiable> cls, InstanceIdentifier key) {
dependencyQueue.processReadyJobsFromConfigQueue(connectionInstance);
}
- public void onOperDataAvailable() {
+ public synchronized void onOperDataAvailable() {
dependencyQueue.processReadyJobsFromOpQueue(connectionInstance);
}
dependencyQueue.submit(() -> connectionInstance.transact(transactCommand));
}
- public void clearInTransitData() {
- //TODO restore old data
- for (Map<InstanceIdentifier, DeviceData> map : opKeyVsData.values()) {
- Iterator<Map.Entry<InstanceIdentifier, DeviceData>> iterator = map.entrySet().iterator();
- while ( iterator.hasNext() ) {
- Map.Entry<InstanceIdentifier, DeviceData> entry = iterator.next();
- if (entry.getValue().getStatus() == DeviceDataStatus.IN_TRANSIT) {
- iterator.remove();
+ public void clearDeviceOperData(Class<? extends Identifiable> cls) {
+ Map<InstanceIdentifier, DeviceData> iids = opKeyVsData.get(cls);
+ if (iids != null && !iids.isEmpty()) {
+ Iterator<Map.Entry<InstanceIdentifier, DeviceData>> it = iids.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry<InstanceIdentifier, DeviceData> entry = it.next();
+ DeviceData deviceData = entry.getValue();
+ if (deviceData != null && deviceData.getStatus() != DeviceDataStatus.IN_TRANSIT) {
+ it.remove();
}
}
}
- onOperDataAvailable();
+ }
+
+ public void clearInTransit(Class<? extends Identifiable> cls, InstanceIdentifier key) {
+ DeviceData deviceData = getDeviceOperData(cls, key);
+ if (deviceData != null && deviceData.isInTransitState()) {
+ if (deviceData.getData() != null) {
+ HwvtepSouthboundUtil.updateData(opKeyVsData, cls, key,
+ new DeviceData(key, deviceData.getUuid(), deviceData.getData(), DeviceDataStatus.AVAILABLE));
+ } else {
+ clearDeviceOperData(cls, key);
+ }
+ }
+ }
+
+ public Map<InstanceIdentifier, DeviceData> getDeviceOperData(Class<? extends Identifiable> cls) {
+ return opKeyVsData.get(cls);
+ }
+
+ public void incRefCount(InstanceIdentifier reference, InstanceIdentifier tep) {
+ if (reference == null || tep == null) {
+ return;
+ }
+ tepIdReferences.computeIfAbsent(tep, (tepId) -> Sets.newConcurrentHashSet());
+ tepIdReferences.get(tep).add(reference);
+ }
+
+ public int getRefCount(InstanceIdentifier tep) {
+ return tepIdReferences.containsKey(tep) ? tepIdReferences.get(tep).size() : 0;
+ }
+
+ public Set<InstanceIdentifier> getRefCounts(InstanceIdentifier tep) {
+ return tepIdReferences.get(tep);
+ }
+
+ public void decRefCount(InstanceIdentifier reference, InstanceIdentifier tep) {
+ if (reference == null || tep == null || !tepIdReferences.containsKey(tep)) {
+ return;
+ }
+ //synchronize to make sure that no two parallel deletes puts the key in transit state twice
+ synchronized (this) {
+ boolean removed = tepIdReferences.get(tep).remove(reference);
+ if (removed && tepIdReferences.get(tep).isEmpty()) {
+ LOG.debug("Marking the termination point as in transit ref count zero {} ", tep);
+ markKeyAsInTransit(TerminationPoint.class, tep);
+ }
+ }
+ }
+
+ public void clearLogicalSwitchRefs(InstanceIdentifier<LogicalSwitches> logicalSwitchKey) {
+ Map<InstanceIdentifier<RemoteMcastMacs>, RemoteMcastMacs> mcasts = logicalSwitchVsMcasts.get(logicalSwitchKey);
+ if (mcasts != null ) {
+ mcasts.entrySet().forEach( (entry) -> removeRemoteMcast(logicalSwitchKey, entry.getKey()));
+ }
+ Map<InstanceIdentifier<RemoteUcastMacs>, RemoteUcastMacs> ucasts = logicalSwitchVsUcasts.get(logicalSwitchKey);
+ if (ucasts != null ) {
+ ucasts.entrySet().forEach( (entry) -> removeRemoteUcast(logicalSwitchKey, entry.getKey()));
+ }
+ markKeyAsInTransit(LogicalSwitches.class, logicalSwitchKey);
+ }
+
+ public void updateRemoteMcast(InstanceIdentifier<LogicalSwitches> lsIid,
+ InstanceIdentifier<RemoteMcastMacs> mcastIid,
+ RemoteMcastMacs mac) {
+ logicalSwitchVsMcasts.computeIfAbsent(lsIid, (lsKey) -> new ConcurrentHashMap<>());
+ logicalSwitchVsMcasts.get(lsIid).put(mcastIid, mac);
+ if (mac.getLocatorSet() != null) {
+ mac.getLocatorSet().forEach( (iid) -> incRefCount(mcastIid, iid.getLocatorRef().getValue()));
+ }
+ }
+
+ public void updateRemoteUcast(InstanceIdentifier<LogicalSwitches> lsIid,
+ InstanceIdentifier<RemoteUcastMacs> ucastIid,
+ RemoteUcastMacs mac) {
+ logicalSwitchVsUcasts.computeIfAbsent(lsIid, (lsKey) -> new ConcurrentHashMap<>());
+ logicalSwitchVsUcasts.get(lsIid).put(ucastIid, mac);
+ incRefCount(ucastIid, mac.getLocatorRef().getValue());
+ }
+
+ public void removeRemoteMcast(InstanceIdentifier<LogicalSwitches> lsIid, InstanceIdentifier<RemoteMcastMacs> mcastIid) {
+ if (!logicalSwitchVsMcasts.containsKey(lsIid)) {
+ return;
+ }
+ RemoteMcastMacs mac = logicalSwitchVsMcasts.get(lsIid).remove(mcastIid);
+ if (mac != null && mac.getLocatorSet() != null) {
+ mac.getLocatorSet().forEach((iid) -> decRefCount(mcastIid, iid.getLocatorRef().getValue()));
+ }
+ markKeyAsInTransit(RemoteMcastMacs.class, mcastIid);
+ }
+
+ public void removeRemoteUcast(InstanceIdentifier<LogicalSwitches> lsIid,
+ InstanceIdentifier<RemoteUcastMacs> ucastIid) {
+ if (!logicalSwitchVsUcasts.containsKey(lsIid)) {
+ return;
+ }
+ RemoteUcastMacs mac = logicalSwitchVsUcasts.get(lsIid).remove(ucastIid);
+ if (mac != null) {
+ decRefCount(ucastIid, mac.getLocatorRef().getValue());
+ }
+ markKeyAsInTransit(RemoteUcastMacs.class, ucastIid);
+ }
+
+ public HwvtepConnectionInstance getConnectionInstance() {
+ return connectionInstance;
}
}
= new ImmutableMap.Builder<String,String>()
.put("Logical_Binding_Stats", "Update callback registration for Logical_Binding_Stats Table is skipped")
.build();
-
+ public static final String VERSION_COLUMN = "_version";
public static final ImmutableMap<String,List<String>> SKIP_COLUMN_FROM_HWVTEP_TABLE
= new ImmutableMap.Builder<String,List<String>>()
- .put("Manager", Arrays.asList("_version", "status"))
+ .put("Manager", Arrays.asList(VERSION_COLUMN, "status"))
.build();
- public static final int WAITING_QUEUE_CAPACITY = 1000;
- public static final long WAITING_JOB_EXPIRY_TIME_MILLIS = 90000;
+ public static final int WAITING_QUEUE_CAPACITY = Integer.getInteger("hwvtep.wait.queue.capacity", 1000);
+ public static final long WAITING_JOB_EXPIRY_TIME_MILLIS = Integer.getInteger(
+ "hwvtep.wait.job.expiry.time.millis", 90000);
+ public static final long IN_TRANSIT_STATE_EXPIRY_TIME_MILLIS = Integer.getInteger(
+ "hwvtep.intransit.job.expiry.time.millis", 10000);
+ public static final long IN_TRANSIT_STATE_CHECK_PERIOD_MILLIS = Integer.getInteger(
+ "hwvtep.intransit.job.check.period.millis", 30000);
}
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
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.HwvtepDeviceInfo;
import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
import org.opendaylight.ovsdb.lib.notation.UUID;
import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
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;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
import org.opendaylight.yangtools.yang.binding.Augmentation;
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 AbstractTransactCommand<T extends Identifiable, Aug extends Augmentation<Node>> implements TransactCommand<T> {
- private HwvtepOperationalState operationalState;
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractTransactCommand.class);
+ protected static final UUID TXUUID = new UUID("TXUUID");
+ protected ThreadLocal<HwvtepOperationalState> threadLocalOperationalState = new ThreadLocal<>();
+ protected ThreadLocal<TransactionBuilder> threadLocalDeviceTransaction = new ThreadLocal<>();
private Collection<DataTreeModification<Node>> changes;
+ protected Map<TransactionBuilder, List<MdsalUpdate<T>>> updates = new ConcurrentHashMap<>();
protected AbstractTransactCommand() {
// NO OP
}
public AbstractTransactCommand(HwvtepOperationalState state, Collection<DataTreeModification<Node>> changes) {
- this.operationalState = state;
+ this.threadLocalOperationalState.set(state);
this.changes = changes;
}
public HwvtepOperationalState getOperationalState() {
- return operationalState;
+ return threadLocalOperationalState.get();
}
public Collection<DataTreeModification<Node>> getChanges() {
}
void updateCurrentTxDeleteData(Class<? extends Identifiable> cls, InstanceIdentifier key, T data) {
- operationalState.updateCurrentTxDeleteData(cls, key);
- operationalState.getDeviceInfo().clearConfigData(cls, key);
+ getOperationalState().getDeviceInfo().markKeyAsInTransit(cls, key);
+ addToUpdates(key, data);
+ getOperationalState().getDeviceInfo().clearConfigData(cls, key);
}
- void updateCurrentTxData(Class<? extends Identifiable> cls, InstanceIdentifier key, UUID uuid, Object data) {
- operationalState.updateCurrentTxData(cls, key, uuid);
- operationalState.getDeviceInfo().updateConfigData(cls, key, data);
+ void updateCurrentTxData(Class<? extends Identifiable> cls, InstanceIdentifier key, UUID uuid, T data) {
+ getOperationalState().getDeviceInfo().markKeyAsInTransit(cls, key);
+ addToUpdates(key, data);
+ getOperationalState().getDeviceInfo().updateConfigData(cls, key, data);
+ }
+
+ void addToUpdates(InstanceIdentifier key, T data) {
+ T oldData = null;
+ Type type = getClass().getGenericSuperclass();
+ Type classType = ((ParameterizedType) type).getActualTypeArguments()[0];
+ if (getDeviceInfo().getConfigData((Class<? extends Identifiable>) classType, key) != null) {
+ oldData = (T) getDeviceInfo().getConfigData((Class<? extends Identifiable>) classType, key);
+ }
+ updates.putIfAbsent(getDeviceTransaction(), new ArrayList<MdsalUpdate<T>>());
+ updates.get(getDeviceTransaction()).add(new MdsalUpdate<T>(key, data, oldData));
}
void processDependencies(final UnMetDependencyGetter<T> unMetDependencyGetter,
final InstanceIdentifier key,
final T data, final Object... extraData) {
- HwvtepDeviceInfo deviceInfo = operationalState.getDeviceInfo();
- Map inTransitDependencies = Collections.EMPTY_MAP;
- Map confingDependencies = Collections.EMPTY_MAP;
+ this.threadLocalDeviceTransaction.set(transaction);
+ HwvtepDeviceInfo deviceInfo = getOperationalState().getDeviceInfo();
+ Map inTransitDependencies = new HashMap<>();
+ Map confingDependencies = new HashMap<>();
if (!isRemoveCommand() && unMetDependencyGetter != null) {
- inTransitDependencies = unMetDependencyGetter.getInTransitDependencies(operationalState, data);
- confingDependencies = unMetDependencyGetter.getUnMetConfigDependencies(operationalState, data);
+ inTransitDependencies = unMetDependencyGetter.getInTransitDependencies(getOperationalState(), data);
+ confingDependencies = unMetDependencyGetter.getUnMetConfigDependencies(getOperationalState(), data);
//we can skip the config termination point dependency as we can create them in device as part of this tx
confingDependencies.remove(TerminationPoint.class);
}
if (HwvtepSouthboundUtil.isEmptyMap(confingDependencies) && HwvtepSouthboundUtil.isEmptyMap(inTransitDependencies)) {
doDeviceTransaction(transaction, nodeIid, data, key, extraData);
- updateCurrentTxData((Class<? extends Identifiable>) classType, key, new UUID("uuid"), data);
+ if (isRemoveCommand()) {
+ getDeviceInfo().clearConfigData((Class<? extends Identifiable>) classType, key);
+ } else {
+ getDeviceInfo().updateConfigData((Class<? extends Identifiable>) classType, key, data);
+ }
}
if (!HwvtepSouthboundUtil.isEmptyMap(confingDependencies)) {
DependentJob<T> configWaitingJob = new DependentJob.ConfigWaitingJob(
@Override
public void onDependencyResolved(HwvtepOperationalState operationalState,
TransactionBuilder transactionBuilder) {
- AbstractTransactCommand.this.operationalState = operationalState;
+ AbstractTransactCommand.this.threadLocalOperationalState.set(operationalState);
+ AbstractTransactCommand.this.threadLocalDeviceTransaction.set(transactionBuilder);
onConfigUpdate(transactionBuilder, nodeIid, data, key, extraData);
}
+
+ public void onFailure() {
+ AbstractTransactCommand.this.onFailure(getDeviceTransaction());
+ }
+
+ public void onSuccess() {
+ AbstractTransactCommand.this.onSuccess(getDeviceTransaction());
+ }
};
deviceInfo.addJobToQueue(configWaitingJob);
}
@Override
public void onDependencyResolved(HwvtepOperationalState operationalState,
TransactionBuilder transactionBuilder) {
- AbstractTransactCommand.this.operationalState = operationalState;
- onConfigUpdate(transactionBuilder, nodeIid, data, key, extraData);
+ //data would have got deleted by , push the data only if it is still in configds
+ threadLocalOperationalState.set(operationalState);
+ threadLocalDeviceTransaction.set(transactionBuilder);
+ T data = (T)new MdsalUtils(operationalState.getDataBroker()).read(
+ LogicalDatastoreType.CONFIGURATION, key);
+ if (data != null) {
+ onConfigUpdate(transactionBuilder, nodeIid, data, key, extraData);
+ } else {
+ LOG.warn("Skipping add of key: {} as it is not present txId: {}", key);
+ }
+ }
+
+ public void onFailure() {
+ AbstractTransactCommand.this.onFailure(getDeviceTransaction());
+ }
+
+ public void onSuccess() {
+ AbstractTransactCommand.this.onSuccess(getDeviceTransaction());
}
};
deviceInfo.addJobToQueue(opWaitingJob);
final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
Class<? extends Identifiable> classType = (Class<? extends Identifiable>) getClassType();
List<T> removed;
- if (operationalState.isInReconciliation()) {
+ if (getOperationalState().isInReconciliation()) {
removed = getRemoved(change);
} else {
- removed = (List<T>) operationalState.getDeletedData(key, classType);
+ removed = (List<T>) getOperationalState().getDeletedData(key, classType);
}
removed.addAll(getCascadeDeleteData(change));
result.put(key, removed);
InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
Class<? extends Identifiable> classType = (Class<? extends Identifiable>) getClassType();
List<T> updated = null;
- if (operationalState.isInReconciliation()) {
+ if (getOperationalState().isInReconciliation()) {
updated = getUpdated(change);
} else {
- updated = (List<T>) operationalState.getUpdatedData(key, classType);
+ updated = (List<T>) getOperationalState().getUpdatedData(key, classType);
}
result.put(key, updated);
}
protected boolean isRemoveCommand() {
return false;
}
+
+ protected HwvtepDeviceInfo getDeviceInfo() {
+ return getOperationalState().getDeviceInfo();
+ }
+
+ protected TransactionBuilder getDeviceTransaction() {
+ return threadLocalDeviceTransaction.get();
+ }
+
+ public void onSuccess(TransactionBuilder deviceTransaction) {
+ if (deviceTransaction == null || !updates.containsKey(deviceTransaction)) {
+ return;
+ }
+ onCommandSucceeded();
+ }
+
+ public void onFailure(TransactionBuilder deviceTransaction) {
+ if (deviceTransaction == null || !updates.containsKey(deviceTransaction)) {
+ return;
+ }
+ for (MdsalUpdate mdsalUpdate : updates.get(deviceTransaction)) {
+ getDeviceInfo().clearInTransit((Class<? extends Identifiable>)mdsalUpdate.getClass(), mdsalUpdate.getKey());
+ }
+ onCommandFailed();
+ }
+
+ protected void onCommandSucceeded() {
+ }
+
+ protected void onCommandFailed() {
+ }
}
public void setInReconciliation(boolean inReconciliation) {
this.inReconciliation = inReconciliation;
}
+
+ public DataBroker getDataBroker() {
+ return db;
+ }
+
+
+ public void clearIntransitKeys() {
+ currentTxUUIDs.forEach( (cls, map) -> {
+ map.forEach( (iid, uuid) -> deviceInfo.clearInTransit(cls, iid));
+ });
+ currentTxDeletedKeys.forEach( (cls, map) -> {
+ map.forEach( (iid, val) -> deviceInfo.clearInTransit(cls, iid));
+ });
+ currentTxUUIDs.clear();
+ currentTxDeletedKeys.clear();
+ deviceInfo.onOperDataAvailable();
+ }
}
import com.google.common.base.Optional;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
import org.opendaylight.ovsdb.lib.notation.UUID;
import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
if (removed != null) {
for (Entry<InstanceIdentifier<Node>, List<LogicalRouters>> created: removed.entrySet()) {
if (!HwvtepSouthboundUtil.isEmpty(created.getValue())) {
- for (LogicalRouters lRouter : created.getValue()) {
- InstanceIdentifier<LogicalRouters> lsKey = created.getKey().augmentation(
- HwvtepGlobalAugmentation.class).child(LogicalRouters.class, lRouter.getKey());
- updateCurrentTxDeleteData(LogicalRouters.class, lsKey, lRouter);
- }
getOperationalState().getDeviceInfo().scheduleTransaction(new TransactCommand() {
@Override
public void execute(TransactionBuilder transactionBuilder) {
+ HwvtepConnectionInstance connectionInstance = getDeviceInfo().getConnectionInstance();
+ HwvtepOperationalState operState = new HwvtepOperationalState(
+ connectionInstance.getDataBroker(), connectionInstance, Collections.EMPTY_LIST);
+ threadLocalOperationalState.set(operState);
+ threadLocalDeviceTransaction.set(transactionBuilder);
LOG.debug("Running delete logical router in seperate tx {}", created.getKey());
removeLogicalRouter(transactionBuilder, created.getKey(), created.getValue());
}
+
@Override
- public void onConfigUpdate(TransactionBuilder transaction, InstanceIdentifier nodeIid,
- Identifiable data, InstanceIdentifier key, Object... extraData) {
+ public void onSuccess(TransactionBuilder deviceTransaction) {
+ LogicalRouterRemoveCommand.this.onSuccess(deviceTransaction);
}
@Override
- public void doDeviceTransaction(TransactionBuilder transaction, InstanceIdentifier nodeIid,
- Identifiable data, InstanceIdentifier key, Object... extraData) {
+ public void onFailure(TransactionBuilder deviceTransaction) {
+ LogicalRouterRemoveCommand.this.onFailure(deviceTransaction);
}
});
}
import static org.opendaylight.ovsdb.lib.operations.Operations.op;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+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;
if (removeds != null) {
for (Entry<InstanceIdentifier<Node>, List<LogicalSwitches>> created: removeds.entrySet()) {
if (!HwvtepSouthboundUtil.isEmpty(created.getValue())) {
- for (LogicalSwitches lswitch : created.getValue()) {
- InstanceIdentifier<LogicalSwitches> lsKey = created.getKey().augmentation(
- HwvtepGlobalAugmentation.class).child(LogicalSwitches.class, lswitch.getKey());
- updateCurrentTxDeleteData(LogicalSwitches.class, lsKey, lswitch);
- }
- getOperationalState().getDeviceInfo().scheduleTransaction(new TransactCommand() {
+ HwvtepConnectionInstance connectionInstance = getDeviceInfo().getConnectionInstance();
+ getDeviceInfo().scheduleTransaction(new TransactCommand() {
@Override
public void execute(TransactionBuilder transactionBuilder) {
+ HwvtepOperationalState operState = new HwvtepOperationalState(
+ connectionInstance.getDataBroker(), connectionInstance, Collections.EMPTY_LIST);
+ threadLocalOperationalState.set(operState);
+ threadLocalDeviceTransaction.set(transactionBuilder);
LOG.debug("Running delete logical switch in seperate tx {}", created.getKey());
removeLogicalSwitch(transactionBuilder, created.getKey(), created.getValue());
}
@Override
- public void onConfigUpdate(TransactionBuilder transaction, InstanceIdentifier nodeIid,
- Identifiable data, InstanceIdentifier key, Object... extraData) {
+ public void onSuccess(TransactionBuilder deviceTransaction) {
+ LogicalSwitchRemoveCommand.this.onSuccess(deviceTransaction);
}
@Override
- public void doDeviceTransaction(TransactionBuilder transaction, InstanceIdentifier nodeIid,
- Identifiable data, InstanceIdentifier key, Object... extraData) {
+ public void onFailure(TransactionBuilder deviceTransaction) {
+ LogicalSwitchRemoveCommand.this.onFailure(deviceTransaction);
}
});
}
McastMacsLocal.class, null);
transaction.add(op.delete(mcastMacsLocal.getSchema())
.where(mcastMacsLocal.getLogicalSwitchColumn().getSchema().opEqual(logicalSwitchUuid)).build());
- getOperationalState().getDeviceInfo().markKeyAsInTransit(RemoteMcastMacs.class, lsKey);
+ updateCurrentTxDeleteData(LogicalSwitches.class, lsKey, lswitch);
} else {
LOG.warn("Unable to delete logical switch {} because it was not found in the operational store",
lswitch.getHwvtepNodeName().getValue());
protected boolean isRemoveCommand() {
return true;
}
+
+ @Override
+ public void onCommandSucceeded() {
+ if (getDeviceTransaction() == null || !updates.containsKey(getDeviceTransaction())) {
+ return;
+ }
+ for (MdsalUpdate mdsalUpdate : updates.get(getDeviceTransaction())) {
+ getDeviceInfo().clearLogicalSwitchRefs((InstanceIdentifier<LogicalSwitches>) mdsalUpdate.getKey());
+ }
+ }
}
import java.util.Set;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepDeviceInfo;
import org.opendaylight.ovsdb.lib.notation.UUID;
import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
}
}
- private void updateLogicalSwitch(final TransactionBuilder transaction,
+ public void updateLogicalSwitch(final TransactionBuilder transaction,
final InstanceIdentifier<Node> nodeIid, final List<LogicalSwitches> lswitchList) {
for (LogicalSwitches lswitch: lswitchList) {
InstanceIdentifier<LogicalSwitches> lsKey = nodeIid.augmentation(HwvtepGlobalAugmentation.class).
final InstanceIdentifier lsKey,
final Object... extraData) {
LOG.debug("Creating logical switch named: {}", lswitch.getHwvtepNodeName());
- Optional<LogicalSwitches> operationalSwitchOptional =
- getOperationalState().getLogicalSwitches(instanceIdentifier, lswitch.getKey());
+ HwvtepDeviceInfo.DeviceData operationalSwitchOptional =
+ getDeviceInfo().getDeviceOperData(LogicalSwitches.class, lsKey);
LogicalSwitch logicalSwitch = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), LogicalSwitch.class);
setDescription(logicalSwitch, lswitch);
setTunnelKey(logicalSwitch, lswitch);
setReplicationMode(logicalSwitch, lswitch);
- if (!operationalSwitchOptional.isPresent()) {
- setName(logicalSwitch, lswitch, operationalSwitchOptional);
+ if (operationalSwitchOptional == null) {
+ setName(logicalSwitch, lswitch);
LOG.trace("execute: creating LogicalSwitch entry: {}", logicalSwitch);
transaction.add(op.insert(logicalSwitch).withId(TransactUtils.getLogicalSwitchId(lswitch)));
transaction.add(op.comment("Logical Switch: Creating " + lswitch.getHwvtepNodeName().getValue()));
UUID lsUuid = new UUID(TransactUtils.getLogicalSwitchId(lswitch));
- getOperationalState().getDeviceInfo().markKeyAsInTransit(RemoteMcastMacs.class, lsKey);
+ updateCurrentTxData(LogicalSwitches.class, lsKey, lsUuid, lswitch);
} else {
- LogicalSwitches updatedLSwitch = operationalSwitchOptional.get();
- String existingLogicalSwitchName = updatedLSwitch.getHwvtepNodeName().getValue();
+ String existingLogicalSwitchName = lswitch.getHwvtepNodeName().getValue();
// Name is immutable, and so we *can't* update it. So we use extraBridge for the schema stuff
LogicalSwitch extraLogicalSwitch = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), LogicalSwitch.class);
extraLogicalSwitch.setName("");
}
}
- private void setName(LogicalSwitch logicalSwitch, LogicalSwitches inputSwitch,
- Optional<LogicalSwitches> inputSwitchOptional) {
+ private void setName(LogicalSwitch logicalSwitch, LogicalSwitches inputSwitch) {
if (inputSwitch.getHwvtepNodeName() != null) {
logicalSwitch.setName(inputSwitch.getHwvtepNodeName().getValue());
- } else if (inputSwitchOptional.isPresent() && inputSwitchOptional.get().getHwvtepNodeName() != null) {
- logicalSwitch.setName(inputSwitchOptional.get().getHwvtepNodeName().getValue());
}
}
import java.util.Objects;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepDeviceInfo;
import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
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.McastMacsRemote;
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.hwvtep.global.attributes.LogicalSwitches;
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.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Optional;
-
public class McastMacsRemoteRemoveCommand extends AbstractTransactCommand<RemoteMcastMacs, HwvtepGlobalAugmentation> {
private static final Logger LOG = LoggerFactory.getLogger(McastMacsRemoteRemoveCommand.class);
final InstanceIdentifier macIid,
final Object... extraData) {
LOG.debug("Removing remoteMcastMacs, mac address: {}", mac.getMacEntryKey().getValue());
- Optional<RemoteMcastMacs> operationalMacOptional =
- getOperationalState().getRemoteMcastMacs(instanceIdentifier, mac.getKey());
+ HwvtepDeviceInfo.DeviceData operationalMacOptional =
+ getDeviceInfo().getDeviceOperData(RemoteMcastMacs.class, macIid);
McastMacsRemote mcastMacsRemote = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(),
McastMacsRemote.class, null);
- if (operationalMacOptional.isPresent() && operationalMacOptional.get().getMacEntryUuid() != null) {
+ if (operationalMacOptional != null && operationalMacOptional.getUuid() != null) {
//when mac entry is deleted, its referenced locator set and locators are deleted automatically.
//TODO: locator in config DS is not deleted
- UUID macEntryUUID = new UUID(operationalMacOptional.get().getMacEntryUuid().getValue());
+ UUID macEntryUUID = operationalMacOptional.getUuid();
mcastMacsRemote.getUuidColumn().setData(macEntryUUID);
transaction.add(op.delete(mcastMacsRemote.getSchema()).
where(mcastMacsRemote.getUuidColumn().getSchema().opEqual(macEntryUUID)).build());
transaction.add(op.comment("McastMacRemote: Deleting " + mac.getMacEntryKey().getValue()));
- getOperationalState().getDeviceInfo().markKeyAsInTransit(RemoteMcastMacs.class, macIid);
+ updateCurrentTxDeleteData(RemoteMcastMacs.class, macIid, mac);
} else {
LOG.warn("Unable to delete remoteMcastMacs {} because it was not found in the operational store",
mac.getMacEntryKey().getValue());
}
- updateCurrentTxDeleteData(RemoteMcastMacs.class, macIid, mac);
}
@Override
protected boolean isRemoveCommand() {
return true;
}
+
+
+ @Override
+ public void onCommandSucceeded() {
+ //remove the refcounts of the deleted macs
+ for (MdsalUpdate mdsalUpdate : updates.get(getDeviceTransaction())) {
+ RemoteMcastMacs deletedMac = (RemoteMcastMacs) mdsalUpdate.getNewData();
+ InstanceIdentifier<RemoteMcastMacs> macIid = mdsalUpdate.getKey();
+ getDeviceInfo().removeRemoteMcast(
+ (InstanceIdentifier<LogicalSwitches>) deletedMac.getLogicalSwitchRef().getValue(), macIid);
+ }
+ }
}
package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
-import com.google.common.base.Optional;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Objects;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepDeviceInfo;
import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundConstants;
import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
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.McastMacsRemote;
-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.hwvtep.global.attributes.LogicalSwitches;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
InstanceIdentifier macKey,
Object... extraData) {
LOG.debug("Creating remoteMcastMacs, mac address: {}", mac.getMacEntryKey().getValue());
- Optional<RemoteMcastMacs> operationalMacOptional =
- getOperationalState().getRemoteMcastMacs(instanceIdentifier, mac.getKey());
+ HwvtepDeviceInfo.DeviceData operationalMacOptional =
+ getDeviceInfo().getDeviceOperData(RemoteMcastMacs.class, macKey);
McastMacsRemote mcastMacsRemote = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), McastMacsRemote.class);
setIpAddress(mcastMacsRemote, mac);
setLocatorSet(transaction, mcastMacsRemote, mac);
- setLogicalSwitch(mcastMacsRemote, mac);
- if (!operationalMacOptional.isPresent()) {
- setMac(mcastMacsRemote, mac, operationalMacOptional);
+ setLogicalSwitch(transaction, mcastMacsRemote, mac);
+ if (operationalMacOptional == null) {
+ setMac(mcastMacsRemote, mac);
LOG.trace("execute: create RemoteMcastMac entry: {}", mcastMacsRemote);
transaction.add(op.insert(mcastMacsRemote));
transaction.add(op.comment("McastMacRemote: Creating " + mac.getMacEntryKey().getValue()));
- getOperationalState().getDeviceInfo().markKeyAsInTransit(RemoteMcastMacs.class, macKey);
- } else if (operationalMacOptional.get().getMacEntryUuid() != null) {
- UUID macEntryUUID = new UUID(operationalMacOptional.get().getMacEntryUuid().getValue());
+ updateCurrentTxData(RemoteMcastMacs.class, macKey, TXUUID, mac);
+ } else if (operationalMacOptional.getUuid() != null) {
+ UUID macEntryUUID = operationalMacOptional.getUuid();
McastMacsRemote extraMac = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(),
McastMacsRemote.class, null);
extraMac.getUuidColumn().setData(macEntryUUID);
.where(extraMac.getUuidColumn().getSchema().opEqual(macEntryUUID))
.build());
transaction.add(op.comment("McastMacRemote: Updating " + macEntryUUID));
+ //add to updates so that tep ref counts can be updated upon success
+ addToUpdates(macKey, mac);
} else {
LOG.warn("Unable to update remoteMcastMacs {} because uuid not found in the operational store",
mac.getMacEntryKey().getValue());
}
}
- private void setLogicalSwitch(McastMacsRemote mcastMacsRemote, RemoteMcastMacs inputMac) {
+ private void setLogicalSwitch(final TransactionBuilder transaction, final McastMacsRemote mcastMacsRemote, final RemoteMcastMacs inputMac) {
if (inputMac.getLogicalSwitchRef() != null) {
@SuppressWarnings("unchecked")
InstanceIdentifier<LogicalSwitches> lswitchIid = (InstanceIdentifier<LogicalSwitches>) inputMac.getLogicalSwitchRef().getValue();
- Optional<LogicalSwitches> operationalSwitchOptional =
- getOperationalState().getLogicalSwitches(lswitchIid);
- if (operationalSwitchOptional.isPresent()) {
- Uuid logicalSwitchUuid = operationalSwitchOptional.get().getLogicalSwitchUuid();
- UUID logicalSwitchUUID = new UUID(logicalSwitchUuid.getValue());
- mcastMacsRemote.setLogicalSwitch(logicalSwitchUUID);
- } else {
- mcastMacsRemote.setLogicalSwitch(TransactUtils.getLogicalSwitchUUID(lswitchIid));
- }
+ mcastMacsRemote.setLogicalSwitch(TransactUtils.getLogicalSwitchUUID(transaction, getOperationalState(), lswitchIid));
}
}
}
}
- private void setMac(McastMacsRemote mcastMacsRemote, RemoteMcastMacs inputMac,
- Optional<RemoteMcastMacs> inputSwitchOptional) {
+ private void setMac(McastMacsRemote mcastMacsRemote, RemoteMcastMacs inputMac) {
if (inputMac.getMacEntryKey() != null) {
if (inputMac.getMacEntryKey().equals(HwvtepSouthboundConstants.UNKNOWN_DST_MAC)) {
mcastMacsRemote.setMac(HwvtepSouthboundConstants.UNKNOWN_DST_STRING);
} else {
mcastMacsRemote.setMac(inputMac.getMacEntryKey().getValue());
}
- } else if (inputSwitchOptional.isPresent() && inputSwitchOptional.get().getMacEntryKey() != null) {
- mcastMacsRemote.setMac(inputSwitchOptional.get().getMacEntryKey().getValue());
}
}
return locators;
}
}
+
+ private void updateLocatorRefCounts(MdsalUpdate mdsalUpdate) {
+ //decrement the refcounts from old mcast mac
+ //increment the refcounts for new mcast mac
+ RemoteMcastMacs newMac = (RemoteMcastMacs) mdsalUpdate.getNewData();
+ RemoteMcastMacs oldMac = (RemoteMcastMacs) mdsalUpdate.getOldData();
+ InstanceIdentifier<RemoteMcastMacs> macIid = mdsalUpdate.getKey();
+
+ if (oldMac != null && !oldMac.equals(newMac)) {
+ if (oldMac.getLocatorSet() != null) {
+ List<LocatorSet> removedLocators = new ArrayList(oldMac.getLocatorSet());
+ if (newMac.getLocatorSet() != null) {
+ removedLocators.removeAll(newMac.getLocatorSet());
+ }
+ removedLocators.forEach( (iid) -> getDeviceInfo().decRefCount(macIid, iid.getLocatorRef().getValue()));
+ }
+ }
+ }
+
+ @Override
+ protected void onCommandSucceeded() {
+ for (MdsalUpdate mdsalUpdate : updates.get(getDeviceTransaction())) {
+ updateLocatorRefCounts(mdsalUpdate);
+ RemoteMcastMacs mac = (RemoteMcastMacs) mdsalUpdate.getNewData();
+ InstanceIdentifier<RemoteMcastMacs> macIid = mdsalUpdate.getKey();
+ getDeviceInfo().updateRemoteMcast(
+ (InstanceIdentifier<LogicalSwitches>) mac.getLogicalSwitchRef().getValue(), macIid, mac);
+ }
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
+
+import org.opendaylight.yangtools.yang.binding.Identifiable;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class MdsalUpdate<T extends Identifiable> {
+
+ private InstanceIdentifier key;
+ private T newData;
+ private T oldData;
+
+ public MdsalUpdate(InstanceIdentifier key, T newData, T oldData) {
+ this.key = key;
+ this.newData = newData;
+ this.oldData = oldData;
+ }
+
+ public InstanceIdentifier getKey() {
+ return key;
+ }
+
+ public T getNewData() {
+ return newData;
+ }
+
+ public T getOldData() {
+ return oldData;
+ }
+}
\ No newline at end of file
if (confLocOptional.isPresent()) {
HwvtepPhysicalLocatorAugmentation locatorAugmentation =
confLocOptional.get().getAugmentation(HwvtepPhysicalLocatorAugmentation.class);
- locatorUUID = TransactUtils.createPhysicalLocator(transaction, locatorAugmentation);
+ locatorUUID = TransactUtils.createPhysicalLocator(transaction, getOperationalState(), iid);
} else {
LOG.warn("Unable to find endpoint for tunnel. Endpoint indentifier is {}", iid);
}
void execute(TransactionBuilder transaction);
- void onConfigUpdate(TransactionBuilder transaction, InstanceIdentifier<Node> nodeIid, T data,
- InstanceIdentifier key, Object... extraData);
+ default void onConfigUpdate(TransactionBuilder transaction, InstanceIdentifier<Node> nodeIid, T data,
+ InstanceIdentifier key, Object... extraData) {
+ }
- void doDeviceTransaction(TransactionBuilder transaction, InstanceIdentifier<Node> nodeIid, T data,
- InstanceIdentifier key, Object... extraData);
+ default void doDeviceTransaction(TransactionBuilder transaction, InstanceIdentifier<Node> nodeIid, T data,
+ InstanceIdentifier key, Object... extraData) {
+ }
+
+ default void onSuccess(TransactionBuilder deviceTransaction) {
+ }
+
+ default void onFailure(TransactionBuilder deviceTransaction) {
+ }
}
}
return null;
}
+
+ @Override
+ public void onFailure(TransactionBuilder deviceTransaction) {
+ commands.forEach( cmd -> cmd.onFailure(deviceTransaction));
+ operationalState.clearIntransitKeys();
+ }
+
+ @Override
+ public void onSuccess(TransactionBuilder deviceTransaction) {
+ commands.forEach( cmd -> cmd.onSuccess(deviceTransaction));
+ }
}
}
}
if (errorOccured) {
- connectionInstance.getDeviceInfo().clearInTransitData();
printError(tb);
+ command.onFailure(tb);
+ } else {
+ command.onSuccess(tb);
}
} catch (Exception e) {
LOG.warn("Transact execution exception: ", e);
import static org.opendaylight.ovsdb.lib.operations.Operations.op;
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalLocator;
import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalLocatorSet;
+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.EncapsulationTypeVxlanOverIpv4;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Optional;
-
public class TransactUtils {
private static final Logger LOG = LoggerFactory.getLogger(TransactUtils.class);
sanitizeUUID(lswitchIid.firstKeyOf(LogicalSwitches.class).getHwvtepNodeName()));
}
+ public static UUID getLogicalSwitchUUID(final TransactionBuilder transaction,
+ final HwvtepOperationalState operationalState,
+ final InstanceIdentifier<LogicalSwitches> lswitchIid) {
+ HwvtepDeviceInfo hwvtepDeviceInfo = operationalState.getDeviceInfo();
+ HwvtepDeviceInfo.DeviceData lsData = hwvtepDeviceInfo.getDeviceOperData(LogicalSwitches.class, lswitchIid);
+ if (lsData != null) {
+ if (lsData.getUuid() != null) {
+ return lsData.getUuid();
+ }
+ if (lsData.isInTransitState()) {
+ return getLogicalSwitchUUID(lswitchIid);
+ }
+ return null;
+ }
+ LogicalSwitchUpdateCommand cmd = new LogicalSwitchUpdateCommand(operationalState, Collections.EMPTY_LIST);
+ MdsalUtils mdsalUtils = new MdsalUtils(operationalState.getDataBroker());
+ LogicalSwitches ls = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, lswitchIid);
+ if (ls != null) {
+ cmd.updateLogicalSwitch(transaction, lswitchIid.firstIdentifierOf(Node.class), Lists.newArrayList(ls));
+ } else {
+ LOG.error("Could not find logical switch in config ds {}", lswitchIid);
+ return null;
+ }
+ return getLogicalSwitchUUID(lswitchIid);
+ }
+
public static String getLogicalRouterId(final LogicalRouters lrouter){
return HwvtepSouthboundConstants.LOGICALROUTER_UUID_PREFIX + sanitizeUUID(lrouter.getHwvtepNodeName());
}
import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
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.hwvtep.global.attributes.LogicalSwitches;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
transaction.add(op.delete(ucastMacsRemote.getSchema()).
where(ucastMacsRemote.getUuidColumn().getSchema().opEqual(macEntryUUID)).build());
transaction.add(op.comment("UcastMacRemote: Deleting " + mac.getMacEntryKey().getValue()));
- getOperationalState().getDeviceInfo().markKeyAsInTransit(RemoteUcastMacs.class, macKey);
+ updateCurrentTxDeleteData(RemoteUcastMacs.class, macKey, mac);
} else {
LOG.warn("Unable to delete remoteUcastMacs {} because it was not found in the operational store",
mac.getMacEntryKey().getValue());
}
- updateCurrentTxDeleteData(RemoteUcastMacs.class, macIid, mac);
}
protected List<RemoteUcastMacs> getData(HwvtepGlobalAugmentation augmentation) {
protected boolean isRemoveCommand() {
return true;
}
+
+ @Override
+ public void onCommandSucceeded() {
+ for (MdsalUpdate mdsalUpdate : updates.get(getDeviceTransaction())) {
+ RemoteUcastMacs deletedMac = (RemoteUcastMacs) mdsalUpdate.getNewData();
+ InstanceIdentifier<RemoteUcastMacs> macIid = mdsalUpdate.getKey();
+ getDeviceInfo().removeRemoteUcast(
+ (InstanceIdentifier<LogicalSwitches>) deletedMac.getLogicalSwitchRef().getValue(), macIid);
+ }
+ }
}
import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
import org.opendaylight.ovsdb.schema.hardwarevtep.UcastMacsRemote;
+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.hwvtep.global.attributes.LogicalSwitches;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
UcastMacsRemote ucastMacsRemote = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), UcastMacsRemote.class);
setIpAddress(ucastMacsRemote, remoteUcastMac);
setLocator(transaction, ucastMacsRemote, remoteUcastMac);
- setLogicalSwitch(ucastMacsRemote, remoteUcastMac);
+ setLogicalSwitch(transaction, ucastMacsRemote, remoteUcastMac);
if (deviceData == null) {
setMac(ucastMacsRemote, remoteUcastMac);
LOG.trace("doDeviceTransaction: creating RemotUcastMac entry: {}", ucastMacsRemote);
}
}
- private void setLogicalSwitch(UcastMacsRemote ucastMacsRemote, RemoteUcastMacs inputMac) {
+ private void setLogicalSwitch(final TransactionBuilder transaction, final UcastMacsRemote ucastMacsRemote, final RemoteUcastMacs inputMac) {
if (inputMac.getLogicalSwitchRef() != null) {
@SuppressWarnings("unchecked")
InstanceIdentifier<LogicalSwitches> lswitchIid =
(InstanceIdentifier<LogicalSwitches>) inputMac.getLogicalSwitchRef().getValue();
- HwvtepDeviceInfo.DeviceData deviceData = getOperationalState().getDeviceInfo().getDeviceOperData(
- LogicalSwitches.class, lswitchIid);
- if (deviceData != null && deviceData.getUuid() != null) {
- ucastMacsRemote.setLogicalSwitch(deviceData.getUuid());
- } else {
- ucastMacsRemote.setLogicalSwitch(TransactUtils.getLogicalSwitchUUID(lswitchIid));
- }
+ ucastMacsRemote.setLogicalSwitch(TransactUtils.getLogicalSwitchUUID(transaction, getOperationalState(), lswitchIid));
}
}
return Collections.singletonList(data.getLocatorRef().getValue());
}
}
+
+ @Override
+ public void onCommandSucceeded() {
+ for (MdsalUpdate mdsalUpdate : updates.get(getDeviceTransaction())) {
+ RemoteUcastMacs newMac = (RemoteUcastMacs) mdsalUpdate.getNewData();
+ InstanceIdentifier<RemoteUcastMacs> macIid = mdsalUpdate.getKey();
+ RemoteUcastMacs oldMac = (RemoteUcastMacs) mdsalUpdate.getOldData();
+ if (oldMac != null && !oldMac.equals(newMac)) {
+ getDeviceInfo().decRefCount(macIid, oldMac.getLocatorRef().getValue());
+ }
+ getDeviceInfo().updateRemoteUcast(
+ (InstanceIdentifier<LogicalSwitches>) newMac.getLogicalSwitchRef().getValue(), macIid, newMac);
+ }
+ }
}
\ No newline at end of file
package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
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.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;
public abstract class AbstractTransactionCommand<T extends DataObject> implements TransactionCommand{
this.key = key;
}
+ public HwvtepDeviceInfo getDeviceInfo() {
+ return key.getDeviceInfo();
+ }
}