this.dataBroker = dataBroker;
}
- public void transact(TransactCommand command) {
+ public synchronized void transact(TransactCommand command) {
for (TransactInvoker transactInvoker: transactInvokers.values()) {
transactInvoker.invoke(command);
}
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.lib.notation.UUID;
import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalLocator;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
new DeviceData(key, null, data, DeviceDataStatus.AVAILABLE));
}
+ public Object getConfigData(Class<? extends Identifiable> cls, InstanceIdentifier key) {
+ return HwvtepSouthboundUtil.getData(configKeyVsData, cls, key);
+ }
+
public void clearConfigData(Class<? extends Identifiable> cls, InstanceIdentifier key) {
HwvtepSouthboundUtil.clearData(configKeyVsData, cls, key);
}
public void markKeyAsInTransit(Class<? extends Identifiable> cls, InstanceIdentifier key) {
+ LOG.debug("Marking device data as intransit {}", key);
HwvtepSouthboundUtil.updateData(opKeyVsData, cls, key,
new DeviceData(key, null, null, DeviceDataStatus.IN_TRANSIT));
}
public void updateDeviceOpData(Class<? extends Identifiable> cls, InstanceIdentifier key, UUID uuid, Object data) {
+ LOG.debug("Updating device data {}", key);
HwvtepSouthboundUtil.updateData(opKeyVsData, cls, key,
new DeviceData(key, uuid, data, DeviceDataStatus.AVAILABLE));
HwvtepSouthboundUtil.updateData(uuidVsData, cls, uuid, data);
public void onOpDataAvailable() {
dependencyQueue.processReadyJobsFromOpQueue(connectionInstance);
}
+
+ public void scheduleTransaction(final TransactCommand transactCommand) {
+ dependencyQueue.submit(new Runnable() {
+ @Override
+ public void run() {
+ 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();
+ }
+ }
+ }
+ onOpDataAvailable();
+ }
}
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;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.ConnectionInfo;
+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.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.Identifiable;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.CheckedFuture;
+
+import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
public class HwvtepSouthboundUtil {
}
}
- public static <T> boolean isEmpty(List<T> list) {
+ public static <T> boolean isEmpty(Collection<T> list) {
return list == null || list.isEmpty();
}
+
+ public static boolean isEmptyMap(Map map) {
+ return map == null || map.isEmpty();
+ }
}
HwvtepGlobalAugmentationBuilder oldAugmentation = getAugmentationFromNode(opNode);
//fire removal of local ucast macs so that logical switches will be deleted
- fillLocalMcacsToBeRemoved(oldAugmentation, configNode, opNode);
+ fillLocalMacsToBeRemoved(oldAugmentation, configNode, opNode);
newNodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, newAugmentation.build());
oldNodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, oldAugmentation.build());
return new DataTreeModificationImpl<Node>(nodeId, newNodeBuilder.build(), oldNodeBuilder.build());
}
- static void fillLocalMcacsToBeRemoved(HwvtepGlobalAugmentationBuilder oldAugmentation, Node configNode,
- Node opNode) {
+ static void fillLocalMacsToBeRemoved(HwvtepGlobalAugmentationBuilder oldAugmentation, Node configNode, Node opNode) {
Set<String> logicalSwitchNamesToBeRemoved = getLogicalSwitchesToBeRemoved(configNode, opNode);
List<LocalUcastMacs> localUcastMacsToBeRemoved = getLocalUcastMacsToBeRemoved(opNode,
logicalSwitchNamesToBeRemoved);
Set<String> opSwitchNames = new HashSet<>();
Set<String> cfgSwitchNames = new HashSet<>();
List<LogicalSwitches> cfgLogicalSwitches = Lists.newArrayList();
+ List<LogicalSwitches> opLogicalSwitches = Lists.newArrayList();
- List<LogicalSwitches> opLogicalSwitches = opNode.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches();
- if (configNode != null) {
+ if (opNode != null && opNode.getAugmentation(HwvtepGlobalAugmentation.class) != null) {
+ opLogicalSwitches = opNode.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches();
+ }
+ if (configNode != null && configNode.getAugmentation(HwvtepGlobalAugmentation.class) != null) {
cfgLogicalSwitches = configNode.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches();
}
if (opLogicalSwitches != null) {
package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
import com.google.common.collect.Lists;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
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.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.Identifiable;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+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;
-public abstract class AbstractTransactCommand<T extends Identifiable> implements TransactCommand<T> {
+public abstract class AbstractTransactCommand<T extends Identifiable, Aug extends Augmentation<Node>> implements TransactCommand<T> {
private HwvtepOperationalState operationalState;
private Collection<DataTreeModification<Node>> changes;
return changes;
}
- void updateCurrentTxDeleteData(InstanceIdentifier key, T data) {
- Class<? extends Identifiable> cls = data.getClass();
+ void updateCurrentTxDeleteData(Class<? extends Identifiable> cls, InstanceIdentifier key, T data) {
operationalState.updateCurrentTxDeleteData(cls, key);
operationalState.getDeviceInfo().clearConfigData(cls, key);
}
//we can skip the config termination point dependency as we can create them in device as part of this tx
confingDependencies.remove(TerminationPoint.class);
+ Type type = getClass().getGenericSuperclass();
+ Type classType = ((ParameterizedType)type).getActualTypeArguments()[0];
+
//If this key itself is in transit wait for the response of this key itself
- if (deviceInfo.isKeyInTransit(data.getClass(), key)) {
- inTransitDependencies.put(data.getClass(), Lists.newArrayList(key));
+ if (deviceInfo.isKeyInTransit((Class<? extends Identifiable>) classType, key)) {
+ inTransitDependencies.put((Class<? extends Identifiable>) classType, Lists.newArrayList(key));
}
- if (confingDependencies.isEmpty() && inTransitDependencies.isEmpty()) {
+ if (HwvtepSouthboundUtil.isEmptyMap(confingDependencies) && HwvtepSouthboundUtil.isEmptyMap(inTransitDependencies)) {
doDeviceTransaction(transaction, nodeIid, data, key, extraData);
//TODO put proper uuid
- updateCurrentTxData(data.getClass(), key, new UUID("uuid"), data);
+ updateCurrentTxData((Class<? extends Identifiable>) classType, key, new UUID("uuid"), data);
}
- if (!confingDependencies.isEmpty()) {
+ if (!HwvtepSouthboundUtil.isEmptyMap(confingDependencies)) {
DependentJob<T> configWaitingJob = new DependentJob.ConfigWaitingJob(
key, data, confingDependencies) {
};
deviceInfo.addJobToQueue(configWaitingJob);
}
- if (inTransitDependencies.size() > 0) {
+ if (!HwvtepSouthboundUtil.isEmptyMap(inTransitDependencies)) {
DependentJob<T> opWaitingJob = new DependentJob.OpWaitingJob(
key, data, inTransitDependencies) {
InstanceIdentifier key, Object... extraData) {
//tobe removed as part of refactoring patch
}
+
+ protected Aug getAugmentation(Node node) {
+ if (node == null) {
+ return null;
+ }
+ ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
+ Class<? extends Augmentation<Node>> augType = (Class<? extends Augmentation<Node>>) parameterizedType.getActualTypeArguments()[1];
+ Augmentation<Node> augmentation = node.getAugmentation(augType);
+ return (Aug)augmentation;
+ }
+
+ protected List<T> getData(Aug augmentation) {
+ return Collections.EMPTY_LIST;
+ }
+
+ protected List<T> getData(Node node) {
+ Aug augmentation = getAugmentation(node);
+ if (augmentation != null) {
+ List<T> data = getData(augmentation);
+ if (data != null) {
+ return Lists.newArrayList(data);
+ }
+ }
+ return Collections.EMPTY_LIST;
+ }
+
+ protected Map<InstanceIdentifier<Node>, List<T>> extractRemoved(
+ Collection<DataTreeModification<Node>> changes, Class<T> class1) {
+ Map<InstanceIdentifier<Node>, List<T>> result
+ = new HashMap<InstanceIdentifier<Node>, List<T>>();
+ List<T> removed = Collections.EMPTY_LIST;
+ if (changes != null && !changes.isEmpty()) {
+ for (DataTreeModification<Node> change : changes) {
+ final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
+ removed = getRemoved(change);
+ removed.addAll(getCascadeDeleteData(change));
+ result.put(key, removed);
+ }
+ }
+ return result;
+ }
+
+ protected Map<InstanceIdentifier<Node>, List<T>> extractUpdated(
+ Collection<DataTreeModification<Node>> changes, Class<T> class1) {
+ Map<InstanceIdentifier<Node>, List<T>> result
+ = new HashMap<InstanceIdentifier<Node>, List<T>>();
+ if (changes != null && !changes.isEmpty()) {
+ for (DataTreeModification<Node> change : changes) {
+ InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
+ result.put(key, getUpdated(change));
+ }
+ }
+ return result;
+ }
+
+ List<T> getCascadeDeleteData(DataTreeModification<Node> change) {
+ if (!cascadeDelete()) {
+ return Collections.EMPTY_LIST;
+ }
+ DataObjectModification<Node> mod = change.getRootNode();
+ Node updatedNode = TransactUtils.getUpdated(mod);
+ List<T> updatedData = getData(updatedNode);
+ Set<InstanceIdentifier> deleted = getOperationalState().getDeletedKeysInCurrentTx(LogicalSwitches.class);
+ UnMetDependencyGetter dependencyGetter = getDependencyGetter();
+ if (!HwvtepSouthboundUtil.isEmpty(deleted) && !HwvtepSouthboundUtil.isEmpty(updatedData) && dependencyGetter != null) {
+ List<T> removed = new ArrayList<T>();
+ for (T ele : updatedData) {
+ if (deleted.containsAll(dependencyGetter.getLogicalSwitchDependencies(ele))) {
+ removed.add(ele);
+ }
+ }
+ return removed;
+ }
+ return Collections.EMPTY_LIST;
+ }
+
+ List<T> getRemoved(DataTreeModification<Node> change) {
+ DataObjectModification<Node> mod = change.getRootNode();
+
+ Node removed = TransactUtils.getRemoved(mod);
+ Node updated = TransactUtils.getUpdated(mod);
+ Node before = mod.getDataBefore();
+ return diffOf(removed, before, updated, true);
+ }
+
+ List<T> getUpdated(DataTreeModification<Node> change) {
+ DataObjectModification<Node> mod = change.getRootNode();
+ Node created = TransactUtils.getCreated(mod);
+ Node updated = TransactUtils.getUpdated(mod);
+ Node before = mod.getDataBefore();
+ return diffOf(created, updated, before, false);
+ }
+
+ List<T> diffOf(Node include, Node a, Node b, boolean compareKeyOnly) {
+ List<T> data1 = getData(include);
+ List<T> data2 = diffOf(a, b, compareKeyOnly);
+ if (HwvtepSouthboundUtil.isEmpty(data1) && HwvtepSouthboundUtil.isEmpty(data2)) {
+ return Collections.EMPTY_LIST;
+ }
+ List<T> result = Lists.newArrayList(data1);
+ result.addAll(data2);
+ return result;
+ }
+
+ List<T> diffOf(Node a, Node b, boolean compareKeyOnly) {
+ List<T> result = new ArrayList<T>();
+
+ List<T> list1 = getData(a);
+ List<T> list2 = getData(b);
+
+ if (HwvtepSouthboundUtil.isEmpty(list1)) {
+ return Collections.EMPTY_LIST;
+ }
+ if (HwvtepSouthboundUtil.isEmpty(list2)) {
+ return HwvtepSouthboundUtil.isEmpty(list1) ? Collections.EMPTY_LIST : list1;
+ }
+
+ Iterator<T> it1 = list1.iterator();
+
+ while(it1.hasNext()) {
+ T ele = it1.next();
+ Iterator<T> it2 = list2.iterator();
+ boolean found = false;
+ while (it2.hasNext()) {
+ T other = it2.next();
+ found = compareKeyOnly ? Objects.equals(ele.getKey(), other.getKey()) : areEqual(ele, other);
+ if ( found ) {
+ it2.remove();
+ break;
+ }
+ }
+ if (!found) {
+ result.add(ele);
+ }
+ }
+ return result;
+ }
+
+ protected boolean areEqual(T a , T b) {
+ return a.getKey().equals(b.getKey());
+ }
+
+ protected UnMetDependencyGetter getDependencyGetter() {
+ return null;
+ }
+
+ /**
+ * Tells if this object needs to be deleted if its dependent object gets deleted
+ * Ex : LocalUcastMac and LocalMacstMac
+ * @return true if this object needs to be deleted if its dependent object gets deleted
+ */
+ protected boolean cascadeDelete() {
+ return false;
+ }
}
public static void close() {
executorService.shutdown();
}
+
+ public void submit(Runnable runnable) {
+ executorService.submit(runnable);
+ }
}
\ No newline at end of file
import static org.opendaylight.ovsdb.lib.operations.Operations.op;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashMap;
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.DataObjectModification;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+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.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.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.Identifiable;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Optional;
-public class LogicalSwitchRemoveCommand extends AbstractTransactCommand {
+public class LogicalSwitchRemoveCommand extends AbstractTransactCommand<LogicalSwitches, HwvtepGlobalAugmentation> {
private static final Logger LOG = LoggerFactory.getLogger(LogicalSwitchRemoveCommand.class);
public LogicalSwitchRemoveCommand(HwvtepOperationalState state,
public void execute(TransactionBuilder transaction) {
Map<InstanceIdentifier<Node>, List<LogicalSwitches>> removeds =
extractRemoved(getChanges(),LogicalSwitches.class);
- if (!removeds.isEmpty()) {
- for (Entry<InstanceIdentifier<Node>, List<LogicalSwitches>> created:
- removeds.entrySet()) {
- if (created.getValue() != null) {
+ 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(lsKey, lswitch);
+ updateCurrentTxDeleteData(LogicalSwitches.class, lsKey, lswitch);
}
+ getOperationalState().getDeviceInfo().scheduleTransaction(new TransactCommand() {
+ @Override
+ public void execute(TransactionBuilder 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) {
+ }
+
+ @Override
+ public void doDeviceTransaction(TransactionBuilder transaction, InstanceIdentifier nodeIid,
+ Identifiable data, InstanceIdentifier key, Object... extraData) {
+ }
+ });
}
- removeLogicalSwitch(transaction, created.getKey(), created.getValue());
}
}
}
}
}
- private Map<InstanceIdentifier<Node>, List<LogicalSwitches>> extractRemoved(
- Collection<DataTreeModification<Node>> changes, Class<LogicalSwitches> class1) {
- Map<InstanceIdentifier<Node>, List<LogicalSwitches>> result
- = new HashMap<InstanceIdentifier<Node>, List<LogicalSwitches>>();
- if (changes != null && !changes.isEmpty()) {
- for (DataTreeModification<Node> change : changes) {
- final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
- final DataObjectModification<Node> mod = change.getRootNode();
- //If the node which logical switches belong to is removed, all logical switches
- //should be removed too.
- Node removed = TransactUtils.getRemoved(mod);
- if (removed != null) {
- List<LogicalSwitches> lswitchListRemoved = null;
- if (removed.getAugmentation(HwvtepGlobalAugmentation.class) != null) {
- lswitchListRemoved = removed.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches();
- }
- if (lswitchListRemoved != null) {
- result.put(key, lswitchListRemoved);
- }
- }
- //If the node which logical switches belong to is updated, and logical switches may
- //be created or updated or deleted, we need to get deleted ones.
- Node updated = TransactUtils.getUpdated(mod);
- Node before = mod.getDataBefore();
- if (updated != null && before != null) {
- List<LogicalSwitches> lswitchListUpdated = null;
- List<LogicalSwitches> lswitchListBefore = null;
- if (updated.getAugmentation(HwvtepGlobalAugmentation.class) != null) {
- lswitchListUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches();
- }
- if (before.getAugmentation(HwvtepGlobalAugmentation.class) != null) {
- lswitchListBefore = before.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches();
- }
- if (lswitchListBefore != null) {
- List<LogicalSwitches> lswitchListRemoved = new ArrayList<LogicalSwitches>();
- if (lswitchListUpdated != null) {
- lswitchListBefore = new ArrayList<>(lswitchListBefore);
- lswitchListBefore.removeAll(lswitchListUpdated);//operate on copy as it has side effect on LogicalSwitchUpdateCommand
- }
- //then exclude updated ones
- if (lswitchListUpdated != null) {
- for (LogicalSwitches lswitchBefore : lswitchListBefore) {
- int i = 0;
- for (; i < lswitchListUpdated.size(); i++) {
- if (lswitchBefore.getHwvtepNodeName().equals(lswitchListUpdated.get(i).getHwvtepNodeName())) {
- break;
- }
- }
- if (i == lswitchListUpdated.size()) {
- lswitchListRemoved.add(lswitchBefore);
- }
- }
- } else {
- lswitchListRemoved.addAll(lswitchListBefore);
- }
- if (!lswitchListRemoved.isEmpty()) {
- result.put(key, lswitchListRemoved);
- }
- }
- }
- }
- }
- return result;
+ @Override
+ protected List<LogicalSwitches> getData(HwvtepGlobalAugmentation augmentation) {
+ return augmentation.getLogicalSwitches();
+ }
+
+ @Override
+ protected boolean areEqual(LogicalSwitches a , LogicalSwitches b) {
+ return a.getKey().equals(b.getKey()) && Objects.equals(a.getTunnelKey(), b.getTunnelKey());
}
}
import static org.opendaylight.ovsdb.lib.operations.Operations.op;
import java.util.Collection;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Objects;
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.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 com.google.common.base.Optional;
-public class LogicalSwitchUpdateCommand extends AbstractTransactCommand {
+public class LogicalSwitchUpdateCommand extends AbstractTransactCommand<LogicalSwitches, HwvtepGlobalAugmentation> {
private static final Logger LOG = LoggerFactory.getLogger(LogicalSwitchUpdateCommand.class);
public LogicalSwitchUpdateCommand(HwvtepOperationalState state,
@Override
public void execute(TransactionBuilder transaction) {
- Map<InstanceIdentifier<Node>, List<LogicalSwitches>> createds =
- extractCreated(getChanges(),LogicalSwitches.class);
- if (!createds.isEmpty()) {
- for (Entry<InstanceIdentifier<Node>, List<LogicalSwitches>> created:
- createds.entrySet()) {
- updateLogicalSwitch(transaction, created.getKey(), created.getValue());
- }
- }
Map<InstanceIdentifier<Node>, List<LogicalSwitches>> updateds =
extractUpdated(getChanges(),LogicalSwitches.class);
if (!updateds.isEmpty()) {
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));
+ updateCurrentTxData(LogicalSwitches.class, lsKey, lsUuid, lswitch);
} else {
LogicalSwitches updatedLSwitch = operationalSwitchOptional.get();
String existingLogicalSwitchName = updatedLSwitch.getHwvtepNodeName().getValue();
.build());
transaction.add(op.comment("Logical Switch: Updating " + existingLogicalSwitchName));
}
- UUID lsUuid = new UUID(TransactUtils.getLogicalSwitchId(lswitch));
- updateCurrentTxData(LogicalSwitches.class, lsKey, lsUuid, lswitch);
}
}
}
}
- private Map<InstanceIdentifier<Node>, List<LogicalSwitches>> extractCreated(
- Collection<DataTreeModification<Node>> changes, Class<LogicalSwitches> class1) {
- Map<InstanceIdentifier<Node>, List<LogicalSwitches>> result
- = new HashMap<InstanceIdentifier<Node>, List<LogicalSwitches>>();
- if (changes != null && !changes.isEmpty()) {
- for (DataTreeModification<Node> change : changes) {
- final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
- final DataObjectModification<Node> mod = change.getRootNode();
- Node created = TransactUtils.getCreated(mod);
- if (created != null) {
- List<LogicalSwitches> lswitchListUpdated = null;
- if (created.getAugmentation(HwvtepGlobalAugmentation.class) != null) {
- lswitchListUpdated = created.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches();
- }
- if (lswitchListUpdated != null) {
- result.put(key, lswitchListUpdated);
- }
- }
- }
- }
- return result;
+ @Override
+ protected List<LogicalSwitches> getData(HwvtepGlobalAugmentation augmentation) {
+ return augmentation.getLogicalSwitches();
}
- private Map<InstanceIdentifier<Node>, List<LogicalSwitches>> extractUpdated(
- Collection<DataTreeModification<Node>> changes, Class<LogicalSwitches> class1) {
- Map<InstanceIdentifier<Node>, List<LogicalSwitches>> result
- = new HashMap<InstanceIdentifier<Node>, List<LogicalSwitches>>();
- if (changes != null && !changes.isEmpty()) {
- for (DataTreeModification<Node> change : changes) {
- final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
- final DataObjectModification<Node> mod = change.getRootNode();
- Node updated = TransactUtils.getUpdated(mod);
- Node before = mod.getDataBefore();
- if (updated != null && before != null) {
- List<LogicalSwitches> lswitchListUpdated = null;
- List<LogicalSwitches> lswitchListBefore = null;
- if (updated.getAugmentation(HwvtepGlobalAugmentation.class) != null) {
- lswitchListUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches();
- }
- if (before.getAugmentation(HwvtepGlobalAugmentation.class) != null) {
- lswitchListBefore = before.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches();
- }
- if (lswitchListUpdated != null) {
- if (lswitchListBefore != null) {
- lswitchListUpdated.removeAll(lswitchListBefore);
- }
- result.put(key, lswitchListUpdated);
- }
- }
- }
- }
- return result;
+ @Override
+ protected boolean areEqual(LogicalSwitches a , LogicalSwitches b) {
+ return a.getKey().equals(b.getKey()) && Objects.equals(a.getTunnelKey(), b.getTunnelKey());
}
}
import static org.opendaylight.ovsdb.lib.operations.Operations.op;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashMap;
+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.DataObjectModification;
+import com.google.common.collect.Lists;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
-import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundConstants;
import org.opendaylight.ovsdb.lib.notation.UUID;
import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
import com.google.common.base.Optional;
-public class McastMacsLocalRemoveCommand extends AbstractTransactCommand {
+public class McastMacsLocalRemoveCommand extends AbstractTransactCommand<LocalMcastMacs, HwvtepGlobalAugmentation> {
private static final Logger LOG = LoggerFactory.getLogger(McastMacsLocalRemoveCommand.class);
public McastMacsLocalRemoveCommand(HwvtepOperationalState state,
}
}
- private Map<InstanceIdentifier<Node>, List<LocalMcastMacs>> extractRemoved(
- Collection<DataTreeModification<Node>> changes, Class<LocalMcastMacs> class1) {
- Map<InstanceIdentifier<Node>, List<LocalMcastMacs>> result
- = new HashMap<InstanceIdentifier<Node>, List<LocalMcastMacs>>();
- if (changes != null && !changes.isEmpty()) {
- for (DataTreeModification<Node> change : changes) {
- final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
- final DataObjectModification<Node> mod = change.getRootNode();
- //If the node which localMcastMacs belong to is removed, all localMcastMacs should be removed too.
- Node removed = TransactUtils.getRemoved(mod);
- if (removed != null) {
- List<LocalMcastMacs> macListRemoved = null;
- if (removed.getAugmentation(HwvtepGlobalAugmentation.class) != null) {
- macListRemoved = removed.getAugmentation(HwvtepGlobalAugmentation.class).getLocalMcastMacs();
- }
- if (macListRemoved != null) {
- result.put(key, macListRemoved);
- }
- }
- //If the node which localMcastMacs belong to is updated, and localMcastMacs may
- //be created or updated or deleted, we need to get deleted ones.
- Node updated = TransactUtils.getUpdated(mod);
- Node before = mod.getDataBefore();
- if (updated != null && before != null) {
- List<LocalMcastMacs> macListUpdated = null;
- List<LocalMcastMacs> macListBefore = null;
- HwvtepGlobalAugmentation hgUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class);
- if (hgUpdated != null) {
- macListUpdated = hgUpdated.getLocalMcastMacs();
- }
- HwvtepGlobalAugmentation hgBefore = before.getAugmentation(HwvtepGlobalAugmentation.class);
- if (hgBefore != null) {
- macListBefore = hgBefore.getLocalMcastMacs();
- }
- if (macListBefore != null) {
- List<LocalMcastMacs> macListRemoved = new ArrayList<LocalMcastMacs>();
- if (macListUpdated != null) {
- macListBefore.removeAll(macListUpdated);
- }
- //then exclude updated localMcastMacs
- if (macListUpdated != null) {
- for (LocalMcastMacs macBefore : macListBefore) {
- int i = 0;
- for (; i < macListUpdated.size(); i++) {
- if (macBefore.getKey().equals(macListUpdated.get(i).getKey())) {
- break;
- }
- }
- if (i == macListUpdated.size()) {
- macListRemoved.add(macBefore);
- }
- }
- } else {
- macListRemoved.addAll(macListBefore);
- }
- if (!macListRemoved.isEmpty()) {
- result.put(key, macListRemoved);
- }
- }
- }
- }
+ @Override
+ protected List<LocalMcastMacs> getData(HwvtepGlobalAugmentation augmentation) {
+ return augmentation.getLocalMcastMacs();
+ }
+
+ @Override
+ protected boolean cascadeDelete() {
+ return true;
+ }
+
+ @Override
+ protected UnMetDependencyGetter getDependencyGetter() {
+ return MAC_DEPENDENCY_GETTER;
+ }
+
+ static UnMetDependencyGetter MAC_DEPENDENCY_GETTER = new MacDependencyGetter();
+
+ public static class MacDependencyGetter extends UnMetDependencyGetter<LocalMcastMacs> {
+ public List<InstanceIdentifier<?>> getLogicalSwitchDependencies(LocalMcastMacs data) {
+ return Lists.newArrayList(data.getLogicalSwitchRef().getValue());
+ }
+
+ @Override
+ public List<InstanceIdentifier<?>> getTerminationPointDependencies(LocalMcastMacs data) {
+ return Collections.EMPTY_LIST;
}
- return result;
}
}
import static org.opendaylight.ovsdb.lib.operations.Operations.op;
import java.util.Collection;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-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.notation.UUID;
import com.google.common.base.Optional;
-public class McastMacsLocalUpdateCommand extends AbstractTransactCommand {
+public class McastMacsLocalUpdateCommand extends AbstractTransactCommand<LocalMcastMacs, HwvtepGlobalAugmentation> {
private static final Logger LOG = LoggerFactory.getLogger(McastMacsLocalUpdateCommand.class);
public McastMacsLocalUpdateCommand(HwvtepOperationalState state,
@Override
public void execute(TransactionBuilder transaction) {
- Map<InstanceIdentifier<Node>, List<LocalMcastMacs>> createds =
- extractCreated(getChanges(),LocalMcastMacs.class);
- if (!createds.isEmpty()) {
- for (Entry<InstanceIdentifier<Node>, List<LocalMcastMacs>> created:
- createds.entrySet()) {
- updateMcastMacsLocal(transaction, created.getKey(), created.getValue());
- }
- }
Map<InstanceIdentifier<Node>, List<LocalMcastMacs>> updateds =
extractUpdated(getChanges(),LocalMcastMacs.class);
if (!updateds.isEmpty()) {
}
}
- private Map<InstanceIdentifier<Node>, List<LocalMcastMacs>> extractCreated(
- Collection<DataTreeModification<Node>> changes, Class<LocalMcastMacs> class1) {
- Map<InstanceIdentifier<Node>, List<LocalMcastMacs>> result
- = new HashMap<InstanceIdentifier<Node>, List<LocalMcastMacs>>();
- if (changes != null && !changes.isEmpty()) {
- for (DataTreeModification<Node> change : changes) {
- final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
- final DataObjectModification<Node> mod = change.getRootNode();
- Node created = TransactUtils.getCreated(mod);
- if (created != null) {
- List<LocalMcastMacs> macListUpdated = null;
- HwvtepGlobalAugmentation hgAugmentation = created.getAugmentation(HwvtepGlobalAugmentation.class);
- if (hgAugmentation != null) {
- macListUpdated = hgAugmentation.getLocalMcastMacs();
- }
- if (macListUpdated != null) {
- result.put(key, macListUpdated);
- }
- }
- }
- }
- return result;
- }
-
- private Map<InstanceIdentifier<Node>, List<LocalMcastMacs>> extractUpdated(
- Collection<DataTreeModification<Node>> changes, Class<LocalMcastMacs> class1) {
- Map<InstanceIdentifier<Node>, List<LocalMcastMacs>> result
- = new HashMap<InstanceIdentifier<Node>, List<LocalMcastMacs>>();
- if (changes != null && !changes.isEmpty()) {
- for (DataTreeModification<Node> change : changes) {
- final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
- final DataObjectModification<Node> mod = change.getRootNode();
- Node updated = TransactUtils.getUpdated(mod);
- Node before = mod.getDataBefore();
- if (updated != null && before != null) {
- List<LocalMcastMacs> macListUpdated = null;
- List<LocalMcastMacs> macListBefore = null;
- HwvtepGlobalAugmentation hgUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class);
- if (hgUpdated != null) {
- macListUpdated = hgUpdated.getLocalMcastMacs();
- }
- HwvtepGlobalAugmentation hgBefore = before.getAugmentation(HwvtepGlobalAugmentation.class);
- if (hgBefore != null) {
- macListBefore = hgBefore.getLocalMcastMacs();
- }
- if (macListUpdated != null) {
- if (macListBefore != null) {
- macListUpdated.removeAll(macListBefore);
- }
- result.put(key, macListUpdated);
- }
- }
- }
- }
- return result;
+ @Override
+ protected List<LocalMcastMacs> getData(HwvtepGlobalAugmentation augmentation) {
+ return augmentation.getLocalMcastMacs();
}
}
\ No newline at end of file
import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashMap;
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.DataObjectModification;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
-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 com.google.common.base.Optional;
-public class McastMacsRemoteRemoveCommand extends AbstractTransactCommand {
+public class McastMacsRemoteRemoveCommand extends AbstractTransactCommand<RemoteMcastMacs, HwvtepGlobalAugmentation> {
private static final Logger LOG = LoggerFactory.getLogger(McastMacsRemoteRemoveCommand.class);
public McastMacsRemoteRemoveCommand(HwvtepOperationalState state,
removeMcastMacRemote(transaction, removed.getKey(), removed.getValue());
}
}
+ //Remove the ones whose locator set got emptied
+ Map<InstanceIdentifier<Node>, List<RemoteMcastMacs>> updated =
+ extractUpdated(getChanges(),RemoteMcastMacs.class);
+ if (!HwvtepSouthboundUtil.isEmptyMap(updated)) {
+ for (Entry<InstanceIdentifier<Node>, List<RemoteMcastMacs>> entry:
+ updated.entrySet()) {
+ List<RemoteMcastMacs> updatedList = entry.getValue();
+ List<RemoteMcastMacs> tobeRemovedList = new ArrayList<>();
+ if (!HwvtepSouthboundUtil.isEmpty(updatedList)) {
+ for (RemoteMcastMacs mac: updatedList) {
+ if (HwvtepSouthboundUtil.isEmpty(mac.getLocatorSet())) {
+ tobeRemovedList.add(mac);
+ }
+ }
+ removeMcastMacRemote(transaction, entry.getKey(), tobeRemovedList);
+ }
+ }
+ }
}
private void removeMcastMacRemote(TransactionBuilder transaction,
}
InstanceIdentifier<RemoteMcastMacs> macIid = instanceIdentifier.augmentation(HwvtepGlobalAugmentation.class).
child(RemoteMcastMacs.class, mac.getKey());
- updateCurrentTxDeleteData(macIid, mac);
+ updateCurrentTxDeleteData(RemoteMcastMacs.class, macIid, mac);
}
}
- private Map<InstanceIdentifier<Node>, List<RemoteMcastMacs>> extractRemoved(
- Collection<DataTreeModification<Node>> changes, Class<RemoteMcastMacs> class1) {
- Map<InstanceIdentifier<Node>, List<RemoteMcastMacs>> result
- = new HashMap<InstanceIdentifier<Node>, List<RemoteMcastMacs>>();
- if (changes != null && !changes.isEmpty()) {
- for (DataTreeModification<Node> change : changes) {
- final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
- final DataObjectModification<Node> mod = change.getRootNode();
- //If the node which remoteMcastMacs belong to is removed, all remoteMcastMacs should be removed too.
- Node removed = TransactUtils.getRemoved(mod);
- if (removed != null) {
- List<RemoteMcastMacs> macListRemoved = null;
- if (removed.getAugmentation(HwvtepGlobalAugmentation.class) != null) {
- macListRemoved = removed.getAugmentation(HwvtepGlobalAugmentation.class).getRemoteMcastMacs();
- }
- if (macListRemoved != null) {
- result.put(key, macListRemoved);
- }
- }
- //If the node which remoteMcastMacs belong to is updated, and remoteMcastMacs may
- //be created or updated or deleted, we need to get deleted ones.
- Node updated = TransactUtils.getUpdated(mod);
- Node before = mod.getDataBefore();
- if (updated != null && before != null) {
- List<RemoteMcastMacs> macListUpdated = null;
- List<RemoteMcastMacs> macListBefore = null;
- HwvtepGlobalAugmentation hgUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class);
- if (hgUpdated != null) {
- macListUpdated = hgUpdated.getRemoteMcastMacs();
- }
- HwvtepGlobalAugmentation hgBefore = before.getAugmentation(HwvtepGlobalAugmentation.class);
- if (hgBefore != null) {
- macListBefore = hgBefore.getRemoteMcastMacs();
- }
- if (macListBefore != null) {
- List<RemoteMcastMacs> macListRemoved = new ArrayList<RemoteMcastMacs>();
- if (macListUpdated != null) {
- macListBefore = new ArrayList<>(macListBefore);
- macListBefore.removeAll(macListUpdated);
- }
- //then exclude updated remoteMcastMacs
- if (macListUpdated != null) {
- for (RemoteMcastMacs macBefore : macListBefore) {
- int i = 0;
- for (; i < macListUpdated.size(); i++) {
- if (macBefore.getKey().equals(macListUpdated.get(i).getKey())) {
- break;
- }
- }
- if (i == macListUpdated.size()) {
- macListRemoved.add(macBefore);
- }
- }
- } else {
- macListRemoved.addAll(macListBefore);
- }
- if (!macListRemoved.isEmpty()) {
- result.put(key, macListRemoved);
- }
- }
- }
- }
- }
- return result;
+ @Override
+ protected List<RemoteMcastMacs> getData(HwvtepGlobalAugmentation augmentation) {
+ return augmentation.getRemoteMcastMacs();
+ }
+
+ @Override
+ protected boolean areEqual(RemoteMcastMacs a, RemoteMcastMacs b) {
+ return a.getKey().equals(b.getKey()) && Objects.equals(a.getLocatorSet(), b.getLocatorSet());
}
}
package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
import com.google.common.base.Optional;
+import static org.opendaylight.ovsdb.lib.operations.Operations.op;
+
+import java.util.ArrayList;
+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 com.google.common.collect.Lists;
-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.hwvtepsouthbound.HwvtepSouthboundUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
import static org.opendaylight.ovsdb.lib.operations.Operations.op;
-public class McastMacsRemoteUpdateCommand extends AbstractTransactCommand<RemoteMcastMacs> {
+public class McastMacsRemoteUpdateCommand extends AbstractTransactCommand<RemoteMcastMacs, HwvtepGlobalAugmentation> {
private static final Logger LOG = LoggerFactory.getLogger(McastMacsRemoteUpdateCommand.class);
private static final McastMacUnMetDependencyGetter MCAST_MAC_DATA_VALIDATOR = new McastMacUnMetDependencyGetter();
@Override
public void execute(TransactionBuilder transaction) {
- Map<InstanceIdentifier<Node>, List<RemoteMcastMacs>> createds =
- extractCreated(getChanges(),RemoteMcastMacs.class);
- if (!createds.isEmpty()) {
- for (Entry<InstanceIdentifier<Node>, List<RemoteMcastMacs>> created:
- createds.entrySet()) {
- updateMcastMacRemote(transaction, created.getKey(), created.getValue());
- }
- }
Map<InstanceIdentifier<Node>, List<RemoteMcastMacs>> updateds =
extractUpdated(getChanges(),RemoteMcastMacs.class);
if (!updateds.isEmpty()) {
private void updateMcastMacRemote(TransactionBuilder transaction,
InstanceIdentifier<Node> instanceIdentifier, List<RemoteMcastMacs> macList) {
for (RemoteMcastMacs mac: macList) {
- onConfigUpdate(transaction, instanceIdentifier, mac, null);
+ //add / update only if locator set got changed
+ if (!HwvtepSouthboundUtil.isEmpty(mac.getLocatorSet())) {
+ onConfigUpdate(transaction, instanceIdentifier, mac, null);
+ }
}
}
}
}
- private Map<InstanceIdentifier<Node>, List<RemoteMcastMacs>> extractCreated(
- Collection<DataTreeModification<Node>> changes, Class<RemoteMcastMacs> class1) {
- Map<InstanceIdentifier<Node>, List<RemoteMcastMacs>> result
- = new HashMap<InstanceIdentifier<Node>, List<RemoteMcastMacs>>();
- if (changes != null && !changes.isEmpty()) {
- for (DataTreeModification<Node> change : changes) {
- final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
- final DataObjectModification<Node> mod = change.getRootNode();
- Node created = TransactUtils.getCreated(mod);
- if (created != null) {
- List<RemoteMcastMacs> macListUpdated = null;
- HwvtepGlobalAugmentation hgAugmentation = created.getAugmentation(HwvtepGlobalAugmentation.class);
- if (hgAugmentation != null) {
- macListUpdated = hgAugmentation.getRemoteMcastMacs();
- }
- if (macListUpdated != null) {
- result.put(key, macListUpdated);
- }
- }
- }
- }
- return result;
+ @Override
+ protected List<RemoteMcastMacs> getData(HwvtepGlobalAugmentation augmentation) {
+ return augmentation.getRemoteMcastMacs();
}
- private Map<InstanceIdentifier<Node>, List<RemoteMcastMacs>> extractUpdated(
- Collection<DataTreeModification<Node>> changes, Class<RemoteMcastMacs> class1) {
- Map<InstanceIdentifier<Node>, List<RemoteMcastMacs>> result
- = new HashMap<InstanceIdentifier<Node>, List<RemoteMcastMacs>>();
- if (changes != null && !changes.isEmpty()) {
- for (DataTreeModification<Node> change : changes) {
- final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
- final DataObjectModification<Node> mod = change.getRootNode();
- Node updated = TransactUtils.getUpdated(mod);
- Node before = mod.getDataBefore();
- if (updated != null && before != null) {
- List<RemoteMcastMacs> macListUpdated = null;
- List<RemoteMcastMacs> macListBefore = null;
- HwvtepGlobalAugmentation hgUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class);
- if (hgUpdated != null) {
- macListUpdated = hgUpdated.getRemoteMcastMacs();
- }
- HwvtepGlobalAugmentation hgBefore = before.getAugmentation(HwvtepGlobalAugmentation.class);
- if (hgBefore != null) {
- macListBefore = hgBefore.getRemoteMcastMacs();
- }
- if (macListUpdated != null) {
- if (macListBefore != null) {
- macListUpdated.removeAll(macListBefore);
- }
- result.put(key, macListUpdated);
- }
- }
- }
- }
- return result;
+ @Override
+ protected boolean areEqual(RemoteMcastMacs a, RemoteMcastMacs b) {
+ return a.getKey().equals(b.getKey()) && Objects.equals(a.getLocatorSet(), b.getLocatorSet());
}
static class McastMacUnMetDependencyGetter extends UnMetDependencyGetter<RemoteMcastMacs> {
@Override
public void execute(TransactionBuilder transaction) {
+ //TODO reuse from base class instead of extractRemovedPorts
Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> removeds =
- extractRemoved(getChanges(),HwvtepPhysicalPortAugmentation.class);
+ extractRemovedPorts(getChanges(), HwvtepPhysicalPortAugmentation.class);
if (!removeds.isEmpty()) {
for (Entry<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> removed:
removeds.entrySet()) {
}
}
- private Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> extractRemoved(
+ protected Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> extractRemovedPorts(
Collection<DataTreeModification<Node>> changes, Class<HwvtepPhysicalPortAugmentation> class1) {
Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> result
= new HashMap<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>>();
}
}
Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> updateds =
- extractUpdated(getChanges(),HwvtepPhysicalPortAugmentation.class);
+ extractUpdatedPorts(getChanges(), HwvtepPhysicalPortAugmentation.class);
if (!updateds.isEmpty()) {
for (Entry<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> updated:
updateds.entrySet()) {
return result;
}
- private Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> extractUpdated(
+ private Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> extractUpdatedPorts(
Collection<DataTreeModification<Node>> changes, Class<HwvtepPhysicalPortAugmentation> class1) {
Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> result
= new HashMap<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>>();
@Override
public void execute(TransactionBuilder transaction) {
Map<InstanceIdentifier<Node>, PhysicalSwitchAugmentation> removeds =
- extractRemoved(getChanges(),PhysicalSwitchAugmentation.class);
+ extractRemovedSwitches(getChanges(),PhysicalSwitchAugmentation.class);
if (!removeds.isEmpty()) {
for (Entry<InstanceIdentifier<Node>, PhysicalSwitchAugmentation> removed:
removeds.entrySet()) {
}
}
- private Map<InstanceIdentifier<Node>, PhysicalSwitchAugmentation> extractRemoved(
+ private Map<InstanceIdentifier<Node>, PhysicalSwitchAugmentation> extractRemovedSwitches(
Collection<DataTreeModification<Node>> changes, Class<PhysicalSwitchAugmentation> class1) {
Map<InstanceIdentifier<Node>, PhysicalSwitchAugmentation> result
= new HashMap<InstanceIdentifier<Node>, PhysicalSwitchAugmentation>();
}
}
Map<InstanceIdentifier<Node>, PhysicalSwitchAugmentation> updated =
- extractUpdated(getChanges(),PhysicalSwitchAugmentation.class);
+ extractUpdatedSwitches(getChanges(),PhysicalSwitchAugmentation.class);
if (!updated.isEmpty()) {
for (Entry<InstanceIdentifier<Node>, PhysicalSwitchAugmentation> physicalSwitchEntry:
updated.entrySet()) {
return result;
}
- private Map<InstanceIdentifier<Node>, PhysicalSwitchAugmentation> extractUpdated(
+ private Map<InstanceIdentifier<Node>, PhysicalSwitchAugmentation> extractUpdatedSwitches(
Collection<DataTreeModification<Node>> changes, Class<PhysicalSwitchAugmentation> class1) {
Map<InstanceIdentifier<Node>, PhysicalSwitchAugmentation> result
= new HashMap<InstanceIdentifier<Node>, PhysicalSwitchAugmentation>();
package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
import java.util.List;
+import java.util.Map;
+import com.google.common.base.Strings;
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.Operation;
import org.opendaylight.ovsdb.lib.operations.OperationResult;
import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.lib.operations.Update;
import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
if (tb.getOperations().size() > 0) {
try {
List<OperationResult> got = result.get();
- LOG.debug("OVSDB transaction result: {}", got);
+ LOG.debug("HWVTEP transaction result: {}", got);
+ boolean errorOccured = false;
+ if (got != null && got.size() > 0) {
+ for (OperationResult opResult : got) {
+ if (!Strings.isNullOrEmpty(opResult.getError())) {
+ LOG.error("HWVTEP transaction operation failed {} {}",
+ opResult.getError(), opResult.getDetails());
+ errorOccured = true;
+ }
+ }
+ }
+ if (errorOccured) {
+ connectionInstance.getDeviceInfo().clearInTransitData();
+ printError(tb);
+ }
} catch (Exception e) {
LOG.warn("Transact execution exception: ", e);
}
}
}
+ void printError(TransactionBuilder tb) {
+ StringBuffer sb = new StringBuffer();
+ for (Operation op : tb.getOperations()) {
+ if (op instanceof Insert) {
+ Insert insert = (Insert)op;
+ Map row = insert.getRow();
+ sb.append("insert [");
+ if (row != null) {
+ for (Object key : row.keySet()) {
+ sb.append(key + " : "+row.get(key)+" , ");
+ }
+ }
+ sb.append("] ");
+ } else if (op instanceof Delete) {
+ Delete delete = (Delete)op;
+ sb.append("delete from " );
+ sb.append(delete.getTableSchema().getName());
+ } else if (op instanceof Update) {
+ Update update = (Update)op;
+ sb.append("update [" );
+ Map row = update.getRow();
+ if (row != null) {
+ for (Object key : row.keySet()) {
+ sb.append(key + " : "+row.get(key)+" , ");
+ }
+ }
+ sb.append("]");
+ }
+ }
+ LOG.error("Failed transaction {}", sb);
+ }
}
import java.util.Set;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
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.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.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.HwvtepPhysicalLocatorAugmentationBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSet;
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;
HwvtepPhysicalLocatorAugmentation locatorAugmentation = operationalLocatorOptional.get();
locatorUuid = new UUID(locatorAugmentation.getPhysicalLocatorUuid().getValue());
} else {
- locatorUuid = hwvtepOperationalState.getPhysicalLocatorInFlight(iid);
+ locatorUuid = hwvtepOperationalState.getUUIDFromCurrentTx(TerminationPoint.class, iid);
if (locatorUuid == null) {
- //if no, get it from config DS and create id
- Optional<TerminationPoint> configLocatorOptional =
- readNodeFromConfig(hwvtepOperationalState.getReadWriteTransaction(), iid);
- if (configLocatorOptional.isPresent()) {
- HwvtepPhysicalLocatorAugmentation locatorAugmentation =
- configLocatorOptional.get().getAugmentation(HwvtepPhysicalLocatorAugmentation.class);
- locatorUuid = TransactUtils.createPhysicalLocator(transaction, locatorAugmentation);
- hwvtepOperationalState.setPhysicalLocatorInFlight(iid, locatorUuid);
- } else {
- LOG.warn("Create or update localMcastMac: No physical locator found in operational datastore!"
- + "Its indentifier is {}", locator.getLocatorRef().getValue());
- }
+ locatorUuid = createPhysicalLocator(transaction, hwvtepOperationalState, iid);
}
}
if (locatorUuid != null) {
return new UUID(locatorSetUuid);
}
+ public static UUID createPhysicalLocator(TransactionBuilder transaction, HwvtepOperationalState operationalState,
+ InstanceIdentifier<TerminationPoint> iid) {
+ Optional<TerminationPoint> configLocatorOptional = TransactUtils.readNodeFromConfig(
+ operationalState.getReadWriteTransaction(), iid);
+ HwvtepPhysicalLocatorAugmentationBuilder builder = new HwvtepPhysicalLocatorAugmentationBuilder();
+ HwvtepPhysicalLocatorAugmentation locatorAugmentation = null;
+ if (configLocatorOptional.isPresent()) {
+ locatorAugmentation = configLocatorOptional.get().getAugmentation(HwvtepPhysicalLocatorAugmentation.class);
+ } else {
+ builder.setEncapsulationType(EncapsulationTypeVxlanOverIpv4.class);
+ String tepKey = iid.firstKeyOf(TerminationPoint.class).getTpId().getValue();
+ String ip = tepKey.substring(tepKey.indexOf(":")+1);
+ builder.setDstIp(new IpAddress(ip.toCharArray()));
+ locatorAugmentation = builder.build();
+ }
+ UUID locatorUuid = TransactUtils.createPhysicalLocator(transaction, locatorAugmentation);
+ operationalState.updateCurrentTxData(TerminationPoint.class, iid, locatorUuid);
+ operationalState.getDeviceInfo().markKeyAsInTransit(TerminationPoint.class, iid);
+ return locatorUuid;
+ }
+
public static UUID createPhysicalLocator(TransactionBuilder transaction, HwvtepPhysicalLocatorAugmentation inputLocator) {
LOG.debug("Creating a physical locator: {}", inputLocator.getDstIp());
PhysicalLocator physicalLocator = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), PhysicalLocator.class);
import static org.opendaylight.ovsdb.lib.operations.Operations.op;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashMap;
+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.DataObjectModification;
+import com.google.common.collect.Lists;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
import org.opendaylight.ovsdb.lib.notation.UUID;
import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
import com.google.common.base.Optional;
-public class UcastMacsLocalRemoveCommand extends AbstractTransactCommand {
+public class UcastMacsLocalRemoveCommand extends AbstractTransactCommand<LocalUcastMacs, HwvtepGlobalAugmentation> {
private static final Logger LOG = LoggerFactory.getLogger(UcastMacsLocalRemoveCommand.class);
public UcastMacsLocalRemoveCommand(HwvtepOperationalState state,
}
}
- private Map<InstanceIdentifier<Node>, List<LocalUcastMacs>> extractRemoved(
- Collection<DataTreeModification<Node>> changes, Class<LocalUcastMacs> class1) {
- Map<InstanceIdentifier<Node>, List<LocalUcastMacs>> result
- = new HashMap<InstanceIdentifier<Node>, List<LocalUcastMacs>>();
- if (changes != null && !changes.isEmpty()) {
- for (DataTreeModification<Node> change : changes) {
- final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
- final DataObjectModification<Node> mod = change.getRootNode();
- //If the node which remoteUcastMacs belong to is removed, all remoteUcastMacs should be removed too.
- Node removed = TransactUtils.getRemoved(mod);
- if (removed != null) {
- List<LocalUcastMacs> macListRemoved = null;
- if (removed.getAugmentation(HwvtepGlobalAugmentation.class) != null) {
- macListRemoved = removed.getAugmentation(HwvtepGlobalAugmentation.class).getLocalUcastMacs();
- }
- if (macListRemoved != null) {
- result.put(key, macListRemoved);
- }
- }
- //If the node which remoteUcastMacs belong to is updated, and remoteUcastMacs may
- //be created or updated or deleted, we need to get deleted ones.
- Node updated = TransactUtils.getUpdated(mod);
- Node before = mod.getDataBefore();
- if (updated != null && before != null) {
- List<LocalUcastMacs> macListUpdated = null;
- List<LocalUcastMacs> macListBefore = null;
- HwvtepGlobalAugmentation hgUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class);
- if (hgUpdated != null) {
- macListUpdated = hgUpdated.getLocalUcastMacs();
- }
- HwvtepGlobalAugmentation hgBefore = before.getAugmentation(HwvtepGlobalAugmentation.class);
- if (hgBefore != null) {
- macListBefore = hgBefore.getLocalUcastMacs();
- }
- if (macListBefore != null) {
- List<LocalUcastMacs> macListRemoved = new ArrayList<LocalUcastMacs>();
- if (macListUpdated != null) {
- macListBefore.removeAll(macListUpdated);
- }
- //then exclude updated remoteUcastMacs
- if (macListUpdated != null) {
- for (LocalUcastMacs macBefore : macListBefore) {
- int i = 0;
- for (; i < macListUpdated.size(); i++) {
- if (macBefore.getKey().equals(macListUpdated.get(i).getKey())) {
- break;
- }
- }
- if (i == macListUpdated.size()) {
- macListRemoved.add(macBefore);
- }
- }
- } else {
- macListRemoved.addAll(macListBefore);
- }
- if (!macListRemoved.isEmpty()) {
- result.put(key, macListRemoved);
- }
- }
- }
- }
+ @Override
+ protected List<LocalUcastMacs> getData(HwvtepGlobalAugmentation augmentation) {
+ return augmentation.getLocalUcastMacs();
+ }
+
+ @Override
+ protected boolean cascadeDelete() {
+ return true;
+ }
+
+ @Override
+ protected UnMetDependencyGetter getDependencyGetter() {
+ return MAC_DEPENDENCY_GETTER;
+ }
+
+ static UnMetDependencyGetter MAC_DEPENDENCY_GETTER = new MacDependencyGetter();
+
+ public static class MacDependencyGetter extends UnMetDependencyGetter<LocalUcastMacs> {
+ @Override
+ public List<InstanceIdentifier<?>> getLogicalSwitchDependencies(LocalUcastMacs data) {
+ return Lists.newArrayList(data.getLogicalSwitchRef().getValue());
+ }
+
+ @Override
+ public List<InstanceIdentifier<?>> getTerminationPointDependencies(LocalUcastMacs data) {
+ return Collections.EMPTY_LIST;
}
- return result;
}
}
\ No newline at end of file
import static org.opendaylight.ovsdb.lib.operations.Operations.op;
import java.util.Collection;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
import org.opendaylight.ovsdb.lib.notation.UUID;
import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
import org.opendaylight.ovsdb.schema.hardwarevtep.UcastMacsLocal;
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.HwvtepNodeName;
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.hwvtep.global.attributes.LocalUcastMacs;
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.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.InstanceIdentifier;
import com.google.common.base.Optional;
-public class UcastMacsLocalUpdateCommand extends AbstractTransactCommand {
+public class UcastMacsLocalUpdateCommand extends AbstractTransactCommand<LocalUcastMacs, HwvtepGlobalAugmentation> {
private static final Logger LOG = LoggerFactory.getLogger(UcastMacsLocalUpdateCommand.class);
public UcastMacsLocalUpdateCommand(HwvtepOperationalState state,
@Override
public void execute(TransactionBuilder transaction) {
- Map<InstanceIdentifier<Node>, List<LocalUcastMacs>> createds =
- extractCreated(getChanges(),LocalUcastMacs.class);
- if (!createds.isEmpty()) {
- for (Entry<InstanceIdentifier<Node>, List<LocalUcastMacs>> created:
- createds.entrySet()) {
- updateUcastMacsLocal(transaction, created.getKey(), created.getValue());
- }
- }
Map<InstanceIdentifier<Node>, List<LocalUcastMacs>> updateds =
extractUpdated(getChanges(),LocalUcastMacs.class);
if (!updateds.isEmpty()) {
}
}
- private Map<InstanceIdentifier<Node>, List<LocalUcastMacs>> extractCreated(
- Collection<DataTreeModification<Node>> changes, Class<LocalUcastMacs> class1) {
- Map<InstanceIdentifier<Node>, List<LocalUcastMacs>> result
- = new HashMap<InstanceIdentifier<Node>, List<LocalUcastMacs>>();
- if (changes != null && !changes.isEmpty()) {
- for (DataTreeModification<Node> change : changes) {
- final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
- final DataObjectModification<Node> mod = change.getRootNode();
- Node created = TransactUtils.getCreated(mod);
- if (created != null) {
- List<LocalUcastMacs> macListUpdated = null;
- HwvtepGlobalAugmentation hgAugmentation = created.getAugmentation(HwvtepGlobalAugmentation.class);
- if (hgAugmentation != null) {
- macListUpdated = hgAugmentation.getLocalUcastMacs();
- }
- if (macListUpdated != null) {
- result.put(key, macListUpdated);
- }
- }
- }
- }
- return result;
+ protected List<LocalUcastMacs> getData(HwvtepGlobalAugmentation augmentation) {
+ return augmentation.getLocalUcastMacs();
}
- private Map<InstanceIdentifier<Node>, List<LocalUcastMacs>> extractUpdated(
- Collection<DataTreeModification<Node>> changes, Class<LocalUcastMacs> class1) {
- Map<InstanceIdentifier<Node>, List<LocalUcastMacs>> result
- = new HashMap<InstanceIdentifier<Node>, List<LocalUcastMacs>>();
- if (changes != null && !changes.isEmpty()) {
- for (DataTreeModification<Node> change : changes) {
- final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
- final DataObjectModification<Node> mod = change.getRootNode();
- Node updated = TransactUtils.getUpdated(mod);
- Node before = mod.getDataBefore();
- if (updated != null && before != null) {
- List<LocalUcastMacs> macListUpdated = null;
- List<LocalUcastMacs> macListBefore = null;
- HwvtepGlobalAugmentation hgUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class);
- if (hgUpdated != null) {
- macListUpdated = hgUpdated.getLocalUcastMacs();
- }
- HwvtepGlobalAugmentation hgBefore = before.getAugmentation(HwvtepGlobalAugmentation.class);
- if (hgBefore != null) {
- macListBefore = hgBefore.getLocalUcastMacs();
- }
- if (macListUpdated != null) {
- if (macListBefore != null) {
- macListUpdated.removeAll(macListBefore);
- }
- result.put(key, macListUpdated);
- }
- }
- }
- }
- return result;
- }
}
import static org.opendaylight.ovsdb.lib.operations.Operations.op;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
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.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.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.yangtools.yang.binding.InstanceIdentifier;
import com.google.common.base.Optional;
-public class UcastMacsRemoteRemoveCommand extends AbstractTransactCommand {
+public class UcastMacsRemoteRemoveCommand extends AbstractTransactCommand<RemoteUcastMacs, HwvtepGlobalAugmentation> {
private static final Logger LOG = LoggerFactory.getLogger(UcastMacsRemoteRemoveCommand.class);
public UcastMacsRemoteRemoveCommand(HwvtepOperationalState state,
}
InstanceIdentifier<RemoteUcastMacs> macIid = instanceIdentifier.augmentation(HwvtepGlobalAugmentation.class).
child(RemoteUcastMacs.class, mac.getKey());
- updateCurrentTxDeleteData(macIid, mac);
+ updateCurrentTxDeleteData(RemoteUcastMacs.class, macIid, mac);
}
}
- private Map<InstanceIdentifier<Node>, List<RemoteUcastMacs>> extractRemoved(
- Collection<DataTreeModification<Node>> changes, Class<RemoteUcastMacs> class1) {
- Map<InstanceIdentifier<Node>, List<RemoteUcastMacs>> result
- = new HashMap<InstanceIdentifier<Node>, List<RemoteUcastMacs>>();
- if (changes != null && !changes.isEmpty()) {
- for (DataTreeModification<Node> change : changes) {
- final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
- final DataObjectModification<Node> mod = change.getRootNode();
- //If the node which remoteUcastMacs belong to is removed, all remoteUcastMacs should be removed too.
- Node removed = TransactUtils.getRemoved(mod);
- if (removed != null) {
- List<RemoteUcastMacs> macListRemoved = null;
- if (removed.getAugmentation(HwvtepGlobalAugmentation.class) != null) {
- macListRemoved = removed.getAugmentation(HwvtepGlobalAugmentation.class).getRemoteUcastMacs();
- }
- if (macListRemoved != null) {
- result.put(key, macListRemoved);
- }
- }
- //If the node which remoteUcastMacs belong to is updated, and remoteUcastMacs may
- //be created or updated or deleted, we need to get deleted ones.
- Node updated = TransactUtils.getUpdated(mod);
- Node before = mod.getDataBefore();
- if (updated != null && before != null) {
- List<RemoteUcastMacs> macListUpdated = null;
- List<RemoteUcastMacs> macListBefore = null;
- HwvtepGlobalAugmentation hgUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class);
- if (hgUpdated != null) {
- macListUpdated = hgUpdated.getRemoteUcastMacs();
- }
- HwvtepGlobalAugmentation hgBefore = before.getAugmentation(HwvtepGlobalAugmentation.class);
- if (hgBefore != null) {
- macListBefore = hgBefore.getRemoteUcastMacs();
- }
- if (macListBefore != null) {
- List<RemoteUcastMacs> macListRemoved = new ArrayList<RemoteUcastMacs>();
- if (macListUpdated != null) {
- macListBefore.removeAll(macListUpdated);
- }
- //then exclude updated remoteUcastMacs
- if (macListUpdated != null) {
- for (RemoteUcastMacs macBefore : macListBefore) {
- int i = 0;
- for (; i < macListUpdated.size(); i++) {
- if (macBefore.getKey().equals(macListUpdated.get(i).getKey())) {
- break;
- }
- }
- if (i == macListUpdated.size()) {
- macListRemoved.add(macBefore);
- }
- }
- } else {
- macListRemoved.addAll(macListBefore);
- }
- if (!macListRemoved.isEmpty()) {
- result.put(key, macListRemoved);
- }
- }
- }
- }
- }
- return result;
+ protected List<RemoteUcastMacs> getData(HwvtepGlobalAugmentation augmentation) {
+ return augmentation.getRemoteUcastMacs();
}
+
}
import com.google.common.base.Optional;
import com.google.common.collect.Lists;
-import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+
+import static org.opendaylight.ovsdb.lib.operations.Operations.op;
+
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
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.UcastMacsRemote;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
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.EncapsulationTypeBase;
+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.HwvtepGlobalAugmentation;
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.HwvtepPhysicalLocatorAugmentationBuilder;
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 static org.opendaylight.ovsdb.lib.operations.Operations.op;
-public class UcastMacsRemoteUpdateCommand extends AbstractTransactCommand<RemoteUcastMacs> {
+public class UcastMacsRemoteUpdateCommand extends AbstractTransactCommand<RemoteUcastMacs, HwvtepGlobalAugmentation> {
private static final Logger LOG = LoggerFactory.getLogger(UcastMacsRemoteUpdateCommand.class);
private static final UcastMacUnMetDependencyGetter UCAST_MAC_DATA_VALIDATOR = new UcastMacUnMetDependencyGetter();
@Override
public void execute(TransactionBuilder transaction) {
- Map<InstanceIdentifier<Node>, List<RemoteUcastMacs>> createds =
- extractCreated(getChanges(),RemoteUcastMacs.class);
- if (!createds.isEmpty()) {
- for (Entry<InstanceIdentifier<Node>, List<RemoteUcastMacs>> created:
- createds.entrySet()) {
- updateUcastMacsRemote(transaction, created.getKey(), created.getValue());
- }
- }
Map<InstanceIdentifier<Node>, List<RemoteUcastMacs>> updateds =
extractUpdated(getChanges(),RemoteUcastMacs.class);
if (!updateds.isEmpty()) {
HwvtepPhysicalLocatorAugmentation locatorAugmentation = operationalLocatorOptional.get();
locatorUuid = new UUID(locatorAugmentation.getPhysicalLocatorUuid().getValue());
} else {
- //TODO: need to optimize by eliminating reading Configuration datastore
- //if no, get it from config DS and create id
- locatorUuid = getOperationalState().getPhysicalLocatorInFlight(iid);
+ locatorUuid = getOperationalState().getUUIDFromCurrentTx(TerminationPoint.class, iid);
if (locatorUuid == null) {
- Optional<TerminationPoint> configLocatorOptional =
- TransactUtils.readNodeFromConfig(getOperationalState().getReadWriteTransaction(), iid);
- if (configLocatorOptional.isPresent()) {
- HwvtepPhysicalLocatorAugmentation locatorAugmentation =
- configLocatorOptional.get().getAugmentation(HwvtepPhysicalLocatorAugmentation.class);
- locatorUuid = TransactUtils.createPhysicalLocator(transaction, locatorAugmentation);
- getOperationalState().setPhysicalLocatorInFlight(iid, locatorUuid);
- } else {
- LOG.warn("Create or update remoteUcastMac: No physical locator found in operational datastore!"
- + "Its indentifier is {}", inputMac.getLocatorRef().getValue());
- }
+ locatorUuid = TransactUtils.createPhysicalLocator(transaction, getOperationalState(),
+ (InstanceIdentifier<TerminationPoint>) inputMac.getLocatorRef().getValue());
+ updateCurrentTxData(TerminationPoint.class, iid, locatorUuid, null);
}
}
if (locatorUuid != null) {
}
}
- private Map<InstanceIdentifier<Node>, List<RemoteUcastMacs>> extractCreated(
- Collection<DataTreeModification<Node>> changes, Class<RemoteUcastMacs> class1) {
- Map<InstanceIdentifier<Node>, List<RemoteUcastMacs>> result
- = new HashMap<InstanceIdentifier<Node>, List<RemoteUcastMacs>>();
- if (changes != null && !changes.isEmpty()) {
- for (DataTreeModification<Node> change : changes) {
- final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
- final DataObjectModification<Node> mod = change.getRootNode();
- Node created = TransactUtils.getCreated(mod);
- if (created != null) {
- List<RemoteUcastMacs> macListUpdated = null;
- HwvtepGlobalAugmentation hgAugmentation = created.getAugmentation(HwvtepGlobalAugmentation.class);
- if (hgAugmentation != null) {
- macListUpdated = hgAugmentation.getRemoteUcastMacs();
- }
- if (macListUpdated != null) {
- result.put(key, macListUpdated);
- }
- }
- }
- }
- return result;
- }
-
- private Map<InstanceIdentifier<Node>, List<RemoteUcastMacs>> extractUpdated(
- Collection<DataTreeModification<Node>> changes, Class<RemoteUcastMacs> class1) {
- Map<InstanceIdentifier<Node>, List<RemoteUcastMacs>> result
- = new HashMap<InstanceIdentifier<Node>, List<RemoteUcastMacs>>();
- if (changes != null && !changes.isEmpty()) {
- for (DataTreeModification<Node> change : changes) {
- final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
- final DataObjectModification<Node> mod = change.getRootNode();
- Node updated = TransactUtils.getUpdated(mod);
- Node before = mod.getDataBefore();
- if (updated != null && before != null) {
- List<RemoteUcastMacs> macListUpdated = null;
- List<RemoteUcastMacs> macListBefore = null;
- HwvtepGlobalAugmentation hgUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class);
- if (hgUpdated != null) {
- macListUpdated = hgUpdated.getRemoteUcastMacs();
- }
- HwvtepGlobalAugmentation hgBefore = before.getAugmentation(HwvtepGlobalAugmentation.class);
- if (hgBefore != null) {
- macListBefore = hgBefore.getRemoteUcastMacs();
- }
- if (macListUpdated != null) {
- if (macListBefore != null) {
- macListUpdated.removeAll(macListBefore);
- }
- result.put(key, macListUpdated);
- }
- }
- }
- }
- return result;
+ protected List<RemoteUcastMacs> getData(HwvtepGlobalAugmentation augmentation) {
+ return augmentation.getRemoteUcastMacs();
}
static class UcastMacUnMetDependencyGetter extends UnMetDependencyGetter<RemoteUcastMacs> {
} else {
transaction.put(LogicalDatastoreType.OPERATIONAL,
tpPath, tpBuilder.build());
- getOvsdbConnectionInstance().getDeviceInfo().updateDeviceOpData(
- TerminationPoint.class, tpPath, pLoc.getUuid(), pLoc);
}
+ getOvsdbConnectionInstance().getDeviceInfo().updateDeviceOpData(
+ TerminationPoint.class, tpPath, pLoc.getUuid(), pLoc);
}
}
}
import org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md.TransactionInvokerImpl;
import org.opendaylight.ovsdb.lib.OvsdbClient;
import org.opendaylight.ovsdb.lib.OvsdbConnectionInfo;
-import org.opendaylight.ovsdb.lib.operations.Comment;
+import org.opendaylight.ovsdb.lib.operations.Delete;
import org.opendaylight.ovsdb.lib.operations.Insert;
import org.opendaylight.ovsdb.lib.operations.OperationResult;
import org.opendaylight.ovsdb.lib.operations.Operations;
+import org.opendaylight.ovsdb.lib.operations.Update;
+import org.opendaylight.ovsdb.lib.operations.Where;
import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
*/
void resetOperations() {
insertOpCapture = ArgumentCaptor.forClass(TypedBaseTable.class);
+ Update update = mock(Update.class);
Insert insert = mock(Insert.class);
+ Delete delete = mock(Delete.class);
+ Where where = mock(Where.class);
+ when(delete.where(any())).thenReturn(where);
when(insert.withId(any(String.class))).thenReturn(insert);
Operations.op = PowerMockito.mock(Operations.class);
- when(Operations.op.comment(any(String.class))).thenReturn(mock(Comment.class));
when(Operations.op.insert(insertOpCapture.capture())).thenReturn(insert);
-
+ when(Operations.op.update(insertOpCapture.capture())).thenReturn(update);
+ when(update.where(any())).thenReturn(where);
+ when(Operations.op.delete(any())).thenReturn(delete);
ListenableFuture<List<OperationResult>> ft = mock(ListenableFuture.class);
transactCaptor = ArgumentCaptor.forClass(List.class);
when(ovsdbClient.transact(any(DatabaseSchema.class), transactCaptor.capture())).thenReturn(ft);
tx.submit();
}
- void addData(LogicalDatastoreType logicalDatastoreType, Class<? extends DataObject> dataObject,
+ Node addData(LogicalDatastoreType logicalDatastoreType, Class<? extends DataObject> dataObject,
String[]... data) {
NodeBuilder nodeBuilder = prepareNode(nodeIid);
HwvtepGlobalAugmentationBuilder builder = new HwvtepGlobalAugmentationBuilder();
TestBuilders.addRemoteMcastMacs(nodeIid, builder, data);
}
nodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, builder.build());
- mergeNode(logicalDatastoreType, nodeIid, nodeBuilder);
+ return mergeNode(logicalDatastoreType, nodeIid, nodeBuilder);
+ }
+
+ void deleteData(LogicalDatastoreType logicalDatastoreType, Class<? extends DataObject> dataObject,
+ String[]... data) {
+ NodeBuilder nodeBuilder = prepareNode(nodeIid);
+ ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
+ HwvtepGlobalAugmentationBuilder builder = new HwvtepGlobalAugmentationBuilder();
+ if (LogicalSwitches.class == dataObject) {
+ List<LogicalSwitches> logicalSwitches = TestBuilders.addLogicalSwitches(builder, data);
+
+ for (LogicalSwitches ls : logicalSwitches) {
+ InstanceIdentifier<LogicalSwitches> key = nodeIid.augmentation(HwvtepGlobalAugmentation.class).
+ child(LogicalSwitches.class, ls.getKey());
+ tx.delete(logicalDatastoreType, key);
+ }
+ }
+ if (TerminationPoint.class == dataObject) {
+ TestBuilders.addGlobalTerminationPoints(nodeBuilder, nodeIid, data);
+ }
+ if (RemoteUcastMacs.class == dataObject) {
+ List<RemoteUcastMacs> macs = TestBuilders.addRemoteUcastMacs(nodeIid, builder, data);
+ for (RemoteUcastMacs mac : macs) {
+ InstanceIdentifier<RemoteUcastMacs> key = nodeIid.augmentation(HwvtepGlobalAugmentation.class).
+ child(RemoteUcastMacs.class, mac.getKey());
+ tx.delete(logicalDatastoreType, key);
+ }
+ }
+ if (RemoteMcastMacs.class == dataObject) {
+ List<RemoteMcastMacs> macs = TestBuilders.addRemoteMcastMacs(nodeIid, builder, data);
+ for (RemoteMcastMacs mac : macs) {
+ InstanceIdentifier<RemoteMcastMacs> key = nodeIid.augmentation(HwvtepGlobalAugmentation.class).
+ child(RemoteMcastMacs.class, mac.getKey());
+ tx.delete(logicalDatastoreType, key);
+ }
+ }
+ tx.submit();
}
NodeBuilder prepareNode(InstanceIdentifier<Node> iid) {
package org.opendaylight.ovsdb.hwvtepsouthbound;
import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.MoreExecutors;
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Matchers;
-import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transact.DependencyQueue;
import org.opendaylight.ovsdb.lib.operations.Operations;
import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable;
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.powermock.core.classloader.annotations.PrepareForTest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
import java.util.Iterator;
import java.util.List;
{"FF:FF:FF:FF:FF:FF", "ls1", "192.168.122.10", "192.168.122.30"}
};
+ String[][] mcastMac2 = new String[][]{
+ {"FF:FF:FF:FF:FF:FF", "ls0", "192.168.122.20", "192.168.122.10"},
+ {"FF:FF:FF:FF:FF:FF", "ls1", "192.168.122.10", "192.168.122.20"}
+ };
+
+ String[][] mcastMac3WithZeroLocators = new String[][]{
+ {"FF:FF:FF:FF:FF:FF", "ls0"},
+ {"FF:FF:FF:FF:FF:FF", "ls1"}
+ };
+
+ HwvtepOperationalDataChangeListener opDataChangeListener;
+
+ @Before
+ public void setupListener() throws Exception {
+ setFinalStatic(DependencyQueue.class, "executorService", MoreExecutors.sameThreadExecutor());
+ opDataChangeListener = new HwvtepOperationalDataChangeListener(dataBroker, hwvtepConnectionManager, connectionInstance);
+ }
+
+ @After
+ public void cleanupListener() {
+ try {
+ opDataChangeListener.close();
+ } catch (Exception e) {
+ }
+ }
+
+ void setFinalStatic(Class cls, String fieldName, Object newValue) throws Exception {
+ Field fields[] = FieldUtils.getAllFields(cls);
+ for (Field field : fields) {
+ if (fieldName.equals(field.getName())) {
+ field.setAccessible(true);
+ Field modifiersField = Field.class.getDeclaredField("modifiers");
+ modifiersField.setAccessible(true);
+ modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
+ field.set(null, newValue);
+ break;
+ }
+ }
+ }
@Test
public <T extends DataObject> void testLogicalSwitchAdd() throws Exception {
verifyThatLogicalSwitchCreated();
}
+ @Test
+ public <T extends DataObject> void testLogicalSwitchDelete() throws Exception {
+ addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
+ addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
+ resetOperations();
+ deleteData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
+ verify(Operations.op, times(2)).delete(any());
+ }
+
@Test
public <T extends DataObject> void testUcastMacAdd() throws Exception {
addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
- connectionInstance.getDeviceInfo().updateDeviceOpData(LogicalSwitches.class, ls0Iid, new UUID("ls0"), "ls0");
- connectionInstance.getDeviceInfo().updateDeviceOpData(LogicalSwitches.class, ls1Iid, new UUID("ls1"), "ls1");
resetOperations();
addData(CONFIGURATION, TerminationPoint.class, terminationPoints);
addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs);
//TODO add finer grained validation
}
+ @Test
+ public <T extends DataObject> void testUcastMacAddWithoutConfigTep() throws Exception {
+ addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
+ addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
+ resetOperations();
+ addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs);
+ //4 ucast macs + 2 termination points
+ verify(Operations.op, times(6)).insert(any(UcastMacsRemote.class));
+ //TODO add finer grained validation
+ }
+
+ @Test
+ public <T extends DataObject> void testUcastMacDelete() throws Exception {
+ addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
+ addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
+ addData(CONFIGURATION, TerminationPoint.class, terminationPoints);
+ addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs);
+ addData(OPERATIONAL, RemoteUcastMacs.class, ucastMacs);
+ addData(OPERATIONAL, TerminationPoint.class, terminationPoints);
+
+ resetOperations();
+ deleteData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs);
+ verify(Operations.op, times(4)).delete(any());
+ //TODO add finer grained validation
+ }
+
@Test
public <T extends DataObject> void testMcastMacAdd() throws Exception {
addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
- connectionInstance.getDeviceInfo().updateDeviceOpData(LogicalSwitches.class, ls0Iid, new UUID("ls0"), "ls0");
- connectionInstance.getDeviceInfo().updateDeviceOpData(LogicalSwitches.class, ls1Iid, new UUID("ls1"), "ls0");
resetOperations();
addData(CONFIGURATION, TerminationPoint.class, terminationPoints);
addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs);
}
@Test
- public <T extends DataObject> void testAddMacs() throws Exception {
+ public <T extends DataObject> void testMcastMacAddWithoutConfigTep() throws Exception {
addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
- connectionInstance.getDeviceInfo().updateDeviceOpData(LogicalSwitches.class, ls0Iid, new UUID("ls0"), "ls0");
- connectionInstance.getDeviceInfo().updateDeviceOpData(LogicalSwitches.class, ls1Iid, new UUID("ls1"), "ls0");
+ resetOperations();
+ addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs);
+ //2 mcast macs + 2 locator sets + 3 termination points
+ verify(Operations.op, times(7)).insert(Matchers.<McastMacsRemote>any());
+ }
+
+ @Test
+ public <T extends DataObject> void testMcastMacDelete() throws Exception {
+ addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
+ addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
+ addData(CONFIGURATION, TerminationPoint.class, terminationPoints);
+ addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs);
+ addData(OPERATIONAL, TerminationPoint.class, terminationPoints);
+ addData(OPERATIONAL, RemoteMcastMacs.class, mcastMacs);
+
+ resetOperations();
+ deleteData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs);
+ verify(Operations.op, times(2)).delete(Matchers.any());
+ }
+
+ @Test
+ public <T extends DataObject> void testAddMacs() throws Exception {
+ Node node = addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
+ addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
resetOperations();
addData(CONFIGURATION, TerminationPoint.class, terminationPoints);
addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs);
addData(OPERATIONAL, TerminationPoint.class, terminationPoints);
addData(OPERATIONAL, RemoteUcastMacs.class, ucastMacs);
+ resetOperations();
+ addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs);
+ //2 mcast mac + 2 locator sets ( termination point already added )
+ verify(Operations.op, times(4)).insert(Matchers.<McastMacsRemote>any());
+ }
+
+ @Test
+ public <T extends DataObject> void testUpdateMacs() throws Exception {
+ Node node = addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
+ addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
+ resetOperations();
+ addData(CONFIGURATION, TerminationPoint.class, terminationPoints);
+ addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs);
+ verify(Operations.op, times(6)).insert(any(UcastMacsRemote.class));
+
+ addData(OPERATIONAL, TerminationPoint.class, terminationPoints);
+ addData(OPERATIONAL, RemoteUcastMacs.class, ucastMacs);
+ resetOperations();
+ addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs);
+ verify(Operations.op, times(4)).insert(Matchers.<McastMacsRemote>any());
+ addData(OPERATIONAL, RemoteMcastMacs.class, mcastMacs);
+
+ resetOperations();
+ addData(CONFIGURATION, RemoteMcastMacs.class, mcastMac2);
+ verify(Operations.op, times(2)).insert(Matchers.<McastMacsRemote>any());
+ verify(Operations.op, times(2)).update(Matchers.<McastMacsRemote>any());
+ verify(Operations.op, times(0)).delete(Matchers.any());
+ }
+
+ @Test
+ public <T extends DataObject> void testUpdateMacsWithZeroLocators() throws Exception {
+ Node node = addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
+ addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
+ resetOperations();
+ addData(CONFIGURATION, TerminationPoint.class, terminationPoints);
+ addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs);
+ verify(Operations.op, times(6)).insert(any(UcastMacsRemote.class));
+
+ addData(OPERATIONAL, TerminationPoint.class, terminationPoints);
+ addData(OPERATIONAL, RemoteUcastMacs.class, ucastMacs);
+ resetOperations();
+ addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs);
+ verify(Operations.op, times(4)).insert(Matchers.<McastMacsRemote>any());
+ addData(OPERATIONAL, RemoteMcastMacs.class, mcastMacs);
+
+ resetOperations();
+ addData(CONFIGURATION, RemoteMcastMacs.class, mcastMac3WithZeroLocators);
+ verify(Operations.op, times(2)).delete(Matchers.any());
+ }
+
+ @Test
+ public <T extends DataObject> void testBackToBackMacsUpdate() throws Exception {
+ Node node = addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
+ addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
+ resetOperations();
+ addData(CONFIGURATION, TerminationPoint.class, terminationPoints);
+ addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs);
+ verify(Operations.op, times(6)).insert(any(UcastMacsRemote.class));
resetOperations();
addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs);
//2 mcast mac + 2 locator sets ( termination point already added )
+ verify(Operations.op, times(0)).insert(Matchers.<McastMacsRemote>any());
+ resetOperations();
+ addData(OPERATIONAL, TerminationPoint.class, terminationPoints);
+ addData(OPERATIONAL, RemoteUcastMacs.class, ucastMacs);
+ connectionInstance.getDeviceInfo().onOpDataAvailable();
+ //2 mcast mac + 2 locator sets ( termination point already added )
verify(Operations.op, times(4)).insert(Matchers.<McastMacsRemote>any());
+
+ resetOperations();
+ addData(CONFIGURATION, RemoteMcastMacs.class, mcastMac2);
+ verify(Operations.op, times(0)).insert(Matchers.<McastMacsRemote>any());
+ addData(OPERATIONAL, RemoteMcastMacs.class, mcastMacs);
+ connectionInstance.getDeviceInfo().onOpDataAvailable();
+ verify(Operations.op, times(2)).insert(Matchers.<McastMacsRemote>any());
+ verify(Operations.op, times(2)).update(Matchers.<McastMacsRemote>any());
}
private void verifyThatLogicalSwitchCreated() {
--- /dev/null
+/*
+ * Copyright (c) 2015 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;
+
+import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
+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.DataObjectModification.ModificationType;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+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.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.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.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.ChildOf;
+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;
+
+import java.util.Collection;
+
+public class HwvtepOperationalDataChangeListener implements ClusteredDataTreeChangeListener<Node>, AutoCloseable {
+
+ private static final Logger LOG = LoggerFactory.getLogger(HwvtepOperationalDataChangeListener.class);
+
+ private final ListenerRegistration<HwvtepOperationalDataChangeListener> registration;
+ private final HwvtepConnectionManager hcm;
+ private final DataBroker db;
+ private final HwvtepConnectionInstance connectionInstance;
+
+ HwvtepOperationalDataChangeListener(DataBroker db, HwvtepConnectionManager hcm, HwvtepConnectionInstance connectionInstance) {
+ this.db = db;
+ this.hcm = hcm;
+ this.connectionInstance = connectionInstance;
+ DataTreeIdentifier<Node> treeId =
+ new DataTreeIdentifier<Node>(LogicalDatastoreType.OPERATIONAL, getWildcardPath());
+ registration = db.registerDataTreeChangeListener(treeId, HwvtepOperationalDataChangeListener.this);
+ }
+
+ @Override
+ public void close() throws Exception {
+ if(registration != null) {
+ registration.close();
+ }
+ }
+
+ @Override
+ public void onDataTreeChanged(Collection<DataTreeModification<Node>> changes) {
+ for (DataTreeModification<Node> change : changes) {
+ final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
+ final DataObjectModification<Node> mod = change.getRootNode();
+ for (DataObjectModification<? extends DataObject> child : mod.getModifiedChildren()) {
+ updateDeviceOpData(key, child);
+ }
+ DataObjectModification<HwvtepGlobalAugmentation> aug = mod.getModifiedAugmentation(HwvtepGlobalAugmentation.class);
+ if (aug != null && getModificationType(aug) != null) {
+ Collection<DataObjectModification<? extends DataObject>> children = aug.getModifiedChildren();
+ for (DataObjectModification<? extends DataObject> child : children) {
+ updateDeviceOpData(key, child);
+ }
+ }
+ }
+ }
+
+ private void updateDeviceOpData(InstanceIdentifier<Node> key, DataObjectModification<? extends DataObject> mod) {
+ ModificationType type = getModificationType(mod);
+ if (type == null) {
+ return;
+ }
+ Class<? extends Identifiable> childClass = (Class<? extends Identifiable>) mod.getDataType();
+ InstanceIdentifier instanceIdentifier = getKey(key, mod, mod.getDataAfter());
+ switch(type) {
+ case WRITE:
+ connectionInstance.getDeviceInfo().updateDeviceOpData(childClass, instanceIdentifier,
+ new UUID("uuid"), mod.getDataAfter());
+ break;
+ case DELETE:
+ connectionInstance.getDeviceInfo().clearDeviceOpData(childClass, instanceIdentifier);
+ break;
+ case SUBTREE_MODIFIED:
+ }
+ }
+
+ private ModificationType getModificationType(DataObjectModification<? extends DataObject> mod) {
+ try {
+ return mod.getModificationType();
+ } catch (IllegalStateException e) {
+ LOG.debug("Failed to get the modification type ", e);
+ }
+ return null;
+ }
+
+ private InstanceIdentifier getKey(InstanceIdentifier<Node> key, DataObjectModification<? extends DataObject> child,
+ DataObject data) {
+ Class<? extends DataObject> childClass = child.getDataType();
+ InstanceIdentifier instanceIdentifier = null;
+ if (LogicalSwitches.class == childClass) {
+ LogicalSwitches ls = (LogicalSwitches)data;
+ instanceIdentifier = key.augmentation(HwvtepGlobalAugmentation.class).child(LogicalSwitches.class, ls.getKey());
+ } else if (org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint.class == childClass) {
+ TerminationPoint tp = (TerminationPoint)data;
+ instanceIdentifier = key.child(TerminationPoint.class, tp.getKey());
+ } else if (RemoteUcastMacs.class == childClass) {
+ RemoteUcastMacs mac = (RemoteUcastMacs)data;
+ instanceIdentifier = key.augmentation(HwvtepGlobalAugmentation.class).child(RemoteUcastMacs.class, mac.getKey());
+ } else if (RemoteMcastMacs.class == childClass) {
+ RemoteMcastMacs mac = (RemoteMcastMacs)data;
+ instanceIdentifier = key.augmentation(HwvtepGlobalAugmentation.class).child(RemoteMcastMacs.class, mac.getKey());
+ }
+ return instanceIdentifier;
+ }
+
+ Class<? extends ChildOf<? super HwvtepGlobalAugmentation>> getClass(Class<? extends DataObject> cls) {
+ return (Class<? extends ChildOf<? super HwvtepGlobalAugmentation>>) cls;
+ }
+
+ private InstanceIdentifier<Node> getWildcardPath() {
+ InstanceIdentifier<Node> path = InstanceIdentifier
+ .create(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID))
+ .child(Node.class);
+ return path;
+ }
+}
public static final String VXLAN_OVER_IPV4 = "vxlan_over_ipv4";
- public static void addLogicalSwitches(HwvtepGlobalAugmentationBuilder augmentationBuilder, String[]... data) {
+ public static List<LogicalSwitches> addLogicalSwitches(HwvtepGlobalAugmentationBuilder augmentationBuilder, String[]... data) {
List<LogicalSwitches> logicalSwitcheses = Lists.newArrayList();
for (String row[] : data) {
logicalSwitcheses.add(TestBuilders.buildLogicalSwitch(row));
}
augmentationBuilder.setLogicalSwitches(logicalSwitcheses);
+ return logicalSwitcheses;
}
- public static void addRemoteMcastMacs(InstanceIdentifier<Node> iid,
+ public static List<RemoteMcastMacs> addRemoteMcastMacs(InstanceIdentifier<Node> iid,
HwvtepGlobalAugmentationBuilder augmentationBuilder, String[]... data) {
List<RemoteMcastMacs> remoteMcastMacses = Lists.newArrayList();
for (String row[] : data) {
remoteMcastMacses.add(TestBuilders.buildRemoteMcastMacs(iid, row[0], row[1], teps));
}
augmentationBuilder.setRemoteMcastMacs(remoteMcastMacses);
+ return remoteMcastMacses;
}
public static List<RemoteUcastMacs> addRemoteUcastMacs(InstanceIdentifier<Node> iid,
"ipaddr": {
"type": "string"
},
+ "_uuid": {
+ "type": "string"
+ },
"locator_set": {
"type": {
"key": {
"ipaddr": {
"type": "string"
},
+ "_uuid": {
+ "type": "string"
+ },
"locator_set": {
"type": {
"key": {
}
}
},
+ "_uuid": {
+ "type": "string"
+ },
"indexes": [
[
"encapsulation_type",
},
"Physical_Locator_Set": {
"columns": {
+ "_uuid": {
+ "type": "string"
+ },
"locators": {
"mutable": false,
"type": {
"description": {
"type": "string"
},
+ "_uuid": {
+ "type": "string"
+ },
"name": {
"type": "string"
},
"description": {
"type": "string"
},
+ "_uuid": {
+ "type": "string"
+ },
"management_ips": {
"type": {
"key": "string",
"ipaddr": {
"type": "string"
},
+ "_uuid": {
+ "type": "string"
+ },
"locator": {
"type": {
"key": {
"ipaddr": {
"type": "string"
},
+ "_uuid": {
+ "type": "uuid"
+ },
+ "uuid": {
+ "type": "uuid"
+ },
"locator": {
"type": {
"key": {